#include "buffered_peripheral.h" #include #include void buffered_transceiver_init(buffered_transceiver_t *transceiver, queue_t *rx_queue, queue_t *tx_queue, void *peripheral, buffered_transceiver_vtable_t vtable) { transceiver->rx_queue = rx_queue; transceiver->tx_queue = tx_queue; transceiver->peripheral = peripheral; transceiver->vtable = vtable; } uint16_t buffered_transceiver_transmit(buffered_transceiver_t *transceiver, void *buffer, uint16_t size) { uint16_t sent = 0; if (size == 0) { size = strlen((char*)buffer); } while (sent < size && queue_space(transceiver->tx_queue) > 0) { queue_enqueue(transceiver->tx_queue, buffer + sent * transceiver->tx_queue->element_size); sent++; } buffered_transceiver_trigger_transmit(transceiver, 1); return sent; } uint16_t buffered_transceiver_receive(buffered_transceiver_t *transceiver, void *buffer, uint16_t max_size) { // Get all data from buffer buffered_transceiver_trigger_receive(transceiver, 1); uint16_t received = 0; while (received < max_size && queue_count(transceiver->rx_queue) > 0) { queue_dequeue_safely(transceiver->rx_queue, buffer + received*transceiver->rx_queue->element_size); received++; } return received; } void buffered_transceiver_trigger_receive(buffered_transceiver_t *transceiver, uint16_t size) { void* element = alloca(transceiver->rx_queue->element_size); while (transceiver->vtable.can_receive(transceiver->peripheral) > 0 && queue_space(transceiver->rx_queue) > 0) { uint16_t received = transceiver->vtable.receive(transceiver->peripheral, element, 1); if (received > 0) { queue_enqueue(transceiver->rx_queue, element); } } } bool buffered_transceiver_trigger_transmit(buffered_transceiver_t *transceiver, uint16_t size) { while (transceiver->vtable.can_transmit(transceiver->peripheral) && queue_count(transceiver->tx_queue) > 0) { void* data = alloca(transceiver->tx_queue->element_size); queue_dequeue_safely(transceiver->tx_queue, data); transceiver->vtable.transmit(transceiver->peripheral, data, 1); return true; } return false; }