149 lines
3.6 KiB
C
Executable File
149 lines
3.6 KiB
C
Executable File
/* Направляет в стандартный вывод данные полученные с
|
||
параллельной 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;
|
||
}
|