From 3f04c7fa3e37c8bb9803c2aa0519c4d4c9c8ea65 Mon Sep 17 00:00:00 2001 From: changtengfei Date: Fri, 13 Dec 2019 17:38:28 +0100 Subject: [PATCH 01/32] SW-15. add the quick_cal implementation (WIP) --- scm_v3c/applications/quick_cal/quick_cal.c | 338 +++++++++++ .../applications/quick_cal/quick_cal.uvoptx | 416 ++++++++++++++ .../applications/quick_cal/quick_cal.uvprojx | 539 ++++++++++++++++++ scm_v3c/gpio.c | 95 ++- scm_v3c/gpio.h | 36 +- 5 files changed, 1422 insertions(+), 2 deletions(-) create mode 100644 scm_v3c/applications/quick_cal/quick_cal.c create mode 100644 scm_v3c/applications/quick_cal/quick_cal.uvoptx create mode 100644 scm_v3c/applications/quick_cal/quick_cal.uvprojx diff --git a/scm_v3c/applications/quick_cal/quick_cal.c b/scm_v3c/applications/quick_cal/quick_cal.c new file mode 100644 index 00000000..d8eafeb8 --- /dev/null +++ b/scm_v3c/applications/quick_cal/quick_cal.c @@ -0,0 +1,338 @@ +/** +\brief This program helps SCuM to find the frequency settings +for each 16 channel with a quick_cal box. + +\author Tengfei Chang Dec 2019 +*/ + +#include + +#include "scm3c_hw_interface.h" +#include "memory_map.h" +#include "rftimer.h" +#include "radio.h" +#include "optical.h" + +//=========================== defines ========================================= + +#define CRC_VALUE (*((unsigned int *) 0x0000FFFC)) +#define CODE_LENGTH (*((unsigned int *) 0x0000FFF8)) + +#define SYNC_CHANNEL 11 +#define NUM_CHANNELS 16 +#define SLOTFRAME_LEN 16 + +#define MAX_PKT_LEN 125+LENGTH_CRC +#define PKT_TX_LEN 2+LENGTH_CRC + +// timing +#define SLOT_DURATION 500000 ///< 500 = 1ms@500kHz +#define SUB_SLOT_DURATION 400 ///< 305 = 610us@500kHz + +// frequency settings +#define SYNC_FREQ_START 22*32*32 +#define FREQ_RANGE 2*32*32 +#define SWEEP_STEP 2 +#define COARSE_MASK (0x001f<<10) +#define COARSE_OFFSET 10 +#define MID_MASK (0x001f<<5) +#define MID_OFFSET 5 +#define FINE_MASK (0x001f) +#define FINE_OFFSET 0 + +//=========================== variables ======================================= + +typedef enum{ + T_IDLE = 0, + T_TX = 1, + T_RX = 2, +}type_t; + +typedef enum{ + S_IDLE = 0, + S_LISTENING = 1, + S_RECEIVING = 2, + S_RXPROC = 3, + S_DATA_SENDING = 4, + S_ACK_SENDING = 5, + S_DATA_SENDDONE = 6, + S_ACK_SENDDONE = 7, + S_DATA_SEND = 8, + S_ACK_SEND = 9, +}state_t; + +typedef struct { + // store the frequency settings for transmitting and receiving each + // 16 channels: + // - coarse = (freq_setting & (0x001f<<10))>>10 + // - mid = (freq_setting & (0x001f<< 5))>> 5 + // - fine = freq_setting & 0x001f + + uint16_t freq_setting_tx[NUM_CHANNELS]; + uint16_t freq_setting_rx[NUM_CHANNELS]; + + uint16_t freq_setting_index; + uint16_t current_freq_setting; + + bool isSync; // is synchronized? + uint8_t currentSlotOffset; + uint32_t slotRerference; // the timer read when slot timer fired + + type_t type; // tx or rx, used in start/end Frame ISR + state_t state; // radio state + + uint8_t channel_to_calc; + + bool freq_setting_rx_done; // TRUE when all 16 rx settings are found + bool freq_setting_tx_done; // TRUE when all 16 tx settings are found + + uint8_t packet[MAX_PKT_LEN]; + uint8_t pkt_len; +} app_vars_t; + +app_vars_t app_vars; + +//=========================== prototypes ====================================== + +void cb_startFrame(uint32_t timestamp); +void cb_endFrame(uint32_t timestamp); +void cb_slot_timer(void); +void cb_calc_process_timer(void); + +//=========================== main ============================================ + +int main(void) { + + uint32_t calc_crc; + + uint8_t i; + uint8_t j; + uint8_t offset; + + memset(&app_vars,0,sizeof(app_vars_t)); + + + printf("Initializing..."); + + // Set up mote configuration + // This function handles all the analog scan chain setup + initialize_mote(); + + radio_setStartFrameRxCb(cb_startFrame); + radio_setEndFrameRxCb(cb_endFrame); + rftimer_set_callback(cb_slot_timer); + + // Disable interrupts for the radio and rftimer + radio_disable_interrupts(); + rftimer_disable_interrupts(); + + // Check CRC to ensure there were no errors during optical programming + printf("\r\n-------------------\r\n"); + printf("Validating program integrity..."); + + calc_crc = crc32c(0x0000,CODE_LENGTH); + + if(calc_crc == CRC_VALUE){ + printf("CRC OK\r\n"); + } else{ + printf("\r\nProgramming Error - CRC DOES NOT MATCH - Halting Execution\r\n"); + while(1); + } + + // Debug output + //printf("\r\nCode length is %u bytes",code_length); + //printf("\r\nCRC calculated by SCM is: 0x%X",calc_crc); + + //printf("done\r\n"); + + // After bootloading the next thing that happens is frequency calibration using optical + printf("Calibrating frequencies...\r\n"); + + // Initial frequency calibration will tune the frequencies for HCLK, the RX/TX chip clocks, and the LO + + // For the LO, calibration for RX channel 11, so turn on AUX, IF, and LO LDOs + // by calling radio rxEnable + radio_rxEnable(); + + // Enable optical SFD interrupt for optical calibration + optical_enable(); + + // Wait for optical cal to finish + while(optical_getCalibrationFinshed() == 0); + + printf("Cal complete\r\n"); + + app_vars.currentSlotOffset = SLOTFRAME_LEN - 1; + + // Enable interrupts for the radio FSM + radio_enable_interrupts(); + + app_vars.current_freq_setting = SYNC_FREQ_START; + rftimer_setCompareIn(rftimer_readCounter()+SLOT_DURATION); + + while(1){ + + } +} + +//=========================== public ========================================== + +//=========================== private ========================================= + + +void cb_startFrame(uint32_t timestamp){ + +} + +void cb_endFrame(uint32_t timestamp){ + +} + +void cb_slot_timer(void) { + + app_vars.slotRerference = rftimer_readCounter(); + rftimer_setCompareIn(app_vars.slotRerference+SLOT_DURATION); + + app_vars.currentSlotOffset = \ + (app_vars.currentSlotOffset+1) % SLOTFRAME_LEN; + + if (app_vars.isSync){ + + if (app_vars.freq_setting_rx_done){ + + app_vars.type = T_TX; + + app_vars.packet[0] = 0xCA; + app_vars.packet[1] = 0xFE; + + if (app_vars.currentSlotOffset==0){ + + // skip slot 0 as all motes are listening on ch11 except root + + // no way to calculate channel rx_11 + + return; + + } else { + + + app_vars.channel_to_calc = \ + app_vars.currentSlotOffset-1 + SYNC_CHANNEL; + + app_vars.freq_setting_index = 0; + cb_calc_process_timer(); + } + + } else { + + // sweep frequency setting to find one Rx channel + + app_vars.type = T_RX; + + app_vars.channel_to_calc = \ + app_vars.currentSlotOffset + SYNC_CHANNEL; + + if (app_vars.currentSlotOffset==0){ + + app_vars.current_freq_setting = SYNC_FREQ_START; + } else { + + if (app_vars.freq_setting_rx[app_vars.currentSlotOffset-1]==0){ + // the previous frequency is unknown + + // don't performance frequency sweep + + // something goes wrong + + return; + + } else { + + app_vars.current_freq_setting = + app_vars.freq_setting_rx[app_vars.currentSlotOffset-1]; + } + } + + app_vars.freq_setting_index = 0; + cb_calc_process_timer(); + } + } else { + + app_vars.type = T_RX; + + app_vars.freq_setting_index = 0; + app_vars.current_freq_setting = SYNC_FREQ_START; + + cb_calc_process_timer(); + } +} + +void cb_calc_process_timer(void) { + + app_vars.freq_setting_index += 1; + + if (app_vars.freq_setting_index>FREQ_RANGE/SWEEP_STEP){ + rftimer_disable_interrupts(); + rftimer_set_callback(cb_slot_timer); + rftimer_setCompareIn(app_vars.slotRerference + SLOT_DURATION); + } else { + rftimer_disable_interrupts(); + rftimer_set_callback(cb_calc_process_timer); + rftimer_setCompareIn( + app_vars.slotRerference + \ + app_vars.freq_setting_index*SUB_SLOT_DURATION + ); + } + + radio_rfOff(); + app_vars.current_freq_setting += SWEEP_STEP; + LC_FREQCHANGE( + (app_vars.current_freq_setting & COARSE_MASK) >> COARSE_OFFSET, + (app_vars.current_freq_setting & MID_MASK) >> MID_OFFSET, + (app_vars.current_freq_setting & FINE_MASK) >> FINE_OFFSET + ); + + switch(app_vars.type){ + + case T_TX: + + if (app_vars.current_freq_setting>SYNC_FREQ_START+FREQ_RANGE){ + if (app_vars.isSync) { + // freq_sweep is done, calculate the freq_setting + // todo + + } else { + // something goes wrong + } + } else { + app_vars.pkt_len = PKT_TX_LEN; + radio_loadPacket(app_vars.packet, app_vars.pkt_len); + radio_txEnable(); + radio_txNow(); + } + + break; + case T_RX: + + + if (app_vars.current_freq_setting>SYNC_FREQ_START+FREQ_RANGE){ + if (app_vars.isSync) { + // freq_sweep is done, calculate the freq_setting + // todo + + } else { + // doesn't receive a valid frame during one slot to sync + + // wait next slot to repeat + } + } else { + radio_rxEnable(); + radio_rxNow(); + } + + break; + default: + // wrong state + break; + } +} diff --git a/scm_v3c/applications/quick_cal/quick_cal.uvoptx b/scm_v3c/applications/quick_cal/quick_cal.uvoptx new file mode 100644 index 00000000..c2f68a91 --- /dev/null +++ b/scm_v3c/applications/quick_cal/quick_cal.uvoptx @@ -0,0 +1,416 @@ + + + + 1.0 + +
### uVision Project, (C) Keil Software
+ + + *.c + *.s*; *.src; *.a* + *.obj; *.o + *.lib + *.txt; *.h; *.inc + *.plm + *.cpp + 0 + + + + 0 + 0 + + + + quick_cal + 0x4 + ARM-ADS + + 10000000 + + 1 + 1 + 0 + 1 + 0 + + + 1 + 65535 + 0 + 0 + 0 + + + 79 + 66 + 8 + .\Listings\ + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 1 + 0 + 1 + + 7 + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 0 + + + + + + + + + + + BIN\UL2CM3.DLL + + + + 0 + UL2CM3 + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000) + + + + + 0 + + + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + 0 + 0 + 0 + + + + + + + + + + + + + app + 0 + 0 + 0 + 0 + + 1 + 1 + 1 + 0 + 0 + 0 + .\quick_cal.c + quick_cal.c + 0 + 0 + + + + + drv + 0 + 0 + 0 + 0 + + 2 + 2 + 2 + 0 + 0 + 0 + ..\..\cm0dsasm.s + cm0dsasm.s + 0 + 0 + + + 2 + 3 + 5 + 0 + 0 + 0 + ..\..\Memory_Map.h + Memory_Map.h + 0 + 0 + + + 2 + 4 + 1 + 0 + 0 + 0 + ..\..\retarget.c + retarget.c + 0 + 0 + + + 2 + 5 + 1 + 0 + 0 + 0 + ..\..\optical.c + optical.c + 0 + 0 + + + 2 + 6 + 5 + 0 + 0 + 0 + ..\..\optical.h + optical.h + 0 + 0 + + + 2 + 7 + 1 + 0 + 0 + 0 + ..\..\radio.c + radio.c + 0 + 0 + + + 2 + 8 + 5 + 0 + 0 + 0 + ..\..\radio.h + radio.h + 0 + 0 + + + 2 + 9 + 1 + 0 + 0 + 0 + ..\..\adc.c + adc.c + 0 + 0 + + + 2 + 10 + 5 + 0 + 0 + 0 + ..\..\adc.h + adc.h + 0 + 0 + + + 2 + 11 + 1 + 0 + 0 + 0 + ..\..\gpio.c + gpio.c + 0 + 0 + + + 2 + 12 + 5 + 0 + 0 + 0 + ..\..\gpio.h + gpio.h + 0 + 0 + + + 2 + 13 + 1 + 0 + 0 + 0 + ..\..\uart.c + uart.c + 0 + 0 + + + 2 + 14 + 5 + 0 + 0 + 0 + ..\..\uart.h + uart.h + 0 + 0 + + + 2 + 15 + 1 + 0 + 0 + 0 + ..\..\rftimer.c + rftimer.c + 0 + 0 + + + 2 + 16 + 5 + 0 + 0 + 0 + ..\..\rftimer.h + rftimer.h + 0 + 0 + + + 2 + 17 + 5 + 0 + 0 + 0 + ..\..\scum_defs.h + scum_defs.h + 0 + 0 + + + 2 + 18 + 5 + 0 + 0 + 0 + ..\..\scm3c_hw_interface.h + scm3c_hw_interface.h + 0 + 0 + + + 2 + 19 + 1 + 0 + 0 + 0 + ..\..\scm3c_hw_interface.c + scm3c_hw_interface.c + 0 + 0 + + + +
diff --git a/scm_v3c/applications/quick_cal/quick_cal.uvprojx b/scm_v3c/applications/quick_cal/quick_cal.uvprojx new file mode 100644 index 00000000..637f0ee4 --- /dev/null +++ b/scm_v3c/applications/quick_cal/quick_cal.uvprojx @@ -0,0 +1,539 @@ + + + + 2.1 + +
### uVision Project, (C) Keil Software
+ + + + quick_cal + 0x4 + ARM-ADS + 5060750::V5.06 update 6 (build 750)::ARMCC + 0 + + + ARMCM0 + ARM + ARM.CMSIS.5.3.0 + http://www.keil.com/pack/ + IROM(0x00000000,0x80000) IRAM(0x20000000,0x20000) CPUTYPE("Cortex-M0") CLOCK(10000000) ELITTLE + + + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0NEW_DEVICE -FS00 -FL040000 -FP0($$Device:ARMCM0$Flash\NEW_DEVICE.flm)) + 0 + $$Device:ARMCM0$Device\Include\ARMCM0.h + + + + + + + + + + $$Device:ARMCM0$SVD\ARMCM0.svd + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + .\Objects\ + quick_cal + 1 + 0 + 1 + 1 + 1 + .\Listings\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 1 + 1 + fromelf --bin .\Objects\quick_cal.axf -o .\Objects\quick_cal.bin + fromelf -cvf .\Objects\quick_cal.axf -o .\Objects\disasm.txt + 0 + 0 + 0 + 0 + + 0 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + SARMCM3.DLL + + DARMCM1.DLL + -pCM0 + SARMCM3.DLL + + TARMCM1.DLL + -pCM0 + + + + 1 + 0 + 0 + 0 + 16 + + + + + 1 + 0 + 0 + 1 + 1 + 4096 + + 1 + BIN\UL2CM3.DLL + "" () + + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M0" + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 8 + 0 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x20000 + + + 1 + 0x0 + 0x80000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x10000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x10000 + + + 0 + 0x0 + 0x0 + + + + + + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 2 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + + + + + ../../ + + + + 1 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + + + + + + + + + 1 + 0 + 0 + 0 + 1 + 0 + 0x00000000 + 0x20000000 + + quick_cal.sct + + + + + + + + + + + app + + + quick_cal.c + 1 + .\quick_cal.c + + + + + drv + + + cm0dsasm.s + 2 + ..\..\cm0dsasm.s + + + Memory_Map.h + 5 + ..\..\Memory_Map.h + + + retarget.c + 1 + ..\..\retarget.c + + + optical.c + 1 + ..\..\optical.c + + + optical.h + 5 + ..\..\optical.h + + + radio.c + 1 + ..\..\radio.c + + + radio.h + 5 + ..\..\radio.h + + + adc.c + 1 + ..\..\adc.c + + + adc.h + 5 + ..\..\adc.h + + + gpio.c + 1 + ..\..\gpio.c + + + gpio.h + 5 + ..\..\gpio.h + + + uart.c + 1 + ..\..\uart.c + + + uart.h + 5 + ..\..\uart.h + + + rftimer.c + 1 + ..\..\rftimer.c + + + rftimer.h + 5 + ..\..\rftimer.h + + + scum_defs.h + 5 + ..\..\scum_defs.h + + + scm3c_hw_interface.h + 5 + ..\..\scm3c_hw_interface.h + + + scm3c_hw_interface.c + 1 + ..\..\scm3c_hw_interface.c + + + + + + + + + + + + + RTE\CMSIS\RTX_Conf_CM.c + + + + + + RTE\Device\ARMCM0\startup_ARMCM0.s + + + + + + RTE\Device\ARMCM0\system_ARMCM0.c + + + + + + RTE\Drivers\NAND_MemBus_Config.h + + + + + + RTE\Drivers\OneNAND_Config.h + + + + + + RTE\File_System\FS_Config.c + + + + + + RTE\File_System\FS_Config_RAM.h + + + + + + + +
diff --git a/scm_v3c/gpio.c b/scm_v3c/gpio.c index f2fd9aeb..f9adbc2d 100644 --- a/scm_v3c/gpio.c +++ b/scm_v3c/gpio.c @@ -1,4 +1,97 @@ - +#include "memory_map.h" + +//=========================== define ========================================== + +//=========================== typedef ========================================= + +//=========================== variables ======================================= + +//=========================== prototypes ====================================== + +void gpio_init(void){ + GPIO_REG__OUTPUT &= ~0xFFFF; // all PINS low at initial +} + +void gpio_1_set(void){ + GPIO_REG__OUTPUT |= 0x0002; +} +void gpio_1_clr(void){ + GPIO_REG__OUTPUT &= ~0x0002; +} +void gpio_1_toggle(void){ + GPIO_REG__OUTPUT ^= 0x0002; +} + +void gpio_2_set(void){ + GPIO_REG__OUTPUT |= 0x0004; +} +void gpio_2_clr(void){ + GPIO_REG__OUTPUT &= ~0x0004; +} +void gpio_2_toggle(void){ + GPIO_REG__OUTPUT ^= 0x0004; +} + +void gpio_3_set(void){ + GPIO_REG__OUTPUT |= 0x0008; +} +void gpio_3_clr(void){ + GPIO_REG__OUTPUT &= ~0x0008; +} +void gpio_3_toggle(void){ + GPIO_REG__OUTPUT ^= 0x0008; +} + +void gpio_4_set(void){ + GPIO_REG__OUTPUT |= 0x0010; +} +void gpio_4_clr(void){ + GPIO_REG__OUTPUT &= ~0x0010; +} +void gpio_4_toggle(void){ + GPIO_REG__OUTPUT ^= 0x0010; +} + +void gpio_5_set(void){ + GPIO_REG__OUTPUT |= 0x0020; +} +void gpio_5_clr(void){ + GPIO_REG__OUTPUT &= ~0x0020; +} +void gpio_5_toggle(void){ + GPIO_REG__OUTPUT ^= 0x0020; +} + +void gpio_6_set(void){ + GPIO_REG__OUTPUT |= 0x0040; +} +void gpio_6_clr(void){ + GPIO_REG__OUTPUT &= ~0x0040; +} +void gpio_6_toggle(void){ + GPIO_REG__OUTPUT ^= 0x0040; +} + +void gpio_7_set(void){ + GPIO_REG__OUTPUT |= 0x0080; +} +void gpio_7_clr(void){ + GPIO_REG__OUTPUT &= ~0x0080; +} +void gpio_7_toggle(void){ + GPIO_REG__OUTPUT ^= 0x0080; +} + +void gpio_8_set(void){ + GPIO_REG__OUTPUT |= 0x0100; +} +void gpio_8_clr(void){ + GPIO_REG__OUTPUT &= ~0x0100; +} +void gpio_8_toggle(void){ + GPIO_REG__OUTPUT ^= 0x0100; +} + // ISRs for external interrupts void ext_gpio3_activehigh_debounced_isr(){ printf("External Interrupt GPIO3 triggered\r\n"); diff --git a/scm_v3c/gpio.h b/scm_v3c/gpio.h index 5781f477..0c8c068a 100644 --- a/scm_v3c/gpio.h +++ b/scm_v3c/gpio.h @@ -9,4 +9,38 @@ //=========================== prototypes ====================================== -#endif \ No newline at end of file +void gpio_init(void); + +void gpio_1_set(void); +void gpio_1_clr(void); +void gpio_1_toggle(void); + +void gpio_2_set(void); +void gpio_2_clr(void); +void gpio_2_toggle(void); + +void gpio_3_set(void); +void gpio_3_clr(void); +void gpio_3_toggle(void); + +void gpio_4_set(void); +void gpio_4_clr(void); +void gpio_4_toggle(void); + +void gpio_5_set(void); +void gpio_5_clr(void); +void gpio_5_toggle(void); + +void gpio_6_set(void); +void gpio_6_clr(void); +void gpio_6_toggle(void); + +void gpio_7_set(void); +void gpio_7_clr(void); +void gpio_7_toggle(void); + +void gpio_8_set(void); +void gpio_8_clr(void); +void gpio_8_toggle(void); + +#endif From b00db74eb2720fd4ad2c9380852712aae4dc5b6b Mon Sep 17 00:00:00 2001 From: changtengfei Date: Mon, 16 Dec 2019 14:28:36 +0100 Subject: [PATCH 02/32] Add gpio for debugging --- scm_v3c/applications/quick_cal/quick_cal.c | 237 ++++++++++++++++-- .../applications/quick_cal/quick_cal.uvoptx | 2 +- scm_v3c/gpio.c | 6 + scm_v3c/gpio.h | 6 + scm_v3c/radio.c | 5 + scm_v3c/rftimer.c | 5 + 6 files changed, 235 insertions(+), 26 deletions(-) diff --git a/scm_v3c/applications/quick_cal/quick_cal.c b/scm_v3c/applications/quick_cal/quick_cal.c index d8eafeb8..35b6a05c 100644 --- a/scm_v3c/applications/quick_cal/quick_cal.c +++ b/scm_v3c/applications/quick_cal/quick_cal.c @@ -12,6 +12,7 @@ for each 16 channel with a quick_cal box. #include "rftimer.h" #include "radio.h" #include "optical.h" +#include "gpio.h" //=========================== defines ========================================= @@ -22,17 +23,22 @@ for each 16 channel with a quick_cal box. #define NUM_CHANNELS 16 #define SLOTFRAME_LEN 16 +#define NUM_SAMPLES 100 + #define MAX_PKT_LEN 125+LENGTH_CRC -#define PKT_TX_LEN 2+LENGTH_CRC +#define TARGET_PKT_LEN 2+LENGTH_CRC // timing #define SLOT_DURATION 500000 ///< 500 = 1ms@500kHz -#define SUB_SLOT_DURATION 400 ///< 305 = 610us@500kHz +#define SUB_SLOT_DURATION 305 ///< 305 = 610us@500kHz +#define TXOFFSET 191 ///< measured, 382us // frequency settings #define SYNC_FREQ_START 22*32*32 #define FREQ_RANGE 2*32*32 #define SWEEP_STEP 2 +#define NUM_PKT_PER_SLOT 32*32 + #define COARSE_MASK (0x001f<<10) #define COARSE_OFFSET 10 #define MID_MASK (0x001f<<5) @@ -50,8 +56,10 @@ typedef enum{ typedef enum{ S_IDLE = 0, - S_LISTENING = 1, - S_RECEIVING = 2, + S_LISTEN_FOR_DATA = 1, + S_LISTEN_FOR_ACK = 2, + S_RECEIVING_DATA = 3, + S_RECEIVING_ACK = 4, S_RXPROC = 3, S_DATA_SENDING = 4, S_ACK_SENDING = 5, @@ -71,12 +79,16 @@ typedef struct { uint16_t freq_setting_tx[NUM_CHANNELS]; uint16_t freq_setting_rx[NUM_CHANNELS]; + uint8_t sample_index; + uint16_t freq_setting_sample[NUM_SAMPLES]; + uint16_t freq_setting_index; uint16_t current_freq_setting; bool isSync; // is synchronized? uint8_t currentSlotOffset; - uint32_t slotRerference; // the timer read when slot timer fired + uint32_t slotReference; // the timer read when slot timer fired + uint32_t lastCaptureTime; // time stampe of receiving frame type_t type; // tx or rx, used in start/end Frame ISR state_t state; // radio state @@ -88,6 +100,9 @@ typedef struct { uint8_t packet[MAX_PKT_LEN]; uint8_t pkt_len; + int8_t rxpk_rssi; + uint8_t rxpk_lqi; + bool rxpk_crc; } app_vars_t; app_vars_t app_vars; @@ -99,6 +114,8 @@ void cb_endFrame(uint32_t timestamp); void cb_slot_timer(void); void cb_calc_process_timer(void); +void synchronize(uint32_t capturedTime, uint8_t pkt_channel, uint16_t pkt_seqNum); + //=========================== main ============================================ int main(void) { @@ -163,6 +180,8 @@ int main(void) { printf("Cal complete\r\n"); app_vars.currentSlotOffset = SLOTFRAME_LEN - 1; + app_vars.freq_setting_index = 0; + app_vars.current_freq_setting = SYNC_FREQ_START; // Enable interrupts for the radio FSM radio_enable_interrupts(); @@ -179,19 +198,161 @@ int main(void) { //=========================== private ========================================= +//==== sync + +void synchronize(uint32_t capturedTime, uint8_t pkt_channel, uint16_t pkt_seqNum){ + + uint32_t slot_boudary; + + // synchronize currentslotoffset + app_vars.currentSlotOffset = pkt_channel-SYNC_CHANNEL; + + // synchronize to slot boudary + rftimer_disable_interrupts(); + slot_boudary = capturedTime - pkt_seqNum*SUB_SLOT_DURATION - TXOFFSET; + rftimer_set_callback(cb_slot_timer); + rftimer_setCompareIn(slot_boudary+SLOT_DURATION); + + app_vars.isSync = true; +} + +//==== isr void cb_startFrame(uint32_t timestamp){ + app_vars.lastCaptureTime = timestamp; + + switch(app_vars.type){ + case T_TX: + + break; + case T_RX: + + switch(app_vars.state){ + case S_LISTEN_FOR_DATA: + app_vars.state = S_RECEIVING_DATA; + break; + case S_LISTEN_FOR_ACK: + app_vars.state = S_RECEIVING_ACK; + break; + default: + // something goes wrong + break; + } + + break; + default: + + break; + } } void cb_endFrame(uint32_t timestamp){ + bool isValidFrame; + uint8_t pkt_channel; + uint16_t pkt_seqNum; + + radio_rfOff(); + + switch(app_vars.type){ + case T_TX: + + app_vars.type = T_RX; + + LC_FREQCHANGE( + (app_vars.freq_setting_rx[app_vars.currentSlotOffset] & COARSE_MASK) >> COARSE_OFFSET, + (app_vars.freq_setting_rx[app_vars.currentSlotOffset] & MID_MASK) >> MID_OFFSET, + (app_vars.freq_setting_rx[app_vars.currentSlotOffset] & FINE_MASK) >> FINE_OFFSET + ); + radio_rxEnable(); + radio_rxNow(); + + app_vars.state = S_LISTEN_FOR_ACK; + break; + case T_RX: + + memset(app_vars.packet,0,MAX_PKT_LEN); + + // get packet from radio + radio_getReceivedFrame( + app_vars.packet, + &app_vars.pkt_len, + sizeof(app_vars.packet), + &app_vars.rxpk_rssi, + &app_vars.rxpk_lqi + ); + + // check the frame is valid or not + + isValidFrame = false; + + if (app_vars.pkt_len == TARGET_PKT_LEN){ + + pkt_channel = (app_vars.packet[0] & 0xf0)>>4; + pkt_seqNum = ((uint16_t)(app_vars.packet[0] & 0x0f))<<8 | + (uint16_t)(app_vars.packet[1]); + if ( + pkt_channel>=11 && + pkt_channel<=26 && + pkt_seqNumFREQ_RANGE/SWEEP_STEP){ + app_vars.freq_setting_index = 1+app_vars.freq_setting_index; + + if (app_vars.isSync && app_vars.freq_setting_index>FREQ_RANGE/SWEEP_STEP){ rftimer_disable_interrupts(); rftimer_set_callback(cb_slot_timer); - rftimer_setCompareIn(app_vars.slotRerference + SLOT_DURATION); + rftimer_setCompareIn(app_vars.slotReference + SLOT_DURATION); } else { rftimer_disable_interrupts(); rftimer_set_callback(cb_calc_process_timer); + + if ( + rftimer_readCounter()+ SUB_SLOT_DURATION - + ( + app_vars.slotReference + + app_vars.freq_setting_index*SUB_SLOT_DURATION + ) <= SUB_SLOT_DURATION + ) { + // slotReference is not changed + + } else { + // slotReference is updated + + app_vars.freq_setting_index = 0; + } + rftimer_setCompareIn( - app_vars.slotRerference + \ + app_vars.slotReference + \ app_vars.freq_setting_index*SUB_SLOT_DURATION ); } radio_rfOff(); - app_vars.current_freq_setting += SWEEP_STEP; - LC_FREQCHANGE( - (app_vars.current_freq_setting & COARSE_MASK) >> COARSE_OFFSET, - (app_vars.current_freq_setting & MID_MASK) >> MID_OFFSET, - (app_vars.current_freq_setting & FINE_MASK) >> FINE_OFFSET - ); switch(app_vars.type){ case T_TX: - if (app_vars.current_freq_setting>SYNC_FREQ_START+FREQ_RANGE){ + if (app_vars.current_freq_setting> COARSE_OFFSET, + (app_vars.current_freq_setting & MID_MASK) >> MID_OFFSET, + (app_vars.current_freq_setting & FINE_MASK) >> FINE_OFFSET + ); + app_vars.pkt_len = TARGET_PKT_LEN; radio_loadPacket(app_vars.packet, app_vars.pkt_len); radio_txEnable(); radio_txNow(); + + app_vars.state = S_DATA_SEND; } break; case T_RX: - if (app_vars.current_freq_setting>SYNC_FREQ_START+FREQ_RANGE){ if (app_vars.isSync) { @@ -323,11 +501,20 @@ void cb_calc_process_timer(void) { } else { // doesn't receive a valid frame during one slot to sync - // wait next slot to repeat + app_vars.current_freq_setting = SYNC_FREQ_START; } } else { + + app_vars.current_freq_setting += SWEEP_STEP; + LC_FREQCHANGE( + (app_vars.current_freq_setting & COARSE_MASK) >> COARSE_OFFSET, + (app_vars.current_freq_setting & MID_MASK) >> MID_OFFSET, + (app_vars.current_freq_setting & FINE_MASK) >> FINE_OFFSET + ); radio_rxEnable(); radio_rxNow(); + + app_vars.state = S_LISTEN_FOR_DATA; } break; diff --git a/scm_v3c/applications/quick_cal/quick_cal.uvoptx b/scm_v3c/applications/quick_cal/quick_cal.uvoptx index c2f68a91..ed8f6163 100644 --- a/scm_v3c/applications/quick_cal/quick_cal.uvoptx +++ b/scm_v3c/applications/quick_cal/quick_cal.uvoptx @@ -191,7 +191,7 @@ drv - 0 + 1 0 0 0 diff --git a/scm_v3c/gpio.c b/scm_v3c/gpio.c index f9adbc2d..d332d676 100644 --- a/scm_v3c/gpio.c +++ b/scm_v3c/gpio.c @@ -12,6 +12,7 @@ void gpio_init(void){ GPIO_REG__OUTPUT &= ~0xFFFF; // all PINS low at initial } +// frame void gpio_1_set(void){ GPIO_REG__OUTPUT |= 0x0002; } @@ -22,6 +23,7 @@ void gpio_1_toggle(void){ GPIO_REG__OUTPUT ^= 0x0002; } +// isr void gpio_2_set(void){ GPIO_REG__OUTPUT |= 0x0004; } @@ -32,6 +34,7 @@ void gpio_2_toggle(void){ GPIO_REG__OUTPUT ^= 0x0004; } +// slot void gpio_3_set(void){ GPIO_REG__OUTPUT |= 0x0008; } @@ -42,6 +45,7 @@ void gpio_3_toggle(void){ GPIO_REG__OUTPUT ^= 0x0008; } +// fsm void gpio_4_set(void){ GPIO_REG__OUTPUT |= 0x0010; } @@ -52,6 +56,7 @@ void gpio_4_toggle(void){ GPIO_REG__OUTPUT ^= 0x0010; } +// task void gpio_5_set(void){ GPIO_REG__OUTPUT |= 0x0020; } @@ -62,6 +67,7 @@ void gpio_5_toggle(void){ GPIO_REG__OUTPUT ^= 0x0020; } +// radio void gpio_6_set(void){ GPIO_REG__OUTPUT |= 0x0040; } diff --git a/scm_v3c/gpio.h b/scm_v3c/gpio.h index 0c8c068a..821c5668 100644 --- a/scm_v3c/gpio.h +++ b/scm_v3c/gpio.h @@ -11,26 +11,32 @@ void gpio_init(void); +// frame void gpio_1_set(void); void gpio_1_clr(void); void gpio_1_toggle(void); +// isr void gpio_2_set(void); void gpio_2_clr(void); void gpio_2_toggle(void); +// slot void gpio_3_set(void); void gpio_3_clr(void); void gpio_3_toggle(void); +// fsm void gpio_4_set(void); void gpio_4_clr(void); void gpio_4_toggle(void); +// task void gpio_5_set(void); void gpio_5_clr(void); void gpio_5_toggle(void); +// radio void gpio_6_set(void); void gpio_6_clr(void); void gpio_6_toggle(void); diff --git a/scm_v3c/radio.c b/scm_v3c/radio.c index 82c48659..6ad6b04d 100644 --- a/scm_v3c/radio.c +++ b/scm_v3c/radio.c @@ -7,6 +7,7 @@ #include "scm3c_hw_interface.h" #include "radio.h" #include "rftimer.h" +#include "gpio.h" // raw_chip interrupt related unsigned int chips[100]; @@ -616,6 +617,8 @@ void radio_isr(void) { unsigned int interrupt = RFCONTROLLER_REG__INT; unsigned int error = RFCONTROLLER_REG__ERROR; + gpio_2_set(); + radio_vars.crc_ok = true; if (error != 0) { @@ -701,6 +704,8 @@ void radio_isr(void) { } RFCONTROLLER_REG__INT_CLEAR = interrupt; + + gpio_2_clr(); } diff --git a/scm_v3c/rftimer.c b/scm_v3c/rftimer.c index 1bcf739f..7a629564 100644 --- a/scm_v3c/rftimer.c +++ b/scm_v3c/rftimer.c @@ -4,6 +4,7 @@ #include "scm3c_hw_interface.h" #include "radio.h" #include "rftimer.h" +#include "gpio.h" // ========================== definition ====================================== @@ -67,6 +68,8 @@ void rftimer_isr(void) { unsigned int interrupt = RFTIMER_REG__INT; + gpio_2_set(); + if (interrupt & 0x00000001){ #ifdef ENABLE_PRINTF printf("COMPARE0 MATCH\r\n"); @@ -170,4 +173,6 @@ void rftimer_isr(void) { } RFTIMER_REG__INT_CLEAR = interrupt; + + gpio_2_clr(); } \ No newline at end of file From 6332ca13bb8091bf8fa309d0b020ce1a7901a1f9 Mon Sep 17 00:00:00 2001 From: changtengfei Date: Mon, 16 Dec 2019 16:18:41 +0100 Subject: [PATCH 03/32] keep doing freq_sweep continuously when not sync'ed. --- scm_v3c/applications/quick_cal/quick_cal.c | 93 +++++++++++----------- scm_v3c/radio.c | 2 + 2 files changed, 49 insertions(+), 46 deletions(-) diff --git a/scm_v3c/applications/quick_cal/quick_cal.c b/scm_v3c/applications/quick_cal/quick_cal.c index 35b6a05c..2b6cab77 100644 --- a/scm_v3c/applications/quick_cal/quick_cal.c +++ b/scm_v3c/applications/quick_cal/quick_cal.c @@ -60,13 +60,13 @@ typedef enum{ S_LISTEN_FOR_ACK = 2, S_RECEIVING_DATA = 3, S_RECEIVING_ACK = 4, - S_RXPROC = 3, - S_DATA_SENDING = 4, - S_ACK_SENDING = 5, - S_DATA_SENDDONE = 6, - S_ACK_SENDDONE = 7, - S_DATA_SEND = 8, - S_ACK_SEND = 9, + S_RXPROC = 6, + S_DATA_SENDING = 7, + S_ACK_SENDING = 8, + S_DATA_SENDDONE = 9, + S_ACK_SENDDONE = 10, + S_DATA_SEND = 11, + S_ACK_SEND = 12, }state_t; typedef struct { @@ -186,7 +186,6 @@ int main(void) { // Enable interrupts for the radio FSM radio_enable_interrupts(); - app_vars.current_freq_setting = SYNC_FREQ_START; rftimer_setCompareIn(rftimer_readCounter()+SLOT_DURATION); while(1){ @@ -272,6 +271,8 @@ void cb_endFrame(uint32_t timestamp){ break; case T_RX: + gpio_7_toggle(); + memset(app_vars.packet,0,MAX_PKT_LEN); // get packet from radio @@ -342,7 +343,7 @@ void cb_endFrame(uint32_t timestamp){ break; default: - + printf("wrong state: type=%d, state=%d\r\n",app_vars.type, app_vars.state); break; } } @@ -440,24 +441,8 @@ void cb_calc_process_timer(void) { rftimer_disable_interrupts(); rftimer_set_callback(cb_calc_process_timer); - if ( - rftimer_readCounter()+ SUB_SLOT_DURATION - - ( - app_vars.slotReference + - app_vars.freq_setting_index*SUB_SLOT_DURATION - ) <= SUB_SLOT_DURATION - ) { - // slotReference is not changed - - } else { - // slotReference is updated - - app_vars.freq_setting_index = 0; - } - rftimer_setCompareIn( - app_vars.slotReference + \ - app_vars.freq_setting_index*SUB_SLOT_DURATION + rftimer_readCounter() + SUB_SLOT_DURATION ); } @@ -492,34 +477,50 @@ void cb_calc_process_timer(void) { break; case T_RX: - - if (app_vars.current_freq_setting>SYNC_FREQ_START+FREQ_RANGE){ - if (app_vars.isSync) { - // freq_sweep is done, calculate the freq_setting - // todo - + + switch(app_vars.state){ + case S_IDLE: + case S_LISTEN_FOR_DATA: + if (app_vars.current_freq_setting>SYNC_FREQ_START+FREQ_RANGE){ + if (app_vars.isSync) { + // freq_sweep is done, calculate the freq_setting + // todo + + } else { + // doesn't receive a valid frame during one slot to sync + + gpio_5_toggle(); + + app_vars.current_freq_setting = SYNC_FREQ_START; + } } else { - // doesn't receive a valid frame during one slot to sync - app_vars.current_freq_setting = SYNC_FREQ_START; + app_vars.current_freq_setting += SWEEP_STEP; + LC_FREQCHANGE( + (app_vars.current_freq_setting & COARSE_MASK) >> COARSE_OFFSET, + (app_vars.current_freq_setting & MID_MASK) >> MID_OFFSET, + (app_vars.current_freq_setting & FINE_MASK) >> FINE_OFFSET + ); + radio_rxEnable(); + radio_rxNow(); + + app_vars.state = S_LISTEN_FOR_DATA; } - } else { - - app_vars.current_freq_setting += SWEEP_STEP; - LC_FREQCHANGE( - (app_vars.current_freq_setting & COARSE_MASK) >> COARSE_OFFSET, - (app_vars.current_freq_setting & MID_MASK) >> MID_OFFSET, - (app_vars.current_freq_setting & FINE_MASK) >> FINE_OFFSET - ); - radio_rxEnable(); - radio_rxNow(); + break; + case S_RECEIVING_DATA: + // do nothing + + gpio_7_toggle(); - app_vars.state = S_LISTEN_FOR_DATA; + break; + default: + // wrong state + break; } break; default: - // wrong state + // wrong type break; } } diff --git a/scm_v3c/radio.c b/scm_v3c/radio.c index 6ad6b04d..f2fa3175 100644 --- a/scm_v3c/radio.c +++ b/scm_v3c/radio.c @@ -618,6 +618,7 @@ void radio_isr(void) { unsigned int error = RFCONTROLLER_REG__ERROR; gpio_2_set(); + gpio_6_set(); radio_vars.crc_ok = true; if (error != 0) { @@ -706,6 +707,7 @@ void radio_isr(void) { RFCONTROLLER_REG__INT_CLEAR = interrupt; gpio_2_clr(); + gpio_6_clr(); } From aba3abedfd839aa56db32e618c86a86816c6c3d4 Mon Sep 17 00:00:00 2001 From: changtengfei Date: Tue, 17 Dec 2019 14:33:39 +0100 Subject: [PATCH 04/32] SW-15. clear RF interrupt respectively. --- scm_v3c/radio.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/scm_v3c/radio.c b/scm_v3c/radio.c index f2fa3175..30221381 100644 --- a/scm_v3c/radio.c +++ b/scm_v3c/radio.c @@ -662,6 +662,8 @@ void radio_isr(void) { #ifdef ENABLE_PRINTF printf("TX LOAD DONE\r\n"); #endif + + RFCONTROLLER_REG__INT_CLEAR |= 0x00000001; } if (interrupt & 0x00000002) { @@ -672,6 +674,8 @@ void radio_isr(void) { if (radio_vars.startFrame_tx_cb != 0) { radio_vars.startFrame_tx_cb(RFTIMER_REG__COUNTER); } + + RFCONTROLLER_REG__INT_CLEAR |= 0x00000002; } if (interrupt & 0x00000004){ @@ -682,6 +686,8 @@ void radio_isr(void) { if (radio_vars.endFrame_tx_cb != 0) { radio_vars.endFrame_tx_cb(RFTIMER_REG__COUNTER); } + + RFCONTROLLER_REG__INT_CLEAR |= 0x00000004; } if (interrupt & 0x00000008){ @@ -692,6 +698,8 @@ void radio_isr(void) { if (radio_vars.startFrame_rx_cb != 0) { radio_vars.startFrame_rx_cb(RFTIMER_REG__COUNTER); } + + RFCONTROLLER_REG__INT_CLEAR |= 0x00000008; } if (interrupt & 0x00000010) { @@ -702,9 +710,11 @@ void radio_isr(void) { if (radio_vars.endFrame_rx_cb != 0) { radio_vars.endFrame_rx_cb(RFTIMER_REG__COUNTER); } + + RFCONTROLLER_REG__INT_CLEAR |= 0x00000010; } - RFCONTROLLER_REG__INT_CLEAR = interrupt; +// RFCONTROLLER_REG__INT_CLEAR = interrupt; gpio_2_clr(); gpio_6_clr(); From 527298456a93214d95c62caeef2b7bc8d7fcfe6f Mon Sep 17 00:00:00 2001 From: changtengfei Date: Tue, 17 Dec 2019 14:34:06 +0100 Subject: [PATCH 05/32] SW-15. clear pending bit before enable interrupt --- scm_v3c/rftimer.c | 11 ++++++++++- scm_v3c/rftimer.h | 1 + 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/scm_v3c/rftimer.c b/scm_v3c/rftimer.c index 7a629564..5833feb4 100644 --- a/scm_v3c/rftimer.c +++ b/scm_v3c/rftimer.c @@ -51,6 +51,10 @@ uint32_t rftimer_readCounter(void){ } void rftimer_enable_interrupts(void){ + + // clear pending bit first + rftimer_clear_interrupts(); + // enable compare interrupt (this also cancels any pending interrupts) RFTIMER_REG__COMPARE0_CONTROL = RFTIMER_COMPARE_ENABLE | \ RFTIMER_COMPARE_INTERRUPT_ENABLE; @@ -58,10 +62,15 @@ void rftimer_enable_interrupts(void){ } void rftimer_disable_interrupts(void){ - RFTIMER_REG__COMPARE0_CONTROL = 0x0; + // disable compare interrupt + RFTIMER_REG__COMPARE0_CONTROL = 0x0000; ICER = 0x80; } +void rftimer_clear_interrupts(void){ + RFTIMER_REG__INT_CLEAR = 0x0001; +} + // ========================== interrupt ======================================= void rftimer_isr(void) { diff --git a/scm_v3c/rftimer.h b/scm_v3c/rftimer.h index 912d6f0e..3412998c 100644 --- a/scm_v3c/rftimer.h +++ b/scm_v3c/rftimer.h @@ -21,6 +21,7 @@ void rftimer_set_callback(rftimer_cbt cb); uint32_t rftimer_readCounter(void); void rftimer_enable_interrupts(void); void rftimer_disable_interrupts(void); +void rftimer_clear_interrupts(void); void rftimer_isr(void); From efb54c297972ecab24acd05e81e102ec6cc1e18c Mon Sep 17 00:00:00 2001 From: changtengfei Date: Tue, 17 Dec 2019 14:34:41 +0100 Subject: [PATCH 06/32] SW-15. use large sub-slot duration to do freq_sweep. --- scm_v3c/applications/quick_cal/quick_cal.c | 184 +++++++++++++++--- .../applications/quick_cal/quick_cal.uvoptx | 2 +- 2 files changed, 156 insertions(+), 30 deletions(-) diff --git a/scm_v3c/applications/quick_cal/quick_cal.c b/scm_v3c/applications/quick_cal/quick_cal.c index 2b6cab77..7576279c 100644 --- a/scm_v3c/applications/quick_cal/quick_cal.c +++ b/scm_v3c/applications/quick_cal/quick_cal.c @@ -30,14 +30,17 @@ for each 16 channel with a quick_cal box. // timing #define SLOT_DURATION 500000 ///< 500 = 1ms@500kHz -#define SUB_SLOT_DURATION 305 ///< 305 = 610us@500kHz +#define TARGET_PKT_INTERVAL 305 ///< 305 = 610us@500kHz +#define SUB_SLOT_DURATION 460 ///< 305 = 610us@500kHz #define TXOFFSET 191 ///< measured, 382us +#define WD_DATA_SENDDONE 100 ///>measured, 161us 100 = 200us@500kHz // frequency settings #define SYNC_FREQ_START 22*32*32 #define FREQ_RANGE 2*32*32 #define SWEEP_STEP 2 -#define NUM_PKT_PER_SLOT 32*32 +//#define NUM_PKT_PER_SLOT 32*32 +#define NUM_PKT_PER_SLOT (SLOT_DURATION/TARGET_PKT_INTERVAL-2) #define COARSE_MASK (0x001f<<10) #define COARSE_OFFSET 10 @@ -113,6 +116,7 @@ void cb_startFrame(uint32_t timestamp); void cb_endFrame(uint32_t timestamp); void cb_slot_timer(void); void cb_calc_process_timer(void); +void cb_timeout_error(void); void synchronize(uint32_t capturedTime, uint8_t pkt_channel, uint16_t pkt_seqNum); @@ -208,7 +212,7 @@ void synchronize(uint32_t capturedTime, uint8_t pkt_channel, uint16_t pkt_seqNum // synchronize to slot boudary rftimer_disable_interrupts(); - slot_boudary = capturedTime - pkt_seqNum*SUB_SLOT_DURATION - TXOFFSET; + slot_boudary = capturedTime - pkt_seqNum*TARGET_PKT_INTERVAL - TXOFFSET; rftimer_set_callback(cb_slot_timer); rftimer_setCompareIn(slot_boudary+SLOT_DURATION); @@ -230,9 +234,20 @@ void cb_startFrame(uint32_t timestamp){ switch(app_vars.state){ case S_LISTEN_FOR_DATA: app_vars.state = S_RECEIVING_DATA; + + // set watch dog + rftimer_disable_interrupts(); + rftimer_set_callback(cb_timeout_error); + rftimer_setCompareIn(rftimer_readCounter()+WD_DATA_SENDDONE); + break; case S_LISTEN_FOR_ACK: app_vars.state = S_RECEIVING_ACK; + + // set watch dog + rftimer_disable_interrupts(); + rftimer_set_callback(cb_timeout_error); + rftimer_setCompareIn(rftimer_readCounter()+WD_DATA_SENDDONE); break; default: // something goes wrong @@ -304,19 +319,40 @@ void cb_endFrame(uint32_t timestamp){ if (isValidFrame){ if (app_vars.isSync){ + switch(app_vars.state){ case S_RECEIVING_DATA: - // doing calibration on rx channel + rftimer_disable_interrupts(); + rftimer_set_callback(cb_calc_process_timer); + rftimer_setCompareIn(rftimer_readCounter()+SUB_SLOT_DURATION); + + gpio_1_toggle(); - app_vars.freq_setting_sample[app_vars.sample_index++] = \ - app_vars.current_freq_setting; + if ( + app_vars.currentSlotOffset==0 && + app_vars.freq_setting_rx[0] != 0 + ) { + // resynchronize + synchronize(app_vars.lastCaptureTime, pkt_channel, pkt_seqNum); + + } else { + + // doing calibration on rx channel + + app_vars.freq_setting_sample[app_vars.sample_index++] = \ + app_vars.current_freq_setting; + } app_vars.state = S_IDLE; break; case S_RECEIVING_ACK: + rftimer_disable_interrupts(); + rftimer_set_callback(cb_calc_process_timer); + rftimer_setCompareIn(rftimer_readCounter()+SUB_SLOT_DURATION); + // doing calibration on tx channel app_vars.freq_setting_sample[app_vars.sample_index++] = \ @@ -331,6 +367,8 @@ void cb_endFrame(uint32_t timestamp){ } } else { + printf("channel=%d, seqNum=%d\r\n", pkt_channel, pkt_seqNum); + // synchronize to the network synchronize(app_vars.lastCaptureTime, pkt_channel, pkt_seqNum); @@ -362,8 +400,6 @@ void cb_slot_timer(void) { if (app_vars.freq_setting_rx_done){ - app_vars.type = T_TX; - app_vars.packet[0] = 0xCA; app_vars.packet[1] = 0xFE; @@ -371,12 +407,26 @@ void cb_slot_timer(void) { // skip slot 0 as all motes are listening on ch11 except root - // no way to calculate channel rx_11 + // re-sync + app_vars.type = T_RX; + + app_vars.current_freq_setting = app_vars.freq_setting_rx[0]; + LC_FREQCHANGE( + (app_vars.current_freq_setting & COARSE_MASK) >> COARSE_OFFSET, + (app_vars.current_freq_setting & MID_MASK) >> MID_OFFSET, + (app_vars.current_freq_setting & FINE_MASK) >> FINE_OFFSET + ); + radio_rxEnable(); + radio_rxNow(); + + app_vars.state = S_LISTEN_FOR_DATA; return; } else { + app_vars.type = T_TX; + app_vars.channel_to_calc = \ app_vars.currentSlotOffset-1 + SYNC_CHANNEL; @@ -397,7 +447,30 @@ void cb_slot_timer(void) { if (app_vars.currentSlotOffset==0){ - app_vars.current_freq_setting = SYNC_FREQ_START; + if (app_vars.freq_setting_rx[0]!=0){ + + // channel rx_11 found already + + // re-sync + app_vars.current_freq_setting = app_vars.freq_setting_rx[0]; + LC_FREQCHANGE( + (app_vars.current_freq_setting & COARSE_MASK) >> COARSE_OFFSET, + (app_vars.current_freq_setting & MID_MASK) >> MID_OFFSET, + (app_vars.current_freq_setting & FINE_MASK) >> FINE_OFFSET + ); + radio_rxEnable(); + radio_rxNow(); + + app_vars.state = S_LISTEN_FOR_DATA; + + return; + } else { + + // channel rx_11 not found, setup freq sweep process + + app_vars.freq_setting_index = 0; + app_vars.current_freq_setting = SYNC_FREQ_START; + } } else { if (app_vars.freq_setting_rx[app_vars.currentSlotOffset-1]==0){ @@ -411,8 +484,13 @@ void cb_slot_timer(void) { } else { - app_vars.current_freq_setting = - app_vars.freq_setting_rx[app_vars.currentSlotOffset-1]; + if (app_vars.freq_setting_rx[app_vars.currentSlotOffset]==0){ + + app_vars.current_freq_setting = + app_vars.freq_setting_rx[app_vars.currentSlotOffset-1]; + } else { + // channel rx_(11+currentSlotOffset) found already + } } } @@ -429,24 +507,18 @@ void cb_slot_timer(void) { void cb_calc_process_timer(void) { + uint8_t i; + uint8_t last_sample; + gpio_4_toggle(); app_vars.freq_setting_index = 1+app_vars.freq_setting_index; - if (app_vars.isSync && app_vars.freq_setting_index>FREQ_RANGE/SWEEP_STEP){ - rftimer_disable_interrupts(); - rftimer_set_callback(cb_slot_timer); - rftimer_setCompareIn(app_vars.slotReference + SLOT_DURATION); - } else { - rftimer_disable_interrupts(); - rftimer_set_callback(cb_calc_process_timer); - - rftimer_setCompareIn( - rftimer_readCounter() + SUB_SLOT_DURATION - ); - } - - radio_rfOff(); + rftimer_disable_interrupts(); + rftimer_set_callback(cb_calc_process_timer); + rftimer_setCompareIn( + rftimer_readCounter() + SUB_SLOT_DURATION + ); switch(app_vars.type){ @@ -455,6 +527,8 @@ void cb_calc_process_timer(void) { if (app_vars.current_freq_settingSYNC_FREQ_START+FREQ_RANGE){ if (app_vars.isSync) { // freq_sweep is done, calculate the freq_setting - // todo - } else { - // doesn't receive a valid frame during one slot to sync + rftimer_disable_interrupts(); + rftimer_set_callback(cb_slot_timer); + rftimer_setCompareIn(app_vars.slotReference + SLOT_DURATION); + last_sample = 0; + gpio_5_toggle(); + if (app_vars.freq_setting_sample[0]!=0){ + for (i=0;i app - 0 + 1 0 0 0 From c381d163f4e5a934d460395ce2c380abd3a531ad Mon Sep 17 00:00:00 2001 From: changtengfei Date: Tue, 17 Dec 2019 17:24:39 +0100 Subject: [PATCH 07/32] SW-15. calculate the freq_setting_rx for different channels. --- scm_v3c/applications/quick_cal/quick_cal.c | 61 ++++++++++++++++++---- 1 file changed, 50 insertions(+), 11 deletions(-) diff --git a/scm_v3c/applications/quick_cal/quick_cal.c b/scm_v3c/applications/quick_cal/quick_cal.c index 7576279c..80e4001a 100644 --- a/scm_v3c/applications/quick_cal/quick_cal.c +++ b/scm_v3c/applications/quick_cal/quick_cal.c @@ -31,7 +31,7 @@ for each 16 channel with a quick_cal box. // timing #define SLOT_DURATION 500000 ///< 500 = 1ms@500kHz #define TARGET_PKT_INTERVAL 305 ///< 305 = 610us@500kHz -#define SUB_SLOT_DURATION 460 ///< 305 = 610us@500kHz +#define SUB_SLOT_DURATION 450 ///< 305 = 610us@500kHz #define TXOFFSET 191 ///< measured, 382us #define WD_DATA_SENDDONE 100 ///>measured, 161us 100 = 200us@500kHz @@ -325,7 +325,12 @@ void cb_endFrame(uint32_t timestamp){ rftimer_disable_interrupts(); rftimer_set_callback(cb_calc_process_timer); - rftimer_setCompareIn(rftimer_readCounter()+SUB_SLOT_DURATION); + + if (app_vars.freq_setting_rx[app_vars.currentSlotOffset]==0) { + rftimer_setCompareIn(rftimer_readCounter()+SUB_SLOT_DURATION); + } else { + rftimer_setCompareIn(app_vars.slotReference+SLOT_DURATION); + } gpio_1_toggle(); @@ -338,10 +343,14 @@ void cb_endFrame(uint32_t timestamp){ } else { - // doing calibration on rx channel + // doing calibration on rx channel if haven't yet - app_vars.freq_setting_sample[app_vars.sample_index++] = \ - app_vars.current_freq_setting; + if (app_vars.freq_setting_rx[app_vars.currentSlotOffset]==0){ + + app_vars.freq_setting_sample[app_vars.sample_index++] = \ + app_vars.current_freq_setting; + } + } app_vars.state = S_IDLE; @@ -396,6 +405,8 @@ void cb_slot_timer(void) { app_vars.currentSlotOffset = \ (app_vars.currentSlotOffset+1) % SLOTFRAME_LEN; + app_vars.state = S_IDLE; + if (app_vars.isSync){ if (app_vars.freq_setting_rx_done){ @@ -485,11 +496,26 @@ void cb_slot_timer(void) { } else { if (app_vars.freq_setting_rx[app_vars.currentSlotOffset]==0){ - + + // doing freq_sweep for target channel + app_vars.current_freq_setting = app_vars.freq_setting_rx[app_vars.currentSlotOffset-1]; } else { // channel rx_(11+currentSlotOffset) found already + + app_vars.current_freq_setting = app_vars.freq_setting_rx[app_vars.currentSlotOffset]; + LC_FREQCHANGE( + (app_vars.current_freq_setting & COARSE_MASK) >> COARSE_OFFSET, + (app_vars.current_freq_setting & MID_MASK) >> MID_OFFSET, + (app_vars.current_freq_setting & FINE_MASK) >> FINE_OFFSET + ); + radio_rxEnable(); + radio_rxNow(); + + app_vars.state = S_LISTEN_FOR_DATA; + + return; } } } @@ -507,8 +533,9 @@ void cb_slot_timer(void) { void cb_calc_process_timer(void) { - uint8_t i; - uint8_t last_sample; + uint8_t i; + uint8_t last_sample; + uint32_t start_frequency; gpio_4_toggle(); @@ -555,8 +582,20 @@ void cb_calc_process_timer(void) { switch(app_vars.state){ case S_IDLE: case S_LISTEN_FOR_DATA: + + // get start frequncy to sweep + + if (app_vars.isSync){ + if (app_vars.currentSlotOffset==0){ + start_frequency = SYNC_FREQ_START; + } else { + start_frequency = app_vars.freq_setting_rx[app_vars.currentSlotOffset-1]; + } + } else { + start_frequency = SYNC_FREQ_START; + } - if (app_vars.current_freq_setting>SYNC_FREQ_START+FREQ_RANGE){ + if (app_vars.current_freq_setting>start_frequency+FREQ_RANGE){ if (app_vars.isSync) { // freq_sweep is done, calculate the freq_setting @@ -565,7 +604,7 @@ void cb_calc_process_timer(void) { rftimer_setCompareIn(app_vars.slotReference + SLOT_DURATION); last_sample = 0; - + gpio_5_toggle(); if (app_vars.freq_setting_sample[0]!=0){ @@ -587,7 +626,7 @@ void cb_calc_process_timer(void) { break; } } - printf("last_sample=%d rx_%d=%d\r\n", + printf("num_sample=%d rx_%d=%d\r\n", last_sample, app_vars.currentSlotOffset+SYNC_CHANNEL, app_vars.freq_setting_rx[app_vars.currentSlotOffset] From a1f0b14cab4517a848efa444c2c06e4d2a78d667 Mon Sep 17 00:00:00 2001 From: changtengfei Date: Wed, 18 Dec 2019 14:29:42 +0100 Subject: [PATCH 08/32] SW-15. bug fixes. --- scm_v3c/applications/quick_cal/quick_cal.c | 77 ++++++++++++++++------ 1 file changed, 56 insertions(+), 21 deletions(-) diff --git a/scm_v3c/applications/quick_cal/quick_cal.c b/scm_v3c/applications/quick_cal/quick_cal.c index 80e4001a..4eea2ee4 100644 --- a/scm_v3c/applications/quick_cal/quick_cal.c +++ b/scm_v3c/applications/quick_cal/quick_cal.c @@ -31,7 +31,7 @@ for each 16 channel with a quick_cal box. // timing #define SLOT_DURATION 500000 ///< 500 = 1ms@500kHz #define TARGET_PKT_INTERVAL 305 ///< 305 = 610us@500kHz -#define SUB_SLOT_DURATION 450 ///< 305 = 610us@500kHz +#define SUB_SLOT_DURATION 400 ///< 305 = 610us@500kHz #define TXOFFSET 191 ///< measured, 382us #define WD_DATA_SENDDONE 100 ///>measured, 161us 100 = 200us@500kHz @@ -301,34 +301,49 @@ void cb_endFrame(uint32_t timestamp){ // check the frame is valid or not - isValidFrame = false; + isValidFrame = true; if (app_vars.pkt_len == TARGET_PKT_LEN){ - pkt_channel = (app_vars.packet[0] & 0xf0)>>4; + pkt_channel = SYNC_CHANNEL+((app_vars.packet[0] & 0xf0)>>4); pkt_seqNum = ((uint16_t)(app_vars.packet[0] & 0x0f))<<8 | (uint16_t)(app_vars.packet[1]); - if ( - pkt_channel>=11 && - pkt_channel<=26 && - pkt_seqNum=NUM_PKT_PER_SLOT){ + isValidFrame = false; + } + + if (app_vars.isSync){ + if ((pkt_channel - SYNC_CHANNEL)!= app_vars.currentSlotOffset){ + isValidFrame = false; + } + } else { + if (pkt_channel != SYNC_CHANNEL){ + isValidFrame = false; + } } + } else { + + isValidFrame = false; } if (isValidFrame){ + + gpio_8_toggle(); + if (app_vars.isSync){ switch(app_vars.state){ case S_RECEIVING_DATA: rftimer_disable_interrupts(); - rftimer_set_callback(cb_calc_process_timer); if (app_vars.freq_setting_rx[app_vars.currentSlotOffset]==0) { + + rftimer_set_callback(cb_calc_process_timer); rftimer_setCompareIn(rftimer_readCounter()+SUB_SLOT_DURATION); } else { + rftimer_set_callback(cb_slot_timer); rftimer_setCompareIn(app_vars.slotReference+SLOT_DURATION); } @@ -346,7 +361,7 @@ void cb_endFrame(uint32_t timestamp){ // doing calibration on rx channel if haven't yet if (app_vars.freq_setting_rx[app_vars.currentSlotOffset]==0){ - + app_vars.freq_setting_sample[app_vars.sample_index++] = \ app_vars.current_freq_setting; } @@ -376,7 +391,13 @@ void cb_endFrame(uint32_t timestamp){ } } else { - printf("channel=%d, seqNum=%d\r\n", pkt_channel, pkt_seqNum); + printf( + "channel=%d, seqNum=%d coarse=%d, mid=%d, fine=%d\r\n", + pkt_channel, pkt_seqNum, + (app_vars.current_freq_setting & COARSE_MASK) >> COARSE_OFFSET, + (app_vars.current_freq_setting & MID_MASK) >> MID_OFFSET, + (app_vars.current_freq_setting & FINE_MASK) >> FINE_OFFSET + ); // synchronize to the network synchronize(app_vars.lastCaptureTime, pkt_channel, pkt_seqNum); @@ -599,6 +620,8 @@ void cb_calc_process_timer(void) { if (app_vars.isSync) { // freq_sweep is done, calculate the freq_setting + radio_rfOff(); + rftimer_disable_interrupts(); rftimer_set_callback(cb_slot_timer); rftimer_setCompareIn(app_vars.slotReference + SLOT_DURATION); @@ -626,11 +649,16 @@ void cb_calc_process_timer(void) { break; } } - printf("num_sample=%d rx_%d=%d\r\n", + printf("num_sample=%d rx_%d= corase=%d, mid=%d, fine=%d\r\n", last_sample, app_vars.currentSlotOffset+SYNC_CHANNEL, - app_vars.freq_setting_rx[app_vars.currentSlotOffset] + (app_vars.freq_setting_rx[app_vars.currentSlotOffset] & COARSE_MASK) >> COARSE_OFFSET, + (app_vars.freq_setting_rx[app_vars.currentSlotOffset] & MID_MASK) >> MID_OFFSET, + (app_vars.freq_setting_rx[app_vars.currentSlotOffset] & FINE_MASK) >> FINE_OFFSET + ); + } else { + printf("no sample found??\r\n"); } } else { @@ -681,11 +709,18 @@ void cb_timeout_error(void){ // change state app_vars.state = S_IDLE; - // skip one setting - app_vars.freq_setting_index = 1+app_vars.freq_setting_index; - app_vars.current_freq_setting += SWEEP_STEP; - - // schedule next sub slot - rftimer_set_callback(cb_calc_process_timer); - rftimer_setCompareIn(rftimer_readCounter()+SUB_SLOT_DURATION); + if (app_vars.freq_setting_rx[app_vars.currentSlotOffset]==0) { + + // skip one setting + app_vars.freq_setting_index = 1+app_vars.freq_setting_index; + app_vars.current_freq_setting += SWEEP_STEP; + + // schedule next sub slot + rftimer_set_callback(cb_calc_process_timer); + rftimer_setCompareIn(rftimer_readCounter()+SUB_SLOT_DURATION); + } else { + // schedule next slot + rftimer_set_callback(cb_slot_timer); + rftimer_setCompareIn(app_vars.slotReference+SLOT_DURATION); + } } From 8990d8bcc18fb6527aca03c76de97e78ca9cc17d Mon Sep 17 00:00:00 2001 From: changtengfei Date: Tue, 24 Dec 2019 15:54:01 +0100 Subject: [PATCH 09/32] SW-15. rewrite slot_cb according to flowchat. --- scm_v3c/applications/quick_cal/quick_cal.c | 405 +++++++++++++----- .../applications/quick_cal/quick_cal.uvoptx | 4 +- 2 files changed, 302 insertions(+), 107 deletions(-) diff --git a/scm_v3c/applications/quick_cal/quick_cal.c b/scm_v3c/applications/quick_cal/quick_cal.c index 4eea2ee4..edc958da 100644 --- a/scm_v3c/applications/quick_cal/quick_cal.c +++ b/scm_v3c/applications/quick_cal/quick_cal.c @@ -36,7 +36,8 @@ for each 16 channel with a quick_cal box. #define WD_DATA_SENDDONE 100 ///>measured, 161us 100 = 200us@500kHz // frequency settings -#define SYNC_FREQ_START 22*32*32 +#define SYNC_FREQ_START_RX 22*32*32 +#define SYNC_FREQ_START_TX 22*32*32 #define FREQ_RANGE 2*32*32 #define SWEEP_STEP 2 //#define NUM_PKT_PER_SLOT 32*32 @@ -49,6 +50,8 @@ for each 16 channel with a quick_cal box. #define FINE_MASK (0x001f) #define FINE_OFFSET 0 +#define MAGIC_BYTE 0xCF // Crystal Free + //=========================== variables ======================================= typedef enum{ @@ -185,7 +188,7 @@ int main(void) { app_vars.currentSlotOffset = SLOTFRAME_LEN - 1; app_vars.freq_setting_index = 0; - app_vars.current_freq_setting = SYNC_FREQ_START; + app_vars.current_freq_setting = SYNC_FREQ_START_RX; // Enable interrupts for the radio FSM radio_enable_interrupts(); @@ -365,7 +368,6 @@ void cb_endFrame(uint32_t timestamp){ app_vars.freq_setting_sample[app_vars.sample_index++] = \ app_vars.current_freq_setting; } - } app_vars.state = S_IDLE; @@ -418,6 +420,10 @@ void cb_endFrame(uint32_t timestamp){ void cb_slot_timer(void) { + uint8_t temp; + bool tx_ch_11_to_25_done; + uint8_t i; + gpio_3_toggle(); app_vars.slotReference = rftimer_readCounter(); @@ -430,14 +436,18 @@ void cb_slot_timer(void) { if (app_vars.isSync){ - if (app_vars.freq_setting_rx_done){ + // sync'ed + + if (app_vars.currentSlotOffset==0){ - app_vars.packet[0] = 0xCA; - app_vars.packet[1] = 0xFE; + // sync'ed + // slot 0 - if (app_vars.currentSlotOffset==0){ + if (app_vars.freq_setting_rx_done){ - // skip slot 0 as all motes are listening on ch11 except root + // sync'ed + // slot 0 + // freq_setting_RX_done is TRUE // re-sync app_vars.type = T_RX; @@ -453,33 +463,13 @@ void cb_slot_timer(void) { app_vars.state = S_LISTEN_FOR_DATA; - return; - } else { - app_vars.type = T_TX; - - app_vars.channel_to_calc = \ - app_vars.currentSlotOffset-1 + SYNC_CHANNEL; - - app_vars.freq_setting_index = 0; - app_vars.current_freq_setting = - app_vars.freq_setting_rx[app_vars.currentSlotOffset]; - cb_calc_process_timer(); - } - - } else { - - // sweep frequency setting to find one Rx channel - - app_vars.type = T_RX; - - app_vars.channel_to_calc = \ - app_vars.currentSlotOffset + SYNC_CHANNEL; - - if (app_vars.currentSlotOffset==0){ + // sync'ed + // slot 0 + // freq_setting_RX_done is FALSE - if (app_vars.freq_setting_rx[0]!=0){ + if (app_vars.freq_setting_rx[0] != 0){ // channel rx_11 found already @@ -495,23 +485,120 @@ void cb_slot_timer(void) { app_vars.state = S_LISTEN_FOR_DATA; - return; } else { + app_vars.type = T_RX; + + app_vars.channel_to_calc = app_vars.currentSlotOffset + SYNC_CHANNEL; + // channel rx_11 not found, setup freq sweep process app_vars.freq_setting_index = 0; - app_vars.current_freq_setting = SYNC_FREQ_START; + app_vars.current_freq_setting = SYNC_FREQ_START_RX; + + app_vars.freq_setting_index = 0; + cb_calc_process_timer(); + } + } + } else { + + // sync'ed + // slot 1 - 15 + + if (app_vars.freq_setting_rx_done){ + + // sync'ed + // slot 1 - 15 + // freq_setting_RX_done is TRUE + + app_vars.type = T_TX; + + app_vars.packet[0] = app_vars.currentSlotOffset << 4; + app_vars.packet[1] = MAGIC_BYTE; + + if (app_vars.freq_setting_tx_done){ + + // sync'ed + // slot 1 - 15 + // freq_setting_RX_done is TRUE + // freq_setting_TX_done is TRUE + + app_vars.current_freq_setting = app_vars.freq_setting_tx[app_vars.currentSlotOffset-1]; + LC_FREQCHANGE( + (app_vars.current_freq_setting & COARSE_MASK) >> COARSE_OFFSET, + (app_vars.current_freq_setting & MID_MASK) >> MID_OFFSET, + (app_vars.current_freq_setting & FINE_MASK) >> FINE_OFFSET + ); + app_vars.pkt_len = TARGET_PKT_LEN; + radio_loadPacket(app_vars.packet, app_vars.pkt_len); + radio_txEnable(); + radio_txNow(); + + } else { + + // sync'ed + // slot 1 - 15 + // freq_setting_RX_done is TRUE + // freq_setting_TX_done is FALSE + + if (app_vars.currentSlotOffset==1){ + + // sync'ed + // slot 1 + // freq_setting_RX_done is TRUE + // freq_setting_TX_done is FALSE + + // check whether channel 11-25 settings are recorded + + tx_ch_11_to_25_done = true; + for (i=0;i<15;i++){ + if (app_vars.freq_setting_tx[i]==0){ + tx_ch_11_to_25_done = false; + break; + } + } + + if (tx_ch_11_to_25_done){ + // calculate for channel 26 + app_vars.channel_to_calc = 26; + + // start with tx freq_setting of channel 25 + app_vars.current_freq_setting = app_vars.freq_setting_tx[14]; + } else { + app_vars.channel_to_calc = app_vars.currentSlotOffset-1 + SYNC_CHANNEL; + app_vars.current_freq_setting = SYNC_FREQ_START_TX; + } + } else { + + // sync'ed + // slot 2 - 15 + // freq_setting_RX_done is TRUE + // freq_setting_TX_done is FALSE + + app_vars.channel_to_calc = app_vars.currentSlotOffset-1 + SYNC_CHANNEL; + app_vars.current_freq_setting = app_vars.freq_setting_rx[app_vars.currentSlotOffset-1]; + } + + app_vars.freq_setting_index = 0; + cb_calc_process_timer(); } } else { + // sync'ed + // slot 1 - 15 + // freq_setting_RX_done is FALSE + + app_vars.type = T_RX; + if (app_vars.freq_setting_rx[app_vars.currentSlotOffset-1]==0){ - // the previous frequency is unknown + // The previous frequency is unknown - // don't performance frequency sweep + // Don't performance frequency sweep // something goes wrong + printf("current slot=%d: previous frequency is unknonw \r\n",app_vars.currentSlotOffset); + return; } else { @@ -519,9 +606,11 @@ void cb_slot_timer(void) { if (app_vars.freq_setting_rx[app_vars.currentSlotOffset]==0){ // doing freq_sweep for target channel + app_vars.channel_to_calc = app_vars.currentSlotOffset + SYNC_CHANNEL; + app_vars.freq_setting_index = 0; + app_vars.current_freq_setting = app_vars.freq_setting_rx[app_vars.currentSlotOffset-1]; + cb_calc_process_timer(); - app_vars.current_freq_setting = - app_vars.freq_setting_rx[app_vars.currentSlotOffset-1]; } else { // channel rx_(11+currentSlotOffset) found already @@ -535,19 +624,18 @@ void cb_slot_timer(void) { radio_rxNow(); app_vars.state = S_LISTEN_FOR_DATA; - - return; } } } - - app_vars.freq_setting_index = 0; - cb_calc_process_timer(); } } else { + // de-sync + app_vars.type = T_RX; + app_vars.freq_setting_index = 0; + app_vars.current_freq_setting = SYNC_FREQ_START_RX; cb_calc_process_timer(); } } @@ -560,64 +648,150 @@ void cb_calc_process_timer(void) { gpio_4_toggle(); + // increment freq_setting index app_vars.freq_setting_index = 1+app_vars.freq_setting_index; + // reschedule sub calc_process rftimer_disable_interrupts(); rftimer_set_callback(cb_calc_process_timer); - rftimer_setCompareIn( - rftimer_readCounter() + SUB_SLOT_DURATION - ); + rftimer_setCompareIn(rftimer_readCounter() + SUB_SLOT_DURATION); switch(app_vars.type){ - case T_TX: + case T_TX: + + // swept 2 coarse setting already? - if (app_vars.current_freq_setting> COARSE_OFFSET, - (app_vars.current_freq_setting & MID_MASK) >> MID_OFFSET, - (app_vars.current_freq_setting & FINE_MASK) >> FINE_OFFSET - ); - app_vars.pkt_len = TARGET_PKT_LEN; - radio_loadPacket(app_vars.packet, app_vars.pkt_len); - radio_txEnable(); - radio_txNow(); - - app_vars.state = S_DATA_SEND; - } - - break; - case T_RX: - switch(app_vars.state){ - case S_IDLE: - case S_LISTEN_FOR_DATA: + // check if 2 coarse freq_sweep is done - // get start frequncy to sweep + if (app_vars.current_freq_setting> COARSE_OFFSET, + (app_vars.freq_setting_tx[app_vars.currentSlotOffset] & MID_MASK) >> MID_OFFSET, + (app_vars.freq_setting_tx[app_vars.currentSlotOffset] & FINE_MASK) >> FINE_OFFSET + + ); + } else { + printf("no sample found??\r\n"); + } + } else { + printf("trying to calibrate tx freq_setting when de-sync!!\r\n"); + } + } else { + + switch(app_vars.state){ + case S_RECEIVING_ACK: + gpio_7_toggle(); + break; + default: + app_vars.current_freq_setting += SWEEP_STEP; + LC_FREQCHANGE( + (app_vars.current_freq_setting & COARSE_MASK) >> COARSE_OFFSET, + (app_vars.current_freq_setting & MID_MASK) >> MID_OFFSET, + (app_vars.current_freq_setting & FINE_MASK) >> FINE_OFFSET + ); + app_vars.pkt_len = TARGET_PKT_LEN; + radio_loadPacket(app_vars.packet, app_vars.pkt_len); + radio_txEnable(); + radio_txNow(); + + app_vars.state = S_DATA_SEND; + break; + } + } + break; + case T_RX: + // determine the start_frequency according to slotoffset + if (app_vars.isSync){ if (app_vars.currentSlotOffset==0){ - start_frequency = SYNC_FREQ_START; + start_frequency = SYNC_FREQ_START_RX; } else { start_frequency = app_vars.freq_setting_rx[app_vars.currentSlotOffset-1]; } } else { - start_frequency = SYNC_FREQ_START; + start_frequency = SYNC_FREQ_START_RX; } - + + // check if 2 coarse freq_sweep is done + if (app_vars.current_freq_setting>start_frequency+FREQ_RANGE){ + if (app_vars.isSync) { + // freq_sweep is done, calculate the freq_setting radio_rfOff(); @@ -627,15 +801,23 @@ void cb_calc_process_timer(void) { rftimer_setCompareIn(app_vars.slotReference + SLOT_DURATION); last_sample = 0; - + gpio_5_toggle(); + // check if there is freq_setting sample recorded + if (app_vars.freq_setting_sample[0]!=0){ + + // found at least one setting sample + for (i=0;i> COARSE_OFFSET, - (app_vars.current_freq_setting & MID_MASK) >> MID_OFFSET, - (app_vars.current_freq_setting & FINE_MASK) >> FINE_OFFSET - ); - radio_rxEnable(); - radio_rxNow(); - - app_vars.state = S_LISTEN_FOR_DATA; + switch(app_vars.state){ + case S_IDLE: + case S_LISTEN_FOR_DATA: + app_vars.current_freq_setting += SWEEP_STEP; + LC_FREQCHANGE( + (app_vars.current_freq_setting & COARSE_MASK) >> COARSE_OFFSET, + (app_vars.current_freq_setting & MID_MASK) >> MID_OFFSET, + (app_vars.current_freq_setting & FINE_MASK) >> FINE_OFFSET + ); + radio_rxEnable(); + radio_rxNow(); + + app_vars.state = S_LISTEN_FOR_DATA; + break; + case S_RECEIVING_DATA: + gpio_7_toggle(); + break; + default: + // something wrong + printf("wrong state in calc_process!\r\n"); + break; + } } break; - case S_RECEIVING_DATA: - // do nothing - - gpio_7_toggle(); - - break; default: - // wrong state + // wrong type break; - } - - break; - default: - // wrong type - break; } } diff --git a/scm_v3c/applications/quick_cal/quick_cal.uvoptx b/scm_v3c/applications/quick_cal/quick_cal.uvoptx index ea1c4473..c2f68a91 100644 --- a/scm_v3c/applications/quick_cal/quick_cal.uvoptx +++ b/scm_v3c/applications/quick_cal/quick_cal.uvoptx @@ -171,7 +171,7 @@ app - 1 + 0 0 0 0 @@ -191,7 +191,7 @@ drv - 1 + 0 0 0 0 From 5569250287c7f24a1ae32c7f357e05337a937a49 Mon Sep 17 00:00:00 2001 From: changtengfei Date: Tue, 24 Dec 2019 16:03:57 +0100 Subject: [PATCH 10/32] SW-15. update endFrame according to flowchat. --- scm_v3c/applications/quick_cal/quick_cal.c | 65 +++++++++++----------- 1 file changed, 34 insertions(+), 31 deletions(-) diff --git a/scm_v3c/applications/quick_cal/quick_cal.c b/scm_v3c/applications/quick_cal/quick_cal.c index edc958da..9e118a23 100644 --- a/scm_v3c/applications/quick_cal/quick_cal.c +++ b/scm_v3c/applications/quick_cal/quick_cal.c @@ -229,38 +229,38 @@ void cb_startFrame(uint32_t timestamp){ app_vars.lastCaptureTime = timestamp; switch(app_vars.type){ - case T_TX: - - break; - case T_RX: - - switch(app_vars.state){ - case S_LISTEN_FOR_DATA: - app_vars.state = S_RECEIVING_DATA; - - // set watch dog - rftimer_disable_interrupts(); - rftimer_set_callback(cb_timeout_error); - rftimer_setCompareIn(rftimer_readCounter()+WD_DATA_SENDDONE); - + case T_TX: + break; - case S_LISTEN_FOR_ACK: - app_vars.state = S_RECEIVING_ACK; - - // set watch dog - rftimer_disable_interrupts(); - rftimer_set_callback(cb_timeout_error); - rftimer_setCompareIn(rftimer_readCounter()+WD_DATA_SENDDONE); + case T_RX: + + switch(app_vars.state){ + case S_LISTEN_FOR_DATA: + app_vars.state = S_RECEIVING_DATA; + + // set watch dog + rftimer_disable_interrupts(); + rftimer_set_callback(cb_timeout_error); + rftimer_setCompareIn(rftimer_readCounter()+WD_DATA_SENDDONE); + + break; + case S_LISTEN_FOR_ACK: + app_vars.state = S_RECEIVING_ACK; + + // set watch dog + rftimer_disable_interrupts(); + rftimer_set_callback(cb_timeout_error); + rftimer_setCompareIn(rftimer_readCounter()+WD_DATA_SENDDONE); + break; + default: + // something goes wrong + break; + } + break; default: - // something goes wrong + break; - } - - break; - default: - - break; } } @@ -269,6 +269,7 @@ void cb_endFrame(uint32_t timestamp){ bool isValidFrame; uint8_t pkt_channel; uint16_t pkt_seqNum; + uint8_t setting_index; radio_rfOff(); @@ -277,10 +278,12 @@ void cb_endFrame(uint32_t timestamp){ app_vars.type = T_RX; + setting_index = app_vars.channel_to_calc-SYNC_CHANNEL; + LC_FREQCHANGE( - (app_vars.freq_setting_rx[app_vars.currentSlotOffset] & COARSE_MASK) >> COARSE_OFFSET, - (app_vars.freq_setting_rx[app_vars.currentSlotOffset] & MID_MASK) >> MID_OFFSET, - (app_vars.freq_setting_rx[app_vars.currentSlotOffset] & FINE_MASK) >> FINE_OFFSET + (app_vars.freq_setting_rx[setting_index] & COARSE_MASK) >> COARSE_OFFSET, + (app_vars.freq_setting_rx[setting_index] & MID_MASK) >> MID_OFFSET, + (app_vars.freq_setting_rx[setting_index] & FINE_MASK) >> FINE_OFFSET ); radio_rxEnable(); radio_rxNow(); From 34a93f3e6cc45831bf9ac32afe8d07c83d2852b2 Mon Sep 17 00:00:00 2001 From: changtengfei Date: Tue, 24 Dec 2019 16:05:00 +0100 Subject: [PATCH 11/32] SW-15. add flowchats for timer, startFrame and endFrame ISR. --- .../quick_cal_flowchat/scum_endFrame_ISR.vsdx | Bin 0 -> 43212 bytes .../quick_cal_flowchat/scum_startFrame_ISR.vsdx | Bin 0 -> 37053 bytes .../quick_cal_flowchat/scum_timer_ISR.vsdx | Bin 0 -> 57959 bytes 3 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 scm_v3c/applications/quick_cal/quick_cal_flowchat/scum_endFrame_ISR.vsdx create mode 100644 scm_v3c/applications/quick_cal/quick_cal_flowchat/scum_startFrame_ISR.vsdx create mode 100644 scm_v3c/applications/quick_cal/quick_cal_flowchat/scum_timer_ISR.vsdx diff --git a/scm_v3c/applications/quick_cal/quick_cal_flowchat/scum_endFrame_ISR.vsdx b/scm_v3c/applications/quick_cal/quick_cal_flowchat/scum_endFrame_ISR.vsdx new file mode 100644 index 0000000000000000000000000000000000000000..bea55d28fa805e148ed2fa897f26fb36237852f4 GIT binary patch literal 43212 zcmeEtW0NRRwq@DAW!tuG+qUhhTefZ6wr$(C?YcF$U(fWsnb-3R-sFc9c@P<~SLQl< z$2u$JrGP<@0l)wt000080OkcY2{Hfy04%@(0Db{L0BH%?**crpI_oKW*qb=%(7M}L z;}?Jck>>#b{aye6um8pfG$l{k2GS#lye5CZk8MI_6~U{hh@<|d-lSfDue*y=ABJC_ zxxD29OJF6J;YYzDG`!(iWimyVYi$Ty(a)ZvBpEd3CzMY=5u{Ok;P8#alQ`m5%0kf; zkaXP}b9VgAl5-2w2C+O*Y<%ABQLtnp6*on);Wv=1tu@ZQvjNIN{b>lDSJ=PjZ>s4b z&->CJC_O?K*Ql~zxJvU!hXgP^@vPmGHcyezc+T#yPEgL08o7qRa0Hpq2-i()HG(Z+ z*rfs_`IyO;BC50h%okx`!l7c8! zT%yec%UYB$UH;R!6yl7haf6+@CK%Q45Eq9Maj9N_s7|*pAJr^eJ@AG<`;;(HNCdwr z2l#ekMs>#O-Ok%&5lNTj7ktO)YsgA34I#FtrqoRHBeKz2_B;y11)jqu-$9M<(C?qH zP+kPE(6T{`s8!mR;=Koh4~JW4)xfI;ju?R&wrs=IgvlLTK5hOI2Ore<`gC3;+QAm(qHUCe}`LwEt-TKb8L*^Y=f6UX?g0 zJNOSOi+=?k|2{0@4w6r_MNo8u2!=<$k}yQ%GnT7(xvhr+B_uJKr{%%j^)jvL(!7

JFVI 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 literal 0 HcmV?d00001 diff --git a/scm_v3c/applications/quick_cal/quick_cal_flowchat/scum_startFrame_ISR.vsdx b/scm_v3c/applications/quick_cal/quick_cal_flowchat/scum_startFrame_ISR.vsdx new file mode 100644 index 0000000000000000000000000000000000000000..ab6919b44c3c658f81070165b24b0c73ba22c6bb GIT binary patch literal 37053 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

q|CzF!xV1g5s#U&pIr^fBYWdS8IZ5hI~{)^(m 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 JYj<>kcmOYo^P2zw literal 0 HcmV?d00001 diff --git a/scm_v3c/applications/quick_cal/quick_cal_flowchat/scum_timer_ISR.vsdx b/scm_v3c/applications/quick_cal/quick_cal_flowchat/scum_timer_ISR.vsdx new file mode 100644 index 0000000000000000000000000000000000000000..a9bb122b0966839bc970f106633d11af2943d40e GIT binary patch literal 57959 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%0A^KS~ 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