Exemple #1
0
/**
****************************************************************************************
* @brief SPI 439 Read
* @param[in] address: 12 bits register address on 439
* @param[in] data: 
*
* To read one data word from the SPI, 3 transactions are needed.
* - First transaction: send command&address
* - Second transaction: send dummy 0
* - Third transacation: read returned data
* This functions uses POLLING to check if SPI transaction has completed.
*
* @return  data read from the 439
****************************************************************************************
*/
uint32_t spi_getword(uint32_t address)  // IZP named changed
{
    uint32_t dataRead = 0;
    
    spi_cs_low();

    uint32_t dataToSend = ((SC14439_MEM_RD<<13) | (address&0x1FFF ));
    SetWord16(SPI_RX_TX_REG0, (uint16_t)dataToSend);    // write (low part of) dataToSend

    while (!GetBits16(SPI_CTRL_REG, SPI_INT_BIT));      // polling to wait for spi transmission
    SetWord16(SPI_CLEAR_INT_REG, 0x01);                 // clear pending flag
    
    dataToSend = 0;
    SetWord16(SPI_RX_TX_REG0, (uint16_t)dataToSend);    // write (low part of) dataToSend

    while (!GetBits16(SPI_CTRL_REG, SPI_INT_BIT));      // polling to wait for spi transmission
    SetWord16(SPI_CLEAR_INT_REG, 0x01);                 // clear pending flag

    SetWord16(SPI_RX_TX_REG0, (uint16_t)dataToSend);    // write (low part of) dataToSend
    
    while (!GetBits16(SPI_CTRL_REG, SPI_INT_BIT));      // polling to wait for spi transmission
    SetWord16(SPI_CLEAR_INT_REG, 0x01);                 // clear pending flag

    dataRead  = GetWord16(SPI_RX_TX_REG0);              //read (low part of) data from spi slave

    spi_cs_high();

    return dataRead;                                    // return data read from spi slave
}
Exemple #2
0
/**
 ****************************************************************************************
 * @brief Read from 3-wire SPI
 * @param[in] registerIndex: Target address (A6..A0)
 *
 * @return  byte read
 ****************************************************************************************
 */
uint8_t read_from_3wire_SPI_register(uint8_t registerIndex, uint8_t is_last_transaction)
{
    static uint8_t i, dataRead;

    GPIO_SetInactive(cs.port, cs.pin);                              // pull CS low

    GPIO_SetPinFunction( sdio.port, sdio.pin, OUTPUT, PID_SPI_DO);  // configure SDIO as output

    SetWord16(SPI_RX_TX_REG0, (uint16_t)(registerIndex) );          // MSB set to HIGH - A6..A0 Address of register to write to
    do {
    } while (GetBits16(SPI_CTRL_REG,SPI_INT_BIT)==0);               // polling to wait for spi transmission

    SetWord16(SPI_CLEAR_INT_REG, 0);                                //Clear SPI_CTRL_REG[SPI_INT_BIT] interrupt

    GPIO_SetPinFunction( sdio.port, sdio.pin, INPUT, PID_SPI_DI);   // configure SDIO as input

    for (i=0; i<TsradCounter; i++);                                 // {DEV.NOTE#: For Mouse sensor Delay > Tsrad = 4us <-- suitable counter is 6}

    SetWord16(SPI_RX_TX_REG0, (uint16_t)0x00 );                     // dummy write data - read data
    do {
    } while (GetBits16(SPI_CTRL_REG,SPI_INT_BIT)==0);               // polling to wait for spi transmission

    SetWord16(SPI_CLEAR_INT_REG, 0);                                //Clear SPI_CTRL_REG[SPI_INT_BIT] interrupt

    dataRead = GetWord16(SPI_RX_TX_REG0);                           // read received byte

    SetWord16(SPI_CLEAR_INT_REG, 0x01);                             // clear pending flag

    if(is_last_transaction)
        GPIO_SetActive(cs.port, cs.pin);                              // set CS high

    return dataRead;
}
Exemple #3
0
void BLE_RF_DIAG_Handler(void)
{
  uint32 irq_scr;
  uint16_t cn;    
  cn = GetWord16(RF_BMCW_REG) & 0x003F;    

  irq_scr = GetWord32(BLE_RF_DIAGIRQ_REG);  // read BLE_RF_DIAGIRQ_REG so that you clear DIAGIRQ_STAT_0 (otherwise interrupt is activated again and again!)
    
#if LUT_PATCH_ENABLED 
  const volatile struct LUT_CFG_struct *pLUT_CFG;	// = (const volatile struct LUT_CFG_struct *)(jump_table_struct[lut_cfg_pos]);
  pLUT_CFG = (const volatile struct LUT_CFG_struct *)(jump_table_struct[lut_cfg_pos]);
  if(!pLUT_CFG->HW_LUT_MODE)
  { 
    set_rf_cal_cap(cn); 
  }
#endif
  
#if MGCKMODA_PATCH_ENABLED 
  if(GetBits16(RF_MGAIN_CTRL_REG, GAUSS_GAIN_SEL) && (irq_scr & DIAGIRQ_STAT_0))  // TODO: If GAUSS_GAIN_SEL==0x1 AND it is an TX_EN interrupt (for RX_EN int it is not necessary to run)
  { 
    set_gauss_modgain(cn); 
  }
#endif
  
#ifdef PRODUCTION_TEST  
	if( irq_scr & DIAGIRQ_STAT_0)//check TXEN posedge 
	{	
		test_tx_packet_nr++;
	}
	if( irq_scr & DIAGIRQ_STAT_1)//check RXEN posedge 
	{	
		test_rx_irq_cnt++;
	}  
#endif    
}
/**
****************************************************************************************
* @brief Read a single item from serial flash via SPI
* @param[in] x: buffer to read the data 
****************************************************************************************
*/
inline void getByte_SPI(uint8* x  )
{
    SetWord16(SPI_RX_TX_REG0, (uint16) DUMMY);
    while (GetBits16(SPI_CTRL_REG, SPI_INT_BIT==0));
    SetWord16(SPI_CLEAR_INT_REG, 0x01);
    *(uint8*)x=(uint8)GetWord16(SPI_RX_TX_REG0);   
} 
Exemple #5
0
/**
****************************************************************************************
* @brief SPI 439  Write
* @param[in] address: 12 bits address on 439
* @param[in] data: 16 bits value for the register
*
* To write one data word to 439 with the SPI, 2 transactions are needed.
* - First transaction: send command&address
* - Second transaction: write data
* This functions uses POLLING to check if SPI transaction has completed.
*
* @return  data read 
****************************************************************************************
*/
void spi_setword(uint32_t address, uint32_t data)  // IZP named changed
{    
    spi_cs_low();
    
    uint32_t dataToSend = ((SC14439_MEM_WR<<13) | (address&0x1FFF ));
    
    SetWord16(SPI_RX_TX_REG0, (uint16_t)dataToSend);    // write address

    while (!GetBits16(SPI_CTRL_REG, SPI_INT_BIT));      // polling to wait for spi transmission
    SetWord16(SPI_CLEAR_INT_REG, 0x01);                 // clear pending flag
        
    SetWord16(SPI_RX_TX_REG0, (uint16_t)data);          // write (low part of) dataToSend

    while (!GetBits16(SPI_CTRL_REG, SPI_INT_BIT));      // polling to wait for spi transmission
    SetWord16(SPI_CLEAR_INT_REG, 0x01);                 // clear pending flag

    spi_cs_high();
}
/**
 ****************************************************************************************
 * @brief  Handler of the Green LED Timer
 *
 * @param[in]   msgid
 * @param[in]   param 
 * @param[in]   dest_id
 * @param[in]   src_id 
 *
 * @return  KE_MSG_CONSUMED
 ****************************************************************************************
 */
