diff --git a/Modem/hardware.c b/Modem/hardware.c index 1ee72e9..39397b2 100644 --- a/Modem/hardware.c +++ b/Modem/hardware.c @@ -3,12 +3,12 @@ ////////////////////////////////////////////////////// #include "hardware.h" // We need the header for this code -#include "afsk.h" // We also need to know about the AFSK modem +#include "afsk.h" // We also need to know about the AFSK modem -#include // Interrupt functions from BertOS +#include // Interrupt functions from BertOS -#include // AVR IO functions from BertOS -#include // AVR interrupt functions from BertOS +#include // AVR IO functions from BertOS +#include // AVR interrupt functions from BertOS // A reference to our modem "object" static Afsk *modem; @@ -25,80 +25,80 @@ static Afsk *modem; // it the way we need. void hw_afsk_adcInit(int ch, Afsk *_modem) { - // Store a reference to our modem "object" - modem = _modem; + // Store a reference to our modem "object" + modem = _modem; - // Also make sure that we are not trying to use - // a pin that can't be used for analog input - ASSERT(ch <= 5); + // Also make sure that we are not trying to use + // a pin that can't be used for analog input + ASSERT(ch <= 5); - // We need a timer to control how often our sampling functions - // should run. To do this we will need to change some registers. - // First we do some configuration on the Timer/Counter Control - // Register 1, aka Timer1. - // - // The following bits are set: - // CS10: ClockSource 10, sets no prescaler on the clock, - // meaning it will run at the same speed as the CPU, ie 16MHz - // WGM13 and WGM12 together enables "Timer Mode 12", which - // is Clear Timer on Compare, compare set to TOP, and the - // source for the TOP value is ICR1 (Input Capture Register1). - // TOP means that we specify a maximum value for the timer, and - // once that value is reached, an interrupt will be triggered. - // The timer will then start from zero again. As just noted, - // the place we specify this value is in the ICR1 register. - TCCR1A = 0; - TCCR1B = BV(CS10) | BV(WGM13) | BV(WGM12); + // We need a timer to control how often our sampling functions + // should run. To do this we will need to change some registers. + // First we do some configuration on the Timer/Counter Control + // Register 1, aka Timer1. + // + // The following bits are set: + // CS10: ClockSource 10, sets no prescaler on the clock, + // meaning it will run at the same speed as the CPU, ie 16MHz + // WGM13 and WGM12 together enables "Timer Mode 12", which + // is Clear Timer on Compare, compare set to TOP, and the + // source for the TOP value is ICR1 (Input Capture Register1). + // TOP means that we specify a maximum value for the timer, and + // once that value is reached, an interrupt will be triggered. + // The timer will then start from zero again. As just noted, + // the place we specify this value is in the ICR1 register. + TCCR1A = 0; + TCCR1B = BV(CS10) | BV(WGM13) | BV(WGM12); - // We now set the ICR1 register to what count value we want to - // reset (and thus trigger the interrupt) at. - // Since the timer is running at 16MHz, the counter will be - // incremented 16 million times each second, and we want the - // interrupt to trigger 9600 times each second. The formula for - // calculating the value of ICR1 (the TOP value) is: - // (CPUClock / Prescaler) / desired frequency - 1 - // So that's what well put in this register to set up our - // 9.6KHz sampling rate. Note that we can also specify a clock - // correction to this calculation. If you measure your processors - // actual clock speed to 16.095MHz, define FREQUENCY_CORRECTION - // as 9500, and the actual sampling (and this modulation and - // demodulation) will be much closer to an actual 9600 Hz. - // No crystals are perfect though, and will also drift with - // temperature variations, but if you have a board with a - // crystal that is way off frequency, this can help alot. - ICR1 = (((CPU_FREQ+FREQUENCY_CORRECTION)) / 9600) - 1; + // We now set the ICR1 register to what count value we want to + // reset (and thus trigger the interrupt) at. + // Since the timer is running at 16MHz, the counter will be + // incremented 16 million times each second, and we want the + // interrupt to trigger 9600 times each second. The formula for + // calculating the value of ICR1 (the TOP value) is: + // (CPUClock / Prescaler) / desired frequency - 1 + // So that's what well put in this register to set up our + // 9.6KHz sampling rate. Note that we can also specify a clock + // correction to this calculation. If you measure your processors + // actual clock speed to 16.095MHz, define FREQUENCY_CORRECTION + // as 9500, and the actual sampling (and this modulation and + // demodulation) will be much closer to an actual 9600 Hz. + // No crystals are perfect though, and will also drift with + // temperature variations, but if you have a board with a + // crystal that is way off frequency, this can help alot. + ICR1 = (((CPU_FREQ+FREQUENCY_CORRECTION)) / 9600) - 1; - // Set reference to AVCC (5V), select pin - // Set the ADMUX register. The first part (BV(REFS0)) sets - // the reference voltage to VCC (5V), and the next selects - // the ADC channel (basically what pin we are capturing on) - ADMUX = BV(REFS0) | ch; + // Set reference to AVCC (5V), select pin + // Set the ADMUX register. The first part (BV(REFS0)) sets + // the reference voltage to VCC (5V), and the next selects + // the ADC channel (basically what pin we are capturing on) + ADMUX = BV(REFS0) | ch; - DDRC &= ~BV(ch); // Set the selected channel (pin) to input - PORTC &= ~BV(ch); // Initialize the selected pin to LOW - DIDR0 |= BV(ch); // Disable the Digital Input Buffer on selected pin + DDRC &= ~BV(ch); // Set the selected channel (pin) to input + PORTC &= ~BV(ch); // Initialize the selected pin to LOW + DIDR0 |= BV(ch); // Disable the Digital Input Buffer on selected pin - // Now a little more configuration to get the ADC working - // the way we want - ADCSRB = BV(ADTS2) | // Setting these three on (1-1-1) sets the ADC to - BV(ADTS1) | // "Timer1 capture event". That means we can declare - BV(ADTS0); // an ISR in the ADC Vector, that will then get called - // everytime the ADC has a sample ready, which will - // happen at the 9.6Khz sampling rate we set up earlier - - ADCSRA = BV(ADEN) | // ADC Enable - Yes, we need to turn it on :) - BV(ADSC) | // ADC Start Converting - Tell it to start doing conversions - BV(ADATE) | // Enable autotriggering - Enables the autotrigger on complete - BV(ADIE) | // ADC Interrupt enable - Enables an interrupt to be called - BV(ADPS2); // Enable prescaler flag 2 (1-0-0 = division by 16 = 1MHz) - // This sets the ADC to run at 1MHz. This is out of spec, - // Since it's normal operating range is only up to 200KHz. - // But don't worry, it's not dangerous! I promise it wont - // blow up :) There is a downside to running at this speed - // though, hence the "out of spec", which is that we get - // a much lower resolution on the output. In this case, - // it's not a problem though, since we don't need the full - // 10-bit resolution, so we'll take fast and less precise! + // Now a little more configuration to get the ADC working + // the way we want + ADCSRB = BV(ADTS2) | // Setting these three on (1-1-1) sets the ADC to + BV(ADTS1) | // "Timer1 capture event". That means we can declare + BV(ADTS0); // an ISR in the ADC Vector, that will then get called + // everytime the ADC has a sample ready, which will + // happen at the 9.6Khz sampling rate we set up earlier + + ADCSRA = BV(ADEN) | // ADC Enable - Yes, we need to turn it on :) + BV(ADSC) | // ADC Start Converting - Tell it to start doing conversions + BV(ADATE)| // Enable autotriggering - Enables the autotrigger on complete + BV(ADIE) | // ADC Interrupt enable - Enables an interrupt to be called + BV(ADPS2); // Enable prescaler flag 2 (1-0-0 = division by 16 = 1MHz) + // This sets the ADC to run at 1MHz. This is out of spec, + // Since it's normal operating range is only up to 200KHz. + // But don't worry, it's not dangerous! I promise it wont + // blow up :) There is a downside to running at this speed + // though, hence the "out of spec", which is that we get + // a much lower resolution on the output. In this case, + // it's not a problem though, since we don't need the full + // 10-bit resolution, so we'll take fast and less precise! } @@ -114,52 +114,52 @@ void hw_afsk_adcInit(int ch, Afsk *_modem) bool hw_ptt_on; bool hw_afsk_dac_isr; DECLARE_ISR(ADC_vect) { - TIFR1 = BV(ICF1); + TIFR1 = BV(ICF1); - // Call the routine for analysing the captured sample - // Notice that we read the ADC sample, and then bitshift - // by two places to the right, effectively eliminating - // two bits of precision. But we didn't have those - // anyway, because the ADC is running at high speed. - // We then subtract 128 from the value, to get the - // representation to match an AC waveform. We need to - // do this because the AC waveform (from the audio input) - // is biased by +2.5V, which is nessecary, since the ADC - // can't read negative voltages. By doing this simple - // math, we bring it back to an AC representation - // we can do further calculations on. - afsk_adc_isr(modem, ((int16_t)((ADC) >> 2) - 128)); + // Call the routine for analysing the captured sample + // Notice that we read the ADC sample, and then bitshift + // by two places to the right, effectively eliminating + // two bits of precision. But we didn't have those + // anyway, because the ADC is running at high speed. + // We then subtract 128 from the value, to get the + // representation to match an AC waveform. We need to + // do this because the AC waveform (from the audio input) + // is biased by +2.5V, which is nessecary, since the ADC + // can't read negative voltages. By doing this simple + // math, we bring it back to an AC representation + // we can do further calculations on. + afsk_adc_isr(modem, ((int16_t)((ADC) >> 2) - 128)); - // We also need to check if we're supposed to spit - // out some modulated data to the DAC. - if (hw_afsk_dac_isr) { - // If there is, it's easy to actually do so. We - // calculate what the sample should be in the - // DAC ISR, and apply the bitmask 11110000. This - // simoultaneously spits out our 4-bit digital - // sample to the four pins connected to our DAC - // circuit, which then converts it to an analog - // waveform. The reason for the " | BV(3)" is that - // we also need to trigger another pin controlled - // by the PORTD register. This is the PTT pin - // which tells the radio to open it transmitter. - PORTD = (afsk_dac_isr(modem) & 0xF0) | BV(3); - } else { - // If we're not supposed to transmit anything, we - // keep quiet by continously sending 128, which - // when converted to an AC waveform by the DAC, - // equates to a steady, unchanging 0 volts. - if (hw_ptt_on) { - PORTD = 136; - } else { - PORTD = 128; - } - } - + // We also need to check if we're supposed to spit + // out some modulated data to the DAC. + if (hw_afsk_dac_isr) { + // If there is, it's easy to actually do so. We + // calculate what the sample should be in the + // DAC ISR, and apply the bitmask 11110000. This + // simoultaneously spits out our 4-bit digital + // sample to the four pins connected to our DAC + // circuit, which then converts it to an analog + // waveform. The reason for the " | BV(3)" is that + // we also need to trigger another pin controlled + // by the PORTD register. This is the PTT pin + // which tells the radio to open it transmitter. + PORTD = (afsk_dac_isr(modem) & 0xF0) | BV(3); + } else { + // If we're not supposed to transmit anything, we + // keep quiet by continously sending 128, which + // when converted to an AC waveform by the DAC, + // equates to a steady, unchanging 0 volts. + if (hw_ptt_on) { + PORTD = 136; + } else { + PORTD = 128; + } + } + } -// * "finally" is probably the wrong description here. +// (*) "finally" is probably the wrong description here. // "All the f'ing time" is probably more accurate :) // but it felt like it was a long way down here, // writing all the explanations. I think this is a diff --git a/Modem/hardware.h b/Modem/hardware.h index a1ba622..ac88536 100644 --- a/Modem/hardware.h +++ b/Modem/hardware.h @@ -5,9 +5,9 @@ #ifndef FSK_MODEM_HW #define FSK_MODEM_HW -#include "cfg/cfg_arch.h" // Architecture configuration +#include "cfg/cfg_arch.h" // Architecture configuration -#include // AVR IO functions from BertOS +#include // AVR IO functions from BertOS ////////////////////////////////////////////////////// // Definitions and some useful macros // diff --git a/Modem/main.c b/Modem/main.c index 0aa166e..3d01f8b 100644 --- a/Modem/main.c +++ b/Modem/main.c @@ -3,40 +3,40 @@ // First things first, all the includes we need // ////////////////////////////////////////////////////// -#include // Interrupt functionality from BertOS +#include // Interrupt functionality from BertOS -#include // Serial driver from BertOS -#include // Timer driver from BertOS +#include // Serial driver from BertOS +#include // Timer driver from BertOS -#include // Standard input/output -#include // String operations +#include // Standard input/output +#include // String operations -#include "afsk.h" // Header for AFSK modem -#include "protocol/mp1.h" // Header for MP.1 protocol +#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 + #include "cfg/debug.h" // Debug configuration from BertOS #endif ////////////////////////////////////////////////////// -// A few definitions // +// A few definitions // ////////////////////////////////////////////////////// -static Afsk afsk; // Declare a AFSK modem struct -static MP1 mp1; // Declare a protocol struct -static Serial ser; // Declare a serial interface struct +static Afsk afsk; // Declare a AFSK modem struct +static MP1 mp1; // Declare a protocol struct +static Serial ser; // Declare a serial interface struct -#define ADC_CH 0 // Define which channel (pin) we want - // for the ADC (this is A0 on arduino) +#define ADC_CH 0 // Define which channel (pin) we want + // for the ADC (this is A0 on arduino) -static uint8_t serialBuffer[MP1_MAX_DATA_SIZE]; // This is a buffer for incoming serial data +static uint8_t serialBuffer[MP1_MAX_DATA_SIZE]; // This is a buffer for incoming serial data -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. +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) ////////////////////////////////////////////////////// @@ -47,147 +47,147 @@ static bool sertx = false; // Flag signifying whether it's time to send da // so we can process each packet as they are decoded. // Right now it just prints the packet to the serial port. static void mp1Callback(struct MP1Packet *packet) { - if (SERIAL_DEBUG) { - kfile_printf(&ser.fd, "%.*s\n", packet->dataLength, packet->data); - } else { - for (unsigned long i = 0; i < packet->dataLength; i++) { - kfile_putc(packet->data[i], &ser.fd); - } - } + if (SERIAL_DEBUG) { + kfile_printf(&ser.fd, "%.*s\n", packet->dataLength, packet->data); + } else { + for (unsigned long i = 0; i < packet->dataLength; i++) { + kfile_putc(packet->data[i], &ser.fd); + } + } } // Simple initialization function. static void init(void) { - // Enable interrupts - IRQ_ENABLE; + // Enable interrupts + IRQ_ENABLE; // Initialize hardware timers - timer_init(); + timer_init(); - // Initialize serial comms on UART0, - // which is the hardware serial on arduino - ser_init(&ser, SER_UART0); - ser_setbaudrate(&ser, 9600); + // Initialize serial comms on UART0, + // which is the hardware serial on arduino + ser_init(&ser, SER_UART0); + ser_setbaudrate(&ser, 9600); - // For some reason BertOS sets the serial - // to 7 bit characters by default. We set - // it to 8 instead. - UCSR0C = _BV(UCSZ01) | _BV(UCSZ00); + // For some reason BertOS sets the serial + // to 7 bit characters by default. We set + // it to 8 instead. + UCSR0C = _BV(UCSZ01) | _BV(UCSZ00); - // Create a modem context - afsk_init(&afsk, ADC_CH); - // ... and a protocol context with the modem - mp1Init(&mp1, &afsk.fd, mp1Callback); + // Create a modem context + afsk_init(&afsk, ADC_CH); + // ... and a protocol context with the modem + mp1Init(&mp1, &afsk.fd, mp1Callback); - // That's all! + // That's all! } int main(void) { - // Start by running the main initialization - init(); - // Record the current tick count for time-keeping - ticks_t start = timer_clock(); - #if MP1_USE_TX_QUEUE - ticks_t frameQueued = 0; - #endif - - // Go into ye good ol' infinite loop - while (1) - { - // First we instruct the protocol to check for - // incoming data - mp1Poll(&mp1); + // Start by running the main initialization + init(); + // Record the current tick count for time-keeping + ticks_t start = timer_clock(); + #if MP1_USE_TX_QUEUE + ticks_t frameQueued = 0; + #endif + + // Go into ye good ol' infinite loop + while (1) + { + // First we instruct the protocol to check for + // incoming data + mp1Poll(&mp1); - - // If there was actually some data waiting for us - // there, let's se what it tastes like :) - if (!sertx && ser_available(&ser)) { - // We then read a byte from the serial port. - // Notice that we use "_nowait" since we can't - // have this blocking execution until a byte - // comes in. - sbyte = ser_getchar_nowait(&ser); + + // If there was actually some data waiting for us + // there, let's se what it tastes like :) + if (!sertx && ser_available(&ser)) { + // We then read a byte from the serial port. + // Notice that we use "_nowait" since we can't + // have this blocking execution until a byte + // comes in. + sbyte = ser_getchar_nowait(&ser); - // 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 we have not yet surpassed the maximum frame length - // and the byte is not a "transmit" (newline) character, - // we should store it for transmission. - if ((serialLen < MP1_MAX_DATA_SIZE) && (sbyte != 10)) { - // Put the read byte into the buffer; - serialBuffer[serialLen] = sbyte; - // Increment the read length counter - serialLen++; - } else { - // If one of the above conditions were actually the - // case, it means we have to transmit, se we set - // transmission flag to true. - sertx = true; - } - #else - // Otherwise we assume the modem is running - // in automated mode, and we push out data - // as it becomes available. We either transmit - // immediately when the max frame length has - // been reached, or when we get no input for - // a certain amount of time. + // 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 we have not yet surpassed the maximum frame length + // and the byte is not a "transmit" (newline) character, + // we should store it for transmission. + if ((serialLen < MP1_MAX_DATA_SIZE) && (sbyte != 10)) { + // Put the read byte into the buffer; + serialBuffer[serialLen] = sbyte; + // Increment the read length counter + serialLen++; + } else { + // If one of the above conditions were actually the + // case, it means we have to transmit, se we set + // transmission flag to true. + sertx = true; + } + #else + // Otherwise we assume the modem is running + // in automated mode, and we push out data + // as it becomes available. We either transmit + // immediately when the max frame length has + // been reached, or when we get no input for + // a certain amount of time. - if (serialLen < MP1_MAX_DATA_SIZE-1) { - // Put the read byte into the buffer; - serialBuffer[serialLen] = sbyte; - // Increment the read length counter - serialLen++; - } else { - // If max frame length has been reached - // we need to transmit. - serialBuffer[serialLen] = sbyte; - serialLen++; - sertx = true; - } + if (serialLen < MP1_MAX_DATA_SIZE-1) { + // Put the read byte into the buffer; + serialBuffer[serialLen] = sbyte; + // Increment the read length counter + serialLen++; + } else { + // If max frame length has been reached + // we need to transmit. + serialBuffer[serialLen] = sbyte; + serialLen++; + sertx = true; + } - start = timer_clock(); - #endif - } else { - if (!SERIAL_DEBUG && serialLen > 0 && timer_clock() - start > ms_to_ticks(TX_MAXWAIT)) { - sertx = true; - } - } + start = timer_clock(); + #endif + } else { + if (!SERIAL_DEBUG && serialLen > 0 && timer_clock() - start > ms_to_ticks(TX_MAXWAIT)) { + sertx = true; + } + } - // Check whether we should send data in our serial buffer - 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 - } + // Check whether we should send data in our serial buffer + 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; + #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 4a66e38..4447998 100644 --- a/Modem/protocol/mp1.c +++ b/Modem/protocol/mp1.c @@ -1,10 +1,10 @@ #include "mp1.h" #include "hardware.h" #include "config.h" -#include // Used for random +#include // Used for random #include #include -#include // Timer driver from BertOS +#include // Timer driver from BertOS #include "compression/heatshrink_encoder.h" #include "compression/heatshrink_decoder.h" @@ -21,7 +21,7 @@ static uint8_t lastByte = 0x00; // We also need a buffer for compressing and // decompressing packet data. #if MP1_ENABLE_COMPRESSION - static uint8_t compressionBuffer[MP1_MAX_DATA_SIZE]; + static uint8_t compressionBuffer[MP1_MAX_DATA_SIZE]; #endif #if SERIAL_DEBUG @@ -42,19 +42,19 @@ INLINE bool GET_BIT(uint8_t byte, int n) { return (byte & (1 << (8-n))) == (1 << // (12,8) Hamming code. INLINE bool BIT(uint8_t byte, int n) { return ((byte & BV(n-1))>>(n-1)); } static uint8_t mp1ParityBlock(uint8_t first, uint8_t other) { - uint8_t parity = 0x00; + uint8_t parity = 0x00; - parity = ((BIT(first, 1) ^ BIT(first, 2) ^ BIT(first, 4) ^ BIT(first, 5) ^ BIT(first, 7))) + - ((BIT(first, 1) ^ BIT(first, 3) ^ BIT(first, 4) ^ BIT(first, 6) ^ BIT(first, 7))<<1) + - ((BIT(first, 2) ^ BIT(first, 3) ^ BIT(first, 4) ^ BIT(first, 8))<<2) + - ((BIT(first, 5) ^ BIT(first, 6) ^ BIT(first, 7) ^ BIT(first, 8))<<3) + + parity = ((BIT(first, 1) ^ BIT(first, 2) ^ BIT(first, 4) ^ BIT(first, 5) ^ BIT(first, 7))) + + ((BIT(first, 1) ^ BIT(first, 3) ^ BIT(first, 4) ^ BIT(first, 6) ^ BIT(first, 7))<<1) + + ((BIT(first, 2) ^ BIT(first, 3) ^ BIT(first, 4) ^ BIT(first, 8))<<2) + + ((BIT(first, 5) ^ BIT(first, 6) ^ BIT(first, 7) ^ BIT(first, 8))<<3) + - ((BIT(other, 1) ^ BIT(other, 2) ^ BIT(other, 4) ^ BIT(other, 5) ^ BIT(other, 7))<<4) + - ((BIT(other, 1) ^ BIT(other, 3) ^ BIT(other, 4) ^ BIT(other, 6) ^ BIT(other, 7))<<5) + - ((BIT(other, 2) ^ BIT(other, 3) ^ BIT(other, 4) ^ BIT(other, 8))<<6) + - ((BIT(other, 5) ^ BIT(other, 6) ^ BIT(other, 7) ^ BIT(other, 8))<<7); + ((BIT(other, 1) ^ BIT(other, 2) ^ BIT(other, 4) ^ BIT(other, 5) ^ BIT(other, 7))<<4) + + ((BIT(other, 1) ^ BIT(other, 3) ^ BIT(other, 4) ^ BIT(other, 6) ^ BIT(other, 7))<<5) + + ((BIT(other, 2) ^ BIT(other, 3) ^ BIT(other, 4) ^ BIT(other, 8))<<6) + + ((BIT(other, 5) ^ BIT(other, 6) ^ BIT(other, 7) ^ BIT(other, 8))<<7); - return parity; + return parity; } // This decode function retrieves the buffer of @@ -65,56 +65,56 @@ static uint8_t mp1ParityBlock(uint8_t first, uint8_t other) { // it is decompressed before being passed to // the registered callback. static void mp1Decode(MP1 *mp1) { - MP1Packet packet; // A decoded packet struct - uint8_t *buffer = mp1->buffer; // Get the buffer from the protocol context - - // Get the header and "remove" it from the buffer - uint8_t header = buffer[0]; - buffer++; + MP1Packet packet; // A decoded packet struct + uint8_t *buffer = mp1->buffer; // Get the buffer from the protocol context + + // Get the header and "remove" it from the buffer + uint8_t header = buffer[0]; + buffer++; - // If header indicates a padded packet, remove - // padding - uint8_t padding = header >> 4; - if (header & MP1_HEADER_PADDED) { - for (int i = 0; i < padding; i++) { - buffer++; - } - } + // If header indicates a padded packet, remove + // padding + uint8_t padding = header >> 4; + if (header & MP1_HEADER_PADDED) { + for (int i = 0; i < padding; i++) { + buffer++; + } + } - if (SERIAL_DEBUG) kprintf("[TS=%d] ", mp1->packetLength); + if (SERIAL_DEBUG) kprintf("[TS=%d] ", mp1->packetLength); - // Set the payload length of the packet to the counted - // length minus 1, so we remove the checksum - packet.dataLength = mp1->packetLength - 2 - (header & MP1_HEADER_PADDED)*padding; + // Set the payload length of the packet to the counted + // length minus 1, so we remove the checksum + packet.dataLength = mp1->packetLength - 2 - (header & MP1_HEADER_PADDED)*padding; - // Check if we have received a compressed packet - if (MP1_ENABLE_COMPRESSION && (header & MP1_HEADER_COMPRESSION)) { - // If we have, we decompress it and use the - // decompressed data for the packet - #if MP1_ENABLE_COMPRESSION - if (SERIAL_DEBUG) kprintf("[CS=%d] ", packet.dataLength); - size_t decompressedSize = decompress(buffer, packet.dataLength); - if (SERIAL_DEBUG) kprintf("[DS=%d]", decompressedSize); - packet.dataLength = decompressedSize; - memcpy(mp1->buffer, compressionBuffer, decompressedSize); - #endif - } else { - // If the packet was not compressed, we shift - // the data in our buffer back down to the actual - // beginning of the buffer array, since we incremented - // the pointer address for removing the header and - // padding. - for (unsigned long i = 0; i < packet.dataLength; i++) { - mp1->buffer[i] = buffer[i]; - } - } + // Check if we have received a compressed packet + if (MP1_ENABLE_COMPRESSION && (header & MP1_HEADER_COMPRESSION)) { + // If we have, we decompress it and use the + // decompressed data for the packet + #if MP1_ENABLE_COMPRESSION + if (SERIAL_DEBUG) kprintf("[CS=%d] ", packet.dataLength); + size_t decompressedSize = decompress(buffer, packet.dataLength); + if (SERIAL_DEBUG) kprintf("[DS=%d]", decompressedSize); + packet.dataLength = decompressedSize; + memcpy(mp1->buffer, compressionBuffer, decompressedSize); + #endif + } else { + // If the packet was not compressed, we shift + // the data in our buffer back down to the actual + // beginning of the buffer array, since we incremented + // the pointer address for removing the header and + // padding. + for (unsigned long i = 0; i < packet.dataLength; i++) { + mp1->buffer[i] = buffer[i]; + } + } - // Set the data field of the packet to our buffer - packet.data = mp1->buffer; + // Set the data field of the packet to our buffer + packet.data = mp1->buffer; - // If a callback have been specified, let's - // call it and pass the decoded packet - if (mp1->callback) mp1->callback(&packet); + // If a callback have been specified, let's + // call it and pass the decoded packet + if (mp1->callback) mp1->callback(&packet); } @@ -124,260 +124,260 @@ static void mp1Decode(MP1 *mp1) { // if valid packets are found // //////////////////////////////////////////////////////////// void mp1Poll(MP1 *mp1) { - int byte; // A place to store our read byte + int byte; // A place to store our read byte - // Read bytes from the modem until we reach EOF - while ((byte = kfile_getc(mp1->modem)) != EOF) { - // We read something from the modem, so we - // set the settleTimer - mp1->settleTimer = timer_clock(); + // Read bytes from the modem until we reach EOF + while ((byte = kfile_getc(mp1->modem)) != EOF) { + // We read something from the modem, so we + // set the settleTimer + mp1->settleTimer = timer_clock(); - ///////////////////////////////////////////// - // This following block handles forward // - // error correction using an interleaved // - // (12,8) Hamming code // - ///////////////////////////////////////////// + ///////////////////////////////////////////// + // This following block handles forward // + // error correction using an interleaved // + // (12,8) Hamming code // + ///////////////////////////////////////////// - // If we have started reading (received an - // HDLC_FLAG), we will start looking at the - // incoming data and perform forward error - // correction on it. - + // If we have started reading (received an + // HDLC_FLAG), we will start looking at the + // incoming data and perform forward error + // correction on it. + - if ((mp1->reading && (byte != AX25_ESC )) || (mp1->reading && (mp1->escape && (byte == AX25_ESC || byte == HDLC_FLAG || byte == HDLC_RESET)))) { - // We have a byte, increment our read counter - mp1->readLength++; + if ((mp1->reading && (byte != AX25_ESC )) || (mp1->reading && (mp1->escape && (byte == AX25_ESC || byte == HDLC_FLAG || byte == HDLC_RESET)))) { + // We have a byte, increment our read counter + mp1->readLength++; - // Check if we have read three bytes. If we - // have, we should now have a block of two - // data bytes and a parity byte. This block - if (mp1->readLength % MP1_INTERLEAVE_SIZE == 0) { - // If the last character in the block - // looks like a control character, we - // need to set the escape indicator to - // false, since the next byte will be - // read immediately after the FEC - // routine, and thus, the normal reading - // code will not reset the indicator. - if (byte == AX25_ESC || byte == HDLC_FLAG || byte == HDLC_RESET) mp1->escape = false; - - // The block is interleaved, so we will - // first put the received bytes in the - // deinterleaving buffer - for (int i = 1; i < MP1_INTERLEAVE_SIZE; i++) { - mp1->interleaveIn[i-1] = mp1->buffer[mp1->packetLength-(MP1_INTERLEAVE_SIZE-i)]; - } - mp1->interleaveIn[MP1_INTERLEAVE_SIZE-1] = byte; + // Check if we have read three bytes. If we + // have, we should now have a block of two + // data bytes and a parity byte. This block + if (mp1->readLength % MP1_INTERLEAVE_SIZE == 0) { + // If the last character in the block + // looks like a control character, we + // need to set the escape indicator to + // false, since the next byte will be + // read immediately after the FEC + // routine, and thus, the normal reading + // code will not reset the indicator. + if (byte == AX25_ESC || byte == HDLC_FLAG || byte == HDLC_RESET) mp1->escape = false; + + // The block is interleaved, so we will + // first put the received bytes in the + // deinterleaving buffer + for (int i = 1; i < MP1_INTERLEAVE_SIZE; i++) { + mp1->interleaveIn[i-1] = mp1->buffer[mp1->packetLength-(MP1_INTERLEAVE_SIZE-i)]; + } + mp1->interleaveIn[MP1_INTERLEAVE_SIZE-1] = byte; - // We then deinterleave the block - mp1Deinterleave(mp1); + // We then deinterleave the block + mp1Deinterleave(mp1); - // Adjust the packet length, since we will get - // parity bytes in the data buffer with block - // sizes larger than 3 - mp1->packetLength -= MP1_INTERLEAVE_SIZE/3 - 1; + // Adjust the packet length, since we will get + // parity bytes in the data buffer with block + // sizes larger than 3 + mp1->packetLength -= MP1_INTERLEAVE_SIZE/3 - 1; - // For each 3-byte block in the deinterleaved - // bytes, we apply forward error correction - for (int i = 0; i < MP1_INTERLEAVE_SIZE; i+=3) { - // We now calculate a parity byte on the - // received data. + // For each 3-byte block in the deinterleaved + // bytes, we apply forward error correction + for (int i = 0; i < MP1_INTERLEAVE_SIZE; i+=3) { + // We now calculate a parity byte on the + // received data. - // Deinterleaved data bytes - uint8_t a = mp1->interleaveIn[i]; - uint8_t b = mp1->interleaveIn[i+1]; + // Deinterleaved data bytes + uint8_t a = mp1->interleaveIn[i]; + uint8_t b = mp1->interleaveIn[i+1]; - // Deinterleaved parity byte - uint8_t p = mp1->interleaveIn[i+2]; + // Deinterleaved parity byte + uint8_t p = mp1->interleaveIn[i+2]; - mp1->calculatedParity = mp1ParityBlock(a, b); + mp1->calculatedParity = mp1ParityBlock(a, b); - // By XORing the calculated parity byte - // with the received parity byte, we get - // what is called the "syndrome". This - // number will tell us if we had any - // errors during transmission, and if so - // where they are. Using Hamming code, we - // can only detect single bit errors in a - // byte though, which is why we interleave - // the data, since most errors will usually - // occur in bursts of more than one bit. - // With 2 data byte interleaving we can - // correct 2 consecutive bit errors. - uint8_t syndrome = mp1->calculatedParity ^ p; - if (syndrome == 0x00) { - // If the syndrome equals 0, we either - // don't have any errors, or the error - // is unrecoverable, so we don't do - // anything - } else { - // If the syndrome is not equal to 0, - // there is a problem, and we will try - // to correct it. We first need to split - // the syndrome byte up into the two - // actual syndrome numbers, one for - // each data byte. - uint8_t syndromes[2]; - syndromes[0] = syndrome & 0x0f; - syndromes[1] = (syndrome & 0xf0) >> 4; + // By XORing the calculated parity byte + // with the received parity byte, we get + // what is called the "syndrome". This + // number will tell us if we had any + // errors during transmission, and if so + // where they are. Using Hamming code, we + // can only detect single bit errors in a + // byte though, which is why we interleave + // the data, since most errors will usually + // occur in bursts of more than one bit. + // With 2 data byte interleaving we can + // correct 2 consecutive bit errors. + uint8_t syndrome = mp1->calculatedParity ^ p; + if (syndrome == 0x00) { + // If the syndrome equals 0, we either + // don't have any errors, or the error + // is unrecoverable, so we don't do + // anything + } else { + // If the syndrome is not equal to 0, + // there is a problem, and we will try + // to correct it. We first need to split + // the syndrome byte up into the two + // actual syndrome numbers, one for + // each data byte. + uint8_t syndromes[2]; + syndromes[0] = syndrome & 0x0f; + syndromes[1] = (syndrome & 0xf0) >> 4; - // Then we look at each syndrome number - // to determine what bit in the data - // bytes to correct. - for (int i = 0; i < 2; i++) { - uint8_t s = syndromes[i]; - uint8_t correction = 0x00; - if (s == 1 || s == 2 || s == 4 || s == 8) { - // This signifies an error in the - // parity block, so we actually - // don't need any correction - continue; - } + // Then we look at each syndrome number + // to determine what bit in the data + // bytes to correct. + for (int i = 0; i < 2; i++) { + uint8_t s = syndromes[i]; + uint8_t correction = 0x00; + if (s == 1 || s == 2 || s == 4 || s == 8) { + // This signifies an error in the + // parity block, so we actually + // don't need any correction + continue; + } - // The following determines what - // bit to correct according to - // the syndrome value. - if (s == 3) correction = 0x01; - if (s == 5) correction = 0x02; - if (s == 6) correction = 0x04; - if (s == 7) correction = 0x08; - if (s == 9) correction = 0x10; - if (s == 10) correction = 0x20; - if (s == 11) correction = 0x40; - if (s == 12) correction = 0x80; + // The following determines what + // bit to correct according to + // the syndrome value. + if (s == 3) correction = 0x01; + if (s == 5) correction = 0x02; + if (s == 6) correction = 0x04; + if (s == 7) correction = 0x08; + if (s == 9) correction = 0x10; + if (s == 10) correction = 0x20; + if (s == 11) correction = 0x40; + if (s == 12) correction = 0x80; - // And finally we apply the correction - if (i == 1) a ^= correction; - if (i == 0) b ^= correction; + // And finally we apply the correction + if (i == 1) a ^= correction; + if (i == 0) b ^= correction; - // This is just for testing purposes. - // Nice to know when corrections were - // actually made. - if (s != 0) mp1->correctionsMade += 1; - } - } + // This is just for testing purposes. + // Nice to know when corrections were + // actually made. + if (s != 0) mp1->correctionsMade += 1; + } + } - // We now update the checksum of the packet - // with the deinterleaved and possibly - // corrected bytes. - mp1->checksum_in ^= a; - mp1->checksum_in ^= b; - mp1->buffer[mp1->packetLength-(MP1_DATA_BLOCK_SIZE)+((i/3)*2)] = a; - mp1->buffer[mp1->packetLength-(MP1_DATA_BLOCK_SIZE-1)+((i/3)*2)] = b; - } + // We now update the checksum of the packet + // with the deinterleaved and possibly + // corrected bytes. + mp1->checksum_in ^= a; + mp1->checksum_in ^= b; + mp1->buffer[mp1->packetLength-(MP1_DATA_BLOCK_SIZE)+((i/3)*2)] = a; + mp1->buffer[mp1->packetLength-(MP1_DATA_BLOCK_SIZE-1)+((i/3)*2)] = b; + } - continue; - } - } - ///////////////////////////////////////////// - // End of forward error correction block // - ///////////////////////////////////////////// - - // This next part of the poll function handles - // the reading from the modem, and looks for - // starts and ends of transmissions. It also - // handles escape characters by discarding them - // so they don't get put into the output data. + continue; + } + } + ///////////////////////////////////////////// + // End of forward error correction block // + ///////////////////////////////////////////// + + // This next part of the poll function handles + // the reading from the modem, and looks for + // starts and ends of transmissions. It also + // handles escape characters by discarding them + // so they don't get put into the output data. - // Let's first check if we have read an HDLC_FLAG. - if (!mp1->escape && byte == HDLC_FLAG) { - // We are not in an escape sequence and we - // found a HDLC_FLAG. This can mean two things: - if (mp1->readLength >= MP1_MIN_FRAME_LENGTH) { - // We already have more data than the minimum - // frame length, which means the flag signifies - // the end of the packet. Pass control to the - // decoder. - // - // We also set the settle timer to indicate - // the time the frame completed reading. - mp1->settleTimer = timer_clock(); - if ((mp1->checksum_in & 0xff) == 0x00) { - if (SERIAL_DEBUG) kprintf("[CHK-OK] [C=%d] ", mp1->correctionsMade); - mp1Decode(mp1); - } else { - // Checksum was incorrect, we don't do anything, - // but you can enable the decode anyway, if you - // need it for testing or debugging - if (PASSALL) { - if (SERIAL_DEBUG) kprintf("[CHK-ER] [C=%d] ", mp1->correctionsMade); - mp1Decode(mp1); - } - } - } - // If the above is not the case, this must be the - // beginning of a frame - mp1->reading = true; - mp1->packetLength = 0; - mp1->readLength = 0; - mp1->checksum_in = MP1_CHECKSUM_INIT; - mp1->correctionsMade = 0; + // Let's first check if we have read an HDLC_FLAG. + if (!mp1->escape && byte == HDLC_FLAG) { + // We are not in an escape sequence and we + // found a HDLC_FLAG. This can mean two things: + if (mp1->readLength >= MP1_MIN_FRAME_LENGTH) { + // We already have more data than the minimum + // frame length, which means the flag signifies + // the end of the packet. Pass control to the + // decoder. + // + // We also set the settle timer to indicate + // the time the frame completed reading. + mp1->settleTimer = timer_clock(); + if ((mp1->checksum_in & 0xff) == 0x00) { + if (SERIAL_DEBUG) kprintf("[CHK-OK] [C=%d] ", mp1->correctionsMade); + mp1Decode(mp1); + } else { + // Checksum was incorrect, we don't do anything, + // but you can enable the decode anyway, if you + // need it for testing or debugging + if (PASSALL) { + if (SERIAL_DEBUG) kprintf("[CHK-ER] [C=%d] ", mp1->correctionsMade); + mp1Decode(mp1); + } + } + } + // If the above is not the case, this must be the + // beginning of a frame + mp1->reading = true; + mp1->packetLength = 0; + mp1->readLength = 0; + mp1->checksum_in = MP1_CHECKSUM_INIT; + mp1->correctionsMade = 0; - // We have indicated that we are reading, - // and reset the length counter. Now we'll - // continue to the next byte. - continue; - } + // We have indicated that we are reading, + // and reset the length counter. Now we'll + // continue to the next byte. + continue; + } - if (!mp1->escape && byte == HDLC_RESET) { - // Not good, we got a reset. The transmitting - // party may have encountered an error. We'll - // stop receiving this packet immediately. - mp1->reading = false; - continue; - } + if (!mp1->escape && byte == HDLC_RESET) { + // Not good, we got a reset. The transmitting + // party may have encountered an error. We'll + // stop receiving this packet immediately. + mp1->reading = false; + continue; + } - if (!mp1->escape && byte == AX25_ESC) { - // We found an escape character. We'll set - // the escape seqeunce indicator so we don't - // interpret the next byte as a reset or flag - mp1->escape = true; + if (!mp1->escape && byte == AX25_ESC) { + // We found an escape character. We'll set + // the escape seqeunce indicator so we don't + // interpret the next byte as a reset or flag + mp1->escape = true; - // We then continue reading the next byte. - continue; - } + // We then continue reading the next byte. + continue; + } - // Now let's get to the actual reading of the data - if (mp1->reading) { - 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 - // bytes, they will be processed by the error - // correction part above. - mp1->buffer[mp1->packetLength++] = byte; - } else { - // If not, we have a problem: The buffer has overrun - // We need to stop receiving, and the packet will be - // dropped :( - mp1->reading = false; - } - } + // Now let's get to the actual reading of the data + if (mp1->reading) { + 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 + // bytes, they will be processed by the error + // correction part above. + mp1->buffer[mp1->packetLength++] = byte; + } else { + // If not, we have a problem: The buffer has overrun + // We need to stop receiving, and the packet will be + // dropped :( + mp1->reading = false; + } + } - // We need to set the escape sequence indicator back - // to false after each byte. - mp1->escape = false; - } + // We need to set the escape sequence indicator back + // to false after each byte. + mp1->escape = false; + } - if (kfile_error(mp1->modem)) { - // If there was an error from the modem, we'll be rude - // and just reset it. No error handling is done for now. - kfile_clearerr(mp1->modem); - } + if (kfile_error(mp1->modem)) { + // If there was an error from the modem, we'll be rude + // and just reset it. No error handling is done for now. + kfile_clearerr(mp1->modem); + } } // This is called to actually send the bytes // after they have been interleaved static void mp1WriteByte(MP1 *mp1, uint8_t byte) { - // If we are sending something that looks - // like an HDLC special byte, send an escape - // character first - if (byte == HDLC_FLAG || - byte == HDLC_RESET || - byte == AX25_ESC) { - kfile_putc(AX25_ESC, mp1->modem); - } - kfile_putc(byte, mp1->modem); + // If we are sending something that looks + // like an HDLC special byte, send an escape + // character first + if (byte == HDLC_FLAG || + byte == HDLC_RESET || + byte == AX25_ESC) { + kfile_putc(AX25_ESC, mp1->modem); + } + kfile_putc(byte, mp1->modem); } // This is an intermediary function that @@ -388,187 +388,187 @@ 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) { - mp1Interleave(mp1, byte); + mp1Interleave(mp1, byte); - if (sendParityBlock) { - uint8_t p = mp1ParityBlock(lastByte, byte); - mp1Interleave(mp1, p); - } + if (sendParityBlock) { + uint8_t p = mp1ParityBlock(lastByte, byte); + mp1Interleave(mp1, p); + } - lastByte = byte; - sendParityBlock ^= true; + lastByte = byte; + sendParityBlock ^= true; } // This function accepts a buffer with data // 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; + // Reset our parity tx indicator + sendParityBlock = false; - // Open transmitter and wait for MP1_TXDELAY msecs - AFSK_HW_PTT_ON(); - ticks_t start = timer_clock(); - #if MP1_USE_TX_QUEUE - if (!mp1->queueProcessing) { - while (timer_clock() - start < ms_to_ticks(MP1_TXDELAY)) { - cpu_relax(); - } - } - #else - while (timer_clock() - start < ms_to_ticks(MP1_TXDELAY)) { - cpu_relax(); - } - #endif + // Open transmitter and wait for MP1_TXDELAY msecs + AFSK_HW_PTT_ON(); + ticks_t start = timer_clock(); + #if MP1_USE_TX_QUEUE + if (!mp1->queueProcessing) { + while (timer_clock() - start < ms_to_ticks(MP1_TXDELAY)) { + cpu_relax(); + } + } + #else + while (timer_clock() - start < ms_to_ticks(MP1_TXDELAY)) { + cpu_relax(); + } + #endif - // Get the transmit data buffer - uint8_t *buffer = (uint8_t *)_buffer; + // Get the transmit data buffer + uint8_t *buffer = (uint8_t *)_buffer; - // Initialize checksum to zero - mp1->checksum_out = MP1_CHECKSUM_INIT; + // Initialize checksum to zero + mp1->checksum_out = MP1_CHECKSUM_INIT; - // We also reset the interleave counter to zero - mp1->interleaveCounter = 0; + // We also reset the interleave counter to zero + mp1->interleaveCounter = 0; - // We start out assuming we should not use - // compression. - bool packetCompression = false; + // We start out assuming we should not use + // compression. + bool packetCompression = false; - // We then try to compress the data to see - // if we can save some space with compression. - #if MP1_ENABLE_COMPRESSION - size_t compressedSize = compress(buffer, length); - if (compressedSize != 0 && compressedSize < length) { - // Compression saved us some space, we'll - // send the paket compressed - packetCompression = true; - // Write the compressed data into the - // outgoing data buffer - memcpy(buffer, compressionBuffer, compressedSize); - - // Make sure to set the length of the - // data to the new (compressed) length - length = compressedSize; - } else { - // We are not going to use compression, - // so we don't do anything. - } - #endif + // We then try to compress the data to see + // if we can save some space with compression. + #if MP1_ENABLE_COMPRESSION + size_t compressedSize = compress(buffer, length); + if (compressedSize != 0 && compressedSize < length) { + // Compression saved us some space, we'll + // send the paket compressed + packetCompression = true; + // Write the compressed data into the + // outgoing data buffer + memcpy(buffer, compressionBuffer, compressedSize); + + // Make sure to set the length of the + // data to the new (compressed) length + length = compressedSize; + } else { + // We are not going to use compression, + // so we don't do anything. + } + #endif - // Transmit the HDLC_FLAG to signify start of TX - kfile_putc(HDLC_FLAG, mp1->modem); - - // We now need to construct a header, that - // can tell the receiving end whether the - // packet is compressed. Since a packet must - // have an even number of total payload bytes - // (including the header), we check the length - // of the outgoing data, and if it is not even, - // we add a single byte of padding to the - // packet. Remember that we also send a single - // byte checksum at the end of the packet, so - // the header and checksum bytes together don't - // change whether the payload length is even - // or not. The payload length needs to be even - // since we are sending a parity byte for every - // two data bytes sent, and because interleaving - // happens in blocks of three bytes. - uint8_t header = 0x00; + // Transmit the HDLC_FLAG to signify start of TX + kfile_putc(HDLC_FLAG, mp1->modem); + + // We now need to construct a header, that + // can tell the receiving end whether the + // packet is compressed. Since a packet must + // have an even number of total payload bytes + // (including the header), we check the length + // of the outgoing data, and if it is not even, + // we add a single byte of padding to the + // packet. Remember that we also send a single + // byte checksum at the end of the packet, so + // the header and checksum bytes together don't + // change whether the payload length is even + // or not. The payload length needs to be even + // since we are sending a parity byte for every + // two data bytes sent, and because interleaving + // happens in blocks of three bytes. + uint8_t header = 0x00; - // If we are using compression, set the - // appropriate header flag to true. - if (packetCompression) header ^= MP1_HEADER_COMPRESSION; + // If we are using compression, set the + // appropriate header flag to true. + if (packetCompression) header ^= MP1_HEADER_COMPRESSION; - // We check if the data length matches our - // required block size - uint8_t padding = (length+2) % MP1_DATA_BLOCK_SIZE; + // We check if the data length matches our + // required block size + uint8_t padding = (length+2) % MP1_DATA_BLOCK_SIZE; - if (padding != 0) { - // If it does not, we set the appropriate - // header flag to indicate that we are - // padding this packet. - header ^= MP1_HEADER_PADDED; + if (padding != 0) { + // If it does not, we set the appropriate + // header flag to indicate that we are + // padding this packet. + header ^= MP1_HEADER_PADDED; - // And calculate how much padding we need - padding = MP1_DATA_BLOCK_SIZE - padding; + // And calculate how much padding we need + padding = MP1_DATA_BLOCK_SIZE - padding; - // And put the amount of padding we are - // going to append in the header - header ^= (padding << 4); + // And put the amount of padding we are + // going to append in the header + header ^= (padding << 4); - // We then update the checksum with the - // header byte and queue it for transmit - mp1->checksum_out = mp1->checksum_out ^ header; - mp1Putbyte(mp1, header); + // We then update the checksum with the + // header byte and queue it for transmit + mp1->checksum_out = mp1->checksum_out ^ header; + mp1Putbyte(mp1, header); - // We now update the checksum with the - // padding bytes, and queue these for - // transmission as well. - for (int i = 0; i < padding; i++) { - mp1->checksum_out = mp1->checksum_out ^ MP1_PADDING; - mp1Putbyte(mp1, MP1_PADDING); - } - } else { - // If the length already matches, we - // just update the checksum with the - // header byte and queue it. - mp1->checksum_out = mp1->checksum_out ^ header; - mp1Putbyte(mp1, header); - } + // We now update the checksum with the + // padding bytes, and queue these for + // transmission as well. + for (int i = 0; i < padding; i++) { + mp1->checksum_out = mp1->checksum_out ^ MP1_PADDING; + mp1Putbyte(mp1, MP1_PADDING); + } + } else { + // If the length already matches, we + // just update the checksum with the + // header byte and queue it. + mp1->checksum_out = mp1->checksum_out ^ header; + mp1Putbyte(mp1, header); + } - // Now we'll transmit the actual data of - // the packet. We continously increment the - // pointer address of the buffer while - // passing it to the intermediary output - // function. Everytime the interleaving - // counter reaches 3, a block will be - // transmitted. - while (length--) { - mp1->checksum_out = mp1->checksum_out ^ *buffer; - mp1Putbyte(mp1, *buffer++); - } + // Now we'll transmit the actual data of + // the packet. We continously increment the + // pointer address of the buffer while + // passing it to the intermediary output + // function. Everytime the interleaving + // counter reaches 3, a block will be + // transmitted. + while (length--) { + mp1->checksum_out = mp1->checksum_out ^ *buffer; + mp1Putbyte(mp1, *buffer++); + } - // Finally we write the checksum to the - // end of the packet. - mp1Putbyte(mp1, mp1->checksum_out); + // Finally we write the checksum to the + // end of the packet. + mp1Putbyte(mp1, mp1->checksum_out); - // And transmit a HDLC_FLAG to signify - // end of the transmission. - kfile_putc(HDLC_FLAG, mp1->modem); + // And transmit a HDLC_FLAG to signify + // end of the transmission. + kfile_putc(HDLC_FLAG, mp1->modem); - // Turn off manual PTT - #if MP1_USE_TX_QUEUE - if (!mp1->queueProcessing) AFSK_HW_PTT_OFF(); - #else - AFSK_HW_PTT_OFF(); - #endif + // Turn off manual PTT + #if MP1_USE_TX_QUEUE + if (!mp1->queueProcessing) AFSK_HW_PTT_OFF(); + #else + AFSK_HW_PTT_OFF(); + #endif } // This function accepts a frame and stores // it in the transmission queue #if MP1_USE_TX_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); - } - } + 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); + } + } #endif // This function processes the transmission // queue. #if MP1_USE_TX_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(); - } + 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(); + } #endif // A simple form of P-persistent CSMA. @@ -579,44 +579,44 @@ void mp1Send(MP1 *mp1, void *_buffer, size_t length) { // number, and if it is less than // MP1_P_PERSISTENCE, we transmit. bool mp1CarrierSense(MP1 *mp1) { - if (MP1_ENABLE_CSMA) { - if (mp1->randomSeed == 0) { - mp1->randomSeed = timer_clock(); - srand(mp1->randomSeed); - } + if (MP1_ENABLE_CSMA) { + if (mp1->randomSeed == 0) { + mp1->randomSeed = timer_clock(); + srand(mp1->randomSeed); + } - if (timer_clock() - mp1->settleTimer > ms_to_ticks(MP1_SETTLE_TIME)) { - uint8_t r = rand() % 255; - if (r < MP1_P_PERSISTENCE) { - return false; - } else { - mp1->settleTimer = timer_clock() - MP1_SETTLE_TIME + MP1_SLOT_TIME; - return true; - } - } else { - return true; - } - } else { - return false; - } + if (timer_clock() - mp1->settleTimer > ms_to_ticks(MP1_SETTLE_TIME)) { + uint8_t r = rand() % 255; + if (r < MP1_P_PERSISTENCE) { + return false; + } else { + mp1->settleTimer = timer_clock() - MP1_SETTLE_TIME + MP1_SLOT_TIME; + return true; + } + } else { + return true; + } + } else { + return false; + } } // 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 + // 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 @@ -634,28 +634,28 @@ int freeRam(void) { // the Heatshrink library #if MP1_ENABLE_COMPRESSION size_t compress(uint8_t *input, size_t length) { - heatshrink_encoder *hse = heatshrink_encoder_alloc(8, 4); - if (hse == NULL) { - if (SERIAL_DEBUG) kprintf("Could not allocate compressor\n"); - return 0; - } + heatshrink_encoder *hse = heatshrink_encoder_alloc(8, 4); + if (hse == NULL) { + if (SERIAL_DEBUG) kprintf("Could not allocate compressor\n"); + return 0; + } - size_t written = 0; - size_t sunk = 0; - heatshrink_encoder_sink(hse, input, length, &sunk); - int status = heatshrink_encoder_finish(hse); + size_t written = 0; + size_t sunk = 0; + heatshrink_encoder_sink(hse, input, length, &sunk); + int status = heatshrink_encoder_finish(hse); - if (sunk < length) { - heatshrink_encoder_free(hse); - return 0; - } else { - if (status == HSER_FINISH_MORE) { - heatshrink_encoder_poll(hse, compressionBuffer, MP1_MAX_FRAME_LENGTH, &written); - } - } + if (sunk < length) { + heatshrink_encoder_free(hse); + return 0; + } else { + if (status == HSER_FINISH_MORE) { + heatshrink_encoder_poll(hse, compressionBuffer, MP1_MAX_FRAME_LENGTH, &written); + } + } - heatshrink_encoder_free(hse); - return written; + heatshrink_encoder_free(hse); + return written; } #endif @@ -663,28 +663,28 @@ size_t compress(uint8_t *input, size_t length) { // the Heatshrink library #if MP1_ENABLE_COMPRESSION size_t decompress(uint8_t *input, size_t length) { - heatshrink_decoder *hsd = heatshrink_decoder_alloc(MP1_MAX_FRAME_LENGTH, 8, 4); - if (hsd == NULL) { - if (SERIAL_DEBUG) kprintf("Could not allocate decompressor\n"); - return 0; - } + heatshrink_decoder *hsd = heatshrink_decoder_alloc(MP1_MAX_FRAME_LENGTH, 8, 4); + if (hsd == NULL) { + if (SERIAL_DEBUG) kprintf("Could not allocate decompressor\n"); + return 0; + } - size_t written = 0; - size_t sunk = 0; - heatshrink_decoder_sink(hsd, input, length, &sunk); - int status = heatshrink_decoder_finish(hsd); + size_t written = 0; + size_t sunk = 0; + heatshrink_decoder_sink(hsd, input, length, &sunk); + int status = heatshrink_decoder_finish(hsd); - if (sunk < length) { - heatshrink_decoder_free(hsd); - return 0; - } else { - if (status == HSER_FINISH_MORE) { - heatshrink_decoder_poll(hsd, compressionBuffer, MP1_MAX_FRAME_LENGTH, &written); - } - } + if (sunk < length) { + heatshrink_decoder_free(hsd); + return 0; + } else { + if (status == HSER_FINISH_MORE) { + heatshrink_decoder_poll(hsd, compressionBuffer, MP1_MAX_FRAME_LENGTH, &written); + } + } - heatshrink_decoder_free(hsd); - return written; + heatshrink_decoder_free(hsd); + return written; } #endif @@ -715,325 +715,325 @@ size_t decompress(uint8_t *input, size_t length) { /////////////////////////////// void mp1Interleave(MP1 *mp1, uint8_t byte) { - mp1->interleaveOut[mp1->interleaveCounter] = byte; - mp1->interleaveCounter++; - if (mp1->interleaveCounter == MP1_INTERLEAVE_SIZE) { - // We have the bytes we need for interleaving - // in the buffer and are ready to interleave them. - #if MP1_INTERLEAVE_SIZE == 3 - // This is for 3-byte interleaving - uint8_t a = (GET_BIT(mp1->interleaveOut[0], 1) << 7) + - (GET_BIT(mp1->interleaveOut[1], 1) << 6) + - (GET_BIT(mp1->interleaveOut[2], 1) << 5) + - (GET_BIT(mp1->interleaveOut[0], 4) << 4) + - (GET_BIT(mp1->interleaveOut[1], 4) << 3) + - (GET_BIT(mp1->interleaveOut[2], 4) << 2) + - (GET_BIT(mp1->interleaveOut[0], 7) << 1) + - (GET_BIT(mp1->interleaveOut[1], 7)); - mp1WriteByte(mp1, a); + mp1->interleaveOut[mp1->interleaveCounter] = byte; + mp1->interleaveCounter++; + if (mp1->interleaveCounter == MP1_INTERLEAVE_SIZE) { + // We have the bytes we need for interleaving + // in the buffer and are ready to interleave them. + #if MP1_INTERLEAVE_SIZE == 3 + // This is for 3-byte interleaving + uint8_t a = (GET_BIT(mp1->interleaveOut[0], 1) << 7) + + (GET_BIT(mp1->interleaveOut[1], 1) << 6) + + (GET_BIT(mp1->interleaveOut[2], 1) << 5) + + (GET_BIT(mp1->interleaveOut[0], 4) << 4) + + (GET_BIT(mp1->interleaveOut[1], 4) << 3) + + (GET_BIT(mp1->interleaveOut[2], 4) << 2) + + (GET_BIT(mp1->interleaveOut[0], 7) << 1) + + (GET_BIT(mp1->interleaveOut[1], 7)); + mp1WriteByte(mp1, a); - uint8_t b = (GET_BIT(mp1->interleaveOut[2], 2) << 7) + - (GET_BIT(mp1->interleaveOut[0], 2) << 6) + - (GET_BIT(mp1->interleaveOut[1], 2) << 5) + - (GET_BIT(mp1->interleaveOut[2], 5) << 4) + - (GET_BIT(mp1->interleaveOut[0], 5) << 3) + - (GET_BIT(mp1->interleaveOut[1], 5) << 2) + - (GET_BIT(mp1->interleaveOut[2], 7) << 1) + - (GET_BIT(mp1->interleaveOut[0], 8)); - mp1WriteByte(mp1, b); + uint8_t b = (GET_BIT(mp1->interleaveOut[2], 2) << 7) + + (GET_BIT(mp1->interleaveOut[0], 2) << 6) + + (GET_BIT(mp1->interleaveOut[1], 2) << 5) + + (GET_BIT(mp1->interleaveOut[2], 5) << 4) + + (GET_BIT(mp1->interleaveOut[0], 5) << 3) + + (GET_BIT(mp1->interleaveOut[1], 5) << 2) + + (GET_BIT(mp1->interleaveOut[2], 7) << 1) + + (GET_BIT(mp1->interleaveOut[0], 8)); + mp1WriteByte(mp1, b); - uint8_t c = (GET_BIT(mp1->interleaveOut[1], 6) << 7) + - (GET_BIT(mp1->interleaveOut[2], 3) << 6) + - (GET_BIT(mp1->interleaveOut[0], 3) << 5) + - (GET_BIT(mp1->interleaveOut[1], 3) << 4) + - (GET_BIT(mp1->interleaveOut[2], 6) << 3) + - (GET_BIT(mp1->interleaveOut[0], 6) << 2) + - (GET_BIT(mp1->interleaveOut[1], 8) << 1) + - (GET_BIT(mp1->interleaveOut[2], 8)); + uint8_t c = (GET_BIT(mp1->interleaveOut[1], 6) << 7) + + (GET_BIT(mp1->interleaveOut[2], 3) << 6) + + (GET_BIT(mp1->interleaveOut[0], 3) << 5) + + (GET_BIT(mp1->interleaveOut[1], 3) << 4) + + (GET_BIT(mp1->interleaveOut[2], 6) << 3) + + (GET_BIT(mp1->interleaveOut[0], 6) << 2) + + (GET_BIT(mp1->interleaveOut[1], 8) << 1) + + (GET_BIT(mp1->interleaveOut[2], 8)); - mp1WriteByte(mp1, c); - #elif MP1_INTERLEAVE_SIZE == 12 - // This is for 12-byte interleaving - uint8_t a = (GET_BIT(mp1->interleaveOut[0], 1) << 7) + - (GET_BIT(mp1->interleaveOut[1], 1) << 6) + - (GET_BIT(mp1->interleaveOut[3], 1) << 5) + - (GET_BIT(mp1->interleaveOut[4], 1) << 4) + - (GET_BIT(mp1->interleaveOut[6], 1) << 3) + - (GET_BIT(mp1->interleaveOut[7], 1) << 2) + - (GET_BIT(mp1->interleaveOut[9], 1) << 1) + - (GET_BIT(mp1->interleaveOut[10],1)); - mp1WriteByte(mp1, a); + mp1WriteByte(mp1, c); + #elif MP1_INTERLEAVE_SIZE == 12 + // This is for 12-byte interleaving + uint8_t a = (GET_BIT(mp1->interleaveOut[0], 1) << 7) + + (GET_BIT(mp1->interleaveOut[1], 1) << 6) + + (GET_BIT(mp1->interleaveOut[3], 1) << 5) + + (GET_BIT(mp1->interleaveOut[4], 1) << 4) + + (GET_BIT(mp1->interleaveOut[6], 1) << 3) + + (GET_BIT(mp1->interleaveOut[7], 1) << 2) + + (GET_BIT(mp1->interleaveOut[9], 1) << 1) + + (GET_BIT(mp1->interleaveOut[10],1)); + mp1WriteByte(mp1, a); - uint8_t b = (GET_BIT(mp1->interleaveOut[0], 2) << 7) + - (GET_BIT(mp1->interleaveOut[1], 2) << 6) + - (GET_BIT(mp1->interleaveOut[3], 2) << 5) + - (GET_BIT(mp1->interleaveOut[4], 2) << 4) + - (GET_BIT(mp1->interleaveOut[6], 2) << 3) + - (GET_BIT(mp1->interleaveOut[7], 2) << 2) + - (GET_BIT(mp1->interleaveOut[9], 2) << 1) + - (GET_BIT(mp1->interleaveOut[10],2)); - mp1WriteByte(mp1, b); + uint8_t b = (GET_BIT(mp1->interleaveOut[0], 2) << 7) + + (GET_BIT(mp1->interleaveOut[1], 2) << 6) + + (GET_BIT(mp1->interleaveOut[3], 2) << 5) + + (GET_BIT(mp1->interleaveOut[4], 2) << 4) + + (GET_BIT(mp1->interleaveOut[6], 2) << 3) + + (GET_BIT(mp1->interleaveOut[7], 2) << 2) + + (GET_BIT(mp1->interleaveOut[9], 2) << 1) + + (GET_BIT(mp1->interleaveOut[10],2)); + mp1WriteByte(mp1, b); - uint8_t c = (GET_BIT(mp1->interleaveOut[0], 3) << 7) + - (GET_BIT(mp1->interleaveOut[1], 3) << 6) + - (GET_BIT(mp1->interleaveOut[3], 3) << 5) + - (GET_BIT(mp1->interleaveOut[4], 3) << 4) + - (GET_BIT(mp1->interleaveOut[6], 3) << 3) + - (GET_BIT(mp1->interleaveOut[7], 3) << 2) + - (GET_BIT(mp1->interleaveOut[9], 3) << 1) + - (GET_BIT(mp1->interleaveOut[10],3)); - mp1WriteByte(mp1, c); + uint8_t c = (GET_BIT(mp1->interleaveOut[0], 3) << 7) + + (GET_BIT(mp1->interleaveOut[1], 3) << 6) + + (GET_BIT(mp1->interleaveOut[3], 3) << 5) + + (GET_BIT(mp1->interleaveOut[4], 3) << 4) + + (GET_BIT(mp1->interleaveOut[6], 3) << 3) + + (GET_BIT(mp1->interleaveOut[7], 3) << 2) + + (GET_BIT(mp1->interleaveOut[9], 3) << 1) + + (GET_BIT(mp1->interleaveOut[10],3)); + mp1WriteByte(mp1, c); - uint8_t d = (GET_BIT(mp1->interleaveOut[0], 4) << 7) + - (GET_BIT(mp1->interleaveOut[1], 4) << 6) + - (GET_BIT(mp1->interleaveOut[3], 4) << 5) + - (GET_BIT(mp1->interleaveOut[4], 4) << 4) + - (GET_BIT(mp1->interleaveOut[6], 4) << 3) + - (GET_BIT(mp1->interleaveOut[7], 4) << 2) + - (GET_BIT(mp1->interleaveOut[9], 4) << 1) + - (GET_BIT(mp1->interleaveOut[10],4)); - mp1WriteByte(mp1, d); + uint8_t d = (GET_BIT(mp1->interleaveOut[0], 4) << 7) + + (GET_BIT(mp1->interleaveOut[1], 4) << 6) + + (GET_BIT(mp1->interleaveOut[3], 4) << 5) + + (GET_BIT(mp1->interleaveOut[4], 4) << 4) + + (GET_BIT(mp1->interleaveOut[6], 4) << 3) + + (GET_BIT(mp1->interleaveOut[7], 4) << 2) + + (GET_BIT(mp1->interleaveOut[9], 4) << 1) + + (GET_BIT(mp1->interleaveOut[10],4)); + mp1WriteByte(mp1, d); - uint8_t e = (GET_BIT(mp1->interleaveOut[0], 5) << 7) + - (GET_BIT(mp1->interleaveOut[1], 5) << 6) + - (GET_BIT(mp1->interleaveOut[3], 5) << 5) + - (GET_BIT(mp1->interleaveOut[4], 5) << 4) + - (GET_BIT(mp1->interleaveOut[6], 5) << 3) + - (GET_BIT(mp1->interleaveOut[7], 5) << 2) + - (GET_BIT(mp1->interleaveOut[9], 5) << 1) + - (GET_BIT(mp1->interleaveOut[10],5)); - mp1WriteByte(mp1, e); + uint8_t e = (GET_BIT(mp1->interleaveOut[0], 5) << 7) + + (GET_BIT(mp1->interleaveOut[1], 5) << 6) + + (GET_BIT(mp1->interleaveOut[3], 5) << 5) + + (GET_BIT(mp1->interleaveOut[4], 5) << 4) + + (GET_BIT(mp1->interleaveOut[6], 5) << 3) + + (GET_BIT(mp1->interleaveOut[7], 5) << 2) + + (GET_BIT(mp1->interleaveOut[9], 5) << 1) + + (GET_BIT(mp1->interleaveOut[10],5)); + mp1WriteByte(mp1, e); - uint8_t f = (GET_BIT(mp1->interleaveOut[0], 6) << 7) + - (GET_BIT(mp1->interleaveOut[1], 6) << 6) + - (GET_BIT(mp1->interleaveOut[3], 6) << 5) + - (GET_BIT(mp1->interleaveOut[4], 6) << 4) + - (GET_BIT(mp1->interleaveOut[6], 6) << 3) + - (GET_BIT(mp1->interleaveOut[7], 6) << 2) + - (GET_BIT(mp1->interleaveOut[9], 6) << 1) + - (GET_BIT(mp1->interleaveOut[10],6)); - mp1WriteByte(mp1, f); + uint8_t f = (GET_BIT(mp1->interleaveOut[0], 6) << 7) + + (GET_BIT(mp1->interleaveOut[1], 6) << 6) + + (GET_BIT(mp1->interleaveOut[3], 6) << 5) + + (GET_BIT(mp1->interleaveOut[4], 6) << 4) + + (GET_BIT(mp1->interleaveOut[6], 6) << 3) + + (GET_BIT(mp1->interleaveOut[7], 6) << 2) + + (GET_BIT(mp1->interleaveOut[9], 6) << 1) + + (GET_BIT(mp1->interleaveOut[10],6)); + mp1WriteByte(mp1, f); - uint8_t g = (GET_BIT(mp1->interleaveOut[0], 7) << 7) + - (GET_BIT(mp1->interleaveOut[1], 7) << 6) + - (GET_BIT(mp1->interleaveOut[3], 7) << 5) + - (GET_BIT(mp1->interleaveOut[4], 7) << 4) + - (GET_BIT(mp1->interleaveOut[6], 7) << 3) + - (GET_BIT(mp1->interleaveOut[7], 7) << 2) + - (GET_BIT(mp1->interleaveOut[9], 7) << 1) + - (GET_BIT(mp1->interleaveOut[10],7)); - mp1WriteByte(mp1, g); + uint8_t g = (GET_BIT(mp1->interleaveOut[0], 7) << 7) + + (GET_BIT(mp1->interleaveOut[1], 7) << 6) + + (GET_BIT(mp1->interleaveOut[3], 7) << 5) + + (GET_BIT(mp1->interleaveOut[4], 7) << 4) + + (GET_BIT(mp1->interleaveOut[6], 7) << 3) + + (GET_BIT(mp1->interleaveOut[7], 7) << 2) + + (GET_BIT(mp1->interleaveOut[9], 7) << 1) + + (GET_BIT(mp1->interleaveOut[10],7)); + mp1WriteByte(mp1, g); - uint8_t h = (GET_BIT(mp1->interleaveOut[0], 8) << 7) + - (GET_BIT(mp1->interleaveOut[1], 8) << 6) + - (GET_BIT(mp1->interleaveOut[3], 8) << 5) + - (GET_BIT(mp1->interleaveOut[4], 8) << 4) + - (GET_BIT(mp1->interleaveOut[6], 8) << 3) + - (GET_BIT(mp1->interleaveOut[7], 8) << 2) + - (GET_BIT(mp1->interleaveOut[9], 8) << 1) + - (GET_BIT(mp1->interleaveOut[10],8)); - mp1WriteByte(mp1, h); + uint8_t h = (GET_BIT(mp1->interleaveOut[0], 8) << 7) + + (GET_BIT(mp1->interleaveOut[1], 8) << 6) + + (GET_BIT(mp1->interleaveOut[3], 8) << 5) + + (GET_BIT(mp1->interleaveOut[4], 8) << 4) + + (GET_BIT(mp1->interleaveOut[6], 8) << 3) + + (GET_BIT(mp1->interleaveOut[7], 8) << 2) + + (GET_BIT(mp1->interleaveOut[9], 8) << 1) + + (GET_BIT(mp1->interleaveOut[10],8)); + mp1WriteByte(mp1, h); - uint8_t p = (GET_BIT(mp1->interleaveOut[2], 1) << 7) + - (GET_BIT(mp1->interleaveOut[2], 5) << 6) + - (GET_BIT(mp1->interleaveOut[5], 1) << 5) + - (GET_BIT(mp1->interleaveOut[5], 5) << 4) + - (GET_BIT(mp1->interleaveOut[8], 1) << 3) + - (GET_BIT(mp1->interleaveOut[8], 5) << 2) + - (GET_BIT(mp1->interleaveOut[11],1) << 1) + - (GET_BIT(mp1->interleaveOut[11],5)); - mp1WriteByte(mp1, p); + uint8_t p = (GET_BIT(mp1->interleaveOut[2], 1) << 7) + + (GET_BIT(mp1->interleaveOut[2], 5) << 6) + + (GET_BIT(mp1->interleaveOut[5], 1) << 5) + + (GET_BIT(mp1->interleaveOut[5], 5) << 4) + + (GET_BIT(mp1->interleaveOut[8], 1) << 3) + + (GET_BIT(mp1->interleaveOut[8], 5) << 2) + + (GET_BIT(mp1->interleaveOut[11],1) << 1) + + (GET_BIT(mp1->interleaveOut[11],5)); + mp1WriteByte(mp1, p); - uint8_t q = (GET_BIT(mp1->interleaveOut[2], 2) << 7) + - (GET_BIT(mp1->interleaveOut[2], 6) << 6) + - (GET_BIT(mp1->interleaveOut[5], 2) << 5) + - (GET_BIT(mp1->interleaveOut[5], 6) << 4) + - (GET_BIT(mp1->interleaveOut[8], 2) << 3) + - (GET_BIT(mp1->interleaveOut[8], 6) << 2) + - (GET_BIT(mp1->interleaveOut[11],2) << 1) + - (GET_BIT(mp1->interleaveOut[11],6)); - mp1WriteByte(mp1, q); + uint8_t q = (GET_BIT(mp1->interleaveOut[2], 2) << 7) + + (GET_BIT(mp1->interleaveOut[2], 6) << 6) + + (GET_BIT(mp1->interleaveOut[5], 2) << 5) + + (GET_BIT(mp1->interleaveOut[5], 6) << 4) + + (GET_BIT(mp1->interleaveOut[8], 2) << 3) + + (GET_BIT(mp1->interleaveOut[8], 6) << 2) + + (GET_BIT(mp1->interleaveOut[11],2) << 1) + + (GET_BIT(mp1->interleaveOut[11],6)); + mp1WriteByte(mp1, q); - uint8_t s = (GET_BIT(mp1->interleaveOut[2], 3) << 7) + - (GET_BIT(mp1->interleaveOut[2], 7) << 6) + - (GET_BIT(mp1->interleaveOut[5], 3) << 5) + - (GET_BIT(mp1->interleaveOut[5], 7) << 4) + - (GET_BIT(mp1->interleaveOut[8], 3) << 3) + - (GET_BIT(mp1->interleaveOut[8], 7) << 2) + - (GET_BIT(mp1->interleaveOut[11],3) << 1) + - (GET_BIT(mp1->interleaveOut[11],7)); - mp1WriteByte(mp1, s); + uint8_t s = (GET_BIT(mp1->interleaveOut[2], 3) << 7) + + (GET_BIT(mp1->interleaveOut[2], 7) << 6) + + (GET_BIT(mp1->interleaveOut[5], 3) << 5) + + (GET_BIT(mp1->interleaveOut[5], 7) << 4) + + (GET_BIT(mp1->interleaveOut[8], 3) << 3) + + (GET_BIT(mp1->interleaveOut[8], 7) << 2) + + (GET_BIT(mp1->interleaveOut[11],3) << 1) + + (GET_BIT(mp1->interleaveOut[11],7)); + mp1WriteByte(mp1, s); - uint8_t t = (GET_BIT(mp1->interleaveOut[2], 4) << 7) + - (GET_BIT(mp1->interleaveOut[2], 8) << 6) + - (GET_BIT(mp1->interleaveOut[5], 4) << 5) + - (GET_BIT(mp1->interleaveOut[5], 8) << 4) + - (GET_BIT(mp1->interleaveOut[8], 4) << 3) + - (GET_BIT(mp1->interleaveOut[8], 8) << 2) + - (GET_BIT(mp1->interleaveOut[11],4) << 1) + - (GET_BIT(mp1->interleaveOut[11],8)); - mp1WriteByte(mp1, t); + uint8_t t = (GET_BIT(mp1->interleaveOut[2], 4) << 7) + + (GET_BIT(mp1->interleaveOut[2], 8) << 6) + + (GET_BIT(mp1->interleaveOut[5], 4) << 5) + + (GET_BIT(mp1->interleaveOut[5], 8) << 4) + + (GET_BIT(mp1->interleaveOut[8], 4) << 3) + + (GET_BIT(mp1->interleaveOut[8], 8) << 2) + + (GET_BIT(mp1->interleaveOut[11],4) << 1) + + (GET_BIT(mp1->interleaveOut[11],8)); + mp1WriteByte(mp1, t); - #endif + #endif - mp1->interleaveCounter = 0; - } + mp1->interleaveCounter = 0; + } } void mp1Deinterleave(MP1 *mp1) { - #if MP1_INTERLEAVE_SIZE == 3 - uint8_t a = (GET_BIT(mp1->interleaveIn[0], 1) << 7) + - (GET_BIT(mp1->interleaveIn[1], 2) << 6) + - (GET_BIT(mp1->interleaveIn[2], 3) << 5) + - (GET_BIT(mp1->interleaveIn[0], 4) << 4) + - (GET_BIT(mp1->interleaveIn[1], 5) << 3) + - (GET_BIT(mp1->interleaveIn[2], 6) << 2) + - (GET_BIT(mp1->interleaveIn[0], 7) << 1) + - (GET_BIT(mp1->interleaveIn[1], 8)); + #if MP1_INTERLEAVE_SIZE == 3 + uint8_t a = (GET_BIT(mp1->interleaveIn[0], 1) << 7) + + (GET_BIT(mp1->interleaveIn[1], 2) << 6) + + (GET_BIT(mp1->interleaveIn[2], 3) << 5) + + (GET_BIT(mp1->interleaveIn[0], 4) << 4) + + (GET_BIT(mp1->interleaveIn[1], 5) << 3) + + (GET_BIT(mp1->interleaveIn[2], 6) << 2) + + (GET_BIT(mp1->interleaveIn[0], 7) << 1) + + (GET_BIT(mp1->interleaveIn[1], 8)); - uint8_t b = (GET_BIT(mp1->interleaveIn[0], 2) << 7) + - (GET_BIT(mp1->interleaveIn[1], 3) << 6) + - (GET_BIT(mp1->interleaveIn[2], 4) << 5) + - (GET_BIT(mp1->interleaveIn[0], 5) << 4) + - (GET_BIT(mp1->interleaveIn[1], 6) << 3) + - (GET_BIT(mp1->interleaveIn[2], 1) << 2) + - (GET_BIT(mp1->interleaveIn[0], 8) << 1) + - (GET_BIT(mp1->interleaveIn[2], 7)); + uint8_t b = (GET_BIT(mp1->interleaveIn[0], 2) << 7) + + (GET_BIT(mp1->interleaveIn[1], 3) << 6) + + (GET_BIT(mp1->interleaveIn[2], 4) << 5) + + (GET_BIT(mp1->interleaveIn[0], 5) << 4) + + (GET_BIT(mp1->interleaveIn[1], 6) << 3) + + (GET_BIT(mp1->interleaveIn[2], 1) << 2) + + (GET_BIT(mp1->interleaveIn[0], 8) << 1) + + (GET_BIT(mp1->interleaveIn[2], 7)); - uint8_t c = (GET_BIT(mp1->interleaveIn[0], 3) << 7) + - (GET_BIT(mp1->interleaveIn[1], 1) << 6) + - (GET_BIT(mp1->interleaveIn[2], 2) << 5) + - (GET_BIT(mp1->interleaveIn[0], 6) << 4) + - (GET_BIT(mp1->interleaveIn[1], 4) << 3) + - (GET_BIT(mp1->interleaveIn[2], 5) << 2) + - (GET_BIT(mp1->interleaveIn[1], 7) << 1) + - (GET_BIT(mp1->interleaveIn[2], 8)); + uint8_t c = (GET_BIT(mp1->interleaveIn[0], 3) << 7) + + (GET_BIT(mp1->interleaveIn[1], 1) << 6) + + (GET_BIT(mp1->interleaveIn[2], 2) << 5) + + (GET_BIT(mp1->interleaveIn[0], 6) << 4) + + (GET_BIT(mp1->interleaveIn[1], 4) << 3) + + (GET_BIT(mp1->interleaveIn[2], 5) << 2) + + (GET_BIT(mp1->interleaveIn[1], 7) << 1) + + (GET_BIT(mp1->interleaveIn[2], 8)); - mp1->interleaveIn[0] = a; - mp1->interleaveIn[1] = b; - mp1->interleaveIn[2] = c; - #elif MP1_INTERLEAVE_SIZE == 12 - uint8_t a = (GET_BIT(mp1->interleaveIn[0], 1) << 7) + - (GET_BIT(mp1->interleaveIn[1], 1) << 6) + - (GET_BIT(mp1->interleaveIn[2], 1) << 5) + - (GET_BIT(mp1->interleaveIn[3], 1) << 4) + - (GET_BIT(mp1->interleaveIn[4], 1) << 3) + - (GET_BIT(mp1->interleaveIn[5], 1) << 2) + - (GET_BIT(mp1->interleaveIn[6], 1) << 1) + - (GET_BIT(mp1->interleaveIn[7], 1)); + mp1->interleaveIn[0] = a; + mp1->interleaveIn[1] = b; + mp1->interleaveIn[2] = c; + #elif MP1_INTERLEAVE_SIZE == 12 + uint8_t a = (GET_BIT(mp1->interleaveIn[0], 1) << 7) + + (GET_BIT(mp1->interleaveIn[1], 1) << 6) + + (GET_BIT(mp1->interleaveIn[2], 1) << 5) + + (GET_BIT(mp1->interleaveIn[3], 1) << 4) + + (GET_BIT(mp1->interleaveIn[4], 1) << 3) + + (GET_BIT(mp1->interleaveIn[5], 1) << 2) + + (GET_BIT(mp1->interleaveIn[6], 1) << 1) + + (GET_BIT(mp1->interleaveIn[7], 1)); - uint8_t b = (GET_BIT(mp1->interleaveIn[0], 2) << 7) + - (GET_BIT(mp1->interleaveIn[1], 2) << 6) + - (GET_BIT(mp1->interleaveIn[2], 2) << 5) + - (GET_BIT(mp1->interleaveIn[3], 2) << 4) + - (GET_BIT(mp1->interleaveIn[4], 2) << 3) + - (GET_BIT(mp1->interleaveIn[5], 2) << 2) + - (GET_BIT(mp1->interleaveIn[6], 2) << 1) + - (GET_BIT(mp1->interleaveIn[7], 2)); + uint8_t b = (GET_BIT(mp1->interleaveIn[0], 2) << 7) + + (GET_BIT(mp1->interleaveIn[1], 2) << 6) + + (GET_BIT(mp1->interleaveIn[2], 2) << 5) + + (GET_BIT(mp1->interleaveIn[3], 2) << 4) + + (GET_BIT(mp1->interleaveIn[4], 2) << 3) + + (GET_BIT(mp1->interleaveIn[5], 2) << 2) + + (GET_BIT(mp1->interleaveIn[6], 2) << 1) + + (GET_BIT(mp1->interleaveIn[7], 2)); - uint8_t p = (GET_BIT(mp1->interleaveIn[8], 1) << 7) + - (GET_BIT(mp1->interleaveIn[9], 1) << 6) + - (GET_BIT(mp1->interleaveIn[10],1) << 5) + - (GET_BIT(mp1->interleaveIn[11],1) << 4) + - (GET_BIT(mp1->interleaveIn[8], 2) << 3) + - (GET_BIT(mp1->interleaveIn[9], 2) << 2) + - (GET_BIT(mp1->interleaveIn[10],2) << 1) + - (GET_BIT(mp1->interleaveIn[11],2)); + uint8_t p = (GET_BIT(mp1->interleaveIn[8], 1) << 7) + + (GET_BIT(mp1->interleaveIn[9], 1) << 6) + + (GET_BIT(mp1->interleaveIn[10],1) << 5) + + (GET_BIT(mp1->interleaveIn[11],1) << 4) + + (GET_BIT(mp1->interleaveIn[8], 2) << 3) + + (GET_BIT(mp1->interleaveIn[9], 2) << 2) + + (GET_BIT(mp1->interleaveIn[10],2) << 1) + + (GET_BIT(mp1->interleaveIn[11],2)); - uint8_t c = (GET_BIT(mp1->interleaveIn[0], 3) << 7) + - (GET_BIT(mp1->interleaveIn[1], 3) << 6) + - (GET_BIT(mp1->interleaveIn[2], 3) << 5) + - (GET_BIT(mp1->interleaveIn[3], 3) << 4) + - (GET_BIT(mp1->interleaveIn[4], 3) << 3) + - (GET_BIT(mp1->interleaveIn[5], 3) << 2) + - (GET_BIT(mp1->interleaveIn[6], 3) << 1) + - (GET_BIT(mp1->interleaveIn[7], 3)); + uint8_t c = (GET_BIT(mp1->interleaveIn[0], 3) << 7) + + (GET_BIT(mp1->interleaveIn[1], 3) << 6) + + (GET_BIT(mp1->interleaveIn[2], 3) << 5) + + (GET_BIT(mp1->interleaveIn[3], 3) << 4) + + (GET_BIT(mp1->interleaveIn[4], 3) << 3) + + (GET_BIT(mp1->interleaveIn[5], 3) << 2) + + (GET_BIT(mp1->interleaveIn[6], 3) << 1) + + (GET_BIT(mp1->interleaveIn[7], 3)); - uint8_t d = (GET_BIT(mp1->interleaveIn[0], 4) << 7) + - (GET_BIT(mp1->interleaveIn[1], 4) << 6) + - (GET_BIT(mp1->interleaveIn[2], 4) << 5) + - (GET_BIT(mp1->interleaveIn[3], 4) << 4) + - (GET_BIT(mp1->interleaveIn[4], 4) << 3) + - (GET_BIT(mp1->interleaveIn[5], 4) << 2) + - (GET_BIT(mp1->interleaveIn[6], 4) << 1) + - (GET_BIT(mp1->interleaveIn[7], 4)); + uint8_t d = (GET_BIT(mp1->interleaveIn[0], 4) << 7) + + (GET_BIT(mp1->interleaveIn[1], 4) << 6) + + (GET_BIT(mp1->interleaveIn[2], 4) << 5) + + (GET_BIT(mp1->interleaveIn[3], 4) << 4) + + (GET_BIT(mp1->interleaveIn[4], 4) << 3) + + (GET_BIT(mp1->interleaveIn[5], 4) << 2) + + (GET_BIT(mp1->interleaveIn[6], 4) << 1) + + (GET_BIT(mp1->interleaveIn[7], 4)); - uint8_t q = (GET_BIT(mp1->interleaveIn[8], 3) << 7) + - (GET_BIT(mp1->interleaveIn[9], 3) << 6) + - (GET_BIT(mp1->interleaveIn[10],3) << 5) + - (GET_BIT(mp1->interleaveIn[11],3) << 4) + - (GET_BIT(mp1->interleaveIn[8], 4) << 3) + - (GET_BIT(mp1->interleaveIn[9], 4) << 2) + - (GET_BIT(mp1->interleaveIn[10],4) << 1) + - (GET_BIT(mp1->interleaveIn[11],4)); + uint8_t q = (GET_BIT(mp1->interleaveIn[8], 3) << 7) + + (GET_BIT(mp1->interleaveIn[9], 3) << 6) + + (GET_BIT(mp1->interleaveIn[10],3) << 5) + + (GET_BIT(mp1->interleaveIn[11],3) << 4) + + (GET_BIT(mp1->interleaveIn[8], 4) << 3) + + (GET_BIT(mp1->interleaveIn[9], 4) << 2) + + (GET_BIT(mp1->interleaveIn[10],4) << 1) + + (GET_BIT(mp1->interleaveIn[11],4)); - uint8_t e = (GET_BIT(mp1->interleaveIn[0], 5) << 7) + - (GET_BIT(mp1->interleaveIn[1], 5) << 6) + - (GET_BIT(mp1->interleaveIn[2], 5) << 5) + - (GET_BIT(mp1->interleaveIn[3], 5) << 4) + - (GET_BIT(mp1->interleaveIn[4], 5) << 3) + - (GET_BIT(mp1->interleaveIn[5], 5) << 2) + - (GET_BIT(mp1->interleaveIn[6], 5) << 1) + - (GET_BIT(mp1->interleaveIn[7], 5)); + uint8_t e = (GET_BIT(mp1->interleaveIn[0], 5) << 7) + + (GET_BIT(mp1->interleaveIn[1], 5) << 6) + + (GET_BIT(mp1->interleaveIn[2], 5) << 5) + + (GET_BIT(mp1->interleaveIn[3], 5) << 4) + + (GET_BIT(mp1->interleaveIn[4], 5) << 3) + + (GET_BIT(mp1->interleaveIn[5], 5) << 2) + + (GET_BIT(mp1->interleaveIn[6], 5) << 1) + + (GET_BIT(mp1->interleaveIn[7], 5)); - uint8_t f = (GET_BIT(mp1->interleaveIn[0], 6) << 7) + - (GET_BIT(mp1->interleaveIn[1], 6) << 6) + - (GET_BIT(mp1->interleaveIn[2], 6) << 5) + - (GET_BIT(mp1->interleaveIn[3], 6) << 4) + - (GET_BIT(mp1->interleaveIn[4], 6) << 3) + - (GET_BIT(mp1->interleaveIn[5], 6) << 2) + - (GET_BIT(mp1->interleaveIn[6], 6) << 1) + - (GET_BIT(mp1->interleaveIn[7], 6)); + uint8_t f = (GET_BIT(mp1->interleaveIn[0], 6) << 7) + + (GET_BIT(mp1->interleaveIn[1], 6) << 6) + + (GET_BIT(mp1->interleaveIn[2], 6) << 5) + + (GET_BIT(mp1->interleaveIn[3], 6) << 4) + + (GET_BIT(mp1->interleaveIn[4], 6) << 3) + + (GET_BIT(mp1->interleaveIn[5], 6) << 2) + + (GET_BIT(mp1->interleaveIn[6], 6) << 1) + + (GET_BIT(mp1->interleaveIn[7], 6)); - uint8_t s = (GET_BIT(mp1->interleaveIn[8], 5) << 7) + - (GET_BIT(mp1->interleaveIn[9], 5) << 6) + - (GET_BIT(mp1->interleaveIn[10],5) << 5) + - (GET_BIT(mp1->interleaveIn[11],5) << 4) + - (GET_BIT(mp1->interleaveIn[8], 6) << 3) + - (GET_BIT(mp1->interleaveIn[9], 6) << 2) + - (GET_BIT(mp1->interleaveIn[10],6) << 1) + - (GET_BIT(mp1->interleaveIn[11],6)); + uint8_t s = (GET_BIT(mp1->interleaveIn[8], 5) << 7) + + (GET_BIT(mp1->interleaveIn[9], 5) << 6) + + (GET_BIT(mp1->interleaveIn[10],5) << 5) + + (GET_BIT(mp1->interleaveIn[11],5) << 4) + + (GET_BIT(mp1->interleaveIn[8], 6) << 3) + + (GET_BIT(mp1->interleaveIn[9], 6) << 2) + + (GET_BIT(mp1->interleaveIn[10],6) << 1) + + (GET_BIT(mp1->interleaveIn[11],6)); - uint8_t g = (GET_BIT(mp1->interleaveIn[0], 7) << 7) + - (GET_BIT(mp1->interleaveIn[1], 7) << 6) + - (GET_BIT(mp1->interleaveIn[2], 7) << 5) + - (GET_BIT(mp1->interleaveIn[3], 7) << 4) + - (GET_BIT(mp1->interleaveIn[4], 7) << 3) + - (GET_BIT(mp1->interleaveIn[5], 7) << 2) + - (GET_BIT(mp1->interleaveIn[6], 7) << 1) + - (GET_BIT(mp1->interleaveIn[7], 7)); + uint8_t g = (GET_BIT(mp1->interleaveIn[0], 7) << 7) + + (GET_BIT(mp1->interleaveIn[1], 7) << 6) + + (GET_BIT(mp1->interleaveIn[2], 7) << 5) + + (GET_BIT(mp1->interleaveIn[3], 7) << 4) + + (GET_BIT(mp1->interleaveIn[4], 7) << 3) + + (GET_BIT(mp1->interleaveIn[5], 7) << 2) + + (GET_BIT(mp1->interleaveIn[6], 7) << 1) + + (GET_BIT(mp1->interleaveIn[7], 7)); - uint8_t h = (GET_BIT(mp1->interleaveIn[0], 8) << 7) + - (GET_BIT(mp1->interleaveIn[1], 8) << 6) + - (GET_BIT(mp1->interleaveIn[2], 8) << 5) + - (GET_BIT(mp1->interleaveIn[3], 8) << 4) + - (GET_BIT(mp1->interleaveIn[4], 8) << 3) + - (GET_BIT(mp1->interleaveIn[5], 8) << 2) + - (GET_BIT(mp1->interleaveIn[6], 8) << 1) + - (GET_BIT(mp1->interleaveIn[7], 8)); + uint8_t h = (GET_BIT(mp1->interleaveIn[0], 8) << 7) + + (GET_BIT(mp1->interleaveIn[1], 8) << 6) + + (GET_BIT(mp1->interleaveIn[2], 8) << 5) + + (GET_BIT(mp1->interleaveIn[3], 8) << 4) + + (GET_BIT(mp1->interleaveIn[4], 8) << 3) + + (GET_BIT(mp1->interleaveIn[5], 8) << 2) + + (GET_BIT(mp1->interleaveIn[6], 8) << 1) + + (GET_BIT(mp1->interleaveIn[7], 8)); - uint8_t t = (GET_BIT(mp1->interleaveIn[8], 7) << 7) + - (GET_BIT(mp1->interleaveIn[9], 7) << 6) + - (GET_BIT(mp1->interleaveIn[10],7) << 5) + - (GET_BIT(mp1->interleaveIn[11],7) << 4) + - (GET_BIT(mp1->interleaveIn[8], 8) << 3) + - (GET_BIT(mp1->interleaveIn[9], 8) << 2) + - (GET_BIT(mp1->interleaveIn[10],8) << 1) + - (GET_BIT(mp1->interleaveIn[11],8)); + uint8_t t = (GET_BIT(mp1->interleaveIn[8], 7) << 7) + + (GET_BIT(mp1->interleaveIn[9], 7) << 6) + + (GET_BIT(mp1->interleaveIn[10],7) << 5) + + (GET_BIT(mp1->interleaveIn[11],7) << 4) + + (GET_BIT(mp1->interleaveIn[8], 8) << 3) + + (GET_BIT(mp1->interleaveIn[9], 8) << 2) + + (GET_BIT(mp1->interleaveIn[10],8) << 1) + + (GET_BIT(mp1->interleaveIn[11],8)); - mp1->interleaveIn[0] = a; - mp1->interleaveIn[1] = b; - mp1->interleaveIn[2] = p; - mp1->interleaveIn[3] = c; - mp1->interleaveIn[4] = d; - mp1->interleaveIn[5] = q; - mp1->interleaveIn[6] = e; - mp1->interleaveIn[7] = f; - mp1->interleaveIn[8] = s; - mp1->interleaveIn[9] = g; - mp1->interleaveIn[10] = h; - mp1->interleaveIn[11] = t; + mp1->interleaveIn[0] = a; + mp1->interleaveIn[1] = b; + mp1->interleaveIn[2] = p; + mp1->interleaveIn[3] = c; + mp1->interleaveIn[4] = d; + mp1->interleaveIn[5] = q; + mp1->interleaveIn[6] = e; + mp1->interleaveIn[7] = f; + mp1->interleaveIn[8] = s; + mp1->interleaveIn[9] = g; + mp1->interleaveIn[10] = h; + mp1->interleaveIn[11] = t; - #endif + #endif } \ No newline at end of file diff --git a/Modem/protocol/mp1.h b/Modem/protocol/mp1.h index 69ecd56..f617d1e 100644 --- a/Modem/protocol/mp1.h +++ b/Modem/protocol/mp1.h @@ -7,23 +7,23 @@ // Options #define MP1_ENABLE_TCP_COMPATIBILITY false #if MP1_ENABLE_TCP_COMPATIBILITY - #define MP1_ENABLE_COMPRESSION false - #define MP1_ENABLE_CSMA true + #define MP1_ENABLE_COMPRESSION false + #define MP1_ENABLE_CSMA true #else - #define MP1_ENABLE_COMPRESSION true - #define MP1_ENABLE_CSMA false + #define MP1_ENABLE_COMPRESSION true + #define MP1_ENABLE_CSMA false #endif // Frame sizing & checksum #define MP1_INTERLEAVE_SIZE 12 #if MP1_ENABLE_COMPRESSION - #define MP1_MAX_FRAME_LENGTH 22 * MP1_INTERLEAVE_SIZE - #define MP1_USE_TX_QUEUE false + #define MP1_MAX_FRAME_LENGTH 22 * MP1_INTERLEAVE_SIZE + #define MP1_USE_TX_QUEUE false #else - #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 + #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 @@ -34,10 +34,10 @@ // These two parameters are used for // P-persistent CSMA -#define MP1_SETTLE_TIME 100UL // The minimum wait time before even 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 +#define MP1_SETTLE_TIME 100UL // The minimum wait time before even 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 @@ -48,9 +48,9 @@ // to send as padding if we need to pad a // packet. Due to forward error correction, // packets must have an even number of bytes. -#define MP1_PADDING 0x55 -#define MP1_HEADER_PADDED 0x01 -#define MP1_HEADER_COMPRESSION 0x02 +#define MP1_PADDING 0x55 +#define MP1_HEADER_PADDED 0x01 +#define MP1_HEADER_COMPRESSION 0x02 // Just a forward declaration that this struct exists struct MP1Packet; @@ -61,35 +61,35 @@ typedef void (*mp1_callback_t)(struct MP1Packet *packet); // Struct for a protocol context typedef struct MP1 { - 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 + 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 typedef struct MP1Packet { - const uint8_t *data; // Pointer to the actual data in the packet - size_t dataLength; // The length of the received data + const uint8_t *data; // Pointer to the actual data in the packet + size_t dataLength; // The length of the received data } MP1Packet; // Declarations of functions diff --git a/buildrev.h b/buildrev.h index ded2f6c..b61514e 100644 --- a/buildrev.h +++ b/buildrev.h @@ -1,2 +1,2 @@ -#define VERS_BUILD 1756 +#define VERS_BUILD 1758 #define VERS_HOST "shard"