void cycle8 (void) { if (do_cycle8 == 1) { // Set Halt set_halt_until_mbus_tx(); // Enable TIMER32 IRQ clear_all_pend_irq(); *NVIC_ISER = (0 /*GPIO*/ << 16) | (0 /*SPI*/ << 15) | (0 /*GOCEP*/ << 14) | (0 /*MBUS_FWD*/ << 13) | (0 /*MBUS_TX*/ << 12) | (0 /*MBUS_RX*/ << 11) | (0 /*MEM_WR*/ << 10) | (0 /*REG7*/ << 9) | (0 /*REG6*/ << 8) | (0 /*REG5*/ << 7) | (0 /*REG4*/ << 6) | (0 /*REG3*/ << 5) | (0 /*REG2*/ << 4) | (0 /*REG1*/ << 3) | (0 /*REG0*/ << 2) | (0 /*TIMER16*/ << 1) | (1 /*TIMER32*/ << 0); // Timer16 with ROI (Reset-On-Interrupt) config_timer32(/*cmp*/ 0x2000, /*roi*/ 0x1, /*cnt*/ 0x0, /*status*/ 0x0); // Start Timer32. Trigger when it reaches 0x2000. Reset on Interrupt. // Wait for Interrupt WFI(); // 1 IRQ: TIMER16 if (irq_history == (1 << 0)) { pass (0xB, irq_history); irq_history = 0;} else { fail (0xB, irq_history); } // Reset Timer16 *TIMER32_GO = 0x0; *TIMER32_CNT = 0x0; } }
static void sns_temp_test(void){ // Read temp result set_halt_until_mbus_rx(); mbus_remote_register_read(SNS_ADDR,0x6,1); set_halt_until_mbus_tx(); mbus_write_message32(0xC0,*REG1); // Reset the counter and temp sensor snsv11_r01.TSNS_RESETn = 0; mbus_remote_register_write(SNS_ADDR,1,snsv11_r01.as_int); // Set temp sensor conversion time snsv11_r03.TSNS_SEL_CONV_TIME = 0x6; mbus_remote_register_write(SNS_ADDR,0x03,snsv11_r03.as_int); // Turn on SNS LDO // snsv11_r00 //snsv11_r00.LDO_VREF_I_AMP = 0; //snsv11_r00.LDO_SEL_TSNS = 4; //snsv11_r00.LDO_SEL_CDC = 4; snsv11_r00.LDO_EN_VREF = 1; mbus_remote_register_write(SNS_ADDR,0,snsv11_r00.as_int); delay(MBUS_DELAY*10); snsv11_r00.LDO_EN_IREF = 1; snsv11_r00.LDO_EN_TSNS_OUT = 1; // Default: 1 mbus_remote_register_write(SNS_ADDR,0,snsv11_r00.as_int); delay(MBUS_DELAY*10); // Turn on digital block snsv11_r01.TSNS_SEL_LDO = 1; mbus_remote_register_write(SNS_ADDR,1,snsv11_r01.as_int); // Turn on analog block snsv11_r01.TSNS_EN_SENSOR_LDO = 1; mbus_remote_register_write(SNS_ADDR,1,snsv11_r01.as_int); snsv11_r01.TSNS_ISOLATE = 0; mbus_remote_register_write(SNS_ADDR,1,snsv11_r01.as_int); delay(MBUS_DELAY*10); // Disable all timers //disable_timerwd(); //*REG_MBUS_WD = 0; mbus_write_message32(0xAA,0xABCD1111); // Start temp measurement snsv11_r01.TSNS_RESETn = 1; mbus_remote_register_write(SNS_ADDR,1,snsv11_r01.as_int); operation_sleep(); WFI(); mbus_write_message32(0xAA,0xABCD2222); }
void cycle7 (void) { if (do_cycle7 == 1) { // Set Halt set_halt_until_mbus_tx(); // Enable TIMER16 IRQ clear_all_pend_irq(); *NVIC_ISER = (0 /*GPIO*/ << 16) | (0 /*SPI*/ << 15) | (0 /*GOCEP*/ << 14) | (0 /*MBUS_FWD*/ << 13) | (0 /*MBUS_TX*/ << 12) | (0 /*MBUS_RX*/ << 11) | (0 /*MEM_WR*/ << 10) | (0 /*REG7*/ << 9) | (0 /*REG6*/ << 8) | (0 /*REG5*/ << 7) | (0 /*REG4*/ << 6) | (0 /*REG3*/ << 5) | (0 /*REG2*/ << 4) | (0 /*REG1*/ << 3) | (0 /*REG0*/ << 2) | (1 /*TIMER16*/ << 1) | (0 /*TIMER32*/ << 0); // Timer16 config_timer16(/*cmp0*/ 0x1000, /*cmp1*/0xF000, /*irq_en*/0x3, /*cnt*/0x0, /*status*/0x0); // Start Timer16. Trigger when it reaches 0x1000 or 0xF000. // Wait for Interrupt WFI(); // 1 IRQ: TIMER16 if (irq_history == (1 << 1)) { pass (0x9, irq_history); irq_history = 0;} else { fail (0x9, irq_history); } // Wait for Interrupt WFI(); // 1 IRQ: TIMER16 if (irq_history == (1 << 1)) { pass (0xA, irq_history); irq_history = 0; disable_all_irq(); } else { fail (0xA, irq_history); disable_all_irq(); } // Reset Timer16 *TIMER16_GO = 0x0; *TIMER16_CNT = 0x0; } }
int main() { // Enable Wake-Up IRQ & REG7 IRQ *NVIC_ISER = ((0x1 << IRQ_WAKEUP) | (0x1 << IRQ_REG7)); // Initialization Sequence if (!get_flag(FLAG_ENUM)) { initialization(); } // Testing Sequence VIMv1_load_imem(); VIMv1_start(); while (1) { WFI(); if (*REG7 == 0xABC) break; if (*REG7 == 0x123) mbus_remote_register_write(VIM_ADDR, 0x44, 0x1); } VIMv1_stop(); // Sleep/Wakeup OR Terminate operation cyc_num = 999; if (cyc_num == 999) *REG_CHIP_ID = 0xFFFF; // This will stop the verilog sim. else { cyc_num++; set_wakeup_timer(5, 1, 1); mbus_sleep_all(); } while(1){ //Never Quit (should not come here.) arb_debug_reg(0xFF, 0xDEADBEEF); asm("nop;"); } return 1; }
static void sns_wakeup_timer_test(void){ // SNS Wakeup Timer Settings snsv11_r17.WUP_ENABLE = 1; snsv11_r17.WUP_AUTO_RESET = 1; snsv11_r17.WUP_INT_RPLY_REG_ADDR = 0x02; mbus_remote_register_write(SNS_ADDR,0x17,snsv11_r17.as_int); // SNS Wakeup Timer Threshold mbus_remote_register_write(SNS_ADDR,0x19,0); // Extended mbus_remote_register_write(SNS_ADDR,0x1A,24000); // Turn on continuous mode snsv11_r01.TSNS_CONT_MODE = 1; mbus_remote_register_write(SNS_ADDR,1,snsv11_r01.as_int); // Turn on SNS LDO // snsv11_r00 //snsv11_r00.LDO_VREF_I_AMP = 0; //snsv11_r00.LDO_SEL_TSNS = 4; //snsv11_r00.LDO_SEL_CDC = 4; snsv11_r00.LDO_EN_VREF = 1; mbus_remote_register_write(SNS_ADDR,0,snsv11_r00.as_int); delay(MBUS_DELAY*10); snsv11_r00.LDO_EN_IREF = 1; snsv11_r00.LDO_EN_TSNS_OUT = 1; // Default: 1 snsv11_r00.LDO_EN_CDC_OUT = 0; mbus_remote_register_write(SNS_ADDR,0,snsv11_r00.as_int); delay(MBUS_DELAY*10); // Turn on digital block snsv11_r01.TSNS_SEL_LDO = 1; mbus_remote_register_write(SNS_ADDR,1,snsv11_r01.as_int); // Turn on analog block snsv11_r01.TSNS_EN_SENSOR_LDO = 1; mbus_remote_register_write(SNS_ADDR,1,snsv11_r01.as_int); snsv11_r01.TSNS_ISOLATE = 0; mbus_remote_register_write(SNS_ADDR,1,snsv11_r01.as_int); delay(MBUS_DELAY*10); // Set temp sensor conversion time snsv11_r03.TSNS_SEL_CONV_TIME = 0x0; mbus_remote_register_write(SNS_ADDR,0x03,snsv11_r03.as_int); // Start temp measurement snsv11_r01.TSNS_RESETn = 1; mbus_remote_register_write(SNS_ADDR,1,snsv11_r01.as_int); WFI(); mbus_write_message32(0xAA,0xABCD2222); snsv11_r01.TSNS_RESETn = 0; mbus_remote_register_write(SNS_ADDR,1,snsv11_r01.as_int); // Disable all timers //disable_timerwd(); //*REG_MBUS_WD = 0; // Start clock snsv11_r01.TSNS_EN_CLK_REF = 1; mbus_remote_register_write(SNS_ADDR,1,snsv11_r01.as_int); operation_sleep(); WFI(); }
//*************************************************** // Temperature measurement operation (SNSv7) //*************************************************** static void operation_temp_run(void){ if (Tstack_state == TSTK_IDLE){ #ifdef DEBUG_MBUS_MSG mbus_write_message32(0xBB, 0xFBFB0000); delay(MBUS_DELAY*10); #endif Tstack_state = TSTK_LDO; temp_timeout_flag = 0; // Power on radio if (radio_tx_option || ((exec_count+1) < TEMP_CYCLE_INIT)){ radio_power_on(); } snsv7_r18.ADC_LDO_ADC_LDO_ENB = 0x0; mbus_remote_register_write(SNS_ADDR,18,snsv7_r18.as_int); // Put system to sleep set_wakeup_timer(WAKEUP_PERIOD_LDO, 0x1, 0x1); operation_sleep_noirqreset(); }else if (Tstack_state == TSTK_LDO){ #ifdef DEBUG_MBUS_MSG mbus_write_message32(0xBB, 0xFBFB1111); delay(MBUS_DELAY*10); #endif Tstack_state = TSTK_TEMP_RSTRL; snsv7_r18.ADC_LDO_ADC_LDO_DLY_ENB = 0x0; mbus_remote_register_write(SNS_ADDR,18,snsv7_r18.as_int); // Put system to sleep set_wakeup_timer(WAKEUP_PERIOD_LDO, 0x1, 0x1); operation_sleep_noirqreset(); }else if (Tstack_state == TSTK_TEMP_RSTRL){ #ifdef DEBUG_MBUS_MSG mbus_write_message32(0xBB, 0xFBFB2222); delay(MBUS_DELAY*10); #endif Tstack_state = TSTK_TEMP_READ; // Release Temp Sensor Reset temp_sensor_release_reset(); delay(MBUS_DELAY); // Start Temp Sensor temp_sensor_enable(); // Put system to sleep set_wakeup_timer(20, 0x1, 0x1); // FIXME timeout value should be set operation_sleep_noirqreset(); }else if (Tstack_state == TSTK_TEMP_START){ // Start temp measurement #ifdef DEBUG_MBUS_MSG mbus_write_message32(0xBB, 0xFBFB3333); delay(MBUS_DELAY*10); #endif mbus_msg_flag = 0; // Start Temp Sensor temp_sensor_enable(); // Use Timer32 as timeout counter config_timer32(0x249F0, 1, 0, 0); // 1/10 of MBUS watchdog timer default // Wait for temp sensor output WFI(); // Turn off Timer32 *TIMER32_GO = 0; Tstack_state = TSTK_TEMP_READ; }else if (Tstack_state == TSTK_TEMP_READ){ #ifdef DEBUG_MBUS_MSG mbus_write_message32(0xBB, 0xFBFB4444); delay(MBUS_DELAY*10); #endif // Grab Temp Sensor Data if (temp_timeout_flag){ mbus_write_message32(0xFA, 0xFAFAFAFA); }else{ read_data_reg11 = *((volatile uint32_t *) 0xA0000000); } meas_count++; // Last measurement from this wakeup if (meas_count == NUM_TEMP_MEAS){ // No error; see if there was a timeout if (temp_timeout_flag){ temp_storage_latest = 0x666; temp_timeout_flag = 0; }else{ temp_storage_latest = read_data_reg11; // Record temp difference from last wakeup adjustment if (temp_storage_latest > temp_storage_last_wakeup_adjust){ temp_storage_diff = temp_storage_latest - temp_storage_last_wakeup_adjust; }else{ temp_storage_diff = temp_storage_last_wakeup_adjust - temp_storage_latest; } #ifdef DEBUG_MBUS_MSG_1 mbus_write_message32(0xEA, temp_storage_diff); delay(MBUS_DELAY); #endif // FIXME: for now, do this every time //measure_wakeup_period(); if ((temp_storage_diff > 10) || (exec_count < 2)){ measure_wakeup_period(); temp_storage_last_wakeup_adjust = temp_storage_latest; } } } // Option to take multiple measurements per wakeup if (meas_count < NUM_TEMP_MEAS){ // Repeat measurement while awake temp_sensor_disable(); Tstack_state = TSTK_TEMP_START; }else{ meas_count = 0; // Assert temp sensor isolation & turn off temp sensor power temp_power_off(); Tstack_state = TSTK_IDLE; #ifdef DEBUG_MBUS_MSG_1 mbus_write_message32(0xCC, exec_count); delay(MBUS_DELAY); mbus_write_message32(0xC0, temp_storage_latest); delay(MBUS_DELAY); #endif exec_count++; // Grab latest PMU ADC readings // PMUv2 register read is handled differently mbus_remote_register_write(PMU_ADDR,0x00,0x03); delay(MBUS_DELAY); delay(MBUS_DELAY); read_data_batadc = *((volatile uint32_t *) REG0) & 0xFF; batadc_reset(); delay(MBUS_DELAY); // Store results in memory; unless buffer is full if (temp_storage_count < TEMP_STORAGE_SIZE){ temp_storage[temp_storage_count] = temp_storage_latest; radio_tx_count = temp_storage_count; temp_storage_count++; } // Optionally transmit the data if (radio_tx_option){ send_radio_data_ppm(0, temp_storage_latest); delay(RADIO_PACKET_DELAY); send_radio_data_ppm(0, read_data_batadc); } // Enter long sleep if(exec_count < TEMP_CYCLE_INIT){ // Send some signal delay(RADIO_PACKET_DELAY); send_radio_data_ppm(1, 0xFAF000); set_wakeup_timer(WAKEUP_PERIOD_CONT_INIT, 0x1, 0x1); }else{ set_wakeup_timer(WAKEUP_PERIOD_CONT, 0x1, 0x1); } // Release PMU ADC Reset for Battery Measurement batadc_resetrelease(); // Make sure Radio is off if (radio_on){ radio_ready = 0; radio_power_off(); } if (temp_run_single){ temp_run_single = 0; temp_running = 0; operation_sleep_notimer(); } if ((set_temp_exec_count != 0) && (exec_count > (50<<set_temp_exec_count))){ // No more measurement required // Make sure temp sensor is off temp_running = 0; operation_sleep_notimer(); }else{ operation_sleep_noirqreset(); } } }else{ //default: // THIS SHOULD NOT HAPPEN // Reset Temp Sensor temp_sensor_assert_reset(); temp_power_off(); operation_sleep_notimer(); } }
static void operation_sns_run(void){ if (Pstack_state == PSTK_IDLE){ wfi_timeout_flag = 0; meas_count = 0; Pstack_state = PSTK_RDC_RUN; RDC_ADDR = 6; }else if (Pstack_state == PSTK_RDC_RUN){ // Start RDC measurement wfi_timeout_flag = 0; if (meas_count == 0){ // Release RDC power gates / isolation rdc_release_v1p2_pg(); rdc_release_pg(); delay(MBUS_DELAY); rdc_release_isolate(); // Need delay for osc to stabilize rdc_osc_enable(); delay(MBUS_DELAY*2); } // Use Timer32 as timeout counter config_timer32(TIMER32_VAL, 1, 0, 0); // 1/10 of MBUS watchdog timer default // Start RDC rdc_enable(); // Wait for output WFI(); // Turn off Timer32 *TIMER32_GO = 0; Pstack_state = PSTK_RDC_READ; }else if (Pstack_state == PSTK_RDC_READ){ // Grab RDC Data if (wfi_timeout_flag){ read_data_rdc = 0xFAFA; mbus_write_message32(0xFA, 0xFAFAFAFA); }else{ // Read register set_halt_until_mbus_rx(); mbus_remote_register_read(RDC_ADDR,0x20,1); read_data_rdc = *REG1; set_halt_until_mbus_tx(); } rdc_data[meas_count] = read_data_rdc; meas_count++; // Option to take multiple measurements per wakeup if (meas_count < RDC_NUM_MEAS){ // Repeat measurement while awake rdc_disable(); Pstack_state = PSTK_RDC_RUN; }else{ meas_count = 0; // Assert RDC isolation & turn off RDC power rdc_disable(); rdc_osc_disable(); rdc_assert_pg(); RDC_ADDR = 7; Pstack_state = PSTK_RDC2_RUN; mbus_write_message32(0xCC, exec_count); mbus_write_message32(0xC1, read_data_rdc); } }else if (Pstack_state == PSTK_RDC2_RUN){ // Start RDC measurement wfi_timeout_flag = 0; if (meas_count == 0){ // Release RDC power gates / isolation rdc_release_v1p2_pg(); rdc_release_pg(); delay(MBUS_DELAY); rdc_release_isolate(); // Need delay for osc to stabilize rdc_osc_enable(); delay(MBUS_DELAY*2); } // Use Timer32 as timeout counter config_timer32(TIMER32_VAL, 1, 0, 0); // 1/10 of MBUS watchdog timer default // Start RDC rdc_enable(); // Wait for output WFI(); // Turn off Timer32 *TIMER32_GO = 0; Pstack_state = PSTK_RDC2_READ; }else if (Pstack_state == PSTK_RDC2_READ){ // Grab RDC Data if (wfi_timeout_flag){ read_data_rdc = 0xFAFA; mbus_write_message32(0xFA, 0xFAFAFAFA); }else{ // Read register set_halt_until_mbus_rx(); mbus_remote_register_read(RDC_ADDR,0x20,1); read_data_rdc = *REG1; set_halt_until_mbus_tx(); } rdc_data[meas_count] = read_data_rdc; meas_count++; // Option to take multiple measurements per wakeup if (meas_count < RDC_NUM_MEAS){ // Repeat measurement while awake rdc_disable(); Pstack_state = PSTK_RDC2_RUN; }else{ meas_count = 0; // Assert RDC isolation & turn off RDC power rdc_disable(); rdc_osc_disable(); rdc_assert_pg(); RDC_ADDR = 8; Pstack_state = PSTK_RDC3_RUN; mbus_write_message32(0xCC, exec_count); mbus_write_message32(0xC2, read_data_rdc); } }else if (Pstack_state == PSTK_RDC3_RUN){ // Start RDC measurement wfi_timeout_flag = 0; if (meas_count == 0){ // Release RDC power gates / isolation rdc_release_v1p2_pg(); rdc_release_pg(); delay(MBUS_DELAY); rdc_release_isolate(); // Need delay for osc to stabilize rdc_osc_enable(); delay(MBUS_DELAY*2); } // Use Timer32 as timeout counter config_timer32(TIMER32_VAL, 1, 0, 0); // 1/10 of MBUS watchdog timer default // Start RDC rdc_enable(); // Wait for output WFI(); // Turn off Timer32 *TIMER32_GO = 0; Pstack_state = PSTK_RDC3_READ; }else if (Pstack_state == PSTK_RDC3_READ){ // Grab RDC Data if (wfi_timeout_flag){ read_data_rdc = 0xFAFA; mbus_write_message32(0xFA, 0xFAFAFAFA); }else{ // Read register set_halt_until_mbus_rx(); mbus_remote_register_read(RDC_ADDR,0x20,1); read_data_rdc = *REG1; set_halt_until_mbus_tx(); } rdc_data[meas_count] = read_data_rdc; meas_count++; // Option to take multiple measurements per wakeup if (meas_count < RDC_NUM_MEAS){ // Repeat measurement while awake rdc_disable(); Pstack_state = PSTK_RDC3_RUN; }else{ meas_count = 0; // Assert RDC isolation & turn off RDC power rdc_disable(); rdc_osc_disable(); rdc_assert_pg(); RDC_ADDR = 9; Pstack_state = PSTK_RDC4_RUN; mbus_write_message32(0xCC, exec_count); mbus_write_message32(0xC3, read_data_rdc); } }else if (Pstack_state == PSTK_RDC4_RUN){ // Start RDC measurement wfi_timeout_flag = 0; if (meas_count == 0){ // Release RDC power gates / isolation rdc_release_v1p2_pg(); rdc_release_pg(); delay(MBUS_DELAY); rdc_release_isolate(); // Need delay for osc to stabilize rdc_osc_enable(); delay(MBUS_DELAY*2); } // Use Timer32 as timeout counter config_timer32(TIMER32_VAL, 1, 0, 0); // 1/10 of MBUS watchdog timer default // Start RDC rdc_enable(); // Wait for output WFI(); // Turn off Timer32 *TIMER32_GO = 0; Pstack_state = PSTK_RDC4_READ; }else if (Pstack_state == PSTK_RDC4_READ){ // Grab RDC Data if (wfi_timeout_flag){ read_data_rdc = 0xFAFA; mbus_write_message32(0xFA, 0xFAFAFAFA); }else{ // Read register set_halt_until_mbus_rx(); mbus_remote_register_read(RDC_ADDR,0x20,1); read_data_rdc = *REG1; set_halt_until_mbus_tx(); } rdc_data[meas_count] = read_data_rdc; meas_count++; // Option to take multiple measurements per wakeup if (meas_count < RDC_NUM_MEAS){ // Repeat measurement while awake rdc_disable(); Pstack_state = PSTK_RDC4_RUN; }else{ meas_count = 0; // Assert RDC isolation & turn off RDC power rdc_disable(); rdc_osc_disable(); rdc_assert_pg(); Pstack_state = PSTK_IDLE; mbus_write_message32(0xC4, read_data_rdc); exec_count++; // Enter long sleep set_wakeup_timer(WAKEUP_PERIOD_CONT, 0x1, 0x1); operation_sleep(); } }else{ //default: // THIS SHOULD NOT HAPPEN // Reset RDC rdc_assert_pg(); rdc_disable(); rdc_osc_disable(); operation_sleep_notimer(); } }
int main_func(void) { volatile unsigned i; sleep_mode_t sleep_mode; // keep at system RAM. On each while loop it will get a new value. sys_startup_flag = true; /* ************************************************************************************ * Platform initialization ************************************************************************************ */ #if (USE_WDOG) SetWord16(WATCHDOG_REG, 0xC8); // 200 * 10.24ms = ~2sec active time! SetWord16(WATCHDOG_CTRL_REG, 0); // Generate an NMI when counter reaches 0 and a WDOG (SYS) Reset when it reaches -16! // WDOG can be frozen by SW! SetWord16(RESET_FREEZE_REG, FRZ_WDOG); // Start WDOG #else SetWord16(SET_FREEZE_REG, FRZ_WDOG); #endif set_system_clocks(); GPIO_init(); periph_init(); /* Don't remove next line otherwhise dummy[0] could be optimized away * The dummy array is intended to reserve the needed Exch.Memory space in retention memory */ dummy[0] = dummy[0]; descript[0] = descript[0]; #if (BLE_CONNECTION_MAX_USER > 4) cs_table[0] = cs_table[0]; #endif /* Don't remove next line otherwhise data__1 is optimized away. * The address 0x9010 is used by the ROM code (rand.o) and cannot be used by the * application code! */ //GZ data__1 = 0; // Initialize unloaded RAM area //unloaded_area_init(); // Initialize random process srand(1); // Initialize the exchange memory interface, emi in RAM for the time being, so no init necessary #if 0 emi_init(); #endif // Initialize NVDS module nvds_init((uint8_t *)NVDS_FLASH_ADDRESS, NVDS_FLASH_SIZE); //check and read BDADDR from OTP nvds_read_bdaddr_from_otp(); #ifdef RADIO_580 iq_trim_from_otp(); #endif /* ************************************************************************************ * BLE initialization ************************************************************************************ */ init_pwr_and_clk_ble(); //diagnostic(); // rf_init(&rwip_rf); // SetBits32(BLE_RADIOCNTL1_REG, XRFSEL, 3); #if UNCALIBRATED_AT_FAB SetBits16(BANDGAP_REG, BGR_TRIM, 0x0); // trim RET Bandgap SetBits16(BANDGAP_REG, LDO_RET_TRIM, 0xA); // trim RET LDO SetWord16(RF_LNA_CTRL1_REG, 0x24E); SetWord16(RF_LNA_CTRL2_REG, 0x26); SetWord16(RF_LNA_CTRL3_REG, 0x7); SetWord16(RF_RSSI_COMP_CTRL_REG, 0x7777); SetWord16(RF_VCO_CTRL_REG, 0x1); SetBits16(CLK_16M_REG, RC16M_TRIM, 0xA); #endif // Initialize BLE stack NVIC_ClearPendingIRQ(BLE_SLP_IRQn); NVIC_ClearPendingIRQ(BLE_EVENT_IRQn); NVIC_ClearPendingIRQ(BLE_RF_DIAG_IRQn); NVIC_ClearPendingIRQ(BLE_RX_IRQn); NVIC_ClearPendingIRQ(BLE_CRYPT_IRQn); NVIC_ClearPendingIRQ(BLE_FINETGTIM_IRQn); NVIC_ClearPendingIRQ(BLE_GROSSTGTIM_IRQn); NVIC_ClearPendingIRQ(BLE_WAKEUP_LP_IRQn); rwip_init(error); /* Set spi to HW (Ble) * Necessary: So from this point the BLE HW can generate spi burst iso SW * SPI BURSTS are necessary for the radio TX and RX burst, done by hardware * beause of the accurate desired timing */ //FPGA #ifdef FPGA_USED SetBits32(BLE_CNTL2_REG,SW_RPL_SPI ,1); #endif //Enable BLE core SetBits32(BLE_RWBTLECNTL_REG,RWBLE_EN ,1); #if RW_BLE_SUPPORT && HCIC_ITF // If FW initializes due to FW reset, send the message to Host if(error != RESET_NO_ERROR) { rwble_send_message(error); } #endif /* ************************************************************************************ * Sleep mode initializations (especially for full embedded) ************************************************************************************ */ #if (EXT_SLEEP_ENABLED) app_set_extended_sleep(); #elif (DEEP_SLEEP_ENABLED) app_set_deep_sleep(); #else app_disable_sleep(); #endif if (lp_clk_sel == LP_CLK_RCX20) { calibrate_rcx20(20); read_rcx_freq(20); } /* ************************************************************************************ * Application initializations ************************************************************************************ */ #if (BLE_APP_PRESENT) { app_init(); // Initialize APP } #endif /* #if (BLE_APP_PRESENT) */ /* ************************************************************************************ * Main loop ************************************************************************************ */ lld_sleep_init_func(); SetWord16(TRIM_CTRL_REG, 0xA2); SetBits16(CLK_16M_REG, XTAL16_CUR_SET, 0x5); // // Gives 1dB higher sensitivity - UNTESTED // if (GetBits16(ANA_STATUS_REG, BOOST_SELECTED) == 0x1) // { // // Boost-mode // SetBits16(DCDC_CTRL2_REG, DCDC_CUR_LIM, 0x8); // 80mA // } // else // { // // Buck-mode // SetBits16(DCDC_CTRL2_REG, DCDC_CUR_LIM, 0x4); // 40mA // } // Now enable the TX_EN/RX_EN interrupts, depending on the RF mode of operation (PLL-LUT and MGC_KMODALPHA combinations) #if LUT_PATCH_ENABLED const volatile struct LUT_CFG_struct *pLUT_CFG; pLUT_CFG = (const volatile struct LUT_CFG_struct *)(jump_table_struct[lut_cfg_pos]); if (!pLUT_CFG->HW_LUT_MODE) { enable_rf_diag_irq(RF_DIAG_IRQ_MODE_RXTX); } else { #if MGCKMODA_PATCH_ENABLED enable_rf_diag_irq(RF_DIAG_IRQ_MODE_TXONLY); // This just enables the TX_EN int. RX_EN int enable status remains as it was #endif //MGCKMODA_PATCH_ENABLED } #else //LUT_PATCH_ENABLED #if MGCKMODA_PATCH_ENABLED enable_rf_diag_irq(RF_DIAG_IRQ_MODE_TXONLY); // This just enables the TX_EN int. RX_EN int enable status remains as it was #endif //MGCKMODA_PATCH_ENABLED #endif //LUT_PATCH_ENABLED #if BLE_APP_SPOTAR //app_spotar_exec_patch(); #endif if ( (app_get_sleep_mode() == 2) || (app_get_sleep_mode() == 1) ) { SetWord16(SET_FREEZE_REG, FRZ_WDOG); // Stop WDOG until debugger is removed if ((GetWord16(SYS_STAT_REG) & DBG_IS_UP) == DBG_IS_UP) SetBits16(SYS_CTRL_REG, DEBUGGER_ENABLE, 1); // close debugger } /* ************************************************************************************ * Watchdog ************************************************************************************ */ #if (USE_WDOG) SetWord16(WATCHDOG_REG, 0xC8); // 200 * 10.24ms active time for initialization! SetWord16(RESET_FREEZE_REG, FRZ_WDOG); // Start WDOG #endif /* ************************************************************************************ * Main loop ************************************************************************************ */ while(1) { // schedule all pending events if(GetBits16(CLK_RADIO_REG, BLE_ENABLE) == 1) { // BLE clock is enabled if(GetBits32(BLE_DEEPSLCNTL_REG, DEEP_SLEEP_STAT) == 0 && !(rwip_prevent_sleep_get() & RW_WAKE_UP_ONGOING)) { // BLE is running #ifndef FPGA_USED uint8_t ble_evt_end_set = ke_event_get(KE_EVENT_BLE_EVT_END); // BLE event end is set. conditional RF calibration can run. #endif rwip_schedule(); #ifndef FPGA_USED if (ble_evt_end_set) { uint32_t sleep_duration = 0; if (lp_clk_sel == LP_CLK_RCX20) read_rcx_freq(20); if (lld_sleep_check(&sleep_duration, 4)) //6 slots -> 3.750 ms conditionally_run_radio_cals(); // check time and temperature to run radio calibrations. } #endif #if (BLE_APP_PRESENT) if ( app_asynch_trm() ) continue; // so that rwip_schedule() is called again #endif } } #if (BLE_APP_PRESENT) // asynchronous events processing if (app_asynch_proc()) continue; // so that rwip_schedule() is called again #endif GLOBAL_INT_STOP(); #if (BLE_APP_PRESENT) app_asynch_sleep_proc(); #endif // if app has turned sleep off, rwip_sleep() will act accordingly // time from rwip_sleep() to WFI() must be kept as short as possible! sleep_mode = rwip_sleep(); // BLE is sleeping ==> app defines the mode if (sleep_mode == mode_sleeping) { if (sleep_env.slp_state == ARCH_EXT_SLEEP_ON) { sleep_mode = mode_ext_sleep; } else { sleep_mode = mode_deep_sleep; } } if (sleep_mode == mode_ext_sleep || sleep_mode == mode_deep_sleep) { SetBits16(PMU_CTRL_REG, RADIO_SLEEP, 1); // turn off radio if (jump_table_struct[nb_links_user] > 1) { if( (sleep_mode == mode_deep_sleep) && func_check_mem() && test_rxdone() && ke_mem_is_empty(KE_MEM_NON_RETENTION) ) { func_check_mem_flag = 2;//true; } else sleep_mode = mode_ext_sleep; } else { if( (sleep_mode == mode_deep_sleep) && ke_mem_is_empty(KE_MEM_NON_RETENTION) ) { func_check_mem_flag = 1;//true; } else sleep_mode = mode_ext_sleep; } #if (BLE_APP_PRESENT) // hook for app specific tasks when preparing sleeping app_sleep_prepare_proc(&sleep_mode); #endif if (sleep_mode == mode_ext_sleep || sleep_mode == mode_deep_sleep) { SCB->SCR |= 1<<2; // enable sleepdeep mode bit in System Control Register (SCR[2]=SLEEPDEEP) SetBits16(SYS_CTRL_REG, PAD_LATCH_EN, 0); // activate PAD latches SetBits16(PMU_CTRL_REG, PERIPH_SLEEP, 1); // turn off peripheral power domain if (sleep_mode == mode_ext_sleep) { SetBits16(SYS_CTRL_REG, RET_SYSRAM, 1); // retain System RAM SetBits16(SYS_CTRL_REG, OTP_COPY, 0); // disable OTP copy } else { // mode_deep_sleep #if DEVELOPMENT__NO_OTP SetBits16(SYS_CTRL_REG, RET_SYSRAM, 1); // retain System RAM #else SetBits16(SYS_CTRL_REG, RET_SYSRAM, 0); // turn System RAM off => all data will be lost! #endif otp_prepare(0x1FC0); // this is 0x1FC0 32 bits words, so 0x7F00 bytes } } SetBits16(CLK_16M_REG, XTAL16_BIAS_SH_DISABLE, 0); #if (BLE_APP_PRESENT) // hook for app specific tasks just before sleeping app_sleep_entry_proc(&sleep_mode); #endif WFI(); #if (BLE_APP_PRESENT) // hook for app specific tasks just after waking up app_sleep_exit_proc(sleep_mode); #endif // reset SCR[2]=SLEEPDEEP bit else the mode=idle WFI will cause a deep sleep // instead of a processor halt SCB->SCR &= ~(1<<2); } else if (sleep_mode == mode_idle) { #if (!BLE_APP_PRESENT) if (check_gtl_state()) { #endif WFI(); #if (!BLE_APP_PRESENT) } #endif } // restore interrupts GLOBAL_INT_START(); #if (USE_WDOG) SetWord16(WATCHDOG_REG, 0xC8); // Reset WDOG! 200 * 10.24ms active time for normal mode! #endif } }
int main_func(void) { volatile unsigned i; sleep_mode_t sleep_mode; // keep at system RAM. On each while loop it will get a new value. sys_startup_flag = true; /* ************************************************************************************ * Platform initialization ************************************************************************************ */ #if (USE_WDOG) SetWord16(WATCHDOG_REG, 0xC8); // 200 * 10.24ms = ~2sec active time! SetWord16(WATCHDOG_CTRL_REG, 0); // Generate an NMI when counter reaches 0 and a WDOG (SYS) Reset when it reaches -16! // WDOG can be frozen by SW! SetWord16(RESET_FREEZE_REG, FRZ_WDOG); // Start WDOG #else SetWord16(SET_FREEZE_REG, FRZ_WDOG); #endif #if defined(CFG_USE_DEFAULT_XTAL16M_TRIM_VALUE_IF_NOT_CALIBRATED) #define DEFAULT_XTAL16M_TRIM_VALUE (1302) // Apply the default XTAL16 trim value if a trim value has not been programmed in OTP if ( 0 == GetWord16(CLK_FREQ_TRIM_REG) ) { SetBits16(CLK_16M_REG, RC16M_ENABLE, 1); // enable RC 16MHz for (volatile int i = 0; i < 20; i++); SetBits16(CLK_CTRL_REG, SYS_CLK_SEL, 1); // switch to RC16 while( (GetWord16(CLK_CTRL_REG) & RUNNING_AT_RC16M) == 0 ); // wait for actual switch SetBits16(CLK_CTRL_REG, XTAL16M_DISABLE, 1); // disable XTAL16 SetWord16(CLK_FREQ_TRIM_REG, DEFAULT_XTAL16M_TRIM_VALUE); // set default trim value SetBits16(CLK_CTRL_REG, XTAL16M_DISABLE, 0); // enable XTAL16 while( (GetWord16(SYS_STAT_REG) & XTAL16_SETTLED) == 0 ); // wait for XTAL16 settle SetBits16(CLK_CTRL_REG , SYS_CLK_SEL ,0); // switch to XTAL16 while( (GetWord16(CLK_CTRL_REG) & RUNNING_AT_XTAL16M) == 0 ); // wait for actual switch } #endif set_system_clocks(); GPIO_init(); periph_init(); /* Don't remove next line otherwhise dummy[0] could be optimized away * The dummy array is intended to reserve the needed Exch.Memory space in retention memory */ dummy[0] = dummy[0]; descript[0] = descript[0]; #ifndef __DA14581__ #if (BLE_CONNECTION_MAX_USER > 4) cs_table[0] = cs_table[0]; #endif #else #if (BLE_CONNECTION_MAX_USER > 1) cs_table[0] = cs_table[0]; #endif #endif /* Don't remove next line otherwhise data__1 is optimized away. * The address 0x9010 is used by the ROM code (rand.o) and cannot be used by the * application code! */ //GZ data__1 = 0; // Initialize unloaded RAM area //unloaded_area_init(); // Initialize random process srand(1); // Initialize the exchange memory interface, emi in RAM for the time being, so no init necessary #if 0 emi_init(); #endif // Initialize NVDS module // 初始化非易失性存储器 nvds_init((uint8_t *)NVDS_FLASH_ADDRESS, NVDS_FLASH_SIZE); //check and read BDADDR from OTP nvds_read_bdaddr_from_otp(); #ifdef RADIO_580 iq_trim_from_otp(); #endif /* ************************************************************************************ * BLE initialization ************************************************************************************ */ init_pwr_and_clk_ble(); //diagnostic(); // rf_init(&rwip_rf); // SetBits32(BLE_RADIOCNTL1_REG, XRFSEL, 3); #if UNCALIBRATED_AT_FAB SetBits16(BANDGAP_REG, BGR_TRIM, 0x0); // trim RET Bandgap SetBits16(BANDGAP_REG, LDO_RET_TRIM, 0xA); // trim RET LDO SetWord16(RF_LNA_CTRL1_REG, 0x24E); SetWord16(RF_LNA_CTRL2_REG, 0x26); SetWord16(RF_LNA_CTRL3_REG, 0x7); SetWord16(RF_VCO_CTRL_REG, 0x1); SetBits16(CLK_16M_REG, RC16M_TRIM, 0xA); #endif // Initialize BLE stack NVIC_ClearPendingIRQ(BLE_SLP_IRQn); NVIC_ClearPendingIRQ(BLE_EVENT_IRQn); NVIC_ClearPendingIRQ(BLE_RF_DIAG_IRQn); NVIC_ClearPendingIRQ(BLE_RX_IRQn); NVIC_ClearPendingIRQ(BLE_CRYPT_IRQn); NVIC_ClearPendingIRQ(BLE_FINETGTIM_IRQn); NVIC_ClearPendingIRQ(BLE_GROSSTGTIM_IRQn); NVIC_ClearPendingIRQ(BLE_WAKEUP_LP_IRQn); rwip_init(error); #if ((BLE_APP_PRESENT == 0 || BLE_INTEGRATED_HOST_GTL == 1) && BLE_HOST_PRESENT ) patch_gtl_task(); #endif // #if (BLE_APP_PRESENT == 0 || BLE_INTEGRATED_HOST_GTL == 1) /* Set spi to HW (Ble) * Necessary: So from this point the BLE HW can generate spi burst iso SW * SPI BURSTS are necessary for the radio TX and RX burst, done by hardware * beause of the accurate desired timing */ //FPGA #ifdef FPGA_USED SetBits32(BLE_CNTL2_REG,SW_RPL_SPI ,1); #endif //Enable BLE core SetBits32(BLE_RWBTLECNTL_REG,RWBLE_EN ,1); #if RW_BLE_SUPPORT && HCIC_ITF // If FW initializes due to FW reset, send the message to Host if(error != RESET_NO_ERROR) { rwble_send_message(error); } #endif /* ************************************************************************************ * Sleep mode initializations (especially for full embedded) ************************************************************************************ */ #if (EXT_SLEEP_ENABLED) app_set_extended_sleep(); #elif (DEEP_SLEEP_ENABLED) app_set_deep_sleep(); #else app_disable_sleep(); #endif if (lp_clk_sel == LP_CLK_RCX20) { calibrate_rcx20(20); read_rcx_freq(20); } /* ************************************************************************************ * Application initializations ************************************************************************************ */ #if (BLE_APP_PRESENT) { app_init(); // Initialize APP // 初始化应用程序 } #endif /* #if (BLE_APP_PRESENT) */ /* ************************************************************************************ * Main loop ************************************************************************************ */ lld_sleep_init_func(); SetWord16(TRIM_CTRL_REG, 0xA2); SetBits16(CLK_16M_REG, XTAL16_CUR_SET, 0x5); // // Gives 1dB higher sensitivity - UNTESTED // if (GetBits16(ANA_STATUS_REG, BOOST_SELECTED) == 0x1) // { // // Boost-mode // SetBits16(DCDC_CTRL2_REG, DCDC_CUR_LIM, 0x8); // 80mA // } // else // { // // Buck-mode // SetBits16(DCDC_CTRL2_REG, DCDC_CUR_LIM, 0x4); // 40mA // } // Now enable the TX_EN/RX_EN interrupts, depending on the RF mode of operation (PLL-LUT and MGC_KMODALPHA combinations) enable_rf_diag_irq(RF_DIAG_IRQ_MODE_RXTX); #if BLE_APP_SPOTAR // 打补丁 //app_spotar_exec_patch(); #endif if ( (app_get_sleep_mode() == 2) || (app_get_sleep_mode() == 1) ) { SetWord16(SET_FREEZE_REG, FRZ_WDOG); // Stop WDOG until debugger is removed while ((GetWord16(SYS_STAT_REG) & DBG_IS_UP) == DBG_IS_UP) {}; SetBits16(SYS_CTRL_REG, DEBUGGER_ENABLE, 0); // close debugger } /* ************************************************************************************ * Watchdog ************************************************************************************ */ #if (USE_WDOG) SetWord16(WATCHDOG_REG, 0xC8); // 200 * 10.24ms active time for initialization! SetWord16(RESET_FREEZE_REG, FRZ_WDOG); // Start WDOG #endif #if (STREAMDATA_QUEUE) stream_fifo_init (); #endif /* ************************************************************************************ * Main loop ************************************************************************************ */ // 设置LED电亮 SetWord16(P10_MODE_REG,0x310); SetWord16(P11_MODE_REG,0x300); //SetWord16(P1_DATA_REG,~(GetWord16(P1_DATA_REG)) | 0xfd); //SetWord16(P10_MODE_REG,0x300); // // 定时器时钟使能 // SetWord16(CLK_PER_REG, 0x0008); // // // SetWord16(TIMER0_CTRL_REG, 0x0e); // SetWord16(TIMER0_ON_REG, 65535); // SetWord16(TIMER0_RELOAD_M_REG, 10000); // SetWord16(TIMER0_RELOAD_N_REG, 5000); // SetWord16(TIMER0_CTRL_REG, TIMER0_CTRL_REG | 0x01); // NVIC_SetPriority(SWTIM_IRQn,254); // NVIC_EnableIRQ(SWTIM_IRQn); while(1) { // schedule all pending events if(GetBits16(CLK_RADIO_REG, BLE_ENABLE) == 1) { // BLE clock is enabled if(GetBits32(BLE_DEEPSLCNTL_REG, DEEP_SLEEP_STAT) == 0 && !(rwip_prevent_sleep_get() & RW_WAKE_UP_ONGOING)) { // BLE is running #ifndef FPGA_USED uint8_t ble_evt_end_set = ke_event_get(KE_EVENT_BLE_EVT_END); // BLE event end is set. conditional RF calibration can run. #endif rwip_schedule(); // 调度 aiwesky 20101003 #ifndef FPGA_USED if (ble_evt_end_set) { uint32_t sleep_duration = 0; if (lp_clk_sel == LP_CLK_RCX20) read_rcx_freq(20); if (lld_sleep_check(&sleep_duration, 4)) //6 slots -> 3.750 ms conditionally_run_radio_cals(); // check time and temperature to run radio calibrations. } #endif #if (BLE_APP_PRESENT) if ( app_asynch_trm() ) continue; // so that rwip_schedule() is called again #endif #ifdef CFG_PRINTF { arch_printf_process(); } #endif } } #if (BLE_APP_PRESENT) // asynchronous events processing if (app_asynch_proc()) continue; // so that rwip_schedule() is called again #endif #if (STREAMDATA_QUEUE) if (stream_queue_more_data( )) continue; #endif #if (!BLE_APP_PRESENT) if (check_gtl_state()) #endif { GLOBAL_INT_STOP(); #if (BLE_APP_PRESENT) app_asynch_sleep_proc(); #endif // // set wake-up delay only for RCX (to cover small frequency shifts due to temerature variation) // if (lp_clk_sel == LP_CLK_RCX20) // set_sleep_delay(); // if app has turned sleep off, rwip_sleep() will act accordingly // time from rwip_sleep() to WFI() must be kept as short as possible! sleep_mode = rwip_sleep(); // 读取休眠模式 // BLE is sleeping ==> app defines the mode if (sleep_mode == mode_sleeping) { if (sleep_env.slp_state == ARCH_EXT_SLEEP_ON) { sleep_mode = mode_ext_sleep; } else { sleep_mode = mode_deep_sleep; } } if (sleep_mode == mode_ext_sleep || sleep_mode == mode_deep_sleep) { SetBits16(PMU_CTRL_REG, RADIO_SLEEP, 1); // turn off radio if (jump_table_struct[nb_links_user] > 1) { if( (sleep_mode == mode_deep_sleep) && func_check_mem() && test_rxdone() && ke_mem_is_empty(KE_MEM_NON_RETENTION) ) { func_check_mem_flag = 2;//true; } else sleep_mode = mode_ext_sleep; } else { if( (sleep_mode == mode_deep_sleep) && ke_mem_is_empty(KE_MEM_NON_RETENTION) ) { func_check_mem_flag = 1;//true; } else sleep_mode = mode_ext_sleep; } #if (BLE_APP_PRESENT) // hook for app specific tasks when preparing sleeping app_sleep_prepare_proc(&sleep_mode); #endif if (sleep_mode == mode_ext_sleep || sleep_mode == mode_deep_sleep) { SCB->SCR |= 1<<2; // enable sleepdeep mode bit in System Control Register (SCR[2]=SLEEPDEEP) SetBits16(SYS_CTRL_REG, PAD_LATCH_EN, 0); // activate PAD latches SetBits16(PMU_CTRL_REG, PERIPH_SLEEP, 1); // turn off peripheral power domain if (sleep_mode == mode_ext_sleep) { SetBits16(SYS_CTRL_REG, RET_SYSRAM, 1); // retain System RAM SetBits16(SYS_CTRL_REG, OTP_COPY, 0); // disable OTP copy } else { // mode_deep_sleep #if DEVELOPMENT_DEBUG SetBits16(SYS_CTRL_REG, RET_SYSRAM, 1); // retain System RAM #else SetBits16(SYS_CTRL_REG, RET_SYSRAM, 0); // turn System RAM off => all data will be lost! #endif otp_prepare(0x1FC0); // this is 0x1FC0 32 bits words, so 0x7F00 bytes } } SetBits16(CLK_16M_REG, XTAL16_BIAS_SH_DISABLE, 0); #if (BLE_APP_PRESENT) // hook for app specific tasks just before sleeping app_sleep_entry_proc(&sleep_mode); #endif #if ((EXTERNAL_WAKEUP) && (!BLE_APP_PRESENT)) // external wake up, only in external processor designs ext_wakeup_enable(EXTERNAL_WAKEUP_GPIO_PORT, EXTERNAL_WAKEUP_GPIO_PIN, EXTERNAL_WAKEUP_GPIO_POLARITY); #endif WFI(); // 暂停执行直到事件发生 aiwesky 20151003 #if (BLE_APP_PRESENT) // hook for app specific tasks just after waking up app_sleep_exit_proc(sleep_mode); #endif #if ((EXTERNAL_WAKEUP) && (!BLE_APP_PRESENT)) // external wake up, only in external processor designs // Disable external wakeup interrupt ext_wakeup_disable(); #endif // reset SCR[2]=SLEEPDEEP bit else the mode=idle WFI will cause a deep sleep // instead of a processor halt SCB->SCR &= ~(1<<2); } else if (sleep_mode == mode_idle) { #if (!BLE_APP_PRESENT) if (check_gtl_state()) #endif { WFI(); } } // restore interrupts GLOBAL_INT_START(); } #if (USE_WDOG) SetWord16(WATCHDOG_REG, 0xC8); // Reset WDOG! 200 * 10.24ms active time for normal mode! #endif } }