Example #1
0
void $Sub$$UART_Handler(void)
#endif
{
    uint32_t idd;
        
    idd = 0x0F & GetWord32(UART_IIR_FCR_REG);
    if(idd!=NO_INT_PEND)
    {
        switch(idd)
        {
            case UART_TIMEOUT:
                if ((uart_sps_env.errordetect == UART_ERROR_DETECT_ENABLED) && uart_fifo_err_getf())
                {
                    uart_sps_rec_error_isr();
                }
                uart_sps_timeout_data_avail_isr();
                break;
            case RECEIVED_AVAILABLE:
                uart_sps_rec_data_avail_isr();               
                break;
            case THR_EMPTY:
                uart_sps_thr_empty_isr();
                break;
            default:
                break;
        }
    }
}
Example #2
0
bool uart_sps_flow_off(void)
{
    bool flow_off = true;

    do
    {
        // First check if no transmission is ongoing
        if ((uart_temt_getf() == 0) || (uart_thre_getf() == 0) || !uart_sps_is_rx_fifo_empty())
        {
            flow_off = false;
            break;
        }
        // Configure modem (HW flow control disable, 'RTS flow off')
        SetWord32(UART_MCR_REG, GetWord32(UART_MCR_REG) & (~UART_RTS)); 
        //SetWord32(UART_MCR_REG, 0);
        
        // Wait for 1 character duration to ensure host has not started a transmission at the
        // same time
        for (int i=0;i<UART_WAIT_BYTE_COUNTER;i++);

        // Check if data has been received during wait time
        if(!uart_sps_is_rx_fifo_empty())
        {
            // Re-enable UART flow
            uart_sps_flow_on();

            // We failed stopping the flow
            flow_off = false;
        }
    } while(false);
    
    
    return (flow_off);
}
Example #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 Used to calculate the boot image CRC
* @param[in] length: 	Length of the image in 32-bit words
* @return CRC checksum (1 byte)
****************************************************************************************
*/
uint8_t calc_crc(uint32_t length){
  uint32_t i;
  uint32_t temp;
  uint8_t crc;
  crc=0xFF;
  for(i=0;i<length;i++)
  {
    temp=GetWord32(program_t+4*i);
    crc^=(0xFF&(temp>>24));
    crc^=(0xFF&(temp>>16));
    crc^=(0xFF&(temp>>8 ));
    crc^=(0xFF&(temp		));
  }
  return crc;
}
Example #5
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!)
}
Example #6
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;
}
Example #7
0
void uart_sps_force_flow_off(void)
{
    SetWord32(UART_MCR_REG, GetWord32(UART_MCR_REG) & (~UART_RTS));
}