Asynchronous IO implemented, packet queueing implemented
This commit is contained in:
parent
06d138d66c
commit
c22123b953
1
device.h
1
device.h
|
@ -23,6 +23,7 @@
|
||||||
#define CONFIG_QUEUE_SIZE 7500
|
#define CONFIG_QUEUE_SIZE 7500
|
||||||
#define CONFIG_QUEUE_MAX_LENGTH 15
|
#define CONFIG_QUEUE_MAX_LENGTH 15
|
||||||
#define CONFIG_SERIAL_BUFFER_SIZE 1532 // TODO: Tune this, what is actually required?
|
#define CONFIG_SERIAL_BUFFER_SIZE 1532 // TODO: Tune this, what is actually required?
|
||||||
|
#define CONFIG_SERIAL_TIMEOUT_MS 10
|
||||||
|
|
||||||
// CSMA Settings
|
// CSMA Settings
|
||||||
#define CONFIG_FULL_DUPLEX false // TODO: Actually implement fdx
|
#define CONFIG_FULL_DUPLEX false // TODO: Actually implement fdx
|
||||||
|
|
|
@ -149,14 +149,6 @@ int afsk_getchar(FILE *stream) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AFSK_transmit(char *buffer, size_t size) {
|
|
||||||
fifo_flush(&AFSK_modem->txFifo);
|
|
||||||
int i = 0;
|
|
||||||
while (size--) {
|
|
||||||
afsk_putchar(buffer[i++], NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t AFSK_dac_isr(Afsk *afsk) {
|
uint8_t AFSK_dac_isr(Afsk *afsk) {
|
||||||
if (afsk->sampleIndex == 0) {
|
if (afsk->sampleIndex == 0) {
|
||||||
if (afsk->txBit == 0) {
|
if (afsk->txBit == 0) {
|
||||||
|
|
|
@ -39,7 +39,7 @@ inline static uint8_t sinSample(uint16_t i) {
|
||||||
#define CPU_FREQ F_CPU
|
#define CPU_FREQ F_CPU
|
||||||
|
|
||||||
|
|
||||||
#define BITRATE 2400
|
#define BITRATE 1200
|
||||||
|
|
||||||
#if BITRATE == 300
|
#if BITRATE == 300
|
||||||
#define CONFIG_ADC_SAMPLERATE 9600UL
|
#define CONFIG_ADC_SAMPLERATE 9600UL
|
||||||
|
@ -49,16 +49,26 @@ inline static uint8_t sinSample(uint16_t i) {
|
||||||
#define CONFIG_DAC_SAMPLERATE 19200UL
|
#define CONFIG_DAC_SAMPLERATE 19200UL
|
||||||
#elif BITRATE == 2400
|
#elif BITRATE == 2400
|
||||||
#define CONFIG_ADC_SAMPLERATE 19200UL
|
#define CONFIG_ADC_SAMPLERATE 19200UL
|
||||||
#define CONFIG_DAC_SAMPLERATE 38400UL
|
#define CONFIG_DAC_SAMPLERATE 19200UL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define CLOCK_TICKS_PER_SEC CONFIG_ADC_SAMPLERATE
|
||||||
|
|
||||||
#define CONFIG_AFSK_RX_BUFLEN AX25_MAX_FRAME_LEN
|
#define CONFIG_AFSK_RX_BUFLEN AX25_MAX_FRAME_LEN
|
||||||
#define CONFIG_AFSK_TX_BUFLEN AX25_MAX_FRAME_LEN
|
#define CONFIG_AFSK_TX_BUFLEN AX25_MAX_FRAME_LEN
|
||||||
#define CONFIG_AFSK_RXTIMEOUT 0
|
#define CONFIG_AFSK_RXTIMEOUT 0
|
||||||
|
|
||||||
|
#if BITRATE == 300
|
||||||
#define CONFIG_AFSK_PREAMBLE_LEN 150UL
|
#define CONFIG_AFSK_PREAMBLE_LEN 150UL
|
||||||
|
#define CONFIG_AFSK_TRAILER_LEN 10UL
|
||||||
|
#elif BITRATE == 1200
|
||||||
|
#define CONFIG_AFSK_PREAMBLE_LEN 150UL
|
||||||
|
#define CONFIG_AFSK_TRAILER_LEN 10UL
|
||||||
|
#elif BITRATE == 2400
|
||||||
|
#define CONFIG_AFSK_PREAMBLE_LEN 200UL
|
||||||
#define CONFIG_AFSK_TRAILER_LEN 25UL
|
#define CONFIG_AFSK_TRAILER_LEN 25UL
|
||||||
|
#endif
|
||||||
|
|
||||||
#define BIT_STUFF_LEN 5
|
#define BIT_STUFF_LEN 5
|
||||||
|
|
||||||
#define ADC_SAMPLESPERBIT (CONFIG_ADC_SAMPLERATE / BITRATE)
|
#define ADC_SAMPLESPERBIT (CONFIG_ADC_SAMPLERATE / BITRATE)
|
||||||
|
@ -230,7 +240,6 @@ typedef struct Afsk
|
||||||
void AFSK_init(Afsk *afsk);
|
void AFSK_init(Afsk *afsk);
|
||||||
void AFSK_adc_init(void);
|
void AFSK_adc_init(void);
|
||||||
void AFSK_dac_init(void);
|
void AFSK_dac_init(void);
|
||||||
void AFSK_transmit(char *buffer, size_t size);
|
|
||||||
void AFSK_poll(Afsk *afsk);
|
void AFSK_poll(Afsk *afsk);
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -65,8 +65,7 @@ void ax25_poll(AX25Ctx *ctx) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ax25_putchar(AX25Ctx *ctx, uint8_t c)
|
static void ax25_putchar(AX25Ctx *ctx, uint8_t c) {
|
||||||
{
|
|
||||||
if (c == HDLC_FLAG || c == HDLC_RESET || c == AX25_ESC) fputc(AX25_ESC, ctx->ch);
|
if (c == HDLC_FLAG || c == HDLC_RESET || c == AX25_ESC) fputc(AX25_ESC, ctx->ch);
|
||||||
ctx->crc_out = update_crc_ccit(c, ctx->crc_out);
|
ctx->crc_out = update_crc_ccit(c, ctx->crc_out);
|
||||||
fputc(c, ctx->ch);
|
fputc(c, ctx->ch);
|
||||||
|
@ -89,5 +88,12 @@ void ax25_sendRaw(AX25Ctx *ctx, void *_buf, size_t len) {
|
||||||
|
|
||||||
fputc(HDLC_FLAG, ctx->ch);
|
fputc(HDLC_FLAG, ctx->ch);
|
||||||
|
|
||||||
|
#if BITRATE == 2400
|
||||||
|
// Insert an extra sync section between long packet segments
|
||||||
|
for (uint8_t i = 0; i < 8; i++) {
|
||||||
|
fputc(HDLC_FLAG, ctx->ch);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
ctx->ready_for_data = true;
|
ctx->ready_for_data = true;
|
||||||
}
|
}
|
|
@ -4,6 +4,7 @@
|
||||||
#include "device.h"
|
#include "device.h"
|
||||||
#include "hardware/Serial.h"
|
#include "hardware/Serial.h"
|
||||||
#include "util/FIFO16.h"
|
#include "util/FIFO16.h"
|
||||||
|
#include "util/time.h"
|
||||||
#include "KISS.h"
|
#include "KISS.h"
|
||||||
|
|
||||||
uint8_t packet_queue[CONFIG_QUEUE_SIZE];
|
uint8_t packet_queue[CONFIG_QUEUE_SIZE];
|
||||||
|
@ -22,6 +23,7 @@ size_t packet_lengths_buf[CONFIG_QUEUE_MAX_LENGTH+1];
|
||||||
AX25Ctx *ax25ctx;
|
AX25Ctx *ax25ctx;
|
||||||
Afsk *channel;
|
Afsk *channel;
|
||||||
Serial *serial;
|
Serial *serial;
|
||||||
|
volatile ticks_t last_serial_read = 0;
|
||||||
size_t frame_len;
|
size_t frame_len;
|
||||||
bool IN_FRAME;
|
bool IN_FRAME;
|
||||||
bool ESCAPE;
|
bool ESCAPE;
|
||||||
|
@ -50,6 +52,7 @@ void kiss_poll(void) {
|
||||||
while (!fifo_isempty_locked(&serialFIFO)) {
|
while (!fifo_isempty_locked(&serialFIFO)) {
|
||||||
char sbyte = fifo_pop_locked(&serialFIFO);
|
char sbyte = fifo_pop_locked(&serialFIFO);
|
||||||
kiss_serialCallback(sbyte);
|
kiss_serialCallback(sbyte);
|
||||||
|
last_serial_read = timer_clock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,6 +82,18 @@ void kiss_messageCallback(AX25Ctx *ctx) {
|
||||||
|
|
||||||
void kiss_csma(void) {
|
void kiss_csma(void) {
|
||||||
if (queue_height > 0) {
|
if (queue_height > 0) {
|
||||||
|
#if BITRATE == 2400
|
||||||
|
if (!channel->hdlc.dcd) {
|
||||||
|
ticks_t timeout = last_serial_read + ms_to_ticks(CONFIG_SERIAL_TIMEOUT_MS);
|
||||||
|
if (timer_clock() > timeout) {
|
||||||
|
if (p == 255) {
|
||||||
|
kiss_flushQueue();
|
||||||
|
} else {
|
||||||
|
// TODO: Implement real CSMA
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
if (!channel->hdlc.dcd) {
|
if (!channel->hdlc.dcd) {
|
||||||
if (p == 255) {
|
if (p == 255) {
|
||||||
kiss_flushQueue();
|
kiss_flushQueue();
|
||||||
|
@ -86,6 +101,7 @@ void kiss_csma(void) {
|
||||||
// TODO: Implement real CSMA
|
// TODO: Implement real CSMA
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,7 +133,7 @@ void kiss_flushQueue(void) {
|
||||||
size_t start = fifo16_pop_locked(&packet_starts);
|
size_t start = fifo16_pop_locked(&packet_starts);
|
||||||
size_t length = fifo16_pop_locked(&packet_lengths);
|
size_t length = fifo16_pop_locked(&packet_lengths);
|
||||||
|
|
||||||
kiss_poll();
|
//kiss_poll();
|
||||||
for (size_t i = 0; i < length; i++) {
|
for (size_t i = 0; i < length; i++) {
|
||||||
size_t pos = (start+i)%CONFIG_QUEUE_SIZE;
|
size_t pos = (start+i)%CONFIG_QUEUE_SIZE;
|
||||||
tx_buffer[i] = packet_queue[pos];
|
tx_buffer[i] = packet_queue[pos];
|
||||||
|
@ -133,7 +149,7 @@ void kiss_flushQueue(void) {
|
||||||
LED_RX_ON();
|
LED_RX_ON();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
printf("Processed %d\r\n", processed);
|
//printf("Processed %d\r\n", processed);
|
||||||
|
|
||||||
queue_height = 0;
|
queue_height = 0;
|
||||||
queued_bytes = 0;
|
queued_bytes = 0;
|
||||||
|
@ -163,7 +179,7 @@ void kiss_serialCallback(uint8_t sbyte) {
|
||||||
fifo16_push_locked(&packet_lengths, l);
|
fifo16_push_locked(&packet_lengths, l);
|
||||||
|
|
||||||
current_packet_start = queue_cursor;
|
current_packet_start = queue_cursor;
|
||||||
printf("Queue height %d\r\n", queue_height);
|
//printf("Queue height %d\r\n", queue_height);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (sbyte == FEND) {
|
} else if (sbyte == FEND) {
|
||||||
|
|
|
@ -2,9 +2,9 @@
|
||||||
#define UTIL_TIME_H
|
#define UTIL_TIME_H
|
||||||
|
|
||||||
#include <util/atomic.h>
|
#include <util/atomic.h>
|
||||||
|
#include "hardware/AFSK.h"
|
||||||
|
|
||||||
#define DIV_ROUND(dividend, divisor) (((dividend) + (divisor) / 2) / (divisor))
|
#define DIV_ROUND(dividend, divisor) (((dividend) + (divisor) / 2) / (divisor))
|
||||||
#define CLOCK_TICKS_PER_SEC CONFIG_ADC_SAMPLERATE
|
|
||||||
|
|
||||||
typedef int32_t ticks_t;
|
typedef int32_t ticks_t;
|
||||||
typedef int32_t mtime_t;
|
typedef int32_t mtime_t;
|
||||||
|
|
Loading…
Reference in New Issue