Reworked queue and buffering
This commit is contained in:
parent
417f39d02a
commit
163c6b021f
47
Config.h
47
Config.h
@ -4,18 +4,14 @@
|
|||||||
#define CONFIG_H
|
#define CONFIG_H
|
||||||
|
|
||||||
#define MAJ_VERS 0x01
|
#define MAJ_VERS 0x01
|
||||||
#define MIN_VERS 0x0D
|
#define MIN_VERS 0x0E
|
||||||
|
|
||||||
#define MCU_328P 0x90
|
|
||||||
#define MCU_1284P 0x91
|
#define MCU_1284P 0x91
|
||||||
|
|
||||||
#define MODE_HOST 0x11
|
#define MODE_HOST 0x11
|
||||||
#define MODE_TNC 0x12
|
#define MODE_TNC 0x12
|
||||||
|
|
||||||
#if defined(__AVR_ATmega328P__)
|
#if defined(__AVR_ATmega1284P__)
|
||||||
#define MCU_VARIANT MCU_328P
|
|
||||||
#warning "Firmware is being compiled for atmega328p based boards"
|
|
||||||
#elif defined(__AVR_ATmega1284P__)
|
|
||||||
#define MCU_VARIANT MCU_1284P
|
#define MCU_VARIANT MCU_1284P
|
||||||
#warning "Firmware is being compiled for atmega1284p based boards"
|
#warning "Firmware is being compiled for atmega1284p based boards"
|
||||||
#else
|
#else
|
||||||
@ -25,22 +21,11 @@
|
|||||||
#define MTU 500
|
#define MTU 500
|
||||||
#define SINGLE_MTU 255
|
#define SINGLE_MTU 255
|
||||||
#define HEADER_L 1
|
#define HEADER_L 1
|
||||||
|
#define MIN_L 1
|
||||||
|
|
||||||
#define CMD_L 4
|
#define CMD_L 4
|
||||||
|
|
||||||
// MCU dependent configuration parameters
|
// MCU dependent configuration parameters
|
||||||
#if MCU_VARIANT == MCU_328P
|
|
||||||
const int pin_cs = 7;
|
|
||||||
const int pin_reset = 6;
|
|
||||||
const int pin_dio = 2;
|
|
||||||
const int pin_led_rx = 5;
|
|
||||||
const int pin_led_tx = 4;
|
|
||||||
|
|
||||||
#define FLOW_CONTROL_ENABLED true
|
|
||||||
#define QUEUE_SIZE 0
|
|
||||||
|
|
||||||
#define EEPROM_SIZE 512
|
|
||||||
#define EEPROM_OFFSET EEPROM_SIZE-EEPROM_RESERVED
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if MCU_VARIANT == MCU_1284P
|
#if MCU_VARIANT == MCU_1284P
|
||||||
const int pin_cs = 4;
|
const int pin_cs = 4;
|
||||||
@ -49,10 +34,9 @@
|
|||||||
const int pin_led_rx = 12;
|
const int pin_led_rx = 12;
|
||||||
const int pin_led_tx = 13;
|
const int pin_led_tx = 13;
|
||||||
|
|
||||||
#define FLOW_CONTROL_ENABLED true
|
#define CONFIG_UART_BUFFER_SIZE 6750
|
||||||
#define QUEUE_SIZE 24
|
#define CONFIG_QUEUE_SIZE 6750
|
||||||
#define QUEUE_BUF_SIZE (QUEUE_SIZE+1)
|
#define CONFIG_QUEUE_MAX_LENGTH 70
|
||||||
#define QUEUE_MEM QUEUE_BUF_SIZE * MTU
|
|
||||||
|
|
||||||
#define EEPROM_SIZE 4096
|
#define EEPROM_SIZE 4096
|
||||||
#define EEPROM_OFFSET EEPROM_SIZE-EEPROM_RESERVED
|
#define EEPROM_OFFSET EEPROM_SIZE-EEPROM_RESERVED
|
||||||
@ -67,7 +51,6 @@
|
|||||||
// SX1276 RSSI offset to get dBm value from
|
// SX1276 RSSI offset to get dBm value from
|
||||||
// packet RSSI register
|
// packet RSSI register
|
||||||
const int rssi_offset = 157;
|
const int rssi_offset = 157;
|
||||||
const int snr_offset = 128;
|
|
||||||
|
|
||||||
// Default LoRa settings
|
// Default LoRa settings
|
||||||
int lora_sf = 0;
|
int lora_sf = 0;
|
||||||
@ -91,23 +74,19 @@
|
|||||||
uint8_t last_snr_raw = 0x00;
|
uint8_t last_snr_raw = 0x00;
|
||||||
size_t read_len = 0;
|
size_t read_len = 0;
|
||||||
uint8_t seq = 0xFF;
|
uint8_t seq = 0xFF;
|
||||||
|
|
||||||
|
// Incoming packet buffer
|
||||||
uint8_t pbuf[MTU];
|
uint8_t pbuf[MTU];
|
||||||
uint8_t sbuf[MTU];
|
|
||||||
|
// KISS command buffer
|
||||||
uint8_t cbuf[CMD_L];
|
uint8_t cbuf[CMD_L];
|
||||||
|
|
||||||
#if QUEUE_SIZE > 0
|
// LoRa transmit buffer
|
||||||
uint8_t tbuf[MTU];
|
uint8_t tbuf[MTU];
|
||||||
uint8_t qbuf[QUEUE_MEM];
|
|
||||||
size_t queued_lengths[QUEUE_BUF_SIZE];
|
|
||||||
#endif
|
|
||||||
|
|
||||||
uint32_t stat_rx = 0;
|
uint32_t stat_rx = 0;
|
||||||
uint32_t stat_tx = 0;
|
uint32_t stat_tx = 0;
|
||||||
|
|
||||||
bool outbound_ready = false;
|
|
||||||
size_t queue_head = 0;
|
|
||||||
size_t queue_tail = 0;
|
|
||||||
|
|
||||||
bool stat_signal_detected = false;
|
bool stat_signal_detected = false;
|
||||||
bool stat_signal_synced = false;
|
bool stat_signal_synced = false;
|
||||||
bool stat_rx_ongoing = false;
|
bool stat_rx_ongoing = false;
|
||||||
|
@ -55,9 +55,6 @@
|
|||||||
size_t frame_len;
|
size_t frame_len;
|
||||||
bool IN_FRAME = false;
|
bool IN_FRAME = false;
|
||||||
bool ESCAPE = false;
|
bool ESCAPE = false;
|
||||||
bool SERIAL_READING = false;
|
|
||||||
uint8_t command = CMD_UNKNOWN;
|
uint8_t command = CMD_UNKNOWN;
|
||||||
uint32_t last_serial_read = 0;
|
|
||||||
uint32_t serial_read_timeout_ms = 60;
|
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -2,27 +2,49 @@
|
|||||||
#include <SPI.h>
|
#include <SPI.h>
|
||||||
#include "Utilities.h"
|
#include "Utilities.h"
|
||||||
|
|
||||||
|
FIFOBuffer serialFIFO;
|
||||||
|
uint8_t serialBuffer[CONFIG_UART_BUFFER_SIZE];
|
||||||
|
|
||||||
|
FIFOBuffer16 packet_starts;
|
||||||
|
size_t packet_starts_buf[CONFIG_QUEUE_MAX_LENGTH+1];
|
||||||
|
|
||||||
|
FIFOBuffer16 packet_lengths;
|
||||||
|
size_t packet_lengths_buf[CONFIG_QUEUE_MAX_LENGTH+1];
|
||||||
|
|
||||||
|
uint8_t packet_queue[CONFIG_QUEUE_SIZE];
|
||||||
|
|
||||||
|
volatile uint8_t queue_height = 0;
|
||||||
|
volatile size_t queued_bytes = 0;
|
||||||
|
volatile size_t queue_cursor = 0;
|
||||||
|
volatile size_t current_packet_start = 0;
|
||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
// Seed the PRNG
|
// Seed the PRNG
|
||||||
randomSeed(analogRead(0));
|
randomSeed(analogRead(0));
|
||||||
|
|
||||||
// Initialise serial communication
|
// Initialise serial communication
|
||||||
|
memset(serialBuffer, 0, sizeof(serialBuffer));
|
||||||
|
fifo_init(&serialFIFO, serialBuffer, sizeof(serialBuffer));
|
||||||
|
|
||||||
Serial.begin(serial_baudrate);
|
Serial.begin(serial_baudrate);
|
||||||
while (!Serial);
|
while (!Serial);
|
||||||
|
|
||||||
|
serial_timer_init();
|
||||||
|
|
||||||
// Configure input and output pins
|
// Configure input and output pins
|
||||||
pinMode(pin_led_rx, OUTPUT);
|
pinMode(pin_led_rx, OUTPUT);
|
||||||
pinMode(pin_led_tx, OUTPUT);
|
pinMode(pin_led_tx, OUTPUT);
|
||||||
|
|
||||||
// Initialise buffers
|
// Initialise buffers
|
||||||
memset(pbuf, 0, sizeof(pbuf));
|
memset(pbuf, 0, sizeof(pbuf));
|
||||||
memset(sbuf, 0, sizeof(sbuf));
|
|
||||||
memset(cbuf, 0, sizeof(cbuf));
|
memset(cbuf, 0, sizeof(cbuf));
|
||||||
|
|
||||||
#if QUEUE_SIZE > 0
|
memset(packet_queue, 0, sizeof(packet_queue));
|
||||||
memset(qbuf, 0, sizeof(qbuf));
|
memset(packet_starts_buf, 0, sizeof(packet_starts));
|
||||||
memset(queued_lengths, 0, sizeof(queued_lengths));
|
memset(packet_lengths_buf, 0, sizeof(packet_lengths));
|
||||||
#endif
|
|
||||||
|
fifo16_init(&packet_starts, packet_starts_buf, sizeof(packet_starts_buf));
|
||||||
|
fifo16_init(&packet_lengths, packet_lengths_buf, sizeof(packet_lengths_buf));
|
||||||
|
|
||||||
// Set chip select, reset and interrupt
|
// Set chip select, reset and interrupt
|
||||||
// pins for the LoRa module
|
// pins for the LoRa module
|
||||||
@ -188,67 +210,38 @@ void receiveCallback(int packet_size) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool outboundReady() {
|
|
||||||
#if QUEUE_SIZE > 0
|
|
||||||
if (queue_head != queue_tail) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
return outbound_ready;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
bool queueFull() {
|
bool queueFull() {
|
||||||
size_t new_queue_head = (queue_head+1)%QUEUE_BUF_SIZE;
|
return (queue_height < CONFIG_QUEUE_MAX_LENGTH && queued_bytes < CONFIG_QUEUE_SIZE);
|
||||||
if (new_queue_head == queue_tail) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void enqueuePacket(size_t length) {
|
volatile bool queue_flushing = false;
|
||||||
size_t new_queue_head = (queue_head+1)%QUEUE_BUF_SIZE;
|
void flushQueue(void) {
|
||||||
if (new_queue_head != queue_tail) {
|
if (!queue_flushing) {
|
||||||
queued_lengths[queue_head] = length;
|
queue_flushing = true;
|
||||||
size_t insert_addr = queue_head * MTU;
|
|
||||||
for (int i = 0; i < length; i++) {
|
size_t processed = 0;
|
||||||
qbuf[insert_addr+i] = sbuf[i];
|
for (size_t n = 0; n < queue_height; n++) {
|
||||||
|
size_t start = fifo16_pop_locked(&packet_starts);
|
||||||
|
size_t length = fifo16_pop_locked(&packet_lengths);
|
||||||
|
|
||||||
|
if (length >= MIN_L) {
|
||||||
|
for (size_t i = 0; i < length; i++) {
|
||||||
|
size_t pos = (start+i)%CONFIG_QUEUE_SIZE;
|
||||||
|
tbuf[i] = packet_queue[pos];
|
||||||
|
}
|
||||||
|
|
||||||
|
transmit(length);
|
||||||
|
processed++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
queue_head = new_queue_head;
|
|
||||||
if (!queueFull()) {
|
|
||||||
kiss_indicate_ready();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
kiss_indicate_error(ERROR_QUEUE_FULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
queue_height = 0;
|
||||||
|
queued_bytes = 0;
|
||||||
|
queue_flushing = false;
|
||||||
|
kiss_indicate_ready();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if QUEUE_SIZE > 0
|
|
||||||
void processQueue() {
|
|
||||||
size_t fetch_address = queue_tail*MTU;
|
|
||||||
size_t fetch_length = queued_lengths[queue_tail];
|
|
||||||
|
|
||||||
for (int i = 0; i < fetch_length; i++) {
|
|
||||||
tbuf[i] = qbuf[fetch_address+i];
|
|
||||||
qbuf[fetch_address+i] = 0x00;
|
|
||||||
}
|
|
||||||
|
|
||||||
queued_lengths[queue_tail] = 0;
|
|
||||||
|
|
||||||
queue_tail = ++queue_tail%QUEUE_BUF_SIZE;
|
|
||||||
|
|
||||||
transmit(fetch_length);
|
|
||||||
|
|
||||||
if (!queueFull()) {
|
|
||||||
kiss_indicate_ready();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void transmit(size_t size) {
|
void transmit(size_t size) {
|
||||||
if (radio_online) {
|
if (radio_online) {
|
||||||
if (!promisc) {
|
if (!promisc) {
|
||||||
@ -264,11 +257,7 @@ void transmit(size_t size) {
|
|||||||
LoRa.write(header); written++;
|
LoRa.write(header); written++;
|
||||||
|
|
||||||
for (size_t i; i < size; i++) {
|
for (size_t i; i < size; i++) {
|
||||||
#if QUEUE_SIZE > 0
|
LoRa.write(tbuf[i]);
|
||||||
LoRa.write(tbuf[i]);
|
|
||||||
#else
|
|
||||||
LoRa.write(sbuf[i]);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
written++;
|
written++;
|
||||||
|
|
||||||
@ -298,11 +287,7 @@ void transmit(size_t size) {
|
|||||||
|
|
||||||
LoRa.beginPacket();
|
LoRa.beginPacket();
|
||||||
for (size_t i; i < size; i++) {
|
for (size_t i; i < size; i++) {
|
||||||
#if QUEUE_SIZE > 0
|
LoRa.write(tbuf[i]);
|
||||||
LoRa.write(tbuf[i]);
|
|
||||||
#else
|
|
||||||
LoRa.write(sbuf[i]);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
written++;
|
written++;
|
||||||
}
|
}
|
||||||
@ -315,26 +300,35 @@ void transmit(size_t size) {
|
|||||||
kiss_indicate_error(ERROR_TXFAILED);
|
kiss_indicate_error(ERROR_TXFAILED);
|
||||||
led_indicate_error(5);
|
led_indicate_error(5);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if QUEUE_SIZE == 0
|
|
||||||
if (FLOW_CONTROL_ENABLED)
|
|
||||||
kiss_indicate_ready();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void serialCallback(uint8_t sbyte) {
|
void serialCallback(uint8_t sbyte) {
|
||||||
if (IN_FRAME && sbyte == FEND && command == CMD_DATA) {
|
if (IN_FRAME && sbyte == FEND && command == CMD_DATA) {
|
||||||
IN_FRAME = false;
|
IN_FRAME = false;
|
||||||
|
|
||||||
if (QUEUE_SIZE == 0) {
|
if (queue_height < CONFIG_QUEUE_MAX_LENGTH && queued_bytes < CONFIG_QUEUE_SIZE) {
|
||||||
if (outbound_ready) {
|
size_t s = current_packet_start;
|
||||||
kiss_indicate_error(ERROR_QUEUE_FULL);
|
size_t e = queue_cursor-1; if (e == -1) e = CONFIG_QUEUE_SIZE-1;
|
||||||
} else {
|
size_t l;
|
||||||
outbound_ready = true;
|
|
||||||
}
|
if (s != e) {
|
||||||
} else {
|
l = (s < e) ? e - s + 1 : CONFIG_QUEUE_SIZE - s + e + 1;
|
||||||
enqueuePacket(frame_len);
|
} else {
|
||||||
|
l = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (l >= MIN_L) {
|
||||||
|
queue_height++;
|
||||||
|
|
||||||
|
fifo16_push_locked(&packet_starts, s);
|
||||||
|
fifo16_push_locked(&packet_lengths, l);
|
||||||
|
|
||||||
|
current_packet_start = queue_cursor;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!queueFull()) kiss_indicate_ready();
|
||||||
|
|
||||||
} else if (sbyte == FEND) {
|
} else if (sbyte == FEND) {
|
||||||
IN_FRAME = true;
|
IN_FRAME = true;
|
||||||
command = CMD_UNKNOWN;
|
command = CMD_UNKNOWN;
|
||||||
@ -352,7 +346,11 @@ void serialCallback(uint8_t sbyte) {
|
|||||||
if (sbyte == TFESC) sbyte = FESC;
|
if (sbyte == TFESC) sbyte = FESC;
|
||||||
ESCAPE = false;
|
ESCAPE = false;
|
||||||
}
|
}
|
||||||
sbuf[frame_len++] = sbyte;
|
if (queue_height < CONFIG_QUEUE_MAX_LENGTH && queued_bytes < CONFIG_QUEUE_SIZE) {
|
||||||
|
queued_bytes++;
|
||||||
|
packet_queue[queue_cursor++] = sbyte;
|
||||||
|
if (queue_cursor == CONFIG_QUEUE_SIZE) queue_cursor = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (command == CMD_FREQUENCY) {
|
} else if (command == CMD_FREQUENCY) {
|
||||||
if (sbyte == FESC) {
|
if (sbyte == FESC) {
|
||||||
@ -566,19 +564,20 @@ void validateStatus() {
|
|||||||
void loop() {
|
void loop() {
|
||||||
if (radio_online) {
|
if (radio_online) {
|
||||||
checkModemStatus();
|
checkModemStatus();
|
||||||
if (outboundReady() && !SERIAL_READING) {
|
|
||||||
|
if (queue_height > 0) {
|
||||||
if (!dcd_waiting) updateModemStatus();
|
if (!dcd_waiting) updateModemStatus();
|
||||||
|
|
||||||
if (!dcd && !dcd_led) {
|
if (!dcd && !dcd_led) {
|
||||||
if (dcd_waiting) delay(lora_rx_turnaround_ms);
|
if (dcd_waiting) delay(lora_rx_turnaround_ms);
|
||||||
|
|
||||||
updateModemStatus();
|
updateModemStatus();
|
||||||
|
|
||||||
if (!dcd) {
|
if (!dcd) {
|
||||||
dcd_waiting = false;
|
dcd_waiting = false;
|
||||||
#if QUEUE_SIZE > 0
|
|
||||||
processQueue();
|
flushQueue();
|
||||||
#else
|
|
||||||
outbound_ready = false;
|
|
||||||
transmit(frame_len);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
dcd_waiting = true;
|
dcd_waiting = true;
|
||||||
@ -594,14 +593,36 @@ void loop() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Serial.available()) {
|
serial_poll();
|
||||||
SERIAL_READING = true;
|
}
|
||||||
char sbyte = Serial.read();
|
|
||||||
|
void serial_poll() {
|
||||||
|
while (!fifo_isempty_locked(&serialFIFO)) {
|
||||||
|
char sbyte = fifo_pop_locked(&serialFIFO);
|
||||||
serialCallback(sbyte);
|
serialCallback(sbyte);
|
||||||
last_serial_read = millis();
|
}
|
||||||
} else {
|
}
|
||||||
if (SERIAL_READING && millis()-last_serial_read >= serial_read_timeout_ms) {
|
|
||||||
SERIAL_READING = false;
|
void buffer_serial() {
|
||||||
|
while (Serial.available()) {
|
||||||
|
char c = Serial.read();
|
||||||
|
if (!fifo_isfull_locked(&serialFIFO)) {
|
||||||
|
fifo_push_locked(&serialFIFO, c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void serial_timer_init() {
|
||||||
|
TCCR3A = 0;
|
||||||
|
TCCR3B = _BV(CS10) |
|
||||||
|
_BV(WGM33)|
|
||||||
|
_BV(WGM32);
|
||||||
|
|
||||||
|
ICR3 = 23704; // Approximation of 16Mhz / 675
|
||||||
|
|
||||||
|
TIMSK3 = _BV(ICIE3);
|
||||||
|
}
|
||||||
|
|
||||||
|
ISR(TIMER3_CAPT_vect) {
|
||||||
|
buffer_serial();
|
||||||
|
}
|
159
Utilities.h
159
Utilities.h
@ -1,4 +1,6 @@
|
|||||||
#include <EEPROM.h>
|
#include <EEPROM.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <util/atomic.h>
|
||||||
#include "LoRa.h"
|
#include "LoRa.h"
|
||||||
#include "ROM.h"
|
#include "ROM.h"
|
||||||
#include "Config.h"
|
#include "Config.h"
|
||||||
@ -468,3 +470,160 @@ void unlock_rom() {
|
|||||||
led_indicate_error(50);
|
led_indicate_error(50);
|
||||||
eeprom_erase();
|
eeprom_erase();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct FIFOBuffer
|
||||||
|
{
|
||||||
|
unsigned char *begin;
|
||||||
|
unsigned char *end;
|
||||||
|
unsigned char * volatile head;
|
||||||
|
unsigned char * volatile tail;
|
||||||
|
} FIFOBuffer;
|
||||||
|
|
||||||
|
inline bool fifo_isempty(const FIFOBuffer *f) {
|
||||||
|
return f->head == f->tail;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool fifo_isfull(const FIFOBuffer *f) {
|
||||||
|
return ((f->head == f->begin) && (f->tail == f->end)) || (f->tail == f->head - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void fifo_push(FIFOBuffer *f, unsigned char c) {
|
||||||
|
*(f->tail) = c;
|
||||||
|
|
||||||
|
if (f->tail == f->end) {
|
||||||
|
f->tail = f->begin;
|
||||||
|
} else {
|
||||||
|
f->tail++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline unsigned char fifo_pop(FIFOBuffer *f) {
|
||||||
|
if(f->head == f->end) {
|
||||||
|
f->head = f->begin;
|
||||||
|
return *(f->end);
|
||||||
|
} else {
|
||||||
|
return *(f->head++);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void fifo_flush(FIFOBuffer *f) {
|
||||||
|
f->head = f->tail;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool fifo_isempty_locked(const FIFOBuffer *f) {
|
||||||
|
bool result;
|
||||||
|
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
|
||||||
|
result = fifo_isempty(f);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool fifo_isfull_locked(const FIFOBuffer *f) {
|
||||||
|
bool result;
|
||||||
|
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
|
||||||
|
result = fifo_isfull(f);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void fifo_push_locked(FIFOBuffer *f, unsigned char c) {
|
||||||
|
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
|
||||||
|
fifo_push(f, c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline unsigned char fifo_pop_locked(FIFOBuffer *f) {
|
||||||
|
unsigned char c;
|
||||||
|
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
|
||||||
|
c = fifo_pop(f);
|
||||||
|
}
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void fifo_init(FIFOBuffer *f, unsigned char *buffer, size_t size) {
|
||||||
|
f->head = f->tail = f->begin = buffer;
|
||||||
|
f->end = buffer + size -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline size_t fifo_len(FIFOBuffer *f) {
|
||||||
|
return f->end - f->begin;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct FIFOBuffer16
|
||||||
|
{
|
||||||
|
size_t *begin;
|
||||||
|
size_t *end;
|
||||||
|
size_t * volatile head;
|
||||||
|
size_t * volatile tail;
|
||||||
|
} FIFOBuffer16;
|
||||||
|
|
||||||
|
inline bool fifo16_isempty(const FIFOBuffer16 *f) {
|
||||||
|
return f->head == f->tail;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool fifo16_isfull(const FIFOBuffer16 *f) {
|
||||||
|
return ((f->head == f->begin) && (f->tail == f->end)) || (f->tail == f->head - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void fifo16_push(FIFOBuffer16 *f, size_t c) {
|
||||||
|
*(f->tail) = c;
|
||||||
|
|
||||||
|
if (f->tail == f->end) {
|
||||||
|
f->tail = f->begin;
|
||||||
|
} else {
|
||||||
|
f->tail++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline size_t fifo16_pop(FIFOBuffer16 *f) {
|
||||||
|
if(f->head == f->end) {
|
||||||
|
f->head = f->begin;
|
||||||
|
return *(f->end);
|
||||||
|
} else {
|
||||||
|
return *(f->head++);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void fifo16_flush(FIFOBuffer16 *f) {
|
||||||
|
f->head = f->tail;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool fifo16_isempty_locked(const FIFOBuffer16 *f) {
|
||||||
|
bool result;
|
||||||
|
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
|
||||||
|
result = fifo16_isempty(f);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool fifo16_isfull_locked(const FIFOBuffer16 *f) {
|
||||||
|
bool result;
|
||||||
|
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
|
||||||
|
result = fifo16_isfull(f);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void fifo16_push_locked(FIFOBuffer16 *f, size_t c) {
|
||||||
|
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
|
||||||
|
fifo16_push(f, c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline size_t fifo16_pop_locked(FIFOBuffer16 *f) {
|
||||||
|
size_t c;
|
||||||
|
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
|
||||||
|
c = fifo16_pop(f);
|
||||||
|
}
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void fifo16_init(FIFOBuffer16 *f, size_t *buffer, size_t size) {
|
||||||
|
f->head = f->tail = f->begin = buffer;
|
||||||
|
f->end = buffer + (size/sizeof(size_t)) - 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline size_t fifo16_len(FIFOBuffer16 *f) {
|
||||||
|
return ((f->end - f->begin))/sizeof(size_t);
|
||||||
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user