Files
gpio-reader/examples/gpio-interrupt.c

149 lines
3.6 KiB
C
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* Направляет в стандартный вывод данные полученные с
параллельной 8-битной шины Raspberry Pi4. Собирать внутри папки WiringPi/examples
командой make really-all.
Предварительные условия:
- WiringPi должен быть собран из этой версии, в которую добавлена функция digitalReadPins()
```
make && make 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>
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; /** Размер буфера ПППУ */
struct fifo {
char *buffer; /** Буфер ПППУ */
size_t len; /** Длина буфера ПППУ */
size_t wri; /** Указатель записи ПППУ */
size_t rdi; /** Указатель чтения ПППУ */
};
void fifo_reset(struct fifo* ff) {
ff->wri = 0U;
ff->rdi = 0U;
}
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) {
if (!fifo_init(&isr_ff, fifo_buffer_len)) {
perror("не выполнено fifo_init()\n");
exit(EXIT_FAILURE);
}
if (wiringPiSetup() == -1) {
perror("не выполнено wiringPiSetup()\n");
exit(EXIT_FAILURE);
}
/** Сигнал записи */
pinMode(wr_pin, INPUT);
pullUpDnControl(wr_pin, PUD_UP);
/** Шина данных 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);
}
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 {
usleep(10000);
}
}
return EXIT_SUCCESS;
}