/** **************************************************************************************** * * @file arch_main.c * * @brief Main loop of the application. * * Copyright (C) RivieraWaves 2009-2015 * * **************************************************************************************** */ /* * INCLUDES **************************************************************************************** */ #include "rwip_config.h" // RW SW configuration #include "arch.h" // architectural platform definitions #include // standard lib functions #include // standard definitions #include // standard integer definition #include // boolean definition #include "boot.h" // boot definition #include "rwip.h" // RW SW initialization #include "xc_drv_pwr.h" #if (BLE_TEST_MODE_SUPPORT) #include "uart.h" // UART initialization #endif // (BLE_TEST_MODE_SUPPORT) #if (BLE_EMB_PRESENT || BT_EMB_PRESENT) #include "rf.h" // RF initialization #endif // BLE_EMB_PRESENT || BT_EMB_PRESENT #if (BLE_APP_PRESENT) //#include "app.h" // application functions #endif // BLE_APP_PRESENT #if PLF_DMA #include "dma.h" // DMA initialization #endif // PLF_DMA #if (PLF_NVDS) #include "nvds.h" // NVDS definitions #endif // PLF_NVDS #include "reg_assert_mgr.h" #if (PLF_PROFILING || PLF_MEM_PROTECTION) #include "reg_sw_profiling.h" #endif // (PLF_PROFILING || PLF_MEM_PROTECTION) #include "platform.h" #include "xc6xxx.h" //CPU early wake-up time (unit:us) #define SLEEP_TIME_EARLY (3300) #define HS_TO_US(frame) (((frame) * SLOT_SIZE) >> 1) /** * @brief clock_init * @details * @param void * @retval void */ void clock_init(void) { CLOCK_InitCfg_t clock_cfg; clock_cfg.hfclk_src = CLOCK_HFCLK_SRC_XTAL; clock_cfg.hfclk_in = CLOCK_HFCLK_IN_32M; clock_cfg.lfclk_src = CLOCK_LFCLK_SRC_RC; // clock_cfg.lfclk_src = CLOCK_LFCLK_SRC_XTAL; if(clock_cfg.lfclk_src == CLOCK_LFCLK_SRC_XTAL) { clock_cfg.lfclk_in = CLOCK_LFCLK_IN_32768; } else if(clock_cfg.lfclk_src == CLOCK_LFCLK_SRC_RC) { clock_cfg.lfclk_in = CLOCK_LFCLK_IN_32K; } xc_clock_init_cfg(&clock_cfg); SysTick_Config(xc_clock_hfclk_in_get( ) / 100); SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk; } #if (SLEEP_ENABLE) void system_sleep_init() { uint32_t wake_it_src; #if (USE_XIP == 1) xc_fmc_spi_init_oprt(); #endif #if 0 #if (USE_XIP!=1) SPI_InitCfg_t spi_cfg = {0}; spi_cfg.Mode = SPI_MODE_MASTER; spi_cfg.DataSize = SSI_CTRL0_DFS_LEN_8BIT; spi_cfg.Direction = SSI_CTRL0_TMOD_WR; spi_cfg.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2; spi_cfg.CLKPolarity = SSI_CTRL0_SCPOL_LOW; spi_cfg.CLKPhase = SPI_CPHA_LEAD; spi_cfg.FirstBit = SPI_FirstBit_MSB; xc_spi_init(XC_SPI0, &spi_cfg); SPI_Flash_PowerDown(XC_SPI0); #endif #endif xc_pwr_gpio_sleep_config(); wake_it_src = GPIO_IRQn_WAKE | RTC_IRQn_WAKE|TIMER_AO0_IRQn_WAKE| TIMER0_IRQn_WAKE; xc_pwr_wake_it_set(wake_it_src); } void system_lightsleep_cfg() { #if (USE_XIP!=1) cprao_aon_puctrl1_set(0x4);/* puctrl1= 0x4 , SSI0RX must pulldown*/ #endif cprao_aon_sys_time_set((RST_READY_TIME<<12) | (OSC32_STABLE_TIME)); xc_pwr_pd_lightsleep_set(); xc_pwr_sleepsrc_mask_set(0x1e001e); xc_pwr_osc_off(); } void cpu_switch_16M() { //M0_FCLK cpr_m0_fclk_ctl__m0_fclk_div_p__setf(0x1); cpr_m0_fclk_ctl__m0_fclk_direct_sw__setf(0x1); //CTL_PCLK cpr_ctl_pclk_grctl__ctl_pclk_gr__setf(0x8); cpr_ctl_pclk_grctl__ctl_pclk_gr_upd__setf(0x1); cprao_aon_bbldo_adj_set(0x3c); /* The value needs to be configured to 7, otherwise the current drop will be slower during sleep and the clock accuracy of the rc32k will be affected. */ cprao_aon_lpoldo_adj_set(0x7); } void sleep_init(void) { system_sleep_init(); system_lightsleep_cfg(); /* Timer for sleep-wake*/ Timer_InitCfg_t timer_cfg; timer_cfg.timer_src_clk = TIMER_CLK_SRC_32K; timer_cfg.timer_div_clk = TIMER_DIV_CLK_32000Hz; timer_cfg.timer_mode = TIMER_MODE_SINGLE; xc_timer_init(TIMER0_IDX, &timer_cfg); //cpu 32M->16M // cpu_switch_16M(); } __RAM_CODE void xc_ble_sleep(void) { xc_adc_powerdown(); xc_pwr_usb_off(); xc_pwr_rc16m_off(); xc_pwr_rc32k_calib_off(); xc_pwr_opa_tempsensor_off(); xc_pwr_opa_volr_off(); xc_pwr_revddldo_off(); xc_pwr_dcdc_close(); xc_pwr_rfdigital_off(); xc_pwr_rc32k_calib_off(); xc_pwr_modem_off(); xc_pwr_pd_lightsleep_set(); #if (USE_XIP == 1) #if (USE_ROM_FLASH) FMC_SPI_Flash_PowerDown(); xc_pwr_rom_off(); #else // (USE_ROM_FLASH) // xc_fmc_spi_flash_power_down(); #endif // (USE_ROM_FLASH) __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); // cpr_fmc_ctl_set(0x3000 | (1 << 9)); // close FMC for (int i = 0; i < 10; i++) { __NOP(); __NOP(); __NOP(); } #endif // __disable_irq(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __WFI(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); // cpr_fmc_ctl_set(0x3503); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); #if (USE_ROM_FLASH) xc_pwr_rom_on(); FMC_SPI_Flash_WakeUp(); #else // (USE_ROM_FLASH) // xc_fmc_spi_flash_wake_up(); #endif // (USE_ROM_FLASH) xc_pwr_ao_timer_pclk32m_Set(); // __enable_irq(); #ifdef USED_DCDC PWR_DCDC_Open(); #endif xc_pwr_modem_on(); xc_pwr_rfdigital_on(); xc_adc_wakeup(); } void enter_cpu_sleep() { cpr_ctlapbclken_grctl__uart0_pclk_en__setf(0); cpr_ahbclken_grctl__dmas_hclk_en__setf(0); cpr_slp_src_mask_set(0x1e000e); __NOP();__NOP();__NOP();__NOP();__NOP();__NOP(); __WFI(); __NOP();__NOP();__NOP();__NOP();__NOP();__NOP(); cpr_slp_src_mask_set(0x1e001e); // open uart clk cpr_ctlapbclken_grctl__uart0_pclk_en__setf(1); } void sleep_schedule() { // Checks for sleep have to be done with interrupt disabled GLOBAL_INT_DISABLE(); // Check if the processor clock can be gated uint32_t duration = 0; uint32_t duration_timer = 0; switch(rwip_sleep(&duration, 2, \ 0x7D00, RWIP_MINIMUM_SLEEP_TIME)){ case RWIP_DEEP_SLEEP: { delay_us(200); duration_timer = (HS_TO_US(duration) - SLEEP_TIME_EARLY); xc_timer_set_value(TIMER0_IDX, duration_timer); xc_timer_start(TIMER0_IDX); xc_ble_sleep(); xc_timer_stop(TIMER0_IDX); } // no break case RWIP_CPU_SLEEP: { enter_cpu_sleep(); } break; case RWIP_ACTIVE: default: { // nothing to do. } break; } // Checks for sleep have to be done with interrupt disabled GLOBAL_INT_RESTORE(); } #endif // (SLEEP_ENABLE)