461 lines
11 KiB
C
461 lines
11 KiB
C
/**
|
|
****************************************************************************************
|
|
*
|
|
* @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 "boot.h" // boot definition
|
|
#include "rwip.h" // RW SW initialization
|
|
#include "xc_drv_pwr.h"
|
|
#include <stdbool.h> // boolean definition
|
|
#include <stddef.h> // standard definitions
|
|
#include <stdint.h> // standard integer definition
|
|
#include <stdlib.h> // standard lib functions
|
|
|
|
#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 "sleep.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_64M;
|
|
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)
|
|
#if (USE_ROM_FLASH)
|
|
FMC_SPI_Init_Oprt();
|
|
#else // (USE_ROM_FLASH)
|
|
xc_fmc_spi_init_oprt();
|
|
#endif // (USE_ROM_FLASH)
|
|
#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();
|
|
cprao_aon_bbldo_adj_set(0x2a);
|
|
cprao_aon_lpoldo_adj_set(0x7);
|
|
}
|
|
|
|
__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();
|
|
cprao_aon_reg4__bb_coreldo_normal_sw_mux__setf(1);
|
|
xc_pwr_modem_off();
|
|
xc_pwr_pd_lightsleep_set();
|
|
|
|
#if (USE_XIP == 1)
|
|
|
|
#if (USE_ROM_FLASH)
|
|
FMC_SPI_Flash_PowerDown();
|
|
#else // (USE_ROM_FLASH)
|
|
// xc_fmc_spi_flash_power_down();
|
|
#endif // (USE_ROM_FLASH)
|
|
xc_pwr_rom_off();
|
|
|
|
__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();
|
|
|
|
xc_pwr_rom_on();
|
|
#if (USE_ROM_FLASH)
|
|
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
|
|
xc_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);
|
|
}
|
|
__RAM_CODE void sleep_close_all()
|
|
{
|
|
xc_timer_stop(TIMER1_IDX);
|
|
xc_adc_disable();
|
|
// xc_pwm_stop((uint8_t reg_idx);
|
|
}
|
|
|
|
__RAM_CODE void sleep_open_all()
|
|
{
|
|
xc_timer_start(TIMER1_IDX);
|
|
xc_adc_enable();
|
|
// xc_pwm_start(uint8_t reg_idx);
|
|
}
|
|
|
|
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: {
|
|
|
|
duration_timer = (HS_TO_US(duration) - SLEEP_TIME_EARLY);
|
|
xc_timer_set_value(TIMER0_IDX, duration_timer);
|
|
xc_timer_start(TIMER0_IDX);
|
|
// Before you sleep, turn off the peripheral to make sure it doesn't generate interrupts,
|
|
// and then turn it on again after you sleep up.
|
|
// For example, timer interrupts
|
|
sleep_close_all();
|
|
|
|
xc_ble_sleep();
|
|
|
|
xc_timer_stop(TIMER0_IDX);
|
|
sleep_open_all();
|
|
// xc_rc32k_soft_calib_enable();
|
|
}
|
|
// 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();
|
|
|
|
#if (POWER_ON)
|
|
power_off_check();
|
|
#endif // (POWER_ON)
|
|
}
|
|
#endif // (SLEEP_ENABLE)
|
|
|
|
#if (POWER_ON)
|
|
|
|
void system_deepsleep_init()
|
|
{
|
|
uint32_t wake_it_src;
|
|
#if (USE_XIP == 1)
|
|
xc_fmc_spi_init_oprt();
|
|
#endif
|
|
xc_pwr_gpio_sleep_config();
|
|
|
|
wake_it_src = GPIO_IRQn_WAKE | RTC_IRQn_WAKE;
|
|
xc_pwr_wake_it_set(wake_it_src);
|
|
}
|
|
|
|
void system_deepsleep_cfg()
|
|
{
|
|
#if (USE_XIP != 1)
|
|
cprao_aon_puctrl1_set(0xf);
|
|
#endif
|
|
cprao_aon_sys_time_set((RST_READY_TIME << 12) | (OSC32_STABLE_TIME));
|
|
xc_pwr_pd_deepsleep_set();
|
|
xc_pwr_sleepsrc_mask_set(0x1e001e);
|
|
xc_pwr_osc_off();
|
|
}
|
|
|
|
void cpu_enter_deepsleep()
|
|
{
|
|
system_deepsleep_init();
|
|
// PWRKEY Initialization is required after deep sleep wakeup
|
|
xc_pwr_pwrkey_init();
|
|
xc_pwr_pwrkey_deepsleep_wake_config(TOUCH_KEY,
|
|
DEEP_SLEEP_GPIO_WAKE_HIGH_LEVEL);
|
|
// xc_pwr_pwrkey_deepsleep_wake_config(TOUCH_KEY,
|
|
// DEEP_SLEEP_GPIO_WAKE_LOW_LEVEL);
|
|
system_deepsleep_cfg();
|
|
xc_deep_sleep();
|
|
}
|
|
|
|
void power_on_check()
|
|
{
|
|
uint16_t power_key_scan = 0;
|
|
uint16_t resleep_count = 0;
|
|
uint16_t power_on_count = 0;
|
|
|
|
while (1) {
|
|
if (power_key_scan == POWER_KEY_SCAN_COUNT) {
|
|
power_key_scan = 0;
|
|
if (xc_gpio_read_pin(TOUCH_KEY) == 0) {
|
|
if (resleep_count >= GENERAL_RESLEEP_TIME_COUNT) {
|
|
cpu_enter_deepsleep();
|
|
}
|
|
resleep_count++;
|
|
power_on_count = 0;
|
|
} else {
|
|
if (power_on_count == POWER_ON_TIME) {
|
|
break;
|
|
}
|
|
power_on_count++;
|
|
resleep_count = 0;
|
|
}
|
|
}
|
|
power_key_scan++;
|
|
}
|
|
xc_pwr_pwrkey_init();
|
|
}
|
|
|
|
void power_off_check()
|
|
{
|
|
if (xc_gpio_read_pin(TOUCH_KEY) == 1) {
|
|
uint16_t power_key_scan = 0;
|
|
uint16_t resleep_count = 0;
|
|
uint16_t power_off_count = 0;
|
|
|
|
while (1) {
|
|
if (power_key_scan == POWER_KEY_SCAN_COUNT) {
|
|
power_key_scan = 0;
|
|
if (xc_gpio_read_pin(TOUCH_KEY) == 0) {
|
|
if (resleep_count >= GENERAL_RESLEEP_TIME_COUNT) {
|
|
break;
|
|
}
|
|
resleep_count++;
|
|
power_off_count = 0;
|
|
} else {
|
|
if (power_off_count == POWER_OFF_TIME) {
|
|
cpu_enter_deepsleep();
|
|
}
|
|
power_off_count++;
|
|
resleep_count = 0;
|
|
}
|
|
}
|
|
power_key_scan++;
|
|
}
|
|
xc_pwr_pwrkey_init();
|
|
}
|
|
}
|
|
#endif // (POWER_ON)
|