mirror of
https://github.com/markqvist/OpenModem.git
synced 2024-10-01 03:15:46 -04:00
Async io work
This commit is contained in:
parent
42dcd121cc
commit
06d138d66c
6
device.h
6
device.h
@ -20,11 +20,17 @@
|
|||||||
#define BAUD 115200
|
#define BAUD 115200
|
||||||
#define SERIAL_DEBUG false
|
#define SERIAL_DEBUG false
|
||||||
#define TX_MAXWAIT 2UL
|
#define TX_MAXWAIT 2UL
|
||||||
|
#define CONFIG_QUEUE_SIZE 7500
|
||||||
|
#define CONFIG_QUEUE_MAX_LENGTH 15
|
||||||
|
#define CONFIG_SERIAL_BUFFER_SIZE 1532 // TODO: Tune this, what is actually required?
|
||||||
|
|
||||||
// CSMA Settings
|
// CSMA Settings
|
||||||
#define CONFIG_FULL_DUPLEX false // TODO: Actually implement fdx
|
#define CONFIG_FULL_DUPLEX false // TODO: Actually implement fdx
|
||||||
#define CONFIG_CSMA_P 255
|
#define CONFIG_CSMA_P 255
|
||||||
|
|
||||||
|
#define AX25_MIN_FRAME_LEN 1
|
||||||
|
#define AX25_MAX_FRAME_LEN 1532
|
||||||
|
|
||||||
// Packet settings
|
// Packet settings
|
||||||
#define CONFIG_PASSALL false
|
#define CONFIG_PASSALL false
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "AFSK.h"
|
#include "AFSK.h"
|
||||||
#include "util/time.h"
|
#include "util/time.h"
|
||||||
|
#include "protocol/KISS.h"
|
||||||
|
|
||||||
// TODO: Remove testing vars ////
|
// TODO: Remove testing vars ////
|
||||||
#define SAMPLES_TO_CAPTURE 128
|
#define SAMPLES_TO_CAPTURE 128
|
||||||
@ -618,33 +619,10 @@ ISR(TIMER3_CAPT_vect) {
|
|||||||
|
|
||||||
ISR(ADC_vect) {
|
ISR(ADC_vect) {
|
||||||
TIFR1 = _BV(ICF1);
|
TIFR1 = _BV(ICF1);
|
||||||
|
|
||||||
if (CONFIG_FULL_DUPLEX || !hw_afsk_dac_isr) {
|
if (CONFIG_FULL_DUPLEX || !hw_afsk_dac_isr) {
|
||||||
AFSK_adc_isr(AFSK_modem, (ADCH - 128));
|
AFSK_adc_isr(AFSK_modem, (ADCH - 128));
|
||||||
}
|
}
|
||||||
|
|
||||||
++_clock;
|
++_clock;
|
||||||
|
|
||||||
/*
|
|
||||||
// TODO: Remove these debug sample collection functions
|
|
||||||
|
|
||||||
//DAC_PORT ^= 0xFF;
|
|
||||||
//DAC_PORT = ADCH;
|
|
||||||
|
|
||||||
if (capturedsamples == SAMPLES_TO_CAPTURE) {
|
|
||||||
printf("--- Dumping samples ---");
|
|
||||||
for (ticks_t i = 0; i < SAMPLES_TO_CAPTURE; i++) {
|
|
||||||
uint8_t c = samplebuf[i];
|
|
||||||
printf("%d\r\n", c);
|
|
||||||
}
|
|
||||||
printf("-------- Done ---------");
|
|
||||||
}
|
|
||||||
DAC_PORT ^= 0xFF;
|
|
||||||
if (capturedsamples < SAMPLES_TO_CAPTURE) {
|
|
||||||
samplebuf[capturedsamples++] = ADCH;
|
|
||||||
// Clear Input Capture Flag from Timer1 Interrupt Flag Register
|
|
||||||
// to allow for next capture interrupt to occur
|
|
||||||
TIFR1 = _BV(ICF1);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
}
|
@ -39,7 +39,7 @@ inline static uint8_t sinSample(uint16_t i) {
|
|||||||
#define CPU_FREQ F_CPU
|
#define CPU_FREQ F_CPU
|
||||||
|
|
||||||
|
|
||||||
#define BITRATE 1200
|
#define BITRATE 2400
|
||||||
|
|
||||||
#if BITRATE == 300
|
#if BITRATE == 300
|
||||||
#define CONFIG_ADC_SAMPLERATE 9600UL
|
#define CONFIG_ADC_SAMPLERATE 9600UL
|
||||||
@ -53,8 +53,8 @@ inline static uint8_t sinSample(uint16_t i) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#define CONFIG_AFSK_RX_BUFLEN CONFIG_ADC_SAMPLERATE/75
|
#define CONFIG_AFSK_RX_BUFLEN AX25_MAX_FRAME_LEN
|
||||||
#define CONFIG_AFSK_TX_BUFLEN CONFIG_ADC_SAMPLERATE/75
|
#define CONFIG_AFSK_TX_BUFLEN AX25_MAX_FRAME_LEN
|
||||||
#define CONFIG_AFSK_RXTIMEOUT 0
|
#define CONFIG_AFSK_RXTIMEOUT 0
|
||||||
|
|
||||||
#define CONFIG_AFSK_PREAMBLE_LEN 150UL
|
#define CONFIG_AFSK_PREAMBLE_LEN 150UL
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
|
|
||||||
void serial_init(Serial *serial) {
|
void serial_init(Serial *serial) {
|
||||||
memset(serial, 0, sizeof(*serial));
|
memset(serial, 0, sizeof(*serial));
|
||||||
|
memset(serialBuf, 0, sizeof(serialBuf));
|
||||||
|
|
||||||
UBRR0H = UBRRH_VALUE;
|
UBRR0H = UBRRH_VALUE;
|
||||||
UBRR0L = UBRRL_VALUE;
|
UBRR0L = UBRRL_VALUE;
|
||||||
|
|
||||||
@ -14,13 +16,15 @@ void serial_init(Serial *serial) {
|
|||||||
UCSR0A &= ~(_BV(U2X0));
|
UCSR0A &= ~(_BV(U2X0));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Set to 8-bit data, enable RX and TX
|
// Set to 8-bit data, enable RX and TX, enable receive interrupt
|
||||||
UCSR0C = _BV(UCSZ01) | _BV(UCSZ00);
|
UCSR0C = _BV(UCSZ01) | _BV(UCSZ00);
|
||||||
UCSR0B = _BV(RXEN0) | _BV(TXEN0);
|
UCSR0B = _BV(RXEN0) | _BV(TXEN0) | _BV(RXCIE0);
|
||||||
|
|
||||||
FILE uart0_fd = FDEV_SETUP_STREAM(uart0_putchar, uart0_getchar, _FDEV_SETUP_RW);
|
FILE uart0_fd = FDEV_SETUP_STREAM(uart0_putchar, uart0_getchar, _FDEV_SETUP_RW);
|
||||||
|
|
||||||
serial->uart0 = uart0_fd;
|
serial->uart0 = uart0_fd;
|
||||||
|
|
||||||
|
fifo_init(&serialFIFO, serialBuf, sizeof(serialBuf));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool serial_available(uint8_t index) {
|
bool serial_available(uint8_t index) {
|
||||||
@ -45,4 +49,11 @@ int uart0_getchar(FILE *stream) {
|
|||||||
char uart0_getchar_nowait(void) {
|
char uart0_getchar_nowait(void) {
|
||||||
if (!(UCSR0A & _BV(RXC0))) return EOF;
|
if (!(UCSR0A & _BV(RXC0))) return EOF;
|
||||||
return UDR0;
|
return UDR0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ISR(USART0_RX_vect) {
|
||||||
|
if (serial_available(0)) {
|
||||||
|
char c = uart0_getchar_nowait();
|
||||||
|
fifo_push(&serialFIFO, c);
|
||||||
|
}
|
||||||
}
|
}
|
@ -6,11 +6,15 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <avr/io.h>
|
#include <avr/io.h>
|
||||||
|
#include "util/FIFO.h"
|
||||||
|
|
||||||
typedef struct Serial {
|
typedef struct Serial {
|
||||||
FILE uart0;
|
FILE uart0;
|
||||||
} Serial;
|
} Serial;
|
||||||
|
|
||||||
|
FIFOBuffer serialFIFO;
|
||||||
|
uint8_t serialBuf[CONFIG_SERIAL_BUFFER_SIZE];
|
||||||
|
|
||||||
void serial_init(Serial *serial);
|
void serial_init(Serial *serial);
|
||||||
bool serial_available(uint8_t index);
|
bool serial_available(uint8_t index);
|
||||||
int uart0_putchar(char c, FILE *stream);
|
int uart0_putchar(char c, FILE *stream);
|
||||||
|
7
main.c
7
main.c
@ -38,11 +38,8 @@ int main (void) {
|
|||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
ax25_poll(&AX25);
|
ax25_poll(&AX25);
|
||||||
|
kiss_poll();
|
||||||
if (serial_available(0)) {
|
kiss_csma();
|
||||||
char sbyte = uart0_getchar_nowait();
|
|
||||||
kiss_serialCallback(sbyte);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return(0);
|
return(0);
|
||||||
|
@ -5,7 +5,8 @@
|
|||||||
#include "AX25.h"
|
#include "AX25.h"
|
||||||
#include "protocol/HDLC.h"
|
#include "protocol/HDLC.h"
|
||||||
#include "util/CRC-CCIT.h"
|
#include "util/CRC-CCIT.h"
|
||||||
#include "../hardware/AFSK.h"
|
#include "hardware/AFSK.h"
|
||||||
|
#include "protocol/KISS.h"
|
||||||
|
|
||||||
#define countof(a) sizeof(a)/sizeof(a[0])
|
#define countof(a) sizeof(a)/sizeof(a[0])
|
||||||
#define MIN(a,b) ({ typeof(a) _a = (a); typeof(b) _b = (b); ((typeof(_a))((_a < _b) ? _a : _b)); })
|
#define MIN(a,b) ({ typeof(a) _a = (a); typeof(b) _b = (b); ((typeof(_a))((_a < _b) ? _a : _b)); })
|
||||||
@ -76,7 +77,10 @@ void ax25_sendRaw(AX25Ctx *ctx, void *_buf, size_t len) {
|
|||||||
ctx->crc_out = CRC_CCIT_INIT_VAL;
|
ctx->crc_out = CRC_CCIT_INIT_VAL;
|
||||||
fputc(HDLC_FLAG, ctx->ch);
|
fputc(HDLC_FLAG, ctx->ch);
|
||||||
const uint8_t *buf = (const uint8_t *)_buf;
|
const uint8_t *buf = (const uint8_t *)_buf;
|
||||||
while (len--) ax25_putchar(ctx, *buf++);
|
while (len--) {
|
||||||
|
ax25_putchar(ctx, *buf++);
|
||||||
|
kiss_poll();
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t crcl = (ctx->crc_out & 0xff) ^ 0xff;
|
uint8_t crcl = (ctx->crc_out & 0xff) ^ 0xff;
|
||||||
uint8_t crch = (ctx->crc_out >> 8) ^ 0xff;
|
uint8_t crch = (ctx->crc_out >> 8) ^ 0xff;
|
||||||
|
@ -6,10 +6,6 @@
|
|||||||
#include "device.h"
|
#include "device.h"
|
||||||
#include "hardware/AFSK.h"
|
#include "hardware/AFSK.h"
|
||||||
|
|
||||||
#define AX25_MIN_FRAME_LEN 1
|
|
||||||
#define AX25_MAX_FRAME_LEN 1532
|
|
||||||
|
|
||||||
|
|
||||||
#define AX25_CRC_CORRECT 0xF0B8
|
#define AX25_CRC_CORRECT 0xF0B8
|
||||||
|
|
||||||
#define AX25_CTRL_UI 0x03
|
#define AX25_CTRL_UI 0x03
|
||||||
|
171
protocol/KISS.c
171
protocol/KISS.c
@ -2,16 +2,29 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "device.h"
|
#include "device.h"
|
||||||
|
#include "hardware/Serial.h"
|
||||||
|
#include "util/FIFO16.h"
|
||||||
#include "KISS.h"
|
#include "KISS.h"
|
||||||
|
|
||||||
static uint8_t serialBuffer[AX25_MAX_FRAME_LEN]; // Buffer for holding incoming serial data
|
uint8_t packet_queue[CONFIG_QUEUE_SIZE];
|
||||||
|
uint8_t tx_buffer[AX25_MAX_FRAME_LEN];
|
||||||
|
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;
|
||||||
|
|
||||||
|
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];
|
||||||
|
|
||||||
AX25Ctx *ax25ctx;
|
AX25Ctx *ax25ctx;
|
||||||
Afsk *channel;
|
Afsk *channel;
|
||||||
Serial *serial;
|
Serial *serial;
|
||||||
size_t frame_len;
|
size_t frame_len;
|
||||||
bool IN_FRAME;
|
bool IN_FRAME;
|
||||||
bool ESCAPE;
|
bool ESCAPE;
|
||||||
bool FLOWCONTROL;
|
|
||||||
|
|
||||||
uint8_t command = CMD_UNKNOWN;
|
uint8_t command = CMD_UNKNOWN;
|
||||||
unsigned long custom_preamble = CONFIG_AFSK_PREAMBLE_LEN;
|
unsigned long custom_preamble = CONFIG_AFSK_PREAMBLE_LEN;
|
||||||
@ -24,7 +37,20 @@ void kiss_init(AX25Ctx *ax25, Afsk *afsk, Serial *ser) {
|
|||||||
ax25ctx = ax25;
|
ax25ctx = ax25;
|
||||||
serial = ser;
|
serial = ser;
|
||||||
channel = afsk;
|
channel = afsk;
|
||||||
FLOWCONTROL = false;
|
|
||||||
|
memset(packet_queue, 0, sizeof(packet_queue));
|
||||||
|
memset(packet_starts_buf, 0, sizeof(packet_starts));
|
||||||
|
memset(packet_lengths_buf, 0, sizeof(packet_lengths));
|
||||||
|
|
||||||
|
fifo16_init(&packet_starts, packet_starts_buf, sizeof(packet_starts_buf));
|
||||||
|
fifo16_init(&packet_lengths, packet_lengths_buf, sizeof(packet_lengths_buf));
|
||||||
|
}
|
||||||
|
|
||||||
|
void kiss_poll(void) {
|
||||||
|
while (!fifo_isempty_locked(&serialFIFO)) {
|
||||||
|
char sbyte = fifo_pop_locked(&serialFIFO);
|
||||||
|
kiss_serialCallback(sbyte);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Remove debug functions
|
// TODO: Remove debug functions
|
||||||
@ -51,60 +77,95 @@ void kiss_messageCallback(AX25Ctx *ctx) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void kiss_csma(AX25Ctx *ctx, uint8_t *buf, size_t len) {
|
void kiss_csma(void) {
|
||||||
bool sent = false;
|
if (queue_height > 0) {
|
||||||
// TODO: Determine if this is to be removed
|
if (!channel->hdlc.dcd) {
|
||||||
// if (CONFIG_AFSK_TXWAIT > 0) {
|
if (p == 255) {
|
||||||
// ticks_t wait_start = timer_clock();
|
kiss_flushQueue();
|
||||||
// long wait_ticks = ms_to_ticks(CONFIG_AFSK_TXWAIT);
|
|
||||||
// while (timer_clock() - wait_start < wait_ticks) {
|
|
||||||
// cpu_relax();
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
while (!sent) {
|
|
||||||
if(CONFIG_FULL_DUPLEX || !channel->hdlc.dcd) {
|
|
||||||
uint8_t tp = rand() & 0xFF;
|
|
||||||
if (tp < p) {
|
|
||||||
ax25_sendRaw(ctx, buf, len);
|
|
||||||
sent = true;
|
|
||||||
} else {
|
} else {
|
||||||
ticks_t start = timer_clock();
|
// TODO: Implement real CSMA
|
||||||
long slot_ticks = ms_to_ticks(slotTime);
|
|
||||||
while (timer_clock() - start < slot_ticks) {
|
|
||||||
cpu_relax();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
while (!sent && channel->hdlc.receiving) {
|
|
||||||
// Continously poll the modem for data
|
|
||||||
// while waiting, so we don't overrun
|
|
||||||
// receive buffers
|
|
||||||
ax25_poll(ax25ctx);
|
|
||||||
|
|
||||||
if (channel->status != 0) {
|
|
||||||
// If an overflow or other error
|
|
||||||
// occurs, we'll back off and drop
|
|
||||||
// this packet silently.
|
|
||||||
channel->status = 0;
|
|
||||||
sent = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (FLOWCONTROL) {
|
// TODO: Remove this
|
||||||
while (!ctx->ready_for_data) { /* Wait */ }
|
void kiss_flushQueueDebug(void) {
|
||||||
fputc(FEND, &serial->uart0);
|
printf("Queue height %d\r\n", queue_height);
|
||||||
fputc(CMD_READY, &serial->uart0);
|
for (size_t n = 0; n < queue_height; n++) {
|
||||||
fputc(0x01, &serial->uart0);
|
size_t start = fifo16_pop(&packet_starts);
|
||||||
fputc(FEND, &serial->uart0);
|
size_t length = fifo16_pop(&packet_lengths);
|
||||||
|
|
||||||
|
printf("--- Packet %d, %d bytes ---\r\n", n+1, length);
|
||||||
|
for (size_t i = 0; i < length; i++) {
|
||||||
|
size_t pos = (start+i)%CONFIG_QUEUE_SIZE;
|
||||||
|
printf("%02x", packet_queue[pos]);
|
||||||
|
}
|
||||||
|
printf("\r\n\r\n");
|
||||||
}
|
}
|
||||||
|
queue_height = 0;
|
||||||
|
queued_bytes = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
volatile bool queue_flushing = false;
|
||||||
|
void kiss_flushQueue(void) {
|
||||||
|
if (!queue_flushing) {
|
||||||
|
queue_flushing = true;
|
||||||
|
|
||||||
|
size_t processed = 0;
|
||||||
|
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);
|
||||||
|
|
||||||
|
kiss_poll();
|
||||||
|
for (size_t i = 0; i < length; i++) {
|
||||||
|
size_t pos = (start+i)%CONFIG_QUEUE_SIZE;
|
||||||
|
tx_buffer[i] = packet_queue[pos];
|
||||||
|
}
|
||||||
|
|
||||||
|
ax25_sendRaw(ax25ctx, tx_buffer, length);
|
||||||
|
processed++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (processed < queue_height) {
|
||||||
|
while (true) {
|
||||||
|
LED_TX_ON();
|
||||||
|
LED_RX_ON();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("Processed %d\r\n", processed);
|
||||||
|
|
||||||
|
queue_height = 0;
|
||||||
|
queued_bytes = 0;
|
||||||
|
queue_flushing = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t kiss_queuedPackets(void) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool kiss_queueIsFull(void) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void kiss_serialCallback(uint8_t sbyte) {
|
void kiss_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;
|
||||||
kiss_csma(ax25ctx, serialBuffer, frame_len);
|
|
||||||
|
if (queue_height < CONFIG_QUEUE_MAX_LENGTH && queued_bytes < CONFIG_QUEUE_SIZE) {
|
||||||
|
queue_height++;
|
||||||
|
size_t s = current_packet_start;
|
||||||
|
size_t e = queue_cursor-1; if (e == -1) e = CONFIG_QUEUE_SIZE-1;
|
||||||
|
size_t l = (s < e) ? e - s + 1 : CONFIG_QUEUE_SIZE - s + e + 1;
|
||||||
|
|
||||||
|
fifo16_push_locked(&packet_starts, s);
|
||||||
|
fifo16_push_locked(&packet_lengths, l);
|
||||||
|
|
||||||
|
current_packet_start = queue_cursor;
|
||||||
|
printf("Queue height %d\r\n", queue_height);
|
||||||
|
}
|
||||||
|
|
||||||
} else if (sbyte == FEND) {
|
} else if (sbyte == FEND) {
|
||||||
IN_FRAME = true;
|
IN_FRAME = true;
|
||||||
command = CMD_UNKNOWN;
|
command = CMD_UNKNOWN;
|
||||||
@ -116,6 +177,7 @@ void kiss_serialCallback(uint8_t sbyte) {
|
|||||||
// strip off the port nibble of the command byte
|
// strip off the port nibble of the command byte
|
||||||
sbyte = sbyte & 0x0F;
|
sbyte = sbyte & 0x0F;
|
||||||
command = sbyte;
|
command = sbyte;
|
||||||
|
if (command == CMD_DATA) current_packet_start = queue_cursor;
|
||||||
} else if (command == CMD_DATA) {
|
} else if (command == CMD_DATA) {
|
||||||
if (sbyte == FESC) {
|
if (sbyte == FESC) {
|
||||||
ESCAPE = true;
|
ESCAPE = true;
|
||||||
@ -125,7 +187,11 @@ void kiss_serialCallback(uint8_t sbyte) {
|
|||||||
if (sbyte == TFESC) sbyte = FESC;
|
if (sbyte == TFESC) sbyte = FESC;
|
||||||
ESCAPE = false;
|
ESCAPE = false;
|
||||||
}
|
}
|
||||||
serialBuffer[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_TXDELAY) {
|
} else if (command == CMD_TXDELAY) {
|
||||||
custom_preamble = sbyte * 10UL;
|
custom_preamble = sbyte * 10UL;
|
||||||
@ -135,12 +201,11 @@ void kiss_serialCallback(uint8_t sbyte) {
|
|||||||
slotTime = sbyte * 10;
|
slotTime = sbyte * 10;
|
||||||
} else if (command == CMD_P) {
|
} else if (command == CMD_P) {
|
||||||
p = sbyte;
|
p = sbyte;
|
||||||
} else if (command == CMD_READY) {
|
} else if (command == CMD_FLUSHQUEUE) {
|
||||||
if (sbyte == 0x00) {
|
kiss_flushQueue();
|
||||||
FLOWCONTROL = false;
|
// TODO: Remove this
|
||||||
} else {
|
} else if (command == CMD_FLUSHQUEUE_DEBUG) {
|
||||||
FLOWCONTROL = true;
|
kiss_flushQueueDebug();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -19,12 +19,16 @@
|
|||||||
#define CMD_TXTAIL 0x04
|
#define CMD_TXTAIL 0x04
|
||||||
#define CMD_FULLDUPLEX 0x05
|
#define CMD_FULLDUPLEX 0x05
|
||||||
#define CMD_SETHARDWARE 0x06
|
#define CMD_SETHARDWARE 0x06
|
||||||
|
#define CMD_FLUSHQUEUE 0x07
|
||||||
|
#define CMD_FLUSHQUEUE_DEBUG 0x08
|
||||||
#define CMD_READY 0x0F
|
#define CMD_READY 0x0F
|
||||||
#define CMD_RETURN 0xFF
|
#define CMD_RETURN 0xFF
|
||||||
|
|
||||||
void kiss_init(AX25Ctx *ax25, Afsk *afsk, Serial *ser);
|
void kiss_init(AX25Ctx *ax25, Afsk *afsk, Serial *ser);
|
||||||
void kiss_csma(AX25Ctx *ctx, uint8_t *buf, size_t len);
|
|
||||||
void kiss_messageCallback(AX25Ctx *ctx);
|
void kiss_messageCallback(AX25Ctx *ctx);
|
||||||
void kiss_serialCallback(uint8_t sbyte);
|
void kiss_serialCallback(uint8_t sbyte);
|
||||||
|
void kiss_flushQueue(void);
|
||||||
|
void kiss_csma(void);
|
||||||
|
void kiss_poll(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
87
util/FIFO16.h
Normal file
87
util/FIFO16.h
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
#ifndef UTIL_FIFO16_H
|
||||||
|
#define UTIL_FIFO16_H
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <util/atomic.h>
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue
Block a user