Доработка. Функция для чтения параллельного порта. Пример в котором данные с параллельной шины направляются в stdout
This commit is contained in:
4
.gitignore
vendored
4
.gitignore
vendored
@@ -5,4 +5,6 @@ lib*.so.*
|
|||||||
debian-template/wiringPi
|
debian-template/wiringPi
|
||||||
debian-template/wiringpi-*.deb
|
debian-template/wiringpi-*.deb
|
||||||
gpio/gpio
|
gpio/gpio
|
||||||
.idea/
|
/.idea/
|
||||||
|
/.vscode/
|
||||||
|
/debian-template/
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ Q ?= @
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
#DEBUG = -g -O0
|
#DEBUG = -g -O0
|
||||||
DEBUG = -O3
|
DEBUG = -O0 -g
|
||||||
CC ?= gcc
|
CC ?= gcc
|
||||||
INCLUDE = -I/usr/local/include
|
INCLUDE = -I/usr/local/include
|
||||||
CFLAGS = $(DEBUG) -Wall $(INCLUDE) -Winline -pipe $(EXTRA_CFLAGS)
|
CFLAGS = $(DEBUG) -Wall $(INCLUDE) -Winline -pipe $(EXTRA_CFLAGS)
|
||||||
|
|||||||
@@ -1,113 +1,148 @@
|
|||||||
/* Demonstration C GPIO interrupt handling routine for Raspberry Pi
|
/* Направляет в стандартный вывод данные полученные с
|
||||||
|
параллельной 8-битной шины Raspberry Pi4. Собирать внутри папки WiringPi/examples
|
||||||
This is a modified code found at https://github.com/phil-lavin/raspberry-pi-gpio-interrupt
|
командой make really-all.
|
||||||
|
Предварительные условия:
|
||||||
The program displays a notice whenever you:
|
- WiringPi должен быть собран из этой версии, в которую добавлена функция digitalReadPins()
|
||||||
-turn on the Raspberry Pi's pin 11 (apply 3.3V),
|
```
|
||||||
-turn the pin off.
|
make && make install
|
||||||
|
```
|
||||||
This routine uses wiringPi library (follow the installation instructions at wiringpi.com),
|
- WiringPi должен быть установлен из того deb-пакета который получен из этой версии
|
||||||
and should be compiled with a command:
|
```
|
||||||
|
make debian && dpkg -i debian-template/WiringPi*.deb
|
||||||
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.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <wiringPi.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
|
unsigned int wr_pin = 27; /** Вывод для сигнала записи */
|
||||||
// (in microseconds); allows to avoid generating interrupts on contact bouncing etc.
|
unsigned int pins[] = { 21, 7, 6, 5, 25, 24, 23, 22 }; /** Выводы для данных */
|
||||||
#define IGNORE_CHANGE_BELOW_USEC 10000
|
const size_t out_buffer_len = 32U; /** Размер выходного буфера */
|
||||||
|
const size_t fifo_buffer_len = 4096U; /** Размер буфера ПППУ */
|
||||||
// Current state of the pin
|
|
||||||
static volatile int state;
|
|
||||||
|
|
||||||
// Time of last change
|
|
||||||
struct timeval last_change;
|
|
||||||
|
|
||||||
|
|
||||||
// Handler for interrupt
|
struct fifo {
|
||||||
void handle(void) {
|
char *buffer; /** Буфер ПППУ */
|
||||||
struct timeval now;
|
size_t len; /** Длина буфера ПППУ */
|
||||||
static __uint64_t cnt;
|
size_t wri; /** Указатель записи ПППУ */
|
||||||
unsigned long diff;
|
size_t rdi; /** Указатель чтения ПППУ */
|
||||||
//gettimeofday(&now, NULL);
|
};
|
||||||
state = digitalRead(PIN);
|
|
||||||
printf("-->%d %d\n", ++cnt, state);
|
|
||||||
return;
|
|
||||||
|
|
||||||
// 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.):
|
void fifo_reset(struct fifo* ff) {
|
||||||
/*
|
ff->wri = 0U;
|
||||||
if (diff > IGNORE_CHANGE_BELOW_USEC) {
|
ff->rdi = 0U;
|
||||||
|
|
||||||
// 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...
|
|
||||||
}
|
|
||||||
|
|
||||||
// Change the "state" variable value:
|
|
||||||
state = !state;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
// Store the time for last state change:
|
|
||||||
last_change = now;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool fifo_init(struct fifo* ff, size_t len) {
|
||||||
|
ff->buffer = malloc(len);
|
||||||
|
ff->len = len;
|
||||||
|
fifo_reset(ff);
|
||||||
|
return ff->buffer != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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) {
|
int main(void) {
|
||||||
// Init -- use the physical pin number on RPi P1 connector
|
|
||||||
if (wiringPiSetup() == -1)
|
if (!fifo_init(&isr_ff, fifo_buffer_len)) {
|
||||||
{
|
perror("не выполнено fifo_init()\n");
|
||||||
printf("ошибка wiringPiSetup()\n");
|
exit(EXIT_FAILURE);
|
||||||
exit(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set pin to input in case it's not
|
if (wiringPiSetup() == -1) {
|
||||||
pinMode(PIN, INPUT);
|
perror("не выполнено wiringPiSetup()\n");
|
||||||
pullUpDnControl(PIN, PUD_UP);
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
// Time now
|
/** Сигнал записи */
|
||||||
gettimeofday(&last_change, NULL);
|
pinMode(wr_pin, INPUT);
|
||||||
|
pullUpDnControl(wr_pin, PUD_UP);
|
||||||
|
|
||||||
// Bind to interrupt
|
/** Шина данных 8 бит */
|
||||||
wiringPiISR(PIN, INT_EDGE_RISING, &handle);
|
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
|
int rc = wiringPiISR(wr_pin, INT_EDGE_RISING, &isr_handle);
|
||||||
state = digitalRead(PIN);
|
if (rc != 0) {
|
||||||
|
perror("не выполнено wiringPiISR()\n");
|
||||||
// Feedback for user that the program has started, depending on input state:
|
exit(EXIT_FAILURE);
|
||||||
if (state) {
|
}
|
||||||
printf("Started! Initial state is on\n");
|
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 {
|
else {
|
||||||
printf("Started! Initial state is off\n");
|
usleep(10000);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Waste time but not CPU
|
|
||||||
for (;;) {
|
|
||||||
sleep(1);
|
|
||||||
state = digitalRead(PIN);
|
|
||||||
}
|
}
|
||||||
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2585,6 +2585,34 @@ unsigned int digitalReadByte (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unsigned int digitalReadPins(unsigned int *pins, unsigned int count)
|
||||||
|
{
|
||||||
|
uint32_t i, x ;
|
||||||
|
uint32_t raw ;
|
||||||
|
uint32_t data = 0 ;
|
||||||
|
|
||||||
|
FailOnModel5("digitalReadPins");
|
||||||
|
|
||||||
|
if (wiringPiMode == WPI_MODE_GPIO_SYS)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
raw = *(gpio + gpioToGPLEV [0]) ; // First bank for these pins
|
||||||
|
data = 0;
|
||||||
|
for (i = 0 ; i < count ; ++ i)
|
||||||
|
{
|
||||||
|
uint32_t pin = pins[i] ;
|
||||||
|
x = pinToGpio [pin & 63];
|
||||||
|
data |= ((raw & (1 << x)) > 0) << i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* digitalWriteByte2:
|
* digitalWriteByte2:
|
||||||
* digitalReadByte2:
|
* digitalReadByte2:
|
||||||
|
|||||||
@@ -288,6 +288,7 @@ extern void pwmSetMode (int mode) ;
|
|||||||
extern void pwmSetRange (unsigned int range) ;
|
extern void pwmSetRange (unsigned int range) ;
|
||||||
extern void pwmSetClock (int divisor) ;
|
extern void pwmSetClock (int divisor) ;
|
||||||
extern void gpioClockSet (int pin, int freq) ;
|
extern void gpioClockSet (int pin, int freq) ;
|
||||||
|
extern unsigned int digitalReadPins (unsigned int *pins, unsigned int count) ;
|
||||||
extern unsigned int digitalReadByte (void) ;
|
extern unsigned int digitalReadByte (void) ;
|
||||||
extern unsigned int digitalReadByte2 (void) ;
|
extern unsigned int digitalReadByte2 (void) ;
|
||||||
extern void digitalWriteByte (int value) ;
|
extern void digitalWriteByte (int value) ;
|
||||||
|
|||||||
Reference in New Issue
Block a user