diff --git a/.gitignore b/.gitignore index 7b0464eeff..16835af538 100644 --- a/.gitignore +++ b/.gitignore @@ -16,6 +16,7 @@ settings /.sconsign.dblite *.map *.lst +*.bak *~ /projects/telosb/00std_button/path.txt /projects/telosb/00std_xon_xoff/path.txt diff --git a/bsp/boards/board.h b/bsp/boards/board.h index a46a95ae17..2019b2481a 100644 --- a/bsp/boards/board.h +++ b/bsp/boards/board.h @@ -17,24 +17,57 @@ //=========================== define ========================================== +#define SLOTDURATION_MS board_getSlotDuration()/PORT_TICS_PER_MS + typedef enum { - DO_NOT_KICK_SCHEDULER = 0, - KICK_SCHEDULER = 1, + DO_NOT_KICK_SCHEDULER = 0, + KICK_SCHEDULER = 1, } kick_scheduler_t; + + //=========================== typedef ========================================= +typedef struct { + uint16_t slotDuration; + + // execution speed related + // also implementation related (e.g. SoC radio or spi-connected radio because of the time to load a packet to/from radio) + uint16_t maxTxDataPrepare; + uint16_t maxRxAckPrepare; + uint16_t maxRxDataPrepare; + uint16_t maxTxAckPrepare; + + // radio speed related + // also implementation related (because the time to execute the Tx/Rx command is highly dependent on the radio AND the configuration) + uint16_t delayTx; + uint16_t delayRx; +} slot_board_vars_t; //board specific slot vars + +// available slot templates +typedef enum{ + SLOT_10ms_24GHZ, + SLOT_20ms_24GHZ, + SLOT_40ms_24GHZ, + SLOT_40ms_FSK_SUBGHZ, + SLOT_40ms_OFDM1MCS0_3_SUBGHZ, + MAX_SLOT_TYPES, +} slotType_t; + //=========================== variables ======================================= //=========================== prototypes ====================================== -void board_init(void); -void board_sleep(void); -void board_reset(void); - +void board_init(void); +void board_sleep(void); +void board_reset(void); +uint16_t board_getSlotDuration (void); +slot_board_vars_t board_selectSlotTemplate(slotType_t slot_type); /** \} \} */ +//=========================== private ========================================= +void board_init_slot_vars(void); #endif diff --git a/bsp/boards/gina/board.c b/bsp/boards/gina/board.c index 3076b0113c..54e4ea657d 100644 --- a/bsp/boards/gina/board.c +++ b/bsp/boards/gina/board.c @@ -26,6 +26,9 @@ //#define ISR_BUTTON 1 //=========================== variables ======================================= +slot_board_vars_t slot_board_vars [MAX_SLOT_TYPES]; +slotType_t selected_slot_type; + //=========================== prototypes ====================================== //=========================== main ============================================ @@ -77,8 +80,10 @@ void board_init(void) { i2c_init(); radio_init(); sctimer_init(); + + board_init_slot_vars(); //ADC_init(); - + // enable interrupts __bis_SR_register(GIE); @@ -99,6 +104,32 @@ void board_init(void) { } } +//==== IEEE802154E timing: bootstrapping slot info lookup table +// 1 clock tick = 30.5 us +void board_init_slot_vars(void){ + + // 20ms slot + slot_board_vars [SLOT_20ms_24GHZ].slotDuration = 655 ; // tics + slot_board_vars [SLOT_20ms_24GHZ].maxTxDataPrepare = 110 ; // 3355us (based on measurement) + slot_board_vars [SLOT_20ms_24GHZ].maxRxAckPrepare = 20 ; // 610us (based on measurement) + slot_board_vars [SLOT_20ms_24GHZ].maxRxDataPrepare = 33 ; // 1000us (based on measurement) + slot_board_vars [SLOT_20ms_24GHZ].maxTxAckPrepare = 50 ; // 1525us (based on measurement) + slot_board_vars [SLOT_20ms_24GHZ].delayTx = 18 ; // 549us (based on measurement) + slot_board_vars [SLOT_20ms_24GHZ].delayRx = 0 ; // 0us (can not measure) +} + +// To get the current slotDuration at any time (in tics) +// if you need the value in MS, divide by PORT_TICS_PER_MS (which varies by board and clock frequency and defined in board_info.h) +uint16_t board_getSlotDuration (void){ + return slot_board_vars [selected_slot_type].slotDuration; +} + +// Setter/Getter function for slot_board_vars +slot_board_vars_t board_selectSlotTemplate (slotType_t slot_type){ + selected_slot_type = slot_type; + return slot_board_vars [selected_slot_type]; +} + void board_sleep(void) { __bis_SR_register(GIE+LPM3_bits); // sleep, but leave ACLK on } diff --git a/bsp/boards/gina/board_info.h b/bsp/boards/gina/board_info.h index 1e4e76c481..0d74de6988 100644 --- a/bsp/boards/gina/board_info.h +++ b/bsp/boards/gina/board_info.h @@ -60,24 +60,6 @@ to return the board's description. #define PORT_PIN_RADIO_RESET_HIGH() // nothing #define PORT_PIN_RADIO_RESET_LOW() // nothing -//===== IEEE802154E timing - -#define SLOTDURATION 20 // in miliseconds - -// time-slot related -#define PORT_TsSlotDuration 655 // 20ms - -// execution speed related -#define PORT_maxTxDataPrepare 110 // 3355us (not measured) -#define PORT_maxRxAckPrepare 20 // 610us (not measured) -#define PORT_maxRxDataPrepare 33 // 1000us (not measured) -#define PORT_maxTxAckPrepare 50 // 1525us (not measured) - -// radio speed related -#define PORT_delayTx 18 // 549us (not measured) -#define PORT_delayRx 0 // 0us (can not measure) -// radio watchdog - //===== adaptive_sync accuracy #define SYNC_ACCURACY 1 // ticks diff --git a/bsp/boards/iot-lab_A8-M3/board.c b/bsp/boards/iot-lab_A8-M3/board.c index ebcf2c515d..d99b41559e 100644 --- a/bsp/boards/iot-lab_A8-M3/board.c +++ b/bsp/boards/iot-lab_A8-M3/board.c @@ -18,7 +18,10 @@ #include "nvic.h" #include "debugpins.h" -//=========================== variable ======================================== +//=========================== variables ======================================= + +slot_board_vars_t slot_board_vars [MAX_SLOT_TYPES]; +slotType_t selected_slot_type; //=========================== private ========================================= @@ -98,12 +101,38 @@ void board_init(void){ debugpins_init(); //enable nvic for the radio NVIC_radio(); - + board_init_slot_vars(); #if defined(BOARD_CRYPTOENGINE_ENABLED) cryptoengine_init(); #endif } + +//==== bootstrapping slot info lookup table +void board_init_slot_vars(void){ + + // 20ms slot + slot_board_vars [SLOT_20ms_24GHZ].slotDuration = 655 ; // ms + slot_board_vars [SLOT_20ms_24GHZ].maxTxDataPrepare = 110 ; // 3355us (not measured) + slot_board_vars [SLOT_20ms_24GHZ].maxRxAckPrepare = 20 ; // 610us (not measured) + slot_board_vars [SLOT_20ms_24GHZ].maxRxDataPrepare = 33 ; // 1000us (not measured) + slot_board_vars [SLOT_20ms_24GHZ].maxTxAckPrepare = 50 ; // 1525us (not measured) + slot_board_vars [SLOT_20ms_24GHZ].delayTx = 18 ; // 549us (not measured) + slot_board_vars [SLOT_20ms_24GHZ].delayRx = 0 ; // 0us (can not measure) +} + +// To get the current slotDuration at any time +// used during initialization by sixtop to fire the first sixtop EB +uint16_t board_getSlotDuration (void){ + return slot_board_vars [selected_slot_type].slotDuration; +} + +// Setter/Getter function for slot_board_vars +slot_board_vars_t board_selectSlotTemplate (slotType_t slot_type){ + selected_slot_type = slot_type; + return slot_board_vars [selected_slot_type]; +} + void board_sleep(void) { DBGMCU_Config(DBGMCU_STOP, ENABLE); // Enable PWR and BKP clock diff --git a/bsp/boards/iot-lab_A8-M3/board_info.h b/bsp/boards/iot-lab_A8-M3/board_info.h index 46b9db4c12..379933fc72 100644 --- a/bsp/boards/iot-lab_A8-M3/board_info.h +++ b/bsp/boards/iot-lab_A8-M3/board_info.h @@ -50,23 +50,6 @@ to return the board's description. #define PORT_PIN_RADIO_RESET_HIGH() //GPIOC->ODR |= 0X0040;// nothing #define PORT_PIN_RADIO_RESET_LOW() //GPIOC->ODR &= ~0X0040;// nothing -//===== IEEE802154E timing - -#define SLOTDURATION 20 // in miliseconds - -// time-slot related -#define PORT_TsSlotDuration 655 // 20ms - -// execution speed related -#define PORT_maxTxDataPrepare 110 // 3355us (not measured) -#define PORT_maxRxAckPrepare 20 // 610us (not measured) -#define PORT_maxRxDataPrepare 33 // 1000us (not measured) -#define PORT_maxTxAckPrepare 50 // 1525us (not measured) - -// radio speed related -#define PORT_delayTx 18 // 549us (not measured) -#define PORT_delayRx 0 // 0us (can not measure) -// radio watchdog //===== adaptive_sync accuracy diff --git a/bsp/boards/iot-lab_M3/board.c b/bsp/boards/iot-lab_M3/board.c index 9a6cf3d01c..82091ebe5b 100644 --- a/bsp/boards/iot-lab_M3/board.c +++ b/bsp/boards/iot-lab_M3/board.c @@ -21,6 +21,10 @@ #include "gpio.h" #include "cryptoengine.h" +//=========================== variables ======================================= +slot_board_vars_t slot_board_vars [MAX_SLOT_TYPES]; +slotType_t selected_slot_type; + //=========================== main ============================================ extern int mote_main(void); @@ -36,8 +40,7 @@ void board_enableHardFaultExceptionHandler(void); //=========================== public ========================================== -void board_init(void) -{ +void board_init(void){ RCC_Configuration();//Configure rcc NVIC_Configuration();//configure NVIC and Vector Table @@ -94,12 +97,39 @@ void board_init(void) debugpins_init(); //enable nvic for the radio NVIC_radio(); + board_init_slot_vars(); #if defined(BOARD_CRYPTOENGINE_ENABLED) cryptoengine_init(); #endif } + +//==== bootstrapping slot info lookup table +void board_init_slot_vars(void){ + + // 20ms slot + slot_board_vars [SLOT_20ms_24GHZ].slotDuration = 655 ; // ms + slot_board_vars [SLOT_20ms_24GHZ].maxTxDataPrepare = 110 ; // 3355us (not measured) + slot_board_vars [SLOT_20ms_24GHZ].maxRxAckPrepare = 20 ; // 610us (not measured) + slot_board_vars [SLOT_20ms_24GHZ].maxRxDataPrepare = 33 ; // 1000us (not measured) + slot_board_vars [SLOT_20ms_24GHZ].maxTxAckPrepare = 50 ; // 1525us (not measured) + slot_board_vars [SLOT_20ms_24GHZ].delayTx = 18 ; // 549us (not measured) + slot_board_vars [SLOT_20ms_24GHZ].delayRx = 0 ; // 0us (can not measure) +} + +// To get the current slotDuration at any time +// used during initialization by sixtop to fire the first sixtop EB +uint16_t board_getSlotDuration (void){ + return slot_board_vars [selected_slot_type].slotDuration; +} + +// Setter/Getter function for slot_board_vars +slot_board_vars_t board_selectSlotTemplate (slotType_t slot_type){ + selected_slot_type = slot_type; + return slot_board_vars [selected_slot_type]; +} + void board_sleep(void) { DBGMCU_Config(DBGMCU_STOP, ENABLE); // Enable PWR and BKP clock diff --git a/bsp/boards/iot-lab_M3/board_info.h b/bsp/boards/iot-lab_M3/board_info.h index babbc4a216..36d3109adb 100644 --- a/bsp/boards/iot-lab_M3/board_info.h +++ b/bsp/boards/iot-lab_M3/board_info.h @@ -49,23 +49,6 @@ to return the board's description. #define PORT_PIN_RADIO_RESET_LOW() //GPIOC->ODR &= ~0X0040;// nothing //#define PORT_PIN_RADIO_RESET_LOW() GPIOC->ODR &= ~(1<<1); -//===== IEEE802154E timing - -#define SLOTDURATION 20 // in miliseconds - -// time-slot related -#define PORT_TsSlotDuration 655 // 20ms - -// execution speed related -#define PORT_maxTxDataPrepare 110 // 3355us (not measured) -#define PORT_maxRxAckPrepare 20 // 610us (not measured) -#define PORT_maxRxDataPrepare 33 // 1000us (not measured) -#define PORT_maxTxAckPrepare 50 // 1525us (not measured) - -// radio speed related -#define PORT_delayTx 18 // 549us (not measured) -#define PORT_delayRx 0 // 0us (can not measure) -// radio watchdog //===== adaptive_sync accuracy diff --git a/bsp/boards/nrf52840/board.c b/bsp/boards/nrf52840/board.c index b969399c98..e595e82b29 100644 --- a/bsp/boards/nrf52840/board.c +++ b/bsp/boards/nrf52840/board.c @@ -90,11 +90,57 @@ void board_init(void) { i2c_init(); + board_init_slot_vars(); + #if defined(BOARD_SENSORS_ENABLED) sensors_init(); #endif } +//==== IEEE802154E timing: bootstrapping slot info lookup table +// 1 clock tick = 30.5 us +void board_init_slot_vars(void){ + + + //10ms slot + slot_board_vars [SLOT_10ms_24GHZ].slotDuration = 328 ; // tics + slot_board_vars [SLOT_10ms_24GHZ].maxTxDataPrepare = 13 ; // ~397us (measured 364us) + slot_board_vars [SLOT_10ms_24GHZ].maxRxAckPrepare = 13 ; // ~397us (measured 364us) + slot_board_vars [SLOT_10ms_24GHZ].maxRxDataPrepare = 13 ; // ~397us (measured 364us) + slot_board_vars [SLOT_10ms_24GHZ].maxTxAckPrepare = 13 ; // ~397us (measured 364us) + slot_board_vars [SLOT_10ms_24GHZ].delayTx = 10 ; // 305us (measured 282us; radio_txNow() to RADIO_IRQHandler() / NRF_RADIO->EVENTS_READY) + slot_board_vars [SLOT_10ms_24GHZ].delayRx = 5 ; // ~153us (measured 147us; radio_rxNow() to RADIO_IRQHandler() / NRF_RADIO->EVENTS_READY) + + // 20ms slot + slot_board_vars [SLOT_20ms_24GHZ].slotDuration = 655 ; // tics + slot_board_vars [SLOT_20ms_24GHZ].maxTxDataPrepare = 13 ; // ~397us (measured 364us) + slot_board_vars [SLOT_20ms_24GHZ].maxRxAckPrepare = 13 ; // ~397us (measured 364us) + slot_board_vars [SLOT_20ms_24GHZ].maxRxDataPrepare = 13 ; // ~397us (measured 364us) + slot_board_vars [SLOT_20ms_24GHZ].maxTxAckPrepare = 13 ; // ~397us (measured 364us) + #if BOARD_PCA10056 + // nrf52840-DK + slot_board_vars [SLOT_20ms_24GHZ].delayTx = 1 ; // 305us (measured 282us; radio_txNow() to RADIO_IRQHandler() / NRF_RADIO->EVENTS_READY) + slot_board_vars [SLOT_20ms_24GHZ].delayRx = 0 ; // ~153us (measured 147us; radio_rxNow() to RADIO_IRQHandler() / NRF_RADIO->EVENTS_READY) + #endif + #if BOARD_PCA10059 + // nrf52840-DONGLE + slot_board_vars [SLOT_20ms_24GHZ].delayTx = 10 ; // 305us (measured 282us; radio_txNow() to RADIO_IRQHandler() / NRF_RADIO->EVENTS_READY) + slot_board_vars [SLOT_20ms_24GHZ].delayRx = 5 ; // ~153us (measured 147us; radio_rxNow() to RADIO_IRQHandler() / NRF_RADIO->EVENTS_READY) + #endif +} + +// To get the current slotDuration at any time (in tics) +// if you need the value in MS, divide by PORT_TICS_PER_MS (which varies by board and clock frequency and defined in board_info.h) +uint16_t board_getSlotDuration (void){ + return slot_board_vars [selected_slot_type].slotDuration; +} + +// Setter/Getter function for slot_board_vars +slot_board_vars_t board_selectSlotTemplate (slotType_t slot_type){ + selected_slot_type = slot_type; + return slot_board_vars [selected_slot_type]; +} + /** * Puts the board to sleep */ diff --git a/bsp/boards/nrf52840/board_info.h b/bsp/boards/nrf52840/board_info.h index 0a00b98d55..891014456d 100644 --- a/bsp/boards/nrf52840/board_info.h +++ b/bsp/boards/nrf52840/board_info.h @@ -39,99 +39,6 @@ // is not connected to a pin on the MSP which allows time capture. #define CAPTURE_TIME() -//===== IEEE802154E timing -// 1 clock tick = 30.5 us - -#define SLOTDURATION 20 // in miliseconds - -#if SLOTDURATION==10 - // time-slot related - #define PORT_TsSlotDuration 328 // counter counts one extra count, see datasheet - -#if BOARD_PCA10056 -// nrf52840-DK - #define PORT_maxTxDataPrepare 13 // ~397us (measured 364us) - #define PORT_maxRxAckPrepare 13 // ~397us (measured 364us) - #define PORT_maxRxDataPrepare 13 // ~397us (measured 364us) - #define PORT_maxTxAckPrepare 13 // ~397us (measured 364us) - - // radio speed related - #define PORT_delayTx 10 // 305us (measured 282us; radio_txNow() to RADIO_IRQHandler() / NRF_RADIO->EVENTS_READY) - #define PORT_delayRx 5 // ~153us (measured 147us; radio_rxNow() to RADIO_IRQHandler() / NRF_RADIO->EVENTS_READY) -#endif -#if BOARD_PCA10059 -// nrf52840-DONGLE - #define PORT_maxTxDataPrepare 13 // ~397us (measured 345us) - #define PORT_maxRxAckPrepare 13 // ~397us (measured 345us) - #define PORT_maxRxDataPrepare 13 // ~397us (measured 345us) - #define PORT_maxTxAckPrepare 13 // ~397us (measured 345us) - - // radio speed related - #define PORT_delayTx 10 // 305us (measured 282us; radio_txNow() to RADIO_IRQHandler() / NRF_RADIO->EVENTS_READY) - #define PORT_delayRx 5 // ~153us (measured 136us; radio_rxNow() to RADIO_IRQHandler() / NRF_RADIO->EVENTS_READY) -#endif - -#endif // SLOTDURATION==10 - -#if SLOTDURATION==15 - // time-slot related - #define PORT_TsSlotDuration 492 // counter counts one extra count, see datasheet - -#if BOARD_PCA10056 -// nrf52840-DK - #define PORT_maxTxDataPrepare 13 // ~397us (measured 364us) - #define PORT_maxRxAckPrepare 13 // ~397us (measured 364us) - #define PORT_maxRxDataPrepare 13 // ~397us (measured 364us) - #define PORT_maxTxAckPrepare 13 // ~397us (measured 364us) - - // radio speed related - #define PORT_delayTx 10 // 305us (measured 282us; radio_txNow() to RADIO_IRQHandler() / NRF_RADIO->EVENTS_READY) - #define PORT_delayRx 5 // ~153us (measured 147us; radio_rxNow() to RADIO_IRQHandler() / NRF_RADIO->EVENTS_READY) -#endif -#if BOARD_PCA10059 -// nrf52840-DONGLE - #define PORT_maxTxDataPrepare 13 // ~397us (measured 345us) - #define PORT_maxRxAckPrepare 13 // ~397us (measured 345us) - #define PORT_maxRxDataPrepare 13 // ~397us (measured 345us) - #define PORT_maxTxAckPrepare 13 // ~397us (measured 345us) - - // radio speed related - #define PORT_delayTx 10 // 305us (measured 282us; radio_txNow() to RADIO_IRQHandler() / NRF_RADIO->EVENTS_READY) - #define PORT_delayRx 5 // ~153us (measured 136us; radio_rxNow() to RADIO_IRQHandler() / NRF_RADIO->EVENTS_READY) -#endif - -#endif // SLOTDURATION==15 - - -#if SLOTDURATION==20 - // time-slot related - #define PORT_TsSlotDuration 656 // counter counts one extra count, see datasheet - -#if BOARD_PCA10056 -// nrf52840-DK - #define PORT_maxTxDataPrepare 13 // ~397us (measured 364us) - #define PORT_maxRxAckPrepare 13 // ~397us (measured 364us) - #define PORT_maxRxDataPrepare 13 // ~397us (measured 364us) - #define PORT_maxTxAckPrepare 13 // ~397us (measured 364us) - - // radio speed related - #define PORT_delayTx 1 // 305us (measured 282us; radio_txNow() to RADIO_IRQHandler() / NRF_RADIO->EVENTS_READY) - #define PORT_delayRx 0 // ~153us (measured 147us; radio_rxNow() to RADIO_IRQHandler() / NRF_RADIO->EVENTS_READY) -#endif -#if BOARD_PCA10059 -// nrf52840-DONGLE - #define PORT_maxTxDataPrepare 13 // ~397us (measured 345us) - #define PORT_maxRxAckPrepare 13 // ~397us (measured 345us) - #define PORT_maxRxDataPrepare 13 // ~397us (measured 345us) - #define PORT_maxTxAckPrepare 13 // ~397us (measured 345us) - - // radio speed related - #define PORT_delayTx 10 // 305us (measured 282us; radio_txNow() to RADIO_IRQHandler() / NRF_RADIO->EVENTS_READY) - #define PORT_delayRx 5 // ~153us (measured 136us; radio_rxNow() to RADIO_IRQHandler() / NRF_RADIO->EVENTS_READY) -#endif - -#endif // SLOTDURATION==20 - //===== adaptive_sync accuracy #define SYNC_ACCURACY 1 // ticks diff --git a/bsp/boards/nrf52840/radio.c b/bsp/boards/nrf52840/radio.c index f3b371943a..234e63eb45 100644 --- a/bsp/boards/nrf52840/radio.c +++ b/bsp/boards/nrf52840/radio.c @@ -193,6 +193,10 @@ void radio_reset(void) { radio_vars.state = RADIOSTATE_STOPPED; } +void radio_setConfig (radioSetting_t radioSetting){ + selected_radioSetting = radioSetting; + //do nothing +} void radio_setFrequency(uint8_t frequency, radio_freq_t tx_or_rx) { diff --git a/bsp/boards/openmote-b-24ghz/board.c b/bsp/boards/openmote-b-24ghz/board.c index 194d9779b8..c1d8876a44 100644 --- a/bsp/boards/openmote-b-24ghz/board.c +++ b/bsp/boards/openmote-b-24ghz/board.c @@ -35,6 +35,11 @@ #define BSP_BUTTON_BASE ( GPIO_D_BASE ) #define BSP_BUTTON_USER ( GPIO_PIN_5 ) +//=========================== variables ============================================ +slot_board_vars_t slot_board_vars [MAX_SLOT_TYPES]; +slotType_t selected_slot_type; + + //=========================== prototypes ====================================== void board_timer_init(void); @@ -56,7 +61,7 @@ static void SysCtrlWakeupSetting(void); extern int mote_main(void); int main(void) { - return mote_main(); + return mote_main(); } //=========================== public ========================================== @@ -74,6 +79,7 @@ void board_init(void) { uart_init(); radio_init(); i2c_init(); + board_init_slot_vars(); #if defined(BOARD_SENSORS_ENABLED) sensors_init(); @@ -84,24 +90,62 @@ void board_init(void) { #endif } +//==== bootstrapping slot info lookup table +void board_init_slot_vars(void){ + //10ms slot + slot_board_vars [SLOT_10ms_24GHZ].slotDuration = 328 ; // 10ms + slot_board_vars [SLOT_10ms_24GHZ].maxTxDataPrepare = 10 ; // 305us (measured 82us) + slot_board_vars [SLOT_10ms_24GHZ].maxRxAckPrepare = 10 ; // 305us (measured 83us) + slot_board_vars [SLOT_10ms_24GHZ].maxRxDataPrepare = 4 ; // 122us (measured 22us) + slot_board_vars [SLOT_10ms_24GHZ].maxTxAckPrepare = 10 ; // 122us (measured 94us) + + #ifdef OPENWSN_IEEE802154E_SECURITY_C + slot_board_vars [SLOT_10ms_24GHZ].delayTx = 14 ; // 366us (measured xxxus) + #else + slot_board_vars [SLOT_10ms_24GHZ].delayTx = 12 ; // 366us (measured xxxus) + #endif + slot_board_vars [SLOT_10ms_24GHZ].delayRx = 0 ; // 0us (can not measure) + + // 20ms slot + slot_board_vars [SLOT_20ms_24GHZ].slotDuration = 655 ; // 20ms + slot_board_vars [SLOT_20ms_24GHZ].maxTxDataPrepare = 15 ; // 457us (based on measurement) + slot_board_vars [SLOT_20ms_24GHZ].maxRxAckPrepare = 10 ; // 305us (based on measurement) + slot_board_vars [SLOT_20ms_24GHZ].maxRxDataPrepare = 10 ; // 305us (based on measurement) + slot_board_vars [SLOT_20ms_24GHZ].maxTxAckPrepare = 15 ; // 457us (based on measurement) + slot_board_vars [SLOT_20ms_24GHZ].delayTx = 13 ; // 396us (based on measurement) + slot_board_vars [SLOT_20ms_24GHZ].delayRx = 0 ; // 0us (can not measure) +} + +// To get the current slotDuration at any time +// used during initialization by sixtop to fire the first sixtop EB +uint16_t board_getSlotDuration (void){ + return slot_board_vars [selected_slot_type].slotDuration; +} + +// Setter/Getter function for slot_board_vars +slot_board_vars_t board_selectSlotTemplate (slotType_t slot_type){ + selected_slot_type = slot_type; + return slot_board_vars [selected_slot_type]; +} + void antenna_init(void) { - /* Configure GPIO as output */ - GPIOPinTypeGPIOOutput(BSP_ANTENNA_BASE, BSP_ANTENNA_CC2538_24GHZ); - GPIOPinTypeGPIOOutput(BSP_ANTENNA_BASE, BSP_ANTENNA_AT215_24GHZ); + /* Configure GPIO as output */ + GPIOPinTypeGPIOOutput(BSP_ANTENNA_BASE, BSP_ANTENNA_CC2538_24GHZ); + GPIOPinTypeGPIOOutput(BSP_ANTENNA_BASE, BSP_ANTENNA_AT215_24GHZ); - /* Use CC2538 antenna by default */ - GPIOPinWrite(BSP_ANTENNA_BASE, BSP_ANTENNA_CC2538_24GHZ, 0); - GPIOPinWrite(BSP_ANTENNA_BASE, BSP_ANTENNA_AT215_24GHZ, BSP_ANTENNA_AT215_24GHZ); + /* Use CC2538 antenna by default */ + GPIOPinWrite(BSP_ANTENNA_BASE, BSP_ANTENNA_CC2538_24GHZ, 0); + GPIOPinWrite(BSP_ANTENNA_BASE, BSP_ANTENNA_AT215_24GHZ, BSP_ANTENNA_AT215_24GHZ); } void antenna_cc2538(void) { - GPIOPinWrite(BSP_ANTENNA_BASE, BSP_ANTENNA_CC2538_24GHZ, 0); - GPIOPinWrite(BSP_ANTENNA_BASE, BSP_ANTENNA_AT215_24GHZ, BSP_ANTENNA_AT215_24GHZ); + GPIOPinWrite(BSP_ANTENNA_BASE, BSP_ANTENNA_CC2538_24GHZ, 0); + GPIOPinWrite(BSP_ANTENNA_BASE, BSP_ANTENNA_AT215_24GHZ, BSP_ANTENNA_AT215_24GHZ); } void antenna_at86rf215(void) { - GPIOPinWrite(BSP_ANTENNA_BASE, BSP_ANTENNA_AT215_24GHZ, 0); - GPIOPinWrite(BSP_ANTENNA_BASE, BSP_ANTENNA_CC2538_24GHZ, BSP_ANTENNA_CC2538_24GHZ); + GPIOPinWrite(BSP_ANTENNA_BASE, BSP_ANTENNA_AT215_24GHZ, 0); + GPIOPinWrite(BSP_ANTENNA_BASE, BSP_ANTENNA_CC2538_24GHZ, BSP_ANTENNA_CC2538_24GHZ); } /** @@ -228,78 +272,78 @@ static void button_init(void) { } static void SysCtrlRunSetting(void) { - /* Disable General Purpose Timers 0, 1, 2, 3 when running */ - SysCtrlPeripheralDisable(SYS_CTRL_PERIPH_GPT0); - SysCtrlPeripheralDisable(SYS_CTRL_PERIPH_GPT1); - SysCtrlPeripheralDisable(SYS_CTRL_PERIPH_GPT3); - - /* Disable SSI 0, 1 when running */ - SysCtrlPeripheralDisable(SYS_CTRL_PERIPH_SSI0); - SysCtrlPeripheralDisable(SYS_CTRL_PERIPH_SSI1); - - /* Disable UART1 when running */ - SysCtrlPeripheralDisable(SYS_CTRL_PERIPH_UART1); - - /* Disable I2C, AES and PKA when running */ - SysCtrlPeripheralDisable(SYS_CTRL_PERIPH_I2C); - SysCtrlPeripheralDisable(SYS_CTRL_PERIPH_PKA); - SysCtrlPeripheralDisable(SYS_CTRL_PERIPH_AES); - - /* Enable UART0 and RFC when running */ - SysCtrlPeripheralEnable(SYS_CTRL_PERIPH_GPT2); - SysCtrlPeripheralEnable(SYS_CTRL_PERIPH_UART0); - SysCtrlPeripheralEnable(SYS_CTRL_PERIPH_RFC); + /* Disable General Purpose Timers 0, 1, 2, 3 when running */ + SysCtrlPeripheralDisable(SYS_CTRL_PERIPH_GPT0); + SysCtrlPeripheralDisable(SYS_CTRL_PERIPH_GPT1); + SysCtrlPeripheralDisable(SYS_CTRL_PERIPH_GPT3); + + /* Disable SSI 0, 1 when running */ + SysCtrlPeripheralDisable(SYS_CTRL_PERIPH_SSI0); + SysCtrlPeripheralDisable(SYS_CTRL_PERIPH_SSI1); + + /* Disable UART1 when running */ + SysCtrlPeripheralDisable(SYS_CTRL_PERIPH_UART1); + + /* Disable I2C, AES and PKA when running */ + SysCtrlPeripheralDisable(SYS_CTRL_PERIPH_I2C); + SysCtrlPeripheralDisable(SYS_CTRL_PERIPH_PKA); + SysCtrlPeripheralDisable(SYS_CTRL_PERIPH_AES); + + /* Enable UART0 and RFC when running */ + SysCtrlPeripheralEnable(SYS_CTRL_PERIPH_GPT2); + SysCtrlPeripheralEnable(SYS_CTRL_PERIPH_UART0); + SysCtrlPeripheralEnable(SYS_CTRL_PERIPH_RFC); } static void SysCtrlSleepSetting(void) { - /* Disable General Purpose Timers 0, 1, 2, 3 during sleep */ - SysCtrlPeripheralSleepDisable(SYS_CTRL_PERIPH_GPT0); - SysCtrlPeripheralSleepDisable(SYS_CTRL_PERIPH_GPT1); - SysCtrlPeripheralSleepDisable(SYS_CTRL_PERIPH_GPT3); - - /* Disable SSI 0, 1 during sleep */ - SysCtrlPeripheralSleepDisable(SYS_CTRL_PERIPH_SSI0); - SysCtrlPeripheralSleepDisable(SYS_CTRL_PERIPH_SSI1); - - /* Disable UART 0, 1 during sleep */ - SysCtrlPeripheralSleepDisable(SYS_CTRL_PERIPH_UART1); - - /* Disable I2C, PKA, AES during sleep */ - SysCtrlPeripheralSleepDisable(SYS_CTRL_PERIPH_I2C); - SysCtrlPeripheralSleepDisable(SYS_CTRL_PERIPH_PKA); - SysCtrlPeripheralSleepDisable(SYS_CTRL_PERIPH_AES); - - /* Enable UART and RFC during sleep */ - SysCtrlPeripheralSleepEnable(SYS_CTRL_PERIPH_GPT2); - SysCtrlPeripheralSleepEnable(SYS_CTRL_PERIPH_UART0); - SysCtrlPeripheralSleepEnable(SYS_CTRL_PERIPH_RFC); + /* Disable General Purpose Timers 0, 1, 2, 3 during sleep */ + SysCtrlPeripheralSleepDisable(SYS_CTRL_PERIPH_GPT0); + SysCtrlPeripheralSleepDisable(SYS_CTRL_PERIPH_GPT1); + SysCtrlPeripheralSleepDisable(SYS_CTRL_PERIPH_GPT3); + + /* Disable SSI 0, 1 during sleep */ + SysCtrlPeripheralSleepDisable(SYS_CTRL_PERIPH_SSI0); + SysCtrlPeripheralSleepDisable(SYS_CTRL_PERIPH_SSI1); + + /* Disable UART 0, 1 during sleep */ + SysCtrlPeripheralSleepDisable(SYS_CTRL_PERIPH_UART1); + + /* Disable I2C, PKA, AES during sleep */ + SysCtrlPeripheralSleepDisable(SYS_CTRL_PERIPH_I2C); + SysCtrlPeripheralSleepDisable(SYS_CTRL_PERIPH_PKA); + SysCtrlPeripheralSleepDisable(SYS_CTRL_PERIPH_AES); + + /* Enable UART and RFC during sleep */ + SysCtrlPeripheralSleepEnable(SYS_CTRL_PERIPH_GPT2); + SysCtrlPeripheralSleepEnable(SYS_CTRL_PERIPH_UART0); + SysCtrlPeripheralSleepEnable(SYS_CTRL_PERIPH_RFC); } static void SysCtrlDeepSleepSetting(void) { - /* Disable General Purpose Timers 0, 1, 2, 3 during deep sleep */ - SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_GPT0); - SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_GPT1); - SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_GPT2); - SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_GPT3); - - /* Disable SSI 0, 1 during deep sleep */ - SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_SSI0); - SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_SSI1); - - /* Disable UART 0, 1 during deep sleep */ - SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_UART0); - SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_UART1); - - /* Disable I2C, PKA, AES during deep sleep */ - SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_I2C); - SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_PKA); - SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_AES); - SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_RFC); + /* Disable General Purpose Timers 0, 1, 2, 3 during deep sleep */ + SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_GPT0); + SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_GPT1); + SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_GPT2); + SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_GPT3); + + /* Disable SSI 0, 1 during deep sleep */ + SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_SSI0); + SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_SSI1); + + /* Disable UART 0, 1 during deep sleep */ + SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_UART0); + SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_UART1); + + /* Disable I2C, PKA, AES during deep sleep */ + SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_I2C); + SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_PKA); + SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_AES); + SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_RFC); } static void SysCtrlWakeupSetting(void) { /* Allow the SMTimer to wake up the processor */ - GPIOIntWakeupEnable(GPIO_IWE_SM_TIMER); + GPIOIntWakeupEnable(GPIO_IWE_SM_TIMER); } //=========================== interrupt handlers ============================== diff --git a/bsp/boards/openmote-b-24ghz/board_info.h b/bsp/boards/openmote-b-24ghz/board_info.h index 3590522c31..0805505544 100644 --- a/bsp/boards/openmote-b-24ghz/board_info.h +++ b/bsp/boards/openmote-b-24ghz/board_info.h @@ -60,42 +60,6 @@ #define PORT_PIN_RADIO_RESET_HIGH() // nothing #define PORT_PIN_RADIO_RESET_LOW() // nothing -#define SLOTDURATION 20 // in miliseconds - -//===== IEEE802154E timing - -#if SLOTDURATION==10 - // time-slot related - #define PORT_TsSlotDuration 328 // counter counts one extra count, see datasheet - // execution speed related - #define PORT_maxTxDataPrepare 10 // 305us (measured 82us) - #define PORT_maxRxAckPrepare 10 // 305us (measured 83us) - #define PORT_maxRxDataPrepare 4 // 122us (measured 22us) - #define PORT_maxTxAckPrepare 10 // 122us (measured 94us) - // radio speed related -#ifdef OPENWSN_IEEE802154E_SECURITY_C - #define PORT_delayTx 14 // 366us (measured xxxus) -#else - #define PORT_delayTx 12 // 366us (measured xxxus) -#endif - #define PORT_delayRx 0 // 0us (can not measure) - // radio watchdog -#endif - -#if SLOTDURATION==20 - #define PORT_TsSlotDuration 655 // 20ms - - // execution speed related - #define PORT_maxTxDataPrepare 15 // 458us (measured 213us) - #define PORT_maxRxAckPrepare 10 // 305us (measured 86us) - #define PORT_maxRxDataPrepare 10 // 305us (measured 88us) - #define PORT_maxTxAckPrepare 15 // 458us (measured 211us) - - // radio speed related - #define PORT_delayTx 13 // 397us (measured 388us) - #define PORT_delayRx 0 // 0us (can not measure) -#endif - //===== adaptive_sync accuracy #define SYNC_ACCURACY 1 // ticks diff --git a/bsp/boards/openmote-b-24ghz/debugpins.c b/bsp/boards/openmote-b-24ghz/debugpins.c index a3843f371c..877b2836d0 100644 --- a/bsp/boards/openmote-b-24ghz/debugpins.c +++ b/bsp/boards/openmote-b-24ghz/debugpins.c @@ -47,13 +47,13 @@ void debugpins_init(void) { // PA7 void debugpins_frame_toggle(void) { - bspDBpinToggle(BSP_PINA_BASE, BSP_PINA_7); + bspDBpinToggle(BSP_PINA_BASE, BSP_PINA_7); } void debugpins_frame_clr(void) { GPIOPinWrite(BSP_PINA_BASE, BSP_PINA_7, 0); } void debugpins_frame_set(void) { - GPIOPinWrite(BSP_PINA_BASE, BSP_PINA_7, BSP_PINA_7); + GPIOPinWrite(BSP_PINA_BASE, BSP_PINA_7, BSP_PINA_7); } // PB3 @@ -122,8 +122,7 @@ void debugpins_isruarttx_set(void) {} //------------ private ------------// -void bspDBpinToggle(uint32_t base, uint8_t ui8Pin) -{ +void bspDBpinToggle(uint32_t base, uint8_t ui8Pin){ // Get current pin values of selected bits uint32_t ui32Toggle = GPIOPinRead(base, ui8Pin); diff --git a/bsp/boards/openmote-b-24ghz/radio.c b/bsp/boards/openmote-b-24ghz/radio.c index 08fe64c205..901a121b72 100644 --- a/bsp/boards/openmote-b-24ghz/radio.c +++ b/bsp/boards/openmote-b-24ghz/radio.c @@ -45,6 +45,8 @@ typedef struct { radio_vars_t radio_vars; +// global radio selection, will use RADIOSETTING_24GHZ by default at initialization. +uint8_t selected_radioSetting = RADIOSETTING_24GHZ; //=========================== prototypes ====================================== void enable_radio_interrupts(void); @@ -181,6 +183,12 @@ void radio_reset(void) { //===== RF admin +void radio_setConfig (radioSetting_t radioSetting){ + selected_radioSetting = radioSetting; + //do nothing +} + + void radio_setFrequency(uint8_t frequency, radio_freq_t tx_or_rx) { // change state diff --git a/bsp/boards/openmote-b/SConscript b/bsp/boards/openmote-b/SConscript index 71941a8ed4..570b55d7c9 100644 --- a/bsp/boards/openmote-b/SConscript +++ b/bsp/boards/openmote-b/SConscript @@ -10,6 +10,17 @@ si70x = localEnv.SConscript( exports = {'env': env}, ) +cc2538rf = localEnv.SConscript( + os.path.join('#','bsp','chips','cc2538rf','SConscript'), + variant_dir = 'cc2538rf', + exports = {'env': env}, +) +rf215 = localEnv.SConscript( + os.path.join('#','bsp','chips','at86rf215','SConscript'), + variant_dir = 'rf215', + exports = {'env': env}, +) + source = \ [file for file in Glob('*.c') if file.name.find('iar')==-1] + \ Glob('source/*.c') @@ -19,10 +30,12 @@ localEnv.Append( os.path.join('#','bsp','boards','openmote-b'), os.path.join('#','bsp','boards','openmote-b','headers'), os.path.join('#','bsp','boards','openmote-b','source'), + os.path.join('#','bsp','chips','cc2538rf'), os.path.join('#','bsp','chips','si70x'), + os.path.join('#','bsp','chips','at86rf215'), ], ) -board = localEnv.Object(source=source) + si70x +board = localEnv.Object(source=source) + si70x + rf215 + cc2538rf Return('board') diff --git a/bsp/boards/openmote-b/board.c b/bsp/boards/openmote-b/board.c index ed1bdf56a4..39ad8d31ba 100644 --- a/bsp/boards/openmote-b/board.c +++ b/bsp/boards/openmote-b/board.c @@ -1,9 +1,11 @@ -/** - * Author: Xavier Vilajosana (xvilajosana@eecs.berkeley.edu) - * Pere Tuset (peretuset@openmote.com) - * Date: July 2013 - * Description: CC2538-specific definition of the "board" bsp module. - */ + + // Author: Xavier Vilajosana (xvilajosana@eecs.berkeley.edu) + // Pere Tuset (peretuset@openmote.com) + // Date: July 2013 + // Description: CC2538-specific definition of the "board" bsp module. + // Updated by: Mina Rady (mina1.rady@orange.com) + // Update date: April 2020 + #include #include @@ -20,6 +22,7 @@ #include "config.h" #include "board.h" +#include "board_info.h" #include "debugpins.h" #include "i2c.h" #include "leds.h" @@ -29,16 +32,13 @@ #include "uart.h" #include "cryptoengine.h" -//=========================== variables ======================================= +//=========================== defines ======================================= -#define BSP_BUTTON_BASE ( GPIO_C_BASE ) -#define BSP_BUTTON_USER ( GPIO_PIN_3 ) +#define BSP_BUTTON_BASE ( GPIO_D_BASE ) +#define BSP_BUTTON_USER ( GPIO_PIN_5 ) + +//=========================== variables ====================================== -#ifdef REVA1 //Rev.A1 uses SF23 cc2538 which start at diffferent location - #define CC2538_FLASH_ADDRESS ( 0x0023F800 ) -#else - #define CC2538_FLASH_ADDRESS ( 0x0027F800 ) -#endif //=========================== prototypes ====================================== void board_timer_init(void); @@ -48,284 +48,339 @@ bool board_timer_expired(uint32_t future); static void clock_init(void); static void gpio_init(void); static void button_init(void); -static void antenna_init(void); +static void antenna_init(void); +void antenna_cc2538(void); +void antenna_at86rf215(void); static void SysCtrlDeepSleepSetting(void); static void SysCtrlSleepSetting(void); static void SysCtrlRunSetting(void); static void SysCtrlWakeupSetting(void); -static void GPIO_C_Handler(void); +//=========================== variables ======================================= -bool user_button_initialized; +slot_board_vars_t slot_board_vars [MAX_SLOT_TYPES]; +slotType_t selected_slot_type; //=========================== main ============================================ - + extern int mote_main(void); -int main(void) { - return mote_main(); +int main(void){ + return mote_main(); } //=========================== public ========================================== -void board_init(void) { - user_button_initialized = FALSE; - - gpio_init(); - clock_init(); - antenna_init(); - board_timer_init(); - leds_init(); - debugpins_init(); - button_init(); - sctimer_init(); - uart_init(); - radio_init(); - i2c_init(); - +void board_init(void){ + + gpio_init(); + clock_init(); + antenna_init(); + board_timer_init(); + leds_init(); + debugpins_init(); + button_init(); + sctimer_init(); + uart_init(); + radio_init(); + i2c_init(); + board_init_slot_vars(); #if defined(BOARD_CRYPTOENGINE_ENABLED) - cryptoengine_init(); + cryptoeng #endif +} +void antenna_init(void){ + // Configure GPIO as output + GPIOPinTypeGPIOOutput(BSP_ANTENNA_BASE, BSP_ANTENNA_CC2538_24GHZ); + GPIOPinTypeGPIOOutput(BSP_ANTENNA_BASE, BSP_ANTENNA_AT215_24GHZ); + +#ifdef ATMEL_24GHZ + // atmel is using 2.4ghz, connect antenna to atrf215 + antenna_at86rf215(); +#else + // atmel is not using 2.4ghz, connect antenna to cc2538 + antenna_cc2538(); +#endif #if defined(BOARD_SENSORS_ENABLED) sensors_init(); #endif } -void antenna_init(void) { - //use cc2538 2.4ghz radio - GPIOPinWrite(BSP_ANTENNA_BASE, BSP_ANTENNA_CC2538_24GHZ, BSP_ANTENNA_CC2538_24GHZ); - GPIOPinWrite(BSP_ANTENNA_BASE, BSP_ANTENNA_AT215_24GHZ, 0); +void antenna_cc2538(void){ + GPIOPinWrite(BSP_ANTENNA_BASE, BSP_ANTENNA_CC2538_24GHZ, 0); + GPIOPinWrite(BSP_ANTENNA_BASE, BSP_ANTENNA_AT215_24GHZ, BSP_ANTENNA_AT215_24GHZ); } -/** - * Puts the board to sleep - */ -void board_sleep(void) { +void antenna_at86rf215(void){ + GPIOPinWrite(BSP_ANTENNA_BASE, BSP_ANTENNA_AT215_24GHZ, 0); + GPIOPinWrite(BSP_ANTENNA_BASE, BSP_ANTENNA_CC2538_24GHZ, BSP_ANTENNA_CC2538_24GHZ); +} + + + // Puts the board to sleep + +void board_sleep(void){ SysCtrlPowerModeSet(SYS_CTRL_PM_NOACTION); SysCtrlSleep(); } -/** - * Timer runs at 32 MHz and is 32-bit wide - * The timer is divided by 32, whichs gives a 1 microsecond ticks - */ -void board_timer_init(void) { - // Configure the timer + + // Timer runs at 32 MHz and is 32-bit wide + // The timer is divided by 32, whichs gives a 1 microsecond ticks + +void board_timer_init(void){ + //Configure the timer TimerConfigure(GPTIMER2_BASE, GPTIMER_CFG_PERIODIC_UP); - + // Enable the timer TimerEnable(GPTIMER2_BASE, GPTIMER_BOTH); } -/** - * Returns the current value of the timer - * The timer is divided by 32, whichs gives a 1 microsecond ticks - */ -uint32_t board_timer_get(void) { + +// Returns the current value of the timer +// The timer is divided by 32, whichs gives a 1 microsecond ticks + +uint32_t board_timer_get(void){ uint32_t current; - + + //Get the current timer value current = TimerValueGet(GPTIMER2_BASE, GPTIMER_A) >> 5; - + return current; } -/** - * Returns true if the timer has expired - * The timer is divided by 32, whichs gives a 1 microsecond ticks - */ -bool board_timer_expired(uint32_t future) { + + // Returns true if the timer has expired + // The timer is divided by 32, whichs gives a 1 microsecond ticks + +bool board_timer_expired(uint32_t future){ uint32_t current; int32_t remaining; + //Get current time current = TimerValueGet(GPTIMER2_BASE, GPTIMER_A) >> 5; + //Calculate remaining time remaining = (int32_t) (future - current); - - if (remaining > 0) { + + //Return if timer has expired + if (remaining > 0){ return false; } else { return true; } } -/** - * Resets the board - */ -void board_reset(void) { +//==== IEEE802154E timing: bootstrapping slot info lookup table +// 1 clock tick = 30.5 us +void board_init_slot_vars(void){ + //10ms slot + slot_board_vars [SLOT_10ms_24GHZ].slotDuration = 328 ; // ms + slot_board_vars [SLOT_10ms_24GHZ].maxTxDataPrepare = 10 ; // 305us (measured 82us) + slot_board_vars [SLOT_10ms_24GHZ].maxRxAckPrepare = 10 ; // 305us (measured 83us) + slot_board_vars [SLOT_10ms_24GHZ].maxRxDataPrepare = 4 ; // 122us (measured 22us) + slot_board_vars [SLOT_10ms_24GHZ].maxTxAckPrepare = 10 ; // 122us (measured 94us) + + #ifdef OPENWSN_IEEE802154E_SECURITY_C + slot_board_vars [SLOT_10ms_24GHZ].delayTx = 14 ; // 366us (measured xxxus) + #else + slot_board_vars [SLOT_10ms_24GHZ].delayTx = 12 ; // 366us (measured xxxus) + #endif + slot_board_vars [SLOT_10ms_24GHZ].delayRx = 0 ; // 0us (can not measure) + + // 20ms slot + slot_board_vars [SLOT_20ms_24GHZ].slotDuration = 655 ; // tics + slot_board_vars [SLOT_20ms_24GHZ].maxTxDataPrepare = 15 ; // 457us (based on measurement) + slot_board_vars [SLOT_20ms_24GHZ].maxRxAckPrepare = 10 ; // 305us (based on measurement) + slot_board_vars [SLOT_20ms_24GHZ].maxRxDataPrepare = 10 ; // 305us (based on measurement) + slot_board_vars [SLOT_20ms_24GHZ].maxTxAckPrepare = 15 ; // 457us (based on measurement) + slot_board_vars [SLOT_20ms_24GHZ].delayTx = 6 ; // 183us (based on measurement) + slot_board_vars [SLOT_20ms_24GHZ].delayRx = 0 ; // 0us (can not measure) + + //40ms slot for 24ghz cc2538 + slot_board_vars [SLOT_40ms_24GHZ].slotDuration = 1310 ; // tics + slot_board_vars [SLOT_40ms_24GHZ].maxTxDataPrepare = 15 ; // 457us (based on measurement) + slot_board_vars [SLOT_40ms_24GHZ].maxRxAckPrepare = 10 ; // 305us (based on measurement) + slot_board_vars [SLOT_40ms_24GHZ].maxRxDataPrepare = 10 ; // 305us (based on measurement) + slot_board_vars [SLOT_40ms_24GHZ].maxTxAckPrepare = 15 ; // 457us (based on measurement) + slot_board_vars [SLOT_40ms_24GHZ].delayTx = 6 ; // 183us (measured xxxus) + slot_board_vars [SLOT_40ms_24GHZ].delayRx = 0 ; // 0us (can not measure) + + //40ms slot for FSK + slot_board_vars [SLOT_40ms_FSK_SUBGHZ].slotDuration = 1310 ; // tics + slot_board_vars [SLOT_40ms_FSK_SUBGHZ].maxTxDataPrepare = 50 ; // 1525us (based on measurement) + slot_board_vars [SLOT_40ms_FSK_SUBGHZ].maxRxAckPrepare = 10 ; // 305µs (based on measurement) + slot_board_vars [SLOT_40ms_FSK_SUBGHZ].maxRxDataPrepare = 10 ; // 305µs (based on measurement) + slot_board_vars [SLOT_40ms_FSK_SUBGHZ].maxTxAckPrepare = 33 ; // 1000µs (based on measurement) + slot_board_vars [SLOT_40ms_FSK_SUBGHZ].delayTx = 66 ; // 2000µs (based on measurement) + slot_board_vars [SLOT_40ms_FSK_SUBGHZ].delayRx = 16 ; // 488µs. This parameter is usually set to 0, however for Atmel on openmote-b, it takes at least 1ms for the transmission to occure because of spi delay (or other implementation specific overhead), so reciver is expected to wait a little more before turning on the radio. + + //40ms slot for OFDM1 MCS0-3 + slot_board_vars [SLOT_40ms_OFDM1MCS0_3_SUBGHZ].slotDuration = 1310 ; // tics + slot_board_vars [SLOT_40ms_OFDM1MCS0_3_SUBGHZ].maxTxDataPrepare = 50 ; // 1525us (based on measurement) + slot_board_vars [SLOT_40ms_OFDM1MCS0_3_SUBGHZ].maxRxAckPrepare = 10 ; // 305us (based on measurement) + slot_board_vars [SLOT_40ms_OFDM1MCS0_3_SUBGHZ].maxRxDataPrepare = 10 ; // 305us (based on measurement) + slot_board_vars [SLOT_40ms_OFDM1MCS0_3_SUBGHZ].maxTxAckPrepare = 33 ; // 1000us (based on measurement) + slot_board_vars [SLOT_40ms_OFDM1MCS0_3_SUBGHZ].delayTx = 41 ; // 1251us (based on measurement) + slot_board_vars [SLOT_40ms_OFDM1MCS0_3_SUBGHZ].delayRx = 16 ; // 488µs. This parameter is usually set to 0, however for Atmel on openmote-b, it takes at least 1ms for the transmission to occure because of spi delay (or other implementation specific overhead), so reciver is expected to wait a little more before turning on the radio. +} + +// To get the current slotDuration at any time (in tics) +// if you need the value in MS, divide by PORT_TICS_PER_MS (which varies by board and clock frequency and defined in board_info.h) +uint16_t board_getSlotDuration (void){ + return slot_board_vars [selected_slot_type].slotDuration; +} + +// Setter/Getter function for slot_board_vars +slot_board_vars_t board_selectSlotTemplate (slotType_t slot_type){ + selected_slot_type = slot_type; + return slot_board_vars [selected_slot_type]; +} + + + // Resets the board + +void board_reset(void){ SysCtrlReset(); } //=========================== private ========================================= -static void gpio_init(void) { - /* Set GPIOs as output */ - GPIOPinTypeGPIOOutput(GPIO_A_BASE, 0xFF); - GPIOPinTypeGPIOOutput(GPIO_B_BASE, 0xFF); - GPIOPinTypeGPIOOutput(GPIO_C_BASE, 0xFF); - GPIOPinTypeGPIOOutput(GPIO_D_BASE, 0xFF); - - /* Initialize GPIOs to low */ - GPIOPinWrite(GPIO_A_BASE, 0xFF, 0x00); - GPIOPinWrite(GPIO_B_BASE, 0xFF, 0x00); - GPIOPinWrite(GPIO_C_BASE, 0xFF, 0x00); - GPIOPinWrite(GPIO_D_BASE, 0xFF, 0x00); +static void gpio_init(void){ + // Configure all GPIO as input + GPIOPinTypeGPIOInput(GPIO_A_BASE, 0xFF); + GPIOPinTypeGPIOInput(GPIO_B_BASE, 0xFF); + GPIOPinTypeGPIOInput(GPIO_C_BASE, 0xFF); + GPIOPinTypeGPIOInput(GPIO_D_BASE, 0xFF); } -static void clock_init(void) { - /* Disable global interrupts */ +static void clock_init(void){ + // Disable global interrupts bool bIntDisabled = IntMasterDisable(); - /* Configure the 32 kHz pins, PD6 and PD7, for crystal operation */ - /* By default they are configured as GPIOs */ + // Configure the 32 kHz pins, PD6 and PD7, for crystal operation + // By default they are configured as GPIOs GPIODirModeSet(GPIO_D_BASE, 0x40, GPIO_DIR_MODE_IN); GPIODirModeSet(GPIO_D_BASE, 0x80, GPIO_DIR_MODE_IN); IOCPadConfigSet(GPIO_D_BASE, 0x40, IOC_OVERRIDE_ANA); IOCPadConfigSet(GPIO_D_BASE, 0x80, IOC_OVERRIDE_ANA); - /* Set the real-time clock to use the 32 kHz external crystal */ - /* Set the system clock to use the external 32 MHz crystal */ - /* Set the system clock to 32 MHz */ + // Set the real-time clock to use the 32 kHz external crystal + // Set the system clock to use the external 32 MHz crystal + // Set the system clock to 32 MHz SysCtrlClockSet(true, false, SYS_CTRL_SYSDIV_32MHZ); - /* Set the IO clock to operate at 16 MHz */ - /* This way peripherals can run while the system clock is gated */ - SysCtrlIOClockSet(SYS_CTRL_SYSDIV_16MHZ); + // Set the IO clock to operate at 32 MHz + // This way peripherals can run while the system clock is gated + SysCtrlIOClockSet(SYS_CTRL_SYSDIV_32MHZ); - /* Wait until the selected clock configuration is stable */ + // Wait until the selected clock configuration is stable while (!((HWREG(SYS_CTRL_CLOCK_STA)) & (SYS_CTRL_CLOCK_STA_XOSC_STB))); - /* Define what peripherals run in each mode */ + // Define what peripherals run in each mode SysCtrlRunSetting(); SysCtrlSleepSetting(); SysCtrlDeepSleepSetting(); SysCtrlWakeupSetting(); - /* Re-enable interrupt if initially enabled */ - if (!bIntDisabled) { + // Re-enable interrupt if initially enabled + if (!bIntDisabled){ IntMasterEnable(); } } -/** - * Configures the user button as input source - */ -static void button_init(void) { - volatile uint32_t i; - - /* Delay to avoid pin floating problems */ - for (i = 0xFFFF; i != 0; i--); - GPIOPinIntDisable(BSP_BUTTON_BASE, BSP_BUTTON_USER); - GPIOPinIntClear(BSP_BUTTON_BASE, BSP_BUTTON_USER); + // Configures the user button as input source - /* The button is an input GPIO on falling edge */ +static void button_init(void){ + // The button is an input GPIO on falling edge GPIOPinTypeGPIOInput(BSP_BUTTON_BASE, BSP_BUTTON_USER); GPIOIntTypeSet(BSP_BUTTON_BASE, BSP_BUTTON_USER, GPIO_FALLING_EDGE); - /* Register the interrupt */ - GPIOPortIntRegister(BSP_BUTTON_BASE, GPIO_C_Handler); + // Enable wake-up capability + GPIOIntWakeupEnable(GPIO_IWE_PORT_D); - /* Clear and enable the interrupt */ + // Clear and enable the interrupt GPIOPinIntClear(BSP_BUTTON_BASE, BSP_BUTTON_USER); GPIOPinIntEnable(BSP_BUTTON_BASE, BSP_BUTTON_USER); - user_button_initialized = TRUE; } -static void SysCtrlRunSetting(void) { - /* Disable General Purpose Timers 0, 1, 2, 3 when running */ - SysCtrlPeripheralDisable(SYS_CTRL_PERIPH_GPT0); - SysCtrlPeripheralDisable(SYS_CTRL_PERIPH_GPT1); - SysCtrlPeripheralDisable(SYS_CTRL_PERIPH_GPT3); +static void SysCtrlRunSetting(void){ + // Disable General Purpose Timers 0, 1, 2, 3 when running + SysCtrlPeripheralDisable(SYS_CTRL_PERIPH_GPT0); + SysCtrlPeripheralDisable(SYS_CTRL_PERIPH_GPT1); + SysCtrlPeripheralDisable(SYS_CTRL_PERIPH_GPT3); - /* Disable SSI 0, 1 when running */ - SysCtrlPeripheralDisable(SYS_CTRL_PERIPH_SSI0); - SysCtrlPeripheralDisable(SYS_CTRL_PERIPH_SSI1); + // Disable SSI 0, 1 when running + SysCtrlPeripheralDisable(SYS_CTRL_PERIPH_SSI0); + SysCtrlPeripheralDisable(SYS_CTRL_PERIPH_SSI1); - /* Disable UART1 when running */ - SysCtrlPeripheralDisable(SYS_CTRL_PERIPH_UART1); + // Disable UART1 when running + SysCtrlPeripheralDisable(SYS_CTRL_PERIPH_UART1); - /* Disable I2C, AES and PKA when running */ - SysCtrlPeripheralDisable(SYS_CTRL_PERIPH_I2C); - SysCtrlPeripheralDisable(SYS_CTRL_PERIPH_PKA); - SysCtrlPeripheralDisable(SYS_CTRL_PERIPH_AES); + // Disable I2C, AES and PKA when running + SysCtrlPeripheralDisable(SYS_CTRL_PERIPH_I2C); + SysCtrlPeripheralDisable(SYS_CTRL_PERIPH_PKA); + SysCtrlPeripheralDisable(SYS_CTRL_PERIPH_AES); - /* Enable UART0 and RFC when running */ - SysCtrlPeripheralEnable(SYS_CTRL_PERIPH_GPT2); - SysCtrlPeripheralEnable(SYS_CTRL_PERIPH_UART0); - SysCtrlPeripheralEnable(SYS_CTRL_PERIPH_RFC); + // Enable UART0 and RFC when running + SysCtrlPeripheralEnable(SYS_CTRL_PERIPH_GPT2); + SysCtrlPeripheralEnable(SYS_CTRL_PERIPH_UART0); + SysCtrlPeripheralEnable(SYS_CTRL_PERIPH_RFC); } -static void SysCtrlSleepSetting(void) { - /* Disable General Purpose Timers 0, 1, 2, 3 during sleep */ - SysCtrlPeripheralSleepDisable(SYS_CTRL_PERIPH_GPT0); - SysCtrlPeripheralSleepDisable(SYS_CTRL_PERIPH_GPT1); - SysCtrlPeripheralSleepDisable(SYS_CTRL_PERIPH_GPT3); +static void SysCtrlSleepSetting(void){ + // Disable General Purpose Timers 0, 1, 2, 3 during sleep + SysCtrlPeripheralSleepDisable(SYS_CTRL_PERIPH_GPT0); + SysCtrlPeripheralSleepDisable(SYS_CTRL_PERIPH_GPT1); + SysCtrlPeripheralSleepDisable(SYS_CTRL_PERIPH_GPT3); - /* Disable SSI 0, 1 during sleep */ - SysCtrlPeripheralSleepDisable(SYS_CTRL_PERIPH_SSI0); - SysCtrlPeripheralSleepDisable(SYS_CTRL_PERIPH_SSI1); + // Disable SSI 0, 1 during sleep + SysCtrlPeripheralSleepDisable(SYS_CTRL_PERIPH_SSI0); + SysCtrlPeripheralSleepDisable(SYS_CTRL_PERIPH_SSI1); - /* Disable UART 0, 1 during sleep */ - SysCtrlPeripheralSleepDisable(SYS_CTRL_PERIPH_UART1); + // Disable UART 0, 1 during sleep + SysCtrlPeripheralSleepDisable(SYS_CTRL_PERIPH_UART1); - /* Disable I2C, PKA, AES during sleep */ - SysCtrlPeripheralSleepDisable(SYS_CTRL_PERIPH_I2C); - SysCtrlPeripheralSleepDisable(SYS_CTRL_PERIPH_PKA); - SysCtrlPeripheralSleepDisable(SYS_CTRL_PERIPH_AES); + // Disable I2C, PKA, AES during sleep + SysCtrlPeripheralSleepDisable(SYS_CTRL_PERIPH_I2C); + SysCtrlPeripheralSleepDisable(SYS_CTRL_PERIPH_PKA); + SysCtrlPeripheralSleepDisable(SYS_CTRL_PERIPH_AES); - /* Enable UART and RFC during sleep */ - SysCtrlPeripheralSleepEnable(SYS_CTRL_PERIPH_GPT2); - SysCtrlPeripheralSleepEnable(SYS_CTRL_PERIPH_UART0); - SysCtrlPeripheralSleepEnable(SYS_CTRL_PERIPH_RFC); + // Enable UART and RFC during sleep + SysCtrlPeripheralSleepEnable(SYS_CTRL_PERIPH_GPT2); + SysCtrlPeripheralSleepEnable(SYS_CTRL_PERIPH_UART0); + SysCtrlPeripheralSleepEnable(SYS_CTRL_PERIPH_RFC); } -static void SysCtrlDeepSleepSetting(void) { - /* Disable General Purpose Timers 0, 1, 2, 3 during deep sleep */ - SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_GPT0); - SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_GPT1); - SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_GPT2); - SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_GPT3); - - /* Disable SSI 0, 1 during deep sleep */ - SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_SSI0); - SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_SSI1); - - /* Disable UART 0, 1 during deep sleep */ - SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_UART0); - SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_UART1); - - /* Disable I2C, PKA, AES during deep sleep */ - SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_I2C); - SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_PKA); - SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_AES); - SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_RFC); +static void SysCtrlDeepSleepSetting(void){ + // Disable General Purpose Timers 0, 1, 2, 3 during deep sleep + SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_GPT0); + SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_GPT1); + SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_GPT2); + SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_GPT3); + + // Disable SSI 0, 1 during deep sleep + SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_SSI0); + SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_SSI1); + + // Disable UART 0, 1 during deep sleep + SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_UART0); + SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_UART1); + + // Disable I2C, PKA, AES during deep sleep + SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_I2C); + SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_PKA); + SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_AES); + SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_RFC); } -static void SysCtrlWakeupSetting(void) { - /* Allow the SMTimer to wake up the processor */ - GPIOIntWakeupEnable(GPIO_IWE_SM_TIMER); +static void SysCtrlWakeupSetting(void){ + // Allow the SMTimer to wake up the processor + GPIOIntWakeupEnable(GPIO_IWE_SM_TIMER); } //=========================== interrupt handlers ============================== - -/** - * GPIO_C interrupt handler. User button is GPIO_C_3 - * Erases a Flash sector to trigger the bootloader backdoor - */ -static void GPIO_C_Handler(void) { - if (!user_button_initialized) return; - /* Disable the interrupts */ - IntMasterDisable(); - leds_all_off(); - - /* Eras the CCA flash page */ - FlashMainPageErase(CC2538_FLASH_ADDRESS); - - leds_circular_shift(); - - /* Reset the board */ - SysCtrlReset(); -} diff --git a/bsp/boards/openmote-b/board_info.h b/bsp/boards/openmote-b/board_info.h index e6c31644b6..d468cda700 100644 --- a/bsp/boards/openmote-b/board_info.h +++ b/bsp/boards/openmote-b/board_info.h @@ -42,11 +42,11 @@ // is not connected to a pin on the MSP which allows time capture. #define CAPTURE_TIME() -/* sleep timer interrupt */ +// sleep timer interrupt #define HAL_INT_PRIOR_ST (4 << 5) -/* MAC interrupts */ +// MAC interrupts #define HAL_INT_PRIOR_MAC (4 << 5) -/* UART interrupt */ +// UART interrupt #define HAL_INT_PRIOR_UART (5 << 5) //===== pinout @@ -59,41 +59,9 @@ #define PORT_PIN_RADIO_RESET_HIGH() // nothing #define PORT_PIN_RADIO_RESET_LOW() // nothing -#define SLOTDURATION 10 // in miliseconds - -//===== IEEE802154E timing - -#if SLOTDURATION==10 - // time-slot related - #define PORT_TsSlotDuration 328 // counter counts one extra count, see datasheet - // execution speed related - #define PORT_maxTxDataPrepare 10 // 305us (measured 82us) - #define PORT_maxRxAckPrepare 10 // 305us (measured 83us) - #define PORT_maxRxDataPrepare 4 // 122us (measured 22us) - #define PORT_maxTxAckPrepare 10 // 122us (measured 94us) - // radio speed related -#ifdef OPENWSN_IEEE802154E_SECURITY_C - #define PORT_delayTx 14 // 366us (measured xxxus) -#else - #define PORT_delayTx 12 // 366us (measured xxxus) -#endif - #define PORT_delayRx 0 // 0us (can not measure) - // radio watchdog -#endif -#if SLOTDURATION==15 - // time-slot related - #define PORT_TsSlotDuration 492 // counter counts one extra count, see datasheet - // execution speed related - #define PORT_maxTxDataPrepare 66 // 2014us (measured 746us) - #define PORT_maxRxAckPrepare 10 // 305us (measured 83us) - #define PORT_maxRxDataPrepare 33 // 1007us (measured 84us) - #define PORT_maxTxAckPrepare 22 // 305us (measured 219us) - // radio speed related - #define PORT_delayTx 12 // 214us (measured 219us) - #define PORT_delayRx 0 // 0us (can not measure) - // radio watchdog -#endif +// Number of available radio settings +#define MAX_RADIOS 7 //===== adaptive_sync accuracy @@ -103,25 +71,25 @@ #define NUMSENSORS 7 -//====== Antenna options ==== +//=========================== Antenna options ================================= + #define BSP_ANTENNA_BASE GPIO_D_BASE #define BSP_ANTENNA_CC2538_24GHZ GPIO_PIN_4 //!< PD4 -- 2.4ghz #define BSP_ANTENNA_AT215_24GHZ GPIO_PIN_3 //!< PD3 -- subghz - //=========================== typedef ======================================== //=========================== variables ======================================= static const uint8_t rreg_uriquery[] = "h=ucb"; -static const uint8_t infoBoardname[] = "CC2538"; +static const uint8_t infoBoardname[] = "Openmote B"; static const uint8_t infouCName[] = "CC2538"; static const uint8_t infoRadioName[] = "CC2538 SoC"; //=========================== prototypes ====================================== //=========================== public ========================================== - +void eraseFlash(void); //=========================== private ========================================= #endif diff --git a/bsp/boards/openmote-b/cc2538rf.h b/bsp/boards/openmote-b/cc2538rf.h deleted file mode 100644 index 82b05c2bb1..0000000000 --- a/bsp/boards/openmote-b/cc2538rf.h +++ /dev/null @@ -1,93 +0,0 @@ -/** - * Author: Xavier Vilajosana (xvilajosana@eecs.berkeley.edu) - * Pere Tuset (peretuset@openmote.com) - * Date: July 2013 - * Description: CC2538-specific definition of the "radio" bsp module. - */ - -#ifndef CC2538RF_H_ -#define CC2538RF_H_ - -#include -#include - -/*--------------------------------------------------------------------------- - * RF Config - *---------------------------------------------------------------------------*/ -/* Constants */ -#define CC2538_RF_CCA_THRES_USER_GUIDE 0xF8 -#define CC2538_RF_TX_POWER_RECOMMENDED 0xD5 /* TODO: Check value */ -#define CC2538_RF_CHANNEL_MIN 11 //poipoi -- in fact is sending on 0x17 check that. -#define CC2538_RF_CHANNEL_MAX 26 -#define CC2538_RF_CHANNEL_SPACING 5 -#define CC2538_RF_MAX_PACKET_LEN 127 -#define CC2538_RF_MIN_PACKET_LEN 4 -#define CC2538_RF_CCA_CLEAR 1 -#define CC2538_RF_CCA_BUSY 0 -/*---------------------------------------------------------------------------*/ -#ifdef CC2538_RF_CONF_TX_POWER -#define CC2538_RF_TX_POWER CC2538_RF_CONF_TX_POWER -#else -#define CC2538_RF_TX_POWER CC2538_RF_TX_POWER_RECOMMENDED -#endif /* CC2538_RF_CONF_TX_POWER */ - - -#ifdef CC2538_RF_CONF_CHANNEL -#define CC2538_RF_CHANNEL CC2538_RF_CONF_CHANNEL -#else -#define CC2538_RF_CHANNEL CC2538_RF_CHANNEL_MIN -#endif /* CC2538_RF_CONF_CHANNEL */ - -#ifdef CC2538_RF_CONF_AUTOACK -#define CC2538_RF_AUTOACK CC2538_RF_CONF_AUTOACK -#else -#define CC2538_RF_AUTOACK 1 -#endif /* CC2538_RF_CONF_AUTOACK */ -/*--------------------------------------------------------------------------- - * Command Strobe Processor - *---------------------------------------------------------------------------*/ -/* OPCODES */ -#define CC2538_RF_CSP_OP_ISRXON 0xE3 -#define CC2538_RF_CSP_OP_ISTXON 0xE9 -#define CC2538_RF_CSP_OP_ISTXONCCA 0xEA -#define CC2538_RF_CSP_OP_ISRFOFF 0xEF -#define CC2538_RF_CSP_OP_ISFLUSHRX 0xED -#define CC2538_RF_CSP_OP_ISFLUSHTX 0xEE - -/** - * \brief Send an RX ON command strobe to the CSP - */ -#define CC2538_RF_CSP_ISRXON() \ - do { HWREG(RFCORE_SFR_RFST) = CC2538_RF_CSP_OP_ISRXON; } while(0) - -/** - * \brief Send a TX ON command strobe to the CSP - */ -#define CC2538_RF_CSP_ISTXON() \ - do { HWREG(RFCORE_SFR_RFST) = CC2538_RF_CSP_OP_ISTXON; } while(0) - -/** - * \brief Send a RF OFF command strobe to the CSP - */ -#define CC2538_RF_CSP_ISRFOFF() \ - do { HWREG(RFCORE_SFR_RFST) = CC2538_RF_CSP_OP_ISRFOFF; } while(0) - -/** - * \brief Flush the RX FIFO - */ -#define CC2538_RF_CSP_ISFLUSHRX() do { \ - HWREG(RFCORE_SFR_RFST) = CC2538_RF_CSP_OP_ISFLUSHRX; \ - HWREG(RFCORE_SFR_RFST) = CC2538_RF_CSP_OP_ISFLUSHRX; \ -} while(0) - -/** - * \brief Flush the TX FIFO - */ -#define CC2538_RF_CSP_ISFLUSHTX() do { \ - HWREG(RFCORE_SFR_RFST) = CC2538_RF_CSP_OP_ISFLUSHTX; \ - HWREG(RFCORE_SFR_RFST) = CC2538_RF_CSP_OP_ISFLUSHTX; \ -} while(0) -/*---------------------------------------------------------------------------*/ - - -#endif /* CC2538RF_H_ */ diff --git a/bsp/boards/openmote-b/cx2538xf53.icf b/bsp/boards/openmote-b/cx2538xf53.icf new file mode 100644 index 0000000000..4585a623ad --- /dev/null +++ b/bsp/boards/openmote-b/cx2538xf53.icf @@ -0,0 +1,109 @@ +/*###ICF### Section handled by ICF editor, don't touch! ****/ +/*-Editor annotation file-*/ +/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ +/*-Specials-*/ +define symbol __ICFEDIT_intvec_start__ = 0x00200000; +/*-Memory Regions-*/ +define symbol __ICFEDIT_region_ROM_start__ = 0x00200000; +define symbol __ICFEDIT_region_ROM_end__ = 0x0027ffd3; +define symbol __ICFEDIT_region_RAM_start__ = 0x20000000; +define symbol __ICFEDIT_region_RAM_end__ = 0x20007FFF; +/*-Sizes-*/ +define symbol __ICFEDIT_size_cstack__ = 0x800; +define symbol __ICFEDIT_size_heap__ = 0x1000; +/**** End of ICF editor section. ###ICF###*/ + +// +// Define a memory region that covers the entire 4 GB addressible space of the +// processor. +// +define memory mem with size = 4G; + +// +// Define a region for the on-chip flash. +// This device has 512KB Flash size +// +define region FLASH = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; + +// +// Define a region for Customer Configuration Area in flash. +// +define region FLASH_CCA = mem:[from 0x0027ffd4 to 0x0027ffdf]; + +// +// Define a region for the on-chip SRAM. +// This device has 32KB RAM size +// +define region SRAM = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; + +// +// Define regions of retention and non-retention RAM. The stack and other +// variables that require retention through PM2/3 should be placed in the +// retention RAM region +// +define region SRAM_NON_RETENTION = mem:[from __ICFEDIT_region_RAM_start__ to 0x20003fff]; +define region SRAM_RETENTION = mem:[from 0x20004000 to __ICFEDIT_region_RAM_end__]; +define region SRAM_TOTAL = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; + +// +// Define a block for the heap. The size should be set to something other +// than zero if things in the C library that require the heap are used. +// +define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; + +// +// Indicate that the read/write values should be initialized by copying from +// flash. +// +initialize by copy { readwrite }; + +// +// Indicate that the noinit values should be left alone. +// +do not initialize { section .noinit }; + +// +// Place the interrupt vectors at the start of flash. +// +place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; + +// +// Place the cca area at the end of flash (start of FLASH_CCA). +// +place at start of FLASH_CCA { readonly section .flashcca }; + +// +// Place the remainder of the read-only items into flash. +// +place in FLASH { readonly }; + +// +// Place the RAM vector table at the start of retention ram. +// +place at start of SRAM_TOTAL { section VTABLE }; + +// +// Place all read/write items into retention SRAM. +// +place in SRAM_TOTAL { readwrite, block HEAP }; + +// +// Define CSTACK block to contain .stack section. This enables the IAR IDE +// to properly show the stack content during debug. Place stack at end of +// retention RAM, do not initialize (initializing the stack will destroy the +// return address from the initialization code, causing the processor to branch +// to zero and fault) +// +define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { section .stack }; +do not initialize { section .stack }; +place at end of SRAM_TOTAL { block CSTACK }; + +// +// Export stack top symbol. Used by startup file. +// +define exported symbol STACK_TOP = __ICFEDIT_region_RAM_end__ + 1; + +// +// Variables that do not need retention should be defined here +// +place in SRAM_TOTAL { section .nonretenvar }; diff --git a/bsp/boards/openmote-b/i2c.c b/bsp/boards/openmote-b/i2c.c index d9028f5dd5..e5c1764a09 100644 --- a/bsp/boards/openmote-b/i2c.c +++ b/bsp/boards/openmote-b/i2c.c @@ -21,10 +21,10 @@ #define I2C_PERIPHERAL ( SYS_CTRL_PERIPH_I2C ) #define I2C_BASE ( GPIO_B_BASE ) -#define I2C_SCL ( GPIO_PIN_3 ) +#define I2C_SCL ( GPIO_PIN_5 ) #define I2C_SDA ( GPIO_PIN_4 ) -#define I2C_BAUDRATE ( 100000 ) -#define I2C_MAX_DELAY_US ( 100000 ) +#define I2C_BAUDRATE ( 400000 ) +#define I2C_MAX_DELAY_US ( 400000 ) //=========================== variables ======================================= diff --git a/bsp/boards/openmote-b/leds.c b/bsp/boards/openmote-b/leds.c index 248b6ed64a..61eff57200 100644 --- a/bsp/boards/openmote-b/leds.c +++ b/bsp/boards/openmote-b/leds.c @@ -59,34 +59,34 @@ uint8_t leds_error_isOn(void) { return (uint8_t)(ui32Toggle & BSP_LED_1)>>4; } -// orange +// green void leds_sync_on(void) { - bspLedSet(BSP_LED_2); + bspLedSet(BSP_LED_4); } void leds_sync_off(void) { - bspLedClear(BSP_LED_2); + bspLedClear(BSP_LED_4); } void leds_sync_toggle(void) { - bspLedToggle(BSP_LED_2); + bspLedToggle(BSP_LED_4); } uint8_t leds_sync_isOn(void) { - uint32_t ui32Toggle = GPIOPinRead(BSP_LED_BASE, BSP_LED_2); - return (uint8_t)(ui32Toggle & BSP_LED_2)>>5; + uint32_t ui32Toggle = GPIOPinRead(BSP_LED_BASE, BSP_LED_4); + return (uint8_t)(ui32Toggle & BSP_LED_4)>>5; } -// green +// orange void leds_radio_on(void) { - bspLedSet(BSP_LED_4); + bspLedSet(BSP_LED_2); } void leds_radio_off(void) { - bspLedClear(BSP_LED_4); + bspLedClear(BSP_LED_2); } void leds_radio_toggle(void) { - bspLedToggle(BSP_LED_4); + bspLedToggle(BSP_LED_2); } uint8_t leds_radio_isOn(void) { - uint32_t ui32Toggle = GPIOPinRead(BSP_LED_BASE, BSP_LED_4); - return (uint8_t)(ui32Toggle & BSP_LED_4)>>7; + uint32_t ui32Toggle = GPIOPinRead(BSP_LED_BASE, BSP_LED_2); + return (uint8_t)(ui32Toggle & BSP_LED_2)>>7; } // yellow diff --git a/bsp/boards/openmote-b/radio.c b/bsp/boards/openmote-b/radio.c index 2d4281a5cf..3b162886bd 100644 --- a/bsp/boards/openmote-b/radio.c +++ b/bsp/boards/openmote-b/radio.c @@ -1,531 +1,324 @@ /** - * Author: Xavier Vilajosana (xvilajosana@eecs.berkeley.edu) - * Pere Tuset (peretuset@openmote.com) - * Date: July 2013 - * Description: CC2538-specific definition of the "radio" bsp module. - */ - -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include - + \brief Definition of the Open Radio interface for openmote-b + \author Mina Rady , March 2020. +*/ #include "board.h" -#include "cc2538rf.h" + #include "debugpins.h" #include "leds.h" -#include "radio.h" #include "sctimer.h" -//=========================== defines ========================================= -/* Bit Masks for the last byte in the RX FIFO */ -#define CRC_BIT_MASK 0x80 -#define LQI_BIT_MASK 0x7F +#include +#include +#include +#include +#include -/* RSSI Offset */ -#define RSSI_OFFSET 73 -#define CHECKSUM_LEN 2 +#include +#include +#include +#include -//=========================== variables ======================================= +// Drivers of radios attached to openmote-b +#include "radio_at86rf215.h" +#include "radio_cc2538rf.h" -typedef struct { - radio_capture_cbt startFrame_cb; - radio_capture_cbt endFrame_cb; - radio_state_t state; -} radio_vars_t; +// The generic radio driver header file +#include "radio.h" -radio_vars_t radio_vars; +//=========================== defines ========================================= -//=========================== prototypes ====================================== -void enable_radio_interrupts(void); -void disable_radio_interrupts(void); +// open radio functions callback types declaration + +typedef void (*radio_reset_cb_t)(void); +typedef void (*radio_init_cb_t)(void); +typedef void (*radio_setConfig_cb_t)(radioSetting_t radioSetting); +typedef void (*radio_setStartFrameCb_cb_t)(radio_capture_cbt cb); +typedef void (*radio_setEndFrameCb_cb_t)(radio_capture_cbt cb); +typedef void (*radio_setFrequency_cb_t)(uint8_t channel, radio_freq_t tx_or_rx); +typedef void (*radio_rfOn_cb_t)(void); +typedef void (*radio_rfOff_cb_t)(void); +typedef int8_t (*radio_getFrequencyOffset_cb_t)(void); +typedef void (*radio_loadPacket_cb_t)(uint8_t* packet, uint16_t len); +typedef radio_state_t (*radio_getState_cb_t)(void); +typedef void (*radio_txEnable_cb_t)(void); +typedef void (*radio_txNow_cb_t)(void); +typedef void (*radio_rxEnable_cb_t)(void); +typedef void (*radio_rxNow_cb_t)(void); +typedef void (*radio_getReceivedFrame_cb_t)( + uint8_t* bufRead, + uint8_t* lenRead, + uint8_t maxBufLen, + int8_t* rssi, + uint8_t* lqi, + bool* crc + ); +typedef kick_scheduler_t (*radio_isr_cb_t)(void); + + +// the template for radio function callbacks +typedef struct { + radio_reset_cb_t radio_reset; + radio_init_cb_t radio_init; + radio_setConfig_cb_t radio_setConfig; + radio_setStartFrameCb_cb_t radio_setStartFrameCb; + radio_setEndFrameCb_cb_t radio_setEndFrameCb; + radio_setFrequency_cb_t radio_setFrequency; + radio_rfOn_cb_t radio_rfOn; + radio_rfOff_cb_t radio_rfOff; + radio_getFrequencyOffset_cb_t radio_getFrequencyOffset; + radio_loadPacket_cb_t radio_loadPacket; + radio_txEnable_cb_t radio_txEnable; + radio_txNow_cb_t radio_txNow; + radio_rxEnable_cb_t radio_rxEnable; + radio_rxNow_cb_t radio_rxNow; + radio_getReceivedFrame_cb_t radio_getReceivedFrame; + radio_isr_cb_t radio_isr; +} radio_functions_t; + + +// global radio selection, will use the slowest by default at initialization. +uint8_t selected_radioSetting = RADIOSETTING_FSK_OPTION1_FEC; -void radio_on(void); -void radio_off(void); +//=========================== variables ======================================= + +//function call back matrix +radio_functions_t dyn_funcs [MAX_RADIOS]; + +//=========================== Bootstrapping =================================== + +// initializing the lookup table for radio function callbacks +void radio_bootstrap (void) +{ + // RADIOSETTING_FSK_OPTION1_FEC + dyn_funcs [RADIOSETTING_FSK_OPTION1_FEC].radio_reset = radio_reset_at86rf215; + dyn_funcs [RADIOSETTING_FSK_OPTION1_FEC].radio_init = radio_init_at86rf215; + dyn_funcs [RADIOSETTING_FSK_OPTION1_FEC].radio_setConfig = radio_setConfig_at86rf215; + dyn_funcs [RADIOSETTING_FSK_OPTION1_FEC].radio_setStartFrameCb = radio_setStartFrameCb_at86rf215; + dyn_funcs [RADIOSETTING_FSK_OPTION1_FEC].radio_setEndFrameCb = radio_setEndFrameCb_at86rf215; + dyn_funcs [RADIOSETTING_FSK_OPTION1_FEC].radio_setFrequency = radio_setFrequency_at86rf215; + dyn_funcs [RADIOSETTING_FSK_OPTION1_FEC].radio_rfOn = radio_rfOn_at86rf215; + dyn_funcs [RADIOSETTING_FSK_OPTION1_FEC].radio_rfOff = radio_rfOff_at86rf215; + dyn_funcs [RADIOSETTING_FSK_OPTION1_FEC].radio_getFrequencyOffset = radio_getFrequencyOffset_at86rf215; + dyn_funcs [RADIOSETTING_FSK_OPTION1_FEC].radio_loadPacket = radio_loadPacket_at86rf215; + dyn_funcs [RADIOSETTING_FSK_OPTION1_FEC].radio_txEnable = radio_txEnable_at86rf215; + dyn_funcs [RADIOSETTING_FSK_OPTION1_FEC].radio_txNow = radio_txNow_at86rf215; + dyn_funcs [RADIOSETTING_FSK_OPTION1_FEC].radio_rxEnable = radio_rxEnable_at86rf215; + dyn_funcs [RADIOSETTING_FSK_OPTION1_FEC].radio_rxNow = radio_rxNow_at86rf215; + dyn_funcs [RADIOSETTING_FSK_OPTION1_FEC].radio_getReceivedFrame = radio_getReceivedFrame_at86rf215; + dyn_funcs [RADIOSETTING_FSK_OPTION1_FEC].radio_isr = radio_isr_at86rf215; + + + //RADIOSETTING_OQPSK_RATE3 + dyn_funcs [RADIOSETTING_OQPSK_RATE3].radio_reset = radio_reset_at86rf215; + dyn_funcs [RADIOSETTING_OQPSK_RATE3].radio_init = radio_init_at86rf215; + dyn_funcs [RADIOSETTING_OQPSK_RATE3].radio_setConfig = radio_setConfig_at86rf215; + dyn_funcs [RADIOSETTING_OQPSK_RATE3].radio_setStartFrameCb = radio_setStartFrameCb_at86rf215; + dyn_funcs [RADIOSETTING_OQPSK_RATE3].radio_setEndFrameCb = radio_setEndFrameCb_at86rf215; + dyn_funcs [RADIOSETTING_OQPSK_RATE3].radio_setFrequency = radio_setFrequency_at86rf215; + dyn_funcs [RADIOSETTING_OQPSK_RATE3].radio_rfOn = radio_rfOn_at86rf215; + dyn_funcs [RADIOSETTING_OQPSK_RATE3].radio_rfOff = radio_rfOff_at86rf215; + dyn_funcs [RADIOSETTING_OQPSK_RATE3].radio_getFrequencyOffset = radio_getFrequencyOffset_at86rf215; + dyn_funcs [RADIOSETTING_OQPSK_RATE3].radio_loadPacket = radio_loadPacket_at86rf215; + dyn_funcs [RADIOSETTING_OQPSK_RATE3].radio_txEnable = radio_txEnable_at86rf215; + dyn_funcs [RADIOSETTING_OQPSK_RATE3].radio_txNow = radio_txNow_at86rf215; + dyn_funcs [RADIOSETTING_OQPSK_RATE3].radio_rxEnable = radio_rxEnable_at86rf215; + dyn_funcs [RADIOSETTING_OQPSK_RATE3].radio_rxNow = radio_rxNow_at86rf215; + dyn_funcs [RADIOSETTING_OQPSK_RATE3].radio_getReceivedFrame = radio_getReceivedFrame_at86rf215; + dyn_funcs [RADIOSETTING_OQPSK_RATE3].radio_isr = radio_isr_at86rf215; + + //RADIOSETTING_OFDM_OPTION_1_MCS0 + dyn_funcs [RADIOSETTING_OFDM_OPTION_1_MCS0].radio_reset = radio_reset_at86rf215; + dyn_funcs [RADIOSETTING_OFDM_OPTION_1_MCS0].radio_init = radio_init_at86rf215; + dyn_funcs [RADIOSETTING_OFDM_OPTION_1_MCS0].radio_setConfig = radio_setConfig_at86rf215; + dyn_funcs [RADIOSETTING_OFDM_OPTION_1_MCS0].radio_setStartFrameCb = radio_setStartFrameCb_at86rf215; + dyn_funcs [RADIOSETTING_OFDM_OPTION_1_MCS0].radio_setEndFrameCb = radio_setEndFrameCb_at86rf215; + dyn_funcs [RADIOSETTING_OFDM_OPTION_1_MCS0].radio_setFrequency = radio_setFrequency_at86rf215; + dyn_funcs [RADIOSETTING_OFDM_OPTION_1_MCS0].radio_rfOn = radio_rfOn_at86rf215; + dyn_funcs [RADIOSETTING_OFDM_OPTION_1_MCS0].radio_rfOff = radio_rfOff_at86rf215; + dyn_funcs [RADIOSETTING_OFDM_OPTION_1_MCS0].radio_getFrequencyOffset = radio_getFrequencyOffset_at86rf215; + dyn_funcs [RADIOSETTING_OFDM_OPTION_1_MCS0].radio_loadPacket = radio_loadPacket_at86rf215; + dyn_funcs [RADIOSETTING_OFDM_OPTION_1_MCS0].radio_txEnable = radio_txEnable_at86rf215; + dyn_funcs [RADIOSETTING_OFDM_OPTION_1_MCS0].radio_txNow = radio_txNow_at86rf215; + dyn_funcs [RADIOSETTING_OFDM_OPTION_1_MCS0].radio_rxEnable = radio_rxEnable_at86rf215; + dyn_funcs [RADIOSETTING_OFDM_OPTION_1_MCS0].radio_rxNow = radio_rxNow_at86rf215; + dyn_funcs [RADIOSETTING_OFDM_OPTION_1_MCS0].radio_getReceivedFrame = radio_getReceivedFrame_at86rf215; + dyn_funcs [RADIOSETTING_OFDM_OPTION_1_MCS0].radio_isr = radio_isr_at86rf215; + + //RADIOSETTING_OFDM_OPTION_1_MCS1 + dyn_funcs [RADIOSETTING_OFDM_OPTION_1_MCS1].radio_reset = radio_reset_at86rf215; + dyn_funcs [RADIOSETTING_OFDM_OPTION_1_MCS1].radio_init = radio_init_at86rf215; + dyn_funcs [RADIOSETTING_OFDM_OPTION_1_MCS1].radio_setConfig = radio_setConfig_at86rf215; + dyn_funcs [RADIOSETTING_OFDM_OPTION_1_MCS1].radio_setStartFrameCb = radio_setStartFrameCb_at86rf215; + dyn_funcs [RADIOSETTING_OFDM_OPTION_1_MCS1].radio_setEndFrameCb = radio_setEndFrameCb_at86rf215; + dyn_funcs [RADIOSETTING_OFDM_OPTION_1_MCS1].radio_setFrequency = radio_setFrequency_at86rf215; + dyn_funcs [RADIOSETTING_OFDM_OPTION_1_MCS1].radio_rfOn = radio_rfOn_at86rf215; + dyn_funcs [RADIOSETTING_OFDM_OPTION_1_MCS1].radio_rfOff = radio_rfOff_at86rf215; + dyn_funcs [RADIOSETTING_OFDM_OPTION_1_MCS1].radio_getFrequencyOffset = radio_getFrequencyOffset_at86rf215; + dyn_funcs [RADIOSETTING_OFDM_OPTION_1_MCS1].radio_loadPacket = radio_loadPacket_at86rf215; + dyn_funcs [RADIOSETTING_OFDM_OPTION_1_MCS1].radio_txEnable = radio_txEnable_at86rf215; + dyn_funcs [RADIOSETTING_OFDM_OPTION_1_MCS1].radio_txNow = radio_txNow_at86rf215; + dyn_funcs [RADIOSETTING_OFDM_OPTION_1_MCS1].radio_rxEnable = radio_rxEnable_at86rf215; + dyn_funcs [RADIOSETTING_OFDM_OPTION_1_MCS1].radio_rxNow = radio_rxNow_at86rf215; + dyn_funcs [RADIOSETTING_OFDM_OPTION_1_MCS1].radio_getReceivedFrame = radio_getReceivedFrame_at86rf215; + dyn_funcs [RADIOSETTING_OFDM_OPTION_1_MCS1].radio_isr = radio_isr_at86rf215; + + //RADIOSETTING_OFDM_OPTION_1_MCS2 + dyn_funcs [RADIOSETTING_OFDM_OPTION_1_MCS2].radio_reset = radio_reset_at86rf215; + dyn_funcs [RADIOSETTING_OFDM_OPTION_1_MCS2].radio_init = radio_init_at86rf215; + dyn_funcs [RADIOSETTING_OFDM_OPTION_1_MCS2].radio_setConfig = radio_setConfig_at86rf215; + dyn_funcs [RADIOSETTING_OFDM_OPTION_1_MCS2].radio_setStartFrameCb = radio_setStartFrameCb_at86rf215; + dyn_funcs [RADIOSETTING_OFDM_OPTION_1_MCS2].radio_setEndFrameCb = radio_setEndFrameCb_at86rf215; + dyn_funcs [RADIOSETTING_OFDM_OPTION_1_MCS2].radio_setFrequency = radio_setFrequency_at86rf215; + dyn_funcs [RADIOSETTING_OFDM_OPTION_1_MCS2].radio_rfOn = radio_rfOn_at86rf215; + dyn_funcs [RADIOSETTING_OFDM_OPTION_1_MCS2].radio_rfOff = radio_rfOff_at86rf215; + dyn_funcs [RADIOSETTING_OFDM_OPTION_1_MCS2].radio_getFrequencyOffset = radio_getFrequencyOffset_at86rf215; + dyn_funcs [RADIOSETTING_OFDM_OPTION_1_MCS2].radio_loadPacket = radio_loadPacket_at86rf215; + dyn_funcs [RADIOSETTING_OFDM_OPTION_1_MCS2].radio_txEnable = radio_txEnable_at86rf215; + dyn_funcs [RADIOSETTING_OFDM_OPTION_1_MCS2].radio_txNow = radio_txNow_at86rf215; + dyn_funcs [RADIOSETTING_OFDM_OPTION_1_MCS2].radio_rxEnable = radio_rxEnable_at86rf215; + dyn_funcs [RADIOSETTING_OFDM_OPTION_1_MCS2].radio_rxNow = radio_rxNow_at86rf215; + dyn_funcs [RADIOSETTING_OFDM_OPTION_1_MCS2].radio_getReceivedFrame = radio_getReceivedFrame_at86rf215; + dyn_funcs [RADIOSETTING_OFDM_OPTION_1_MCS2].radio_isr = radio_isr_at86rf215; + + //RADIOSETTING_OFDM_OPTION_1_MCS3 + dyn_funcs [RADIOSETTING_OFDM_OPTION_1_MCS3].radio_reset = radio_reset_at86rf215; + dyn_funcs [RADIOSETTING_OFDM_OPTION_1_MCS3].radio_init = radio_init_at86rf215; + dyn_funcs [RADIOSETTING_OFDM_OPTION_1_MCS3].radio_setConfig = radio_setConfig_at86rf215; + dyn_funcs [RADIOSETTING_OFDM_OPTION_1_MCS3].radio_setStartFrameCb = radio_setStartFrameCb_at86rf215; + dyn_funcs [RADIOSETTING_OFDM_OPTION_1_MCS3].radio_setEndFrameCb = radio_setEndFrameCb_at86rf215; + dyn_funcs [RADIOSETTING_OFDM_OPTION_1_MCS3].radio_setFrequency = radio_setFrequency_at86rf215; + dyn_funcs [RADIOSETTING_OFDM_OPTION_1_MCS3].radio_rfOn = radio_rfOn_at86rf215; + dyn_funcs [RADIOSETTING_OFDM_OPTION_1_MCS3].radio_rfOff = radio_rfOff_at86rf215; + dyn_funcs [RADIOSETTING_OFDM_OPTION_1_MCS3].radio_getFrequencyOffset = radio_getFrequencyOffset_at86rf215; + dyn_funcs [RADIOSETTING_OFDM_OPTION_1_MCS3].radio_loadPacket = radio_loadPacket_at86rf215; + dyn_funcs [RADIOSETTING_OFDM_OPTION_1_MCS3].radio_txEnable = radio_txEnable_at86rf215; + dyn_funcs [RADIOSETTING_OFDM_OPTION_1_MCS3].radio_txNow = radio_txNow_at86rf215; + dyn_funcs [RADIOSETTING_OFDM_OPTION_1_MCS3].radio_rxEnable = radio_rxEnable_at86rf215; + dyn_funcs [RADIOSETTING_OFDM_OPTION_1_MCS3].radio_rxNow = radio_rxNow_at86rf215; + dyn_funcs [RADIOSETTING_OFDM_OPTION_1_MCS3].radio_getReceivedFrame = radio_getReceivedFrame_at86rf215; + dyn_funcs [RADIOSETTING_OFDM_OPTION_1_MCS3].radio_isr = radio_isr_at86rf215; + + + //RADIOSETTING_24GHZ + dyn_funcs [RADIOSETTING_24GHZ].radio_reset = radio_reset_cc2538rf; + dyn_funcs [RADIOSETTING_24GHZ].radio_init = radio_init_cc2538rf; + dyn_funcs [RADIOSETTING_24GHZ].radio_setConfig = radio_setConfig_cc2538rf; + dyn_funcs [RADIOSETTING_24GHZ].radio_setStartFrameCb = radio_setStartFrameCb_cc2538rf; + dyn_funcs [RADIOSETTING_24GHZ].radio_setEndFrameCb = radio_setEndFrameCb_cc2538rf; + dyn_funcs [RADIOSETTING_24GHZ].radio_setFrequency = radio_setFrequency_cc2538rf; + dyn_funcs [RADIOSETTING_24GHZ].radio_rfOn = radio_rfOn_cc2538rf; + dyn_funcs [RADIOSETTING_24GHZ].radio_rfOff = radio_rfOff_cc2538rf; + dyn_funcs [RADIOSETTING_24GHZ].radio_getFrequencyOffset = radio_getFrequencyOffset_cc2538rf; + dyn_funcs [RADIOSETTING_24GHZ].radio_loadPacket = radio_loadPacket_cc2538rf; + dyn_funcs [RADIOSETTING_24GHZ].radio_txEnable = radio_txEnable_cc2538rf; + dyn_funcs [RADIOSETTING_24GHZ].radio_txNow = radio_txNow_cc2538rf; + dyn_funcs [RADIOSETTING_24GHZ].radio_rxEnable = radio_rxEnable_cc2538rf; + dyn_funcs [RADIOSETTING_24GHZ].radio_rxNow = radio_rxNow_cc2538rf; + dyn_funcs [RADIOSETTING_24GHZ].radio_getReceivedFrame = radio_getReceivedFrame_cc2538rf; + dyn_funcs [RADIOSETTING_24GHZ].radio_isr = radio_isr_cc2538rf; +} -void radio_error_isr(void); -void radio_isr_internal(void); //=========================== public ========================================== //===== admin -void radio_init(void) { - - // clear variables - memset(&radio_vars,0,sizeof(radio_vars_t)); - - // change state - radio_vars.state = RADIOSTATE_STOPPED; - //flush fifos - CC2538_RF_CSP_ISFLUSHRX(); - CC2538_RF_CSP_ISFLUSHTX(); - - radio_off(); - - //disable radio interrupts - disable_radio_interrupts(); - - /* - This CORR_THR value should be changed to 0x14 before attempting RX. Testing has shown that - too many false frames are received if the reset value is used. Make it more likely to detect - sync by removing the requirement that both symbols in the SFD must have a correlation value - above the correlation threshold, and make sync word detection less likely by raising the - correlation threshold. - */ - HWREG(RFCORE_XREG_MDMCTRL1) = 0x14; - /* tuning adjustments for optimal radio performance; details available in datasheet */ - - HWREG(RFCORE_XREG_RXCTRL) = 0x3F; - /* Adjust current in synthesizer; details available in datasheet. */ - HWREG(RFCORE_XREG_FSCTRL) = 0x55; - - /* Makes sync word detection less likely by requiring two zero symbols before the sync word. - * details available in datasheet. - */ - HWREG(RFCORE_XREG_MDMCTRL0) = 0x85; - - /* Adjust current in VCO; details available in datasheet. */ - HWREG(RFCORE_XREG_FSCAL1) = 0x01; - /* Adjust target value for AGC control loop; details available in datasheet. */ - HWREG(RFCORE_XREG_AGCCTRL1) = 0x15; - - /* Tune ADC performance, details available in datasheet. */ - HWREG(RFCORE_XREG_ADCTEST0) = 0x10; - HWREG(RFCORE_XREG_ADCTEST1) = 0x0E; - HWREG(RFCORE_XREG_ADCTEST2) = 0x03; - - //update CCA register to -81db as indicated by manual.. won't be used.. - HWREG(RFCORE_XREG_CCACTRL0) = 0xF8; - /* - * Changes from default values - * See User Guide, section "Register Settings Update" - */ - HWREG(RFCORE_XREG_TXFILTCFG) = 0x09; /** TX anti-aliasing filter bandwidth */ - HWREG(RFCORE_XREG_AGCCTRL1) = 0x15; /** AGC target value */ - HWREG(ANA_REGS_O_IVCTRL) = 0x0B; /** Bias currents */ - - /* disable the CSPT register compare function */ - HWREG(RFCORE_XREG_CSPT) = 0xFFUL; - /* - * Defaults: - * Auto CRC; Append RSSI, CRC-OK and Corr. Val.; CRC calculation; - * RX and TX modes with FIFOs - */ - HWREG(RFCORE_XREG_FRMCTRL0) = RFCORE_XREG_FRMCTRL0_AUTOCRC; - - //poipoi disable frame filtering by now.. sniffer mode. - HWREG(RFCORE_XREG_FRMFILT0) &= ~RFCORE_XREG_FRMFILT0_FRAME_FILTER_EN; - - /* Disable source address matching and autopend */ - HWREG(RFCORE_XREG_SRCMATCH) = 0; - - /* MAX FIFOP threshold */ - HWREG(RFCORE_XREG_FIFOPCTRL) = CC2538_RF_MAX_PACKET_LEN; - - HWREG(RFCORE_XREG_TXPOWER) = CC2538_RF_TX_POWER; - HWREG(RFCORE_XREG_FREQCTRL) = CC2538_RF_CHANNEL_MIN; - - /* Enable RF interrupts see page 751 */ - // enable_radio_interrupts(); - - //register interrupt - IntRegister(INT_RFCORERTX, radio_isr_internal); - IntRegister(INT_RFCOREERR, radio_error_isr); - - IntEnable(INT_RFCORERTX); - - /* Enable all RF Error interrupts */ - HWREG(RFCORE_XREG_RFERRM) = RFCORE_XREG_RFERRM_RFERRM_M; //all errors - IntEnable(INT_RFCOREERR); - //radio_on(); - - // change state - radio_vars.state = RADIOSTATE_RFOFF; -} - -void radio_setStartFrameCb(radio_capture_cbt cb) { - radio_vars.startFrame_cb = cb; -} - -void radio_setEndFrameCb(radio_capture_cbt cb) { - radio_vars.endFrame_cb = cb; +void radio_init (void) { + //bootstrapping the radio look-up matrix + radio_bootstrap(); + + // Initializing the atmel radio + dyn_funcs [RADIOSETTING_FSK_OPTION1_FEC].radio_init(); + + // Initializing the ti radio + dyn_funcs [RADIOSETTING_24GHZ].radio_init(); } -//===== reset void radio_reset(void) { - /* Wait for ongoing TX to complete (e.g. this could be an outgoing ACK) */ - while(HWREG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_TX_ACTIVE); - - //flush fifos - CC2538_RF_CSP_ISFLUSHRX(); - CC2538_RF_CSP_ISFLUSHTX(); - - /* Don't turn off if we are off as this will trigger a Strobe Error */ - if(HWREG(RFCORE_XREG_RXENABLE) != 0) { - CC2538_RF_CSP_ISRFOFF(); - } - radio_init(); + dyn_funcs [selected_radioSetting].radio_reset(); } -//===== RF admin -void radio_setFrequency(uint8_t frequency, radio_freq_t tx_or_rx) { - - // change state - radio_vars.state = RADIOSTATE_SETTING_FREQUENCY; - - radio_off(); - // configure the radio to the right frequency - if((frequency < CC2538_RF_CHANNEL_MIN) || (frequency > CC2538_RF_CHANNEL_MAX)) { - while(1); - } - - /* Changes to FREQCTRL take effect after the next recalibration */ - HWREG(RFCORE_XREG_FREQCTRL) = (CC2538_RF_CHANNEL_MIN - + (frequency - CC2538_RF_CHANNEL_MIN) * CC2538_RF_CHANNEL_SPACING); - - //radio_on(); - - // change state - radio_vars.state = RADIOSTATE_FREQUENCY_SET; +void radio_setConfig (radioSetting_t radioSetting){ + selected_radioSetting = radioSetting; + dyn_funcs [selected_radioSetting].radio_setConfig(selected_radioSetting); } -void radio_rfOn(void) { - //radio_on(); + +void radio_setStartFrameCb (radio_capture_cbt cb) { + dyn_funcs [selected_radioSetting].radio_setStartFrameCb(cb); } -void radio_rfOff(void) { - - // change state - radio_vars.state = RADIOSTATE_TURNING_OFF; - radio_off(); - // wiggle debug pin - debugpins_radio_clr(); - leds_radio_off(); - //enable radio interrupts - disable_radio_interrupts(); - - // change state - radio_vars.state = RADIOSTATE_RFOFF; +void radio_setEndFrameCb (radio_capture_cbt cb) { + dyn_funcs [selected_radioSetting].radio_setEndFrameCb(cb); } -//===== TX +//===== RF admin -void radio_loadPacket(uint8_t* packet, uint16_t len) { - uint8_t i=0; - - // change state - radio_vars.state = RADIOSTATE_LOADING_PACKET; - - // load packet in TXFIFO - /* - When we transmit in very quick bursts, make sure previous transmission - is not still in progress before re-writing to the TX FIFO - */ - while(HWREG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_TX_ACTIVE); - - CC2538_RF_CSP_ISFLUSHTX(); - - /* Send the phy length byte first */ - HWREG(RFCORE_SFR_RFDATA) = len; //crc len is included - - for(i = 0; i < len; i++) { - HWREG(RFCORE_SFR_RFDATA) = packet[i]; - } - - // change state - radio_vars.state = RADIOSTATE_PACKET_LOADED; +void radio_setFrequency (uint8_t channel, radio_freq_t tx_or_rx) { + dyn_funcs [selected_radioSetting].radio_setFrequency(channel, tx_or_rx); } -void radio_txEnable(void) { - - // change state - radio_vars.state = RADIOSTATE_ENABLING_TX; - - // wiggle debug pin - debugpins_radio_set(); - leds_radio_on(); - - //do nothing -- radio is activated by the strobe on rx or tx - //radio_rfOn(); - - // change state - radio_vars.state = RADIOSTATE_TX_ENABLED; +void radio_rfOn (void) { + dyn_funcs [selected_radioSetting].radio_rfOn(); } -void radio_txNow(void) { - PORT_TIMER_WIDTH count; - - // change state - radio_vars.state = RADIOSTATE_TRANSMITTING; - - //enable radio interrupts - enable_radio_interrupts(); - - //make sure we are not transmitting already - while(HWREG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_TX_ACTIVE); - - // send packet by STON strobe see pag 669 +void radio_rfOff (void) { + dyn_funcs [selected_radioSetting].radio_rfOff(); +} - CC2538_RF_CSP_ISTXON(); - //wait 192uS - count=0; - while(!((HWREG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_TX_ACTIVE))){ - count++; //debug - } +int8_t radio_getFrequencyOffset (void){ + return dyn_funcs [selected_radioSetting].radio_getFrequencyOffset(); } -//===== RX +//===== TX -void radio_rxEnable(void) { - - // change state - radio_vars.state = RADIOSTATE_ENABLING_RX; - - //enable radio interrupts - - // do nothing as we do not want to receive anything yet. - // wiggle debug pin - debugpins_radio_set(); - leds_radio_on(); - - // change state - radio_vars.state = RADIOSTATE_LISTENING; +void radio_loadPacket (uint8_t* packet, uint16_t len) { + dyn_funcs [selected_radioSetting].radio_loadPacket(packet, len); } -void radio_rxNow(void) { - //empty buffer before receiving - //CC2538_RF_CSP_ISFLUSHRX(); - - //enable radio interrupts - CC2538_RF_CSP_ISFLUSHRX(); - enable_radio_interrupts(); - - CC2538_RF_CSP_ISRXON(); - // busy wait until radio really listening - while(!((HWREG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_RX_ACTIVE))); -} -void radio_getReceivedFrame(uint8_t* pBufRead, - uint8_t* pLenRead, - uint8_t maxBufLen, - int8_t* pRssi, - uint8_t* pLqi, - bool* pCrc) { - uint8_t crc_corr,i; - - uint8_t len=0; - - /* Check the length */ - len = HWREG(RFCORE_SFR_RFDATA); //first byte is len - - - /* Check for validity */ - if(len > CC2538_RF_MAX_PACKET_LEN) { - /* wrong len */ - CC2538_RF_CSP_ISFLUSHRX(); - return; - } - - - if(len <= CC2538_RF_MIN_PACKET_LEN) { - //too short - CC2538_RF_CSP_ISFLUSHRX(); - return; - } - - //check if this fits to the buffer - if(len > maxBufLen) { - CC2538_RF_CSP_ISFLUSHRX(); - return; - } - - // when reading the packet from the RX buffer, you get the following: - // - *[1B] length byte - // - [0-125B] packet (excluding CRC) - // - [1B] RSSI - // - *[2B] CRC - - //skip first byte is len - for(i = 0; i < len - 2; i++) { - pBufRead[i] = HWREG(RFCORE_SFR_RFDATA); - } - - *pRssi = ((int8_t)(HWREG(RFCORE_SFR_RFDATA)) - RSSI_OFFSET); - crc_corr = HWREG(RFCORE_SFR_RFDATA); - *pCrc = crc_corr & CRC_BIT_MASK; - *pLenRead = len; - - //flush it - CC2538_RF_CSP_ISFLUSHRX(); +void radio_txEnable (void) { + dyn_funcs [selected_radioSetting].radio_txEnable(); } -//=========================== private ========================================= +void radio_txNow (void) { + dyn_funcs [selected_radioSetting].radio_txNow(); +} -void enable_radio_interrupts(void){ - /* Enable RF interrupts 0, RXPKTDONE,SFD,FIFOP only -- see page 751 */ - HWREG(RFCORE_XREG_RFIRQM0) |= ((0x06|0x02|0x01) << RFCORE_XREG_RFIRQM0_RFIRQM_S) & RFCORE_XREG_RFIRQM0_RFIRQM_M; +//===== RX - /* Enable RF interrupts 1, TXDONE only */ - HWREG(RFCORE_XREG_RFIRQM1) |= ((0x02) << RFCORE_XREG_RFIRQM1_RFIRQM_S) & RFCORE_XREG_RFIRQM1_RFIRQM_M; +void radio_rxEnable (void) { + dyn_funcs [selected_radioSetting].radio_rxEnable(); } -void disable_radio_interrupts(void){ - /* Enable RF interrupts 0, RXPKTDONE,SFD,FIFOP only -- see page 751 */ - HWREG(RFCORE_XREG_RFIRQM0) = 0; - /* Enable RF interrupts 1, TXDONE only */ - HWREG(RFCORE_XREG_RFIRQM1) = 0; +void radio_rxNow (void) { + dyn_funcs [selected_radioSetting].radio_rxNow(); } -void radio_on(void){ - // CC2538_RF_CSP_ISFLUSHRX(); - CC2538_RF_CSP_ISRXON(); -} +void radio_getReceivedFrame ( + uint8_t* bufRead, + uint8_t* lenRead, + uint8_t maxBufLen, + int8_t* rssi, + uint8_t* lqi, + bool* crc +) { -void radio_off(void){ - /* Wait for ongoing TX to complete (e.g. this could be an outgoing ACK) */ - while(HWREG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_TX_ACTIVE); - //CC2538_RF_CSP_ISFLUSHRX(); - - /* Don't turn off if we are off as this will trigger a Strobe Error */ - if(HWREG(RFCORE_XREG_RXENABLE) != 0) { - CC2538_RF_CSP_ISRFOFF(); - //clear fifo isr flag - HWREG(RFCORE_SFR_RFIRQF0) = ~(RFCORE_SFR_RFIRQF0_FIFOP|RFCORE_SFR_RFIRQF0_RXPKTDONE); - } + dyn_funcs [selected_radioSetting].radio_getReceivedFrame (bufRead, lenRead, maxBufLen, rssi, lqi, crc ); } +//=========================== private ========================================= + //=========================== callbacks ======================================= //=========================== interrupt handlers ============================== - -/** -\brief Stub function for the CC2538. - -In MSP430 platforms the CPU status after servicing an interrupt can be managed -toggling some bits in a special register, e.g. CPUOFF, LPM1, etc, within the -interrupt context itself. By default, after servicing an interrupt the CPU will -be off so it makes sense to return a value and enable it if something has -happened that needs the scheduler to run (a packet has been received that needs -to be processed). Otherwise, the CPU is kept in sleep mode without even -reaching the main loop. - -In the CC2538, however, the default behaviour is the contrary. After servicing -an interrupt the CPU will be on by default and it is the responsability of the -main thread to put it back to sleep (which is already done). This means that -the scheduler will always be kicked in after servicing an interrupt. This -behaviour can be changed by modifying the SLEEPEXIT field in the SYSCTRL -regiser (see page 131 of the CC2538 manual). -*/ kick_scheduler_t radio_isr(void) { - return DO_NOT_KICK_SCHEDULER; + return dyn_funcs [selected_radioSetting].radio_isr(); } -void radio_isr_internal(void) { - volatile PORT_TIMER_WIDTH capturedTime; - uint8_t irq_status0,irq_status1; - - debugpins_isr_set(); - - // capture the time - capturedTime = sctimer_readCounter(); - - // reading IRQ_STATUS - irq_status0 = HWREG(RFCORE_SFR_RFIRQF0); - irq_status1 = HWREG(RFCORE_SFR_RFIRQF1); - - IntPendClear(INT_RFCORERTX); - - //clear interrupt - HWREG(RFCORE_SFR_RFIRQF0) = 0; - HWREG(RFCORE_SFR_RFIRQF1) = 0; - - //STATUS0 Register - // start of frame event - if ((irq_status0 & RFCORE_SFR_RFIRQF0_SFD) == RFCORE_SFR_RFIRQF0_SFD) { - // change state - radio_vars.state = RADIOSTATE_RECEIVING; - if (radio_vars.startFrame_cb!=NULL) { - // call the callback - radio_vars.startFrame_cb(capturedTime); - debugpins_isr_clr(); - // kick the OS - return; - } else { - while(1); - } - } - - //or RXDONE is full -- we have a packet. - if (((irq_status0 & RFCORE_SFR_RFIRQF0_RXPKTDONE) == RFCORE_SFR_RFIRQF0_RXPKTDONE)) { - // change state - radio_vars.state = RADIOSTATE_TXRX_DONE; - if (radio_vars.endFrame_cb!=NULL) { - // call the callback - radio_vars.endFrame_cb(capturedTime); - debugpins_isr_clr(); - // kick the OS - return; - } else { - while(1); - } - } - - // or FIFOP is full -- we have a packet. - if (((irq_status0 & RFCORE_SFR_RFIRQF0_FIFOP) == RFCORE_SFR_RFIRQF0_FIFOP)) { - // change state - radio_vars.state = RADIOSTATE_TXRX_DONE; - if (radio_vars.endFrame_cb!=NULL) { - // call the callback - radio_vars.endFrame_cb(capturedTime); - debugpins_isr_clr(); - // kick the OS - return; - } else { - while(1); - } - } - - //STATUS1 Register - // end of frame event --either end of tx . - if (((irq_status1 & RFCORE_SFR_RFIRQF1_TXDONE) == RFCORE_SFR_RFIRQF1_TXDONE)) { - // change state - radio_vars.state = RADIOSTATE_TXRX_DONE; - if (radio_vars.endFrame_cb!=NULL) { - // call the callback - radio_vars.endFrame_cb(capturedTime); - debugpins_isr_clr(); - // kick the OS - return; - } else { - while(1); - } - } - debugpins_isr_clr(); - - return; -} -void radio_error_isr(void){ - uint8_t rferrm; - - rferrm = (uint8_t)HWREG(RFCORE_XREG_RFERRM); - - if ((HWREG(RFCORE_XREG_RFERRM) & (((0x02)<, September 2017. +*/ +#include "board.h" +#include "board_info.h" +#include "ssi.h" +#include "spi.h" +#include "gpio.h" +#include "ioc.h" +#include "sys_ctrl.h" + +#include +#include +#include +#include +#include +#include + + +//=========================== defines ========================================= + +#define SPI_PIN_SSI_CLK GPIO_PIN_2 // CLK +#define SPI_PIN_SSI_FSS GPIO_PIN_3 // CSn +#define SPI_PIN_SSI_RX GPIO_PIN_4 // MISO +#define SPI_PIN_SSI_TX GPIO_PIN_5 // MOSI +#define SPI_GPIO_SSI_BASE GPIO_A_BASE + +//=========================== variables ======================================= + +typedef struct { + // information about the current transaction + uint8_t* pNextTxByte; + uint16_t numTxedBytes; + uint16_t txBytesLeft; + spi_return_t returnType; + uint8_t* pNextRxByte; + uint16_t maxRxBytes; + spi_first_t isFirst; + spi_last_t isLast; + // state of the module + uint8_t busy; +#ifdef SPI_IN_INTERRUPT_MODE + // callback when module done + spi_cbt callback; +#endif +} spi_vars_t; + +spi_vars_t spi_vars; + +//=========================== prototypes ====================================== + +static void disableInterrupts(void); +static void enableInterrupts(void); + +//=========================== public ========================================== + +void spi_init() { + // clear variables + memset(&spi_vars,0,sizeof(spi_vars_t)); + + // set the clk miso and cs pins as output + GPIOPinTypeGPIOOutput(SPI_GPIO_SSI_BASE, SPI_PIN_SSI_CLK); + GPIOPinTypeGPIOOutput(SPI_GPIO_SSI_BASE, SPI_PIN_SSI_TX); + GPIOPinTypeGPIOOutput(SPI_GPIO_SSI_BASE, SPI_PIN_SSI_FSS); + + //set cs to high + GPIOPinWrite(SPI_GPIO_SSI_BASE, SPI_PIN_SSI_FSS, SPI_PIN_SSI_FSS); + //set pins to low + GPIOPinWrite(SPI_GPIO_SSI_BASE, SPI_PIN_SSI_TX, 0); + GPIOPinWrite(SPI_GPIO_SSI_BASE, SPI_PIN_SSI_CLK, 0); + + SysCtrlPeripheralEnable(SYS_CTRL_PERIPH_SSI0); + SysCtrlPeripheralSleepEnable(SYS_CTRL_PERIPH_SSI0); + SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_SSI0); + + SSIDisable(SSI0_BASE); + SSIClockSourceSet(SSI0_BASE, SSI_CLOCK_PIOSC); + + IOCPinConfigPeriphOutput(SPI_GPIO_SSI_BASE, SPI_PIN_SSI_CLK, IOC_MUX_OUT_SEL_SSI0_CLKOUT); + IOCPinConfigPeriphOutput(SPI_GPIO_SSI_BASE, SPI_PIN_SSI_TX, IOC_MUX_OUT_SEL_SSI0_TXD); + IOCPinConfigPeriphInput(SPI_GPIO_SSI_BASE, SPI_PIN_SSI_RX, IOC_SSIRXD_SSI0); + + GPIOPinTypeSSI(SPI_GPIO_SSI_BASE, SPI_PIN_SSI_CLK ); + GPIOPinTypeSSI(SPI_GPIO_SSI_BASE, SPI_PIN_SSI_RX ); + GPIOPinTypeSSI(SPI_GPIO_SSI_BASE, SPI_PIN_SSI_TX ); + + SSIConfigSetExpClk(SSI0_BASE, SysCtrlIOClockGet(), SSI_FRF_MOTO_MODE_0, SSI_MODE_MASTER, /*SysCtrlIOClockGet()/2*/16000000, 8); + + // Enable the SSI0 module. + SSIEnable(SSI0_BASE); +} + +#ifdef SPI_IN_INTERRUPT_MODE +void spi_setCb(spi_cbt cb) { + spi_vars.spi_cb = cb; +} +#endif + +void spi_txrx(uint8_t* bufTx, + uint16_t lenbufTx, + spi_return_t returnType, + uint8_t* bufRx, + uint16_t maxLenBufRx, + spi_first_t isFirst, + spi_last_t isLast) { + + uint32_t data,i; + GPIOPinWrite(GPIO_B_BASE, GPIO_PIN_1, GPIO_PIN_1); + // register spi frame to send + spi_vars.pNextTxByte = bufTx; + spi_vars.numTxedBytes = 0; + spi_vars.txBytesLeft = lenbufTx; + spi_vars.returnType = returnType; + spi_vars.pNextRxByte = bufRx; + spi_vars.maxRxBytes = maxLenBufRx; + spi_vars.isFirst = isFirst; + spi_vars.isLast = isLast; + + // SPI is now busy + spi_vars.busy = 1; + + // lower CS signal to have slave listening + if (spi_vars.isFirst==SPI_FIRST) { + GPIOPinWrite(SPI_GPIO_SSI_BASE, SPI_PIN_SSI_FSS, 0); + } + + for ( i = 0; i < lenbufTx; i++) + { + // Push a byte + SSIDataPut(SSI0_BASE, spi_vars.pNextTxByte[i]); + + // Wait until it is complete + while(SSIBusy(SSI0_BASE)); + + // Read a byte + SSIDataGet(SSI0_BASE, &data); + + // Store the result + spi_vars.pNextRxByte[i] = (uint8_t)(data & 0xFF); + // one byte less to go + } + + if (spi_vars.isLast==SPI_LAST) { + GPIOPinWrite(SPI_GPIO_SSI_BASE, SPI_PIN_SSI_FSS, SPI_PIN_SSI_FSS); + } + + // SPI is not busy anymore + spi_vars.busy = 0; + GPIOPinWrite(GPIO_B_BASE, GPIO_PIN_1, 0); +} + +//=========================== private ========================================= + +port_INLINE void enableInterrupts(void) +{ + // Enable the SPI interrupt + SSIIntEnable(SSI0_BASE, (SSI_TXFF | SSI_RXFF | SSI_RXTO | SSI_RXOR)); + + // Enable the SPI interrupt + IntEnable(INT_SSI0); +} + +port_INLINE void disableInterrupts(void) +{ + // Disable the SPI interrupt + SSIIntDisable(SSI0_BASE, (SSI_TXFF | SSI_RXFF | SSI_RXTO | SSI_RXOR)); + + // Disable the SPI interrupt + IntDisable(INT_SSI0); +} + +//=========================== interrupt handlers ============================== + +kick_scheduler_t spi_isr() { +#ifdef SPI_IN_INTERRUPT_MODE + uint32_t data; + // save the byte just received in the RX buffer + status = SSIIntStatus(SSI0_BASE, true); + + // Clear SPI interrupt in the NVIC + IntPendClear(INT_SSI0); + + SSIDataGet(SSI0_BASE, &data); + + // Store the result + spi_vars.pNextRxByte = (uint8_t)(data & 0xFF); + + // one byte less to go + spi_vars.pNextTxByte++; + spi_vars.pNextRxByte++; + spi_vars.txBytesLeft--; + + if (spi_vars.txBytesLeft>0) { + // write next byte to TX buffer + SSIDataPut(SSI0_BASE, *spi_vars.pNextTxByte); + + } else { + // SPI is not busy anymore + spi_vars.busy = 0; + + // SPI is done! + if (spi_vars.callback!=NULL) { + // call the callback + spi_vars.spi_cb(); + // kick the OS + return KICK_SCHEDULER; + } + } + +#endif + return DO_NOT_KICK_SCHEDULER; +} diff --git a/bsp/boards/openmote-b/startup_iar.c b/bsp/boards/openmote-b/startup_iar.c index e63d7bc74b..4b7c2ad585 100644 --- a/bsp/boards/openmote-b/startup_iar.c +++ b/bsp/boards/openmote-b/startup_iar.c @@ -39,8 +39,8 @@ #include #define FLASH_START_ADDR 0x00200000 -#define BOOTLOADER_BACKDOOR_ENABLE 0xF7FFFFFF // ENABLED: PORT A, PIN 6, LOW #define BOOTLOADER_BACKDOOR_DISABLE 0xEFFFFFFF +#define BOOTLOADER_BACKDOOR_ENABLE 0xF6FFFFFF // ENABLED: PORT A, PIN 6, LOW #define SYS_CTRL_EMUOVR 0x400D20B4 #define SYS_CTRL_I_MAP 0x400D2098 @@ -191,7 +191,7 @@ lockPageCCA_t; __root const lockPageCCA_t __cca @ ".flashcca" = { - BOOTLOADER_BACKDOOR_ENABLE, // Bootloader backdoor disabled + BOOTLOADER_BACKDOOR_ENABLE, // Bootloader backdoor enabled 0, // Image valid bytes FLASH_START_ADDR // Vector table located at flash start address }; diff --git a/bsp/boards/openmote-cc2538/board.c b/bsp/boards/openmote-cc2538/board.c index 07f666fcf3..9e6589cabf 100644 --- a/bsp/boards/openmote-cc2538/board.c +++ b/bsp/boards/openmote-cc2538/board.c @@ -40,6 +40,9 @@ #else #define CC2538_FLASH_ADDRESS ( 0x0027F800 ) #endif + +slot_board_vars_t slot_board_vars [MAX_SLOT_TYPES]; +slotType_t selected_slot_type; //=========================== prototypes ====================================== void board_timer_init(void); @@ -101,8 +104,46 @@ void board_init(void) { #endif pwm_init(); + board_init_slot_vars(); +} + +//==== bootstrapping slot info lookup table +void board_init_slot_vars(void){ + //10ms slot + slot_board_vars [SLOT_10ms_24GHZ].slotDuration = 328 ; // ms + slot_board_vars [SLOT_10ms_24GHZ].maxTxDataPrepare = 10 ; // 305us (measured 82us) + slot_board_vars [SLOT_10ms_24GHZ].maxRxAckPrepare = 10 ; // 305us (measured 83us) + slot_board_vars [SLOT_10ms_24GHZ].maxRxDataPrepare = 4 ; // 122us (measured 22us) + slot_board_vars [SLOT_10ms_24GHZ].maxTxAckPrepare = 10 ; // 122us (measured 94us) + + #ifdef OPENWSN_IEEE802154E_SECURITY_C + slot_board_vars [SLOT_10ms_24GHZ].delayTx = 14 ; // 366us (measured xxxus) + #else + slot_board_vars [SLOT_10ms_24GHZ].delayTx = 12 ; // 366us (measured xxxus) + #endif + slot_board_vars [SLOT_10ms_24GHZ].delayRx = 0 ; // 0us (can not measure) + + // 20ms slot + slot_board_vars [SLOT_20ms_24GHZ].slotDuration = 655 ; // ms + slot_board_vars [SLOT_20ms_24GHZ].maxTxDataPrepare = 15 ; // 457us (based on measurement) + slot_board_vars [SLOT_20ms_24GHZ].maxRxAckPrepare = 10 ; // 305us (based on measurement) + slot_board_vars [SLOT_20ms_24GHZ].maxRxDataPrepare = 10 ; // 305us (based on measurement) + slot_board_vars [SLOT_20ms_24GHZ].maxTxAckPrepare = 15 ; // 457us (based on measurement) + slot_board_vars [SLOT_20ms_24GHZ].delayTx = 13 ; // 396us (based on measurement) + slot_board_vars [SLOT_20ms_24GHZ].delayRx = 0 ; // 0us (can not measure) } +// To get the current slotDuration at any time +// used during initialization by sixtop to fire the first sixtop EB +uint16_t board_getSlotDuration (void){ + return slot_board_vars [selected_slot_type].slotDuration; +} + +// Setter/Getter function for slot_board_vars +slot_board_vars_t board_selectSlotTemplate (slotType_t slot_type) { + selected_slot_type = slot_type; + return slot_board_vars [selected_slot_type]; +} /** * Puts the board to sleep */ diff --git a/bsp/boards/openmote-cc2538/board_info.h b/bsp/boards/openmote-cc2538/board_info.h index 63f980d4ee..568ded9da5 100644 --- a/bsp/boards/openmote-cc2538/board_info.h +++ b/bsp/boards/openmote-cc2538/board_info.h @@ -60,44 +60,6 @@ #define PORT_PIN_RADIO_RESET_HIGH() // nothing #define PORT_PIN_RADIO_RESET_LOW() // nothing -//===== IEEE802154E timing - -#define SLOTDURATION 20 // in miliseconds - -//===== IEEE802154E timing - -#if SLOTDURATION==10 - // time-slot related - #define PORT_TsSlotDuration 328 // counter counts one extra count, see datasheet - // execution speed related - #define PORT_maxTxDataPrepare 10 // 305us (measured 82us) - #define PORT_maxRxAckPrepare 10 // 305us (measured 83us) - #define PORT_maxRxDataPrepare 4 // 122us (measured 22us) - #define PORT_maxTxAckPrepare 10 // 122us (measured 94us) - // radio speed related -#ifdef OPENWSN_IEEE802154E_SECURITY_C - #define PORT_delayTx 14 // 366us (measured xxxus) -#else - #define PORT_delayTx 12 // 366us (measured xxxus) -#endif - #define PORT_delayRx 0 // 0us (can not measure) - // radio watchdog -#endif - -#if SLOTDURATION==20 - #define PORT_TsSlotDuration 655 // 20ms - - // execution speed related - #define PORT_maxTxDataPrepare 15 // 458us (measured 213us) - #define PORT_maxRxAckPrepare 10 // 305us (measured 86us) - #define PORT_maxRxDataPrepare 10 // 305us (measured 88us) - #define PORT_maxTxAckPrepare 15 // 458us (measured 211us) - - // radio speed related - #define PORT_delayTx 13 // 397us (measured 388us) - #define PORT_delayRx 0 // 0us (can not measure) -#endif - //===== adaptive_sync accuracy #define SYNC_ACCURACY 1 // ticks diff --git a/bsp/boards/openmote-cc2538/radio.c b/bsp/boards/openmote-cc2538/radio.c index 8094ef5663..6f7f06b58a 100644 --- a/bsp/boards/openmote-cc2538/radio.c +++ b/bsp/boards/openmote-cc2538/radio.c @@ -45,6 +45,9 @@ typedef struct { radio_vars_t radio_vars; +// global radio selection, will use the slowest by default at initialization. +uint8_t selected_radioSetting = RADIOSETTING_24GHZ; + //=========================== prototypes ====================================== void enable_radio_interrupts(void); @@ -184,6 +187,11 @@ void radio_reset(void) { //===== RF admin +void radio_setConfig (radioSetting_t radioSetting){ + selected_radioSetting = radioSetting; + //do nothing +} + void radio_setFrequency(uint8_t frequency, radio_freq_t tx_or_rx) { // change state diff --git a/bsp/boards/openmotestm/board.c b/bsp/boards/openmotestm/board.c index a0420b8a9a..1059fe333c 100644 --- a/bsp/boards/openmotestm/board.c +++ b/bsp/boards/openmotestm/board.c @@ -32,7 +32,9 @@ extern int mote_main(void); int main(void) { return mote_main(); } - +//=========================== variables ======================================= +slot_board_vars_t slot_board_vars [MAX_SLOT_TYPES]; +slotType_t selected_slot_type; //=========================== public ========================================== void board_init(void){ @@ -95,6 +97,34 @@ void board_init(void){ debugpins_init(); //enable nvic for the radio NVIC_radio(); + board_init_slot_vars(); +} + +//==== bootstrapping slot info lookup table + +//===== IEEE802154E timing +void board_init_slot_vars(void) { + // 20ms slot + slot_board_vars [SLOT_20ms_24GHZ].slotDuration = 655 ; // ms + slot_board_vars [SLOT_20ms_24GHZ].maxTxDataPrepare = 66 ; // 2014us (not measured) + slot_board_vars [SLOT_20ms_24GHZ].maxRxAckPrepare = 20 ; // 610us (not measured) + slot_board_vars [SLOT_20ms_24GHZ].maxRxDataPrepare = 33 ; // 1007us (not measured) + slot_board_vars [SLOT_20ms_24GHZ].maxTxAckPrepare = 30 ; // 915us (not measured) + slot_board_vars [SLOT_20ms_24GHZ].delayTx = 10 ; // 305us (not measured) + slot_board_vars [SLOT_20ms_24GHZ].delayRx = 0 ; // 0us (can not measure) + +} + +// To get the current slotDuration at any time +// used during initialization by sixtop to fire the first sixtop EB +uint16_t board_getSlotDuration (void) { + return slot_board_vars [selected_slot_type].slotDuration; +} + +// Setter/Getter function for slot_board_vars +slot_board_vars_t board_selectSlotTemplate (slotType_t slot_type) { + selected_slot_type = slot_type; + return slot_board_vars [selected_slot_type]; } void board_sleep(void) { @@ -123,24 +153,24 @@ void board_reset(void){ void GPIO_Config_ALL_AIN(void){ GPIO_InitTypeDef GPIO_InitStructure; - /* Enable GPIOD and GPIOE clock */ + //Enable GPIOD and GPIOE clock RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD | RCC_APB2Periph_AFIO, ENABLE); - /* PA */ + //PA GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; GPIO_Init(GPIOA, &GPIO_InitStructure); - /* PB */ + //PB GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; GPIO_Init(GPIOB, &GPIO_InitStructure); - /* PC */ + //PC GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; GPIO_Init(GPIOC, &GPIO_InitStructure); - /* PD */ + //PD GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; GPIO_Init(GPIOD, &GPIO_InitStructure); diff --git a/bsp/boards/openmotestm/board_info.h b/bsp/boards/openmotestm/board_info.h index 0cfe4f67c0..43add1fb89 100644 --- a/bsp/boards/openmotestm/board_info.h +++ b/bsp/boards/openmotestm/board_info.h @@ -53,21 +53,6 @@ to return the board's description. #define PORT_PIN_RADIO_RESET_HIGH() //GPIOC->ODR |= 0X0040; #define PORT_PIN_RADIO_RESET_LOW() //GPIOC->ODR &= ~0X0040; -//===== IEEE802154E timing - -#define SLOTDURATION 20 // in miliseconds - -// time-slot related -#define PORT_TsSlotDuration 655 // counter counts one extra count, see datasheet -// execution speed related -#define PORT_maxTxDataPrepare 66 // 2014us (measured 746us) -#define PORT_maxRxAckPrepare 20 // 305us (measured 83us) -#define PORT_maxRxDataPrepare 33 // 1007us (measured 84us) -#define PORT_maxTxAckPrepare 30 // 305us (measured 219us) -// radio speed related -#define PORT_delayTx 10 // 214us (measured 219us) -#define PORT_delayRx 0 // 0us (can not measure) -// radio watchdog //===== adaptive_sync accuracy diff --git a/bsp/boards/openmotestm/spi.c b/bsp/boards/openmotestm/spi.c index 55b07d6bda..5feb1ef4f7 100644 --- a/bsp/boards/openmotestm/spi.c +++ b/bsp/boards/openmotestm/spi.c @@ -18,20 +18,20 @@ //=========================== variables ======================================= typedef struct { - // information about the current transaction - uint8_t* pNextTxByte; - uint8_t numTxedBytes; - uint8_t txBytesLeft; - spi_return_t returnType; - uint8_t* pNextRxByte; - uint8_t maxRxBytes; - spi_first_t isFirst; - spi_last_t isLast; - // state of the module - uint8_t busy; + // information about the current transaction + uint8_t* pNextTxByte; + uint8_t numTxedBytes; + uint8_t txBytesLeft; + spi_return_t returnType; + uint8_t* pNextRxByte; + uint8_t maxRxBytes; + spi_first_t isFirst; + spi_last_t isLast; + // state of the module + uint8_t busy; #ifdef SPI_IN_INTERRUPT_MODE - // callback when module done - spi_cbt callback; + // callback when module done + spi_cbt callback; #endif } spi_vars_t; @@ -42,7 +42,7 @@ spi_vars_t spi_vars; //=========================== public ========================================== void spi_init(void) { - // clear variables + // clear variables memset(&spi_vars,0,sizeof(spi_vars_t)); SPI_InitTypeDef SPI_InitStructure; diff --git a/bsp/boards/python/board_info.h b/bsp/boards/python/board_info.h index bd753a556f..8bdab16286 100644 --- a/bsp/boards/python/board_info.h +++ b/bsp/boards/python/board_info.h @@ -29,20 +29,6 @@ #define SCHEDULER_WAKEUP() #define SCHEDULER_ENABLE_INTERRUPT() -#define SLOTDURATION 10 // in miliseconds - -//===== IEEE802154E timing -// time-slot related -#define PORT_TsSlotDuration 328 // counter counts one extra count, see datasheet -// execution speed related -#define PORT_maxTxDataPrepare 10 // 305us (measured 82us) -#define PORT_maxRxAckPrepare 10 // 305us (measured 83us) -#define PORT_maxRxDataPrepare 4 // 122us (measured 22us) -#define PORT_maxTxAckPrepare 4 // 122us (measured 94us) -// radio speed related -#define PORT_delayTx 7 // 366us (measured xxxus) -#define PORT_delayRx 0 // 0us (can not measure) - //===== adaptive_sync accuracy #define SYNC_ACCURACY 1 // when using openmoteSTM, change to 2 diff --git a/bsp/boards/python/board_obj.c b/bsp/boards/python/board_obj.c index 583a06b331..3ca3cd52d6 100644 --- a/bsp/boards/python/board_obj.c +++ b/bsp/boards/python/board_obj.c @@ -15,6 +15,8 @@ #include "sctimer_obj.h" //=========================== variables ======================================= +slot_board_vars_t slot_board_vars [MAX_SLOT_TYPES]; +slotType_t selected_slot_type; //=========================== prototypes ====================================== @@ -27,26 +29,53 @@ void board_init(OpenMote* self) { printf("C@0x%x: board_init()...\n",self); #endif - // initialize bsp modules - debugpins_init(self); - leds_init(self); - sctimer_init(self); - uart_init(self); - radio_init(self); - - // forward to Python - result = PyObject_CallObject(self->callback[MOTE_NOTIF_board_init],NULL); - if (result == NULL) { - printf("[CRITICAL] board_init() returned NULL\r\n"); - return; - } - Py_DECREF(result); - + // initialize bsp modules + debugpins_init(self); + leds_init(self); + sctimer_init(self); + uart_init(self); + radio_init(self); + + board_init_slot_vars(); + + // forward to Python + result = PyObject_CallObject(self->callback[MOTE_NOTIF_board_init],NULL); + if (result == NULL) { + printf("[CRITICAL] board_init() returned NULL\r\n"); + return; + } + Py_DECREF(result); + #ifdef TRACE_ON - printf("C@0x%x: ...done.\n",self); + printf("C@0x%x: ...done.\n",self); #endif } + +//==== bootstrapping slot info lookup table +void board_init_slot_vars(void){ + //10ms slot + slot_board_vars [SLOT_10ms_24GHZ].slotDuration = 328 ; // ms + slot_board_vars [SLOT_10ms_24GHZ].maxTxDataPrepare = 10 ; // 305us (measured 82us) + slot_board_vars [SLOT_10ms_24GHZ].maxRxAckPrepare = 10 ; // 305us (measured 83us) + slot_board_vars [SLOT_10ms_24GHZ].maxRxDataPrepare = 4 ; // 122us (measured 22us) + slot_board_vars [SLOT_10ms_24GHZ].maxTxAckPrepare = 4 ; // 122us (measured 94us) + slot_board_vars [SLOT_10ms_24GHZ].delayTx = 7 ; // 213us (measured xxxus) + slot_board_vars [SLOT_10ms_24GHZ].delayRx = 0 ; // 0us (can not measure) +} + +// To get the current slotDuration at any time +// used during initialization by sixtop to fire the first sixtop EB +uint16_t board_getSlotDuration (void){ + return slot_board_vars [selected_slot_type].slotDuration; +} + +// Setter/Getter function for slot_board_vars +slot_board_vars_t board_selectSlotTemplate (slotType_t slot_type){ + selected_slot_type = slot_type; + return slot_board_vars [selected_slot_type]; +} + void board_sleep(OpenMote* self) { PyObject* result; @@ -54,13 +83,13 @@ void board_sleep(OpenMote* self) { printf("C@0x%x: board_sleep()... \n",self); #endif - // forward to Python - result = PyObject_CallObject(self->callback[MOTE_NOTIF_board_sleep],NULL); - if (result == NULL) { + // forward to Python + result = PyObject_CallObject(self->callback[MOTE_NOTIF_board_sleep],NULL); + if (result == NULL) { printf("[CRITICAL] board_sleep() returned NULL\r\n"); return; - } - Py_DECREF(result); + } + Py_DECREF(result); #ifdef TRACE_ON printf("C@0x%x: ...done.\n",self); diff --git a/bsp/boards/python/radio_obj.c b/bsp/boards/python/radio_obj.c index 3e1b9f00fa..a9cf2f7b92 100644 --- a/bsp/boards/python/radio_obj.c +++ b/bsp/boards/python/radio_obj.c @@ -9,7 +9,8 @@ //=========================== defines ========================================= //=========================== variables ======================================= - +// global radio selection +uint8_t selected_radioSetting = RADIOSETTING_24GHZ; //=========================== prototypes ====================================== @@ -86,6 +87,10 @@ void radio_reset(OpenMote *self) { } //===== RF admin +void radio_setConfig ( radioSetting_t radioSetting){ + selected_radioSetting = radioSetting; + //do nothing +} void radio_setFrequency(OpenMote *self, uint8_t frequency, radio_freq_t tx_or_rx) { PyObject *result; diff --git a/bsp/boards/radio.h b/bsp/boards/radio.h index df4333e870..40ed004308 100644 --- a/bsp/boards/radio.h +++ b/bsp/boards/radio.h @@ -26,27 +26,50 @@ are called in the righr order. The radio keeps a state for debugging purposes only. */ typedef enum { - RADIOSTATE_STOPPED = 0x00, ///< Completely stopped. - RADIOSTATE_RFOFF = 0x01, ///< Listening for commands, but RF chain is off. - RADIOSTATE_SETTING_FREQUENCY = 0x02, ///< Configuring the frequency. - RADIOSTATE_FREQUENCY_SET = 0x03, ///< Done configuring the frequency. - RADIOSTATE_LOADING_PACKET = 0x04, ///< Loading packet into the radio's TX buffer. - RADIOSTATE_PACKET_LOADED = 0x05, ///< Packet is fully loaded in the radio's TX buffer. - RADIOSTATE_ENABLING_TX = 0x06, ///< The RF TX chaing is being enabled (includes locking the PLL). - RADIOSTATE_TX_ENABLED = 0x07, ///< Radio ready to transmit. - RADIOSTATE_TRANSMITTING = 0x08, ///< Busy transmitting bytes. - RADIOSTATE_ENABLING_RX = 0x09, ///< The RF RX chain is being enabled (includes locking the PLL). - RADIOSTATE_LISTENING = 0x0a, ///< RF chain is on, listening, but no packet received yet. - RADIOSTATE_RECEIVING = 0x0b, ///< Busy receiving bytes. - RADIOSTATE_TXRX_DONE = 0x0c, ///< Frame has been sent/received completely. - RADIOSTATE_TURNING_OFF = 0x0d, ///< Turning the RF chain off. + RADIOSTATE_STOPPED = 0x00, ///< Completely stopped. + RADIOSTATE_RFOFF = 0x01, ///< Listening for commands, but RF chain is off. + RADIOSTATE_SETTING_FREQUENCY = 0x02, ///< Configuring the frequency. + RADIOSTATE_FREQUENCY_SET = 0x03, ///< Done configuring the frequency. + RADIOSTATE_LOADING_PACKET = 0x04, ///< Loading packet into the radio's TX buffer. + RADIOSTATE_PACKET_LOADED = 0x05, ///< Packet is fully loaded in the radio's TX buffer. + RADIOSTATE_ENABLING_TX = 0x06, ///< The RF TX chaing is being enabled (includes locking the PLL). + RADIOSTATE_TX_ENABLED = 0x07, ///< Radio ready to transmit. + RADIOSTATE_TRANSMITTING = 0x08, ///< Busy transmitting bytes. + RADIOSTATE_ENABLING_RX = 0x09, ///< The RF RX chain is being enabled (includes locking the PLL). + RADIOSTATE_LISTENING = 0x0a, ///< RF chain is on, listening, but no packet received yet. + RADIOSTATE_RECEIVING = 0x0b, ///< Busy receiving bytes. + RADIOSTATE_TXRX_DONE = 0x0c, ///< Frame has been sent/received completely. + RADIOSTATE_TURNING_OFF = 0x0d, ///< Turning the RF chain off. } radio_state_t; typedef enum { - FREQ_TX = 0x01, - FREQ_RX = 0x02, + FREQ_TX = 0x01, + FREQ_RX = 0x02, } radio_freq_t; +// radio settings available for the MAC layer and supported by openmote-b +typedef enum +{ + + // different "modulations" (AT86RF215-specific) + // At83rf215 settings start at index 0 because they are used directly in a sub-array in the atmel driver. + RADIOSETTING_FSK_OPTION1_FEC, + RADIOSETTING_OQPSK_RATE3, + RADIOSETTING_OFDM_OPTION_1_MCS0, + RADIOSETTING_OFDM_OPTION_1_MCS1, + RADIOSETTING_OFDM_OPTION_1_MCS2, + RADIOSETTING_OFDM_OPTION_1_MCS3, + + // default + RADIOSETTING_24GHZ, + + // can be useful for switching receiver between OFDMx MCS modes. + RADIOSETTING_NONE, + + RADIOSETTING_MAX + +} radioSetting_t; + //=========================== typedef ========================================= typedef void (*radio_capture_cbt)(PORT_TIMER_WIDTH timestamp); @@ -57,13 +80,14 @@ typedef void (*radio_capture_cbt)(PORT_TIMER_WIDTH timestamp); // admin void radio_init(void); +void radio_powerOn(void); void radio_setStartFrameCb(radio_capture_cbt cb); void radio_setEndFrameCb(radio_capture_cbt cb); // reset void radio_reset(void); // RF admin void radio_setFrequency(uint8_t frequency, radio_freq_t tx_or_rx); -//void radio_setFrequency(uint8_t frequency); +void radio_setConfig(radioSetting_t radioSetting); void radio_rfOn(void); void radio_rfOff(void); int8_t radio_getFrequencyOffset(void); @@ -75,16 +99,18 @@ void radio_loadPacket(uint8_t* packet, uint16_t len); void radio_txEnable(void); void radio_txNow(void); // RX + +//referenced in the MAC in scum context only. void radio_rxPacket_prepare(void); void radio_rxEnable(void); void radio_rxEnable_scum(void); void radio_rxNow(void); void radio_getReceivedFrame(uint8_t* bufRead, - uint8_t* lenRead, - uint8_t maxBufLen, - int8_t* rssi, - uint8_t* lqi, - bool* crc); + uint8_t* lenRead, + uint8_t maxBufLen, + int8_t* rssi, + uint8_t* lqi, + bool* crc); // interrupt handlers kick_scheduler_t radio_isr(void); diff --git a/bsp/boards/samr21_xpro/board.c b/bsp/boards/samr21_xpro/board.c index 25ed3b6e5b..028f1d3805 100644 --- a/bsp/boards/samr21_xpro/board.c +++ b/bsp/boards/samr21_xpro/board.c @@ -55,19 +55,22 @@ #include "leds.h" #include "delay.h" +//=========================== variables ======================================= +slot_board_vars_t slot_board_vars [MAX_SLOT_TYPES]; +slotType_t selected_slot_type; -/* === MACROS ============================================================== */ +//=== MACROS ============================================================== -/* TRX Parameter: t10 */ +//TRX Parameter: t10 #define RST_PULSE_WIDTH_US (10) -/* TRX Parameter: tTR1 typical value */ +//TRX Parameter: tTR1 typical value #define P_ON_TO_CLKM_AVAILABLE_TYP_US (330) #define TRX_EXT_INT_CH (0) -/* === GLOBALS ============================================================= */ +//=== GLOBALS ============================================================= extern int mote_main(); @@ -98,43 +101,46 @@ int main(void) */ void board_init(void) { - /* Disable the irq before initialization */ + //Disable the irq before initialization cpu_irq_disable(); - /* Initialize the Clock and event system and more */ + // Initialize the Clock and event system and more sys_clock_init(); - /* Configure the Debug Pins */ + //Configure the Debug Pins debugpins_init(); - /* Configure the Radio Interrupt */ + //Configure the Radio Interrupt at86rfx_intc_init(); - /* Clear the Radio Interrupt */ + //Clear the Radio Interrupt extint_flag_clear(TRX_EXT_INT_CH); -/* Initialize board hardware - SPI Init Configure the Radio Pins and Like RST, SLP_TR, EXTI(IRQ on Rising Edge) - */ +// Initialize board hardware +// SPI Init Configure the Radio Pins and Like RST, SLP_TR, EXTI(IRQ on Rising Edge) + rf_interface_init(); - /* Initialize the LED Output */ + //Initialize the LED Output leds_init(); - /* Initialize the Button Input */ + //Initialize the Button Input button_init(); - /* Radio Init */ + //Radio Init radio_init(); - /* UART Init */ + //UART Init uart_init(); - /* BSP Timer Init*/ + //BSP Timer Init sctimer_init(); - /* Clear the Radio Interrupt */ + //Initialize slot vars + board_init_slot_vars(); + + //Clear the Radio Interrupt extint_enable_irq(TRX_EXT_INT_CH); - /* Enable the IRQ */ + //Enable the IRQ cpu_irq_enable(); } @@ -149,7 +155,7 @@ void board_init(void) void rf_interface_init(void) { pinmux_t pinmux; - /* Configure the RF233 SPI Interface */ + //Configure the RF233 SPI Interface pinmux.dir = PORT_PIN_DIR_OUTPUT; pinmux.mux_loc = SYSTEM_PINMUX_GPIO; pinmux.pull = PORT_PIN_PULLUP; @@ -169,7 +175,7 @@ void rf_interface_init(void) port_pin_set_level(AT86RFX_RST_PIN, SET_HIGH); port_pin_set_level(AT86RFX_SLP_PIN, SET_HIGH); - /* Enable the RF Block */ + //Enable the RF Block PM->APBCMASK.reg |= (1<>. 0x64 = txPwr=>0x04, max: 0x1F. - {RG_BBC0_IRQM, 0x1F},// TXFE, RXEM, RXAM, RXFE, RXFS interrupts enabled + {RG_RF09_PAC, 0x7F}, // Tx Power 5 bits >>. 0x64 = txPwr=>0x04, max: 0x1F. + {RG_BBC0_IRQM, 0x1F}, // TXFE, RXEM, RXAM, RXFE, RXFS interrupts enabled {RG_BBC1_IRQM, 0x00}, - {RG_BBC0_PC, 0x1D},// No FCS filter, 32 bits FCS, FSK. >Mina: used to be 15. Set to 1D to use 16 bit FCS - {RG_BBC0_FSKDM, 0x01},//Direct modulation and preemphasis enabled. + {RG_BBC0_PC, 0x1D}, // No FCS filter, 16 bits FCS, FSK. + {RG_BBC0_FSKDM, 0x01}, //Direct modulation and preemphasis enabled. {RG_BBC0_FSKC0, 0xD6}, {RG_BBC0_FSKC1, 0x00}, // {RG_BBC0_FSKC2, 0x00}, @@ -4071,8 +4071,8 @@ static const registerSetting_t basic_settings_fsk_option3 []={ //DO NOT USE {RG_BBC0_FSKPHRTX, 0x00},// No data whitening SFD0 used. }; //------------------------------------ OQPSK -----------------------------------// -static const registerSetting_t basic_settings_oqpsk_rate1[] = { - {RG_BBC0_PC, 0x17}, +static const registerSetting_t basic_settings_oqpsk_rate0[] = { + {RG_BBC0_PC, 0x1F}, // 16bit FCS {RG_BBC0_OQPSKPHRTX, 0x00}, // MR-OQPSK, rate mode 0 {RG_BBC0_OQPSKC0, 0x10}, // 100kchips/s, RC-0.8 shaping, direct-modulation enabled // {RG_BBC0_OQPSKC1, 0x3F}, // MINIMUM preamble-detection sensitivities, rx-override disabled @@ -4092,7 +4092,7 @@ static const registerSetting_t basic_settings_oqpsk_rate1[] = { {RG_RF09_PAC, 0x7F},// Tx Power 5 bits >>. 0x64 = txPwr=>0x04, max: 0x1F. }; -static const registerSetting_t basic_settings_oqpsk_rate2[] = { +static const registerSetting_t basic_settings_oqpsk_rate1[] = { {RG_BBC0_PC, 0x17}, {RG_BBC0_OQPSKPHRTX, 0x02}, // MR-OQPSK, rate mode 0 {RG_BBC0_OQPSKC0, 0x10}, // 100kchips/s, RC-0.8 shaping, direct-modulation enabled @@ -4113,9 +4113,9 @@ static const registerSetting_t basic_settings_oqpsk_rate2[] = { {RG_RF09_PAC, 0x7F},// Tx Power 5 bits >>. 0x64 = txPwr=>0x04, max: 0x1F. }; -static const registerSetting_t basic_settings_oqpsk_rate3[] = { +static const registerSetting_t basic_settings_oqpsk_rate2[] = { {RG_BBC0_PC, 0x1F}, // Mina: used to be 17 but change to 1F make 2B FCS - {RG_BBC0_OQPSKPHRTX, 0x04}, // MR-OQPSK, rate mode 0 + {RG_BBC0_OQPSKPHRTX, 0x04}, // MR-OQPSK, rate mode 3 {RG_BBC0_OQPSKC0, 0x10}, // 100kchips/s, RC-0.8 shaping, direct-modulation enabled // {RG_BBC0_OQPSKC1, 0x3F}, // MINIMUM preamble-detection sensitivities, rx-override disabled // {RG_BBC0_OQPSKC2, 0x00}, // listen for MR-OQPSK frames only @@ -4134,9 +4134,9 @@ static const registerSetting_t basic_settings_oqpsk_rate3[] = { {RG_RF09_PAC, 0x7F},// Tx Power 5 bits >>. 0x64 = txPwr=>0x04, max: 0x1F. }; -static const registerSetting_t basic_settings_oqpsk_rate4[] = { - {RG_BBC0_PC, 0x17}, - {RG_BBC0_OQPSKPHRTX, 0x06}, // MR-OQPSK, rate mode 0 +static registerSetting_t basic_settings_oqpsk_rate3[] = { + {RG_BBC0_PC, 0x1F}, // 16 bit FCS + {RG_BBC0_OQPSKPHRTX, 0x06}, // MR-OQPSK, rate mode 0//ERORR {RG_BBC0_OQPSKC0, 0x10}, // 100kchips/s, RC-0.8 shaping, direct-modulation enabled // {RG_BBC0_OQPSKC1, 0x3F}, // MINIMUM preamble-detection sensitivities, rx-override disabled // {RG_BBC0_OQPSKC2, 0x00}, // listen for MR-OQPSK frames only @@ -4178,7 +4178,7 @@ static const registerSetting_t basic_settings_oqpsk_250kbps[] = { //------------------------------------ OFDM -----------------------------------// /** Preferred settings for OFDM */ -static const registerSetting_t basic_settings_ofdm_1_mcs0[] = { +static registerSetting_t basic_settings_ofdm_1_mcs0[] = { {RG_RF09_CMD, 0x02}, {RG_RF09_IRQM, 0x1F}, {RG_RF24_IRQM, 0x00}, @@ -4196,7 +4196,7 @@ static const registerSetting_t basic_settings_ofdm_1_mcs0[] = { {RG_BBC0_OFDMPHRTX, 0x00}, }; -static const registerSetting_t basic_settings_ofdm_1_mcs1[] = { +static registerSetting_t basic_settings_ofdm_1_mcs1[] = { {RG_RF09_CMD, 0x02}, {RG_RF09_IRQM, 0x1F}, {RG_RF24_IRQM, 0x00}, @@ -4214,7 +4214,7 @@ static const registerSetting_t basic_settings_ofdm_1_mcs1[] = { {RG_BBC0_OFDMPHRTX, 0x01}, }; -static const registerSetting_t basic_settings_ofdm_1_mcs2[] = { +static registerSetting_t basic_settings_ofdm_1_mcs2[] = { {RG_RF09_CMD, 0x02}, {RG_RF09_IRQM, 0x1F}, {RG_RF24_IRQM, 0x00}, @@ -4232,7 +4232,7 @@ static const registerSetting_t basic_settings_ofdm_1_mcs2[] = { {RG_BBC0_OFDMPHRTX, 0x02}, }; -static const registerSetting_t basic_settings_ofdm_1_mcs3[] = { //TODO +static registerSetting_t basic_settings_ofdm_1_mcs3[] = { //TODO {RG_RF09_CMD, 0x02}, {RG_RF09_IRQM, 0x1F}, {RG_RF24_IRQM, 0x00}, diff --git a/bsp/chips/at86rf215/radio.h b/bsp/chips/at86rf215/radio.h deleted file mode 100644 index b8b810db38..0000000000 --- a/bsp/chips/at86rf215/radio.h +++ /dev/null @@ -1,98 +0,0 @@ -#ifndef __RADIO_H -#define __RADIO_H - -/** -\addtogroup BSP -\{ -\addtogroup radio -\{ - -\brief Cross-platform declaration "radio" bsp module. - -\author Thomas Watteyne , February 2012. -*/ - -/* -\modifications to implement the IEEE 802.15.4-SUN -\done by Jonathan Munoz -*/ - -#include "at86rf215.h" - -//=========================== define ========================================== - -#define LENGTH_CRC 2 - -//=========================== typedef ========================================= - -/** -\brief Current state of the radio. - -\note This radio driver is very minimal in that it does not follow a state machine. - It is up to the MAC layer to ensure that the different radio operations - are called in the righr order. The radio keeps a state for debugging purposes only. -*/ -typedef enum { - RADIOSTATE_STOPPED = 0x00, ///< Completely stopped. - RADIOSTATE_RFOFF = 0x01, ///< Listening for commands, but RF chain is off. - RADIOSTATE_SETTING_FREQUENCY = 0x02, ///< Configuring the frequency. - RADIOSTATE_FREQUENCY_SET = 0x03, ///< Done configuring the frequency. - RADIOSTATE_LOADING_PACKET = 0x04, ///< Loading packet into the radio's TX buffer. - RADIOSTATE_PACKET_LOADED = 0x05, ///< Packet is fully loaded in the radio's TX buffer. - RADIOSTATE_ENABLING_TX = 0x06, ///< The RF TX chaing is being enabled (includes locking the PLL). - RADIOSTATE_TX_ENABLED = 0x07, ///< Radio ready to transmit. - RADIOSTATE_TRANSMITTING = 0x08, ///< Busy transmitting bytes. - RADIOSTATE_ENABLING_RX = 0x09, ///< The RF RX chain is being enabled (includes locking the PLL). - RADIOSTATE_LISTENING = 0x0a, ///< RF chain is on, listening, but no packet received yet. - RADIOSTATE_RECEIVING = 0x0b, ///< Busy receiving bytes. - RADIOSTATE_TXRX_DONE = 0x0c, ///< Frame has been sent/received completely. - RADIOSTATE_TURNING_OFF = 0x0d, ///< Turning the RF chain off. -} radio_state_t; - -typedef enum { - FREQ_TX = 0x01, - FREQ_RX = 0x02, -} radio_freq_t; - -typedef void (*radio_capture_cbt)(PORT_TIMER_WIDTH timestamp); - -//=========================== variables ======================================= - -//=========================== prototypes ====================================== - -// admin -void radio_powerOn(void); -void radio_init(void); -void radio_setStartFrameCb(radio_capture_cbt cb); -void radio_setEndFrameCb(radio_capture_cbt cb); -// reset -void radio_reset(void); -// RF admin -void radio_setFrequency(uint16_t channel, radio_freq_t tx_or_rx); -void radio_rfOn(void); -void radio_rfOff(void); -void radio_change_modulation(registerSetting_t * mod); -void radio_change_size(uint16_t* size); -// TX -void radio_loadPacket(uint8_t* packet, uint16_t len); -void radio_txEnable(void); -void radio_txNow(void); -// RX -void radio_rxEnable(void); -void radio_rxNow(void); -void radio_getReceivedFrame(uint8_t* bufRead, - uint16_t* lenRead, - uint16_t maxBufLen, - int8_t* rssi, - uint8_t* lqi, - bool* crc); - -// interrupt handlers -void radio_isr(void); - -/** -\} -\} -*/ - -#endif diff --git a/bsp/chips/at86rf215/radio.c b/bsp/chips/at86rf215/radio_at86rf215.c similarity index 52% rename from bsp/chips/at86rf215/radio.c rename to bsp/chips/at86rf215/radio_at86rf215.c index 1171388777..e713a8dde9 100644 --- a/bsp/chips/at86rf215/radio.c +++ b/bsp/chips/at86rf215/radio_at86rf215.c @@ -2,16 +2,17 @@ \brief at86rf215-specific definition of the "radio" bsp module. \author Jonathan Munoz , July 2016. -*/ +Modified by Mina Rady +*/ #include "board.h" -#include "radio.h" #include "spi.h" #include "debugpins.h" #include "leds.h" #include "sctimer.h" + #include #include #include @@ -23,6 +24,11 @@ #include #include +#include "radio.h" +#include "radio_at86rf215.h" +#include "at86rf215.h" + + #define AT86RF215_IRQ_BASE ( GPIO_D_BASE ) #define AT86RF215_IRQ_PIN ( GPIO_PIN_0 ) #define AT86RF215_IRQ_IOC ( IOC_OVERRIDE_DIS ) @@ -43,28 +49,20 @@ #define ATMEL_FREQUENCY_TYPE FREQ_SUGHZ #endif -//=========================== variables ======================================= +//=========================== variables ========================================== +radio_vars_at86rf215_t radio_vars_at86rf215; -typedef struct { - radio_capture_cbt startFrame_cb; - radio_capture_cbt endFrame_cb; - radio_state_t state; - uint8_t rf09_isr; - uint8_t rf24_isr; - uint8_t bb0_isr; - uint8_t bb1_isr; -} radio_vars_t; - -radio_vars_t radio_vars; +// open radio register mapping: an array of pointers to registersettings arrays +radio_config_t radio_api; //=========================== public ========================================== -static void radio_read_isr(void); -static void radio_clear_isr(void); +static void radio_read_isr_at86rf215(void); +static void radio_clear_isr_at86rf215(void); //===== admin -void radio_powerOn(void) { +void radio_powerOn_at86rf215(void) { volatile uint32_t delay; GPIOPinTypeGPIOOutput(GPIO_C_BASE, GPIO_PIN_0); @@ -84,32 +82,31 @@ void radio_powerOn(void) { } -void radio_reset(void) { +void radio_reset_at86rf215(void) { at86rf215_spiWriteReg( RG_RF_RST, CMD_RF_RESET); } -void radio_init(void) { - - uint16_t i; +void radio_init_at86rf215(void) { + //power it on and configure pins - radio_powerOn(); + radio_powerOn_at86rf215(); spi_init(); // clear variables - memset(&radio_vars,0,sizeof(radio_vars_t)); + memset(&radio_vars_at86rf215,0,sizeof(radio_vars_at86rf215_t)); // change state - radio_vars.state = RADIOSTATE_STOPPED; + radio_vars_at86rf215.state = RADIOSTATE_STOPPED; // reset radio - radio_reset(); + radio_reset_at86rf215(); at86rf215_spiStrobe(CMD_RF_TRXOFF, ATMEL_FREQUENCY_TYPE); while(at86rf215_status(ATMEL_FREQUENCY_TYPE) != RF_STATE_TRXOFF); // change state - radio_vars.state = RADIOSTATE_RFOFF; + radio_vars_at86rf215.state = RADIOSTATE_RFOFF; //configure external radio interrupt in pin D0 GPIOPinIntDisable(AT86RF215_IRQ_BASE, AT86RF215_IRQ_PIN); @@ -121,7 +118,7 @@ void radio_init(void) { GPIOPinIntClear(AT86RF215_IRQ_BASE, AT86RF215_IRQ_PIN); /* Register the interrupt */ - GPIOPortIntRegister(AT86RF215_IRQ_BASE, radio_isr); + GPIOPortIntRegister(AT86RF215_IRQ_BASE, radio_isr_internal_at86rf215); /* Clear and enable the interrupt */ GPIOPinIntEnable(AT86RF215_IRQ_BASE, AT86RF215_IRQ_PIN); @@ -130,28 +127,37 @@ void radio_init(void) { if ((at86rf215_spiReadReg(RG_RF_PN) != 0x34) | (at86rf215_spiReadReg(RG_RF_VN) != 0x03)) { while(1); //UNKNOWN DEVICE, FINISH } - // Write registers to radio -- configuration 2-FSK-50kbps - if (ATMEL_FREQUENCY_TYPE==FREQ_SUGHZ){ - for( i = 0; i < (sizeof(basic_settings_fsk_option1)/sizeof(registerSetting_t)); i++) { - at86rf215_spiWriteReg( basic_settings_fsk_option1[i].addr, basic_settings_fsk_option1[i].data); - }; - } else { - for( i = 0; i < (sizeof(basic_settings_oqpsk_250kbps)/sizeof(registerSetting_t)); i++) { - at86rf215_spiWriteReg( basic_settings_oqpsk_250kbps[i].addr, basic_settings_oqpsk_250kbps[i].data); - }; - } - - - radio_read_isr(); + + //Initialize the lookup table for register configurations + + radio_local_bootstrap_at86rf215(); + + // select the radio configuration to use -- configuration 2-FSK-50kbps + radio_setConfig_at86rf215 (RADIOSETTING_FSK_OPTION1_FEC); + radio_read_isr_at86rf215(); } -void radio_change_size(uint16_t* size){ +void radio_change_size_at86rf215(uint16_t* size){ static int i = 0; *size = sizes[i%4]; i++; } -void radio_change_modulation(registerSetting_t * mod){ +// This function accepts one of the existing radio presets and writes them to the radio chip. +void radio_setConfig_at86rf215(radioSetting_t radioSetting){ + uint16_t _register; + + at86rf215_spiStrobe(CMD_RF_TRXOFF, ATMEL_FREQUENCY_TYPE); + while(at86rf215_status(ATMEL_FREQUENCY_TYPE) != RF_STATE_TRXOFF); + + for( _register = 0; _register < radio_api.size[radioSetting]; _register++) { + at86rf215_spiWriteReg(radio_api.radios[radioSetting][_register].addr, radio_api.radios[radioSetting][_register].data); + }; + radio_read_isr_at86rf215(); +} + +// This function writes a specific set of register values to customize the configuration of the radio chip +void radio_change_modulation_at86rf215(registerSetting_t * mod){ static int mod_list = 1; uint16_t i; @@ -161,23 +167,23 @@ void radio_change_modulation(registerSetting_t * mod){ for( i = 0; i < (sizeof(*mod)/sizeof(registerSetting_t)); i++) { at86rf215_spiWriteReg( mod[i].addr, mod[i].data); }; - radio_read_isr(); + radio_read_isr_at86rf215(); mod_list++; } -void radio_setStartFrameCb(radio_capture_cbt cb) { - radio_vars.startFrame_cb = cb; +void radio_setStartFrameCb_at86rf215(radio_capture_cbt cb) { + radio_vars_at86rf215.startFrame_cb = cb; } -void radio_setEndFrameCb(radio_capture_cbt cb) { - radio_vars.endFrame_cb = cb; +void radio_setEndFrameCb_at86rf215(radio_capture_cbt cb) { + radio_vars_at86rf215.endFrame_cb = cb; } //===== RF admin //channel spacing in KHz //frequency_0 in kHz //frequency_nb integer -void radio_setFrequency(uint16_t channel, radio_freq_t tx_or_rx) { +void radio_setFrequency_at86rf215(uint8_t channel, radio_freq_t tx_or_rx) { uint16_t frequency_0; @@ -191,8 +197,8 @@ void radio_setFrequency(uint16_t channel, radio_freq_t tx_or_rx) { at86rf215_spiWriteReg(RG_RF09_CS, (uint8_t)(DEFAULT_CHANNEL_SPACING_FSK_OPTION_1/25)); at86rf215_spiWriteReg(RG_RF09_CCF0L, (uint8_t)(frequency_0%256)); at86rf215_spiWriteReg(RG_RF09_CCF0H, (uint8_t)(frequency_0/256)); - at86rf215_spiWriteReg(RG_RF09_CNL, (uint8_t)(channel%256)); - at86rf215_spiWriteReg(RG_RF09_CNM, (uint8_t)(channel/256)); + at86rf215_spiWriteReg(RG_RF09_CNL, channel%256); + at86rf215_spiWriteReg(RG_RF09_CNM, channel/256); } else { frequency_0 = (DEFAULT_CENTER_FREQUENCY_0_OQPSK_24GHZ/25); at86rf215_spiWriteReg(RG_RF24_CS, (uint8_t)(DEFAULT_CHANNEL_SPACING_OQPSK_24GHZ/25)); @@ -203,19 +209,19 @@ void radio_setFrequency(uint16_t channel, radio_freq_t tx_or_rx) { } // change state - radio_vars.state = RADIOSTATE_FREQUENCY_SET; + radio_vars_at86rf215.state = RADIOSTATE_FREQUENCY_SET; } -void radio_rfOn(void) { +void radio_rfOn_at86rf215(void) { //put the radio in the TRXPREP state at86rf215_spiStrobe(CMD_RF_TRXOFF, ATMEL_FREQUENCY_TYPE); while(at86rf215_status(ATMEL_FREQUENCY_TYPE) != RF_STATE_TRXOFF); } -void radio_rfOff(void) { +void radio_rfOff_at86rf215(void) { // change state - radio_vars.state = RADIOSTATE_TURNING_OFF; + radio_vars_at86rf215.state = RADIOSTATE_TURNING_OFF; at86rf215_spiStrobe(CMD_RF_TRXOFF, ATMEL_FREQUENCY_TYPE); while(at86rf215_status(ATMEL_FREQUENCY_TYPE) != RF_STATE_TRXOFF); @@ -224,10 +230,10 @@ void radio_rfOff(void) { leds_radio_off(); // change state - radio_vars.state = RADIOSTATE_RFOFF; + radio_vars_at86rf215.state = RADIOSTATE_RFOFF; } -int8_t radio_getFrequencyOffset(void){ +int8_t radio_getFrequencyOffset_at86rf215(void){ // not available return 0; @@ -235,23 +241,23 @@ int8_t radio_getFrequencyOffset(void){ //===== TX -void radio_loadPacket(uint8_t* packet, uint16_t len) { +void radio_loadPacket_at86rf215(uint8_t* packet, uint16_t len) { - radio_vars.state = RADIOSTATE_LOADING_PACKET; + radio_vars_at86rf215.state = RADIOSTATE_LOADING_PACKET; at86rf215_spiWriteFifo(packet, len, ATMEL_FREQUENCY_TYPE); // change state - radio_vars.state = RADIOSTATE_PACKET_LOADED; + radio_vars_at86rf215.state = RADIOSTATE_PACKET_LOADED; //at86rf215_readBurst(0x0306, packet, len); } -radio_state_t radio_getState(void){ - return radio_vars.state; +radio_state_t radio_getState_at86rf215(void){ + return radio_vars_at86rf215.state; } -void radio_txEnable(void) { +void radio_txEnable_at86rf215(void) { // change state - radio_vars.state = RADIOSTATE_ENABLING_TX; + radio_vars_at86rf215.state = RADIOSTATE_ENABLING_TX; at86rf215_spiStrobe(CMD_RF_TXPREP, ATMEL_FREQUENCY_TYPE); while(at86rf215_status(ATMEL_FREQUENCY_TYPE) != RF_STATE_TXPREP); @@ -260,41 +266,41 @@ void radio_txEnable(void) { debugpins_radio_set(); leds_radio_on(); - radio_vars.state = RADIOSTATE_TX_ENABLED; + radio_vars_at86rf215.state = RADIOSTATE_TX_ENABLED; } -void radio_txNow(void) { +void radio_txNow_at86rf215(void) { PORT_TIMER_WIDTH capturedTime; // change state - radio_vars.state = RADIOSTATE_TRANSMITTING; + radio_vars_at86rf215.state = RADIOSTATE_TRANSMITTING; at86rf215_spiStrobe(CMD_RF_TX, ATMEL_FREQUENCY_TYPE); - if (radio_vars.startFrame_cb!=NULL) { + if (radio_vars_at86rf215.startFrame_cb!=NULL) { // capture the time capturedTime = sctimer_readCounter(); // call the callback - radio_vars.startFrame_cb(capturedTime); + radio_vars_at86rf215.startFrame_cb(capturedTime); } } //===== RX -void radio_rxEnable(void) { +void radio_rxEnable_at86rf215(void) { // change state - radio_vars.state = RADIOSTATE_ENABLING_RX; + radio_vars_at86rf215.state = RADIOSTATE_ENABLING_RX; // wiggle debug pin debugpins_radio_set(); leds_radio_on(); at86rf215_spiStrobe(CMD_RF_RX, ATMEL_FREQUENCY_TYPE); // change state - radio_vars.state = RADIOSTATE_LISTENING; + radio_vars_at86rf215.state = RADIOSTATE_LISTENING; } -void radio_rxNow(void) { +void radio_rxNow_at86rf215(void) { //nothing to do if(at86rf215_status(ATMEL_FREQUENCY_TYPE) != RF_STATE_RX){ leds_error_toggle(); @@ -302,10 +308,10 @@ void radio_rxNow(void) { } } -void radio_getReceivedFrame( +void radio_getReceivedFrame_at86rf215( uint8_t* bufRead, - uint16_t* lenRead, - uint16_t maxBufLen, + uint8_t* lenRead, + uint8_t maxBufLen, int8_t* rssi, uint8_t* lqi, bool* crc @@ -324,7 +330,7 @@ void radio_getReceivedFrame( } // read the received packet from the RXFIFO - at86rf215_spiReadRxFifo(bufRead, lenRead, ATMEL_FREQUENCY_TYPE, maxBufLen); + at86rf215_spiReadRxFifo(bufRead, (uint16_t*)lenRead, ATMEL_FREQUENCY_TYPE, maxBufLen); *rssi = at86rf215_spiReadReg(register_edv); *crc = (at86rf215_spiReadReg(register_bbc_pc)>>5); @@ -332,23 +338,48 @@ void radio_getReceivedFrame( //=========================== private ========================================= -void radio_read_isr(void){ +//This function creates a matrix of register configurations of each modulation supported by the readio chip. It is used for dynamic modulation change inside the chip. +void radio_local_bootstrap_at86rf215(void){ + + radio_api.radios [RADIOSETTING_FSK_OPTION1_FEC] = basic_settings_fsk_option1; + radio_api.radios [RADIOSETTING_OQPSK_RATE3] = basic_settings_oqpsk_rate3; + radio_api.radios [RADIOSETTING_OFDM_OPTION_1_MCS0] = basic_settings_ofdm_1_mcs0; + radio_api.radios [RADIOSETTING_OFDM_OPTION_1_MCS1] = basic_settings_ofdm_1_mcs1; + radio_api.radios [RADIOSETTING_OFDM_OPTION_1_MCS2] = basic_settings_ofdm_1_mcs2; + radio_api.radios [RADIOSETTING_OFDM_OPTION_1_MCS3] = basic_settings_ofdm_1_mcs3; + + radio_api.size [RADIOSETTING_FSK_OPTION1_FEC] = sizeof(basic_settings_fsk_option1)/sizeof(registerSetting_t); + radio_api.size [RADIOSETTING_OQPSK_RATE3] = sizeof(basic_settings_oqpsk_rate3)/sizeof(registerSetting_t); + radio_api.size [RADIOSETTING_OFDM_OPTION_1_MCS0] = sizeof(basic_settings_ofdm_1_mcs0)/sizeof(registerSetting_t); + radio_api.size [RADIOSETTING_OFDM_OPTION_1_MCS1] = sizeof(basic_settings_ofdm_1_mcs1)/sizeof(registerSetting_t); + radio_api.size [RADIOSETTING_OFDM_OPTION_1_MCS2] = sizeof(basic_settings_ofdm_1_mcs2)/sizeof(registerSetting_t); + radio_api.size [RADIOSETTING_OFDM_OPTION_1_MCS3] = sizeof(basic_settings_ofdm_1_mcs3)/sizeof(registerSetting_t); +} +void radio_read_isr_at86rf215(void){ uint8_t flags[4]; at86rf215_read_isr(flags, ATMEL_FREQUENCY_TYPE); - radio_vars.rf09_isr = flags[0]; - radio_vars.rf24_isr = flags[1]; - radio_vars.bb0_isr = flags[2]; - radio_vars.bb1_isr = flags[3]; + radio_vars_at86rf215.rf09_isr = flags[0]; + radio_vars_at86rf215.rf24_isr = flags[1]; + radio_vars_at86rf215.bb0_isr = flags[2]; + radio_vars_at86rf215.bb1_isr = flags[3]; } + //=========================== callbacks ======================================= //=========================== interrupt handlers ============================== -void radio_isr(void) { + +// Wrapper function for radio_isr_at86rf215 to be called by the radio interrupt +void radio_isr_internal_at86rf215(void) { + + kick_scheduler_t ks = radio_isr_at86rf215(); + +} +kick_scheduler_t radio_isr_at86rf215(void) { PORT_TIMER_WIDTH capturedTime; - // kick_scheduler_t result = DO_NOT_KICK_SCHEDULER; + kick_scheduler_t result = DO_NOT_KICK_SCHEDULER; debugpins_isr_set(); @@ -357,50 +388,52 @@ void radio_isr(void) { // capture the time capturedTime = sctimer_readCounter(); //get isr that happened from radio - radio_read_isr(); + radio_read_isr_at86rf215(); - if (radio_vars.bb0_isr & IRQS_RXFS_MASK){ - radio_vars.state = RADIOSTATE_RECEIVING; - if (radio_vars.startFrame_cb!=NULL) { + if (radio_vars_at86rf215.bb0_isr & IRQS_RXFS_MASK){ + radio_vars_at86rf215.state = RADIOSTATE_RECEIVING; + if (radio_vars_at86rf215.startFrame_cb!=NULL) { // call the callback - radio_vars.startFrame_cb(capturedTime); + radio_vars_at86rf215.startFrame_cb(capturedTime); // kick the OS - // result = KICK_SCHEDULER; + result = KICK_SCHEDULER; } else { //while(1); } } else { - if ((radio_vars.bb0_isr & IRQS_TXFE_MASK)){ - radio_vars.state = RADIOSTATE_TXRX_DONE; - if (radio_vars.endFrame_cb!=NULL) { + if ((radio_vars_at86rf215.bb0_isr & IRQS_TXFE_MASK)){ + radio_vars_at86rf215.state = RADIOSTATE_TXRX_DONE; + if (radio_vars_at86rf215.endFrame_cb!=NULL) { // call the callback - radio_vars.endFrame_cb(capturedTime); + radio_vars_at86rf215.endFrame_cb(capturedTime); // kick the OS - // result = KICK_SCHEDULER; + result = KICK_SCHEDULER; } else { //while(1); } } else { - if ((radio_vars.bb0_isr & IRQS_RXFE_MASK)){ - radio_vars.state = RADIOSTATE_TXRX_DONE; - if (radio_vars.endFrame_cb!=NULL) { + if ((radio_vars_at86rf215.bb0_isr & IRQS_RXFE_MASK)){ + radio_vars_at86rf215.state = RADIOSTATE_TXRX_DONE; + if (radio_vars_at86rf215.endFrame_cb!=NULL) { // call the callback - radio_vars.endFrame_cb(capturedTime); + radio_vars_at86rf215.endFrame_cb(capturedTime); + // kick the OS - //result = KICK_SCHEDULER; + result = KICK_SCHEDULER; } else { // while(1); } } } } - radio_clear_isr(); + radio_clear_isr_at86rf215(); debugpins_isr_clr(); + return result; } -port_INLINE void radio_clear_isr(){ - radio_vars.rf09_isr = 0; - radio_vars.rf24_isr = 0; - radio_vars.bb0_isr = 0; - radio_vars.bb1_isr = 0; +port_INLINE void radio_clear_isr_at86rf215(){ + radio_vars_at86rf215.rf09_isr = 0; + radio_vars_at86rf215.rf24_isr = 0; + radio_vars_at86rf215.bb0_isr = 0; + radio_vars_at86rf215.bb1_isr = 0; } diff --git a/bsp/chips/at86rf215/radio_at86rf215.h b/bsp/chips/at86rf215/radio_at86rf215.h new file mode 100644 index 0000000000..b687ec7d1f --- /dev/null +++ b/bsp/chips/at86rf215/radio_at86rf215.h @@ -0,0 +1,96 @@ +#ifndef __RADIO_AT86RF215_H +#define __RADIO_AT86RF215_H + +/** +\addtogroup BSP +\{ +\addtogroup radio +\{ + +\brief Cross-platform declaration "radio" bsp module. + +\author Thomas Watteyne , February 2012. +*/ + +/* +\modifications to implement the IEEE 802.15.4-SUN +\done by Jonathan Munoz +*/ + +#include "radio.h" +#include "at86rf215.h" + +//=========================== define ========================================== + +// Number of modulations available on this radio chip. This is different from MAC_RADIOS which is for all the board and defined in board_info.h +#define MAX_MODULATIONS 6 + +//=========================== typedef ========================================= + + +typedef struct { + radio_capture_cbt startFrame_cb; + radio_capture_cbt endFrame_cb; + radio_state_t state; + uint8_t rf09_isr; + uint8_t rf24_isr; + uint8_t bb0_isr; + uint8_t bb1_isr; +} radio_vars_at86rf215_t; + + + + +// open radio register mapping: an array of pointers to registersettings arrays + +typedef struct { + registerSetting_t * radios [MAX_MODULATIONS]; + size_t size [MAX_MODULATIONS]; +} radio_config_t; + + +//=========================== variables ======================================= + +//=========================== prototypes ====================================== + +// admin +void radio_powerOn_at86rf215(void); +void radio_init_at86rf215(void); +void radio_setStartFrameCb_at86rf215(radio_capture_cbt cb); +void radio_setEndFrameCb_at86rf215(radio_capture_cbt cb); +// reset +void radio_reset_at86rf215(void); +// RF admin +void radio_setFrequency_at86rf215(uint8_t channel, radio_freq_t tx_or_rx); +int8_t radio_getFrequencyOffset_at86rf215(void); +void radio_rfOn_at86rf215(void); +void radio_rfOff_at86rf215(void); +void radio_setConfig_at86rf215 (radioSetting_t radioSetting); +void radio_change_modulation_at86rf215(registerSetting_t * mod); +void radio_change_size_at86rf215(uint16_t* size); +// TX +void radio_loadPacket_at86rf215(uint8_t* packet, uint16_t len); +radio_state_t radio_getState_at86rf215(void); +void radio_txEnable_at86rf215(void); +void radio_txNow_at86rf215(void); +// RX +void radio_rxEnable_at86rf215(void); +void radio_rxNow_at86rf215(void); +void radio_getReceivedFrame_at86rf215(uint8_t* bufRead, + uint8_t* lenRead, + uint8_t maxBufLen, + int8_t* rssi, + uint8_t* lqi, + bool* crc); + +// interrupt handlers +kick_scheduler_t radio_isr_at86rf215(void); +// private +void radio_isr_internal_at86rf215(void); +void radio_local_bootstrap_at86rf215(void); +/** +\} +\} +*/ + +#endif diff --git a/bsp/chips/at86rf231/radio.c b/bsp/chips/at86rf231/radio.c index a5792ab6f6..69dbbec5fb 100644 --- a/bsp/chips/at86rf231/radio.c +++ b/bsp/chips/at86rf231/radio.c @@ -25,6 +25,9 @@ typedef struct { radio_vars_t radio_vars; +// global radio selection. +uint8_t selected_radioSetting = RADIOSETTING_24GHZ; + //=========================== prototypes ====================================== void radio_spiWriteReg(uint8_t reg_addr, uint8_t reg_setting); @@ -86,6 +89,10 @@ void radio_reset(void) { //===== RF admin +void radio_setConfig (radioSetting_t radioSetting){ + selected_radioSetting = radioSetting; + //do nothing +} void radio_setFrequency(uint8_t frequency, radio_freq_t tx_or_rx) { // change state radio_vars.state = RADIOSTATE_SETTING_FREQUENCY; diff --git a/bsp/chips/cc2538rf/SConscript b/bsp/chips/cc2538rf/SConscript new file mode 100644 index 0000000000..cfbcf68cfb --- /dev/null +++ b/bsp/chips/cc2538rf/SConscript @@ -0,0 +1,13 @@ +# chip support sconscripts are expected to return a list of objects, so +# that they can be included in a board bsp library. This allows the board +# to include the chip support without knowing exactly what the filenames +# are or where they live. + +Import('env') + +localEnv = env.Clone() + +source = ['radio_cc2538rf.c'] +cc2538rf = localEnv.Object(source=source) + +Return('cc2538rf') \ No newline at end of file diff --git a/bsp/chips/cc2538rf/radio_cc2538rf.c b/bsp/chips/cc2538rf/radio_cc2538rf.c new file mode 100644 index 0000000000..cf80c258d9 --- /dev/null +++ b/bsp/chips/cc2538rf/radio_cc2538rf.c @@ -0,0 +1,539 @@ +/** + * Author: Xavier Vilajosana (xvilajosana@eecs.berkeley.edu) + * Pere Tuset (peretuset@openmote.com) + * Date: July 2013 + * Description: CC2538-specific definition of the "radio" bsp module. + */ + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "board.h" +#include "debugpins.h" +#include "leds.h" +#include "radio_cc2538rf.h" +#include "radio.h" +#include "sctimer.h" + +//=========================== defines ========================================= + +/* Bit Masks for the last byte in the RX FIFO */ +#define CRC_BIT_MASK 0x80 +#define LQI_BIT_MASK 0x7F + +/* RSSI Offset */ +#define RSSI_OFFSET 73 +#define CHECKSUM_LEN 2 + +//=========================== variables ======================================= + + +radio_vars_cc2538rf_t radio_vars_cc2538rf; + +//=========================== prototypes ====================================== + +void enable_radio_interrupts(void); +void disable_radio_interrupts(void); + +void radio_on(void); +void radio_off(void); + +void radio_error_isr_cc2538rf(void); +void radio_isr_internal_cc2538rf(void); + +//=========================== public ========================================== + +//===== admin + +void radio_init_cc2538rf(void) { + + // clear variables + memset(&radio_vars_cc2538rf,0,sizeof(radio_vars_cc2538rf_t)); + + // change state + radio_vars_cc2538rf.state = RADIOSTATE_STOPPED; + //flush fifos + CC2538_RF_CSP_ISFLUSHRX(); + CC2538_RF_CSP_ISFLUSHTX(); + + radio_off(); + + //disable radio interrupts + disable_radio_interrupts(); + + /* + This CORR_THR value should be changed to 0x14 before attempting RX. Testing has shown that + too many false frames are received if the reset value is used. Make it more likely to detect + sync by removing the requirement that both symbols in the SFD must have a correlation value + above the correlation threshold, and make sync word detection less likely by raising the + correlation threshold. + */ + HWREG(RFCORE_XREG_MDMCTRL1) = 0x14; + /* tuning adjustments for optimal radio performance; details available in datasheet */ + + HWREG(RFCORE_XREG_RXCTRL) = 0x3F; + /* Adjust current in synthesizer; details available in datasheet. */ + HWREG(RFCORE_XREG_FSCTRL) = 0x55; + + /* Makes sync word detection less likely by requiring two zero symbols before the sync word. + * details available in datasheet. + */ + HWREG(RFCORE_XREG_MDMCTRL0) = 0x85; + + /* Adjust current in VCO; details available in datasheet. */ + HWREG(RFCORE_XREG_FSCAL1) = 0x01; + /* Adjust target value for AGC control loop; details available in datasheet. */ + HWREG(RFCORE_XREG_AGCCTRL1) = 0x15; + + /* Tune ADC performance, details available in datasheet. */ + HWREG(RFCORE_XREG_ADCTEST0) = 0x10; + HWREG(RFCORE_XREG_ADCTEST1) = 0x0E; + HWREG(RFCORE_XREG_ADCTEST2) = 0x03; + + //update CCA register to -81db as indicated by manual.. won't be used.. + HWREG(RFCORE_XREG_CCACTRL0) = 0xF8; + /* + * Changes from default values + * See User Guide, section "Register Settings Update" + */ + HWREG(RFCORE_XREG_TXFILTCFG) = 0x09; /** TX anti-aliasing filter bandwidth */ + HWREG(RFCORE_XREG_AGCCTRL1) = 0x15; /** AGC target value */ + HWREG(ANA_REGS_O_IVCTRL) = 0x0B; /** Bias currents */ + + /* disable the CSPT register compare function */ + HWREG(RFCORE_XREG_CSPT) = 0xFFUL; + /* + * Defaults: + * Auto CRC; Append RSSI, CRC-OK and Corr. Val.; CRC calculation; + * RX and TX modes with FIFOs + */ + HWREG(RFCORE_XREG_FRMCTRL0) = RFCORE_XREG_FRMCTRL0_AUTOCRC; + + //poipoi disable frame filtering by now.. sniffer mode. + HWREG(RFCORE_XREG_FRMFILT0) &= ~RFCORE_XREG_FRMFILT0_FRAME_FILTER_EN; + + /* Disable source address matching and autopend */ + HWREG(RFCORE_XREG_SRCMATCH) = 0; + + /* MAX FIFOP threshold */ + HWREG(RFCORE_XREG_FIFOPCTRL) = CC2538_RF_MAX_PACKET_LEN; + + HWREG(RFCORE_XREG_TXPOWER) = CC2538_RF_TX_POWER; + HWREG(RFCORE_XREG_FREQCTRL) = CC2538_RF_CHANNEL_MIN; + + /* Enable RF interrupts see page 751 */ + // enable_radio_interrupts(); + + //register interrupt + IntRegister(INT_RFCORERTX, radio_isr_internal_cc2538rf); + IntRegister(INT_RFCOREERR, radio_error_isr_cc2538rf); + + IntEnable(INT_RFCORERTX); + + /* Enable all RF Error interrupts */ + HWREG(RFCORE_XREG_RFERRM) = RFCORE_XREG_RFERRM_RFERRM_M; //all errors + IntEnable(INT_RFCOREERR); + //radio_on(); + + // change state + radio_vars_cc2538rf.state = RADIOSTATE_RFOFF; +} + +void radio_setStartFrameCb_cc2538rf(radio_capture_cbt cb) { + radio_vars_cc2538rf.startFrame_cb = cb; +} + +void radio_setEndFrameCb_cc2538rf(radio_capture_cbt cb) { + radio_vars_cc2538rf.endFrame_cb = cb; +} + +//===== reset + +void radio_reset_cc2538rf(void) { + /* Wait for ongoing TX to complete (e.g. this could be an outgoing ACK) */ + while(HWREG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_TX_ACTIVE); + + //flush fifos + CC2538_RF_CSP_ISFLUSHRX(); + CC2538_RF_CSP_ISFLUSHTX(); + + /* Don't turn off if we are off as this will trigger a Strobe Error */ + if(HWREG(RFCORE_XREG_RXENABLE) != 0) { + CC2538_RF_CSP_ISRFOFF(); + } + radio_init(); +} + +//===== RF admin + +void radio_setFrequency_cc2538rf(uint8_t frequency, radio_freq_t tx_or_rx) { + + // change state + radio_vars_cc2538rf.state = RADIOSTATE_SETTING_FREQUENCY; + + radio_off(); + // configure the radio to the right frequecy + if((frequency < CC2538_RF_CHANNEL_MIN) || (frequency > CC2538_RF_CHANNEL_MAX)) { + while(1); + } + + /* Changes to FREQCTRL take effect after the next recalibration */ + HWREG(RFCORE_XREG_FREQCTRL) = (CC2538_RF_CHANNEL_MIN + + (frequency - CC2538_RF_CHANNEL_MIN) * CC2538_RF_CHANNEL_SPACING); + + //radio_on(); + + // change state + radio_vars_cc2538rf.state = RADIOSTATE_FREQUENCY_SET; +} + +void radio_setConfig_cc2538rf(radioSetting_t radioSetting){ + // do nothing +} + +void radio_rfOn_cc2538rf(void) { + //radio_on(); +} + +void radio_rfOff_cc2538rf(void) { + + // change state + radio_vars_cc2538rf.state = RADIOSTATE_TURNING_OFF; + radio_off(); + // wiggle debug pin + debugpins_radio_clr(); + leds_radio_off(); + //enable radio interrupts + disable_radio_interrupts(); + + // change state + radio_vars_cc2538rf.state = RADIOSTATE_RFOFF; +} + +int8_t radio_getFrequencyOffset_cc2538rf(void){ + + int8_t freq_offset; + + freq_offset = HWREG(RFCORE_XREG_FREQEST); + + return freq_offset; +} + +//===== TX + +void radio_loadPacket_cc2538rf(uint8_t* packet, uint16_t len) { + uint8_t i=0; + + // change state + radio_vars_cc2538rf.state = RADIOSTATE_LOADING_PACKET; + + // load packet in TXFIFO + /* + When we transmit in very quick bursts, make sure previous transmission + is not still in progress before re-writing to the TX FIFO + */ + while(HWREG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_TX_ACTIVE); + + CC2538_RF_CSP_ISFLUSHTX(); + + /* Send the phy length byte first */ + HWREG(RFCORE_SFR_RFDATA) = len; //crc len is included + + for(i = 0; i < len; i++) { + HWREG(RFCORE_SFR_RFDATA) = packet[i]; + } + + // change state + radio_vars_cc2538rf.state = RADIOSTATE_PACKET_LOADED; +} + +void radio_txEnable_cc2538rf(void) { + + // change state + radio_vars_cc2538rf.state = RADIOSTATE_ENABLING_TX; + + // wiggle debug pin + debugpins_radio_set(); + leds_radio_on(); + + //do nothing -- radio is activated by the strobe on rx or tx + //radio_rfOn(); + + // change state + radio_vars_cc2538rf.state = RADIOSTATE_TX_ENABLED; +} + +void radio_txNow_cc2538rf(void) { + PORT_TIMER_WIDTH count; + + // change state + radio_vars_cc2538rf.state = RADIOSTATE_TRANSMITTING; + + //enable radio interrupts + enable_radio_interrupts(); + + //make sure we are not transmitting already + while(HWREG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_TX_ACTIVE); + + // send packet by STON strobe see pag 669 + + CC2538_RF_CSP_ISTXON(); + //wait 192uS + count=0; + while(!((HWREG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_TX_ACTIVE))){ + count++; //debug + } +} + +//===== RX + +void radio_rxEnable_cc2538rf(void) { + + // change state + radio_vars_cc2538rf.state = RADIOSTATE_ENABLING_RX; + + //enable radio interrupts + + // do nothing as we do not want to receive anything yet. + // wiggle debug pin + debugpins_radio_set(); + leds_radio_on(); + + // change state + radio_vars_cc2538rf.state = RADIOSTATE_LISTENING; +} + +void radio_rxNow_cc2538rf(void) { + //empty buffer before receiving + //CC2538_RF_CSP_ISFLUSHRX(); + + //enable radio interrupts + CC2538_RF_CSP_ISFLUSHRX(); + enable_radio_interrupts(); + + CC2538_RF_CSP_ISRXON(); + // busy wait until radio really listening + while(!((HWREG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_RX_ACTIVE))); +} + +void radio_getReceivedFrame_cc2538rf(uint8_t* pBufRead, + uint8_t* pLenRead, + uint8_t maxBufLen, + int8_t* pRssi, + uint8_t* pLqi, + bool* pCrc) { + uint8_t crc_corr,i; + + uint8_t len=0; + + /* Check the length */ + len = HWREG(RFCORE_SFR_RFDATA); //first byte is len + + + /* Check for validity */ + if(len > CC2538_RF_MAX_PACKET_LEN) { + /* wrong len */ + CC2538_RF_CSP_ISFLUSHRX(); + return; + } + + + if(len < CC2538_RF_MIN_PACKET_LEN) { + //too short + CC2538_RF_CSP_ISFLUSHRX(); + return; + } + + //check if this fits to the buffer + if(len > maxBufLen) { + CC2538_RF_CSP_ISFLUSHRX(); + return; + } + + // when reading the packet from the RX buffer, you get the following: + // - *[1B] length byte + // - [0-125B] packet (excluding CRC) + // - [1B] RSSI + // - *[2B] CRC + + //skip first byte is len + for(i = 0; i < len - 2; i++) { + pBufRead[i] = HWREG(RFCORE_SFR_RFDATA); + } + + *pRssi = ((int8_t)(HWREG(RFCORE_SFR_RFDATA)) - RSSI_OFFSET); + crc_corr = HWREG(RFCORE_SFR_RFDATA); + *pCrc = crc_corr & CRC_BIT_MASK; + *pLenRead = len; + + //flush it + CC2538_RF_CSP_ISFLUSHRX(); +} + +//=========================== private ========================================= + +void enable_radio_interrupts(void){ + /* Enable RF interrupts 0, RXPKTDONE,SFD,FIFOP only -- see page 751 */ + HWREG(RFCORE_XREG_RFIRQM0) |= ((0x06|0x02|0x01) << RFCORE_XREG_RFIRQM0_RFIRQM_S) & RFCORE_XREG_RFIRQM0_RFIRQM_M; + + /* Enable RF interrupts 1, TXDONE only */ + HWREG(RFCORE_XREG_RFIRQM1) |= ((0x02) << RFCORE_XREG_RFIRQM1_RFIRQM_S) & RFCORE_XREG_RFIRQM1_RFIRQM_M; +} + +void disable_radio_interrupts(void){ + /* Enable RF interrupts 0, RXPKTDONE,SFD,FIFOP only -- see page 751 */ + HWREG(RFCORE_XREG_RFIRQM0) = 0; + /* Enable RF interrupts 1, TXDONE only */ + HWREG(RFCORE_XREG_RFIRQM1) = 0; +} + +void radio_on(void){ + // CC2538_RF_CSP_ISFLUSHRX(); + CC2538_RF_CSP_ISRXON(); +} + +void radio_off(void){ + /* Wait for ongoing TX to complete (e.g. this could be an outgoing ACK) */ + while(HWREG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_TX_ACTIVE); + //CC2538_RF_CSP_ISFLUSHRX(); + + /* Don't turn off if we are off as this will trigger a Strobe Error */ + if(HWREG(RFCORE_XREG_RXENABLE) != 0) { + CC2538_RF_CSP_ISRFOFF(); + //clear fifo isr flag + HWREG(RFCORE_SFR_RFIRQF0) = ~(RFCORE_SFR_RFIRQF0_FIFOP|RFCORE_SFR_RFIRQF0_RXPKTDONE); + } +} + +//=========================== callbacks ======================================= + +//=========================== interrupt handlers ============================== + +/** +\brief Stub function for the CC2538. + +In MSP430 platforms the CPU status after servicing an interrupt can be managed +toggling some bits in a special register, e.g. CPUOFF, LPM1, etc, within the +interrupt context itself. By default, after servicing an interrupt the CPU will +be off so it makes sense to return a value and enable it if something has +happened that needs the scheduler to run (a packet has been received that needs +to be processed). Otherwise, the CPU is kept in sleep mode without even +reaching the main loop. + +In the CC2538, however, the default behaviour is the contrary. After servicing +an interrupt the CPU will be on by default and it is the responsability of the +main thread to put it back to sleep (which is already done). This means that +the scheduler will always be kicked in after servicing an interrupt. This +behaviour can be changed by modifying the SLEEPEXIT field in the SYSCTRL +regiser (see page 131 of the CC2538 manual). +*/ +kick_scheduler_t radio_isr_cc2538rf(void) { + return DO_NOT_KICK_SCHEDULER; +} + +void radio_isr_internal_cc2538rf(void) { + volatile PORT_TIMER_WIDTH capturedTime; + uint8_t irq_status0,irq_status1; + + debugpins_isr_set(); + + // capture the time + capturedTime = sctimer_readCounter(); + + // reading IRQ_STATUS + irq_status0 = HWREG(RFCORE_SFR_RFIRQF0); + irq_status1 = HWREG(RFCORE_SFR_RFIRQF1); + + IntPendClear(INT_RFCORERTX); + + //clear interrupt + HWREG(RFCORE_SFR_RFIRQF0) = 0; + HWREG(RFCORE_SFR_RFIRQF1) = 0; + + //STATUS0 Register + // start of frame event + if ((irq_status0 & RFCORE_SFR_RFIRQF0_SFD) == RFCORE_SFR_RFIRQF0_SFD) { + // change state + radio_vars_cc2538rf.state = RADIOSTATE_RECEIVING; + if (radio_vars_cc2538rf.startFrame_cb!=NULL) { + // call the callback + radio_vars_cc2538rf.startFrame_cb(capturedTime); + debugpins_isr_clr(); + // kick the OS + return; + } else { + while(1); + } + } + + //or RXDONE is full -- we have a packet. + if (((irq_status0 & RFCORE_SFR_RFIRQF0_RXPKTDONE) == RFCORE_SFR_RFIRQF0_RXPKTDONE)) { + // change state + radio_vars_cc2538rf.state = RADIOSTATE_TXRX_DONE; + if (radio_vars_cc2538rf.endFrame_cb!=NULL) { + // call the callback + radio_vars_cc2538rf.endFrame_cb(capturedTime); + debugpins_isr_clr(); + // kick the OS + return; + } else { + while(1); + } + } + + // or FIFOP is full -- we have a packet. + if (((irq_status0 & RFCORE_SFR_RFIRQF0_FIFOP) == RFCORE_SFR_RFIRQF0_FIFOP)) { + // change state + radio_vars_cc2538rf.state = RADIOSTATE_TXRX_DONE; + if (radio_vars_cc2538rf.endFrame_cb!=NULL) { + // call the callback + radio_vars_cc2538rf.endFrame_cb(capturedTime); + debugpins_isr_clr(); + // kick the OS + return; + } else { + while(1); + } + } + + //STATUS1 Register + // end of frame event --either end of tx . + if (((irq_status1 & RFCORE_SFR_RFIRQF1_TXDONE) == RFCORE_SFR_RFIRQF1_TXDONE)) { + // change state + radio_vars_cc2538rf.state = RADIOSTATE_TXRX_DONE; + if (radio_vars_cc2538rf.endFrame_cb!=NULL) { + // call the callback + radio_vars_cc2538rf.endFrame_cb(capturedTime); + debugpins_isr_clr(); + // kick the OS + return; + } else { + while(1); + } + } + debugpins_isr_clr(); + + return; +} + +void radio_error_isr_cc2538rf(void){ + uint8_t rferrm; + + rferrm = (uint8_t)HWREG(RFCORE_XREG_RFERRM); + + if ((HWREG(RFCORE_XREG_RFERRM) & (((0x02)< +#include +#include "radio.h" +/*--------------------------------------------------------------------------- + * RF Config + *---------------------------------------------------------------------------*/ +/* Constants */ +#define CC2538_RF_CCA_THRES_USER_GUIDE 0xF8 +/** Tx Power register + dbm - value +{ 7, 0xFF }, +{ 5, 0xED }, +{ 3, 0xD5 }, +{ 1, 0xC5 }, +{ 0, 0xB6 }, +{ -1, 0xB0 }, +{ -3, 0xA1 }, +{ -5, 0x91 }, +{ -7, 0x88 }, +{ -9, 0x72 }, +{-11, 0x62 }, +{-13, 0x58 }, +{-15, 0x42 }, +{-24, 0x00 }, +*/ +#define CC2538_RF_TX_POWER_RECOMMENDED 0xFF // use 7dbm maxmium txpower +#define CC2538_RF_CHANNEL_MIN 11 // poipoi -- in fact is sending on 0x17 check that. +#define CC2538_RF_CHANNEL_MAX 26 +#define CC2538_RF_CHANNEL_SPACING 5 +#define CC2538_RF_MAX_PACKET_LEN 127 +#define CC2538_RF_MIN_PACKET_LEN 4 +#define CC2538_RF_CCA_CLEAR 1 +#define CC2538_RF_CCA_BUSY 0 + + + +/*---------------------------------------------------------------------------*/ +#ifdef CC2538_RF_CONF_TX_POWER +#define CC2538_RF_TX_POWER CC2538_RF_CONF_TX_POWER +#else +#define CC2538_RF_TX_POWER CC2538_RF_TX_POWER_RECOMMENDED +#endif /* CC2538_RF_CONF_TX_POWER */ + + +#ifdef CC2538_RF_CONF_CHANNEL +#define CC2538_RF_CHANNEL CC2538_RF_CONF_CHANNEL +#else +#define CC2538_RF_CHANNEL CC2538_RF_CHANNEL_MIN +#endif /* CC2538_RF_CONF_CHANNEL */ + +#ifdef CC2538_RF_CONF_AUTOACK +#define CC2538_RF_AUTOACK CC2538_RF_CONF_AUTOACK +#else +#define CC2538_RF_AUTOACK 1 +#endif /* CC2538_RF_CONF_AUTOACK */ +/*--------------------------------------------------------------------------- + * Command Strobe Processor + *---------------------------------------------------------------------------*/ +/* OPCODES */ +#define CC2538_RF_CSP_OP_ISRXON 0xE3 +#define CC2538_RF_CSP_OP_ISTXON 0xE9 +#define CC2538_RF_CSP_OP_ISTXONCCA 0xEA +#define CC2538_RF_CSP_OP_ISRFOFF 0xEF +#define CC2538_RF_CSP_OP_ISFLUSHRX 0xED +#define CC2538_RF_CSP_OP_ISFLUSHTX 0xEE + +/** + * \brief Send an RX ON command strobe to the CSP + */ +#define CC2538_RF_CSP_ISRXON() \ + do { HWREG(RFCORE_SFR_RFST) = CC2538_RF_CSP_OP_ISRXON; } while(0) + +/** + * \brief Send a TX ON command strobe to the CSP + */ +#define CC2538_RF_CSP_ISTXON() \ + do { HWREG(RFCORE_SFR_RFST) = CC2538_RF_CSP_OP_ISTXON; } while(0) + +/** + * \brief Send a RF OFF command strobe to the CSP + */ +#define CC2538_RF_CSP_ISRFOFF() \ + do { HWREG(RFCORE_SFR_RFST) = CC2538_RF_CSP_OP_ISRFOFF; } while(0) + +/** + * \brief Flush the RX FIFO + */ +#define CC2538_RF_CSP_ISFLUSHRX() do { \ + HWREG(RFCORE_SFR_RFST) = CC2538_RF_CSP_OP_ISFLUSHRX; \ + HWREG(RFCORE_SFR_RFST) = CC2538_RF_CSP_OP_ISFLUSHRX; \ +} while(0) + +/** + * \brief Flush the TX FIFO + */ +#define CC2538_RF_CSP_ISFLUSHTX() do { \ + HWREG(RFCORE_SFR_RFST) = CC2538_RF_CSP_OP_ISFLUSHTX; \ + HWREG(RFCORE_SFR_RFST) = CC2538_RF_CSP_OP_ISFLUSHTX; \ +} while(0) +/*---------------------------------------------------------------------------*/ +typedef struct { + radio_capture_cbt startFrame_cb; + radio_capture_cbt endFrame_cb; + radio_state_t state; +} radio_vars_cc2538rf_t; + +//=========================== variables ======================================= + +//=========================== prototypes ====================================== + +// admin +void radio_init_cc2538rf(void); +void radio_setStartFrameCb_cc2538rf(radio_capture_cbt cb); +void radio_setEndFrameCb_cc2538rf(radio_capture_cbt cb); +// reset +void radio_reset_cc2538rf(void); +// RF admin +void radio_setFrequency_cc2538rf(uint8_t channel, radio_freq_t tx_or_rx); +int8_t radio_getFrequencyOffset_cc2538rf(void); +void radio_rfOn_cc2538rf(void); +void radio_rfOff_cc2538rf(void); +void radio_setConfig_cc2538rf (radioSetting_t radioSetting); + +// TX +void radio_loadPacket_cc2538rf(uint8_t* packet, uint16_t len); +void radio_txEnable_cc2538rf(void); +void radio_txNow_cc2538rf(void); +// RX +void radio_rxEnable_cc2538rf(void); +void radio_rxNow_cc2538rf(void); +void radio_getReceivedFrame_cc2538rf(uint8_t* bufRead, + uint8_t* lenRead, + uint8_t maxBufLen, + int8_t* rssi, + uint8_t* lqi, + bool* crc); + +// interrupt handlers +kick_scheduler_t radio_isr_cc2538rf(void); + +/** +\} +\} +*/ + + +#endif /* RADIO_CC2538RF_H_ */ diff --git a/drivers/common/opentimers.h b/drivers/common/opentimers.h index 763035e420..fdffaa6c32 100644 --- a/drivers/common/opentimers.h +++ b/drivers/common/opentimers.h @@ -8,7 +8,7 @@ #define __OPENTIMERS_H #include "opendefs.h" - +#include "board.h" /** \addtogroup drivers \{ @@ -32,7 +32,8 @@ #define TIMER_NUMBER_NON_GENERAL 2 #define SPLITE_TIMER_DURATION 15 // in ticks -#define PRE_CALL_TIMER_WINDOW PORT_TsSlotDuration + +#define PRE_CALL_TIMER_WINDOW board_getSlotDuration() typedef void (*opentimers_cbt)(opentimers_id_t id); diff --git a/openstack/02a-MAClow/IEEE802154E.c b/openstack/02a-MAClow/IEEE802154E.c index 70017ab7d9..03bb1ec532 100644 --- a/openstack/02a-MAClow/IEEE802154E.c +++ b/openstack/02a-MAClow/IEEE802154E.c @@ -26,9 +26,14 @@ ieee154e_vars_t ieee154e_vars; ieee154e_stats_t ieee154e_stats; ieee154e_dbg_t ieee154e_dbg; +slotTemplate_t slotTemplate; +slot_154e_vars_t slot_154e_vars [MAX_SLOT_TYPES]; //=========================== prototypes ====================================== +// INITIALIZE +void ieee154e_slot_template_init(void); + // SYNCHRONIZING void activity_synchronize_newSlot(void); @@ -136,7 +141,6 @@ void notif_sendDone(OpenQueueEntry_t *packetSent, owerror_t error); void notif_receive(OpenQueueEntry_t *packetReceived); // statistics -void resetStats(void); void updateStats(PORT_SIGNED_INT_WIDTH timeCorrection); @@ -180,7 +184,7 @@ void ieee154e_init(void) { #endif ieee154e_vars.isAckEnabled = TRUE; ieee154e_vars.isSecurityEnabled = FALSE; - ieee154e_vars.slotDuration = TsSlotDuration; + ieee154e_vars.numOfSleepSlots = 1; // default hopping template @@ -192,9 +196,30 @@ void ieee154e_init(void) { changeIsSync(FALSE); } - resetStats(); + ieee154e_resetStats(); ieee154e_stats.numDeSync = 0; + // initialize slot template lookup table + + ieee154e_slot_template_init(); + + /* select the desired slot template to use, default is SLOT_20ms_24GHZ + currently, the following slot template/radio setting combinations are supported: + + SLOT_20ms_24GHZ , RADIOSETTING_24GHZ --> Default + SLOT_40ms_24GHZ , RADIOSETTING_24GHZ + SLOT_40ms_FSK_SUBGHZ , RADIOSETTING_FSK_OPTION1_FEC + SLOT_40ms_OFDM1MCS0_3_SUBGHZ , RADIOSETTING_OFDM_OPTION_1_MCS0 + SLOT_40ms_OFDM1MCS0_3_SUBGHZ , RADIOSETTING_OFDM_OPTION_1_MCS1 + SLOT_40ms_OFDM1MCS0_3_SUBGHZ , RADIOSETTING_OFDM_OPTION_1_MCS2 + SLOT_40ms_OFDM1MCS0_3_SUBGHZ , RADIOSETTING_OFDM_OPTION_1_MCS3 + */ + ieee154e_select_slot_template (SLOT_20ms_24GHZ); + ieee154e_vars.slotDuration = slotTemplate.slotDuration; + + //set the radio setting to use, default is RADIOSETTING_24GHZ + radio_setConfig (RADIOSETTING_24GHZ); + // switch radio on radio_rfOn(); @@ -216,6 +241,86 @@ void ieee154e_init(void) { ieee154e_vars.serialInhibitTimerId = opentimers_create(TIMER_INHIBIT, TASKPRIO_NONE); } +/** +\brief This function initializes the lookup table for the slot templates. + +Call this function once, preferrably at end of the ieee154e_init function +*/ +void ieee154e_slot_template_init(void){ + + //10ms slot + slot_154e_vars [SLOT_10ms_24GHZ].TsTxOffset = ( 2120 /PORT_US_PER_TICK ) ; // 2120us + slot_154e_vars [SLOT_10ms_24GHZ].TsLongGT = ( 1100 /PORT_US_PER_TICK ) ; // 1100us + slot_154e_vars [SLOT_10ms_24GHZ].TsTxAckDelay = ( 1000 /PORT_US_PER_TICK ) ; // 1000us + slot_154e_vars [SLOT_10ms_24GHZ].TsShortGT = ( 500 /PORT_US_PER_TICK ) ; // 500us; The standardlized value for this is 400/2=200us(7ticks). Currectly 7 doesn't work for short packet; change it back to 7 when found the problem. + slot_154e_vars [SLOT_10ms_24GHZ].wdRadioTx = ( 1342 /PORT_US_PER_TICK ) ; // 1000us (needs to be >delayTx) (SCuM need a larger value; 45 is tested and works) + slot_154e_vars [SLOT_10ms_24GHZ].wdDataDuration = ( 5000 /PORT_US_PER_TICK ) ; // 5000us (measured 4280us with max payload) + slot_154e_vars [SLOT_10ms_24GHZ].wdAckDuration = ( 3000 /PORT_US_PER_TICK ) ; // 3000us (measured 1000us) + + // 20ms slot for 24ghz cc2538 + slot_154e_vars [SLOT_20ms_24GHZ].TsTxOffset = ( 5215 /PORT_US_PER_TICK ) ; // 5215us + slot_154e_vars [SLOT_20ms_24GHZ].TsLongGT = ( 1311 /PORT_US_PER_TICK ) ; // 1311us + slot_154e_vars [SLOT_20ms_24GHZ].TsTxAckDelay = ( 5521 /PORT_US_PER_TICK ) ; // 5521us + slot_154e_vars [SLOT_20ms_24GHZ].TsShortGT = ( 700 /PORT_US_PER_TICK ) ; // 700us + slot_154e_vars [SLOT_20ms_24GHZ].wdRadioTx = ( 1342 /PORT_US_PER_TICK ) ; // 1000us (needs to be >delayTx) (SCuM need a larger value; 45 is tested and works) + slot_154e_vars [SLOT_20ms_24GHZ].wdDataDuration = ( 5000 /PORT_US_PER_TICK ) ; // 5000us (measured 4280us with max payload) + slot_154e_vars [SLOT_20ms_24GHZ].wdAckDuration = ( 3000 /PORT_US_PER_TICK ) ; // 3000us (measured 1000us) + + //40ms slot for 24ghz cc2538 + slot_154e_vars [SLOT_40ms_24GHZ].TsTxOffset = ( 5215 /PORT_US_PER_TICK ) ; // 5215us + slot_154e_vars [SLOT_40ms_24GHZ].TsLongGT = ( 1311 /PORT_US_PER_TICK ) ; // 1311us + slot_154e_vars [SLOT_40ms_24GHZ].TsTxAckDelay = ( 5521 /PORT_US_PER_TICK ) ; // 5521us + slot_154e_vars [SLOT_40ms_24GHZ].TsShortGT = ( 700 /PORT_US_PER_TICK ) ; // 700us + slot_154e_vars [SLOT_40ms_24GHZ].wdRadioTx = ( 1342 /PORT_US_PER_TICK ) ; // 1000us (needs to be >delayTx) (SCuM need a larger value; 45 is tested and works) + slot_154e_vars [SLOT_40ms_24GHZ].wdDataDuration = ( 5000 /PORT_US_PER_TICK ) ; // 5000us (measured 4280us with max payload) + slot_154e_vars [SLOT_40ms_24GHZ].wdAckDuration = ( 3000 /PORT_US_PER_TICK ) ; // 3000us (measured 1000us) + + //40ms slot for FSK + slot_154e_vars [SLOT_40ms_FSK_SUBGHZ].TsTxOffset = ( 4000 /PORT_US_PER_TICK ); // measured: 131 ticks + slot_154e_vars [SLOT_40ms_FSK_SUBGHZ].TsLongGT = ( 2000 /PORT_US_PER_TICK ); // measured: 66 ticks + slot_154e_vars [SLOT_40ms_FSK_SUBGHZ].TsTxAckDelay = ( 3700 /PORT_US_PER_TICK ); // measured: 121 ticks + slot_154e_vars [SLOT_40ms_FSK_SUBGHZ].TsShortGT = ( 1831 /PORT_US_PER_TICK ); // measured: 60 ticks + slot_154e_vars [SLOT_40ms_FSK_SUBGHZ].wdRadioTx = ( 7000 /PORT_US_PER_TICK ); // 230 ticks 7019us delayTx+Tx time for 10 bytes( (needs to be >delayTx) (SCuM need a larger value; 45 is tested and works) + slot_154e_vars [SLOT_40ms_FSK_SUBGHZ].wdDataDuration = ( 30000 /PORT_US_PER_TICK ); // 983 ticks ; estimated based on max payload + slot_154e_vars [SLOT_40ms_FSK_SUBGHZ].wdAckDuration = ( 20000 /PORT_US_PER_TICK ); // 655 ticks; estimated + + //40ms slot for OFDM1 MCS0-3 + slot_154e_vars [SLOT_40ms_OFDM1MCS0_3_SUBGHZ].TsTxOffset = ( 3500 /PORT_US_PER_TICK ); // measured: 115 ticks; + slot_154e_vars [SLOT_40ms_OFDM1MCS0_3_SUBGHZ].TsLongGT = ( 2000 /PORT_US_PER_TICK ); // measured: 66 ticks; + slot_154e_vars [SLOT_40ms_OFDM1MCS0_3_SUBGHZ].TsTxAckDelay = ( 3700 /PORT_US_PER_TICK ); // measured: 121 ticks + slot_154e_vars [SLOT_40ms_OFDM1MCS0_3_SUBGHZ].TsShortGT = ( 1831 /PORT_US_PER_TICK ); // measured: 60 ticks + slot_154e_vars [SLOT_40ms_OFDM1MCS0_3_SUBGHZ].wdRadioTx = ( 7000 /PORT_US_PER_TICK ); // 230 ticks 7019us delayTx+Tx time for 10 bytes( (needs to be >delayTx) (SCuM need a larger value; 45 is tested and works) + slot_154e_vars [SLOT_40ms_OFDM1MCS0_3_SUBGHZ].wdDataDuration = ( 30000 /PORT_US_PER_TICK ); // 983 ticks; estimated based on max payload + slot_154e_vars [SLOT_40ms_OFDM1MCS0_3_SUBGHZ].wdAckDuration = ( 20000 /PORT_US_PER_TICK ); // 655 ticks; estimated +} + +/** +\brief This function initializes the lookup table for the slot templates. + +Call this function once, preferrably at end of the ieee154e_init function +*/ +void ieee154e_select_slot_template(slotType_t slotType){ + + slot_board_vars_t slot_board_vars= board_selectSlotTemplate(slotType); + + // board-specific template details + slotTemplate.slotDuration = slot_board_vars.slotDuration; + slotTemplate.maxTxDataPrepare = slot_board_vars.maxTxDataPrepare; + slotTemplate.maxRxAckPrepare = slot_board_vars.maxRxAckPrepare; + slotTemplate.maxRxDataPrepare = slot_board_vars.maxRxDataPrepare; + slotTemplate.maxTxAckPrepare = slot_board_vars.maxTxAckPrepare; + slotTemplate.delayTx = slot_board_vars.delayTx; + slotTemplate.delayRx = slot_board_vars.delayRx; + + //154e general slot template + slotTemplate.TsTxOffset = slot_154e_vars [slotType].TsTxOffset; + slotTemplate.TsLongGT = slot_154e_vars [slotType].TsLongGT; + slotTemplate.TsTxAckDelay = slot_154e_vars [slotType].TsTxAckDelay; + slotTemplate.TsShortGT = slot_154e_vars [slotType].TsShortGT; + slotTemplate.wdRadioTx = slot_154e_vars [slotType].wdRadioTx; + slotTemplate.wdDataDuration = slot_154e_vars [slotType].wdDataDuration; + slotTemplate.wdAckDuration = slot_154e_vars [slotType].wdAckDuration; +} //=========================== public ========================================== /** @@ -334,12 +439,12 @@ void isr_ieee154e_newSlot(opentimers_id_t id) { opentimers_scheduleAbsolute( ieee154e_vars.timerId, // timerId - TsSlotDuration, // duration + slotTemplate.slotDuration, // duration ieee154e_vars.startOfSlotReference, // reference TIME_TICS, // timetype isr_ieee154e_newSlot // callback ); - ieee154e_vars.slotDuration = TsSlotDuration; + ieee154e_vars.slotDuration = slotTemplate.slotDuration; if (ieee154e_vars.isSync == FALSE) { if (idmanager_getIsDAGroot() == TRUE) { @@ -977,12 +1082,12 @@ port_INLINE void activity_ti1ORri1(void) { opentimers_scheduleAbsolute( ieee154e_vars.timerId, // timerId - TsSlotDuration * (ieee154e_vars.numOfSleepSlots), // duration + slotTemplate.slotDuration * (ieee154e_vars.numOfSleepSlots), // duration ieee154e_vars.startOfSlotReference, // reference TIME_TICS, // timetype isr_ieee154e_newSlot // callback ); - ieee154e_vars.slotDuration = TsSlotDuration * (ieee154e_vars.numOfSleepSlots); + ieee154e_vars.slotDuration = slotTemplate.slotDuration * (ieee154e_vars.numOfSleepSlots); //increase ASN by numOfSleepSlots-1 slots as at this slot is already incremented by 1 for (i = 0; i < ieee154e_vars.numOfSleepSlots - 1; i++) { @@ -1862,7 +1967,7 @@ port_INLINE void activity_ri5(PORT_TIMER_WIDTH capturedTime) { // record the timeCorrection and print out at end of slot ieee154e_vars.dataReceived->l2_timeCorrection = (PORT_SIGNED_INT_WIDTH)( - (PORT_SIGNED_INT_WIDTH) TsTxOffset - (PORT_SIGNED_INT_WIDTH) ieee154e_vars.syncCapturedTime); + (PORT_SIGNED_INT_WIDTH) slotTemplate.TsTxOffset - (PORT_SIGNED_INT_WIDTH) ieee154e_vars.syncCapturedTime); // check if ack requested if (ieee802514_header.ackRequested == 1 && ieee154e_vars.isAckEnabled == TRUE) { @@ -1887,7 +1992,7 @@ port_INLINE void activity_ri5(PORT_TIMER_WIDTH capturedTime) { // calculate the time timeCorrection (this is the time the sender is off w.r.t to this node. A negative number means // the sender is too late. ieee154e_vars.timeCorrection = (PORT_SIGNED_INT_WIDTH)( - (PORT_SIGNED_INT_WIDTH) TsTxOffset - (PORT_SIGNED_INT_WIDTH) ieee154e_vars.syncCapturedTime); + (PORT_SIGNED_INT_WIDTH) slotTemplate.TsTxOffset - (PORT_SIGNED_INT_WIDTH) ieee154e_vars.syncCapturedTime); // prepend the IEEE802.15.4 header to the ACK ieee154e_vars.ackToSend->l2_frameType = IEEE154_TYPE_ACK; @@ -2023,7 +2128,7 @@ port_INLINE void activity_ri6(void) { // calculate the time timeCorrection (this is the time the sender is off w.r.t to this node. A negative number means // the sender is too late. ieee154e_vars.timeCorrection = (PORT_SIGNED_INT_WIDTH)( - (PORT_SIGNED_INT_WIDTH) TsTxOffset - (PORT_SIGNED_INT_WIDTH) ieee154e_vars.syncCapturedTime); + (PORT_SIGNED_INT_WIDTH) slotTemplate.TsTxOffset - (PORT_SIGNED_INT_WIDTH) ieee154e_vars.syncCapturedTime); // prepend the IEEE802.15.4 header to the ACK ieee154e_vars.ackToSend->l2_frameType = IEEE154_TYPE_ACK; @@ -2561,7 +2666,7 @@ void synchronizePacket(PORT_TIMER_WIDTH timeReceived) { currentPeriod = ieee154e_vars.slotDuration; // calculate new period - timeCorrection = (PORT_SIGNED_INT_WIDTH)((PORT_SIGNED_INT_WIDTH) timeReceived - (PORT_SIGNED_INT_WIDTH) TsTxOffset); + timeCorrection = (PORT_SIGNED_INT_WIDTH)((PORT_SIGNED_INT_WIDTH) timeReceived - (PORT_SIGNED_INT_WIDTH) slotTemplate.TsTxOffset); // The interrupt beginning a new slot can either occur after the packet has been or while it is being received, // possibly because the mote is not yet synchronized. In the former case we simply take the usual slotLength and @@ -2579,7 +2684,7 @@ void synchronizePacket(PORT_TIMER_WIDTH timeReceived) { // length to be 2 slots long if ((PORT_SIGNED_INT_WIDTH) newPeriod - (PORT_SIGNED_INT_WIDTH) currentValue < (PORT_SIGNED_INT_WIDTH) RESYNCHRONIZATIONGUARD) { - newPeriod += TsSlotDuration; + newPeriod += slotTemplate.slotDuration; incrementAsnOffset(); } @@ -2670,7 +2775,7 @@ void changeIsSync(bool newIsSync) { if (ieee154e_vars.isSync == TRUE) { leds_sync_on(); - resetStats(); + ieee154e_resetStats(); } else { leds_sync_off(); schedule_resetBackoff(); @@ -2708,7 +2813,7 @@ void notif_receive(OpenQueueEntry_t *packetReceived) { //======= stats -port_INLINE void resetStats(void) { +port_INLINE void ieee154e_resetStats(void) { ieee154e_stats.numSyncPkt = 0; ieee154e_stats.numSyncAck = 0; ieee154e_stats.minCorrection = 127; diff --git a/openstack/02a-MAClow/IEEE802154E.h b/openstack/02a-MAClow/IEEE802154E.h index f3274979c7..20c1499b5a 100644 --- a/openstack/02a-MAClow/IEEE802154E.h +++ b/openstack/02a-MAClow/IEEE802154E.h @@ -153,56 +153,59 @@ typedef enum { #define TIMESLOT_TEMPLATE_ID 0x00 #define CHANNELHOPPING_TEMPLATE_ID 0x00 -// Atomic durations -// expressed in 32kHz ticks: +//===== Slot Template Configurations + +//general MAC slot template +typedef struct { + uint16_t TsTxOffset; + uint16_t TsLongGT; + uint16_t TsTxAckDelay; + uint16_t TsShortGT; + uint16_t wdRadioTx; + uint16_t wdDataDuration; + uint16_t wdAckDuration; +} slot_154e_vars_t; + + +//======== global 802154e atomic duration variables + // - ticks = duration_in_seconds * 32768 // - duration_in_seconds = ticks / 32768 -enum ieee154e_atomicdurations_enum { -// time-slot related -#if SLOTDURATION == 10 - TsTxOffset = (2120/PORT_US_PER_TICK), // 2120us - TsLongGT = (1100/PORT_US_PER_TICK), // 1100us - TsTxAckDelay = (1000/PORT_US_PER_TICK), // 1000us - TsShortGT = (500/PORT_US_PER_TICK), // 500us, The standardlized value for this is 400/2=200us(7ticks). Currectly 7 doesn't work for short packet, change it back to 7 when found the problem. - wdRadioTx = (1342/PORT_US_PER_TICK), // 1000us (needs to be >delayTx) (SCuM need a larger value, 45 is tested and works) - wdDataDuration = (5000/PORT_US_PER_TICK), // 5000us (measured 4280us with max payload) - wdAckDuration = (3000/PORT_US_PER_TICK), // 3000us (measured 1000us) -#endif +// This slotTemplate should be instantiated only once for the currently used slotTemplate +typedef struct { + + // 1. slot template variables + // data transmission template + uint16_t TsTxOffset; //tx + uint16_t TsLongGT; //rx -#if SLOTDURATION == 20 - TsTxOffset = (5215/PORT_US_PER_TICK), // 5215us - TsLongGT = (1311/PORT_US_PER_TICK), // 1311us - TsTxAckDelay = (5521/PORT_US_PER_TICK), // 5521us - TsShortGT = (700/PORT_US_PER_TICK), // 700us - wdRadioTx = (1342/PORT_US_PER_TICK), // 1000us (needs to be >delayTx) (SCuM need a larger value, 45 is tested and works) - wdDataDuration = (5000/PORT_US_PER_TICK), // 5000us (measured 4280us with max payload) - wdAckDuration = (3000/PORT_US_PER_TICK), // 3000us (measured 1000us) -#endif + // ack transmission template + uint16_t TsTxAckDelay; //tx + uint16_t TsShortGT; //rx -#if SLOTDURATION == 160 - TsTxOffset = (10986/PORT_US_PER_TICK), // 360 ticks, 10986us - TsLongGT = (7324/PORT_US_PER_TICK), // 240 ticks, 7324us - TsTxAckDelay = (11047/PORT_US_PER_TICK), // 362 ticks, 11047us - TsShortGT = (1831/PORT_US_PER_TICK), // 60 ticksz 1831us - // radio watchdog - wdRadioTx = (7019/PORT_US_PER_TICK), // 230 ticks 7019us delayTx+Tx time for 10 bytes( (needs to be >delayTx) (SCuM need a larger value, 45 is tested and works) - wdDataDuration = (81238/PORT_US_PER_TICK), // 2662 ticks 81238us (measured with max payload) - wdAckDuration = (18310/PORT_US_PER_TICK), // 600 ticks 18310us (measured) -#endif + // watchdog (safety check) template + uint16_t wdRadioTx; + uint16_t wdDataDuration; + uint16_t wdAckDuration; - TsSlotDuration = PORT_TsSlotDuration, - // execution speed related - maxTxDataPrepare = PORT_maxTxDataPrepare, - maxRxAckPrepare = PORT_maxRxAckPrepare, - maxRxDataPrepare = PORT_maxRxDataPrepare, - maxTxAckPrepare = PORT_maxTxAckPrepare, - // radio speed related - delayTx = PORT_delayTx, // between GO signal and SFD - delayRx = PORT_delayRx, // between GO signal and start listening - // radio watchdog + // 2. board/implementation specific durations + // note that these variables MUST respect (i.e. fit) the slot template section 1 in order for the scedule to maintain its integrity. -}; + uint16_t slotDuration; + uint16_t maxTxDataPrepare; + uint16_t maxRxAckPrepare; + uint16_t maxRxDataPrepare; + uint16_t maxTxAckPrepare; + + //3. radio setting specific durations + + // this parameter is specifically helpful in tuning the radio transmission timing to meet the TsTxOffset for accurate synchronization + uint16_t delayTx; // between GO signal and SFD + + // this parameter is helpful to have the radio listen later or earlier to save energy in listening state. + uint16_t delayRx; // between GO signal and start listening +} slotTemplate_t; //shift of bytes in the linkOption bitmap: draft-ietf-6tisch-minimal-10.txt: page 6 enum ieee154e_linkOption_enum { @@ -214,23 +217,23 @@ enum ieee154e_linkOption_enum { // FSM timer durations (combinations of atomic durations) // TX -#define DURATION_tt1 ieee154e_vars.lastCapturedTime+TsTxOffset-delayTx-maxTxDataPrepare -#define DURATION_tt2 ieee154e_vars.lastCapturedTime+TsTxOffset-delayTx -#define DURATION_tt3 ieee154e_vars.lastCapturedTime+TsTxOffset-delayTx+wdRadioTx -#define DURATION_tt4 ieee154e_vars.lastCapturedTime+wdDataDuration -#define DURATION_tt5 ieee154e_vars.lastCapturedTime+TsTxAckDelay-TsShortGT-delayRx-maxRxAckPrepare -#define DURATION_tt6 ieee154e_vars.lastCapturedTime+TsTxAckDelay-TsShortGT-delayRx -#define DURATION_tt7 ieee154e_vars.lastCapturedTime+TsTxAckDelay+TsShortGT -#define DURATION_tt8 ieee154e_vars.lastCapturedTime+wdAckDuration +#define DURATION_tt1 ieee154e_vars.lastCapturedTime+slotTemplate.TsTxOffset-slotTemplate.delayTx-slotTemplate.maxTxDataPrepare +#define DURATION_tt2 ieee154e_vars.lastCapturedTime+slotTemplate.TsTxOffset-slotTemplate.delayTx +#define DURATION_tt3 ieee154e_vars.lastCapturedTime+slotTemplate.TsTxOffset-slotTemplate.delayTx+slotTemplate.wdRadioTx +#define DURATION_tt4 ieee154e_vars.lastCapturedTime+slotTemplate.wdDataDuration +#define DURATION_tt5 ieee154e_vars.lastCapturedTime+slotTemplate.TsTxAckDelay-slotTemplate.TsShortGT-slotTemplate.delayRx-slotTemplate.maxRxAckPrepare +#define DURATION_tt6 ieee154e_vars.lastCapturedTime+slotTemplate.TsTxAckDelay-slotTemplate.TsShortGT-slotTemplate.delayRx +#define DURATION_tt7 ieee154e_vars.lastCapturedTime+slotTemplate.TsTxAckDelay+slotTemplate.TsShortGT +#define DURATION_tt8 ieee154e_vars.lastCapturedTime+slotTemplate.wdAckDuration // RX -#define DURATION_rt1 ieee154e_vars.lastCapturedTime+TsTxOffset-TsLongGT-delayRx-maxRxDataPrepare -#define DURATION_rt2 ieee154e_vars.lastCapturedTime+TsTxOffset-TsLongGT-delayRx -#define DURATION_rt3 ieee154e_vars.lastCapturedTime+TsTxOffset+TsLongGT -#define DURATION_rt4 ieee154e_vars.lastCapturedTime+wdDataDuration -#define DURATION_rt5 ieee154e_vars.lastCapturedTime+TsTxAckDelay-delayTx-maxTxAckPrepare -#define DURATION_rt6 ieee154e_vars.lastCapturedTime+TsTxAckDelay-delayTx -#define DURATION_rt7 ieee154e_vars.lastCapturedTime+TsTxAckDelay-delayTx+wdRadioTx -#define DURATION_rt8 ieee154e_vars.lastCapturedTime+wdAckDuration +#define DURATION_rt1 ieee154e_vars.lastCapturedTime+slotTemplate.TsTxOffset-slotTemplate.TsLongGT-slotTemplate.delayRx-slotTemplate.maxRxDataPrepare +#define DURATION_rt2 ieee154e_vars.lastCapturedTime+slotTemplate.TsTxOffset-slotTemplate.TsLongGT-slotTemplate.delayRx +#define DURATION_rt3 ieee154e_vars.lastCapturedTime+slotTemplate.TsTxOffset+slotTemplate.TsLongGT +#define DURATION_rt4 ieee154e_vars.lastCapturedTime+slotTemplate.wdDataDuration +#define DURATION_rt5 ieee154e_vars.lastCapturedTime+slotTemplate.TsTxAckDelay-slotTemplate.delayTx-slotTemplate.maxTxAckPrepare +#define DURATION_rt6 ieee154e_vars.lastCapturedTime+slotTemplate.TsTxAckDelay-slotTemplate.delayTx +#define DURATION_rt7 ieee154e_vars.lastCapturedTime+slotTemplate.TsTxAckDelay-slotTemplate.delayTx+slotTemplate.wdRadioTx +#define DURATION_rt8 ieee154e_vars.lastCapturedTime+slotTemplate.wdAckDuration // serialInhibit #define DURATION_si ieee154e_vars.slotDuration-SERIALINHIBITGUARD @@ -313,8 +316,9 @@ typedef struct { //=========================== prototypes ====================================== // admin -void ieee154e_init(void); - +void ieee154e_init(void); +void ieee154e_select_slot_template(slotType_t slotType); +slotTemplate_t ieee154e_getSlotTemplate (void); // public PORT_TIMER_WIDTH ieee154e_asnDiff(asn_t *someASN); @@ -349,6 +353,8 @@ bool debugPrint_isSync(void); bool debugPrint_macStats(void); +void ieee154e_resetStats(void); + /** \} \} diff --git a/openstack/02b-MAChigh/sixtop.c b/openstack/02b-MAChigh/sixtop.c index 133971bcf8..fa5133d7c4 100644 --- a/openstack/02b-MAChigh/sixtop.c +++ b/openstack/02b-MAChigh/sixtop.c @@ -122,7 +122,7 @@ void sixtop_init(void) { sixtop_vars.ebSendingTimerId = opentimers_create(TIMER_GENERAL_PURPOSE, TASKPRIO_SIXTOP); opentimers_scheduleIn( sixtop_vars.ebSendingTimerId, - SLOTFRAME_LENGTH * SLOTDURATION, + SLOTFRAME_LENGTH * SLOTDURATION_MS, TIME_MS, TIMER_PERIODIC, sixtop_sendingEb_timer_cb diff --git a/openstack/03b-IPv6/icmpv6rpl.c b/openstack/03b-IPv6/icmpv6rpl.c index 21bc54ac28..200514cc35 100644 --- a/openstack/03b-IPv6/icmpv6rpl.c +++ b/openstack/03b-IPv6/icmpv6rpl.c @@ -133,7 +133,7 @@ void icmpv6rpl_init(void) { opentimers_scheduleIn( icmpv6rpl_vars.timerIdDIO, - SLOTFRAME_LENGTH * SLOTDURATION, + SLOTFRAME_LENGTH * SLOTDURATION_MS, TIME_MS, TIMER_PERIODIC, icmpv6rpl_timer_DIO_cb @@ -178,7 +178,7 @@ void icmpv6rpl_init(void) { icmpv6rpl_vars.timerIdDAO = opentimers_create(TIMER_GENERAL_PURPOSE, TASKPRIO_RPL); opentimers_scheduleIn( icmpv6rpl_vars.timerIdDAO, - SLOTFRAME_LENGTH * SLOTDURATION, + SLOTFRAME_LENGTH * SLOTDURATION_MS, TIME_MS, TIMER_PERIODIC, icmpv6rpl_timer_DAO_cb diff --git a/projects/python/SConscript.env b/projects/python/SConscript.env index ce07c79ed8..897fbb617c 100644 --- a/projects/python/SConscript.env +++ b/projects/python/SConscript.env @@ -522,7 +522,7 @@ functionsToChange = [ 'changeIsSync', 'notif_sendDone', 'notif_receive', - 'resetStats', + 'ieee154e_resetStats', 'updateStats', 'calculateFrequency', 'changeState',