int app_green_led_timer_handler(ke_msg_id_t const msgid,
                                void const *param,
                                ke_task_id_t const dest_id,
                                ke_task_id_t const src_id)
{
    if (!dbg_uses_led_pins() || !((GetWord16(SYS_STAT_REG) & DBG_IS_UP) == DBG_IS_UP)) {
        // GPIOs are not being used by the debugger                    
        switch(green_led_st) {
        case LED_OFF:
            green_led_off();
            break;
        
        case BLINK_LED_IS_ON__TURN_OFF:
            GPIO_SetActive(KBD_GREEN_LED_PORT, KBD_GREEN_LED_PIN); // high - off
            app_timer_set(APP_GREEN_LED_TIMER, TASK_APP, BLINK_GREEN_OFF);
            green_led_st = BLINK_LED_IS_OFF__TURN_ON;
            if ((GetBits16(ANA_STATUS_REG, BOOST_SELECTED) == 0x1) && 
                ((red_led_st == LED_OFF) || (red_led_st == BLINK_LED_IS_OFF__TURN_ON))) {
                    app_restore_sleep_mode(); // restore sleep
            }
            break;
            
        case BLINK_LED_IS_OFF__TURN_ON:
            green_led_blink();
            app_timer_set(APP_GREEN_LED_TIMER, TASK_APP, BLINK_GREEN_ON);
            leds_block_sleep();
            break;
        
        case LED_ON:
            green_led_off();
            if ((GetBits16(ANA_STATUS_REG, BOOST_SELECTED) == 0x1) &&
                ((red_led_st == LED_OFF) || (red_led_st == BLINK_LED_IS_OFF__TURN_ON))) {
                app_restore_sleep_mode(); // restore sleep
            }
            break;
        
        default:
            break;
        }
    }
 	
	return (KE_MSG_CONSUMED);
}
/**
****************************************************************************************
* @brief Write a single item to serial flash via SPI
* @param[in] x: data to send
****************************************************************************************
*/
void putByte_SPI(uint32 x)
{ 
    uint16 tmp; 
    SetWord16(SPI_RX_TX_REG0, (uint16_t)x);    // write (low part of) dataToSend
    do
    {
    } while (GetBits16(SPI_CTRL_REG, SPI_INT_BIT) == 0);  // polling to wait for spi transmission
    SetWord16(SPI_CLEAR_INT_REG, 0x01);            // clear pending flag
    tmp = GetWord16(SPI_RX_TX_REG0);
}
Exemple #8
0
/**
 ****************************************************************************************
 * @brief Write to 3-wire SPI
 * @param[in] registerIndex: Target address (A6..A0)
 * @param[in] valueToWrite: Value to write
 *
 * @return  Number of read bytes
 ****************************************************************************************
 */
void write_to_3wire_SPI_register(uint8_t registerIndex, uint8_t valueToWrite)
{
    GPIO_SetInactive(cs.port, cs.pin);                              // pull CS low

    GPIO_SetPinFunction( sdio.port, sdio.pin, OUTPUT, PID_SPI_DO);  // configure SDIO as output

    SetWord16(SPI_RX_TX_REG0, (uint16_t)(registerIndex | 0x80) );   // MSB set to HIGH - A6..A0 Address of register to write to
    do {
    } while (GetBits16(SPI_CTRL_REG,SPI_INT_BIT)==0);               // polling to wait for spi transmission

    SetWord16(SPI_CLEAR_INT_REG, 0);                                //Clear SPI_CTRL_REG[SPI_INT_BIT] interrupt

    SetWord16(SPI_RX_TX_REG0, (uint16_t)valueToWrite );             // write data
    do {
    } while (GetBits16(SPI_CTRL_REG,SPI_INT_BIT)==0);               // polling to wait for spi transmission

    SetWord16(SPI_CLEAR_INT_REG, 0);                                // Clear SPI_CTRL_REG[SPI_INT_BIT] interrupt

    GPIO_SetActive(cs.port, cs.pin);                                // set CS high
}
Exemple #9
0
void burst_write_to_3wire_SPI_register(uint8_t registerIndex)
{
    GPIO_SetPinFunction( sdio.port, sdio.pin, OUTPUT, PID_SPI_DO);   // configure SDIO as output
    SetWord16(SPI_RX_TX_REG0, (uint16_t)(registerIndex) );           // MSB set to HIGH - A6..A0 Address of register to write to
    do {
    } while (GetBits16(SPI_CTRL_REG,SPI_INT_BIT)==0);                // polling to wait for spi transmission

    SetWord16(SPI_CLEAR_INT_REG, 0);                                 // Clear SPI_CTRL_REG[SPI_INT_BIT] interrupt
    GPIO_SetPinFunction( sdio.port, sdio.pin, INPUT, PID_SPI_DI);    // configure SDIO as input

}
Exemple #10
0
uint16_t $Sub$$get_rc16m_count_func(void)
{
    uint16_t count;
    uint16_t trim = GetBits16(CLK_16M_REG, RC16M_TRIM);
    
    count = $Super$$get_rc16m_count_func();

    SetBits16(CLK_16M_REG, RC16M_TRIM, trim);
    
    return count;
}
Exemple #11
0
uint16_t __wrap_get_rc16m_count_func(void)
{
    uint16_t count;
    uint16_t trim = GetBits16(CLK_16M_REG, RC16M_TRIM);
    
    count = __real_get_rc16m_count_func();

    SetBits16(CLK_16M_REG, RC16M_TRIM, trim);
    
    return count;
}
Exemple #12
0
/**
 ****************************************************************************************
 * @brief Callback function, called when external wakeup function is triggered.
 *
 * @return void.
 ****************************************************************************************
 */
void ext_wakeup_cb(void)
{ 	
	if (GetBits16(SYS_STAT_REG, PER_IS_DOWN)) {
		// Return GPIO functionality from external wakeup GPIO
#if DEVELOPMENT_DEBUG
		GPIO_reservations();
#endif		
		set_pad_functions();
  } 
	
	SetBits32(GP_CONTROL_REG, BLE_WAKEUP_REQ, 1);
}
Exemple #13
0
uint8_t burst_read_from_3wire_SPI_register(void)
{
    static uint8_t dataRead;

    SetWord16(SPI_RX_TX_REG0, (uint16_t)0x00 );                      // dummy write data - read data
    do {
    } while (GetBits16(SPI_CTRL_REG,SPI_INT_BIT)==0);                // polling to wait for spi transmission

    SetWord16(SPI_CLEAR_INT_REG, 0);                                 // Clear SPI_CTRL_REG[SPI_INT_BIT] interrupt
    dataRead = GetWord16(SPI_RX_TX_REG0);                            // read received byte
    SetWord16(SPI_CLEAR_INT_REG, 0x01);                              // clear pending flag

    return dataRead;
}
/**
 ****************************************************************************************
 * @brief Enable pad's and peripheral clocks assuming that peripherals' power domain is down.
 *
 *
 * @return void
 ****************************************************************************************
 */
