@@ -1,113 +1,148 @@
/* Demonstration C GPIO interrupt handling routine for Raspberry Pi
This is a modified code found at https://github.com/phil-lavin/raspberry-pi-gpio-interrupt
The program displays a notice whenever you:
-turn on the Raspberry Pi's pin 11 (apply 3.3V),
-turn th e p in off.
This routine uses wiringPi library (follow the installation instructions at wiringpi.com),
and should be compiled with a command:
gcc source_filename -o executable_filename -lwiringPi
You must have root privileges to run it - I don't know any workaround yet:
sudo ./executable_filename
Then the program displays a notice whenever you turn the GPIO pin 11 on and off.
It runs as an infinite loop and you can cancel it by pressing ctrl-C.
/* Направляет в стандартный вывод данные полученные с
параллельной 8-битной шины Raspberry Pi4. Собирать внутри папки WiringPi/examples
командой make really-all.
Предварительные условия:
- WiringPi должен быть собран из этой версии, в которую добавлена функция digitalReadPins()
```
make && mak e install
```
- WiringPi должен быть установлен из того deb-пакета который получен из этой версии
```
make debian && dpkg -i debian-template/WiringPi*.deb
```
*/
# include <stdlib.h>
# include <string.h>
# include <unistd.h>
# include <stdio.h>
# include <sys/time.h>
# include <wiringPi.h>
// Which GPIO pin we're using. For this program we'll use physical pin numbers.
# define PIN 27
// How much time a change must be since the last in order to count as a change
// (in microseconds); allows to avoid generating interrupts on contact bouncing etc.
# define IGNORE_CHANGE_BELOW_USEC 10000
// Current state of the pin
static volatile int state ;
// Time of last change
struct timeval last_change ;
unsigned int wr_pin = 27 ; /** Вывод для сигнала записи */
unsigned int pins [ ] = { 21 , 7 , 6 , 5 , 25 , 24 , 23 , 22 } ; /** Выводы для данных */
const size_t out_buffer_len = 32U ; /** Размер выходного буфера */
const size_t fifo_buffer_len = 4096U ; /** Размер буфера ПППУ */
// Handler for interrupt
void handle ( void ) {
struct timeval now ;
static __uint64 _t cnt ;
unsigned long diff ;
//gettimeofday(&now, NULL);
state = digitalRead ( PIN ) ;
printf ( " -->%d %d \n " , + + cnt , state ) ;
return ;
struct fifo {
char * buffer ; /** Буфер ПППУ */
size_t len ; /** Длина буфера ПППУ */
size _t wri ; /** Указатель записи ПППУ */
size_t r di; /** Указатель чтения ПППУ */
} ;
// Time difference in microseconds
diff = ( now . tv_sec * 1000000 + now . tv_usec ) - ( last_change . tv_sec * 1000000 + last_change . tv_usec ) ;
// Filter any changes in intervals shorter than diff (like contact bouncing etc.):
/*
if (diff > IGNORE_CHANGE_BELOW_USEC) {
// Check whether the last state was on or off:
if (state) {
// Print info to console:
printf("Input goes off\n");
// You can add some code to do when input goes off here...
}
else {
// Print info to console:
printf("Input goes on\n");
// Add code to do when input goes on here...
void fifo_reset ( struct fifo * ff ) {
ff - > wri = 0U ;
ff - > rdi = 0U ;
}
// Change the "state" variable value:
state = !state;
bool fifo_init ( struct fifo * ff , size_t len ) {
ff - > buffer = malloc ( len ) ;
ff - > len = len ;
fifo_reset ( ff ) ;
return ff - > buffer ! = NULL ;
}
*/
// Store the time for last state change:
last_change = now ;
void fifo_uninit ( struct fifo * ff , size_t len ) {
free ( ff - > buffer ) ;
ff - > buffer = NULL ;
fifo_reset ( ff ) ;
}
bool fifo_is_full ( struct fifo * ff ) {
return ( ( ff - > wri + 1U ) % ff - > len ) = = ff - > rdi ;
}
size_t fifo_available ( struct fifo * ff ) {
bool v = ff - > wri > = ff - > rdi ;
return ( ff - > wri - ff - > rdi ) * v + ( ff - > wri + ff - > len - ff - > rdi ) * ( ! v ) ;
}
bool fifo_can_write ( struct fifo * ff , size_t len ) {
return ( ff - > len - fifo_available ( ff ) ) > len ;
}
bool fifo_can_read ( struct fifo * ff , size_t len ) {
return fifo_available ( ff ) > = len ;
}
bool fifo_try_read ( struct fifo * ff , char * buffer , size_t len ) {
if ( ! fifo_can_read ( ff , len ) ) {
return false ;
}
memcpy ( buffer , & ff - > buffer [ ff - > rdi ] , len ) ;
ff - > rdi = ( ff - > rdi + len ) % ff - > len ;
return true ;
}
bool fifo_try_write ( struct fifo * ff , char * buffer , size_t len ) {
if ( ! fifo_can_write ( ff , len ) ) {
return false ;
}
memcpy ( & ff - > buffer [ ff - > wri ] , buffer , len ) ;
ff - > wri = ( ff - > wri + len ) % ff - > len ;
return true ;
}
static struct fifo isr_ff ;
void isr_handle ( void ) {
char byte_read = digitalReadPins ( pins , sizeof pins / sizeof pins [ 0 ] ) ;
fifo_try_write ( & isr_ff , & byte_read , 1 ) ;
}
int main ( void ) {
// Init -- use the physical pin number on RPi P1 connector
if ( wiringPiSetup ( ) = = - 1 )
{
printf ( " ошибка wiringPiSetup() \n " ) ;
exit ( 1 ) ;
if ( ! fifo_init ( & isr_ff , fifo_buffer_len ) ) {
perror ( " не выполнено fifo_init() \n " ) ;
exit ( EXIT_FAILURE ) ;
}
// Set pin to input in case it's not
pinMode ( PIN , INPUT ) ;
pullUpDnControl ( PIN , PUD_UP ) ;
if ( wiringPiSetup ( ) = = - 1 ) {
perror ( " не выполнено wiringPiSetup() \n " ) ;
exit ( EXIT_FAILURE ) ;
}
// Time now
gettimeofday ( & last_change , NULL ) ;
/** Сигнал записи */
pinMode ( wr_pin , INPUT ) ;
pullUpDnControl ( wr_pin , PUD_UP ) ;
// Bind to interrupt
wiringPiISR ( PIN , INT_EDGE_RISING , & handle ) ;
/** Шина данных 8 бит */
for ( unsigned int i = 0 ; i < ( sizeof pins / sizeof pins [ 0 ] ) ; i + + ) {
unsigned int pin = pins [ i ] ;
pinMode ( pin , INPUT ) ;
pullUpDnControl ( pin , PUD_UP ) ;
}
// Get initial state of pin
state = digitalRead ( PIN ) ;
// Feedback for user that the program has started, depending on input state:
if ( state ) {
printf ( " Started! Initial state is on \n " ) ;
int rc = wiringPiISR ( wr_pin , INT_EDGE_RISING , & isr_handle ) ;
if ( rc ! = 0 ) {
perror ( " не выполнено wiringPiISR() \n " ) ;
exit ( EXIT_FAILURE ) ;
}
char buffer [ out_buffer_len ] ;
while ( true ) {
bool is_read = fifo_try_read ( & isr_ff , buffer , sizeof buffer ) ;
if ( is_read ) {
fwrite ( buffer , 1U , sizeof buffer , stdout ) ;
fflush ( stdout ) ;
}
else {
printf ( " Started! Initial state is off \n " ) ;
}
// Waste time but not CPU
for ( ; ; ) {
sleep ( 1 ) ;
state = digitalRead ( PIN ) ;
usleep ( 10000 ) ;
}
}
return EXIT_SUCCESS ;
}