From 474f3ad4d22fca6c6afd5156618f2715aace122d Mon Sep 17 00:00:00 2001 From: Mark Qvist Date: Fri, 8 Feb 2019 13:18:49 +0100 Subject: [PATCH] EEPROM configuration --- Makefile | 2 +- device.h | 11 ++- hardware/AFSK.c | 96 +------------------- hardware/AFSK.h | 1 - hardware/Crypto.c | 50 +++++++++-- hardware/Crypto.h | 6 ++ hardware/VREF.c | 16 ++-- main.c | 19 +++- protocol/AX25.c | 3 +- protocol/KISS.c | 25 +++--- protocol/KISS.h | 2 +- util/Config.c | 222 ++++++++++++++++++++++++++++++++++++++++++++++ util/Config.h | 107 ++++++++++++++++++++++ 13 files changed, 429 insertions(+), 131 deletions(-) create mode 100644 util/Config.c create mode 100644 util/Config.h diff --git a/Makefile b/Makefile index 8db9e3c..78a128b 100755 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ TARGET = images/OpenModem OPT = s FORMAT = ihex -SRC = main.c hardware/Serial.c hardware/AFSK.c hardware/VREF.c hardware/LED.c hardware/UserIO.c hardware/SD.c hardware/sdcard/diskio.c hardware/sdcard/ff.c hardware/sdcard/ffsystem.c hardware/sdcard/ffunicode.c hardware/Bluetooth.c hardware/GPS.c hardware/Crypto.c hardware/crypto/AES.c hardware/crypto/HMAC_MD5.c hardware/crypto/MD5.c hardware/crypto/MD5_sbox.c util/CRC-CCIT.c protocol/AX25.c protocol/KISS.c +SRC = main.c util/Config.c hardware/Serial.c hardware/AFSK.c hardware/VREF.c hardware/LED.c hardware/UserIO.c hardware/SD.c hardware/sdcard/diskio.c hardware/sdcard/ff.c hardware/sdcard/ffsystem.c hardware/sdcard/ffunicode.c hardware/Bluetooth.c hardware/GPS.c hardware/Crypto.c hardware/crypto/AES.c hardware/crypto/HMAC_MD5.c hardware/crypto/MD5.c hardware/crypto/MD5_sbox.c util/CRC-CCIT.c protocol/AX25.c protocol/KISS.c # TODO: Try hardware/crypto/MD5_asm.S # List Assembler source files here. diff --git a/device.h b/device.h index f210287..a9112a9 100755 --- a/device.h +++ b/device.h @@ -3,6 +3,10 @@ #ifndef DEVICE_CONFIGURATION #define DEVICE_CONFIGURATION +// Version info +#define MAJ_VERSION 0x01 +#define MIN_VERSION 0x00 + // CPU settings #define TARGET_CPU m1284p #define F_CPU 20000000UL @@ -10,12 +14,12 @@ // Voltage references // TODO: Determine best defaults -#define CONFIG_ADC_REF 255 +#define CONFIG_ADC_REF 128 #define CONFIG_DAC_REF 128 // TODO: Change this back to default -#define CONFIG_LED_INTENSITY 35 //#define CONFIG_LED_INTENSITY 192 +#define CONFIG_LED_INTENSITY 37 #define CONFIG_COM_LED_TIMEOUT_MS 40 #define CONFIG_LED_UPDATE_INTERVAL_MS 40 @@ -34,7 +38,8 @@ // CSMA Settings #define CONFIG_FULL_DUPLEX false // TODO: Actually implement fdx -#define CONFIG_CSMA_P 255 +#define CONFIG_CSMA_P_DEFAULT 255 +#define CONFIG_CSMA_SLOTTIME_DEFAULT 20 #define AX25_MIN_FRAME_LEN 1 #define AX25_MAX_FRAME_LEN 611 diff --git a/hardware/AFSK.c b/hardware/AFSK.c index bd2cd4d..c652dbf 100755 --- a/hardware/AFSK.c +++ b/hardware/AFSK.c @@ -4,16 +4,9 @@ #include "hardware/LED.h" #include "protocol/KISS.h" #include "hardware/SD.h" - -// TODO: Remove testing vars //// -#define SAMPLES_TO_CAPTURE 128 -ticks_t capturedsamples = 0; -uint8_t samplebuf[SAMPLES_TO_CAPTURE]; -///////////////////////////////// +#include "util/Config.h" extern volatile ticks_t _clock; -extern unsigned long custom_preamble; -extern unsigned long custom_tail; bool hw_afsk_dac_isr = false; bool hw_5v_ref = false; @@ -128,11 +121,11 @@ static void AFSK_txStart(Afsk *afsk) { afsk->sending = true; afsk->sending_data = true; LED_TX_ON(); - afsk->preambleLength = DIV_ROUND(custom_preamble * BITRATE, 8000); + afsk->preambleLength = DIV_ROUND(config_preamble * BITRATE, 8000); AFSK_DAC_IRQ_START(); } ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { - afsk->tailLength = DIV_ROUND(custom_tail * BITRATE, 8000); + afsk->tailLength = DIV_ROUND(config_tail * BITRATE, 8000); } } @@ -468,50 +461,12 @@ void AFSK_adc_isr(Afsk *afsk, int8_t currentSample) { #error No filters defined for specified samplerate! #endif - // We put the sampled bit in a delay-line: - // First we bitshift everything 1 left afsk->sampledBits <<= 1; - // And then add the sampled bit to our delay line afsk->sampledBits |= (afsk->iirY[1] > 0) ? 0 : 1; - //afsk->sampledBits |= (freq_disc > 0) ? 0 : 1; - // Put the current raw sample in the delay FIFO fifo_push(&afsk->delayFifo, currentSample); - // We need to check whether there is a signal transition. - // If there is, we can recalibrate the phase of our - // sampler to stay in sync with the transmitter. A bit of - // explanation is required to understand how this works. - // Since we have PHASE_MAX/PHASE_BITS = 8 samples per bit, - // we employ a phase counter (currentPhase), that increments - // by PHASE_BITS everytime a sample is captured. When this - // counter reaches PHASE_MAX, it wraps around by modulus - // PHASE_MAX. We then look at the last three samples we - // captured and determine if the bit was a one or a zero. - // - // This gives us a "window" looking into the stream of - // samples coming from the ADC. Sort of like this: - // - // Past Future - // 0000000011111111000000001111111100000000 - // |________| - // || - // Window - // - // Every time we detect a signal transition, we adjust - // where this window is positioned a little. How much we - // adjust it is defined by PHASE_INC. If our current phase - // phase counter value is less than half of PHASE_MAX (ie, - // the window size) when a signal transition is detected, - // add PHASE_INC to our phase counter, effectively moving - // the window a little bit backward (to the left in the - // illustration), inversely, if the phase counter is greater - // than half of PHASE_MAX, we move it forward a little. - // This way, our "window" is constantly seeking to position - // it's center at the bit transitions. Thus, we synchronise - // our timing to the transmitter, even if it's timing is - // a little off compared to our own. if (SIGNAL_TRANSITIONED(afsk->sampledBits)) { if (afsk->currentPhase < PHASE_THRESHOLD) { afsk->currentPhase += PHASE_INC; @@ -523,24 +478,12 @@ void AFSK_adc_isr(Afsk *afsk, int8_t currentSample) { afsk->silentSamples++; } - // We increment our phase counter afsk->currentPhase += PHASE_BITS; - // Check if we have reached the end of - // our sampling window. if (afsk->currentPhase >= PHASE_MAX) { - // If we have, wrap around our phase - // counter by modulus afsk->currentPhase %= PHASE_MAX; - // Bitshift to make room for the next - // bit in our stream of demodulated bits afsk->actualBits <<= 1; - - // We determine the actual bit value by reading - // the last 3 sampled bits. If there is two or - // more 1's, we will assume that the transmitter - // sent us a one, otherwise we assume a zero uint8_t bits = afsk->sampledBits & 0x07; if (bits == 0x07 || // 111 @@ -551,39 +494,6 @@ void AFSK_adc_isr(Afsk *afsk, int8_t currentSample) { afsk->actualBits |= 1; } - - //// Alternative using six bits //////////////// - // uint8_t bits = afsk->sampledBits & 0x3F; - // uint8_t c = 0; - // c += bits & _BV(0); - // c += bits & _BV(1); - // c += bits & _BV(2); - // c += bits & _BV(3); - // c += bits & _BV(4); - // c += bits & _BV(5); - // if (c >= 3) afsk->actualBits |= 1; - ///////////////////////////////////////////////// - - // Now we can pass the actual bit to the HDLC parser. - // We are using NRZ-S coding, so if 2 consecutive bits - // have the same value, we have a 1, otherwise a 0. - // We use the TRANSITION_FOUND function to determine this. - // - // This is smart in combination with bit stuffing, - // since it ensures a transmitter will never send more - // than five consecutive 1's. When sending consecutive - // ones, the signal stays at the same level, and if - // this happens for longer periods of time, we would - // not be able to synchronize our phase to the transmitter - // and would start experiencing "bit slip". - // - // By combining bit-stuffing with NRZ-S coding, we ensure - // that the signal will regularly make transitions - // that we can use to synchronize our phase. - // - // We also check the return of the Link Control parser - // to check if an error occured. - if (!hdlcParse(&afsk->hdlc, !TRANSITION_FOUND(afsk->actualBits), &afsk->rxFifo)) { afsk->status |= 1; if (fifo_isfull(&afsk->rxFifo)) { diff --git a/hardware/AFSK.h b/hardware/AFSK.h index 4c9d2c6..a47a34e 100755 --- a/hardware/AFSK.h +++ b/hardware/AFSK.h @@ -36,7 +36,6 @@ inline static uint8_t sinSample(uint16_t i) { #define TRANSITION_FOUND(bits) BITS_DIFFER((bits), (bits) >> 1) #define DUAL_XOR(bits1, bits2) ((((bits1)^(bits2)) & 0x03) == 0x03) #define QUAD_XOR(bits1, bits2) ((((bits1)^(bits2)) & 0x0F) == 0x0F) - #define CPU_FREQ F_CPU diff --git a/hardware/Crypto.c b/hardware/Crypto.c index a53be4b..8f85462 100644 --- a/hardware/Crypto.c +++ b/hardware/Crypto.c @@ -1,4 +1,5 @@ #include "Crypto.h" +#include "util/Config.h" bool encryption_enabled = false; uint8_t active_key[CRYPTO_KEY_SIZE]; @@ -18,17 +19,39 @@ FRESULT crypto_fr; // Result codes void crypto_init(void) { encryption_enabled = false; - if (load_key()) { - if (load_entropy_index() && load_entropy()) { - encryption_enabled = true; + if (should_disable_enryption()) { + if (config_crypto_lock) config_crypto_lock_disable(); + } else { + if (load_key()) { + if (load_entropy_index() && load_entropy()) { + config_crypto_lock_enable(); + encryption_enabled = true; + } + } + + if (config_crypto_lock) { + if (encryption_enabled) { + LED_indicate_enabled_crypto(); + } else { + LED_indicate_error_crypto(); + } } } +} - if (encryption_enabled) { - LED_indicate_enabled_crypto(); - } else { - LED_indicate_error_crypto(); +bool crypto_wait(void) { + size_t wait_timer = 0; + size_t interval_ms = 100; + while (!crypto_enabled()) { + delay_ms(100); + wait_timer++; + sd_jobs(); + if (wait_timer*interval_ms > CRYPTO_WAIT_TIMEOUT_MS) { + return false; + } } + + return true; } void crypto_generate_hmac(uint8_t *data, size_t length) { @@ -170,6 +193,19 @@ bool load_entropy(void) { return false; } +bool should_disable_enryption(void) { + if (sd_mounted()) { + crypto_fr = f_open(&crypto_fp, PATH_CRYPTO_DISABLE, FA_READ); + if (crypto_fr == FR_OK) { + f_close(&crypto_fp); + + return true; + } + } + + return false; +} + bool load_key(void) { if (sd_mounted()) { crypto_fr = f_open(&crypto_fp, PATH_AES_128_KEY, FA_READ); diff --git a/hardware/Crypto.h b/hardware/Crypto.h index 6e56394..e819b30 100644 --- a/hardware/Crypto.h +++ b/hardware/Crypto.h @@ -13,6 +13,7 @@ #define PATH_ENTROPY_INDEX "OpenModem/entropy.index" #define PATH_ENTROPY_SOURCE "OpenModem/entropy.source" #define PATH_AES_128_KEY "OpenModem/aes128.key" +#define PATH_CRYPTO_DISABLE "OpenModem/aes128.disable" #define CRYPTO_KEY_SIZE_BITS 128 #define CRYPTO_KEY_SIZE (CRYPTO_KEY_SIZE_BITS/8) @@ -20,9 +21,13 @@ #define CRYPTO_HMAC_SIZE (CRYPTO_HMAC_SIZE_BITS/8) #define MAX_IVS_PER_ENTROPY_BLOCK 128 +#define CRYPTO_WAIT_TIMEOUT_MS 2000 + uint8_t crypto_work_block[CRYPTO_KEY_SIZE]; void crypto_init(void); +bool crypto_wait(void); + bool crypto_enabled(void); bool crypto_generate_iv(void); uint8_t* crypto_get_iv(void); @@ -35,6 +40,7 @@ void crypto_decrypt_block(uint8_t block[CRYPTO_KEY_SIZE]); void crypto_test(void); +bool should_disable_enryption(void); bool load_key(void); bool load_entropy(void); bool load_entropy_index(void); diff --git a/hardware/VREF.c b/hardware/VREF.c index 5544e07..faade13 100644 --- a/hardware/VREF.c +++ b/hardware/VREF.c @@ -1,7 +1,5 @@ #include "VREF.h" - -uint8_t adcReference = CONFIG_ADC_REF; -uint8_t dacReference = CONFIG_DAC_REF; +#include "util/Config.h" void VREF_init(void) { // Enable output for OC2A and OC2B (PD7 and PD6) @@ -14,17 +12,17 @@ void VREF_init(void) { TCCR2B = _BV(CS20); - OCR2A = adcReference; - OCR2B = dacReference; + OCR2A = config_input_gain; + OCR2B = config_output_gain; } void vref_setADC(uint8_t value) { - adcReference = value; - OCR2A = adcReference; + config_input_gain = value; + OCR2A = config_input_gain; } void vref_setDAC(uint8_t value) { - dacReference = value; - OCR2B = dacReference; + config_output_gain = value; + OCR2B = config_output_gain; } \ No newline at end of file diff --git a/main.c b/main.c index 8b27440..69010ce 100755 --- a/main.c +++ b/main.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -18,11 +19,10 @@ #include "hardware/GPS.h" #include "protocol/AX25.h" #include "protocol/KISS.h" +#include "util/Config.h" #include "util/time.h" #include "util/FIFO.h" - - uint8_t boot_vector = 0x00; uint8_t OPTIBOOT_MCUSR __attribute__ ((section(".noinit"))); void resetFlagsInit(void) __attribute__ ((naked)) __attribute__ ((used)) __attribute__ ((section (".init0"))); @@ -39,6 +39,7 @@ static void ax25_callback(struct AX25Ctx *ctx) { } void system_check(void) { + // Check boot vector if (OPTIBOOT_MCUSR & (1<ch)) != EOF) { if (!ctx->escape && c == HDLC_FLAG) { if (ctx->frame_len >= AX25_MIN_FRAME_LEN) { - if (ctx->crc_in == AX25_CRC_CORRECT || CONFIG_PASSALL) { + if (ctx->crc_in == AX25_CRC_CORRECT || config_passall) { ax25_decode(ctx); } } diff --git a/protocol/KISS.c b/protocol/KISS.c index 3f9bdb1..174680c 100755 --- a/protocol/KISS.c +++ b/protocol/KISS.c @@ -7,6 +7,7 @@ #include "hardware/Crypto.h" #include "util/FIFO16.h" #include "util/time.h" +#include "util/Config.h" #include "KISS.h" uint8_t packet_queue[CONFIG_QUEUE_SIZE]; @@ -31,11 +32,10 @@ bool IN_FRAME; bool ESCAPE; uint8_t command = CMD_UNKNOWN; -unsigned long custom_preamble = CONFIG_AFSK_PREAMBLE_LEN; -unsigned long custom_tail = CONFIG_AFSK_TRAILER_LEN; -unsigned long slotTime = 200; -uint8_t p = CONFIG_CSMA_P; +//unsigned long custom_preamble = CONFIG_AFSK_PREAMBLE_LEN; +//unsigned long custom_tail = CONFIG_AFSK_TRAILER_LEN; + void kiss_init(AX25Ctx *ax25, Afsk *afsk, Serial *ser) { ax25ctx = ax25; @@ -89,6 +89,7 @@ void kiss_messageCallback(AX25Ctx *ctx) { for (uint8_t i = 0; i < CRYPTO_HMAC_SIZE; i++) { if (hmac[i] != crypto_work_block[i]) { HMAC_ok = false; + break; } } @@ -145,7 +146,7 @@ void kiss_csma(void) { if (!channel->hdlc.dcd) { ticks_t timeout = last_serial_read + ms_to_ticks(CONFIG_SERIAL_TIMEOUT_MS); if (timer_clock() > timeout) { - if (p == 255) { + if (config_p == 255) { kiss_flushQueue(); } else { // TODO: Implement real CSMA @@ -155,7 +156,7 @@ void kiss_csma(void) { } #else if (!channel->hdlc.dcd) { - if (p == 255) { + if (config_p == 255) { kiss_flushQueue(); } else { // TODO: Implement real CSMA @@ -302,16 +303,14 @@ void kiss_serialCallback(uint8_t sbyte) { if (queue_cursor == CONFIG_QUEUE_SIZE) queue_cursor = 0; } } - } else if (command == CMD_TXDELAY) { - custom_preamble = sbyte * 10UL; + } else if (command == CMD_PREAMBLE) { + config_preamble = sbyte * 10UL; } else if (command == CMD_TXTAIL) { - custom_tail = sbyte * 10; + config_tail = sbyte * 10UL; } else if (command == CMD_SLOTTIME) { - slotTime = sbyte * 10; + config_slottime = sbyte * 10UL; } else if (command == CMD_P) { - p = sbyte; - } else if (command == CMD_FLUSHQUEUE) { - kiss_flushQueue(); + config_p = sbyte; } else if (command == CMD_LED_INTENSITY) { if (sbyte == FESC) { ESCAPE = true; diff --git a/protocol/KISS.h b/protocol/KISS.h index 01dcd01..918b5af 100755 --- a/protocol/KISS.h +++ b/protocol/KISS.h @@ -13,7 +13,7 @@ #define CMD_UNKNOWN 0xFE #define CMD_DATA 0x00 -#define CMD_TXDELAY 0x01 +#define CMD_PREAMBLE 0x01 #define CMD_P 0x02 #define CMD_SLOTTIME 0x03 #define CMD_TXTAIL 0x04 diff --git a/util/Config.c b/util/Config.c new file mode 100644 index 0000000..7773703 --- /dev/null +++ b/util/Config.c @@ -0,0 +1,222 @@ +#include +#include +#include +#include +#include +#include "Config.h" +#include "device.h" +#include "hardware/crypto/MD5.h" +#include "hardware/AFSK.h" + + +void config_init(void) { + config_source = CONFIG_SOURCE_NONE; + + bool has_valid_eeprom_config = config_validate_eeprom(); + + if (has_valid_eeprom_config) { + config_load_from_eeprom(); + } else { + config_load_defaults(); + config_save_to_eeprom(); + } +} + +void config_wipe_eeprom(void) { + for (uint16_t i = 0; i < ADDR_E_END; i++) { + EEPROM_updatebyte(i, 0x00); + } +} + +bool config_validate_eeprom(void) { + uint8_t config_size = ADDR_E_END; + uint8_t config_data_size = ADDR_E_END - CONF_CHECKSUM_SIZE; + uint8_t config_data[config_data_size]; + uint8_t config_checksum[CONF_CHECKSUM_SIZE]; + + for (uint16_t addr = 0; addr < config_data_size; addr++) { + config_data[addr] = EEPROM_readbyte(addr); + } + + for (uint16_t addr = config_data_size; addr < config_size; addr++) { + config_checksum[addr-config_data_size] = EEPROM_readbyte(addr); + } + + md5_hash_t calculated_checksum; + md5(&calculated_checksum, &config_data, config_data_size*8); + + bool checksums_match = true; + for (uint8_t i = 0; i < CONF_CHECKSUM_SIZE; i++) { + if (calculated_checksum[i] != config_checksum[i]) { + checksums_match = false; + break; + } + } + + if (checksums_match) { + return true; + } else { + return false; + } +} + +void config_save_to_eeprom(void) { + uint8_t i = 0; + uint8_t config_size = ADDR_E_END; + uint8_t config_data_size = ADDR_E_END - CONF_CHECKSUM_SIZE; + uint8_t config_data[config_size]; + memset(config_data, 0x00, ADDR_E_END); + + config_data[i++] = MAJ_VERSION; + config_data[i++] = MIN_VERSION; + config_data[i++] = CONF_VERSION; + config_data[i++] = config_p; + config_data[i++] = config_slottime/10; + config_data[i++] = config_preamble/10; + config_data[i++] = config_tail/10; + config_data[i++] = config_led_intensity; + config_data[i++] = config_output_gain; + config_data[i++] = config_input_gain; + config_data[i++] = config_passall; + config_data[i++] = config_log_packets; + config_data[i++] = config_crypto_lock; + config_data[i++] = config_gps_mode; + config_data[i++] = config_bluetooth_mode; + config_data[i++] = config_serial_baudrate; + + md5_hash_t checksum; + md5(&checksum, &config_data, config_data_size*8); + for (uint8_t j = 0; j < CONF_CHECKSUM_SIZE; j++) { + config_data[i++] = checksum[j]; + } + + for (uint16_t addr = 0; addr < config_size; addr++) { + EEPROM_updatebyte(addr, config_data[addr]); + } +} + +void config_load_defaults(void) { + config_p = CONFIG_CSMA_P_DEFAULT; + config_slottime = CONFIG_CSMA_SLOTTIME_DEFAULT; + config_preamble = CONFIG_AFSK_PREAMBLE_LEN; + config_tail = CONFIG_AFSK_TRAILER_LEN; + config_led_intensity = CONFIG_LED_INTENSITY; + config_output_gain = CONFIG_DAC_REF; + config_input_gain = CONFIG_ADC_REF; + config_passall = false; + config_log_packets = false; + config_crypto_lock = false; + config_gps_mode = CONFIG_GPS_AUTODETECT; + config_bluetooth_mode = CONFIG_BLUETOOTH_AUTODETECT; + config_serial_baudrate = CONFIG_BAUDRATE_115200; + config_source = CONFIG_SOURCE_DEFAULT; +} + +void config_load_from_eeprom(void) { + uint8_t config_data_size = ADDR_E_END - CONF_CHECKSUM_SIZE; + uint8_t config_data[config_data_size]; + + for (uint16_t addr = 0; addr < config_data_size; addr++) { + config_data[addr] = EEPROM_readbyte(addr); + } + + config_p = config_data[ADDR_E_P]; + config_slottime = config_data[ADDR_E_SLOTTIME]*10UL; + config_preamble = config_data[ADDR_E_PREAMBLE]*10UL; + config_tail = config_data[ADDR_E_TAIL]*10UL; + config_led_intensity = config_data[ADDR_E_LED_INTENSITY]; + config_output_gain = config_data[ADDR_E_OUTPUT_GAIN]; + config_input_gain = config_data[ADDR_E_INPUT_GAIN]; + config_passall = config_data[ADDR_E_PASSALL]; + config_log_packets = config_data[ADDR_E_LOG_PACKETS]; + config_crypto_lock = config_data[ADDR_E_CRYPTO_LOCK]; + config_gps_mode = config_data[ADDR_E_GPS_MODE]; + config_bluetooth_mode = config_data[ADDR_E_BLUETOOTH_MODE]; + config_serial_baudrate = config_data[ADDR_E_SERIAL_BAUDRATE]; + + // printf("Configuration loaded from EEPROM:\r\n"); + // printf("\tP\t\t%02X\r\n", config_p); + // printf("\tSlottime\t%lu\r\n", config_slottime); + // printf("\tPreamble\t%lu\r\n", config_preamble); + // printf("\tTail\t\t%lu\r\n", config_tail); + // printf("\tLEDs\t\t%02X\r\n", config_led_intensity); + // printf("\tOut gain\t%02X\r\n", config_output_gain); + // printf("\tIn gain\t\t%02X\r\n", config_input_gain); + // printf("\tPassall\t\t%02X\r\n", config_passall); + // printf("\tLog pkts\t%02X\r\n", config_log_packets); + // printf("\tCrypto lock\t%02X\r\n", config_crypto_lock); + // printf("\tGPS mode\t%02X\r\n", config_gps_mode); + // printf("\tBT Mode\t\t%02X\r\n", config_bluetooth_mode); + // printf("\tBaudrate\t%02X\r\n", config_serial_baudrate); +} + +bool config_validate_sd(void) { + // TODO: Implement + return false; +} + +void config_save_to_sd(void) { + // TODO: Implement +} + +void config_load_from_sd(void) { + // TODO: Implement + return; +} + +void config_crypto_lock_enable(void) { + config_crypto_lock = true; + config_save_to_eeprom(); +} + +void config_crypto_lock_disable(void) { + config_crypto_lock = false; + config_save_to_eeprom(); + wdt_enable(WDTO_15MS); + while(true) { } +} + +void EEPROM_writebyte(uint16_t addr, uint8_t data) { + // Disable interrupts + cli(); + + // Wait for EEPROM ready + while(EECR & (1< +#include + +#define CONF_VERSION 0x01 + +#define ADDR_E_MAJ_VERSION 0x00 +#define ADDR_E_MIN_VERSION 0x01 +#define ADDR_E_CONF_VERSION 0x02 +#define ADDR_E_P 0x03 +#define ADDR_E_SLOTTIME 0x04 +#define ADDR_E_PREAMBLE 0x05 +#define ADDR_E_TAIL 0x06 +#define ADDR_E_LED_INTENSITY 0x07 +#define ADDR_E_OUTPUT_GAIN 0x08 +#define ADDR_E_INPUT_GAIN 0x09 +#define ADDR_E_PASSALL 0x0A +#define ADDR_E_LOG_PACKETS 0x0B +#define ADDR_E_CRYPTO_LOCK 0x0C +#define ADDR_E_GPS_MODE 0x0D +#define ADDR_E_BLUETOOTH_MODE 0x0E +#define ADDR_E_SERIAL_BAUDRATE 0x0F +#define ADDR_E_CHECKSUM 0x10 +#define ADDR_E_END 0x20 + +#define CONFIG_GPS_OFF 0x00 +#define CONFIG_GPS_AUTODETECT 0x01 +#define CONFIG_GPS_REQUIRED 0x02 + +#define CONFIG_BLUETOOTH_OFF 0x00 +#define CONFIG_BLUETOOTH_AUTODETECT 0x01 +#define CONFIG_BLUETOOTH_REQUIRED 0x02 + +#define CONFIG_BAUDRATE_1200 0x01 +#define CONFIG_BAUDRATE_2400 0x02 +#define CONFIG_BAUDRATE_4800 0x03 +#define CONFIG_BAUDRATE_9600 0x04 +#define CONFIG_BAUDRATE_14400 0x05 +#define CONFIG_BAUDRATE_19200 0x06 +#define CONFIG_BAUDRATE_28800 0x07 +#define CONFIG_BAUDRATE_38400 0x08 +#define CONFIG_BAUDRATE_57600 0x09 +#define CONFIG_BAUDRATE_76800 0x0A +#define CONFIG_BAUDRATE_115200 0x0B +#define CONFIG_BAUDRATE_230400 0x0C + +#define CONFIG_SOURCE_NONE 0x00 +#define CONFIG_SOURCE_DEFAULT 0x01 +#define CONFIG_SOURCE_EEPROM 0x02 +#define CONFIG_SOURCE_SD 0x03 + +#define CONF_CHECKSUM_SIZE 16 + +uint8_t config_source; + +uint8_t config_p; +unsigned long config_slottime; +unsigned long config_preamble; +unsigned long config_tail; +uint8_t config_led_intensity; +uint8_t config_output_gain; +uint8_t config_input_gain; +bool config_passall; +bool config_log_packets; +bool config_crypto_lock; +uint8_t config_gps_mode; +uint8_t config_bluetooth_mode; +uint8_t config_serial_baudrate; + +void config_init(void); + +bool config_validate_eeprom(void); +bool config_validate_sd(void); + +void config_wipe_eeprom(void); +void config_save_to_eeprom(void); +void config_save_to_sd(void); + +void config_load_defaults(void); +void config_load_from_eeprom(void); +void config_load_from_sd(void); + +void config_crypto_lock_enable(void); +void config_crypto_lock_disable(void); + +void EEPROM_updatebyte(uint16_t addr, uint8_t data); +uint8_t EEPROM_readbyte(uint16_t addr); +void EEPROM_writebyte(uint16_t addr, uint8_t data); + +#endif + +/* + CSMA P + CSMA Slot Time + Preamble + Tail + + LED intensity + Output gain + Input gain + + Pass-all + + Log packets +*/ \ No newline at end of file