#include "include.h" #include "app_variable.h" #ifdef TJD_COMPASS_INCLUDE_MMC5603 #include "MMC5603.h" #endif/*TJD_COMPASS_INCLUDE_MMC5603*/ #include "watch.h" xcfg_cb_t xcfg_cb; sys_cb_t sys_cb AT(.buf.bsp.sys_cb); volatile int micl2gnd_flag; volatile u32 ticks_50ms; uint8_t cfg_spiflash_speed_up_en = SPIFLASH_SPEED_UP_EN; //SPI FLASH提速。部份FLASH不支持提速 extern u32 __max_flash_size, __bank_size; extern u32 __comm_start, __comm_end, __comm_size, __sram_size; extern u32 __bss_start, __bss_end, __bss_size; #if SECURITY_PAY_EN extern u32 __alipay_start, __alipay_end, __alipay_size; #endif void sd_detect(void); void tbox_uart_isr(void); #if USER_KEY_QDEC_EN void bsp_qdec_process(void); #endif static u8 heap_func[HEAP_FUNC_SIZE] AT(.heap.func); #if PWRKEY_2_HW_PWRON //软开机模拟硬开关,松开PWRKEY就关机。 AT(.com_text.detect) void pwrkey_2_hw_pwroff_detect(void) { static int off_cnt = 0; if (!PWRKEY_2_HW_PWRON) { return; } if (IS_PWRKEY_PRESS()) { off_cnt = 0; } else { if (off_cnt < 10) { off_cnt++; } else if (off_cnt == 10) { //pwrkey已松开,需要关机 off_cnt = 20; sys_cb.pwrdwn_hw_flag = 1; sys_cb.poweron_flag = 0; } } } #endif // PWRKEY_2_HW_PWRON extern u16 dnr_voice_maxpow(void); extern bool dac_sclk_is_enable(void); AT(.bcom_text.dac) uint16_t max_pow_up(void) { if(sys_cb.incall_flag & INCALL_FLAG_SCO) return 0x10; return 0x18; } AT(.bcom_text.dac) uint16_t max_pow_down(void) { if(sys_cb.incall_flag & INCALL_FLAG_SCO) return 0x02; return 0x10; } AT(.bcom_text.dac) void dac_dnr_ex_process(void) { static u8 voice_power_count = 0, silence_pow_cont = 0; static u8 loud_is_open = 0xff; u16 max_pow; if (!dac_sclk_is_enable()) { return; } max_pow = dnr_voice_maxpow(); if(max_pow > max_pow_up()){ voice_power_count++; silence_pow_cont = 0; if(voice_power_count >= 2){ voice_power_count = 2; if(loud_is_open != 0){ loud_is_open = 0; loudspeaker_unmute(); } } }else if(max_pow < max_pow_down()){ silence_pow_cont++; voice_power_count = 0; if(silence_pow_cont >= 10){ silence_pow_cont = 10; if(loud_is_open != 1){ loud_is_open = 1; loudspeaker_mute(); } } } } //timer tick interrupt(1ms) AT(.com_text.timer) void usr_tmr1ms_isr(void) { #if USER_KEY_QDEC_EN bsp_qdec_process(); #endif #if LED_DISP_EN port_2led_scan(); #endif // LED_DISP_EN /* 1ms tick stopwatch timer */ sys_cb.timer_tick++; sys_cb.stopwatch_tick++; bsp_saradc_tmr1ms_process(); plugin_tmr1ms_isr(); } //timer tick interrupt(5ms) AT(.com_text.timer) void usr_tmr5ms_isr(void) { tmr5ms_cnt++; //5ms timer process dac_fade_process(); bsp_key_scan(); #if PWRKEY_2_HW_PWRON pwrkey_2_hw_pwroff_detect(); #endif plugin_tmr5ms_isr(); //20ms timer process if ((tmr5ms_cnt % 4) == 0) { dac_dnr_ex_process(); #if DAC_DNR_EN dac_dnr_process(); #endif // DAC_DNR_EN } //50ms timer process if ((tmr5ms_cnt % 10) == 0) { co_timer_pro(2); ticks_50ms++; #if LED_DISP_EN led_scan(); #endif } //100ms timer process if ((tmr5ms_cnt % 20) == 0) { lowpwr_tout_ticks(); } //500ms timer process if ((tmr5ms_cnt % 100) == 0) { msg_enqueue(MSG_SYS_500MS); sys_cb.cm_times++; } //1s timer process if ((tmr5ms_cnt % 200) == 0) { msg_enqueue(MSG_SYS_1S); tmr5ms_cnt = 0; sys_cb.lpwr_warning_cnt++; if (sys_cb.lpwr_cnt > 0) { // printf("sys_cb.lpwr_cnt%d\n", sys_cb.lpwr_cnt); sys_cb.lpwr_cnt++; } } } AT(.com_text.bsp.sys) void bsp_loudspeaker_mute(void) { LOUDSPEAKER_MUTE(); sys_cb.loudspeaker_mute = 1; } AT(.com_text.bsp.sys) void bsp_loudspeaker_unmute(void) { sys_cb.loudspeaker_mute = 0; LOUDSPEAKER_UNMUTE(); } AT(.text.bsp.sys) void bsp_sys_mute(void) { if (!sys_cb.mute) { sys_cb.mute = 1; dac_fade_out(); bsp_loudspeaker_mute(); #if DAC_DNR_EN dac_dnr_set_sta(0); #endif } } AT(.text.bsp.sys) void bsp_sys_unmute(void) { if (sys_cb.mute) { sys_cb.mute = 0; bsp_loudspeaker_unmute(); dac_fade_in(); #if DAC_DNR_EN dac_dnr_set_sta(sys_cb.dnr_sta); #endif } } AT(.text.bsp.sys) void bsp_clr_mute_sta(void) { if (sys_cb.mute) { sys_cb.mute = 0; #if DAC_DNR_EN dac_dnr_set_sta(sys_cb.dnr_sta); #endif } } AT(.com_text.bsp.sys) bool bsp_get_mute_sta(void) { if (get_mp3_res_sta()) { return 0; } return sys_cb.mute; } ////PWRKEY 引脚通过开关80K上拉/10K下拉, 来实现输出高低电平, 注意高电平为1.8V //AT(.com_text.bsp.sys) //void powerkey_out_set(bool high) //里面调用到的函数都在公共区. //{ // if (high) { // RTCCON1 &= ~(BIT(1)| BIT(2) | BIT(3)) ; //bit1: 10K PD DISABLE //bit2,bit3 = 00, PU IS 80K // RTCCON1 |= BIT(4) ; //PU ENABLE, // } else { // RTCCON1 &= ~BIT(4) ; //PU DISABLE // RTCCON1 |= BIT(1) ; //10K PD ENABLE // if (!(RTCCON11 & BIT(4))){ //PD enable protect bit. // RTCCON11 |= BIT(4); // } // } //} AT(.text.bsp.sys.init) bool rtc_init(void) { u32 temp; sys_cb.rtc_first_pwron = 0; // printf("RTCCON0: %x, RTCCNT: %x\n", RTCCON0, RTCCNT); temp = RTCCON0; temp |= BIT(9) | BIT(8); //rtc clk sel x26m div temp &= ~BIT(6); //enable clk32k_rtc temp &= ~BIT(2); //disable osc_32k out RTCCON0 = temp; RTCCON2 = 16249; //26m / 16 / 100 - 1 if (temp & BIT(7)) { temp &= ~BIT(7); //clear first poweron flag RTCCON0 = temp; sys_cb.rtc_first_pwron = 1; rtc_clock_init(); // printf("rtc 1st pwrup\n"); return false; } return true; } //UART0打印信息输出GPIO选择,UART0默认G1(PA7) void uart0_mapping_sel(void) { //等待uart0发送完成 if(UART0CON & BIT(0)) { while (!(UART0CON & BIT(8))); } GPIOBPU &= ~(BIT(2) | BIT(3) | BIT(4)); FUNCMCON0 = (0xf << 12) | (0xf << 8); //clear uart0 mapping #if (UART0_PRINTF_SEL == PRINTF_PB3) GPIOBDE |= BIT(3); GPIOBPU |= BIT(3); GPIOBDIR |= BIT(3); GPIOBFEN |= BIT(3); FUNCMCON0 = URX0MAP_TX | UTX0MAP_PB3; //RX0 Map To TX0, TX0 Map to G1 #elif (UART0_PRINTF_SEL == PRINTF_PA1) GPIOBDE |= BIT(1); GPIOAPU |= BIT(1); GPIOADIR |= BIT(1); GPIOAFEN |= BIT(1); GPIOADRV |= BIT(1); FUNCMCON0 = URX0MAP_TX | UTX0MAP_PA1; //RX0 Map To TX0, TX0 Map to G2 #elif (UART0_PRINTF_SEL == PRINTF_PA3) GPIOBDE |= BIT(3); GPIOAPU |= BIT(3); GPIOADIR |= BIT(3); GPIOAFEN |= BIT(3); GPIOADRV |= BIT(3); FUNCMCON0 = URX0MAP_TX | UTX0MAP_PA3; //RX0 Map To TX0, TX0 Map to G3 #elif (UART0_PRINTF_SEL == PRINTF_PE3) GPIOEDE |= BIT(3); GPIOEPU |= BIT(3); GPIOEDIR |= BIT(3); GPIOEFEN |= BIT(3); FUNCMCON0 = URX0MAP_TX | UTX0MAP_PE3; //RX0 Map To TX0, TX0 Map to G4 #elif (UART0_PRINTF_SEL == PRINTF_PE5) GPIOEDE |= BIT(5); GPIOEPU |= BIT(5); GPIOEDIR |= BIT(5); GPIOEFEN |= BIT(5); FUNCMCON0 = URX0MAP_TX | UTX0MAP_PE5; //RX0 Map To TX0, TX0 Map to G5 #elif (UART0_PRINTF_SEL == PRINTF_PE7) GPIOEDE |= BIT(7); GPIOEPU |= BIT(7); GPIOEDIR |= BIT(7); GPIOEFEN |= BIT(7); FUNCMCON0 = URX0MAP_TX | UTX0MAP_PE7; //RX0 Map To TX0, TX0 Map to G6 #elif (UART0_PRINTF_SEL == PRINTF_PF5) GPIOFDE |= BIT(5); GPIOFPU |= BIT(5); GPIOFDIR |= BIT(5); GPIOFFEN |= BIT(5); FUNCMCON0 = URX0MAP_TX | UTX0MAP_PF5; //RX0 Map To TX0, TX0 Map to G7 #elif (UART0_PRINTF_SEL == PRINTF_VUSB) FUNCMCON0 = URX0MAP_TX | UTX0MAP_VUSB; //RX0 Map To TX0, TX0 Map to G8 #endif } AT(.rodata.vol) const u8 maxvol_tbl[2] = {16, 32}; //开user timer前初始化的内容 AT(.text.bsp.sys.init) static void bsp_var_init(void) { memset(&sys_cb, 0, sizeof(sys_cb)); func_heap_init(heap_func, HEAP_FUNC_SIZE); sys_cb.loudspeaker_mute = 1; sys_cb.ms_ticks = tick_get(); xcfg_cb.vol_max = maxvol_tbl[xcfg_cb.vol_max]; sys_cb.hfp2sys_mul = (xcfg_cb.vol_max + 2) / 16; if (SYS_INIT_VOLUME > xcfg_cb.vol_max) { SYS_INIT_VOLUME = xcfg_cb.vol_max; } if (WARNING_VOLUME > xcfg_cb.vol_max) { WARNING_VOLUME = xcfg_cb.vol_max; } #if (WORK_MODE == MODE_BQB_RF) xcfg_cb.sys_sleep_time = 0; #endif sys_cb.flag_pwroff = false; SysVariable.sleep_time= -1L; SysVariable.pwroff_time = -1L; SysVariable.guioff_delay = SysVariable.sleep_time; // if (xcfg_cb.sys_sleep_time != 0) { // SysVariable.sleep_time= (u32)xcfg_cb.sys_sleep_time * 10; //100ms为单位 // } // if (xcfg_cb.sys_off_time != 0) { // SysVariable.pwroff_time = (u32)xcfg_cb.sys_off_time * 10; //100ms为单位 // } SysVariable.sleep_delay = -1L; // SysVariable.pwroff_delay = -1L; sys_cb.sleep_en = 0; sys_cb.lpwr_warning_times = LPWR_WARING_TIMES; if ((!xcfg_cb.ft_osc_cap_en) || (xcfg_cb.osci_cap == 0 && xcfg_cb.osco_cap == 0)) { //没有过产测时,使用自定义OSC电容 xcfg_cb.osci_cap = xcfg_cb.uosci_cap; xcfg_cb.osco_cap = xcfg_cb.uosco_cap; } port_var_init(); key_var_init(); plugin_var_init(); msg_queue_init(); saradc_var_init(); sdadc_var_init(); dac_cb_init((DAC_CH_SEL & 0x0f) | ((u8)DAC_LDOH_SEL << 4) | (0x100 * DAC_FAST_SETUP_EN) | (0x200 * DACVDD_BYPASS_EN)); } //获取系统控制位 u8 bsp_sys_get_ctlbit(uint n) { if (n >= SYS_CTL_TOTAL_BITS) { halt(HALT_BSP_SYS_CTLBITS); } int by = n / 8; int bi = n % 8; return ((sys_cb.ctl_bits[by] >> bi) & 1); } //设置系统控制位 void bsp_sys_set_ctlbit(uint n, u8 v) { if (n >= SYS_CTL_TOTAL_BITS) { halt(HALT_BSP_SYS_CTLBITS); } int by = n / 8; int bi = n % 8; sys_cb.ctl_bits[by] = (sys_cb.ctl_bits[by] & ~BIT(bi)) | (v << bi); } //反转系统控制位 void bsp_sys_reverse_ctlbit(uint n) { if (n >= SYS_CTL_TOTAL_BITS) { halt(HALT_BSP_SYS_CTLBITS); } int by = n / 8; int bi = n % 8; sys_cb.ctl_bits[by] ^= BIT(bi); } AT(.text.bsp.sys.init) static void bsp_io_init(void) { GPIOADE = BIT(7); //UART GPIOBDE = 0; GPIOEDE = 0; GPIOFDE = 0; GPIOGDE = 0x3F; //MCP FLASH uart0_mapping_sel(); //调试UART IO选择或关闭 LOUDSPEAKER_MUTE_INIT(); AMPLIFIER_SEL_INIT(); } void bsp_get_xosc_xcfg(u8 *osci_cap, u8 *osco_cap, u8 *both_cap) { *osci_cap = xcfg_cb.osci_cap; *osco_cap = xcfg_cb.osco_cap; *both_cap = xcfg_cb.osc_both_cap; } AT(.text.bsp.sys.init) void bsp_update_init(void) { /// config memset(&xcfg_cb, 0, sizeof(xcfg_cb)); if (!xcfg_init(&xcfg_cb, sizeof(xcfg_cb))) { //获取配置参数 // printf("xcfg init error\n"); } // printf("TBOX OTA Update Finish!\n"); } /* AT(.com_rodata.isr) const char str_t3[] = "T3 "; AT(.com_text.isr) FIQ void timer3_isr(void) { if (TMR3CON & BIT(16)) { TMR3CPND = BIT(16); //Clear Pending } printk(str_t3); } void timer3_init(void) { TMR3CON = BIT(7); //Timer overflow interrupt enable TMR3CNT = 0; TMR3PR = 1000000 / 2 - 1; //500ms, select xosc26_div 1M clk TMR3CON |= BIT(2) | BIT(0); //Timer works in Counter Mode sys_irq_init(IRQ_TMR3_VECTOR, 1, timer3_isr); } */ void rtc_printf(void) { tm_t rtc_tm = time_to_tm(RTCCNT); //更新时间结构体 // printf("time: %d.%02d.%02d %02d:%02d:%02d\n", (rtc_tm.year+0), rtc_tm.mon, rtc_tm.day,rtc_tm.hour, rtc_tm.min, rtc_tm.sec); } void rtc_pwd_calibration(void) { param_init(sys_cb.rtc_first_pwron); u32 rtccon9 = RTCCON9; if((rtccon9 & 1) == 1){ //1000s起来一次校准rc rtc RTCCON9 = 0xfff; //Clr pending if (cm_read8(PARAM_RTC_CAL_VALID) == 1) { sniff_rc_init(); rtc_calibration_read(PARAM_RTC_CAL_ADDR); rtc_sleep_process(); rtc_calibration_write(PARAM_RTC_CAL_ADDR); cm_write8(PARAM_RTC_CAL_VALID, 1); cm_sync(); rtc_printf(); } sfunc_pwrdown(1); return; } //RTCCON9 = 0xfff; //Clr pending } void print_comm_info(void) { if (RTCCON9 & 1) { return; } printf("-------------------flash info----------------------\n"); printf("flash total = %d KB, used = %d KB, remain = %d KB\n", (u32)&__max_flash_size/1024, (u32)&__bank_size/1024, ((u32)&__max_flash_size - (u32)&__bank_size)/1024); printf("--------------------------------------------------\n"); printf("-------------------sram info----------------------\n"); printf("sram total = 0x%X, used = 0x%X, remain = 0x%X\n", (u32)&__sram_size, (u32)&__comm_size+(u32)&__bss_size, (u32)&__sram_size - (u32)&__comm_size-(u32)&__bss_size); printf("comm: 0x%X ~ 0x%X size: 0x%X\n", (u32)&__comm_start, (u32)&__comm_end, (u32)&__comm_size); printf("bss : 0x%X ~ 0x%X size: 0x%X\n", (u32)&__bss_start, (u32)&__bss_end, (u32)&__bss_size); #if SECURITY_PAY_EN printf("pay : 0x%X ~ 0x%X size: 0x%X\n", (u32)&__alipay_start, (u32)&__alipay_end, (u32)&__alipay_size); #endif printf("--------------------------------------------------\n"); } /** * @author: Ronaldo(linzequan) * * @explain: 该函数放置于(xcfg_init)之后,用于烧录管理配置工具检索 * 将一些重要易修改参数值赋值于xcfg_cb成员变量, * 保证OTA后在不擦除原厂CM区的情况下对xcfg_cb进行及时修改。 * * 如须增加其余参数在(watch_set_make.py)脚本增加对应KEY值 * 编译后会自动获取最新数据并生成对应参数宏 */ AT(.text.bsp.sys.init) static void xcfg_user_data_init(void) { /* 充电截止电流 */ xcfg_cb.charge_stop_curr = USER_CHARGE_STOP_CURR; /* 恒流充电电流 */ xcfg_cb.charge_constant_curr = USER_CHARGE_CONSTANT_CURR; /* 涓流充电电流 */ xcfg_cb.charge_trickle_curr = USER_CHARGE_TRICKLE_CURR; /* BT 蓝牙名 */ memset(xcfg_cb.bt_name, 0, sizeof(xcfg_cb.bt_name)); memcpy(xcfg_cb.bt_name, USER_BT_NAME, sizeof(USER_BT_NAME)); /* LE 蓝牙名 */ memset(xcfg_cb.le_name, 0, sizeof(xcfg_cb.le_name)); memcpy(xcfg_cb.le_name, USER_LE_NAME, sizeof(USER_LE_NAME)); } AT(.text.bsp.sys.init) void bsp_sys_init(void) { /// config memset(&xcfg_cb, 0, sizeof(xcfg_cb)); if (!xcfg_init(&xcfg_cb, sizeof(xcfg_cb))) { //获取配置参数 // printf("xcfg init error\n"); } xcfg_user_data_init(); print_comm_info(); // io init bsp_io_init(); // var init bsp_var_init(); #if USE_APP_TYPE app_platform_init(); #endif rtc_pwd_calibration(); // power init pmu_init(BUCK_MODE_EN*xcfg_cb.buck_mode_en); // clock init adpll_init(DAC_OUT_SPR); sys_clk_set(SYS_CLK_SEL); // peripheral init rtc_init(); param_init(sys_cb.rtc_first_pwron); //晶振配置 xosc_init(); xosc_driver_init(); plugin_init(); if (POWKEY_10S_RESET) { RTCCON10 = BIT(10); //clear 10s pending RTCCON12 &= ~0x0f; //10S Reset Enable } else { RTCCON12 = (RTCCON12 & ~0xf) | 0x0a; //10S Reset Disable } #if CHARGE_EN if (xcfg_cb.charge_en) { bsp_charge_init(); } #endif // CHARGE_EN key_init(); /// enable user timer for display & dac sys_set_tmr_enable(1, 1); bt_init(); #if BT_BACKSTAGE_EN func_bt_init(); #endif dac_init(); // printf("SysVariable.vol = %d\n",SysVariable.vol); bsp_change_volume(SysVariable.vol); #if WARNING_POWER_ON mp3_res_play(RES_BUF_POWERON_MP3, RES_LEN_POWERON_MP3); #endif // WARNING_POWER_ON #if BT_BACKSTAGE_MUSIC_EN bt_audio_enable(); #if DAC_DNR_EN dac_dnr_set_sta(1); sys_cb.dnr_sta = 1; #endif #endif #if EQ_DBG_IN_UART || EQ_DBG_IN_SPP eq_dbg_init(); #endif // EQ_DBG_IN_UART mic_bias_trim_w4_done(); bsp_i2c_init(); /* GUI相关初始化 */ gui_init(); /* 需放在IIC初始化之后,未使用外设时注意关闭 */ bsp_sensor_pe2_pwr_pg_on(); /* 步数传感器初始化 */ bsp_sensor_step_init(); #if SENSOR_STEP_SEL != SENSOR_STEP_NULL bsp_sensor_step_set_pedo(SysVariable.curSportRecord.pedo); // 设置计步值 #endif /* 心率传感器初始化 */ bsp_sensor_hr_init(); bsp_sensor_hr_stop(); #ifdef TJD_COMPASS_INCLUDE_MMC5603 MMC5603_chip_init(); #endif /*TJD_COMPASS_INCLUDE_MMC5603*/ bsp_vbat_percent_init(); //放最后电压稍微稳定点 SysVariable.bt_state_set = false; //bsp_internal_sensor_init(); #ifdef TJD_SETTING_AUDIO_SWITCH if(SysVariable.bt_a2dp_profile_state) bt_a2dp_profile_en(); else bt_a2dp_profile_dis(); if(SysVariable.bt_hfp_profile_state) bt_hfp_profile_en(); else bt_hfp_profile_dis(); #endif } AT(.com_rodata) const char func_msg_enqueue[] = "my_msg_enqueue[%d,%d,%d,%d]\n"; AT(.com_text.ctp) void my_msg_enqueue(u16 msg) { // printf(func_msg_enqueue, SysVariable.password_cnt, SysVariable.password_need, SysVariable.password_allow_push, func_cb.sta); if (!sys_cb.password_show && SysVariable.password_cnt == 4 && SysVariable.password_need && func_cb.sta != FUN_POWER_ON_LOGO && func_cb.sta != FUNC_PASSWORD_SUB_DISP) { sys_cb.password_show = true; return; } msg_enqueue(msg); } // #define XO26MCON SFR_RW (SFR3_BASE + 0x29*4) void xosc_driver_init(void) { // printf("=====xosc_driver_init\n"); XO26MCON = (XO26MCON & ~(31<<0)) | ((20)<<0); }