void periph_init(void)
{
	// Power up peripherals' power domain
    SetBits16(PMU_CTRL_REG, PERIPH_SLEEP, 0);
    while (!(GetWord16(SYS_STAT_REG) & PER_IS_UP)) ; 

    SetBits16(CLK_16M_REG, XTAL16_BIAS_SH_DISABLE, 1);
	
    // Initialize UART component
#ifdef PROGRAM_ENABLE_UART
    if (GetBits16(CLK_CTRL_REG, RUNNING_AT_XTAL16M)) {
        SetBits16(CLK_PER_REG, UART1_ENABLE, 1);    // enable clock - always @16MHz       
        
        // mode=3-> no parity, 1 stop bit 8 data length
#ifdef UART_MEGABIT
        uart_init(UART_BAUDRATE_1M, 3);
#else
        uart_init(UART_BAUDRATE_115K2, 3);
#endif // UART_MEGABIT
    }
#endif // PROGRAM_ENABLE_UART

    //FPGA  
#ifdef FPGA_USED    
    SetBits16(CLK_PER_REG, SPI_ENABLE, 1);      // enable  clock
    SetBits16(CLK_PER_REG, SPI_DIV, 1);	        // set divider to 1	
	SetBits16(CLK_PER_REG, WAKEUPCT_ENABLE, 1); // enable clock of Wakeup Controller
#endif

	//rom patch
	patch_func();
	
	//Init pads
	set_pad_functions();

#ifndef FPGA_USED
//	SetBits16(CLK_PER_REG, WAKEUPCT_ENABLE, 1); // enable clock of Wakeup Controller
#endif    

    //SetWord16(P01_PADPWR_CTRL_REG,0xFF);

    // Enable the pads
	SetBits16(SYS_CTRL_REG, PAD_LATCH_EN, 1);
}
/**
****************************************************************************************
* @brief Send an HCI message over the SPI
* @param[in] size: 			size of data to send in bytes
* @param[in] *msg_ptr: 	pointer to the first byte to be sent

****************************************************************************************
*/
void spi_send_hci_msg(uint16_t size, uint8_t *msg_ptr)
{
    uint16_t i;

    NVIC_DisableIRQ(GPIO0_IRQn);

    while(GetBits16(SPI_DATA_REG,1<<SPI_DREADY_PIN)==1);  // Polling DREADY to detect if data is being received

    spi_cs_high();  // Close CS
    spi_cs_low();   // Open CS

    spi_access(0x05);

    for (i=0; i<size; i++)
    {
        spi_access(*msg_ptr++);
    }

    spi_cs_high();  // Close CS

    NVIC_EnableIRQ(GPIO0_IRQn);
}
Exemple #16
0
void BLE_RF_DIAG_Handler(void)
{
  uint16_t cn;    
  cn = GetWord16(RF_BMCW_REG) & 0x003F;    
  
#if LUT_PATCH_ENABLED 
  const volatile struct LUT_CFG_struct *pLUT_CFG;	// = (const volatile struct LUT_CFG_struct *)(jump_table_struct[lut_cfg_pos]);
  pLUT_CFG = (const volatile struct LUT_CFG_struct *)(jump_table_struct[lut_cfg_pos]);
  if(!pLUT_CFG->HW_LUT_MODE)
  { 
    set_rf_cal_cap(cn); 
  }
#endif
  
#if MGCKMODA_PATCH_ENABLED 
  if(GetBits16(RF_MGAIN_CTRL_REG, GAUSS_GAIN_SEL) && GetBits32(BLE_RF_DIAGIRQ_REG, DIAGIRQ_STAT_0))  // TODO: If GAUSS_GAIN_SEL==0x1 AND it is an TX_EN interrupt (for RX_EN int it is not necessary to run)
  { 
    set_gauss_modgain(cn); 
  }
#endif
  
  GetWord32(BLE_RF_DIAGIRQ_REG);  // read BLE_RF_DIAGIRQ_REG so that you clear DIAGIRQ_STAT_0 (otherwise interrupt is activated again and again!)
}
Exemple #17
0
void rf_reinit_func(void)
{
    uint32 tmp32 = 0;

    SetBits32(&tmp32, RTRIP_DELAY, 7);    
    SetBits32(&tmp32, TXPWRDN, 0x5);  
    SetBits32(&tmp32, RXPWRUP, RXPWRUP_VAL);  
    SetBits32(&tmp32, TXPWRUP, TXPWRUP_VAL);  
    SetWord32(BLE_RADIOPWRUPDN_REG, tmp32);    

    SetBits32(BLE_RADIOCNTL1_REG, XRFSEL, 3);
    SetBits32(BLE_RWBTLECNTL_REG, SYNCERR, 0); //this must be always '0'

    SetBits16(CLK_RADIO_REG, RFCU_DIV, 1); //RFCU clock must always be 8MHz!
    SetBits16(CLK_RADIO_REG, RFCU_ENABLE, 1);
    
    SetBits16(PMU_CTRL_REG, RETENTION_MODE, 0xF);

    if (lp_clk_sel == LP_CLK_XTAL32)
    {
        //If LP clock is XTAL32 in Boost mode set XTAL32K_CUR to 1.
        if (GetBits16(ANA_STATUS_REG, BOOST_SELECTED) == 0x1) 
            SetBits16(CLK_32K_REG,  XTAL32K_CUR, 1);
    }
        
    rf_regs();  
        
#if LUT_PATCH_ENABLED
    const volatile struct LUT_CFG_struct *pLUT_CFG;          // = (const volatile struct LUT_CFG_struct *)(jump_table_struct[lut_cfg_pos]);
    pLUT_CFG= (const volatile struct LUT_CFG_struct *)(jump_table_struct[lut_cfg_pos]);
    if (pLUT_CFG->HW_LUT_MODE)
    {
        SetWord16(RF_VCOCAL_CTRL_REG, vcocal_ctrl_reg_val);
    }
#endif //LUT_PATCH_ENABLED
    enable_rf_diag_irq(RF_DIAG_IRQ_MODE_RXTX);                               // This just enables the TX_EN int. RX_EN int enable status remains as it was
}
Exemple #18
0
/**
 ****************************************************************************************
 * @brief Calculates RCX20 frequency. 
 *
 * @param[in]   cal_time. Calibration time in RCX20 cycles. 
 *
 * @return void 
 ****************************************************************************************
 */
void read_rcx_freq(uint16_t cal_time)
{
    if ( (cal_enable) && ((CFG_LP_CLK == LP_CLK_FROM_OTP) || (CFG_LP_CLK == LP_CLK_RCX20)) )
    {
        while(GetBits16(CLK_REF_SEL_REG, REF_CAL_START) == 1);
        volatile uint32_t high = GetWord16(CLK_REF_VAL_H_REG);
        volatile uint32_t low = GetWord16(CLK_REF_VAL_L_REG);
        volatile uint32_t value = ( high << 16 ) + low;
        volatile uint32_t f = (16000000 * cal_time) / value;

        cal_enable = 0;

        rcx_freq = f;
        rcx_period = ((float) 1000000/f) * 1024;
        rcx_slot_duration = 0.000625 * (float)rcx_freq;
        
#ifdef RCX_MEASURE
        if (rcx_period_last)
        {
            volatile int diff = rcx_period_last - rcx_period;
            if (abs(diff) > rcx_period_diff)
                rcx_period_diff = abs(diff);
        }
        rcx_period_last = rcx_period;
        
        if (rcx_freq_min == 0)
        {
            rcx_freq_min = rcx_freq;
            rcx_freq_max = rcx_freq;
        }
        if (rcx_freq < rcx_freq_min)
            rcx_freq_min = rcx_freq;
        else if (rcx_freq > rcx_freq_max)
            rcx_freq_max = rcx_freq;
#endif    
    }
}
Exemple #19
0
/**
 ****************************************************************************************
 * @brief Initialisation of ble core, pwr and clk
 *
 * The Hclk and Pclk are set
 ****************************************************************************************
 */
