/* Направляет в стандартный вывод данные полученные с параллельной 8-битной шины Raspberry Pi4. Собирать внутри папки WiringPi/examples командой make really-all. Предварительные условия: - WiringPi должен быть собран из этой версии, в которую добавлена функция digitalReadPins() ``` make && make install ``` - WiringPi должен быть установлен из того deb-пакета который получен из этой версии ``` make debian && dpkg -i debian-template/WiringPi*.deb ``` */ #include #include #include #include #include #include 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; }