Exemple #1
0
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;
    }
}
Exemple #2
0
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);

}
Exemple #3
0
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;
    }
}
Exemple #4
0
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;
}
Exemple #5
0
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();
    }

}
Exemple #8
0
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
    }
}
Exemple #9
0
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
    }
}