void init_pwr_and_clk_ble(void) 
{
    SetBits16(CLK_RADIO_REG, BLE_DIV, 0);
    SetBits16(CLK_RADIO_REG, BLE_ENABLE, 1); 
    SetBits16(CLK_RADIO_REG, RFCU_DIV, 1);
    SetBits16(CLK_RADIO_REG, RFCU_ENABLE, 1);

    /* 
     * Power up BLE core & reset BLE Timers
    */
    SetBits16(CLK_32K_REG,  RC32K_ENABLE, 1);  
    SetBits16(SYS_CTRL_REG, CLK32_SOURCE, 0);  
    SetBits16(CLK_RADIO_REG, BLE_LP_RESET, 1);  
    SetBits16(PMU_CTRL_REG, RADIO_SLEEP, 0);
    while (!(GetWord16(SYS_STAT_REG) & RAD_IS_UP)); // Just wait for radio to truely wake up
                                
    select_lp_clk();

    if ( ((lp_clk_sel == LP_CLK_XTAL32) && (CFG_LP_CLK == LP_CLK_FROM_OTP)) || (CFG_LP_CLK == LP_CLK_XTAL32) )
    {
        SetBits16(CLK_32K_REG, XTAL32K_ENABLE, 1);  // Enable XTAL32KHz 

        // Disable XTAL32 amplitude regulation in BOOST mode
        if (GetBits16(ANA_STATUS_REG, BOOST_SELECTED) == 0x1) 
            SetBits16(CLK_32K_REG,  XTAL32K_DISABLE_AMPREG, 1);  
        else
            SetBits16(CLK_32K_REG,  XTAL32K_DISABLE_AMPREG, 0);  
        SetBits16(CLK_32K_REG,  XTAL32K_CUR, 5);
        SetBits16(CLK_32K_REG,  XTAL32K_RBIAS, 3);
        SetBits16(SYS_CTRL_REG, CLK32_SOURCE, 1);  // Select XTAL32K as LP clock
        
     }
    else if ( ((lp_clk_sel == LP_CLK_RCX20) && (CFG_LP_CLK == LP_CLK_FROM_OTP)) || (CFG_LP_CLK == LP_CLK_RCX20) )
    {
        SetBits16(CLK_RCX20K_REG, RCX20K_NTC, 0xB);      
        SetBits16(CLK_RCX20K_REG, RCX20K_BIAS, 1);
        SetBits16(CLK_RCX20K_REG, RCX20K_TRIM, 0);
        SetBits16(CLK_RCX20K_REG, RCX20K_LOWF, 1);
                           
        SetBits16(CLK_RCX20K_REG, RCX20K_ENABLE, 1);
    
        SetBits16(CLK_RCX20K_REG, RCX20K_SELECT, 1);
    
        SetBits16(SYS_CTRL_REG, CLK32_SOURCE, 0);                                               

        SetBits16(CLK_32K_REG, XTAL32K_ENABLE, 0); // Disable Xtal32KHz
    }
    else
        ASSERT_WARNING(0);
    
    SetBits16(CLK_32K_REG,  RC32K_ENABLE, 0);   // Disable RC32KHz
                                
    SetBits16(CLK_RADIO_REG, BLE_LP_RESET, 0);
    
    if (GetBits16(ANA_STATUS_REG, BOOST_SELECTED) == 0x1) 
        SetWord16(DCDC_CTRL3_REG, 0x5);
    
    /* 
     * Just make sure that BLE core is stopped (if already running)
     */
    SetBits32(BLE_RWBTLECNTL_REG, RWBLE_EN, 0); 
 
    /* 
     * Since BLE is stopped (and powered), set CLK_SEL
     */    
    SetBits32(BLE_CNTL2_REG, BLE_CLK_SEL, 16);
    SetBits32(BLE_CNTL2_REG, BLE_RSSI_SEL, 1);    
}
Exemple #20
0
/**
 ****************************************************************************************
 * @brief Initialisation of ble core, pwr and clk
 *
 * The Hclk and Pclk are set
 ****************************************************************************************
 */
void init_pwr_and_clk_ble(void) 
{

    
    SetBits16(CLK_RADIO_REG, BLE_DIV, 0);
    SetBits16(CLK_RADIO_REG, BLE_ENABLE, 1); 
    SetBits16(CLK_RADIO_REG, RFCU_DIV, 1);
    SetBits16(CLK_RADIO_REG, RFCU_ENABLE, 1);

    /* 
     * Power up BLE core & reset BLE Timers
    */
    SetBits16(CLK_32K_REG,  RC32K_ENABLE, 1);  
    SetBits16(SYS_CTRL_REG, CLK32_SOURCE, 0);  
    SetBits16(CLK_RADIO_REG, BLE_LP_RESET, 1);  
    SetBits16(PMU_CTRL_REG, RADIO_SLEEP, 0);
    while (!(GetWord16(SYS_STAT_REG) & RAD_IS_UP)); // Just wait for radio to truely wake up
                                
    select_lp_clk();   
    if (lp_clk_sel == LP_CLK_XTAL32)
    {
        SetBits16(CLK_32K_REG, XTAL32K_ENABLE, 1);  // Enable XTAL32KHz 

        // Disable XTAL32 amplitude regulation in BOOST mode
        if (GetBits16(ANA_STATUS_REG, BOOST_SELECTED) == 0x1) 
            SetBits16(CLK_32K_REG,  XTAL32K_DISABLE_AMPREG, 1);  
        else
            SetBits16(CLK_32K_REG,  XTAL32K_DISABLE_AMPREG, 0);  
        SetBits16(CLK_32K_REG,  XTAL32K_CUR, 5);
        SetBits16(CLK_32K_REG,  XTAL32K_RBIAS, 3);
        SetBits16(SYS_CTRL_REG, CLK32_SOURCE, 1);  // Select XTAL32K as LP clock
        
     }
    else if (lp_clk_sel == LP_CLK_RCX20)
    {
        SetBits16(CLK_RCX20K_REG, RCX20K_NTC, 0xB);      
        SetBits16(CLK_RCX20K_REG, RCX20K_BIAS, 1);
        SetBits16(CLK_RCX20K_REG, RCX20K_TRIM, 0);
        SetBits16(CLK_RCX20K_REG, RCX20K_LOWF, 1);
                           
        SetBits16(CLK_RCX20K_REG, RCX20K_ENABLE, 1);
    
        SetBits16(CLK_RCX20K_REG, RCX20K_SELECT, 1);
    
        SetBits16(SYS_CTRL_REG, CLK32_SOURCE, 0);                                               
    }
    SetBits16(CLK_32K_REG,  RC32K_ENABLE, 0);   // Disable RC32KHz
                                
    SetBits16(CLK_RADIO_REG, BLE_LP_RESET, 0);
    
    if (GetBits16(ANA_STATUS_REG, BOOST_SELECTED) == 0x1) 
        SetWord16(DCDC_CTRL3_REG, 0x5);
    
    /* 
     * Just make sure that BLE core is stopped (if already running)
     */
    SetBits32(BLE_RWBTLECNTL_REG, RWBLE_EN, 0); 
 
    /* 
     * Since BLE is stopped (and powered), set CLK_SEL
     */    
    SetBits32(BLE_CNTL2_REG, BLE_CLK_SEL, 16);
    SetBits32(BLE_CNTL2_REG, BLE_RSSI_SEL, 1);    

    /* 
     * Set spi interface to software
     */   
#ifdef FPGA_USED     
    // the following 2 lines are for FPGA implementation
    SetBits32(BLE_CNTL2_REG, SW_RPL_SPI, 0);
    SetBits32(BLE_CNTL2_REG, BB_ONLY, 1);     
#endif    
}
/**
 ****************************************************************************************
 * @brief  Handler of the Red LED Timer
 *
 * @param[in]   msgid
 * @param[in]   param 
 * @param[in]   dest_id
 * @param[in]   src_id 
 *
 * @return  KE_MSG_CONSUMED
 ****************************************************************************************
 */
