From f960709e82854957f9ebccf15d8ea37385ac88dc Mon Sep 17 00:00:00 2001 From: Mark Qvist Date: Mon, 28 Apr 2014 17:47:32 +0200 Subject: [PATCH] TCP mode --- Modem/config.h | 4 +- Modem/hardware.c | 1 - Modem/main.c | 48 +++++++++++++++------ Modem/protocol/mp1.c | 69 ++++++++++++++++++++++-------- Modem/protocol/mp1.h | 59 ++++++++++++++++---------- bertos/cfg/cfg_dac.h | 88 --------------------------------------- bertos/cfg/cfg_random.h | 65 ----------------------------- bertos/cfg/cfg_randpool.h | 55 ------------------------ bertos/cfg/cfg_ser.h | 8 ++-- buildrev.h | 2 +- 10 files changed, 131 insertions(+), 268 deletions(-) delete mode 100644 bertos/cfg/cfg_dac.h delete mode 100644 bertos/cfg/cfg_random.h delete mode 100644 bertos/cfg/cfg_randpool.h diff --git a/Modem/config.h b/Modem/config.h index 2bdc2ca..e28b5be 100644 --- a/Modem/config.h +++ b/Modem/config.h @@ -19,7 +19,7 @@ #define CONFIG_AFSK_RXTIMEOUT 0 // How long a read operation from the modem // will wait for data before timing out. -#define CONFIG_AFSK_PREAMBLE_LEN 550UL // The length of the packet preamble in milliseconds -#define CONFIG_AFSK_TRAILER_LEN 10UL // The length of the packet tail in milliseconds +#define CONFIG_AFSK_PREAMBLE_LEN 400UL // The length of the packet preamble in milliseconds +#define CONFIG_AFSK_TRAILER_LEN 50UL // The length of the packet tail in milliseconds #endif \ No newline at end of file diff --git a/Modem/hardware.c b/Modem/hardware.c index 439ae01..1ee72e9 100644 --- a/Modem/hardware.c +++ b/Modem/hardware.c @@ -114,7 +114,6 @@ void hw_afsk_adcInit(int ch, Afsk *_modem) bool hw_ptt_on; bool hw_afsk_dac_isr; DECLARE_ISR(ADC_vect) { - TIFR1 = BV(ICF1); // Call the routine for analysing the captured sample diff --git a/Modem/main.c b/Modem/main.c index a6fa726..1fa2e39 100644 --- a/Modem/main.c +++ b/Modem/main.c @@ -4,7 +4,6 @@ ////////////////////////////////////////////////////// #include // Interrupt functionality from BertOS -#include "cfg/debug.h" // Debug configuration from BertOS #include // Serial driver from BertOS #include // Timer driver from BertOS @@ -15,6 +14,10 @@ #include "afsk.h" // Header for AFSK modem #include "protocol/mp1.h" // Header for MP.1 protocol +#if SERIAL_DEBUG + #include "cfg/debug.h" // Debug configuration from BertOS +#endif + ////////////////////////////////////////////////////// // A few definitions // @@ -34,6 +37,7 @@ static int sbyte; // For holding byte read from serial port static size_t serialLen = 0; // Counter for counting length of data from serial static bool sertx = false; // Flag signifying whether it's time to send data // Received on the serial port. +#define SER_BUFFER_FULL (serialLen < MP1_MAX_DATA_SIZE-1) ////////////////////////////////////////////////////// // And here comes the actual program :) // @@ -85,6 +89,7 @@ int main(void) init(); // Record the current tick count for time-keeping ticks_t start = timer_clock(); + ticks_t frameQueued = 0; // Go into ye good ol' infinite loop while (1) @@ -106,7 +111,7 @@ int main(void) // If SERIAL_DEBUG is specified we'll handle // serial data as direct human input and only // transmit when we get a LF character - if (SERIAL_DEBUG) { + #if SERIAL_DEBUG // If we have not yet surpassed the maximum frame length // and the byte is not a "transmit" (newline) character, // we should store it for transmission. @@ -121,7 +126,7 @@ int main(void) // transmission flag to true. sertx = true; } - } else { + #else // Otherwise we assume the modem is running // in automated mode, and we push out data // as it becomes available. We either transmit @@ -143,7 +148,7 @@ int main(void) } start = timer_clock(); - } + #endif } else { if (!SERIAL_DEBUG && serialLen > 0 && timer_clock() - start > ms_to_ticks(TX_MAXWAIT)) { sertx = true; @@ -151,17 +156,36 @@ int main(void) } // Check whether we should send data in our serial buffer - if (sertx) { - // Wait until incoming packets are done - if (!mp1CarrierSense(&mp1)) { - // And then send the data - mp1Send(&mp1, serialBuffer, serialLen); - - // Reset the transmission flag and length counter + if (sertx) { + #if MP1_USE_TX_QUEUE + mp1QueueFrame(&mp1, serialBuffer, serialLen); + frameQueued = timer_clock(); sertx = false; serialLen = 0; - } + #else + // Wait until incoming packets are done + if (!mp1CarrierSense(&mp1)) { + // And then send the data + mp1Send(&mp1, serialBuffer, serialLen); + + // Reset the transmission flag and length counter + sertx = false; + serialLen = 0; + } + #endif } + + #if MP1_USE_TX_QUEUE + // We first wait a little to see if more + // frames are coming in. + if (timer_clock() - frameQueued > ms_to_ticks(MP1_QUEUE_TX_WAIT)) { + if (!ser_available(&ser) && !mp1CarrierSense(&mp1)) { + // And if not, we send process the frame + // queue if possible. + mp1ProcessQueue(&mp1); + } + } + #endif } return 0; } \ No newline at end of file diff --git a/Modem/protocol/mp1.c b/Modem/protocol/mp1.c index 4fcc95d..ba49b54 100644 --- a/Modem/protocol/mp1.c +++ b/Modem/protocol/mp1.c @@ -125,7 +125,6 @@ static void mp1Decode(MP1 *mp1) { //////////////////////////////////////////////////////////// void mp1Poll(MP1 *mp1) { int byte; // A place to store our read byte - sendParityBlock = false; // Reset our parity tx indicator // Read bytes from the modem until we reach EOF while ((byte = kfile_getc(mp1->modem)) != EOF) { @@ -263,7 +262,9 @@ void mp1Poll(MP1 *mp1) { // corrected bytes. mp1->checksum_in ^= a; mp1->checksum_in ^= b; + // DEL kprintf("wt %d %c\n", mp1->packetLength-(MP1_DATA_BLOCK_SIZE)+((i/3)*2), a); mp1->buffer[mp1->packetLength-(MP1_DATA_BLOCK_SIZE)+((i/3)*2)] = a; + // DEL kprintf("wt %d %c\n", mp1->packetLength-(MP1_DATA_BLOCK_SIZE-1)+((i/3)*2), b); mp1->buffer[mp1->packetLength-(MP1_DATA_BLOCK_SIZE-1)+((i/3)*2)] = b; } @@ -340,7 +341,7 @@ void mp1Poll(MP1 *mp1) { // Now let's get to the actual reading of the data if (mp1->reading) { - if (mp1->packetLength < MP1_MAX_FRAME_LENGTH) { + if (mp1->packetLength < MP1_MAX_FRAME_LENGTH + MP1_INTERLEAVE_SIZE) { // If the length of the current incoming frame is // still less than our max length, put the incoming // byte in the buffer. When we have collected 3 @@ -389,6 +390,7 @@ static void mp1WriteByte(MP1 *mp1, uint8_t byte) { // be 3 bytes long due to the added parity // byte. static void mp1Putbyte(MP1 *mp1, uint8_t byte) { + // DEL kprintf("wb %c\n", byte); mp1Interleave(mp1, byte); if (sendParityBlock) { @@ -404,11 +406,16 @@ static void mp1Putbyte(MP1 *mp1, uint8_t byte) { // to be transmitted, and structures it into // a valid packet. void mp1Send(MP1 *mp1, void *_buffer, size_t length) { + // Reset our parity tx indicator + sendParityBlock = false; + // Open transmitter and wait for MP1_TXDELAY msecs AFSK_HW_PTT_ON(); ticks_t start = timer_clock(); - while (timer_clock() - start < ms_to_ticks(MP1_TXDELAY)) { - cpu_relax(); + if (!mp1->queueProcessing) { + while (timer_clock() - start < ms_to_ticks(MP1_TXDELAY)) { + cpu_relax(); + } } // Get the transmit data buffer @@ -527,21 +534,29 @@ void mp1Send(MP1 *mp1, void *_buffer, size_t length) { kfile_putc(HDLC_FLAG, mp1->modem); // Turn off manual PTT - AFSK_HW_PTT_OFF(); + if (!mp1->queueProcessing) AFSK_HW_PTT_OFF(); } -// This function will simply initialize -// the protocol context and allocate the -// needed memory. -void mp1Init(MP1 *mp1, KFile *modem, mp1_callback_t callback) { - // Allocate memory for our protocol "object" - memset(mp1, 0, sizeof(*mp1)); - // Set references to our modem "object" and - // a callback for when a packet has been decoded - mp1->modem = modem; - mp1->callback = callback; - mp1->settleTimer = timer_clock(); - mp1->randomSeed = 0; +// This function accepts a frame and stores +// it in the transmission queue +void mp1QueueFrame(MP1 *mp1, void *_buffer, size_t length) { + if (mp1->queueLength < MP1_TX_QUEUE_LENGTH) { + uint8_t *buffer = (uint8_t *)_buffer; + mp1->frameLengths[mp1->queueLength] = length; + memcpy(mp1->frameQueue[mp1->queueLength++], buffer, length); + } +} + +// This function processes the transmission +// queue. +void mp1ProcessQueue(MP1 *mp1) { + int i = 0; + while (mp1->queueLength) { + mp1Send(mp1, mp1->frameQueue[i], mp1->frameLengths[i]); + i++; + mp1->queueLength--; + } + AFSK_HW_PTT_OFF(); } // A simple form of P-persistent CSMA. @@ -563,7 +578,7 @@ bool mp1CarrierSense(MP1 *mp1) { if (r < MP1_P_PERSISTENCE) { return false; } else { - mp1->settleTimer = timer_clock(); + mp1->settleTimer = timer_clock() - MP1_SETTLE_TIME + MP1_SLOT_TIME; return true; } } else { @@ -574,6 +589,24 @@ bool mp1CarrierSense(MP1 *mp1) { } } +// This function will simply initialize +// the protocol context and allocate the +// needed memory. +void mp1Init(MP1 *mp1, KFile *modem, mp1_callback_t callback) { + // Allocate memory for our protocol "object" + memset(mp1, 0, sizeof(*mp1)); + // Set references to our modem "object" and + // a callback for when a packet has been decoded + mp1->modem = modem; + mp1->callback = callback; + mp1->settleTimer = timer_clock(); + mp1->randomSeed = 0; + #if MP1_USE_TX_QUEUE + mp1->queueLength = 0; + mp1->queueProcessing = false; + #endif +} + // A handy debug function that can determine // how much available memory we have left. #if SERIAL_DEBUG diff --git a/Modem/protocol/mp1.h b/Modem/protocol/mp1.h index a3e04d6..b596ac0 100644 --- a/Modem/protocol/mp1.h +++ b/Modem/protocol/mp1.h @@ -5,7 +5,10 @@ #include // Options -#define MP1_ENABLE_COMPRESSION false +#define MP1_ENABLE_TCP_COMPATIBILITY true +#if MP1_ENABLE_TCP_COMPATIBILITY + #define MP1_ENABLE_COMPRESSION false +#endif #define MP1_ENABLE_CSMA true // Frame sizing & checksum @@ -13,7 +16,10 @@ #if MP1_ENABLE_COMPRESSION #define MP1_MAX_FRAME_LENGTH 22 * MP1_INTERLEAVE_SIZE #else - #define MP1_MAX_FRAME_LENGTH 56 * MP1_INTERLEAVE_SIZE + #define MP1_MAX_FRAME_LENGTH 25 * MP1_INTERLEAVE_SIZE + #define MP1_USE_TX_QUEUE true + #define MP1_TX_QUEUE_LENGTH 2 + #define MP1_QUEUE_TX_WAIT 16UL #endif #define MP1_HEADER_SIZE 1 #define MP1_CHECKSUM_SIZE 1 @@ -24,9 +30,10 @@ // These two parameters are used for // P-persistent CSMA -#define MP1_SETTLE_TIME 250UL // The minimum wait time before considering sending -#define MP1_P_PERSISTENCE 64UL // The probability (between 0 and 255) for sending -#define MP1_TXDELAY 0UL // Delay between turning on the transmitter and sending +#define MP1_SETTLE_TIME 175UL // The minimum wait time before considering sending +#define MP1_SLOT_TIME 100UL // The time to wait if deciding not to send +#define MP1_P_PERSISTENCE 85UL // The probability (between 0 and 255) for sending +#define MP1_TXDELAY 0UL // Delay between turning on the transmitter and sending // We need to know some basic HDLC flag bytes #define HDLC_FLAG 0x7E @@ -50,23 +57,29 @@ typedef void (*mp1_callback_t)(struct MP1Packet *packet); // Struct for a protocol context typedef struct MP1 { - uint8_t buffer[MP1_MAX_FRAME_LENGTH]; // A buffer for incoming packets - uint8_t fecBuffer[3]; // Forward Error Correction buffer - KFile *modem; // KFile access to the modem - size_t packetLength; // Counter for received packet length - size_t readLength; // This is the full read length, including parity bytes - uint8_t calculatedParity; // Calculated parity for incoming data block - mp1_callback_t callback; // The function to call when a packet has been received - uint8_t checksum_in; // Rolling checksum for incoming packets - uint8_t checksum_out; // Rolling checksum for outgoing packets - bool reading; // True when we have seen a HDLC flag - bool escape; // We need to know if we are in an escape sequence - ticks_t settleTimer; // Timer used for carrier sense settling - long correctionsMade; // A counter for how many corrections were made to a packet - uint8_t interleaveCounter; // Keeps track of when we have received an entire interleaved block - uint8_t interleaveOut[MP1_INTERLEAVE_SIZE]; // A buffer for interleaving bytes before they are sent - uint8_t interleaveIn[MP1_INTERLEAVE_SIZE]; // A buffer for storing interleaved bytes before they are deinterleaved - uint8_t randomSeed; // A seed for the pseudo-random number generator + uint8_t buffer[MP1_MAX_FRAME_LENGTH+MP1_INTERLEAVE_SIZE]; // A buffer for incoming packets + KFile *modem; // KFile access to the modem + size_t packetLength; // Counter for received packet length + size_t readLength; // This is the full read length, including parity bytes + uint8_t calculatedParity; // Calculated parity for incoming data block + mp1_callback_t callback; // The function to call when a packet has been received + uint8_t checksum_in; // Rolling checksum for incoming packets + uint8_t checksum_out; // Rolling checksum for outgoing packets + bool reading; // True when we have seen a HDLC flag + bool escape; // We need to know if we are in an escape sequence + ticks_t settleTimer; // Timer used for carrier sense settling + long correctionsMade; // A counter for how many corrections were made to a packet + uint8_t interleaveCounter; // Keeps track of when we have received an entire interleaved block + uint8_t interleaveOut[MP1_INTERLEAVE_SIZE]; // A buffer for interleaving bytes before they are sent + uint8_t interleaveIn[MP1_INTERLEAVE_SIZE]; // A buffer for storing interleaved bytes before they are deinterleaved + uint8_t randomSeed; // A seed for the pseudo-random number generator + #if MP1_USE_TX_QUEUE + bool queueProcessing; // For sending queued frames without preamble after first one + size_t queueLength; // The length of the transmission queue + size_t frameLengths[MP1_TX_QUEUE_LENGTH]; // The lengths of the frames in the queue + uint8_t frameQueue[MP1_TX_QUEUE_LENGTH] // A buffer for a queued frame + [MP1_MAX_DATA_SIZE]; + #endif } MP1; // A struct encapsulating a network packet @@ -80,6 +93,8 @@ void mp1Init(MP1 *mp1, KFile *modem, mp1_callback_t callback); void mp1Read(MP1 *mp1, int byte); void mp1Poll(MP1 *mp1); void mp1Send(MP1 *mp1, void *_buffer, size_t length); +void mp1QueueFrame(MP1 *mp1, void *_buffer, size_t length); +void mp1ProcessQueue(MP1 *mp1); bool mp1CarrierSense(MP1 *mp1); int freeRam(void); diff --git a/bertos/cfg/cfg_dac.h b/bertos/cfg/cfg_dac.h deleted file mode 100644 index 1ae1e98..0000000 --- a/bertos/cfg/cfg_dac.h +++ /dev/null @@ -1,88 +0,0 @@ -/** - * \file - * - * - * \brief Configuration file for DAC module. - * - * - * \author Daniele Basile - */ - -#ifndef CFG_DAC_H -#define CFG_DAC_H - -/** - * Module logging level. - * - * $WIZ$ type = "enum" - * $WIZ$ value_list = "log_level" - */ -#define DAC_LOG_LEVEL LOG_LVL_WARN - -/** - * Module logging format. - * - * $WIZ$ type = "enum" - * $WIZ$ value_list = "log_format" - */ -#define DAC_LOG_FORMAT LOG_FMT_TERSE - -/** - * DAC Refresh Period = 1024*REFRESH/DACC Clock - * - * $WIZ$ type = "int" - * $WIZ$ supports = "sam3x" - * $WIZ$ min = 0 - * $WIZ$ max = 65536 - */ -#define CONFIG_DAC_REFRESH 16 - -/** - * DAC Startup Time Selection. - * see datasheet table. - * - * $WIZ$ type = "int" - * $WIZ$ supports = "sam3x" - * $WIZ$ min = 0 - * $WIZ$ max = 63 - */ -#define CONFIG_DAC_STARTUP 0 - -/** - * DAC Trigger Selection. - * - * $WIZ$ type = "enum" - * $WIZ$ value_list = "sam3x_dac_tc" - * $WIZ$ supports = "sam3x" - */ -#define CONFIG_DAC_TIMER DACC_TRGSEL_TIO_CH0 - -#endif /* CFG_DAC_H */ diff --git a/bertos/cfg/cfg_random.h b/bertos/cfg/cfg_random.h deleted file mode 100644 index 5e3afdf..0000000 --- a/bertos/cfg/cfg_random.h +++ /dev/null @@ -1,65 +0,0 @@ -/** - * \file - * - * - * \author Andrea Righi - * - * \brief Configuration file for the "random" module - */ - -#ifndef CFG_RANDOM_H -#define CFG_RANDOM_H - -/** - * Module logging level. - * - * $WIZ$ type = "enum" - * $WIZ$ value_list = "log_level" - */ -#define RANDOM_LOG_LEVEL LOG_LVL_INFO - -/** - * module logging format. - * - * $WIZ$ type = "enum" - * $WIZ$ value_list = "log_format" - */ -#define RANDOM_LOG_FORMAT LOG_FMT_TERSE - -/** - * Random security level. - * - * $WIZ$ type = "enum" - * $WIZ$ value_list = "random_level" - */ -#define RANDOM_SECURITY_LEVEL RANDOM_SECURITY_MINIMUM - -#endif /* CFG_RANDOM_H */ diff --git a/bertos/cfg/cfg_randpool.h b/bertos/cfg/cfg_randpool.h deleted file mode 100644 index 3038363..0000000 --- a/bertos/cfg/cfg_randpool.h +++ /dev/null @@ -1,55 +0,0 @@ -/** - * \file - * - * - * \brief Configuration file for randpool module. - * - * - * \author Daniele Basile - */ - -#ifndef CFG_RANDPOOL_H -#define CFG_RANDPOOL_H - - -/** - * Define a size, in byte, of entropy pool. - * $WIZ$ type = "int" - * $WIZ$ min = 1 - */ -#define CONFIG_SIZE_ENTROPY_POOL 64 - -/// Enable timer in randpool algo. $WIZ$ type = "boolean" -#define CONFIG_RANDPOOL_TIMER 1 - -#endif /* CFG_RANDPOOL_H */ - - diff --git a/bertos/cfg/cfg_ser.h b/bertos/cfg/cfg_ser.h index 91a10e0..9b6a7b8 100644 --- a/bertos/cfg/cfg_ser.h +++ b/bertos/cfg/cfg_ser.h @@ -113,7 +113,7 @@ * $WIZ$ min = 2 * $WIZ$ supports = "avr" */ -#define CONFIG_SPI_TXBUFSIZE 32 +#define CONFIG_SPI_TXBUFSIZE 0 /** * Size of the inbound FIFO buffer for SPI port [bytes]. @@ -121,7 +121,7 @@ * $WIZ$ min = 2 * $WIZ$ supports = "avr" */ -#define CONFIG_SPI_RXBUFSIZE 32 +#define CONFIG_SPI_RXBUFSIZE 0 /** * Size of the outbound FIFO buffer for SPI port 0 [bytes]. @@ -129,7 +129,7 @@ * $WIZ$ min = 2 * $WIZ$ supports = "at91" */ -#define CONFIG_SPI0_TXBUFSIZE 32 +#define CONFIG_SPI0_TXBUFSIZE 0 /** * Size of the inbound FIFO buffer for SPI port 0 [bytes]. @@ -137,7 +137,7 @@ * $WIZ$ min = 2 * $WIZ$ supports = "at91" */ -#define CONFIG_SPI0_RXBUFSIZE 32 +#define CONFIG_SPI0_RXBUFSIZE 0 /** * Size of the outbound FIFO buffer for SPI port 1 [bytes]. diff --git a/buildrev.h b/buildrev.h index 8c410c3..8e98bd7 100644 --- a/buildrev.h +++ b/buildrev.h @@ -1,2 +1,2 @@ -#define VERS_BUILD 1603 +#define VERS_BUILD 1724 #define VERS_HOST "shard"