int app_red_led_timer_handler(ke_msg_id_t const msgid,
                              void const *param,
                              ke_task_id_t const dest_id,
                              ke_task_id_t const src_id)
{
    if (!dbg_uses_led_pins() || !((GetWord16(SYS_STAT_REG) & DBG_IS_UP) == DBG_IS_UP)) {
        // GPIOs are not being used by the debugger                    
        switch(red_led_st) {
        case LED_OFF:
            red_led_off();
            break;                    
            
        case DOUBLE_BLINK_LED_IS_ON__TURN_OFF_A:
            red_led_off();
            app_timer_set(APP_RED_LED_TIMER, TASK_APP, DOUBLE_BLINK_RED_OFF_A);
            red_led_st = DOUBLE_BLINK_LED_IS_OFF__TURN_ON_B;
            if ((GetBits16(ANA_STATUS_REG, BOOST_SELECTED) == 0x1) && 
                ((green_led_st == LED_OFF) || (green_led_st == BLINK_LED_IS_OFF__TURN_ON))) {
                app_restore_sleep_mode();
            }
            break;
                
        case DOUBLE_BLINK_LED_IS_OFF__TURN_ON_B:
            red_led_blink();
            app_timer_set(APP_RED_LED_TIMER, TASK_APP, DOUBLE_BLINK_RED_ON_B);
            red_led_st = DOUBLE_BLINK_LED_IS_ON__TURN_OFF_B;
            leds_block_sleep();
            break;                   

        case DOUBLE_BLINK_LED_IS_ON__TURN_OFF_B:
            red_led_off();
            app_timer_set(APP_RED_LED_TIMER, TASK_APP, DOUBLE_BLINK_RED_OFF_B);
            red_led_st = LED_OFF;
            if ((GetBits16(ANA_STATUS_REG, BOOST_SELECTED) == 0x1) &&
                ((green_led_st == LED_OFF) || (green_led_st == BLINK_LED_IS_OFF__TURN_ON))) {
                app_restore_sleep_mode();
            }
            break;                        

        case BLINK_LED_IS_ON__TURN_OFF:
            red_led_off();
            app_timer_set(APP_RED_LED_TIMER, TASK_APP, BLINK_RED_OFF);
            red_led_st = BLINK_LED_IS_OFF__TURN_ON;
            if ((GetBits16(ANA_STATUS_REG, BOOST_SELECTED) == 0x1) &&
                ((green_led_st == LED_OFF) || (green_led_st == BLINK_LED_IS_OFF__TURN_ON))){
                app_restore_sleep_mode(); // restore sleep
            }
            break;
                
        case BLINK_LED_IS_OFF__TURN_ON:
            red_led_blink();
            app_timer_set(APP_RED_LED_TIMER, TASK_APP, BLINK_RED_ON);
            leds_block_sleep();
            break;
            
        case LED_ON:
            red_led_off();
            if ((GetBits16(ANA_STATUS_REG, BOOST_SELECTED) == 0x1) &&
                ((green_led_st == LED_OFF) || (green_led_st == BLINK_LED_IS_OFF__TURN_ON))) {
                app_restore_sleep_mode(); // restore sleep
            }
            high_priority_indications_active = false;
            break;
            
        default:
            break;
        }
    }
		
	return (KE_MSG_CONSUMED);
}
Exemple #22
0
sleep_mode_t rwip_sleep(void)
{
    sleep_mode_t proc_sleep = mode_active;
    uint32_t twirq_set_value;
    uint32_t twirq_reset_value;
    uint32_t twext_value;
    #if (DEEP_SLEEP)
    uint32_t sleep_duration = jump_table_struct[max_sleep_duration_external_wakeup_pos];//MAX_SLEEP_DURATION_EXTERNAL_WAKEUP;
    #endif //DEEP_SLEEP
#ifndef DEVELOPMENT_DEBUG
    uint32_t sleep_lp_cycles;
#endif

    DBG_SWDIAG(SLEEP, ALGO, 0);

#if (BLE_APP_PRESENT)
    if ( app_ble_ext_wakeup_get() || (rwip_env.ext_wakeup_enable == 2) )  // sleep forever!
        sleep_duration = 0;
#else
# if (!EXTERNAL_WAKEUP) // sleep_duration will remain as it was set above....
    if (rwip_env.ext_wakeup_enable == 2)
        sleep_duration = 0;
# endif		
#endif    
    
    do
    {
        /************************************************************************
         **************            CHECK STARTUP FLAG             **************
         ************************************************************************/
        POWER_PROFILE_INIT;

        // Do not allow sleep if system is in startup period
        if (check_sys_startup_period())
            break;
        
        /************************************************************************
         **************            CHECK KERNEL EVENTS             **************
         ************************************************************************/
        // Check if some kernel processing is ongoing
        if (!ke_sleep_check())
            break;
        
        // Processor sleep can be enabled
        proc_sleep = mode_idle;

        DBG_SWDIAG(SLEEP, ALGO, 1);

        
#if (DEEP_SLEEP)
        /************************************************************************
         **************             CHECK ENABLE FLAG              **************
         ************************************************************************/
        // Check sleep enable flag
        if(!rwip_env.sleep_enable)
            break;

        
        /************************************************************************
         **************           CHECK RADIO POWER DOWN           **************
         ************************************************************************/
        // Check if BLE + Radio are still sleeping
        if(GetBits16(SYS_STAT_REG, RAD_IS_DOWN)) {
            // If BLE + Radio are in sleep return the appropriate mode for ARM
            proc_sleep = mode_sleeping;
            break;
        }

        /************************************************************************
         **************              CHECK RW FLAGS                **************
         ************************************************************************/
        // First check if no pending procedure prevents us from going to sleep
        if (rwip_prevent_sleep_get() != 0)
            break;

        DBG_SWDIAG(SLEEP, ALGO, 2);

        
        /************************************************************************
         **************           CHECK EXT WAKEUP FLAG            **************
         ************************************************************************/
        /* If external wakeup is enabled, sleep duration can be set to maximum, otherwise
         * the system must be woken-up periodically to poll incoming packets from HCI */
        if((BLE_APP_PRESENT == 0) || (BLE_INTEGRATED_HOST_GTL == 1 )) // No need for periodic wakeup if we have full-hosted system
        {
            if(!rwip_env.ext_wakeup_enable)
                sleep_duration = jump_table_struct[max_sleep_duration_periodic_wakeup_pos]; // MAX_SLEEP_DURATION_PERIODIC_WAKEUP;
        }

        
        
        /************************************************************************
         *                                                                      *
         *                   CHECK DURATION UNTIL NEXT EVENT                    *
         *                                                                      *
         ************************************************************************/
        // If there's any timer pending, compute the time to wake-up to serve it
        if (ke_env.queue_timer.first != NULL)
            sleep_duration = jump_table_struct[max_sleep_duration_external_wakeup_pos];
#ifdef USE_POWER_OPTIMIZATIONS
        // Store sleep_duration calculated so far. Check below if sleep would be allowed.
        // If not, there's no reason to verify / ensure the available time for SLP...
        uint32_t tmp_dur = sleep_duration;
#endif

        /************************************************************************
         **************            CHECK KERNEL TIMERS             **************
         ************************************************************************/
        // Compute the duration up to the next software timer expires
        if (!ke_timer_sleep_check(&sleep_duration, rwip_env.wakeup_delay))
            break;

        DBG_SWDIAG(SLEEP, ALGO, 3);

        #if (BLE_EMB_PRESENT)
        /************************************************************************
         **************                 CHECK BLE                  **************
         ************************************************************************/
        // Compute the duration up to the next BLE event
        if (!lld_sleep_check(&sleep_duration, rwip_env.wakeup_delay))
            break;
        #endif // BLE_EMB_PRESENT
        
        DBG_SWDIAG(SLEEP, ALGO, 4);

        #if (BT_EMB_PRESENT)
        /************************************************************************
         **************                 CHECK BT                   **************
         ************************************************************************/
        // Compute the duration up to the next BT active slot
        if (!ld_sleep_check(&sleep_duration, rwip_env.wakeup_delay))
            break;
        #endif // BT_EMB_PRESENT

        DBG_SWDIAG(SLEEP, ALGO, 5);

        #if (HCIC_ITF)
        /************************************************************************
         **************                 CHECK HCI                  **************
         ************************************************************************/
        if((BLE_APP_PRESENT == 0) || (BLE_INTEGRATED_HOST_GTL == 1 ))
        {       
            // Try to switch off HCI
            if (!hci_enter_sleep())
                break;
        }
        #endif // HCIC_ITF

        #if (GTL_ITF)
        /************************************************************************
         **************                 CHECK TL                   **************
         ************************************************************************/
        if((BLE_APP_PRESENT == 0) || (BLE_INTEGRATED_HOST_GTL == 1 ))
        {
            // Try to switch off Transport Layer
            if (!gtl_enter_sleep())
                break;
        }
        #endif // GTL_ITF

        DBG_SWDIAG(SLEEP, ALGO, 6);
        
#ifdef USE_POWER_OPTIMIZATIONS
        /************************************************************************
         ******      BLOCK UNTIL THERE'S TIME FOR sleep() AND SLP ISR      ******
         ************************************************************************/
        uint32_t xtal16m_settling_cycles;
        bool rcx_duration_corr = false;
        
        // Restore sleep_duration
        sleep_duration = tmp_dur;
        /*
         * Wait until there's enough time for SLP to restore clocks when the chip wakes up.
         * Then check again if sleep is possible.
         */
        if ( ((lp_clk_sel == LP_CLK_RCX20) && (CFG_LP_CLK == LP_CLK_FROM_OTP)) || (CFG_LP_CLK == LP_CLK_RCX20) )
        {
            xtal16m_settling_cycles = lld_sleep_us_2_lpcycles_sel_func(XTAL16M_SETTLING_IN_USEC);
            
            while ( (ble_finetimecnt_get() < 550) && (ble_finetimecnt_get() > 200) ); 
            // If we are close to the end of this slot then the actual sleep entry will
            // occur during the next one. But the sleep_duration will have been calculated
            // based on the current slot...
            if (ble_finetimecnt_get() <= 200)
                rcx_duration_corr = true;
        }
        else if ( ((lp_clk_sel == LP_CLK_XTAL32) && (CFG_LP_CLK == LP_CLK_FROM_OTP)) || (CFG_LP_CLK == LP_CLK_XTAL32) )
        {
            while (ble_finetimecnt_get() < 300);  
        }
        
        /************************************************************************
         *                                                                      *
         *                   CHECK DURATION UNTIL NEXT EVENT                    *
         *                       (this is the 2nd check)                        *
         *                                                                      *
         ************************************************************************/
        bool sleep_check = false;
        
        do
        {
            /************************************************************************
             **************            CHECK KERNEL TIMERS (2)         **************
             ************************************************************************/
            // Compute the duration up to the next software timer expires
            if (!ke_timer_sleep_check(&sleep_duration, rwip_env.wakeup_delay))
                break;

            DBG_SWDIAG(SLEEP, ALGO, 3);

            #if (BLE_EMB_PRESENT)
            /************************************************************************
             **************                 CHECK BLE (2)              **************
             ************************************************************************/
            // Compute the duration up to the next BLE event
            if (!lld_sleep_check(&sleep_duration, rwip_env.wakeup_delay))
                break;
            #endif // BLE_EMB_PRESENT
            
            sleep_check = true;
        } while(0);
        
        if (!sleep_check)
        {
            if((BLE_APP_PRESENT == 0) || (BLE_INTEGRATED_HOST_GTL == 1 ))
            {
#if BLE_HOST_PRESENT		
                gtl_eif_init();
#else
                hci_eif_init();
#endif		
            }
            // sleep is aborted and serial i/f communication is restored
            break;
        }
        
        if (sleep_duration && rcx_duration_corr)
            sleep_duration--;
        
        DBG_SWDIAG(SLEEP, ALGO, 4);
#endif

        POWER_PROFILE_CHECKS_COMPLETED;
        
        /************************************************************************
         **************          PROGRAM CORE DEEP SLEEP           **************
         ************************************************************************/
        if ( ((lp_clk_sel == LP_CLK_RCX20) && (CFG_LP_CLK == LP_CLK_FROM_OTP)) || (CFG_LP_CLK == LP_CLK_RCX20) )
        {
#if !defined(USE_POWER_OPTIMIZATIONS)
            twirq_set_value = lld_sleep_us_2_lpcycles_sel_func(XTAL_TRIMMING_TIME_USEC);
            
            twirq_reset_value = TWIRQ_RESET_VALUE;
            
            // TWEXT setting
            twext_value = TWEXT_VALUE_RCX;
#else
            // Calculate the time we need to wake-up before "time 0" to do XTAL16 settling,
            // call periph_init() and power-up the BLE core.
            uint32_t lpcycles = lld_sleep_us_2_lpcycles_sel_func(LP_ISR_TIME_USEC);
            
            // Set TWIRQ_SET taking into account that some LP cycles are needed for the power up FSM.
            twirq_set_value = RCX_POWER_UP_TIME + lpcycles;
            if (sleep_env.slp_state == ARCH_DEEP_SLEEP_ON)
                twirq_set_value += RCX_OTP_COPY_OVERHEAD;
            
            // BOOST mode + RCX is not supported
            if (GetBits16(ANA_STATUS_REG, BOOST_SELECTED) == 1)
                ASSERT_WARNING(0);

            // Program LP deassertion to occur when the XTAL16M has settled
            twirq_reset_value = lpcycles - xtal16m_settling_cycles;
            
            // TWEXT setting
            twext_value = lpcycles;
#endif
        }
        else if ( ((lp_clk_sel == LP_CLK_XTAL32) && (CFG_LP_CLK == LP_CLK_FROM_OTP)) || (CFG_LP_CLK == LP_CLK_XTAL32) )
        {
#if !defined(USE_POWER_OPTIMIZATIONS)
            twirq_set_value = XTAL_TRIMMING_TIME;
            twirq_reset_value = TWIRQ_RESET_VALUE;
            twext_value = TWEXT_VALUE_XTAL32;
#else       
            // The time we need to wake-up before "time 0" to do XTAL16 settling,
            // call periph_init() and power-up the BLE core is LP_ISR_TIME_XTAL32_CYCLES in this case.
            
            // Set TWIRQ_SET taking into account that some LP cycles are needed for the power up FSM.
            twirq_set_value = XTAL32_POWER_UP_TIME + LP_ISR_TIME_XTAL32_CYCLES;
            if (sleep_env.slp_state == ARCH_DEEP_SLEEP_ON)
                twirq_set_value += XTAL32_OTP_COPY_OVERHEAD;
            
            // Adjust TWIRQ_SET in case of BOOST mode, if needed
            if (set_boost_low_vbat1v_overhead == APPLY_OVERHEAD)
                twirq_set_value += BOOST_POWER_UP_OVERHEAD;
            set_boost_low_vbat1v_overhead = NOT_MEASURED;

            // Program LP deassertion to occur when the XTAL16M has settled
            twirq_reset_value = LP_ISR_TIME_XTAL32_CYCLES - XTAL16M_SETTLING_IN_XTAL32_CYCLES;
            
            // TWEXT setting
            twext_value = LP_ISR_TIME_XTAL32_CYCLES;
#endif
        }

       
        //Prepare BLE_ENBPRESET_REG for next sleep cycle
        SetBits32(BLE_ENBPRESET_REG, TWIRQ_RESET, twirq_reset_value);   // TWIRQ_RESET
        SetBits32(BLE_ENBPRESET_REG, TWIRQ_SET, twirq_set_value);       // TWIRQ_SET
        SetBits32(BLE_ENBPRESET_REG, TWEXT, twext_value);               // TWEXT

        //Everything ready for sleep!
        proc_sleep = mode_sleeping;
        
#ifdef USE_POWER_OPTIMIZATIONS
        // Eliminate any additional delays.
        if (sleep_duration) 
            sleep_duration += SLEEP_DURATION_CORR;
        
        POWER_PROFILE_SLEEP_TIMES;
#endif

        #if (BT_EMB_PRESENT)
        // Put BT core into deep sleep
        ld_sleep_enter(rwip_slot_2_lpcycles(sleep_duration), rwip_env.ext_wakeup_enable);
        #elif (BLE_EMB_PRESENT)
        // Put BT core into deep sleep
        if ( ((lp_clk_sel == LP_CLK_XTAL32) && (CFG_LP_CLK == LP_CLK_FROM_OTP)) || (CFG_LP_CLK == LP_CLK_XTAL32) )
            sleep_lp_cycles = rwip_slot_2_lpcycles(sleep_duration);
        else if ( ((lp_clk_sel == LP_CLK_RCX20) && (CFG_LP_CLK == LP_CLK_FROM_OTP)) || (CFG_LP_CLK == LP_CLK_RCX20) )
            sleep_lp_cycles = rwip_slot_2_lpcycles_rcx(sleep_duration);
        
        lld_sleep_enter(sleep_lp_cycles, rwip_env.ext_wakeup_enable);
        #endif //BT_EMB_PRESENT / BT_EMB_PRESENT
        

        DBG_SWDIAG(SLEEP, SLEEP, 1);

        /************************************************************************
         **************               SWITCH OFF RF                **************
         ************************************************************************/        
        POWER_PROFILE_REMAINING_TIME;
        
        rwip_rf.sleep();
        
#ifdef USE_POWER_OPTIMIZATIONS
        // We may lower the clock now while we are waiting the BLE to go to sleep...
        bool slow_system_clk = false;
#if (BLE_APP_PRESENT)            
        if ( app_use_lower_clocks_check() )
#endif
        {
            // It will save some power if you lower the clock while waiting for STAT...
            SetBits16(CLK_AMBA_REG, PCLK_DIV, 3);  // lowest is 2MHz (div 8, source is @16MHz)
            SetBits16(CLK_AMBA_REG, HCLK_DIV, 3);
            
            slow_system_clk = true;
        }
#endif
                
        while(!ble_deep_sleep_stat_getf());
                
        //check and wait till you may disable the radio. 32.768KHz XTAL must be running!
        //(debug note: use BLE_CNTL2_REG:MON_LP_CLK bit to check (write 0, should be set to 1 by the BLE))
        while ( !(GetWord32(BLE_CNTL2_REG) & RADIO_PWRDN_ALLOW) ) {};
        
#ifdef USE_POWER_OPTIMIZATIONS
        if (slow_system_clk)
        {
            // and restore clock rates (refer to a couple of lines above)
            use_highest_amba_clocks();
        }
#endif

        ble_regs_push();    // push the ble ret.vars to retention memory
//        smpc_regs_push();   // push smpc ble ret.vars to retention memory
        
        //BLE CLK must be turned off when DEEP_SLEEP_STAT is set
        SetBits16(CLK_RADIO_REG, BLE_ENABLE, 0);   												

        #endif // DEEP_SLEEP
    } while(0);

    return proc_sleep;
}
Exemple #23
0
/*
 * LOCAL FUNCTIONS DEFINITIONS
 ****************************************************************************************
 */
 
 
// ============================================================================================
// ==================== DEEP SLEEP PATCH - THIS CODE MUST STAY IN RAM =========================
// ============================================================================================
extern void rf_workaround_init(void);
extern void rf_reinit(void);

// /*********************************************************************************
//  *** WAKEUP_LP_INT ISR
//  ***/
void BLE_WAKEUP_LP_Handler(void)
{    
	volatile long t=0;

#if !(USE_WDOG)
    SetWord16(SET_FREEZE_REG, FRZ_WDOG); //Prepare WDOG, i.e. stop
#endif
    
//    // 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
//    }
    
	/*
	* Wait and Switch to XTAL 16MHz
	* (default after each wake-up is RC 16MHz, but XTAL initialization sequence has been already initiated by PMU)
	* NOTE: 
	*       1. If app does not need XTAL16MHz but RC16MHz is enough then skip this section!
	*       2. Wait-loop BEFORE activating PERIPH_PD in order to save some power...
	*/
    // It will save some power if you lower the clock while waiting for XTAL16 to settle.
	// Could also switch to 32KHz, but then processing power is dramatically reduced (e.g. patching() routine may be too slow).
    SetBits16(CLK_AMBA_REG, PCLK_DIV, 3);  // lowest is 2MHz (div 8, source is RC @16MHz)
    SetBits16(CLK_AMBA_REG, HCLK_DIV, 3);

    while ( !GetBits16(SYS_STAT_REG, XTAL16_SETTLED) )  // this takes some mili seconds
        __NOP(), __NOP(), __NOP();  // reduce some APB activity

    SetBits16(CLK_CTRL_REG, SYS_CLK_SEL, 0); // select XTAL 16MHz
    SetBits16(CLK_16M_REG, RC16M_ENABLE, 0); // save power from RC 16MHz
    
    // and restore clock rates (refer to a couple of lines above)
    SetBits16(CLK_AMBA_REG, PCLK_DIV, 0);
    SetBits16(CLK_AMBA_REG, HCLK_DIV, 0);
    
    /*
	* Init System Power Domain blocks: GPIO, WD Timer, Sys Timer, etc.
	* Power up and init Peripheral Power Domain blocks,
	* and finally release the pad latches.
	*/
    if(GetBits16(SYS_STAT_REG, PER_IS_DOWN))
        periph_init();

    
	/*
	* Since XTAL 16MHz is activated, power-up the Radio Subsystem (including BLE)
	*
	* Note that BLE core clock is masked in order to handle the case where RADIO_PD does not get into power down state.
	* The BLE clock should be active only as long as system is running at XTAL 16MHz (not at RC16 or 32KHz).
	* Also BLE clock should be enabled before powering up the RADIO Power Domain !
	*/
	SetBits16(CLK_RADIO_REG, BLE_ENABLE, 1); // BLE clock enable
	SetBits16(PMU_CTRL_REG, RADIO_SLEEP, 0); // Power up! Note: System must run at 16MHz when powering up RADIO_PD.
	while (!(GetWord16(SYS_STAT_REG) & RAD_IS_UP)) {}; // this may take up to 1/2 of the 32KHz clock period
        
        
    /* 
    * Wait for at least one Low Power clock edge after the power up of the Radio Power Domain *e.g. with ble_wait_lp_clk_posedge() )
    * or even better check the BLE_CNTL2_REG[WAKEUPLPSTAT] !
    * Thus you assure that BLE_WAKEUP_LP_IRQ is deasserted and BLE_SLP_IRQ is asserted.
    * After this check exit this ISE in order to proceed with BLE_SLP_Handler().
    */
	while ( GetBits32(BLE_CNTL2_REG, WAKEUPLPSTAT) || !GetBits32(BLE_INTSTAT_REG, SLPINTSTAT))
		if (t) break;

	// Now BLE_WAKEUP_LP_IRQ is deasserted and BLE_SLP_IRQ is asserted, so exit in order to proceed with BLE_SLP_Handler().
	// NOTE: If returning from BLE_WAKEUP_LP_Handler() will not cause BLE_SLP_Handler() to start, 
	//       but the code after __WFI() is executed, then THERE WAS A SW SETUP PROBLEM !!! 
	//			 so it is recommended to place a check after __WFI().
}
Exemple #24
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
    }
}
/**
 ****************************************************************************************
 * @brief WKUPCT IRQ Handler
 *
 * @return void
 ****************************************************************************************
 */ 
void WKUP_QUADEC_Handler(void)
{

#ifdef WKUP_ENABLED    
	wakeup_handler_function_t wakeupHandlerFunction;   
#endif //WKUP_ENABLED 
#ifdef QUADEC_ENABLED    
    quad_encoder_handler_function_t quadEncoderHandlerFunction;   
#endif //QUADEC_ENABLED
    uint8_t source = 0;
	/*
	* The system operates with RC16 clk
	*/
    
	/*
	* Restore clock 
	*/
	SetBits16(CLK_AMBA_REG, PCLK_DIV, 0); 
	SetBits16(CLK_AMBA_REG, HCLK_DIV, 0);
#ifdef QUADEC_ENABLED
    if ((GetBits16(CLK_PER_REG, QUAD_ENABLE) != 0) && (GetBits16(QDEC_CTRL_REG,QD_IRQ_STATUS) !=0 ))
    { // Quadrature Decoder clock is enabled & Quadrature Decoder interrupt has triggered
        source = SRC_QUAD_IRQ;
        SetBits16(QDEC_CTRL_REG, QD_IRQ_CLR, 1);  // write 1 to clear Quadrature Decoder interrupt
        SetBits16(QDEC_CTRL_REG, QD_IRQ_MASK, 0); // write 0 to mask the Quadrature Decoder interrupt
    }
    else 
#endif //QUADEC_ENABLED
    {
#ifdef WKUP_ENABLED
        if  ((GetBits16(CLK_PER_REG, WAKEUPCT_ENABLE) != 0))
        { // since the interrupt does not come from the Quadrature controller, it is from the wakeup timer
            source = SRC_WKUP_IRQ;
            SetWord16(WKUP_RESET_IRQ_REG, 1); //Acknowledge it
            SetBits16(WKUP_CTRL_REG, WKUP_ENABLE_IRQ, 0); //No more interrupts of this kind
        }
#endif //WKUP_ENABLED
    }
    /* Note: in case of simultaneous triggering of quadrature decoder and wakeup timer, quadrature decoder
             interrupt will be handled. The */ 

	
	///To check SetBits16(CLK_PER_REG, WAKEUPCT_ENABLE, 1);  // enable clock of Wakeup Controller
	
	//NVIC_DisableIRQ(WKUP_QUADEC_IRQn);

    /*
	* Init System Power Domain blocks: GPIO, WD Timer, Sys Timer, etc.
	* Power up and init Peripheral Power Domain blocks,
	* and finally release the pad latches.
	*/
    
    
    //if(GetBits16(SYS_STAT_REG, PER_IS_DOWN))
		//periph_init();

	/*
	* run callback functions
	*/
#ifdef QUADEC_ENABLED    
    if (source == SRC_QUAD_IRQ)
    {
        if (QUADDEC_callback != NULL) // Quadrature Decoder callback has been set-up by the application clock is enabled
        {
            int16_t x,y,z;
            
            x = quad_decoder_get_x_counter();
            y = quad_decoder_get_y_counter();
            z = quad_decoder_get_z_counter();
            quadEncoderHandlerFunction = (quad_encoder_handler_function_t)(QUADDEC_callback);    
            quadEncoderHandlerFunction(x,y,z);
        }
    }        
    else 
#endif //QUADEC_ENABLED
    {
#ifdef WKUP_ENABLED        
        if (source == SRC_WKUP_IRQ)
        {
            if (WKUPCT_callback != NULL)
            {
                wakeupHandlerFunction = (wakeup_handler_function_t)(WKUPCT_callback);    
                wakeupHandlerFunction();
            }
        }
#endif //WKUP_ENABLED
    }
	return;
}
Exemple #26
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
    }
}
/**
 ****************************************************************************************
 * @brief Block sleep when a LED is up in BOOST mode for the period a LED is on.
 *
 * @param   None    
 *
 * @return  void
 ****************************************************************************************
 */
void leds_block_sleep()
{
    if ((GetBits16(ANA_STATUS_REG, BOOST_SELECTED) == 0x1) && app_get_sleep_mode()) {
        app_force_active_mode(); // in BOOST mode, prevent sleep only if enabled
    }
}