From f0a8f13cd66b31b9a954496d05d831b4da50edc5 Mon Sep 17 00:00:00 2001 From: helloyifa Date: Fri, 16 May 2025 17:31:05 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=8F=90=E4=BA=A4=20=201.?= =?UTF-8?q?=E9=AA=8C=E8=AF=81=E4=BA=86RTC=20=E5=94=A4=E9=86=92=20=202.?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E8=93=9D=E7=89=99=E7=9B=B4=E8=BF=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- fw-AC63_BT_SDK/apps/spp_and_le/app_main.c | 618 +++-- .../apps/spp_and_le/app_temperature.c | 1361 +++++----- .../board/bd19/board_ac6323a_demo.c | 1162 ++++----- .../board/bd19/board_ac6323a_demo_cfg.h | 688 ++--- .../examples/trans_data/ble_trans.c | 2235 +++++++++-------- .../apps/spp_and_le/include/app_temperature.h | 116 +- .../spp_and_le/modules/power/app_charge.c | 237 +- .../apps/spp_and_le/modules/rtc_alarm.c | 866 +++---- 8 files changed, 3722 insertions(+), 3561 deletions(-) diff --git a/fw-AC63_BT_SDK/apps/spp_and_le/app_main.c b/fw-AC63_BT_SDK/apps/spp_and_le/app_main.c index d472ed3..e80e030 100644 --- a/fw-AC63_BT_SDK/apps/spp_and_le/app_main.c +++ b/fw-AC63_BT_SDK/apps/spp_and_le/app_main.c @@ -1,311 +1,307 @@ -/********************************************************************************************* - * Filename : app_main.c - - * Description : - - * Copyright:(c)JIELI 2011-2019 @ , All Rights Reserved. -*********************************************************************************************/ -#include "system/includes.h" -#include "app_config.h" -#include "app_action.h" -#include "app_main.h" -#include "update.h" -#include "update_loader_download.h" -#include "app_charge.h" -#include "app_power_manage.h" -#include "asm/charge.h" -#include "app_temperature.h" - -#if TCFG_KWS_VOICE_RECOGNITION_ENABLE -#include "jl_kws/jl_kws_api.h" -#endif /* #if TCFG_KWS_VOICE_RECOGNITION_ENABLE */ - -#define LOG_TAG_CONST APP -#define LOG_TAG "[APP]" -#define LOG_ERROR_ENABLE -#define LOG_DEBUG_ENABLE -#define LOG_INFO_ENABLE -/* #define LOG_DUMP_ENABLE */ -#define LOG_CLI_ENABLE -#include "debug.h" - -/*任务列表 */ -const struct task_info task_info_table[] = { -#if CONFIG_APP_FINDMY - {"app_core", 1, 0, 640 * 2, 128 }, -#else - {"app_core", 1, 0, 640, 128 }, -#endif - - {"sys_event", 7, 0, 256, 0 }, - {"btctrler", 4, 0, 512, 256 }, - {"btencry", 1, 0, 512, 128 }, - {"btstack", 3, 0, 768, 256 }, - {"systimer", 7, 0, 128, 0 }, - {"update", 1, 0, 512, 0 }, - {"dw_update", 2, 0, 256, 128 }, -#if (RCSP_BTMATE_EN) - {"rcsp_task", 2, 0, 640, 0}, -#endif -#if(USER_UART_UPDATE_ENABLE) - {"uart_update", 1, 0, 256, 128 }, -#endif -#if (XM_MMA_EN) - {"xm_mma", 2, 0, 640, 256 }, -#endif - {"usb_msd", 1, 0, 512, 128 }, -#if TCFG_AUDIO_ENABLE - {"audio_dec", 3, 0, 768, 128 }, - {"audio_enc", 4, 0, 512, 128 }, -#endif/*TCFG_AUDIO_ENABLE*/ -#if TCFG_KWS_VOICE_RECOGNITION_ENABLE - {"kws", 2, 0, 256, 64 }, -#endif /* #if TCFG_KWS_VOICE_RECOGNITION_ENABLE */ -#if (TUYA_DEMO_EN) - {"user_deal", 2, 0, 512, 512 },//定义线程 tuya任务调度 -#endif -#if (CONFIG_APP_HILINK) - {"hilink_task", 2, 0, 1024, 0},//定义线程 hilink任务调度 -#endif - {0, 0}, -}; - -APP_VAR app_var; - -void app_var_init(void) -{ - app_var.play_poweron_tone = 1; - - app_var.auto_off_time = TCFG_AUTO_SHUT_DOWN_TIME; - app_var.warning_tone_v = 340; - app_var.poweroff_tone_v = 330; -} - -__attribute__((weak)) -u8 get_charge_online_flag(void) -{ - return 0; -} - -void clr_wdt(void); -void check_power_on_key(void) -{ -#if TCFG_POWER_ON_NEED_KEY - - u32 delay_10ms_cnt = 0; - while (1) { - clr_wdt(); - os_time_dly(1); - - extern u8 get_power_on_status(void); - if (get_power_on_status()) { - log_info("+"); - delay_10ms_cnt++; - if (delay_10ms_cnt > 70) { - /* extern void set_key_poweron_flag(u8 flag); */ - /* set_key_poweron_flag(1); */ - return; - } - } else { - log_info("-"); - delay_10ms_cnt = 0; - log_info("enter softpoweroff\n"); - power_set_soft_poweroff(); - } - } -#endif -} - - -void enter_sleep(){ - printf(">>>>>>>>>>>>>>>>>enter_sleep...\n"); - sys_s_hi_timer_del(enter_sleep); - extern void user_alarm_test(void); - - extern void alarm_rtc_start(void); - alarm_rtc_start(); - user_alarm_test(); - //power_set_soft_poweroff(); -} - -void alarm_isr_user_cbfun(u8 index) -{ - printf("**** alarm %d : hello world ****\n", index); -} - -void user_main(){ - printf(">>>>>>>>>>>>>>>>>user_main...\n"); - temperature_init(); - - - //sys_s_hi_timer_add(NULL,enter_sleep,5000); - - // user_alarm_test(); - // extern void alarm_rtc_start(void); - // alarm_rtc_start(); - // rtc_alarm_set_timer(30); - - //extern void rtc_alarm_set_timer(u32 seconds); - //rtc_alarm_set_timer(30); - //power_set_soft_poweroff(); - //user_alarm_test(); -} -void app_main() -{ - struct intent it; - - if (!UPDATE_SUPPORT_DEV_IS_NULL()) { - int update = 0; - update = update_result_deal(); - } - - printf(">>>>>>>>>>>>>>>>>app_main...\n"); - printf(">>> v220,2022-11-23 >>>\n"); - - if (get_charge_online_flag()) { -#if(TCFG_SYS_LVD_EN == 1) - vbat_check_init(); -#endif - } else { - check_power_on_voltage(); - } - temperature_ble_init(); -#if TCFG_POWER_ON_NEED_KEY - check_power_on_key(); -#endif - -#if TCFG_AUDIO_ENABLE - extern int audio_dec_init(); - extern int audio_enc_init(); - audio_dec_init(); - audio_enc_init(); -#endif/*TCFG_AUDIO_ENABLE*/ - -#if TCFG_KWS_VOICE_RECOGNITION_ENABLE - jl_kws_main_user_demo(); -#endif /* #if TCFG_KWS_VOICE_RECOGNITION_ENABLE */ - - init_intent(&it); - -#if CONFIG_APP_SPP_LE - it.name = "spp_le"; - it.action = ACTION_SPPLE_MAIN; - -#elif CONFIG_APP_AT_COM || CONFIG_APP_AT_CHAR_COM - it.name = "at_com"; - it.action = ACTION_AT_COM; - -#elif CONFIG_APP_DONGLE - it.name = "dongle"; - it.action = ACTION_DONGLE_MAIN; - -#elif CONFIG_APP_MULTI - it.name = "multi_conn"; - it.action = ACTION_MULTI_MAIN; - -#elif CONFIG_APP_NONCONN_24G - it.name = "nonconn_24g"; - it.action = ACTION_NOCONN_24G_MAIN; - -#elif CONFIG_APP_HILINK - it.name = "hilink"; - it.action = ACTION_HILINK_MAIN; - -#elif CONFIG_APP_LL_SYNC - it.name = "ll_sync"; - it.action = ACTION_LL_SYNC; - -#elif CONFIG_APP_TUYA - it.name = "tuya"; - it.action = ACTION_TUYA; - -#elif CONFIG_APP_CENTRAL - it.name = "central"; - it.action = ACTION_CENTRAL_MAIN; - -#elif CONFIG_APP_DONGLE - it.name = "dongle"; - it.action = ACTION_DONGLE_MAIN; - -#elif CONFIG_APP_BEACON - it.name = "beacon"; - it.action = ACTION_BEACON_MAIN; - -#elif CONFIG_APP_IDLE - it.name = "idle"; - it.action = ACTION_IDLE_MAIN; - -#elif CONFIG_APP_CONN_24G - it.name = "conn_24g"; - it.action = ACTION_CONN_24G_MAIN; - -#elif CONFIG_APP_FINDMY - it.name = "findmy"; - it.action = ACTION_FINDMY; - -#elif CONFIG_APP_FTMS - it.name = "ftms"; - it.action = ACTION_FTMS; - -#else - while (1) { - printf("no app!!!"); - } -#endif - - - log_info("run app>>> %s", it.name); - log_info("%s,%s", __DATE__, __TIME__); - - start_app(&it); - user_main(); -#if TCFG_CHARGE_ENABLE - set_charge_event_flag(1); -#endif -} - -/* - * app模式切换 - */ -void app_switch(const char *name, int action) -{ - struct intent it; - struct application *app; - - log_info("app_exit\n"); - - init_intent(&it); - app = get_current_app(); - if (app) { - /* - * 退出当前app, 会执行state_machine()函数中APP_STA_STOP 和 APP_STA_DESTORY - */ - it.name = app->name; - it.action = ACTION_BACK; - start_app(&it); - } - - /* - * 切换到app (name)并执行action分支 - */ - it.name = name; - it.action = action; - start_app(&it); -} - -int eSystemConfirmStopStatus(void) -{ - /* 系统进入在未来时间里,无任务超时唤醒,可根据用户选择系统停止,或者系统定时唤醒(100ms) */ - //1:Endless Sleep - //0:100 ms wakeup - /* log_info("100ms wakeup"); */ - return 1; -} - -__attribute__((used)) int *__errno() -{ - static int err; - return &err; -} - - +/********************************************************************************************* + * Filename : app_main.c + + * Description : + + * Copyright:(c)JIELI 2011-2019 @ , All Rights Reserved. +*********************************************************************************************/ +#include "system/includes.h" +#include "app_config.h" +#include "app_action.h" +#include "app_main.h" +#include "update.h" +#include "update_loader_download.h" +#include "app_charge.h" +#include "app_power_manage.h" +#include "asm/charge.h" +#include "app_temperature.h" + +#if TCFG_KWS_VOICE_RECOGNITION_ENABLE +#include "jl_kws/jl_kws_api.h" +#endif /* #if TCFG_KWS_VOICE_RECOGNITION_ENABLE */ + +#define LOG_TAG_CONST APP +#define LOG_TAG "[APP]" +#define LOG_ERROR_ENABLE +#define LOG_DEBUG_ENABLE +#define LOG_INFO_ENABLE +/* #define LOG_DUMP_ENABLE */ +#define LOG_CLI_ENABLE +#include "debug.h" + +/*任务列表 */ +const struct task_info task_info_table[] = { +#if CONFIG_APP_FINDMY + {"app_core", 1, 0, 640 * 2, 128 }, +#else + {"app_core", 1, 0, 640, 128 }, +#endif + + {"sys_event", 7, 0, 256, 0 }, + {"btctrler", 4, 0, 512, 256 }, + {"btencry", 1, 0, 512, 128 }, + {"btstack", 3, 0, 768, 256 }, + {"systimer", 7, 0, 128, 0 }, + {"update", 1, 0, 512, 0 }, + {"dw_update", 2, 0, 256, 128 }, +#if (RCSP_BTMATE_EN) + {"rcsp_task", 2, 0, 640, 0}, +#endif +#if(USER_UART_UPDATE_ENABLE) + {"uart_update", 1, 0, 256, 128 }, +#endif +#if (XM_MMA_EN) + {"xm_mma", 2, 0, 640, 256 }, +#endif + {"usb_msd", 1, 0, 512, 128 }, +#if TCFG_AUDIO_ENABLE + {"audio_dec", 3, 0, 768, 128 }, + {"audio_enc", 4, 0, 512, 128 }, +#endif/*TCFG_AUDIO_ENABLE*/ +#if TCFG_KWS_VOICE_RECOGNITION_ENABLE + {"kws", 2, 0, 256, 64 }, +#endif /* #if TCFG_KWS_VOICE_RECOGNITION_ENABLE */ +#if (TUYA_DEMO_EN) + {"user_deal", 2, 0, 512, 512 },//定义线程 tuya任务调度 +#endif +#if (CONFIG_APP_HILINK) + {"hilink_task", 2, 0, 1024, 0},//定义线程 hilink任务调度 +#endif + {0, 0}, +}; + +APP_VAR app_var; + +void app_var_init(void) +{ + app_var.play_poweron_tone = 1; + + app_var.auto_off_time = TCFG_AUTO_SHUT_DOWN_TIME; + app_var.warning_tone_v = 340; + app_var.poweroff_tone_v = 330; +} + +__attribute__((weak)) +u8 get_charge_online_flag(void) +{ + return 0; +} + +void clr_wdt(void); +void check_power_on_key(void) +{ +#if TCFG_POWER_ON_NEED_KEY + + u32 delay_10ms_cnt = 0; + while (1) { + clr_wdt(); + os_time_dly(1); + + extern u8 get_power_on_status(void); + if (get_power_on_status()) { + log_info("+"); + delay_10ms_cnt++; + if (delay_10ms_cnt > 70) { + /* extern void set_key_poweron_flag(u8 flag); */ + /* set_key_poweron_flag(1); */ + return; + } + } else { + log_info("-"); + delay_10ms_cnt = 0; + log_info("enter softpoweroff\n"); + power_set_soft_poweroff(); + } + } +#endif +} + + +void enter_sleep(){ + printf(">>>>>>>>>>>>>>>>>enter_sleep...\n"); + sys_s_hi_timer_del(enter_sleep); + extern void user_alarm_test(void); + + extern void alarm_rtc_start(void); + alarm_rtc_start(); + user_alarm_test(); + //power_set_soft_poweroff(); +} + + +void user_main(){ + printf(">>>>>>>>>>>>>>>>>user_main...\n"); + temperature_init(); + + + //sys_s_hi_timer_add(NULL,enter_sleep,5000); + + // user_alarm_test(); + // extern void alarm_rtc_start(void); + // alarm_rtc_start(); + // rtc_alarm_set_timer(30); + + //extern void rtc_alarm_set_timer(u32 seconds); + //rtc_alarm_set_timer(30); + //power_set_soft_poweroff(); + //user_alarm_test(); +} +void app_main() +{ + struct intent it; + + if (!UPDATE_SUPPORT_DEV_IS_NULL()) { + int update = 0; + update = update_result_deal(); + } + + printf(">>>>>>>>>>>>>>>>>app_main...\n"); + printf(">>> v220,2022-11-23 >>>\n"); + + if (get_charge_online_flag()) { +#if(TCFG_SYS_LVD_EN == 1) + vbat_check_init(); +#endif + } else { + check_power_on_voltage(); + } + temperature_ble_init(); +#if TCFG_POWER_ON_NEED_KEY + check_power_on_key(); +#endif + +#if TCFG_AUDIO_ENABLE + extern int audio_dec_init(); + extern int audio_enc_init(); + audio_dec_init(); + audio_enc_init(); +#endif/*TCFG_AUDIO_ENABLE*/ + +#if TCFG_KWS_VOICE_RECOGNITION_ENABLE + jl_kws_main_user_demo(); +#endif /* #if TCFG_KWS_VOICE_RECOGNITION_ENABLE */ + + init_intent(&it); + +#if CONFIG_APP_SPP_LE + it.name = "spp_le"; + it.action = ACTION_SPPLE_MAIN; + +#elif CONFIG_APP_AT_COM || CONFIG_APP_AT_CHAR_COM + it.name = "at_com"; + it.action = ACTION_AT_COM; + +#elif CONFIG_APP_DONGLE + it.name = "dongle"; + it.action = ACTION_DONGLE_MAIN; + +#elif CONFIG_APP_MULTI + it.name = "multi_conn"; + it.action = ACTION_MULTI_MAIN; + +#elif CONFIG_APP_NONCONN_24G + it.name = "nonconn_24g"; + it.action = ACTION_NOCONN_24G_MAIN; + +#elif CONFIG_APP_HILINK + it.name = "hilink"; + it.action = ACTION_HILINK_MAIN; + +#elif CONFIG_APP_LL_SYNC + it.name = "ll_sync"; + it.action = ACTION_LL_SYNC; + +#elif CONFIG_APP_TUYA + it.name = "tuya"; + it.action = ACTION_TUYA; + +#elif CONFIG_APP_CENTRAL + it.name = "central"; + it.action = ACTION_CENTRAL_MAIN; + +#elif CONFIG_APP_DONGLE + it.name = "dongle"; + it.action = ACTION_DONGLE_MAIN; + +#elif CONFIG_APP_BEACON + it.name = "beacon"; + it.action = ACTION_BEACON_MAIN; + +#elif CONFIG_APP_IDLE + it.name = "idle"; + it.action = ACTION_IDLE_MAIN; + +#elif CONFIG_APP_CONN_24G + it.name = "conn_24g"; + it.action = ACTION_CONN_24G_MAIN; + +#elif CONFIG_APP_FINDMY + it.name = "findmy"; + it.action = ACTION_FINDMY; + +#elif CONFIG_APP_FTMS + it.name = "ftms"; + it.action = ACTION_FTMS; + +#else + while (1) { + printf("no app!!!"); + } +#endif + + + log_info("run app>>> %s", it.name); + log_info("%s,%s", __DATE__, __TIME__); + + start_app(&it); + user_main(); +#if TCFG_CHARGE_ENABLE + set_charge_event_flag(1); +#endif +} + +/* + * app模式切换 + */ +void app_switch(const char *name, int action) +{ + struct intent it; + struct application *app; + + log_info("app_exit\n"); + + init_intent(&it); + app = get_current_app(); + if (app) { + /* + * 退出当前app, 会执行state_machine()函数中APP_STA_STOP 和 APP_STA_DESTORY + */ + it.name = app->name; + it.action = ACTION_BACK; + start_app(&it); + } + + /* + * 切换到app (name)并执行action分支 + */ + it.name = name; + it.action = action; + start_app(&it); +} + +int eSystemConfirmStopStatus(void) +{ + /* 系统进入在未来时间里,无任务超时唤醒,可根据用户选择系统停止,或者系统定时唤醒(100ms) */ + //1:Endless Sleep + //0:100 ms wakeup + /* log_info("100ms wakeup"); */ + return 1; +} + +__attribute__((used)) int *__errno() +{ + static int err; + return &err; +} + + diff --git a/fw-AC63_BT_SDK/apps/spp_and_le/app_temperature.c b/fw-AC63_BT_SDK/apps/spp_and_le/app_temperature.c index 7b4e0e6..e023899 100644 --- a/fw-AC63_BT_SDK/apps/spp_and_le/app_temperature.c +++ b/fw-AC63_BT_SDK/apps/spp_and_le/app_temperature.c @@ -1,607 +1,754 @@ -#include "system/includes.h" -#include "app_config.h" -#include "app_action.h" -#include "app_main.h" -#include "update.h" -#include "update_loader_download.h" -#include "app_charge.h" -#include "app_power_manage.h" -#include "asm/charge.h" -#include "app_temperature.h" -#include "typedef.h" - -#include "le_common.h" -#include "cpu.h" -#include "timer.h" -#include "os/os_api.h" -#include "system/includes.h" - -#include "gatt_common/le_gatt_common.h" -#include "examples/trans_data/ble_trans_profile.h" -//#include "ble_trans_profile.h" -static int led_state = 0; -static u16 temer_temperature_detect = 0; - -//struct app_dev_info_t dev_info; -//struct app_dev_config_t dev_config; -app_dev_config_t dev_config; - -static int charge_state = 0; -void temperature_blink_led() -{ - if (led_state) - { - gpio_direction_output(BLE_TEMPERATURE_WORK_LED, 0); - led_state = 0; - } - else - { - led_state = 1; - gpio_set_hd0(BLE_TEMPERATURE_WORK_LED, 1); - gpio_direction_output(BLE_TEMPERATURE_WORK_LED, 1); - } -} - -void ble_send_data(u8 *sdata,u8 len) -{ - //先查明当前连接的conn_handle - u16 connection_handle = ble_comm_dev_get_handle(0, GATT_ROLE_SERVER); - //printf("connection_handle: %04x\n", connection_handle); - if(connection_handle == 0)//无连接 - { - return; - } - //检查预备发送的数据包长度是否能填入,并且获取 notify or indicate 通知使能值 - if (ble_comm_att_check_send(connection_handle, len) && - ble_gatt_server_characteristic_ccc_get(connection_handle, ATT_CHARACTERISTIC_ae02_01_CLIENT_CONFIGURATION_HANDLE)) - { - //使用notify方式发送 - ble_comm_att_send_data(connection_handle, ATT_CHARACTERISTIC_ae02_01_VALUE_HANDLE, sdata, len, ATT_OP_NOTIFY); - } -} - -void ble_receive_callback(u8* data,u16 len){ - printf("ble_receive_callback (rx:%d): %s\n",len, data); - if(strstr(data,"AT+GETTEMP=?") != NULL){ - printf("111\n"); - int detect_temp = 365; - u8 str_get_temp[24] = {0}; - sprintf(str_get_temp,"AT+GETTEMP=%d",detect_temp); - ble_send_data(&str_get_temp,strlen(str_get_temp)); - }else{ - printf("222\n"); - } -} - - -//有概率会被中断打断,导致延时变大 -AT_VOLATILE_RAM_CODE -void delay_us_by_timer0(u32 usec) -{ - usec -= 2; //usec > 5,减掉此函数执行本身的耗时,48M->2us,24M->5us - JL_TIMER0->CON = BIT(14); - JL_TIMER0->CNT = 0; - JL_TIMER0->PRD = clk_get("lsb") / 2 / 1000000L * usec; - JL_TIMER0->CON = BIT(0) | BIT(6); //lsb clk 2分频 - while ((JL_TIMER0->CON & BIT(15)) == 0); - JL_TIMER0->CON = BIT(14); -} - -//关中断,临界区延时 -AT_VOLATILE_RAM_CODE -void delay_us_by_timer0_irq(u32 usec) -{ - usec -= 2; //usec > 5,减掉此函数执行本身的耗时,48M->2us,24M->5us - local_irq_disable(); - JL_TIMER0->CON = BIT(14); - JL_TIMER0->CNT = 0; - JL_TIMER0->PRD = clk_get("lsb") / 2 / 1000000L * usec; - JL_TIMER0->CON = BIT(0) | BIT(6); //lsb clk 2分频 - while ((JL_TIMER0->CON & BIT(15)) == 0); - JL_TIMER0->CON = BIT(14); - local_irq_enable(); -} - -//ms级延时,一般要求不需要精准,不用加关中断 -AT_VOLATILE_RAM_CODE -void delay_ms_by_timer0(u32 msec) -{ - JL_TIMER0->CON = BIT(14); - JL_TIMER0->CNT = 0; - JL_TIMER0->PRD = clk_get("lsb") / 64 / 1000L * msec; - JL_TIMER0->CON = BIT(0) | BIT(5) | BIT(4); //lsb clk 64分频 - while ((JL_TIMER0->CON & BIT(15)) == 0); - JL_TIMER0->CON = BIT(14); -} - -static void udelay(u32 usec) -{ - /* if (set_to_close_timer0_delay) { */ - /* JL_MCPWM->MCPWM_CON0 &= ~BIT(8 + 3); */ - /* JL_MCPWM->TMR3_CNT = 0; */ - /* JL_MCPWM->TMR3_PR = clk_get("lsb") / 1000000 * usec; */ - /* JL_MCPWM->TMR3_CON = BIT(10) | BIT(0); */ - /* JL_MCPWM->MCPWM_CON0 |= BIT(8 + 3); */ - /* while (!(JL_MCPWM->TMR3_CON & BIT(12))); */ - /* JL_MCPWM->TMR3_CON = BIT(10); */ - /* JL_MCPWM->MCPWM_CON0 &= ~BIT(8 + 3); */ - /* } else { */ - JL_TIMER0->CON = BIT(14); - JL_TIMER0->CNT = 0; - JL_TIMER0->PRD = 16 * 1000000L / 1000000L * usec; //1us - JL_TIMER0->CON = BIT(0); //sys clk - while ((JL_TIMER0->CON & BIT(15)) == 0); - JL_TIMER0->CON = BIT(14); - /* } */ -} - -#ifdef BLE_TEMPERATURE_DEVICE_NST1002 - -//extern void handshake_timer_delay_us(u8 us); -//extern void handshake_timer_delay_ms(u8 ms); - -#define ERR_NC -100 -#define ERR_DONE -101 -#define ERR_DAT -102 -#define ERR_CRC -103 -//-----------------by usr --- ------------------ -#define pin_write(x, y) gpio_direction_output(x, y);//rt_pin_write(x, y) -//#define pin_mode(x, y) rt_pin_mode(x, y) -#define pin_read(x) gpio_read(x) -#define DQ_PIN IO_PORTB_04 //GET_PIN(A, 1) -#define delay_ms(x) delay_ms_by_timer0(x);//rt_thread_mdelay(x) -#define delay_us(x) udelay(x);//rt_hw_us_delay(x) - -//-------------------------------------- -static uint8_t reversal(uint8_t data) -{ - uint8_t _data = data; - uint8_t i, retValue = 1; - for (i = 0; i < 8; i++) - { - unsigned char temp = _data & 0x01; - if (temp) - retValue |= 0x01; - else - retValue &= ~0x01; - if (i == 7) - break; - retValue <<= 1; - _data >>= 1; - } - return retValue; -} - - // crc8_maxim input and output reversal - //x8+x5+x4+1 0x131 - static uint8_t crc8_maxim(uint8_t *pdat, uint8_t len) - { - uint8_t ret; - uint8_t uCRC = 0x00; //CRC - for (uint8_t num = 0; num < len; num++) - { ret = reversal(*pdat++); - uCRC = (ret) ^ uCRC; // - for (uint8_t x = 0; x < 8; x++) - { - if (uCRC & 0x80) - { - uCRC = uCRC << 1; // - uCRC = uCRC ^ 0x31; // - } - else // - { - uCRC = uCRC << 1; // - } - } - } - ret = reversal(uCRC); - return ret; - } - - int nst1002_read_cal(uint16_t *pcal) - { - int retry = 0; - uint8_t crc; - uint8_t i, j; - uint8_t bit0 = 1; - uint8_t data[3] = {0, 0, 0}; - uint8_t swap[2]; - uint8_t read[4]; - //--------------power up----------------------- - //pin_mode(DQ_PIN, PIN_MODE_OUTPUT_OD); - //pin_write(DQ_PIN, PIN_HIGH); - gpio_set_direction(DQ_PIN,0); - gpio_direction_output(DQ_PIN, 1); - - delay_ms(15); - //--------------send start convert ----------------------------- - gpio_direction_output(DQ_PIN, 0);//pin_write(DQ_PIN, PIN_LOW); // DQ low - //printf("send start convert out 0\r\n"); - delay_us_by_timer0(300); - gpio_direction_output(DQ_PIN, 1);//pin_write(DQ_PIN, PIN_HIGH); - //printf("send start convert out 1\r\n"); - delay_us_by_timer0(20); - //-----------------check DQ pin status should be high--------------------------------------- - - gpio_set_direction(DQ_PIN,1); - gpio_set_die(DQ_PIN,1); - //gpio_set_direction(DQ_PIN,1);//pin_mode(DQ_PIN, PIN_MODE_INPUT); - //gpio_set_pull_up(DQ_PIN, 1); - //printf("check DQ pin status should be high cur dq:%d:\r\n" ,pin_read(DQ_PIN)); - //delay_ms(30); - if (pin_read(DQ_PIN) == 0) - { - printf("check DQ pin == 0 should be high!!\r\n"); - *pcal = (uint16_t)(ERR_NC * 128); - - return -1; - } - //printf("check DQ pin status pin_read(DQ_PIN) == 1 \r\n"); - //delay_ms(20); - //--------------wait for done pulse--------------- - printf("wait for done pulse ... \r\n"); - do - { - bit0 = pin_read(DQ_PIN); - delay_us_by_timer0(2); - retry++; - if (retry > 30000) // time out 40ms - { - *pcal = (uint16_t)(ERR_DONE * 128); - printf("wait for done pulse fail \r\n"); - return -2; - } - } while (bit0); - printf("wait for done pulse succ \r\n"); - delay_us_by_timer0(10); - //--------------read 24bit data--------------- - gpio_set_direction(DQ_PIN,0); - gpio_direction_output(DQ_PIN, 1);//pin_write(DQ_PIN, PIN_HIGH); - //pin_mode(DQ_PIN, PIN_MODE_OUTPUT_OD); - //delay_us(200); - for (i = 0; i < 24; i++) - { - gpio_direction_output(DQ_PIN, 0);//pin_write(DQ_PIN, PIN_LOW); // Falling edge - delay_us(1);// Adjust according to the mcu clock cycle,It's not necessary - - gpio_set_direction(DQ_PIN,1);//pin_mode(DQ_PIN, PIN_MODE_INPUT); - gpio_set_die(DQ_PIN,1); - //gpio_set_pull_up(DQ_PIN, 1); - // If the output bit is 0, the DQ will remain low for about 14us - for (j = 0; j < 4; j++) - // It's not necessary to read it 4 timers , adjust according to the mcuclock cycle - { - read[j] = pin_read(DQ_PIN); - } - - if (read[0] == read[1]) // It's not necessary - bit0 = read[1]; - else - { - *pcal = (uint16_t)(ERR_DAT * 128); - return -3; - } - data[i / 8] <<= 1; - data[i / 8] |= bit0; - - gpio_set_direction(DQ_PIN,0); - gpio_direction_output(DQ_PIN, 1);//pin_write(DQ_PIN, PIN_HIGH); // DQ low - - //pin_mode(DQ_PIN, PIN_MODE_OUTPUT_OD); - //delay_us(60); - delay_us_by_timer0(60); - } - //------------------- NST1002 Big Endian,but mcu Little Endian - swap[0] = data[1]; - swap[1] = data[0]; - *pcal = *((uint16_t *)swap); // output data need swap - crc = crc8_maxim(data, 2); - if (crc == data[2]) - return 0; - else - { - printf("data %02x %02x %02x CRC %02x\r\n", data[0], data[1], data[2], crc); - *pcal = ERR_CRC * 128; - return -4; - } - } - char err_code[4][20] = {"NOT Connected", "No DONE signal", "DAT Recv Err", "CRC Err"}; - void nst1002_read_temperatura(void) - { - if(charge_state){ - printf("charging...\r\n"); - return; - } - int err, ei; - float dtmp; - int16_t cal; - - // NTC VDD - gpio_set_direction(IO_PORTB_05,0); - gpio_direction_output(IO_PORTB_05, 1); - - err = nst1002_read_cal((uint16_t *)&cal); - if (err < 0) - { - if (ei < 4) - ei = -1 - err; - printf("NST1002 err code :%d err %s\r\n", err,err_code[ei]); - return; - } - - //printf("cal %d\r\n", cal); - dtmp = cal / 128.0f; - int temp_value = dtmp*100; - //printf("Temp %3.7f\r\n", dtmp); - - printf("Temp: %d\r\n\r\n", temp_value); - - - //FF - - //先查明当前连接的conn_handle - u16 connection_handle = ble_comm_dev_get_handle(0, GATT_ROLE_SERVER); - if(connection_handle != 0)// - { - printf("ble connected !! connection_handle: %04x\n", connection_handle); - return ; - }else{ - //printf("connection_handle: %04x\n", connection_handle); - } - //BBOOEEb 2字节体温 2字节物温 2字节环温 1字节电量 - u16 body = (u16)temp_value; - u16 obj = (u16)temp_value; - u16 ntc = (u16)0; - u8 battery = 99; - u8 ff_temp_data[7] = {0}; - //body - ff_temp_data[0] = (body >> 8) & 0xFF; - ff_temp_data[1] = (body) & 0xFF; - //obj - ff_temp_data[2] = (obj >> 8) & 0xFF; - ff_temp_data[3] = (obj) & 0xFF; - //env - ff_temp_data[4] = (ntc >> 8) & 0xFF; - ff_temp_data[5] = (ntc) & 0xFF; - //batt - battery = get_cur_battery_level() *10; - ff_temp_data[6] = battery & 0xFF; - trans_client_adv_data_set_ff(ff_temp_data,sizeof(ff_temp_data)); - gpio_direction_output(IO_PORTB_05, 0); - } - - /** - * 更新BLE广播信息 - * //BBOOEEbs 2字节体温 2字节物温 2字节环温 1字节电量 1字节状态 - * 状态:00 正常模式 01 进入充电 - */ - void temperature_update_adv_ff(u16 temp_body,u16 temp_obj,u16 temp_env,u8 batt,u8 state){ - u16 body = (u16)temp_body; - u16 obj = (u16)temp_obj; - u16 ntc = (u16)temp_env; - u8 battery = 99; - u8 ff_temp_data[8] = {0}; - //body - ff_temp_data[0] = (body >> 8) & 0xFF; - ff_temp_data[1] = (body) & 0xFF; - //obj - ff_temp_data[2] = (obj >> 8) & 0xFF; - ff_temp_data[3] = (obj) & 0xFF; - //env - ff_temp_data[4] = (ntc >> 8) & 0xFF; - ff_temp_data[5] = (ntc) & 0xFF; - //batt - battery = get_cur_battery_level() *10; - ff_temp_data[6] = battery & 0xFF; - ff_temp_data[7] = state & 0xFF; - trans_client_adv_data_set_ff(ff_temp_data,sizeof(ff_temp_data)); - } - -void temperature_detect(void) -{ - nst1002_read_temperatura(); - -} -#endif - -u16 charge_led_hander = 0; -void temperature_charge_lowpower(u8 on){ - if(charge_led_hander){ - sys_timer_del(charge_led_hander); - } - if(on){ - charge_led_hander = sys_timer_add(NULL, temperature_blink_led, 1000); - }else{ - sys_timer_del(charge_led_hander); - } -} - -void temperature_work_led(u8 on){ - - if(on){ - gpio_set_hd0(BLE_TEMPERATURE_WORK_LED, 1); - gpio_direction_output(BLE_TEMPERATURE_WORK_LED, 1); - }else{ - gpio_direction_output(BLE_TEMPERATURE_WORK_LED, 0); - } -} - -void temperature_poweron_led_timeout(){ - temperature_work_led(0); -} - -void temperature_set_soft_poweroff(void) -{ - printf("temperature_set_soft_poweroff\n"); - //VCM_DET_EN(0);//关闭VCM复位 - //gpio_shortpress_reset_config(0);//1--enable 0--disable - - //P33_CON_SET(P3_PINR_CON, 0, 1, 0);//关闭长按复位 - //P33_CON_SET(P3_PINR_CON, 0, 1, 1);//打开长按复位 - gpio_longpress_pin0_reset_config(IO_PORTA_09, 0, 0); - - //必须先主动断开蓝牙链路,否则要等链路超时断开 -#if TCFG_USER_BLE_ENABLE - btstack_ble_exit(0); - //延时300ms,确保BT退出链路断开 - sys_timeout_add(NULL, power_set_soft_poweroff, 300); -#else - power_set_soft_poweroff(); -#endif -} - -void temperature_charge_state(int state){ - switch (state) - { - //接入充电 - case BLE_TEMPERATURE_CHARGE_STATE_CHARGING : - charge_state = 1; - printf("BLE_TEMPERATURE_CHARGE_STATE_CHARGING\n"); - //关闭低电提示LED - temperature_charge_lowpower(0); - sys_timer_del(temer_temperature_detect); - //体温计指标灯闪烁3次后转灭 - for(int i = 0; i< 3 ; i++){ - temperature_work_led(1); - delay_ms_by_timer0(150); - temperature_work_led(0); - delay_ms_by_timer0(150); - } - //接入充电关闭蓝牙广播 - ble_op_adv_enable(0); - ble_module_enable(0); - //spple_power_event_to_user(POWER_EVENT_POWER_SOFTOFF); - //printf("!!!!!!!!!!!!!! CHARGING POWER OFF!!!!!!!!!!!!!!!!\n"); - //printf("BLE_TEMPERATURE_CHARGE_STATE_CHARGING 2\n"); - - break; - //充电完成 - case BLE_TEMPERATURE_CHARGE_STATE_FULL : - //printf("BLE_TEMPERATURE_CHARGE_STATE_FULL\n"); - temperature_set_soft_poweroff(); - break; - //拔出充电 - case BLE_TEMPERATURE_CHARGE_STATE_IDLE : - charge_state = 0; - printf("BLE_TEMPERATURE_CHARGE_STATE_IDLE\n"); - temer_temperature_detect = sys_timer_add(NULL, temperature_detect, dev_config.detect_interval); - //temperature_charge_led(0); - temperature_work_led(1); - sys_s_hi_timerout_add(NULL,temperature_poweron_led_timeout,2000); - - //拔出充电打开蓝牙广播 - ble_module_enable(1); - ble_op_adv_enable(1); - - break; - //低电 - case BLE_TEMPERATURE_CHARGE_STATE_LOWPOWER: - temperature_charge_lowpower(1); - break; - default: - break; - } -} - -void temperature_ble_init(){ - printf(">>>>>>>>>>>>>>>>> temperature_ble_init ...\n"); - - // GET DEVICE MAC - u8 bt_mac_addr[6] = {0}; - bt_get_vm_mac_addr(&bt_mac_addr); - // le_controller_set_mac((void *)bt_mac_addr); - printf("device mac: %02x %02x %02x %02x %02x %02x \n", bt_mac_addr[0], bt_mac_addr[1], bt_mac_addr[2], bt_mac_addr[3], bt_mac_addr[4], bt_mac_addr[5]); - //设置MAC地址 - le_controller_set_mac((void *)bt_mac_addr); - //设置名称 - char ble_name[12] ={0}; - sprintf(ble_name,"iT12_%02X%02X",bt_mac_addr[1],bt_mac_addr[0]); - ble_comm_set_config_name(&ble_name, 0); - - -} -/** - * 初始化测温相关的参数 - */ -void temperature_config_init(){ - //int syscfg_read(u16 item_id, void *buf, u16 len); - //int syscfg_write(u16 item_id, void *buf, u16 len); - - int ret = syscfg_read(BLE_TEMPERATURE_VM_DEVICE_CONFIG, &dev_config, sizeof(app_dev_config_t)); - if (ret != sizeof(app_dev_config_t)) { - printf("temperature_config_init err:%d", ret); - - dev_config.detect_interval = 500; - dev_config.temperature_offset = 0; - syscfg_write(BLE_TEMPERATURE_VM_DEVICE_CONFIG, &dev_config, sizeof(app_dev_config_t)); - } - //test - dev_config.detect_interval = 0; - dev_config.temperature_offset = 0; - ret = syscfg_read(BLE_TEMPERATURE_VM_DEVICE_CONFIG, &dev_config, sizeof(app_dev_config_t)); - if (ret != sizeof(app_dev_config_t)) { - printf("temperature_config_init err:%d", ret); - }else{ - printf("detect_interval :%d", dev_config.detect_interval); - printf("temperature_offset :%d", dev_config.temperature_offset); - } - dev_config.detect_interval = 2000; - -} - -void temperature_init(void) -{ - printf(">>>>>>>>>>>>>>>>> temperature_init ...\n"); - delay_us(60); - printf(">>>>>>>>>>>>>>>>> temperature_OTA ...\n"); - - extern u16 get_vbat_trim(); - extern u16 get_vbg_trim(); - printf("vbat_trim:%d...vbg_trim:%d", get_vbat_trim(), get_vbg_trim()); - // 添加以上代码,看打印值,如果为15跟63,那就要用烧录器先烧录一遍。 - - temperature_config_init(); - - //从收纳仓取出时自动开机(指示灯亮2S后灭) - temperature_work_led(1); - sys_s_hi_timerout_add(NULL,temperature_poweron_led_timeout,2000); - - //sys_s_hi_timer_add(NULL, temperature_blink_led, 200); - //sys_s_hi_timer_add(NULL, temperature_detect, 2000); - //sys_timer_add 方式添加定时任务 任务里边可以使用udelay delay_ms 等延时 sys_s_hi_timer_add 则延时无效 - temer_temperature_detect = sys_timer_add(NULL, temperature_detect, dev_config.detect_interval); - - - //HALL PIN 输入 - gpio_set_direction(IO_PORTA_00,1); - gpio_set_die(IO_PORTA_00,1); - - // NTC VDD - //gpio_set_direction(IO_PORTB_05,0); - //gpio_direction_output(IO_PORTB_05, 1); - - /* - //test delay - gpio_set_direction(DQ_PIN,0); - gpio_direction_output(DQ_PIN, 1); - delay_us_by_timer0(20); - gpio_direction_output(DQ_PIN, 0); - delay_us_by_timer0(20); - gpio_direction_output(DQ_PIN, 1); - delay_us_by_timer0(20); - gpio_direction_output(DQ_PIN, 0); - delay_ms(200); - gpio_direction_output(DQ_PIN, 1); - delay_ms(200); - gpio_direction_output(DQ_PIN, 0); - delay_ms(200); - gpio_direction_output(DQ_PIN, 1); - */ -} - -void temperature_deinit(void) -{ - printf(">>>>>>>>>>>>>>>>> temperature_deinit ...\n"); - // NTC VDD - gpio_direction_output(IO_PORTB_05, 0); -} +#include "system/includes.h" +#include "app_config.h" +#include "app_action.h" +#include "app_main.h" +#include "update.h" +#include "update_loader_download.h" +#include "app_charge.h" +#include "app_power_manage.h" +#include "asm/charge.h" +#include "app_temperature.h" +#include "typedef.h" + +#include "le_common.h" +#include "cpu.h" +#include "timer.h" +#include "os/os_api.h" +#include "system/includes.h" + +#include "gatt_common/le_gatt_common.h" +#include "examples/trans_data/ble_trans_profile.h" +//#include "ble_trans_profile.h" +static int led_state = 0; +static u16 temer_temperature_detect = 0; +static u16 temer_sleep = 0; + +app_dev_info_t dev_info; +//struct app_dev_config_t dev_config; +app_dev_config_t dev_config; + +static int charge_state = 0; +void temperature_blink_led() +{ + if (led_state) + { + gpio_direction_output(BLE_TEMPERATURE_WORK_LED, 0); + led_state = 0; + } + else + { + led_state = 1; + gpio_set_hd0(BLE_TEMPERATURE_WORK_LED, 1); + gpio_direction_output(BLE_TEMPERATURE_WORK_LED, 1); + } +} + +void ble_send_data(u8 *sdata,u8 len) +{ + //先查明当前连接的conn_handle + u16 connection_handle = ble_comm_dev_get_handle(0, GATT_ROLE_SERVER); + //printf("connection_handle: %04x\n", connection_handle); + if(connection_handle == 0)//无连接 + { + return; + } + //检查预备发送的数据包长度是否能填入,并且获取 notify or indicate 通知使能值 + if (ble_comm_att_check_send(connection_handle, len) && + ble_gatt_server_characteristic_ccc_get(connection_handle, ATT_CHARACTERISTIC_ae02_01_CLIENT_CONFIGURATION_HANDLE)) + { + printf("SEND: %s\n",sdata); + //使用notify方式发送 + ble_comm_att_send_data(connection_handle, ATT_CHARACTERISTIC_ae02_01_VALUE_HANDLE, sdata, len, ATT_OP_NOTIFY); + } +} + +void ble_receive_callback(u8* data,u16 len){ + printf("ble_receive_callback (rx:%d): %s\n",len, data); + //TEMP + if(strstr(data,"AT^TEMP:") != NULL){ + u8 str_get_temp[64] = {0}; + memset(str_get_temp,0,sizeof(str_get_temp)); + sprintf(str_get_temp,"AT^TEMP:%d,%d,%d", dev_info.temperature_sensor/10, dev_info.temperature_sensor/10, dev_info.temperature_sensor/10); + ble_send_data(&str_get_temp,strlen(str_get_temp)); + } + else if(strstr(data,"AT+TEMP=") != NULL){ + u8 str_get_temp[64] = {0}; + memset(str_get_temp,0,sizeof(str_get_temp)); + sprintf(str_get_temp,"AT+TEMP=%d,%d,%d", dev_info.temperature_sensor/10, dev_info.temperature_sensor/10, dev_info.temperature_sensor/10); + ble_send_data(&str_get_temp,strlen(str_get_temp)); + } + //BATT 真实电压值 + else if(strstr(data,"AT^BATT=") != NULL){ + u8 str_get_batt[64] = {0}; + memset(str_get_batt,0,sizeof(str_get_batt)); + sprintf(str_get_batt,"AT^BATT=%d", dev_info.batt_val); + ble_send_data(&str_get_batt,strlen(str_get_batt)); + } + else if(strstr(data,"AT+BATT=") != NULL){ + u8 str_get_batt[64] = {0}; + memset(str_get_batt,0,sizeof(str_get_batt)); + sprintf(str_get_batt,"AT+BATT=%d", dev_info.batt_val); + ble_send_data(&str_get_batt,strlen(str_get_batt)); + } + //BATT 转换后的电量百分百 + else if(strstr(data,"AT^BATP=") != NULL){ + u8 str_get_batt[64] = {0}; + memset(str_get_batt,0,sizeof(str_get_batt)); + sprintf(str_get_batt,"AT^BATP=%d", dev_info.batt_percent); + ble_send_data(&str_get_batt,strlen(str_get_batt)); + } + else if(strstr(data,"AT+BATP=") != NULL){ + u8 str_get_batt[64] = {0}; + memset(str_get_batt,0,sizeof(str_get_batt)); + sprintf(str_get_batt,"AT+BATP=%d", dev_info.batt_percent); + ble_send_data(&str_get_batt,strlen(str_get_batt)); + } + //VERSION 软件版本 + else if(strstr(data,"AT^VER=") != NULL){ + u8 str_get_batt[64] = {0}; + memset(str_get_batt,0,sizeof(str_get_batt)); + sprintf(str_get_batt,"AT^VER=%s", BLE_TEMPERATURE_DEVICE_SOFT_VER); + ble_send_data(&str_get_batt,strlen(str_get_batt)); + } + else if(strstr(data,"AT+VER=") != NULL){ + u8 str_get_batt[64] = {0}; + memset(str_get_batt,0,sizeof(str_get_batt)); + sprintf(str_get_batt,"AT+VER=%s", BLE_TEMPERATURE_DEVICE_SOFT_VER); + ble_send_data(&str_get_batt,strlen(str_get_batt)); + } + else if(strstr(data,"AT+ADJ37=") != NULL){ + u8 str_adj[64] = {0}; + memset(str_adj,0,sizeof(str_adj)); + sprintf(str_adj,"AT+ADJ37=OK"); + ble_send_data(&str_adj,strlen(str_adj)); + } + else{ + printf("unknow cmd\n"); + } +} +/** + * + *当有蓝牙连接1 蓝牙断开 +*/ +void ble_on_connect_change(u8 is_connect){ + printf("ble_on_connect_change :(state:%d) \n",is_connect); + if(is_connect){ + temperature_work_led(1); + }else{ + temperature_work_led(0); + } +} + + +//有概率会被中断打断,导致延时变大 +AT_VOLATILE_RAM_CODE +void delay_us_by_timer0(u32 usec) +{ + usec -= 2; //usec > 5,减掉此函数执行本身的耗时,48M->2us,24M->5us + JL_TIMER0->CON = BIT(14); + JL_TIMER0->CNT = 0; + JL_TIMER0->PRD = clk_get("lsb") / 2 / 1000000L * usec; + JL_TIMER0->CON = BIT(0) | BIT(6); //lsb clk 2分频 + while ((JL_TIMER0->CON & BIT(15)) == 0); + JL_TIMER0->CON = BIT(14); +} + +//关中断,临界区延时 +AT_VOLATILE_RAM_CODE +void delay_us_by_timer0_irq(u32 usec) +{ + usec -= 2; //usec > 5,减掉此函数执行本身的耗时,48M->2us,24M->5us + local_irq_disable(); + JL_TIMER0->CON = BIT(14); + JL_TIMER0->CNT = 0; + JL_TIMER0->PRD = clk_get("lsb") / 2 / 1000000L * usec; + JL_TIMER0->CON = BIT(0) | BIT(6); //lsb clk 2分频 + while ((JL_TIMER0->CON & BIT(15)) == 0); + JL_TIMER0->CON = BIT(14); + local_irq_enable(); +} + +//ms级延时,一般要求不需要精准,不用加关中断 +AT_VOLATILE_RAM_CODE +void delay_ms_by_timer0(u32 msec) +{ + JL_TIMER0->CON = BIT(14); + JL_TIMER0->CNT = 0; + JL_TIMER0->PRD = clk_get("lsb") / 64 / 1000L * msec; + JL_TIMER0->CON = BIT(0) | BIT(5) | BIT(4); //lsb clk 64分频 + while ((JL_TIMER0->CON & BIT(15)) == 0); + JL_TIMER0->CON = BIT(14); +} + +static void udelay(u32 usec) +{ + /* if (set_to_close_timer0_delay) { */ + /* JL_MCPWM->MCPWM_CON0 &= ~BIT(8 + 3); */ + /* JL_MCPWM->TMR3_CNT = 0; */ + /* JL_MCPWM->TMR3_PR = clk_get("lsb") / 1000000 * usec; */ + /* JL_MCPWM->TMR3_CON = BIT(10) | BIT(0); */ + /* JL_MCPWM->MCPWM_CON0 |= BIT(8 + 3); */ + /* while (!(JL_MCPWM->TMR3_CON & BIT(12))); */ + /* JL_MCPWM->TMR3_CON = BIT(10); */ + /* JL_MCPWM->MCPWM_CON0 &= ~BIT(8 + 3); */ + /* } else { */ + JL_TIMER0->CON = BIT(14); + JL_TIMER0->CNT = 0; + JL_TIMER0->PRD = 16 * 1000000L / 1000000L * usec; //1us + JL_TIMER0->CON = BIT(0); //sys clk + while ((JL_TIMER0->CON & BIT(15)) == 0); + JL_TIMER0->CON = BIT(14); + /* } */ +} + +#ifdef BLE_TEMPERATURE_DEVICE_NST1002 + +//extern void handshake_timer_delay_us(u8 us); +//extern void handshake_timer_delay_ms(u8 ms); + +#define ERR_NC -100 +#define ERR_DONE -101 +#define ERR_DAT -102 +#define ERR_CRC -103 +//-----------------by usr --- ------------------ +#define pin_write(x, y) gpio_direction_output(x, y);//rt_pin_write(x, y) +//#define pin_mode(x, y) rt_pin_mode(x, y) +#define pin_read(x) gpio_read(x) +#define DQ_PIN IO_PORTB_04 //GET_PIN(A, 1) +#define delay_ms(x) delay_ms_by_timer0(x);//rt_thread_mdelay(x) +#define delay_us(x) udelay(x);//rt_hw_us_delay(x) + +//-------------------------------------- +static uint8_t reversal(uint8_t data) +{ + uint8_t _data = data; + uint8_t i, retValue = 1; + for (i = 0; i < 8; i++) + { + unsigned char temp = _data & 0x01; + if (temp) + retValue |= 0x01; + else + retValue &= ~0x01; + if (i == 7) + break; + retValue <<= 1; + _data >>= 1; + } + return retValue; +} + + // crc8_maxim input and output reversal + //x8+x5+x4+1 0x131 + static uint8_t crc8_maxim(uint8_t *pdat, uint8_t len) + { + uint8_t ret; + uint8_t uCRC = 0x00; //CRC + for (uint8_t num = 0; num < len; num++) + { ret = reversal(*pdat++); + uCRC = (ret) ^ uCRC; // + for (uint8_t x = 0; x < 8; x++) + { + if (uCRC & 0x80) + { + uCRC = uCRC << 1; // + uCRC = uCRC ^ 0x31; // + } + else // + { + uCRC = uCRC << 1; // + } + } + } + ret = reversal(uCRC); + return ret; + } + + int nst1002_read_cal(uint16_t *pcal) + { + int retry = 0; + uint8_t crc; + uint8_t i, j; + uint8_t bit0 = 1; + uint8_t data[3] = {0, 0, 0}; + uint8_t swap[2]; + uint8_t read[4]; + //--------------power up----------------------- + //pin_mode(DQ_PIN, PIN_MODE_OUTPUT_OD); + //pin_write(DQ_PIN, PIN_HIGH); + gpio_set_direction(DQ_PIN,0); + gpio_direction_output(DQ_PIN, 1); + + delay_ms(15); + //--------------send start convert ----------------------------- + gpio_direction_output(DQ_PIN, 0);//pin_write(DQ_PIN, PIN_LOW); // DQ low + //printf("send start convert out 0\r\n"); + delay_us_by_timer0(300); + gpio_direction_output(DQ_PIN, 1);//pin_write(DQ_PIN, PIN_HIGH); + //printf("send start convert out 1\r\n"); + delay_us_by_timer0(20); + //-----------------check DQ pin status should be high--------------------------------------- + + gpio_set_direction(DQ_PIN,1); + gpio_set_die(DQ_PIN,1); + //gpio_set_direction(DQ_PIN,1);//pin_mode(DQ_PIN, PIN_MODE_INPUT); + //gpio_set_pull_up(DQ_PIN, 1); + //printf("check DQ pin status should be high cur dq:%d:\r\n" ,pin_read(DQ_PIN)); + //delay_ms(30); + if (pin_read(DQ_PIN) == 0) + { + printf("check DQ pin == 0 should be high!!\r\n"); + *pcal = (uint16_t)(ERR_NC * 128); + + return -1; + } + //printf("check DQ pin status pin_read(DQ_PIN) == 1 \r\n"); + //delay_ms(20); + //--------------wait for done pulse--------------- + printf("wait for done pulse ... \r\n"); + do + { + bit0 = pin_read(DQ_PIN); + delay_us_by_timer0(2); + retry++; + if (retry > 30000) // time out 40ms + { + *pcal = (uint16_t)(ERR_DONE * 128); + printf("wait for done pulse fail \r\n"); + return -2; + } + } while (bit0); + printf("wait for done pulse succ \r\n"); + delay_us_by_timer0(10); + //--------------read 24bit data--------------- + gpio_set_direction(DQ_PIN,0); + gpio_direction_output(DQ_PIN, 1);//pin_write(DQ_PIN, PIN_HIGH); + //pin_mode(DQ_PIN, PIN_MODE_OUTPUT_OD); + //delay_us(200); + for (i = 0; i < 24; i++) + { + gpio_direction_output(DQ_PIN, 0);//pin_write(DQ_PIN, PIN_LOW); // Falling edge + delay_us(1);// Adjust according to the mcu clock cycle,It's not necessary + + gpio_set_direction(DQ_PIN,1);//pin_mode(DQ_PIN, PIN_MODE_INPUT); + gpio_set_die(DQ_PIN,1); + //gpio_set_pull_up(DQ_PIN, 1); + // If the output bit is 0, the DQ will remain low for about 14us + for (j = 0; j < 4; j++) + // It's not necessary to read it 4 timers , adjust according to the mcuclock cycle + { + read[j] = pin_read(DQ_PIN); + } + + if (read[0] == read[1]) // It's not necessary + bit0 = read[1]; + else + { + *pcal = (uint16_t)(ERR_DAT * 128); + return -3; + } + data[i / 8] <<= 1; + data[i / 8] |= bit0; + + gpio_set_direction(DQ_PIN,0); + gpio_direction_output(DQ_PIN, 1);//pin_write(DQ_PIN, PIN_HIGH); // DQ low + + //pin_mode(DQ_PIN, PIN_MODE_OUTPUT_OD); + //delay_us(60); + delay_us_by_timer0(60); + } + //------------------- NST1002 Big Endian,but mcu Little Endian + swap[0] = data[1]; + swap[1] = data[0]; + *pcal = *((uint16_t *)swap); // output data need swap + crc = crc8_maxim(data, 2); + if (crc == data[2]) + return 0; + else + { + printf("data %02x %02x %02x CRC %02x\r\n", data[0], data[1], data[2], crc); + *pcal = ERR_CRC * 128; + return -4; + } + } + char err_code[4][20] = {"NOT Connected", "No DONE signal", "DAT Recv Err", "CRC Err"}; + void nst1002_read_temperatura(void) + { + if(charge_state){ + printf("charging...\r\n"); + return; + } + int err, ei; + float dtmp; + int16_t cal; + + // NTC VDD + gpio_set_direction(IO_PORTB_05,0); + gpio_direction_output(IO_PORTB_05, 1); + + err = nst1002_read_cal((uint16_t *)&cal); + if (err < 0) + { + if (ei < 4) + ei = -1 - err; + printf("NST1002 err code :%d err %s\r\n", err,err_code[ei]); + return; + } + + //printf("cal %d\r\n", cal); + dtmp = cal / 128.0f; + int temp_value = dtmp*100; + //printf("Temp %3.7f\r\n", dtmp); + + printf("Temp: %d\r\n\r\n", temp_value); + + + //FF + //BBOOEEb 2字节体温 2字节物温 2字节环温 1字节电量 + u16 body = (u16)temp_value; + u16 obj = (u16)temp_value; + u16 ntc = (u16)0; + u8 battery = 99; + //batt + battery = get_cur_battery_level() *10; + + dev_info.temperature_sensor = body; + dev_info.temperature_ntc = body; + dev_info.batt_percent = battery; + dev_info.batt_val = get_vbat_value(); + + u8 ff_temp_data[7] = {0}; + //body + ff_temp_data[0] = (body >> 8) & 0xFF; + ff_temp_data[1] = (body) & 0xFF; + //obj + ff_temp_data[2] = (obj >> 8) & 0xFF; + ff_temp_data[3] = (obj) & 0xFF; + //env + ff_temp_data[4] = (ntc >> 8) & 0xFF; + ff_temp_data[5] = (ntc) & 0xFF; + + ff_temp_data[6] = battery & 0xFF; + //先查明当前连接的conn_handle + u16 connection_handle = ble_comm_dev_get_handle(0, GATT_ROLE_SERVER); + if(connection_handle != 0)// + { + printf("ble connected !! connection_handle: %04x\n", connection_handle); + + + + return ; + }else{ + //printf("connection_handle: %04x\n", connection_handle); + } + + trans_client_adv_data_set_ff(ff_temp_data,sizeof(ff_temp_data)); + gpio_direction_output(IO_PORTB_05, 0); + } + + /** + * 更新BLE广播信息 + * //BBOOEEbs 2字节体温 2字节物温 2字节环温 1字节电量 1字节状态 + * 状态:00 正常模式 01 进入充电 + */ + void temperature_update_adv_ff(u16 temp_body,u16 temp_obj,u16 temp_env,u8 batt,u8 state){ + u16 body = (u16)temp_body; + u16 obj = (u16)temp_obj; + u16 ntc = (u16)temp_env; + u8 battery = 99; + u8 ff_temp_data[8] = {0}; + //body + ff_temp_data[0] = (body >> 8) & 0xFF; + ff_temp_data[1] = (body) & 0xFF; + //obj + ff_temp_data[2] = (obj >> 8) & 0xFF; + ff_temp_data[3] = (obj) & 0xFF; + //env + ff_temp_data[4] = (ntc >> 8) & 0xFF; + ff_temp_data[5] = (ntc) & 0xFF; + //batt + battery = get_cur_battery_level() *10; + ff_temp_data[6] = battery & 0xFF; + ff_temp_data[7] = state & 0xFF; + trans_client_adv_data_set_ff(ff_temp_data,sizeof(ff_temp_data)); + } + + + +void rtc_test_demo() +{ + struct sys_time tmp_time; + memset((u8 *)&tmp_time, 0, sizeof(tmp_time)); + + read_sys_time(&tmp_time); //读当前rtc时间 + printf("read_sys_time: %d-%d-%d %d:%d:%d", tmp_time.year, tmp_time.month, tmp_time.day, tmp_time.hour, tmp_time.min, tmp_time.sec); //打印读取时间值 + + //rtc_write_time(&test_sys_time); //修改rtc时间 + //read_sys_time(&tmp_time); //读修改后rtc时间 + //printf("rtc_rtc_read_time_after: %d-%d-%d %d:%d:%d", tmp_time.year, tmp_time.month, tmp_time.day, tmp_time.hour, tmp_time.min, tmp_time.sec); //打印修改后时间值 + + //read_alarm(&tmp_time); //读当前alarm时间 + //printf("rtc_read_alarm_before: %d-%d-%d %d:%d:%d", tmp_time.year, tmp_time.month, tmp_time.day, tmp_time.hour, tmp_time.min, tmp_time.sec); //打印读取闹钟时间值 + + //rtc_write_alarm(&test_alarm); //修改alarm时间 + //read_alarm(&tmp_time); //读修改后alarm时间 + //printf("rtc_read_alarm_after: %d-%d-%d %d:%d:%d", tmp_time.year, tmp_time.month, tmp_time.day, tmp_time.hour, tmp_time.min, tmp_time.sec); //打印修改后闹钟时间值 +} + +void temperature_detect(void) +{ + rtc_test_demo(); + nst1002_read_temperatura(); + +} +#endif + +u16 charge_led_hander = 0; +void temperature_charge_lowpower(u8 on){ + if(charge_led_hander){ + sys_timer_del(charge_led_hander); + } + if(on){ + charge_led_hander = sys_timer_add(NULL, temperature_blink_led, 1000); + }else{ + sys_timer_del(charge_led_hander); + } +} + +void temperature_work_led(u8 on){ + + if(on){ + gpio_set_hd0(BLE_TEMPERATURE_WORK_LED, 1); + gpio_direction_output(BLE_TEMPERATURE_WORK_LED, 1); + }else{ + gpio_direction_output(BLE_TEMPERATURE_WORK_LED, 0); + } +} + +void temperature_poweron_led_timeout(){ + temperature_work_led(0); +} + +void temperature_set_soft_poweroff(void) +{ + printf("temperature_set_soft_poweroff\n"); + + temperature_deinit(); + //VCM_DET_EN(0);//关闭VCM复位 + //gpio_shortpress_reset_config(0);//1--enable 0--disable + + //P33_CON_SET(P3_PINR_CON, 0, 1, 0);//关闭长按复位 + //P33_CON_SET(P3_PINR_CON, 0, 1, 1);//打开长按复位 + gpio_longpress_pin0_reset_config(IO_PORTA_09, 0, 0); + + //必须先主动断开蓝牙链路,否则要等链路超时断开 +#if TCFG_USER_BLE_ENABLE + btstack_ble_exit(0); + //延时300ms,确保BT退出链路断开 + sys_timeout_add(NULL, power_set_soft_poweroff, 300); +#else + power_set_soft_poweroff(); +#endif +} + +void temperature_charge_state(int state){ + switch (state) + { + //接入充电 + case BLE_TEMPERATURE_CHARGE_STATE_CHARGING : + charge_state = 1; + printf("BLE_TEMPERATURE_CHARGE_STATE_CHARGING\n"); + //关闭低电提示LED + temperature_charge_lowpower(0); + sys_timer_del(temer_temperature_detect); + //体温计指标灯闪烁3次后转灭 + for(int i = 0; i< 3 ; i++){ + temperature_work_led(1); + delay_ms_by_timer0(150); + temperature_work_led(0); + delay_ms_by_timer0(150); + } + //接入充电关闭蓝牙广播 + ble_op_adv_enable(0); + ble_module_enable(0); + //spple_power_event_to_user(POWER_EVENT_POWER_SOFTOFF); + //printf("!!!!!!!!!!!!!! CHARGING POWER OFF!!!!!!!!!!!!!!!!\n"); + //printf("BLE_TEMPERATURE_CHARGE_STATE_CHARGING 2\n"); + + break; + //充电完成 + case BLE_TEMPERATURE_CHARGE_STATE_FULL : + //printf("BLE_TEMPERATURE_CHARGE_STATE_FULL\n"); + temperature_set_soft_poweroff(); + break; + //拔出充电 + case BLE_TEMPERATURE_CHARGE_STATE_IDLE : + charge_state = 0; + printf("BLE_TEMPERATURE_CHARGE_STATE_IDLE\n"); + temer_temperature_detect = sys_timer_add(NULL, temperature_detect, dev_config.detect_interval); + //temperature_charge_led(0); + temperature_work_led(1); + sys_s_hi_timerout_add(NULL,temperature_poweron_led_timeout,2000); + + //拔出充电打开蓝牙广播 + ble_module_enable(1); + ble_op_adv_enable(1); + + break; + //低电 + case BLE_TEMPERATURE_CHARGE_STATE_LOWPOWER: + temperature_charge_lowpower(1); + break; + default: + break; + } +} + +void temperature_ble_init(){ + printf(">>>>>>>>>>>>>>>>> temperature_ble_init ...\n"); + + // GET DEVICE MAC + u8 bt_mac_addr[6] = {0}; + bt_get_vm_mac_addr(&bt_mac_addr); + // le_controller_set_mac((void *)bt_mac_addr); + printf("device mac: %02x %02x %02x %02x %02x %02x \n", bt_mac_addr[0], bt_mac_addr[1], bt_mac_addr[2], bt_mac_addr[3], bt_mac_addr[4], bt_mac_addr[5]); + //设置MAC地址 + le_controller_set_mac((void *)bt_mac_addr); + //设置名称 + char ble_name[12] ={0}; + sprintf(ble_name,"iT12_%02X%02X",bt_mac_addr[1],bt_mac_addr[0]); + ble_comm_set_config_name(&ble_name, 0); + + +} +/** + * 初始化测温相关的参数 + */ +void temperature_config_init(){ + //int syscfg_read(u16 item_id, void *buf, u16 len); + //int syscfg_write(u16 item_id, void *buf, u16 len); + + int ret = syscfg_read(BLE_TEMPERATURE_VM_DEVICE_CONFIG, &dev_config, sizeof(app_dev_config_t)); + if (ret != sizeof(app_dev_config_t)) { + printf("temperature_config_init err:%d", ret); + + dev_config.detect_interval = 500; + dev_config.temperature_offset = 0; + syscfg_write(BLE_TEMPERATURE_VM_DEVICE_CONFIG, &dev_config, sizeof(app_dev_config_t)); + } + //test + dev_config.detect_interval = 0; + dev_config.temperature_offset = 0; + ret = syscfg_read(BLE_TEMPERATURE_VM_DEVICE_CONFIG, &dev_config, sizeof(app_dev_config_t)); + if (ret != sizeof(app_dev_config_t)) { + printf("temperature_config_init err:%d", ret); + }else{ + printf("detect_interval :%d", dev_config.detect_interval); + printf("temperature_offset :%d", dev_config.temperature_offset); + } + dev_config.detect_interval = 2000; + +} +void alarm_isr_user_cbfun(u8 index) +{ + printf("**** 11 alarm %d : hello world ****\n", index); +} + +/** + * 定时关机 + */ +void timer_sleep_callback(void) +{ + //关机开启闹钟 + printf(">>>>>>>>>>>>>>>>> timer_sleep_callback ...\n"); + rtc_alarm_set_timer(10); + temperature_set_soft_poweroff(); +} + +void temperature_init(void) +{ + + //extern void user_alarm_test(void); + //extern void alarm_rtc_start(void); + //alarm_rtc_start(); + //user_alarm_test(); + + printf(">>>>>>>>>>>>>>>>> temperature_init ...\n"); + delay_us(60); + printf(">>>>>>>>>>>>>>>>> temperature_OTA ...\n"); + + extern u16 get_vbat_trim(); + extern u16 get_vbg_trim(); + printf("vbat_trim:%d...vbg_trim:%d", get_vbat_trim(), get_vbg_trim()); + // 添加以上代码,看打印值,如果为15跟63,那就要用烧录器先烧录一遍。 + + temperature_config_init(); + + //从收纳仓取出时自动开机(指示灯亮2S后灭) + temperature_work_led(1); + sys_s_hi_timerout_add(NULL,temperature_poweron_led_timeout,2000); + + //sys_s_hi_timer_add(NULL, temperature_blink_led, 200); + //sys_s_hi_timer_add(NULL, temperature_detect, 2000); + //sys_timer_add 方式添加定时任务 任务里边可以使用udelay delay_ms 等延时 sys_s_hi_timer_add 则延时无效 + temer_temperature_detect = sys_timer_add(NULL, temperature_detect, dev_config.detect_interval); + //工作10秒关机 关机10s后 RTC重新唤醒 + //temer_sleep = sys_timer_add(NULL, timer_sleep_callback,10*1000); + + //HALL PIN 输入 + gpio_set_direction(IO_PORTA_00,1); + gpio_set_die(IO_PORTA_00,1); + + gpio_set_direction(IO_PORTB_04,0); + gpio_direction_output(IO_PORTB_04, 1); + + gpio_set_direction(IO_PORTB_06,0); + gpio_direction_output(IO_PORTB_06, 1); + + + + // NTC VDD + //gpio_set_direction(IO_PORTB_05,0); + //gpio_direction_output(IO_PORTB_05, 1); + + /* + //test delay + gpio_set_direction(DQ_PIN,0); + gpio_direction_output(DQ_PIN, 1); + delay_us_by_timer0(20); + gpio_direction_output(DQ_PIN, 0); + delay_us_by_timer0(20); + gpio_direction_output(DQ_PIN, 1); + delay_us_by_timer0(20); + gpio_direction_output(DQ_PIN, 0); + delay_ms(200); + gpio_direction_output(DQ_PIN, 1); + delay_ms(200); + gpio_direction_output(DQ_PIN, 0); + delay_ms(200); + gpio_direction_output(DQ_PIN, 1); + */ +} + +void temperature_deinit(void) +{ + printf(">>>>>>>>>>>>>>>>> temperature_deinit ...\n"); + // NTC VDD + gpio_set_direction(IO_PORTB_05,0); + gpio_direction_output(IO_PORTB_05, 0); + + //gpio_set_direction(IO_PORTB_04,0); + //gpio_direction_output(IO_PORTB_04, 0); + + // gpio_set_direction(IO_PORTB_06,0); + //gpio_direction_output(IO_PORTB_06, 0); + + + gpio_set_direction(IO_PORTA_00,0); + gpio_direction_output(IO_PORTA_00, 0); + + + + gpio_set_pull_up(IO_PORTB_04,0); + gpio_set_pull_up(IO_PORTB_06,0); +} diff --git a/fw-AC63_BT_SDK/apps/spp_and_le/board/bd19/board_ac6323a_demo.c b/fw-AC63_BT_SDK/apps/spp_and_le/board/bd19/board_ac6323a_demo.c index c5a92cd..9e1634c 100644 --- a/fw-AC63_BT_SDK/apps/spp_and_le/board/bd19/board_ac6323a_demo.c +++ b/fw-AC63_BT_SDK/apps/spp_and_le/board/bd19/board_ac6323a_demo.c @@ -1,579 +1,583 @@ -#include "app_config.h" - -#ifdef CONFIG_BOARD_AC6323A_DEMO - -#include "system/includes.h" -#include "device/key_driver.h" -#include "asm/chargestore.h" -#include "asm/charge.h" -#include "rtc_alarm.h" -#include "asm/pwm_led.h" -#include "user_cfg.h" -#include "usb/otg.h" -#include "norflash.h" -#include "asm/power/p33.h" - -#define LOG_TAG_CONST BOARD -#define LOG_TAG "[BOARD]" -#define LOG_ERROR_ENABLE -#define LOG_DEBUG_ENABLE -#define LOG_INFO_ENABLE -/* #define LOG_DUMP_ENABLE */ -#define LOG_CLI_ENABLE -#include "debug.h" - -void board_power_init(void); - -/************************** LOW POWER config ****************************/ -const struct low_power_param power_param = { - .config = TCFG_LOWPOWER_LOWPOWER_SEL, //0:sniff时芯片不进入低功耗 1:sniff时芯片进入powerdown - .btosc_hz = TCFG_CLOCK_OSC_HZ, //外接晶振频率 - .delay_us = TCFG_CLOCK_SYS_HZ / 1000000L, //提供给低功耗模块的延时(不需要需修改) - .btosc_disable = TCFG_LOWPOWER_BTOSC_DISABLE, //进入低功耗时BTOSC是否保持 - .vddiom_lev = TCFG_LOWPOWER_VDDIOM_LEVEL, //强VDDIO等级,可选:2.0V 2.2V 2.4V 2.6V 2.8V 3.0V 3.2V 3.6V - .vddiow_lev = TCFG_LOWPOWER_VDDIOW_LEVEL, //弱VDDIO等级,可选:2.1V 2.4V 2.8V 3.2V - .osc_type = TCFG_LOWPOWER_OSC_TYPE, - .lpctmu_en = TCFG_LP_TOUCH_KEY_ENABLE, - .vd13_cap_en = TCFG_VD13_CAP_EN, -}; - -/************************** KEY MSG****************************/ -/*各个按键的消息设置,如果USER_CFG中设置了USE_CONFIG_KEY_SETTING为1,则会从配置文件读取对应的配置来填充改结构体*/ -/* u8 key_table[KEY_NUM_MAX][KEY_EVENT_MAX] = { */ -// SHORT LONG HOLD UP DOUBLE TRIPLE -/* }; */ - - -// *INDENT-OFF* -/************************** UART config****************************/ -#if TCFG_UART0_ENABLE -UART0_PLATFORM_DATA_BEGIN(uart0_data) - .tx_pin = TCFG_UART0_TX_PORT, //串口打印TX引脚选择 - .rx_pin = TCFG_UART0_RX_PORT, //串口打印RX引脚选择 - .baudrate = TCFG_UART0_BAUDRATE, //串口波特率 - - .flags = UART_DEBUG, //串口用来打印需要把改参数设置为UART_DEBUG -UART0_PLATFORM_DATA_END() -#endif //TCFG_UART0_ENABLE - - -/************************** CHARGE config****************************/ -#if TCFG_CHARGE_ENABLE -CHARGE_PLATFORM_DATA_BEGIN(charge_data) - .charge_en = TCFG_CHARGE_ENABLE, //内置充电使能 - .charge_poweron_en = TCFG_CHARGE_POWERON_ENABLE, //是否支持充电开机 - .charge_full_V = TCFG_CHARGE_FULL_V, //充电截止电压 - .charge_full_mA = TCFG_CHARGE_FULL_MA, //充电截止电流 - .charge_mA = TCFG_CHARGE_MA, //充电电流 -/*ldo5v拔出过滤值,过滤时间 = (filter*2 + 20)ms,ldoin<0.6V且时间大于过滤时间才认为拔出 - 对于充满直接从5V掉到0V的充电仓,该值必须设置成0,对于充满由5V先掉到0V之后再升压到xV的 - 充电仓,需要根据实际情况设置该值大小*/ - .ldo5v_off_filter = 100, - .ldo5v_on_filter = 50, - .ldo5v_keep_filter = 220, - .ldo5v_pulldown_lvl = CHARGE_PULLDOWN_200K, //下拉电阻档位选择 - .ldo5v_pulldown_keep = 1, -//1、对于自动升压充电舱,若充电舱需要更大的负载才能检测到插入时,请将该变量置1,并且根据需求配置下拉电阻档位 -//2、对于按键升压,并且是通过上拉电阻去提供维持电压的舱,请将该变量设置1,并且根据舱的上拉配置下拉需要的电阻挡位 -//3、对于常5V的舱,可将改变量设为0,省功耗 -//4、为LDOIN防止被误触发唤醒,可设置为200k下拉 - .ldo5v_pulldown_en = 1, -CHARGE_PLATFORM_DATA_END() -#endif//TCFG_CHARGE_ENABLE - - /************************** AD KEY ****************************/ -#if TCFG_ADKEY_ENABLE -const struct adkey_platform_data adkey_data = { - .enable = TCFG_ADKEY_ENABLE, //AD按键使能 - .adkey_pin = TCFG_ADKEY_PORT, //AD按键对应引脚 - .ad_channel = TCFG_ADKEY_AD_CHANNEL, //AD通道值 - .extern_up_en = TCFG_ADKEY_EXTERN_UP_ENABLE, //是否使用外接上拉电阻 - .ad_value = { //根据电阻算出来的电压值 - TCFG_ADKEY_VOLTAGE0, - TCFG_ADKEY_VOLTAGE1, - TCFG_ADKEY_VOLTAGE2, - TCFG_ADKEY_VOLTAGE3, - TCFG_ADKEY_VOLTAGE4, - TCFG_ADKEY_VOLTAGE5, - TCFG_ADKEY_VOLTAGE6, - TCFG_ADKEY_VOLTAGE7, - TCFG_ADKEY_VOLTAGE8, - TCFG_ADKEY_VOLTAGE9, - }, - .key_value = { //AD按键各个按键的键值 - TCFG_ADKEY_VALUE0, - TCFG_ADKEY_VALUE1, - TCFG_ADKEY_VALUE2, - TCFG_ADKEY_VALUE3, - TCFG_ADKEY_VALUE4, - TCFG_ADKEY_VALUE5, - TCFG_ADKEY_VALUE6, - TCFG_ADKEY_VALUE7, - TCFG_ADKEY_VALUE8, - TCFG_ADKEY_VALUE9, - }, -}; -#endif - -/************************** IO KEY ****************************/ -#if TCFG_IOKEY_ENABLE -const struct iokey_port iokey_list[] = { - { - .connect_way = TCFG_IOKEY_POWER_CONNECT_WAY, //IO按键的连接方式 - .key_type.one_io.port = TCFG_IOKEY_POWER_ONE_PORT, //IO按键对应的引脚 - .key_value = 0, //按键值 - }, - - { - .connect_way = TCFG_IOKEY_PREV_CONNECT_WAY, - .key_type.one_io.port = TCFG_IOKEY_PREV_ONE_PORT, - .key_value = 1, - }, - - { - .connect_way = TCFG_IOKEY_NEXT_CONNECT_WAY, - .key_type.one_io.port = TCFG_IOKEY_NEXT_ONE_PORT, - .key_value = 2, - }, -}; -const struct iokey_platform_data iokey_data = { - .enable = TCFG_IOKEY_ENABLE, //是否使能IO按键 - .num = ARRAY_SIZE(iokey_list), //IO按键的个数 - .port = iokey_list, //IO按键参数表 -}; - -#if MULT_KEY_ENABLE -//组合按键消息映射表 -//配置注意事项:单个按键按键值需要按照顺序编号,如power:0, prev:1, next:2 -//bit_value = BIT(0) | BIT(1) 指按键值为0和按键值为1的两个按键被同时按下, -//remap_value = 3指当这两个按键被同时按下后重新映射的按键值; -const struct key_remap iokey_remap_table[] = { - {.bit_value = BIT(0) | BIT(1), .remap_value = 3}, - {.bit_value = BIT(0) | BIT(2), .remap_value = 4}, - {.bit_value = BIT(1) | BIT(2), .remap_value = 5}, -}; - -const struct key_remap_data iokey_remap_data = { - .remap_num = ARRAY_SIZE(iokey_remap_table), - .table = iokey_remap_table, -}; -#endif - -#endif - -#if TCFG_RTC_ALARM_ENABLE -const struct sys_time def_sys_time = { //初始一下当前时间 - .year = 2020, - .month = 1, - .day = 1, - .hour = 0, - .min = 0, - .sec = 0, -}; -const struct sys_time def_alarm = { //初始一下目标时间,即闹钟时间 - .year = 2050, - .month = 1, - .day = 1, - .hour = 0, - .min = 0, - .sec = 0, -}; - -extern void alarm_isr_user_cbfun(u8 index); -RTC_DEV_PLATFORM_DATA_BEGIN(rtc_data) - .default_sys_time = &def_sys_time, - .default_alarm = &def_alarm, - /* .cbfun = NULL, //闹钟中断的回调函数,用户自行定义 */ - .cbfun = alarm_isr_user_cbfun, -RTC_DEV_PLATFORM_DATA_END() -#endif - -/************************** PWM_LED ****************************/ -#if TCFG_PWMLED_ENABLE -LED_PLATFORM_DATA_BEGIN(pwm_led_data) - .io_mode = TCFG_PWMLED_IOMODE, //推灯模式设置:支持单个IO推两个灯和两个IO推两个灯 - .io_cfg.one_io.pin = TCFG_PWMLED_PIN, //单个IO推两个灯的IO口配置 -LED_PLATFORM_DATA_END() -#endif - -/************************** norflash ****************************/ -NORFLASH_DEV_PLATFORM_DATA_BEGIN(norflash_fat_dev_data) - .spi_hw_num = TCFG_FLASH_DEV_SPI_HW_NUM, - .spi_cs_port = TCFG_FLASH_DEV_SPI_CS_PORT, - .spi_read_width = 4, -#if (TCFG_FLASH_DEV_SPI_HW_NUM == 1) - .spi_pdata = &spi1_p_data, -#elif (TCFG_FLASH_DEV_SPI_HW_NUM == 2) - .spi_pdata = &spi2_p_data, -#endif - .start_addr = 0, - .size = 16*1024*1024, -NORFLASH_DEV_PLATFORM_DATA_END() - - - -/************************** otg data****************************/ -#if TCFG_OTG_MODE -struct otg_dev_data otg_data = { - .usb_dev_en = TCFG_OTG_USB_DEV_EN, - .slave_online_cnt = TCFG_OTG_SLAVE_ONLINE_CNT, - .slave_offline_cnt = TCFG_OTG_SLAVE_OFFLINE_CNT, - .host_online_cnt = TCFG_OTG_HOST_ONLINE_CNT, - .host_offline_cnt = TCFG_OTG_HOST_OFFLINE_CNT, - .detect_mode = TCFG_OTG_MODE, - .detect_time_interval = TCFG_OTG_DET_INTERVAL, -}; -#endif - -REGISTER_DEVICES(device_table) = { -#if TCFG_OTG_MODE - { "otg", &usb_dev_ops, (void *) &otg_data}, -#endif -#if TCFG_CHARGE_ENABLE - { "charge", &charge_dev_ops, (void *)&charge_data }, -#endif - -}; - -void debug_uart_init(const struct uart_platform_data *data) -{ -#if TCFG_UART0_ENABLE - if (data) { - uart_init(data); - } else { - uart_init(&uart0_data); - } -#endif -} - -static void board_devices_init(void) -{ -#if TCFG_PWMLED_ENABLE - pwm_led_init(&pwm_led_data); -#endif - -#if (TCFG_IOKEY_ENABLE || TCFG_ADKEY_ENABLE || TCFG_TOUCH_KEY_ENABLE) - key_driver_init(); -#endif - -#if TCFG_CHARGE_ENABLE - charge_api_init(&charge_data); -#else - /* CHGBG_EN(0); */ - /* CHARGE_EN(0); */ -#endif - -#if TCFG_RTC_ALARM_ENABLE - alarm_init(&rtc_data); -#endif - -} - -//maskrom 使用到的io -static void mask_io_cfg() -{ - struct boot_soft_flag_t boot_soft_flag = {0}; - boot_soft_flag.flag0.boot_ctrl.wdt_dis = 0; - boot_soft_flag.flag0.boot_ctrl.poweroff = 0; - boot_soft_flag.flag0.boot_ctrl.is_port_b = JL_IOMAP->CON0 & BIT(16) ? 1 : 0; - - boot_soft_flag.flag1.misc.usbdm = SOFTFLAG_HIGH_RESISTANCE; - boot_soft_flag.flag1.misc.usbdp = SOFTFLAG_HIGH_RESISTANCE; - - boot_soft_flag.flag1.misc.uart_key_port = 0; - boot_soft_flag.flag1.misc.ldoin = SOFTFLAG_HIGH_RESISTANCE; - - boot_soft_flag.flag2.pa7_pb4.pa7 = SOFTFLAG_HIGH_RESISTANCE; - boot_soft_flag.flag2.pa7_pb4.pb4 = SOFTFLAG_HIGH_RESISTANCE; - - boot_soft_flag.flag3.pc3_pc5.pc3 = SOFTFLAG_HIGH_RESISTANCE; - boot_soft_flag.flag3.pc3_pc5.pc5 = SOFTFLAG_HIGH_RESISTANCE; - mask_softflag_config(&boot_soft_flag); -} - - -extern void cfg_file_parse(u8 idx); -void board_init() -{ - board_power_init(); - adc_vbg_init(); - adc_init(); - cfg_file_parse(0); - devices_init(); - - board_devices_init(); - - if(get_charge_online_flag()) { - power_set_mode(PWR_LDO15); - } else { - power_set_mode(TCFG_LOWPOWER_POWER_SEL); - } - - /*close FAST CHARGE */ -#if TCFG_UART0_ENABLE - if (uart0_data.rx_pin < IO_MAX_NUM) { - gpio_set_die(uart0_data.rx_pin, 1); - } -#endif - -} - -enum { - PORTA_GROUP = 0, - PORTB_GROUP, - PORTC_GROUP, -}; - -static void port_protect(u16 *port_group, u32 port_num) -{ - if (port_num == NO_CONFIG_PORT) { - return; - } - port_group[port_num / IO_GROUP_NUM] &= ~BIT(port_num % IO_GROUP_NUM); -} - -void usb1_iomode(u32 enable); -/*进软关机之前默认将IO口都设置成高阻状态,需要保留原来状态的请修改该函数*/ -static void close_gpio(void) -{ - u16 port_group[] = { - [PORTA_GROUP] = 0x1ff, - [PORTB_GROUP] = 0x3ff,// - [PORTC_GROUP] = 0x3ff,// - }; - - if(P3_ANA_CON2 & BIT(3)) - { - port_protect(port_group, IO_PORTB_02); //protect VCM_IO - } - -#if TCFG_ADKEY_ENABLE - port_protect(port_group,TCFG_ADKEY_PORT); -#endif /* */ - -#if TCFG_IOKEY_ENABLE - port_protect(port_group, TCFG_IOKEY_POWER_ONE_PORT); - port_protect(port_group, TCFG_IOKEY_PREV_ONE_PORT); - port_protect(port_group, TCFG_IOKEY_NEXT_ONE_PORT); -#endif /* TCFG_IOKEY_ENABLE */ - -#if TCFG_RTC_ALARM_ENABLE - /* port_protect(port_group, IO_PORTA_01); */ - /* port_protect(port_group, IO_PORTA_02); */ -#endif /* TCFG_RTC_ALARM_ENABLE */ - - //< close gpio - gpio_dir(GPIOA, 0, 9, port_group[PORTA_GROUP], GPIO_OR); - gpio_set_pu(GPIOA, 0, 9, ~port_group[PORTA_GROUP], GPIO_AND); - gpio_set_pd(GPIOA, 0, 9, ~port_group[PORTA_GROUP], GPIO_AND); - gpio_die(GPIOA, 0, 9, ~port_group[PORTA_GROUP], GPIO_AND); - gpio_dieh(GPIOA, 0, 9, ~port_group[PORTA_GROUP], GPIO_AND); - - gpio_dir(GPIOB, 0, 10, port_group[PORTB_GROUP], GPIO_OR); - gpio_set_pu(GPIOB, 0, 10, ~port_group[PORTB_GROUP], GPIO_AND); - gpio_set_pd(GPIOB, 0, 10, ~port_group[PORTB_GROUP], GPIO_AND); - gpio_die(GPIOB, 0, 10, ~port_group[PORTB_GROUP], GPIO_AND); - gpio_dieh(GPIOB, 0, 10, ~port_group[PORTB_GROUP], GPIO_AND); - - //< close usb io - usb_iomode(1); - gpio_set_pull_up(IO_PORT_DP, 0); - gpio_set_pull_down(IO_PORT_DP, 0); - gpio_set_direction(IO_PORT_DP, 1); - gpio_set_die(IO_PORT_DP, 0); - gpio_set_dieh(IO_PORT_DP, 0); - - gpio_set_pull_up(IO_PORT_DM, 0); - gpio_set_pull_down(IO_PORT_DM, 0); - gpio_set_direction(IO_PORT_DM, 1); - gpio_set_die(IO_PORT_DM, 0); - gpio_set_dieh(IO_PORT_DM, 0); - - usb1_iomode(1); - gpio_set_pull_up(IO_PORT_DP1, 0); - gpio_set_pull_down(IO_PORT_DP1, 0); - gpio_set_direction(IO_PORT_DP1, 1); - gpio_set_die(IO_PORT_DP1, 0); - gpio_set_dieh(IO_PORT_DP1, 0); - - gpio_set_pull_up(IO_PORT_DM1, 0); - gpio_set_pull_down(IO_PORT_DM1, 0); - gpio_set_direction(IO_PORT_DM1, 1); - gpio_set_die(IO_PORT_DM1, 0); - gpio_set_dieh(IO_PORT_DM1, 0); - - /* printf("JL_USB_IO->CON0=0x%x\r\n", JL_USB_IO->CON0); */ - /* printf("JL_USB_IO->CON1=0x%x\r\n", JL_USB_IO->CON1); */ - /* printf("JL_USB->CON0=0x%x\r\n", JL_USB->CON0); */ - /* */ - /* printf("JL_USB1_IO->CON0=0x%x\r\n", JL_USB1_IO->CON0); */ - /* printf("JL_USB1_IO->CON1=0x%x\r\n", JL_USB1_IO->CON1); */ - /* printf("JL_USB1->CON0=0x%x\r\n", JL_USB1->CON0); */ -} - -/************************** PWR config ****************************/ -struct port_wakeup port0 = { - .pullup_down_enable = ENABLE, //配置I/O 内部上下拉是否使能 - .edge = FALLING_EDGE, //唤醒方式选择,可选:上升沿\下降沿 - .both_edge = 0, - -#if TCFG_ADKEY_ENABLE - .iomap = TCFG_ADKEY_PORT, //唤醒口选择 -#else - .iomap = TCFG_IOKEY_POWER_ONE_PORT, //唤醒口选择 -#endif - .filter = PORT_FLT_2ms, -}; - -#if TCFG_TEST_BOX_ENABLE -struct port_wakeup port1 = { - .pullup_down_enable = DISABLE, //配置I/O 内部上下拉是否使能 - .edge = FALLING_EDGE, //唤醒方式选择,可选:上升沿\下降沿 - .both_edge = 1, - .filter = PORT_FLT_1ms, - .iomap = TCFG_CHARGESTORE_PORT, //唤醒口选择 -}; -#endif - -#if TCFG_CHARGE_ENABLE -struct port_wakeup charge_port = { - .edge = RISING_EDGE, //唤醒方式选择,可选:上升沿\下降沿\双边沿 - .both_edge = 0, - .filter = PORT_FLT_16ms, - .iomap = IO_CHGFL_DET, //唤醒口选择 -}; - -struct port_wakeup vbat_port = { - .edge = BOTH_EDGE, //唤醒方式选择,可选:上升沿\下降沿\双边沿 - .both_edge = 1, - .filter = PORT_FLT_16ms, - .iomap = IO_VBTCH_DET, //唤醒口选择 -}; - -struct port_wakeup ldoin_port = { - .edge = BOTH_EDGE, //唤醒方式选择,可选:上升沿\下降沿\双边沿 - .both_edge = 1, - .filter = PORT_FLT_16ms, - .iomap = IO_LDOIN_DET, //唤醒口选择 -}; -#endif - -const struct wakeup_param wk_param = { - -#if TCFG_ADKEY_ENABLE || TCFG_IOKEY_ENABLE - .port[1] = &port0, -#endif - /* .sub = &sub_wkup, */ - /* .charge = &charge_wkup, */ - -#if TCFG_TEST_BOX_ENABLE - .port[2] = &port1, -#endif -#if TCFG_CHARGE_ENABLE - .aport[0] = &charge_port, - .aport[1] = &vbat_port, - .aport[2] = &ldoin_port, -#endif - -}; - -//----------------------------------------------- - - -/*进软关机之前默认将IO口都设置成高阻状态,需要保留原来状态的请修改该函数*/ -extern void dac_power_off(void); -void board_set_soft_poweroff(void) -{ - log_info("%s",__FUNCTION__); - mask_io_cfg(); - -#if TCFG_TEST_BOX_ENABLE - power_wakeup_index_disable(2); -#endif - - close_gpio(); -} - -#define APP_IO_DEBUG_0(i,x) //{JL_PORT##i->DIR &= ~BIT(x), JL_PORT##i->OUT &= ~BIT(x);} -#define APP_IO_DEBUG_1(i,x) //{JL_PORT##i->DIR &= ~BIT(x), JL_PORT##i->OUT |= BIT(x);} - - -void sleep_exit_callback(u32 usec) -{ - putchar('>'); - APP_IO_DEBUG_0(A, 5); -} - -void sleep_enter_callback(u8 step) -{ - /* 此函数禁止添加打印 */ - if (step == 1) { - putchar('<'); - APP_IO_DEBUG_1(A, 5); - /*dac_power_off();*/ - } else { - close_gpio(); - } -} - -static void wl_audio_clk_on(void) -{ - JL_WL_AUD->CON0 = 1; -} - -static void port_wakeup_callback(u8 index, u8 gpio) -{ - /* log_info("%s:%d,%d",__FUNCTION__,index,gpio); */ - - switch (index) { -#if TCFG_TEST_BOX_ENABLE - case 2: - extern void chargestore_ldo5v_fall_deal(void); - chargestore_ldo5v_fall_deal(); - break; -#endif - } -} - -static void aport_wakeup_callback(u8 index, u8 gpio, u8 edge) -{ -#if TCFG_CHARGE_ENABLE - switch (gpio) { - case IO_CHGFL_DET://charge port - charge_wakeup_isr(); - break; - case IO_VBTCH_DET://vbat port - case IO_LDOIN_DET://ldoin port - ldoin_wakeup_isr(); - break; - } -#endif -} - -void board_power_init(void) -{ - log_info("Power init : %s", __FILE__); - - power_init(&power_param); - - //< close short key reset - /* power_mclr(0); */ - //< close long key reset - /* power_pin_reset(0); */ - - power_set_callback(TCFG_LOWPOWER_LOWPOWER_SEL, sleep_enter_callback, sleep_exit_callback, board_set_soft_poweroff); - -// wl_audio_clk_on(); - - power_keep_dacvdd_en(0); - - power_wakeup_init(&wk_param); - - aport_edge_wkup_set_callback(aport_wakeup_callback); - port_edge_wkup_set_callback(port_wakeup_callback); - - /* #if (!TCFG_IOKEY_ENABLE && !TCFG_ADKEY_ENABLE) */ - /* charge_check_and_set_pinr(0); */ -/* #endif */ -} -#endif +#include "app_config.h" + +#ifdef CONFIG_BOARD_AC6323A_DEMO + +#include "system/includes.h" +#include "device/key_driver.h" +#include "asm/chargestore.h" +#include "asm/charge.h" +#include "rtc_alarm.h" +#include "asm/pwm_led.h" +#include "user_cfg.h" +#include "usb/otg.h" +#include "norflash.h" +#include "asm/power/p33.h" + +#define LOG_TAG_CONST BOARD +#define LOG_TAG "[BOARD]" +#define LOG_ERROR_ENABLE +#define LOG_DEBUG_ENABLE +#define LOG_INFO_ENABLE +/* #define LOG_DUMP_ENABLE */ +#define LOG_CLI_ENABLE +#include "debug.h" + +void board_power_init(void); + +/************************** LOW POWER config ****************************/ +const struct low_power_param power_param = { + .config = TCFG_LOWPOWER_LOWPOWER_SEL, //0:sniff时芯片不进入低功耗 1:sniff时芯片进入powerdown + .btosc_hz = TCFG_CLOCK_OSC_HZ, //外接晶振频率 + .delay_us = TCFG_CLOCK_SYS_HZ / 1000000L, //提供给低功耗模块的延时(不需要需修改) + .btosc_disable = TCFG_LOWPOWER_BTOSC_DISABLE, //进入低功耗时BTOSC是否保持 + .vddiom_lev = TCFG_LOWPOWER_VDDIOM_LEVEL, //强VDDIO等级,可选:2.0V 2.2V 2.4V 2.6V 2.8V 3.0V 3.2V 3.6V + .vddiow_lev = TCFG_LOWPOWER_VDDIOW_LEVEL, //弱VDDIO等级,可选:2.1V 2.4V 2.8V 3.2V + .osc_type = TCFG_LOWPOWER_OSC_TYPE, + .lpctmu_en = TCFG_LP_TOUCH_KEY_ENABLE, + .vd13_cap_en = TCFG_VD13_CAP_EN, + //helloyifa + .rtc_clk = 1, +}; + +/************************** KEY MSG****************************/ +/*各个按键的消息设置,如果USER_CFG中设置了USE_CONFIG_KEY_SETTING为1,则会从配置文件读取对应的配置来填充改结构体*/ +/* u8 key_table[KEY_NUM_MAX][KEY_EVENT_MAX] = { */ +// SHORT LONG HOLD UP DOUBLE TRIPLE +/* }; */ + + +// *INDENT-OFF* +/************************** UART config****************************/ +#if TCFG_UART0_ENABLE +UART0_PLATFORM_DATA_BEGIN(uart0_data) + .tx_pin = TCFG_UART0_TX_PORT, //串口打印TX引脚选择 + .rx_pin = TCFG_UART0_RX_PORT, //串口打印RX引脚选择 + .baudrate = TCFG_UART0_BAUDRATE, //串口波特率 + + .flags = UART_DEBUG, //串口用来打印需要把改参数设置为UART_DEBUG +UART0_PLATFORM_DATA_END() +#endif //TCFG_UART0_ENABLE + + +/************************** CHARGE config****************************/ +#if TCFG_CHARGE_ENABLE +CHARGE_PLATFORM_DATA_BEGIN(charge_data) + .charge_en = TCFG_CHARGE_ENABLE, //内置充电使能 + .charge_poweron_en = TCFG_CHARGE_POWERON_ENABLE, //是否支持充电开机 + .charge_full_V = TCFG_CHARGE_FULL_V, //充电截止电压 + .charge_full_mA = TCFG_CHARGE_FULL_MA, //充电截止电流 + .charge_mA = TCFG_CHARGE_MA, //充电电流 +/*ldo5v拔出过滤值,过滤时间 = (filter*2 + 20)ms,ldoin<0.6V且时间大于过滤时间才认为拔出 + 对于充满直接从5V掉到0V的充电仓,该值必须设置成0,对于充满由5V先掉到0V之后再升压到xV的 + 充电仓,需要根据实际情况设置该值大小*/ + .ldo5v_off_filter = 100, + .ldo5v_on_filter = 50, + .ldo5v_keep_filter = 220, + .ldo5v_pulldown_lvl = CHARGE_PULLDOWN_200K, //下拉电阻档位选择 + .ldo5v_pulldown_keep = 1, +//1、对于自动升压充电舱,若充电舱需要更大的负载才能检测到插入时,请将该变量置1,并且根据需求配置下拉电阻档位 +//2、对于按键升压,并且是通过上拉电阻去提供维持电压的舱,请将该变量设置1,并且根据舱的上拉配置下拉需要的电阻挡位 +//3、对于常5V的舱,可将改变量设为0,省功耗 +//4、为LDOIN防止被误触发唤醒,可设置为200k下拉 + .ldo5v_pulldown_en = 1, +CHARGE_PLATFORM_DATA_END() +#endif//TCFG_CHARGE_ENABLE + + /************************** AD KEY ****************************/ +#if TCFG_ADKEY_ENABLE +const struct adkey_platform_data adkey_data = { + .enable = TCFG_ADKEY_ENABLE, //AD按键使能 + .adkey_pin = TCFG_ADKEY_PORT, //AD按键对应引脚 + .ad_channel = TCFG_ADKEY_AD_CHANNEL, //AD通道值 + .extern_up_en = TCFG_ADKEY_EXTERN_UP_ENABLE, //是否使用外接上拉电阻 + .ad_value = { //根据电阻算出来的电压值 + TCFG_ADKEY_VOLTAGE0, + TCFG_ADKEY_VOLTAGE1, + TCFG_ADKEY_VOLTAGE2, + TCFG_ADKEY_VOLTAGE3, + TCFG_ADKEY_VOLTAGE4, + TCFG_ADKEY_VOLTAGE5, + TCFG_ADKEY_VOLTAGE6, + TCFG_ADKEY_VOLTAGE7, + TCFG_ADKEY_VOLTAGE8, + TCFG_ADKEY_VOLTAGE9, + }, + .key_value = { //AD按键各个按键的键值 + TCFG_ADKEY_VALUE0, + TCFG_ADKEY_VALUE1, + TCFG_ADKEY_VALUE2, + TCFG_ADKEY_VALUE3, + TCFG_ADKEY_VALUE4, + TCFG_ADKEY_VALUE5, + TCFG_ADKEY_VALUE6, + TCFG_ADKEY_VALUE7, + TCFG_ADKEY_VALUE8, + TCFG_ADKEY_VALUE9, + }, +}; +#endif + +/************************** IO KEY ****************************/ +#if TCFG_IOKEY_ENABLE +const struct iokey_port iokey_list[] = { + { + .connect_way = TCFG_IOKEY_POWER_CONNECT_WAY, //IO按键的连接方式 + .key_type.one_io.port = TCFG_IOKEY_POWER_ONE_PORT, //IO按键对应的引脚 + .key_value = 0, //按键值 + }, + + { + .connect_way = TCFG_IOKEY_PREV_CONNECT_WAY, + .key_type.one_io.port = TCFG_IOKEY_PREV_ONE_PORT, + .key_value = 1, + }, + + { + .connect_way = TCFG_IOKEY_NEXT_CONNECT_WAY, + .key_type.one_io.port = TCFG_IOKEY_NEXT_ONE_PORT, + .key_value = 2, + }, +}; +const struct iokey_platform_data iokey_data = { + .enable = TCFG_IOKEY_ENABLE, //是否使能IO按键 + .num = ARRAY_SIZE(iokey_list), //IO按键的个数 + .port = iokey_list, //IO按键参数表 +}; + +#if MULT_KEY_ENABLE +//组合按键消息映射表 +//配置注意事项:单个按键按键值需要按照顺序编号,如power:0, prev:1, next:2 +//bit_value = BIT(0) | BIT(1) 指按键值为0和按键值为1的两个按键被同时按下, +//remap_value = 3指当这两个按键被同时按下后重新映射的按键值; +const struct key_remap iokey_remap_table[] = { + {.bit_value = BIT(0) | BIT(1), .remap_value = 3}, + {.bit_value = BIT(0) | BIT(2), .remap_value = 4}, + {.bit_value = BIT(1) | BIT(2), .remap_value = 5}, +}; + +const struct key_remap_data iokey_remap_data = { + .remap_num = ARRAY_SIZE(iokey_remap_table), + .table = iokey_remap_table, +}; +#endif + +#endif + +#if TCFG_RTC_ALARM_ENABLE +const struct sys_time def_sys_time = { //初始一下当前时间 + .year = 2020, + .month = 1, + .day = 1, + .hour = 0, + .min = 0, + .sec = 0, +}; +const struct sys_time def_alarm = { //初始一下目标时间,即闹钟时间 + .year = 2050, + .month = 1, + .day = 1, + .hour = 0, + .min = 0, + .sec = 0, +}; + +extern void alarm_isr_user_cbfun(u8 index); +RTC_DEV_PLATFORM_DATA_BEGIN(rtc_data) + .default_sys_time = &def_sys_time, + .default_alarm = &def_alarm, + /* .cbfun = NULL, //闹钟中断的回调函数,用户自行定义 */ + .cbfun = alarm_isr_user_cbfun, + //helloyifa + .clk_sel = CLK_SEL_LRC, +RTC_DEV_PLATFORM_DATA_END() +#endif + +/************************** PWM_LED ****************************/ +#if TCFG_PWMLED_ENABLE +LED_PLATFORM_DATA_BEGIN(pwm_led_data) + .io_mode = TCFG_PWMLED_IOMODE, //推灯模式设置:支持单个IO推两个灯和两个IO推两个灯 + .io_cfg.one_io.pin = TCFG_PWMLED_PIN, //单个IO推两个灯的IO口配置 +LED_PLATFORM_DATA_END() +#endif + +/************************** norflash ****************************/ +NORFLASH_DEV_PLATFORM_DATA_BEGIN(norflash_fat_dev_data) + .spi_hw_num = TCFG_FLASH_DEV_SPI_HW_NUM, + .spi_cs_port = TCFG_FLASH_DEV_SPI_CS_PORT, + .spi_read_width = 4, +#if (TCFG_FLASH_DEV_SPI_HW_NUM == 1) + .spi_pdata = &spi1_p_data, +#elif (TCFG_FLASH_DEV_SPI_HW_NUM == 2) + .spi_pdata = &spi2_p_data, +#endif + .start_addr = 0, + .size = 16*1024*1024, +NORFLASH_DEV_PLATFORM_DATA_END() + + + +/************************** otg data****************************/ +#if TCFG_OTG_MODE +struct otg_dev_data otg_data = { + .usb_dev_en = TCFG_OTG_USB_DEV_EN, + .slave_online_cnt = TCFG_OTG_SLAVE_ONLINE_CNT, + .slave_offline_cnt = TCFG_OTG_SLAVE_OFFLINE_CNT, + .host_online_cnt = TCFG_OTG_HOST_ONLINE_CNT, + .host_offline_cnt = TCFG_OTG_HOST_OFFLINE_CNT, + .detect_mode = TCFG_OTG_MODE, + .detect_time_interval = TCFG_OTG_DET_INTERVAL, +}; +#endif + +REGISTER_DEVICES(device_table) = { +#if TCFG_OTG_MODE + { "otg", &usb_dev_ops, (void *) &otg_data}, +#endif +#if TCFG_CHARGE_ENABLE + { "charge", &charge_dev_ops, (void *)&charge_data }, +#endif + +}; + +void debug_uart_init(const struct uart_platform_data *data) +{ +#if TCFG_UART0_ENABLE + if (data) { + uart_init(data); + } else { + uart_init(&uart0_data); + } +#endif +} + +static void board_devices_init(void) +{ +#if TCFG_PWMLED_ENABLE + pwm_led_init(&pwm_led_data); +#endif + +#if (TCFG_IOKEY_ENABLE || TCFG_ADKEY_ENABLE || TCFG_TOUCH_KEY_ENABLE) + key_driver_init(); +#endif + +#if TCFG_CHARGE_ENABLE + charge_api_init(&charge_data); +#else + /* CHGBG_EN(0); */ + /* CHARGE_EN(0); */ +#endif + +#if TCFG_RTC_ALARM_ENABLE + alarm_init(&rtc_data); +#endif + +} + +//maskrom 使用到的io +static void mask_io_cfg() +{ + struct boot_soft_flag_t boot_soft_flag = {0}; + boot_soft_flag.flag0.boot_ctrl.wdt_dis = 0; + boot_soft_flag.flag0.boot_ctrl.poweroff = 0; + boot_soft_flag.flag0.boot_ctrl.is_port_b = JL_IOMAP->CON0 & BIT(16) ? 1 : 0; + + boot_soft_flag.flag1.misc.usbdm = SOFTFLAG_HIGH_RESISTANCE; + boot_soft_flag.flag1.misc.usbdp = SOFTFLAG_HIGH_RESISTANCE; + + boot_soft_flag.flag1.misc.uart_key_port = 0; + boot_soft_flag.flag1.misc.ldoin = SOFTFLAG_HIGH_RESISTANCE; + + boot_soft_flag.flag2.pa7_pb4.pa7 = SOFTFLAG_HIGH_RESISTANCE; + boot_soft_flag.flag2.pa7_pb4.pb4 = SOFTFLAG_HIGH_RESISTANCE; + + boot_soft_flag.flag3.pc3_pc5.pc3 = SOFTFLAG_HIGH_RESISTANCE; + boot_soft_flag.flag3.pc3_pc5.pc5 = SOFTFLAG_HIGH_RESISTANCE; + mask_softflag_config(&boot_soft_flag); +} + + +extern void cfg_file_parse(u8 idx); +void board_init() +{ + board_power_init(); + adc_vbg_init(); + adc_init(); + cfg_file_parse(0); + devices_init(); + + board_devices_init(); + + if(get_charge_online_flag()) { + power_set_mode(PWR_LDO15); + } else { + power_set_mode(TCFG_LOWPOWER_POWER_SEL); + } + + /*close FAST CHARGE */ +#if TCFG_UART0_ENABLE + if (uart0_data.rx_pin < IO_MAX_NUM) { + gpio_set_die(uart0_data.rx_pin, 1); + } +#endif + +} + +enum { + PORTA_GROUP = 0, + PORTB_GROUP, + PORTC_GROUP, +}; + +static void port_protect(u16 *port_group, u32 port_num) +{ + if (port_num == NO_CONFIG_PORT) { + return; + } + port_group[port_num / IO_GROUP_NUM] &= ~BIT(port_num % IO_GROUP_NUM); +} + +void usb1_iomode(u32 enable); +/*进软关机之前默认将IO口都设置成高阻状态,需要保留原来状态的请修改该函数*/ +static void close_gpio(void) +{ + u16 port_group[] = { + [PORTA_GROUP] = 0x1ff, + [PORTB_GROUP] = 0x3ff,// + [PORTC_GROUP] = 0x3ff,// + }; + + if(P3_ANA_CON2 & BIT(3)) + { + port_protect(port_group, IO_PORTB_02); //protect VCM_IO + } + +#if TCFG_ADKEY_ENABLE + port_protect(port_group,TCFG_ADKEY_PORT); +#endif /* */ + +#if TCFG_IOKEY_ENABLE + port_protect(port_group, TCFG_IOKEY_POWER_ONE_PORT); + port_protect(port_group, TCFG_IOKEY_PREV_ONE_PORT); + port_protect(port_group, TCFG_IOKEY_NEXT_ONE_PORT); +#endif /* TCFG_IOKEY_ENABLE */ + +#if TCFG_RTC_ALARM_ENABLE + /* port_protect(port_group, IO_PORTA_01); */ + /* port_protect(port_group, IO_PORTA_02); */ +#endif /* TCFG_RTC_ALARM_ENABLE */ + + //< close gpio + gpio_dir(GPIOA, 0, 9, port_group[PORTA_GROUP], GPIO_OR); + gpio_set_pu(GPIOA, 0, 9, ~port_group[PORTA_GROUP], GPIO_AND); + gpio_set_pd(GPIOA, 0, 9, ~port_group[PORTA_GROUP], GPIO_AND); + gpio_die(GPIOA, 0, 9, ~port_group[PORTA_GROUP], GPIO_AND); + gpio_dieh(GPIOA, 0, 9, ~port_group[PORTA_GROUP], GPIO_AND); + + gpio_dir(GPIOB, 0, 10, port_group[PORTB_GROUP], GPIO_OR); + gpio_set_pu(GPIOB, 0, 10, ~port_group[PORTB_GROUP], GPIO_AND); + gpio_set_pd(GPIOB, 0, 10, ~port_group[PORTB_GROUP], GPIO_AND); + gpio_die(GPIOB, 0, 10, ~port_group[PORTB_GROUP], GPIO_AND); + gpio_dieh(GPIOB, 0, 10, ~port_group[PORTB_GROUP], GPIO_AND); + + //< close usb io + usb_iomode(1); + gpio_set_pull_up(IO_PORT_DP, 0); + gpio_set_pull_down(IO_PORT_DP, 0); + gpio_set_direction(IO_PORT_DP, 1); + gpio_set_die(IO_PORT_DP, 0); + gpio_set_dieh(IO_PORT_DP, 0); + + gpio_set_pull_up(IO_PORT_DM, 0); + gpio_set_pull_down(IO_PORT_DM, 0); + gpio_set_direction(IO_PORT_DM, 1); + gpio_set_die(IO_PORT_DM, 0); + gpio_set_dieh(IO_PORT_DM, 0); + + usb1_iomode(1); + gpio_set_pull_up(IO_PORT_DP1, 0); + gpio_set_pull_down(IO_PORT_DP1, 0); + gpio_set_direction(IO_PORT_DP1, 1); + gpio_set_die(IO_PORT_DP1, 0); + gpio_set_dieh(IO_PORT_DP1, 0); + + gpio_set_pull_up(IO_PORT_DM1, 0); + gpio_set_pull_down(IO_PORT_DM1, 0); + gpio_set_direction(IO_PORT_DM1, 1); + gpio_set_die(IO_PORT_DM1, 0); + gpio_set_dieh(IO_PORT_DM1, 0); + + /* printf("JL_USB_IO->CON0=0x%x\r\n", JL_USB_IO->CON0); */ + /* printf("JL_USB_IO->CON1=0x%x\r\n", JL_USB_IO->CON1); */ + /* printf("JL_USB->CON0=0x%x\r\n", JL_USB->CON0); */ + /* */ + /* printf("JL_USB1_IO->CON0=0x%x\r\n", JL_USB1_IO->CON0); */ + /* printf("JL_USB1_IO->CON1=0x%x\r\n", JL_USB1_IO->CON1); */ + /* printf("JL_USB1->CON0=0x%x\r\n", JL_USB1->CON0); */ +} + +/************************** PWR config ****************************/ +struct port_wakeup port0 = { + .pullup_down_enable = ENABLE, //配置I/O 内部上下拉是否使能 + .edge = FALLING_EDGE, //唤醒方式选择,可选:上升沿\下降沿 + .both_edge = 0, + +#if TCFG_ADKEY_ENABLE + .iomap = TCFG_ADKEY_PORT, //唤醒口选择 +#else + .iomap = TCFG_IOKEY_POWER_ONE_PORT, //唤醒口选择 +#endif + .filter = PORT_FLT_2ms, +}; + +#if TCFG_TEST_BOX_ENABLE +struct port_wakeup port1 = { + .pullup_down_enable = DISABLE, //配置I/O 内部上下拉是否使能 + .edge = FALLING_EDGE, //唤醒方式选择,可选:上升沿\下降沿 + .both_edge = 1, + .filter = PORT_FLT_1ms, + .iomap = TCFG_CHARGESTORE_PORT, //唤醒口选择 +}; +#endif + +#if TCFG_CHARGE_ENABLE +struct port_wakeup charge_port = { + .edge = RISING_EDGE, //唤醒方式选择,可选:上升沿\下降沿\双边沿 + .both_edge = 0, + .filter = PORT_FLT_16ms, + .iomap = IO_CHGFL_DET, //唤醒口选择 +}; + +struct port_wakeup vbat_port = { + .edge = BOTH_EDGE, //唤醒方式选择,可选:上升沿\下降沿\双边沿 + .both_edge = 1, + .filter = PORT_FLT_16ms, + .iomap = IO_VBTCH_DET, //唤醒口选择 +}; + +struct port_wakeup ldoin_port = { + .edge = BOTH_EDGE, //唤醒方式选择,可选:上升沿\下降沿\双边沿 + .both_edge = 1, + .filter = PORT_FLT_16ms, + .iomap = IO_LDOIN_DET, //唤醒口选择 +}; +#endif + +const struct wakeup_param wk_param = { + +#if TCFG_ADKEY_ENABLE || TCFG_IOKEY_ENABLE + .port[1] = &port0, +#endif + /* .sub = &sub_wkup, */ + /* .charge = &charge_wkup, */ + +#if TCFG_TEST_BOX_ENABLE + .port[2] = &port1, +#endif +#if TCFG_CHARGE_ENABLE + .aport[0] = &charge_port, + .aport[1] = &vbat_port, + .aport[2] = &ldoin_port, +#endif + +}; + +//----------------------------------------------- + + +/*进软关机之前默认将IO口都设置成高阻状态,需要保留原来状态的请修改该函数*/ +extern void dac_power_off(void); +void board_set_soft_poweroff(void) +{ + log_info("%s",__FUNCTION__); + mask_io_cfg(); + +#if TCFG_TEST_BOX_ENABLE + power_wakeup_index_disable(2); +#endif + + close_gpio(); +} + +#define APP_IO_DEBUG_0(i,x) //{JL_PORT##i->DIR &= ~BIT(x), JL_PORT##i->OUT &= ~BIT(x);} +#define APP_IO_DEBUG_1(i,x) //{JL_PORT##i->DIR &= ~BIT(x), JL_PORT##i->OUT |= BIT(x);} + + +void sleep_exit_callback(u32 usec) +{ + putchar('>'); + APP_IO_DEBUG_0(A, 5); +} + +void sleep_enter_callback(u8 step) +{ + /* 此函数禁止添加打印 */ + if (step == 1) { + putchar('<'); + APP_IO_DEBUG_1(A, 5); + /*dac_power_off();*/ + } else { + close_gpio(); + } +} + +static void wl_audio_clk_on(void) +{ + JL_WL_AUD->CON0 = 1; +} + +static void port_wakeup_callback(u8 index, u8 gpio) +{ + /* log_info("%s:%d,%d",__FUNCTION__,index,gpio); */ + + switch (index) { +#if TCFG_TEST_BOX_ENABLE + case 2: + extern void chargestore_ldo5v_fall_deal(void); + chargestore_ldo5v_fall_deal(); + break; +#endif + } +} + +static void aport_wakeup_callback(u8 index, u8 gpio, u8 edge) +{ +#if TCFG_CHARGE_ENABLE + switch (gpio) { + case IO_CHGFL_DET://charge port + charge_wakeup_isr(); + break; + case IO_VBTCH_DET://vbat port + case IO_LDOIN_DET://ldoin port + ldoin_wakeup_isr(); + break; + } +#endif +} + +void board_power_init(void) +{ + log_info("Power init : %s", __FILE__); + + power_init(&power_param); + + //< close short key reset + /* power_mclr(0); */ + //< close long key reset + /* power_pin_reset(0); */ + + power_set_callback(TCFG_LOWPOWER_LOWPOWER_SEL, sleep_enter_callback, sleep_exit_callback, board_set_soft_poweroff); + +// wl_audio_clk_on(); + + power_keep_dacvdd_en(0); + + power_wakeup_init(&wk_param); + + aport_edge_wkup_set_callback(aport_wakeup_callback); + port_edge_wkup_set_callback(port_wakeup_callback); + + /* #if (!TCFG_IOKEY_ENABLE && !TCFG_ADKEY_ENABLE) */ + /* charge_check_and_set_pinr(0); */ +/* #endif */ +} +#endif diff --git a/fw-AC63_BT_SDK/apps/spp_and_le/board/bd19/board_ac6323a_demo_cfg.h b/fw-AC63_BT_SDK/apps/spp_and_le/board/bd19/board_ac6323a_demo_cfg.h index a6b86ed..e950292 100644 --- a/fw-AC63_BT_SDK/apps/spp_and_le/board/bd19/board_ac6323a_demo_cfg.h +++ b/fw-AC63_BT_SDK/apps/spp_and_le/board/bd19/board_ac6323a_demo_cfg.h @@ -1,344 +1,344 @@ -#ifndef CONFIG_BOARD_AC6323A_DEMO_H -#define CONFIG_BOARD_AC6323A_DEMO_H - -#include "board_ac6323a_demo_global_build_cfg.h" - -#ifdef CONFIG_BOARD_AC6323A_DEMO - -#define CONFIG_SDFILE_ENABLE - -//*********************************************************************************// -// 配置开始 // -//*********************************************************************************// -#define ENABLE_THIS_MOUDLE 1 -#define DISABLE_THIS_MOUDLE 0 - -#define ENABLE 1 -#define DISABLE 0 - -#define NO_CONFIG_PORT (-1) - -//*********************************************************************************// -// UART配置 // -//*********************************************************************************// -#define TCFG_UART0_ENABLE ENABLE_THIS_MOUDLE //串口打印模块使能 -#define TCFG_UART0_RX_PORT NO_CONFIG_PORT //串口接收脚配置(用于打印可以选择NO_CONFIG_PORT) -#define TCFG_UART0_TX_PORT IO_PORTA_01 //串口发送脚配置 -#define TCFG_UART0_BAUDRATE 1000000 //串口波特率配置 - -//*********************************************************************************// -// USB 配置 // -//*********************************************************************************// -#define TCFG_PC_ENABLE DISABLE_THIS_MOUDLE //PC模块使能 -#define TCFG_UDISK_ENABLE DISABLE_THIS_MOUDLE //U盘模块使能 -#define TCFG_HID_HOST_ENABLE DISABLE_THIS_MOUDLE//ENABLE_THIS_MOUDLE //游戏盒子模式 -#define TCFG_ADB_ENABLE DISABLE_THIS_MOUDLE//ENABLE_THIS_MOUDLE -#define TCFG_AOA_ENABLE DISABLE_THIS_MOUDLE//ENABLE_THIS_MOUDLE - -#define TCFG_OTG_USB_DEV_EN (BIT(0) | BIT(1))//USB0 = BIT(0) USB1 = BIT(1) -//*********************************************************************************// -// IIC配置 // -//*********************************************************************************// -/*软件IIC设置*/ -#define TCFG_SW_I2C0_CLK_PORT IO_PORTA_09 //软件IIC CLK脚选择 -#define TCFG_SW_I2C0_DAT_PORT IO_PORTA_10 //软件IIC DAT脚选择 -#define TCFG_SW_I2C0_DELAY_CNT 50 //IIC延时参数,影响通讯时钟频率 - -/*硬件IIC端口选择 - SCL SDA - 'A': IO_PORT_DP IO_PORT_DM - 'B': IO_PORTA_09 IO_PORTA_10 - 'C': IO_PORTA_07 IO_PORTA_08 - 'D': IO_PORTA_05 IO_PORTA_06 - */ -#define TCFG_HW_I2C0_PORTS 'B' -#define TCFG_HW_I2C0_CLK 100000 //硬件IIC波特率 - -//*********************************************************************************// -// 硬件SPI 配置 // -//*********************************************************************************// -#define TCFG_HW_SPI1_ENABLE ENABLE_THIS_MOUDLE -//A组IO: DI: PB2 DO: PB1 CLK: PB0 -//B组IO: DI: PC3 DO: PC5 CLK: PC4 -#define TCFG_HW_SPI1_PORT 'A' -#define TCFG_HW_SPI1_BAUD 2000000L -#define TCFG_HW_SPI1_MODE SPI_MODE_BIDIR_1BIT -#define TCFG_HW_SPI1_ROLE SPI_ROLE_MASTER - -#define TCFG_HW_SPI2_ENABLE ENABLE_THIS_MOUDLE -//A组IO: DI: PB8 DO: PB10 CLK: PB9 -//B组IO: DI: PA13 DO: DM CLK: DP -#define TCFG_HW_SPI2_PORT 'A' -#define TCFG_HW_SPI2_BAUD 2000000L -#define TCFG_HW_SPI2_MODE SPI_MODE_BIDIR_1BIT -#define TCFG_HW_SPI2_ROLE SPI_ROLE_MASTER - -//*********************************************************************************// -// FLASH 配置 // -//*********************************************************************************// -#define TCFG_CODE_FLASH_ENABLE DISABLE_THIS_MOUDLE -#define TCFG_FLASH_DEV_SPI_HW_NUM 1// 1: SPI1 2: SPI2 -#define TCFG_FLASH_DEV_SPI_CS_PORT IO_PORTB_06 -#define TCFG_NORFLASH_DEV_ENABLE DISABLE_THIS_MOUDLE - - -//*********************************************************************************// -// key 配置 // -//*********************************************************************************// -#define KEY_NUM_MAX 10 -#define KEY_NUM 3 - -#define MULT_KEY_ENABLE DISABLE //是否使能组合按键消息, 使能后需要配置组合按键映射表 -//*********************************************************************************// -// iokey 配置 // -//*********************************************************************************// -#define TCFG_IOKEY_ENABLE DISABLE_THIS_MOUDLE //是否使能IO按键 - -#define TCFG_IOKEY_POWER_CONNECT_WAY ONE_PORT_TO_LOW //按键一端接低电平一端接IO - -#define TCFG_IOKEY_POWER_ONE_PORT IO_PORTA_01 //IO按键端口 - -#define TCFG_IOKEY_PREV_CONNECT_WAY ONE_PORT_TO_LOW //按键一端接低电平一端接IO -#define TCFG_IOKEY_PREV_ONE_PORT IO_PORTB_04 - -#define TCFG_IOKEY_NEXT_CONNECT_WAY ONE_PORT_TO_LOW //按键一端接低电平一端接IO -#define TCFG_IOKEY_NEXT_ONE_PORT IO_PORTB_05 - -//*********************************************************************************// -// adkey 配置 // -//*********************************************************************************// -#define TCFG_ADKEY_ENABLE DISABLE_THIS_MOUDLE //是否使能AD按键 -#define TCFG_ADKEY_PORT IO_PORTA_01 //AD按键端口(需要注意选择的IO口是否支持AD功能) -/*AD通道选择,需要和AD按键的端口相对应: - AD_CH_PA1 AD_CH_PA3 AD_CH_PA4 AD_CH_PA5 - AD_CH_PA9 AD_CH_PA1 AD_CH_PB1 AD_CH_PB4 - AD_CH_PB6 AD_CH_PB7 AD_CH_DP AD_CH_DM - AD_CH_PB2 -*/ -#define TCFG_ADKEY_AD_CHANNEL AD_CH_PA1 -#define TCFG_ADKEY_EXTERN_UP_ENABLE ENABLE_THIS_MOUDLE //是否使用外部上拉 - -#if TCFG_ADKEY_EXTERN_UP_ENABLE -#define R_UP 220 //22K,外部上拉阻值在此自行设置 -#else -#define R_UP 100 //10K,内部上拉默认10K -#endif - -//必须从小到大填电阻,没有则同VDDIO,填0x3ffL -#define TCFG_ADKEY_AD0 (0) //0R -#define TCFG_ADKEY_AD1 (0x3ffL * 30 / (30 + R_UP)) //3k -#define TCFG_ADKEY_AD2 (0x3ffL * 62 / (62 + R_UP)) //6.2k -#define TCFG_ADKEY_AD3 (0x3ffL * 91 / (91 + R_UP)) //9.1k -#define TCFG_ADKEY_AD4 (0x3ffL * 150 / (150 + R_UP)) //15k -#define TCFG_ADKEY_AD5 (0x3ffL * 240 / (240 + R_UP)) //24k -#define TCFG_ADKEY_AD6 (0x3ffL * 330 / (330 + R_UP)) //33k -#define TCFG_ADKEY_AD7 (0x3ffL * 510 / (510 + R_UP)) //51k -#define TCFG_ADKEY_AD8 (0x3ffL * 1000 / (1000 + R_UP)) //100k -#define TCFG_ADKEY_AD9 (0x3ffL * 2200 / (2200 + R_UP)) //220k -#define TCFG_ADKEY_VDDIO (0x3ffL) - -#define TCFG_ADKEY_VOLTAGE0 ((TCFG_ADKEY_AD0 + TCFG_ADKEY_AD1) / 2) -#define TCFG_ADKEY_VOLTAGE1 ((TCFG_ADKEY_AD1 + TCFG_ADKEY_AD2) / 2) -#define TCFG_ADKEY_VOLTAGE2 ((TCFG_ADKEY_AD2 + TCFG_ADKEY_AD3) / 2) -#define TCFG_ADKEY_VOLTAGE3 ((TCFG_ADKEY_AD3 + TCFG_ADKEY_AD4) / 2) -#define TCFG_ADKEY_VOLTAGE4 ((TCFG_ADKEY_AD4 + TCFG_ADKEY_AD5) / 2) -#define TCFG_ADKEY_VOLTAGE5 ((TCFG_ADKEY_AD5 + TCFG_ADKEY_AD6) / 2) -#define TCFG_ADKEY_VOLTAGE6 ((TCFG_ADKEY_AD6 + TCFG_ADKEY_AD7) / 2) -#define TCFG_ADKEY_VOLTAGE7 ((TCFG_ADKEY_AD7 + TCFG_ADKEY_AD8) / 2) -#define TCFG_ADKEY_VOLTAGE8 ((TCFG_ADKEY_AD8 + TCFG_ADKEY_AD9) / 2) -#define TCFG_ADKEY_VOLTAGE9 ((TCFG_ADKEY_AD9 + TCFG_ADKEY_VDDIO) / 2) - -#define TCFG_ADKEY_VALUE0 0 -#define TCFG_ADKEY_VALUE1 1 -#define TCFG_ADKEY_VALUE2 2 -#define TCFG_ADKEY_VALUE3 3 -#define TCFG_ADKEY_VALUE4 4 -#define TCFG_ADKEY_VALUE5 5 -#define TCFG_ADKEY_VALUE6 6 -#define TCFG_ADKEY_VALUE7 7 -#define TCFG_ADKEY_VALUE8 8 -#define TCFG_ADKEY_VALUE9 9 - -//*********************************************************************************// -// Audio配置 // -//*********************************************************************************// -#ifdef CONFIG_LITE_AUDIO -#define TCFG_AUDIO_ENABLE DISABLE -#if TCFG_AUDIO_ENABLE -#define TCFG_DEC_USBC_ENABLE DISABLE -#define TCFG_ENC_USBC_ENABLE DISABLE -#define TCFG_DEC_LC3_ENABLE DISABLE -#define TCFG_ENC_LC3_ENABLE DISABLE - - -//lc3 参数配置 -#if (TCFG_ENC_LC3_ENABLE || TCFG_DEC_LC3_ENABLE) -#define LC3_CODING_SAMPLERATE 16000 //lc3 编码的采样率 -#define LC3_CODING_FRAME_LEN 50 //帧长度,只支持25,50,100 -#define LC3_CODING_CHANNEL 1 //lc3 的通道数 -#endif - -#endif - -#endif -//*********************************************************************************// -// irkey 配置 // -//*********************************************************************************// -#define TCFG_IRKEY_ENABLE DISABLE_THIS_MOUDLE//是否使能AD按键 -#define TCFG_IRKEY_PORT IO_PORTA_08 //IR按键端口 - -//*********************************************************************************// -// tocuh key 配置 // -//*********************************************************************************// -#define TCFG_LP_TOUCH_KEY_ENABLE DISABLE_THIS_MOUDLE //是否使能触摸按键 - -//*********************************************************************************// -// RTC_ALARM配置 // -//*********************************************************************************// -#define TCFG_RTC_ALARM_ENABLE ENABLE_THIS_MOUDLE - -//*********************************************************************************// -// 充电仓配置(不支持) // -//*********************************************************************************// -#define TCFG_TEST_BOX_ENABLE DISABLE_THIS_MOUDLE -#define TCFG_CHARGESTORE_PORT IO_PORTP_00 -#define TCFG_CHARGESTORE_UART_ID IRQ_UART1_IDX - -//*********************************************************************************// -// 充电参数配置 // -//*********************************************************************************// -//是否支持芯片内置充电 -#define TCFG_CHARGE_ENABLE ENABLE -//是否支持开机充电 -#define TCFG_CHARGE_POWERON_ENABLE ENABLE -//是否支持拔出充电自动开机功能 -#define TCFG_CHARGE_OFF_POWERON_NE ENABLE -/* -充电截止电压可选配置: - CHARGE_FULL_V_3962 CHARGE_FULL_V_4002 CHARGE_FULL_V_4044 CHARGE_FULL_V_4086 - CHARGE_FULL_V_4130 CHARGE_FULL_V_4175 CHARGE_FULL_V_4222 CHARGE_FULL_V_4270 - CHARGE_FULL_V_4308 CHARGE_FULL_V_4349 CHARGE_FULL_V_4391 CHARGE_FULL_V_4434 - CHARGE_FULL_V_4472 CHARGE_FULL_V_4517 CHARGE_FULL_V_4564 CHARGE_FULL_V_4611 -*/ -#define TCFG_CHARGE_FULL_V CHARGE_FULL_V_4222 -/* -充电截止电流可选配置: - CHARGE_FULL_mA_2 CHARGE_FULL_mA_5 CHARGE_FULL_mA_7 CHARGE_FULL_mA_10 - CHARGE_FULL_mA_15 CHARGE_FULL_mA_20 CHARGE_FULL_mA_25 CHARGE_FULL_mA_30 -*/ -#define TCFG_CHARGE_FULL_MA CHARGE_FULL_mA_5 -/* -充电电流可选配置: - CHARGE_mA_20 CHARGE_mA_30 CHARGE_mA_40 CHARGE_mA_50 - CHARGE_mA_60 CHARGE_mA_70 CHARGE_mA_80 CHARGE_mA_90 - CHARGE_mA_100 CHARGE_mA_110 CHARGE_mA_120 CHARGE_mA_140 - CHARGE_mA_160 CHARGE_mA_180 CHARGE_mA_200 CHARGE_mA_220 - */ -#define TCFG_CHARGE_MA CHARGE_mA_20 - -//*********************************************************************************// -// LED 配置 // -//*********************************************************************************// -#define TCFG_PWMLED_ENABLE DISABLE_THIS_MOUDLE //是否支持PMW LED推灯模块 -#define TCFG_PWMLED_IOMODE LED_ONE_IO_MODE //LED模式,单IO还是两个IO推灯 -#define TCFG_PWMLED_PIN IO_PORTB_06 //LED使用的IO口 -//*********************************************************************************// -// 时钟配置 // -//*********************************************************************************// -#define TCFG_CLOCK_SYS_SRC SYS_CLOCK_INPUT_PLL_BT_OSC //系统时钟源选择 -#define TCFG_CLOCK_SYS_HZ 24000000 //系统时钟设置 -#define TCFG_CLOCK_OSC_HZ 24000000 //外界晶振频率设置 -/* #define TCFG_CLOCK_MODE CLOCK_MODE_USR//CLOCK_MODE_ADAPTIVE */ -#define TCFG_CLOCK_MODE CLOCK_MODE_ADAPTIVE - -//*********************************************************************************// -// 低功耗配置 // -//*********************************************************************************// -#define TCFG_LOWPOWER_POWER_SEL PWR_LDO15 -// #define TCFG_LOWPOWER_POWER_SEL PWR_LDO15 PWR_DCDC15 //电源模式设置,可选DCDC和LDO -#define TCFG_LOWPOWER_BTOSC_DISABLE 0 //低功耗模式下BTOSC是否保持 -#define TCFG_LOWPOWER_LOWPOWER_SEL 0 //SLEEP_EN //SNIFF状态下芯片是否进入powerdown -/*强VDDIO等级配置,可选: - VDDIOM_VOL_20V VDDIOM_VOL_22V VDDIOM_VOL_24V VDDIOM_VOL_26V - VDDIOM_VOL_30V VDDIOM_VOL_30V VDDIOM_VOL_32V VDDIOM_VOL_36V*/ -#define TCFG_LOWPOWER_VDDIOM_LEVEL VDDIOM_VOL_30V -/*弱VDDIO等级配置,可选: - VDDIOW_VOL_21V VDDIOW_VOL_24V VDDIOW_VOL_28V VDDIOW_VOL_32V*/ -#define TCFG_LOWPOWER_VDDIOW_LEVEL VDDIOW_VOL_28V //弱VDDIO等级配置 -#define TCFG_LOWPOWER_OSC_TYPE OSC_TYPE_LRC -#define TCFG_VD13_CAP_EN 1 - - -//*********************************************************************************// -// g-sensor配置 // -//*********************************************************************************// -#define TCFG_GSENSOR_ENABLE 0 //gSensor使能 -#define TCFG_DA230_EN 0 -#define TCFG_SC7A20_EN 0 -#define TCFG_STK8321_EN 0 -#define TCFG_GSENOR_USER_IIC_TYPE 0 //0:软件IIC 1:硬件IIC - -//*********************************************************************************// -// 系统配置 // -//*********************************************************************************// -#define TCFG_AUTO_SHUT_DOWN_TIME 0 //没有蓝牙连接自动关机时间 -#if (TCFG_LOWPOWER_POWER_SEL == PWR_DCDC15) -#define TCFG_SYS_LVD_EN 1 //dcdc模式电压低于2.4v的时候切为LDO模式,需要开启电量检测 -#else -#define TCFG_SYS_LVD_EN 1 //电量检测使能 -#endif -#define TCFG_POWER_ON_NEED_KEY 0 //是否需要按按键开机配置 -#define TCFG_HID_AUTO_SHUTDOWN_TIME (0 * 60) //HID无操作自动关机(单位:秒) - -//*********************************************************************************// -// 蓝牙配置 // -//*********************************************************************************// -#define TCFG_USER_TWS_ENABLE 0 //tws功能使能 -#define TCFG_USER_BLE_ENABLE 1 //BLE功能使能,---使能后,请配置TCFG_BLE_DEMO_SELECT选择DEMO例子 -#define TCFG_USER_EDR_ENABLE 0 //EDR功能使能 - -#define USER_SUPPORT_PROFILE_SPP 0 -#define USER_SUPPORT_PROFILE_HFP 0 -#define USER_SUPPORT_PROFILE_A2DP 0 -#define USER_SUPPORT_PROFILE_AVCTP 0 -#define USER_SUPPORT_PROFILE_HID 0 -#define USER_SUPPORT_PROFILE_PNP 0 -#define USER_SUPPORT_PROFILE_PBAP 0 - - -#if(TCFG_USER_TWS_ENABLE || TCFG_USER_BLE_ENABLE) -#define TCFG_BD_NUM 1 //连接设备个数配置 -#define TCFG_AUTO_STOP_PAGE_SCAN_TIME 0 //配置一拖二第一台连接后自动关闭PAGE SCAN的时间(单位分钟) -#else -#define TCFG_BD_NUM 1 //连接设备个数配置 -#define TCFG_AUTO_STOP_PAGE_SCAN_TIME 0 //配置一拖二第一台连接后自动关闭PAGE SCAN的时间(单位分钟) -#endif - -#define BT_INBAND_RINGTONE 0 //是否播放手机自带来电铃声 -#define BT_PHONE_NUMBER 0 //是否播放来电报号 -#define BT_SUPPORT_DISPLAY_BAT 0 //是否使能电量检测 -#define BT_SUPPORT_MUSIC_VOL_SYNC 0 //是否使能音量同步 - - -//*********************************************************************************// -// 电源切换配置 // -//*********************************************************************************// - -#define CONFIG_PHONE_CALL_USE_LDO15 1 - -//*********************************************************************************// -// 时钟配置 // -//*********************************************************************************// - -#define CONFIG_BT_NORMAL_HZ (48 * 1000000L) -//#define CONFIG_BT_CONNECT_HZ (48 * 1000000L) - -//*********************************************************************************// -// 配置结束 // -//*********************************************************************************// - -#endif - -#endif - - +#ifndef CONFIG_BOARD_AC6323A_DEMO_H +#define CONFIG_BOARD_AC6323A_DEMO_H + +#include "board_ac6323a_demo_global_build_cfg.h" + +#ifdef CONFIG_BOARD_AC6323A_DEMO + +#define CONFIG_SDFILE_ENABLE + +//*********************************************************************************// +// 配置开始 // +//*********************************************************************************// +#define ENABLE_THIS_MOUDLE 1 +#define DISABLE_THIS_MOUDLE 0 + +#define ENABLE 1 +#define DISABLE 0 + +#define NO_CONFIG_PORT (-1) + +//*********************************************************************************// +// UART配置 // +//*********************************************************************************// +#define TCFG_UART0_ENABLE ENABLE_THIS_MOUDLE //串口打印模块使能 +#define TCFG_UART0_RX_PORT NO_CONFIG_PORT //串口接收脚配置(用于打印可以选择NO_CONFIG_PORT) +#define TCFG_UART0_TX_PORT IO_PORTA_01 //串口发送脚配置 +#define TCFG_UART0_BAUDRATE 1000000 //串口波特率配置 + +//*********************************************************************************// +// USB 配置 // +//*********************************************************************************// +#define TCFG_PC_ENABLE DISABLE_THIS_MOUDLE //PC模块使能 +#define TCFG_UDISK_ENABLE DISABLE_THIS_MOUDLE //U盘模块使能 +#define TCFG_HID_HOST_ENABLE DISABLE_THIS_MOUDLE//ENABLE_THIS_MOUDLE //游戏盒子模式 +#define TCFG_ADB_ENABLE DISABLE_THIS_MOUDLE//ENABLE_THIS_MOUDLE +#define TCFG_AOA_ENABLE DISABLE_THIS_MOUDLE//ENABLE_THIS_MOUDLE + +#define TCFG_OTG_USB_DEV_EN (BIT(0) | BIT(1))//USB0 = BIT(0) USB1 = BIT(1) +//*********************************************************************************// +// IIC配置 // +//*********************************************************************************// +/*软件IIC设置*/ +#define TCFG_SW_I2C0_CLK_PORT IO_PORTA_09 //软件IIC CLK脚选择 +#define TCFG_SW_I2C0_DAT_PORT IO_PORTA_10 //软件IIC DAT脚选择 +#define TCFG_SW_I2C0_DELAY_CNT 50 //IIC延时参数,影响通讯时钟频率 + +/*硬件IIC端口选择 + SCL SDA + 'A': IO_PORT_DP IO_PORT_DM + 'B': IO_PORTA_09 IO_PORTA_10 + 'C': IO_PORTA_07 IO_PORTA_08 + 'D': IO_PORTA_05 IO_PORTA_06 + */ +#define TCFG_HW_I2C0_PORTS 'B' +#define TCFG_HW_I2C0_CLK 100000 //硬件IIC波特率 + +//*********************************************************************************// +// 硬件SPI 配置 // +//*********************************************************************************// +#define TCFG_HW_SPI1_ENABLE ENABLE_THIS_MOUDLE +//A组IO: DI: PB2 DO: PB1 CLK: PB0 +//B组IO: DI: PC3 DO: PC5 CLK: PC4 +#define TCFG_HW_SPI1_PORT 'A' +#define TCFG_HW_SPI1_BAUD 2000000L +#define TCFG_HW_SPI1_MODE SPI_MODE_BIDIR_1BIT +#define TCFG_HW_SPI1_ROLE SPI_ROLE_MASTER + +#define TCFG_HW_SPI2_ENABLE ENABLE_THIS_MOUDLE +//A组IO: DI: PB8 DO: PB10 CLK: PB9 +//B组IO: DI: PA13 DO: DM CLK: DP +#define TCFG_HW_SPI2_PORT 'A' +#define TCFG_HW_SPI2_BAUD 2000000L +#define TCFG_HW_SPI2_MODE SPI_MODE_BIDIR_1BIT +#define TCFG_HW_SPI2_ROLE SPI_ROLE_MASTER + +//*********************************************************************************// +// FLASH 配置 // +//*********************************************************************************// +#define TCFG_CODE_FLASH_ENABLE DISABLE_THIS_MOUDLE +#define TCFG_FLASH_DEV_SPI_HW_NUM 1// 1: SPI1 2: SPI2 +#define TCFG_FLASH_DEV_SPI_CS_PORT IO_PORTB_06 +#define TCFG_NORFLASH_DEV_ENABLE DISABLE_THIS_MOUDLE + + +//*********************************************************************************// +// key 配置 // +//*********************************************************************************// +#define KEY_NUM_MAX 10 +#define KEY_NUM 3 + +#define MULT_KEY_ENABLE DISABLE //是否使能组合按键消息, 使能后需要配置组合按键映射表 +//*********************************************************************************// +// iokey 配置 // +//*********************************************************************************// +#define TCFG_IOKEY_ENABLE DISABLE_THIS_MOUDLE //是否使能IO按键 + +#define TCFG_IOKEY_POWER_CONNECT_WAY ONE_PORT_TO_LOW //按键一端接低电平一端接IO + +#define TCFG_IOKEY_POWER_ONE_PORT IO_PORTA_01 //IO按键端口 + +#define TCFG_IOKEY_PREV_CONNECT_WAY ONE_PORT_TO_LOW //按键一端接低电平一端接IO +#define TCFG_IOKEY_PREV_ONE_PORT IO_PORTB_04 + +#define TCFG_IOKEY_NEXT_CONNECT_WAY ONE_PORT_TO_LOW //按键一端接低电平一端接IO +#define TCFG_IOKEY_NEXT_ONE_PORT IO_PORTB_05 + +//*********************************************************************************// +// adkey 配置 // +//*********************************************************************************// +#define TCFG_ADKEY_ENABLE DISABLE_THIS_MOUDLE //是否使能AD按键 +#define TCFG_ADKEY_PORT IO_PORTA_01 //AD按键端口(需要注意选择的IO口是否支持AD功能) +/*AD通道选择,需要和AD按键的端口相对应: + AD_CH_PA1 AD_CH_PA3 AD_CH_PA4 AD_CH_PA5 + AD_CH_PA9 AD_CH_PA1 AD_CH_PB1 AD_CH_PB4 + AD_CH_PB6 AD_CH_PB7 AD_CH_DP AD_CH_DM + AD_CH_PB2 +*/ +#define TCFG_ADKEY_AD_CHANNEL AD_CH_PA1 +#define TCFG_ADKEY_EXTERN_UP_ENABLE ENABLE_THIS_MOUDLE //是否使用外部上拉 + +#if TCFG_ADKEY_EXTERN_UP_ENABLE +#define R_UP 220 //22K,外部上拉阻值在此自行设置 +#else +#define R_UP 100 //10K,内部上拉默认10K +#endif + +//必须从小到大填电阻,没有则同VDDIO,填0x3ffL +#define TCFG_ADKEY_AD0 (0) //0R +#define TCFG_ADKEY_AD1 (0x3ffL * 30 / (30 + R_UP)) //3k +#define TCFG_ADKEY_AD2 (0x3ffL * 62 / (62 + R_UP)) //6.2k +#define TCFG_ADKEY_AD3 (0x3ffL * 91 / (91 + R_UP)) //9.1k +#define TCFG_ADKEY_AD4 (0x3ffL * 150 / (150 + R_UP)) //15k +#define TCFG_ADKEY_AD5 (0x3ffL * 240 / (240 + R_UP)) //24k +#define TCFG_ADKEY_AD6 (0x3ffL * 330 / (330 + R_UP)) //33k +#define TCFG_ADKEY_AD7 (0x3ffL * 510 / (510 + R_UP)) //51k +#define TCFG_ADKEY_AD8 (0x3ffL * 1000 / (1000 + R_UP)) //100k +#define TCFG_ADKEY_AD9 (0x3ffL * 2200 / (2200 + R_UP)) //220k +#define TCFG_ADKEY_VDDIO (0x3ffL) + +#define TCFG_ADKEY_VOLTAGE0 ((TCFG_ADKEY_AD0 + TCFG_ADKEY_AD1) / 2) +#define TCFG_ADKEY_VOLTAGE1 ((TCFG_ADKEY_AD1 + TCFG_ADKEY_AD2) / 2) +#define TCFG_ADKEY_VOLTAGE2 ((TCFG_ADKEY_AD2 + TCFG_ADKEY_AD3) / 2) +#define TCFG_ADKEY_VOLTAGE3 ((TCFG_ADKEY_AD3 + TCFG_ADKEY_AD4) / 2) +#define TCFG_ADKEY_VOLTAGE4 ((TCFG_ADKEY_AD4 + TCFG_ADKEY_AD5) / 2) +#define TCFG_ADKEY_VOLTAGE5 ((TCFG_ADKEY_AD5 + TCFG_ADKEY_AD6) / 2) +#define TCFG_ADKEY_VOLTAGE6 ((TCFG_ADKEY_AD6 + TCFG_ADKEY_AD7) / 2) +#define TCFG_ADKEY_VOLTAGE7 ((TCFG_ADKEY_AD7 + TCFG_ADKEY_AD8) / 2) +#define TCFG_ADKEY_VOLTAGE8 ((TCFG_ADKEY_AD8 + TCFG_ADKEY_AD9) / 2) +#define TCFG_ADKEY_VOLTAGE9 ((TCFG_ADKEY_AD9 + TCFG_ADKEY_VDDIO) / 2) + +#define TCFG_ADKEY_VALUE0 0 +#define TCFG_ADKEY_VALUE1 1 +#define TCFG_ADKEY_VALUE2 2 +#define TCFG_ADKEY_VALUE3 3 +#define TCFG_ADKEY_VALUE4 4 +#define TCFG_ADKEY_VALUE5 5 +#define TCFG_ADKEY_VALUE6 6 +#define TCFG_ADKEY_VALUE7 7 +#define TCFG_ADKEY_VALUE8 8 +#define TCFG_ADKEY_VALUE9 9 + +//*********************************************************************************// +// Audio配置 // +//*********************************************************************************// +#ifdef CONFIG_LITE_AUDIO +#define TCFG_AUDIO_ENABLE DISABLE +#if TCFG_AUDIO_ENABLE +#define TCFG_DEC_USBC_ENABLE DISABLE +#define TCFG_ENC_USBC_ENABLE DISABLE +#define TCFG_DEC_LC3_ENABLE DISABLE +#define TCFG_ENC_LC3_ENABLE DISABLE + + +//lc3 参数配置 +#if (TCFG_ENC_LC3_ENABLE || TCFG_DEC_LC3_ENABLE) +#define LC3_CODING_SAMPLERATE 16000 //lc3 编码的采样率 +#define LC3_CODING_FRAME_LEN 50 //帧长度,只支持25,50,100 +#define LC3_CODING_CHANNEL 1 //lc3 的通道数 +#endif + +#endif + +#endif +//*********************************************************************************// +// irkey 配置 // +//*********************************************************************************// +#define TCFG_IRKEY_ENABLE DISABLE_THIS_MOUDLE//是否使能AD按键 +#define TCFG_IRKEY_PORT IO_PORTA_08 //IR按键端口 + +//*********************************************************************************// +// tocuh key 配置 // +//*********************************************************************************// +#define TCFG_LP_TOUCH_KEY_ENABLE DISABLE_THIS_MOUDLE //是否使能触摸按键 + +//*********************************************************************************// +// RTC_ALARM配置 // +//*********************************************************************************// +#define TCFG_RTC_ALARM_ENABLE ENABLE_THIS_MOUDLE + +//*********************************************************************************// +// 充电仓配置(不支持) // +//*********************************************************************************// +#define TCFG_TEST_BOX_ENABLE DISABLE_THIS_MOUDLE +#define TCFG_CHARGESTORE_PORT IO_PORTP_00 +#define TCFG_CHARGESTORE_UART_ID IRQ_UART1_IDX + +//*********************************************************************************// +// 充电参数配置 // +//*********************************************************************************// +//是否支持芯片内置充电 +#define TCFG_CHARGE_ENABLE ENABLE +//是否支持开机充电 +#define TCFG_CHARGE_POWERON_ENABLE ENABLE +//是否支持拔出充电自动开机功能 +#define TCFG_CHARGE_OFF_POWERON_NE ENABLE +/* +充电截止电压可选配置: + CHARGE_FULL_V_3962 CHARGE_FULL_V_4002 CHARGE_FULL_V_4044 CHARGE_FULL_V_4086 + CHARGE_FULL_V_4130 CHARGE_FULL_V_4175 CHARGE_FULL_V_4222 CHARGE_FULL_V_4270 + CHARGE_FULL_V_4308 CHARGE_FULL_V_4349 CHARGE_FULL_V_4391 CHARGE_FULL_V_4434 + CHARGE_FULL_V_4472 CHARGE_FULL_V_4517 CHARGE_FULL_V_4564 CHARGE_FULL_V_4611 +*/ +#define TCFG_CHARGE_FULL_V CHARGE_FULL_V_4175 +/* +充电截止电流可选配置: + CHARGE_FULL_mA_2 CHARGE_FULL_mA_5 CHARGE_FULL_mA_7 CHARGE_FULL_mA_10 + CHARGE_FULL_mA_15 CHARGE_FULL_mA_20 CHARGE_FULL_mA_25 CHARGE_FULL_mA_30 +*/ +#define TCFG_CHARGE_FULL_MA CHARGE_FULL_mA_7 +/* +充电电流可选配置: + CHARGE_mA_20 CHARGE_mA_30 CHARGE_mA_40 CHARGE_mA_50 + CHARGE_mA_60 CHARGE_mA_70 CHARGE_mA_80 CHARGE_mA_90 + CHARGE_mA_100 CHARGE_mA_110 CHARGE_mA_120 CHARGE_mA_140 + CHARGE_mA_160 CHARGE_mA_180 CHARGE_mA_200 CHARGE_mA_220 + */ +#define TCFG_CHARGE_MA CHARGE_mA_30 + +//*********************************************************************************// +// LED 配置 // +//*********************************************************************************// +#define TCFG_PWMLED_ENABLE DISABLE_THIS_MOUDLE //是否支持PMW LED推灯模块 +#define TCFG_PWMLED_IOMODE LED_ONE_IO_MODE //LED模式,单IO还是两个IO推灯 +#define TCFG_PWMLED_PIN IO_PORTB_06 //LED使用的IO口 +//*********************************************************************************// +// 时钟配置 // +//*********************************************************************************// +#define TCFG_CLOCK_SYS_SRC SYS_CLOCK_INPUT_PLL_BT_OSC //系统时钟源选择 +#define TCFG_CLOCK_SYS_HZ 24000000 //系统时钟设置 +#define TCFG_CLOCK_OSC_HZ 24000000 //外界晶振频率设置 +/* #define TCFG_CLOCK_MODE CLOCK_MODE_USR//CLOCK_MODE_ADAPTIVE */ +#define TCFG_CLOCK_MODE CLOCK_MODE_ADAPTIVE + +//*********************************************************************************// +// 低功耗配置 // +//*********************************************************************************// +#define TCFG_LOWPOWER_POWER_SEL PWR_LDO15 +// #define TCFG_LOWPOWER_POWER_SEL PWR_LDO15 PWR_DCDC15 //电源模式设置,可选DCDC和LDO +#define TCFG_LOWPOWER_BTOSC_DISABLE 0 //低功耗模式下BTOSC是否保持 +#define TCFG_LOWPOWER_LOWPOWER_SEL 0 //SLEEP_EN //SNIFF状态下芯片是否进入powerdown +/*强VDDIO等级配置,可选: + VDDIOM_VOL_20V VDDIOM_VOL_22V VDDIOM_VOL_24V VDDIOM_VOL_26V + VDDIOM_VOL_30V VDDIOM_VOL_30V VDDIOM_VOL_32V VDDIOM_VOL_36V*/ +#define TCFG_LOWPOWER_VDDIOM_LEVEL VDDIOM_VOL_30V +/*弱VDDIO等级配置,可选: + VDDIOW_VOL_21V VDDIOW_VOL_24V VDDIOW_VOL_28V VDDIOW_VOL_32V*/ +#define TCFG_LOWPOWER_VDDIOW_LEVEL VDDIOW_VOL_28V //弱VDDIO等级配置 +#define TCFG_LOWPOWER_OSC_TYPE OSC_TYPE_LRC +#define TCFG_VD13_CAP_EN 1 + + +//*********************************************************************************// +// g-sensor配置 // +//*********************************************************************************// +#define TCFG_GSENSOR_ENABLE 0 //gSensor使能 +#define TCFG_DA230_EN 0 +#define TCFG_SC7A20_EN 0 +#define TCFG_STK8321_EN 0 +#define TCFG_GSENOR_USER_IIC_TYPE 0 //0:软件IIC 1:硬件IIC + +//*********************************************************************************// +// 系统配置 // +//*********************************************************************************// +#define TCFG_AUTO_SHUT_DOWN_TIME 0 //没有蓝牙连接自动关机时间 +#if (TCFG_LOWPOWER_POWER_SEL == PWR_DCDC15) +#define TCFG_SYS_LVD_EN 1 //dcdc模式电压低于2.4v的时候切为LDO模式,需要开启电量检测 +#else +#define TCFG_SYS_LVD_EN 1 //电量检测使能 +#endif +#define TCFG_POWER_ON_NEED_KEY 0 //是否需要按按键开机配置 +#define TCFG_HID_AUTO_SHUTDOWN_TIME (0 * 60) //HID无操作自动关机(单位:秒) + +//*********************************************************************************// +// 蓝牙配置 // +//*********************************************************************************// +#define TCFG_USER_TWS_ENABLE 0 //tws功能使能 +#define TCFG_USER_BLE_ENABLE 1 //BLE功能使能,---使能后,请配置TCFG_BLE_DEMO_SELECT选择DEMO例子 +#define TCFG_USER_EDR_ENABLE 0 //EDR功能使能 + +#define USER_SUPPORT_PROFILE_SPP 0 +#define USER_SUPPORT_PROFILE_HFP 0 +#define USER_SUPPORT_PROFILE_A2DP 0 +#define USER_SUPPORT_PROFILE_AVCTP 0 +#define USER_SUPPORT_PROFILE_HID 0 +#define USER_SUPPORT_PROFILE_PNP 0 +#define USER_SUPPORT_PROFILE_PBAP 0 + + +#if(TCFG_USER_TWS_ENABLE || TCFG_USER_BLE_ENABLE) +#define TCFG_BD_NUM 1 //连接设备个数配置 +#define TCFG_AUTO_STOP_PAGE_SCAN_TIME 0 //配置一拖二第一台连接后自动关闭PAGE SCAN的时间(单位分钟) +#else +#define TCFG_BD_NUM 1 //连接设备个数配置 +#define TCFG_AUTO_STOP_PAGE_SCAN_TIME 0 //配置一拖二第一台连接后自动关闭PAGE SCAN的时间(单位分钟) +#endif + +#define BT_INBAND_RINGTONE 0 //是否播放手机自带来电铃声 +#define BT_PHONE_NUMBER 0 //是否播放来电报号 +#define BT_SUPPORT_DISPLAY_BAT 0 //是否使能电量检测 +#define BT_SUPPORT_MUSIC_VOL_SYNC 0 //是否使能音量同步 + + +//*********************************************************************************// +// 电源切换配置 // +//*********************************************************************************// + +#define CONFIG_PHONE_CALL_USE_LDO15 1 + +//*********************************************************************************// +// 时钟配置 // +//*********************************************************************************// + +#define CONFIG_BT_NORMAL_HZ (48 * 1000000L) +//#define CONFIG_BT_CONNECT_HZ (48 * 1000000L) + +//*********************************************************************************// +// 配置结束 // +//*********************************************************************************// + +#endif + +#endif + + diff --git a/fw-AC63_BT_SDK/apps/spp_and_le/examples/trans_data/ble_trans.c b/fw-AC63_BT_SDK/apps/spp_and_le/examples/trans_data/ble_trans.c index 3dae1fb..5201b41 100644 --- a/fw-AC63_BT_SDK/apps/spp_and_le/examples/trans_data/ble_trans.c +++ b/fw-AC63_BT_SDK/apps/spp_and_le/examples/trans_data/ble_trans.c @@ -1,1116 +1,1119 @@ -/********************************************************************************************* - * Filename : .c - - * Description : - - * Author : JM - - * Email : zh-jieli.com - - * Last modifiled : 2017-01-17 11:14 - - * Copyright:(c)JIELI 2011-2016 @ , All Rights Reserved. -*********************************************************************************************/ -#include "system/app_core.h" -#include "system/includes.h" - -#include "app_config.h" -#include "app_action.h" - -#include "btstack/btstack_task.h" -#include "btstack/bluetooth.h" -#include "user_cfg.h" -#include "vm.h" -#include "btcontroller_modules.h" -#include "bt_common.h" -#include "3th_profile_api.h" -#include "le_common.h" -#include "rcsp_bluetooth.h" -#include "JL_rcsp_api.h" -#include "custom_cfg.h" -#include "btstack/btstack_event.h" -#include "gatt_common/le_gatt_common.h" -#include "ble_trans.h" -#include "ble_trans_profile.h" -#include "app_temperature.h" -#if CONFIG_APP_SPP_LE - -#if LE_DEBUG_PRINT_EN -#define log_info(x, ...) printf("[BLE_TRANS]" x " ", ## __VA_ARGS__) -#define log_info_hexdump put_buf - -#else -#define log_info(...) -#define log_info_hexdump(...) -#endif - -/* - 打开流控使能后,确定使能接口 att_server_flow_enable 被调用 - 然后使用过程 通过接口 att_server_flow_hold 来控制流控开关 - 注意:流控只能控制对方使用带响应READ/WRITE等命令方式 - 例如:ATT_WRITE_REQUEST = 0x12 - */ -#define ATT_DATA_RECIEVT_FLOW 0//流控功能使能 - - -//测试NRF连接,工具不会主动发起交换流程,需要手动操作; 但设备可配置主动发起MTU长度交换请求 -#define ATT_MTU_REQUEST_ENALBE 0 /*配置1,就是设备端主动发起交换*/ - -//检测对方的系统类型,ios or 非ios -#define ATT_CHECK_REMOTE_REQUEST_ENALBE 0 /*配置1,就是设备端主动检查*/ - -//ATT发送的包长, note: 23 <=need >= MTU -#define ATT_LOCAL_MTU_SIZE (512) /*一般是主机发起交换,如果主机没有发起,设备端也可以主动发起(ATT_MTU_REQUEST_ENALBE set 1)*/ - -//ATT缓存的buffer支持缓存数据包个数 -#define ATT_PACKET_NUMS_MAX (2) - -//ATT缓存的buffer大小, note: need >= 23,可修改 -#define ATT_SEND_CBUF_SIZE (ATT_PACKET_NUMS_MAX * (ATT_PACKET_HEAD_SIZE + ATT_LOCAL_MTU_SIZE)) - -// 广播周期 (unit:0.625ms) -#define ADV_INTERVAL_MIN (160 * 5)// - -#define TEST_TRANS_CHANNEL_DATA 0 /*测试记录收发数据速度*/ -#define TEST_TRANS_NOTIFY_HANDLE ATT_CHARACTERISTIC_ae02_01_VALUE_HANDLE /*主动发送hanlde,为空则不测试发数*/ -#if CONFIG_BLE_HIGH_SPEED -#define TEST_TRANS_TIMER_MS 5 -#else -#define TEST_TRANS_TIMER_MS 500 -#endif -#define TEST_PAYLOAD_LEN (244)/*发送配PDU长度是251的包*/ - -static u32 trans_recieve_test_count; -static u32 trans_send_test_count; - -//--------------- -//连接参数更新请求设置 -//是否使能参数请求更新,0--disable, 1--enable -static uint8_t trans_connection_update_enable = 1; ///0--disable, 1--enable - -//请求的参数数组表,排队方式请求;哪组对方接受就用那组 -static const struct conn_update_param_t trans_connection_param_table[] = { - -#if CONFIG_BLE_HIGH_SPEED - {6, 12, 10, 400},// ios fast -#endif - - {16, 24, 10, 600},//11 - {12, 28, 10, 600},//3.7 - {8, 20, 10, 600}, -}; - -//共可用的参数组数 -#define CONN_PARAM_TABLE_CNT (sizeof(trans_connection_param_table)/sizeof(struct conn_update_param_t)) - -#define EIR_TAG_STRING 0xd6, 0x05, 0x08, 0x00, 'J', 'L', 'A', 'I', 'S', 'D','K' -static const char user_tag_string[] = {EIR_TAG_STRING}; - -//定义的产品信息,for test -#define PNP_VID_SOURCE 0x02 -#define PNP_VID 0x05ac //0x05d6 -#define PNP_PID 0x022C // -#define PNP_PID_VERSION 0x011b //1.1.11 - -static const u8 trans_PNP_ID[] = {PNP_VID_SOURCE, PNP_VID & 0xFF, PNP_VID >> 8, PNP_PID & 0xFF, PNP_PID >> 8, PNP_PID_VERSION & 0xFF, PNP_PID_VERSION >> 8}; - -static u8 trans_adv_data[ADV_RSP_PACKET_MAX];//max is 31 -static u8 trans_scan_rsp_data[ADV_RSP_PACKET_MAX];//max is 31 -static u8 trans_test_read_write_buf[4]; -static u16 trans_con_handle; -static adv_cfg_t trans_server_adv_config; -//------------------------------------------------------------------------------------- -static uint16_t trans_att_read_callback(hci_con_handle_t connection_handle, uint16_t att_handle, uint16_t offset, uint8_t *buffer, uint16_t buffer_size); -static int trans_att_write_callback(hci_con_handle_t connection_handle, uint16_t att_handle, uint16_t transaction_mode, uint16_t offset, uint8_t *buffer, uint16_t buffer_size); -static int trans_event_packet_handler(int event, u8 *packet, u16 size, u8 *ext_param); -extern void uart_db_regiest_recieve_callback(void *rx_cb); -//------------------------------------------------------------------------------------- - -//------------------------------------------------------------------------------------- -//输入passkey 加密 -#define PASSKEY_ENABLE 0 - -static const sm_cfg_t trans_sm_init_config = { - .slave_security_auto_req = 0, - .slave_set_wait_security = 0, - -#if PASSKEY_ENABLE - .io_capabilities = IO_CAPABILITY_DISPLAY_ONLY, -#else - .io_capabilities = IO_CAPABILITY_NO_INPUT_NO_OUTPUT, -#endif - - .authentication_req_flags = SM_AUTHREQ_BONDING | SM_AUTHREQ_MITM_PROTECTION, - .min_key_size = 7, - .max_key_size = 16, - .sm_cb_packet_handler = NULL, -}; - -const gatt_server_cfg_t trans_server_init_cfg = { - .att_read_cb = &trans_att_read_callback, - .att_write_cb = &trans_att_write_callback, - .event_packet_handler = &trans_event_packet_handler, -}; - -static gatt_ctrl_t trans_gatt_control_block = { - //public - .mtu_size = ATT_LOCAL_MTU_SIZE, - .cbuffer_size = ATT_SEND_CBUF_SIZE, - .multi_dev_flag = 0, - - //config -#if CONFIG_BT_GATT_SERVER_NUM - .server_config = &trans_server_init_cfg, -#else - .server_config = NULL, -#endif - -#if CONFIG_BT_GATT_CLIENT_NUM - .client_config = &trans_client_init_cfg, -#else - .client_config = NULL, -#endif - -#if CONFIG_BT_SM_SUPPORT_ENABLE - .sm_config = &trans_sm_init_config, -#else - .sm_config = NULL, -#endif - //cbk,event handle - .hci_cb_packet_handler = NULL, -}; - - -#define TEST_AUDIO_DATA_UPLOAD 0//测试文件上传 - -#if TEST_AUDIO_DATA_UPLOAD -static const u8 test_audio_data_file[1024] = { - 1, 2, 3, 4, 5, 6, 7, 8, 9 -}; - -/*************************************************************************************************/ -/*! - * \brief 测试上传文件 - * - * \param [in] - * - * \return - * - * \note - */ -/*************************************************************************************************/ -#define AUDIO_ONE_PACKET_LEN 128 -static void trans_test_send_audio_data(int init_flag) -{ - static u32 send_pt = 0; - static u32 start_flag = 0; - - if (!trans_con_handle) { - return; - } - - if (init_flag) { - log_info("audio send init\n"); - send_pt = 0; - start_flag = 1; - } - - if (!start_flag) { - return; - } - - u32 file_size = sizeof(test_audio_data_file); - u8 *file_ptr = test_audio_data_file; - - if (send_pt >= file_size) { - log_info("audio send Complete\n"); - start_flag = 0; - return; - } - - u32 send_len = file_size - send_pt; - if (send_len > AUDIO_ONE_PACKET_LEN) { - send_len = AUDIO_ONE_PACKET_LEN; - } - - while (1) { - if (ble_comm_cbuffer_vaild_len(trans_con_handle) > send_len) { - log_info("audio send %08x\n", send_pt); - if (ble_comm_att_send_data(trans_con_handle, ATT_CHARACTERISTIC_ae3c_01_VALUE_HANDLE, &file_ptr[send_pt], send_len, ATT_OP_AUTO_READ_CCC)) { - log_info("audio send fail!\n"); - break; - } else { - send_pt += send_len; - } - } else { - break; - } - } -} - -#endif - -/*************************************************************************************************/ -/*! - * \brief 串口接收转发到BLE - * - * \param [in] - * - * \return - * - * \note - */ -/*************************************************************************************************/ -static void trans_uart_rx_to_ble(u8 *packet, u32 size) -{ - if (trans_con_handle && ble_comm_att_check_send(trans_con_handle, size) && - ble_gatt_server_characteristic_ccc_get(trans_con_handle, ATT_CHARACTERISTIC_ae02_01_CLIENT_CONFIGURATION_HANDLE)) { - ble_comm_att_send_data(trans_con_handle, ATT_CHARACTERISTIC_ae02_01_VALUE_HANDLE, packet, size, ATT_OP_AUTO_READ_CCC); - } else { - log_info("drop uart data!!!\n"); - } -} - -/*************************************************************************************************/ -/*! - * \brief 发送请求连接参数表 - * - * \param [in] - * - * \return - * - * \note - */ -/*************************************************************************************************/ -static void trans_send_connetion_updata_deal(u16 conn_handle) -{ - if (trans_connection_update_enable) { - if (0 == ble_gatt_server_connetion_update_request(conn_handle, trans_connection_param_table, CONN_PARAM_TABLE_CNT)) { - trans_connection_update_enable = 0; - } - } -} - -/*************************************************************************************************/ -/*! - * \brief 回连状态,使能所有profile - * - * \param [in] - * - * \return - * - * \note 配对绑定的方式,主机回连不是在使能server的通知开关,需要自己打开 - */ -/*************************************************************************************************/ -static void trans_resume_all_ccc_enable(u16 conn_handle, u8 update_request) -{ - log_info("resume_all_ccc_enable\n"); - -#if RCSP_BTMATE_EN - ble_gatt_server_characteristic_ccc_set(conn_handle, ATT_CHARACTERISTIC_ae02_02_CLIENT_CONFIGURATION_HANDLE, ATT_OP_NOTIFY); -#endif - ble_gatt_server_characteristic_ccc_set(conn_handle, ATT_CHARACTERISTIC_ae02_01_CLIENT_CONFIGURATION_HANDLE, ATT_OP_NOTIFY); - ble_gatt_server_characteristic_ccc_set(conn_handle, ATT_CHARACTERISTIC_ae04_01_CLIENT_CONFIGURATION_HANDLE, ATT_OP_NOTIFY); - ble_gatt_server_characteristic_ccc_set(conn_handle, ATT_CHARACTERISTIC_ae05_01_CLIENT_CONFIGURATION_HANDLE, ATT_OP_INDICATE); - ble_gatt_server_characteristic_ccc_set(conn_handle, ATT_CHARACTERISTIC_ae3c_01_CLIENT_CONFIGURATION_HANDLE, ATT_OP_NOTIFY); - - if (update_request) { - trans_send_connetion_updata_deal(conn_handle); - } -} - -/*************************************************************************************************/ -/*! - * \brief 反馈检查对方的操作系统 - * - * \param [in] - * - * \return - * - * \note 参考识别手机系统 - */ -/*************************************************************************************************/ -static void trans_check_remote_result(u16 con_handle, remote_type_e remote_type) -{ - char *str; - if (REMOTE_TYPE_IOS == remote_type) { - str = "is"; - } else { - str = "not"; - } - - log_info("trans_check %02x:remote_type= %02x, %s ios", con_handle, remote_type, str); -} - -/*************************************************************************************************/ -/*! - * \brief 处理gatt 返回的事件(hci && gatt) - * - * \param [in] - * - * \return - * - * \note - */ -/*************************************************************************************************/ -static int trans_event_packet_handler(int event, u8 *packet, u16 size, u8 *ext_param) -{ - /* log_info("event: %02x,size= %d\n",event,size); */ - - switch (event) { - - case GATT_COMM_EVENT_CAN_SEND_NOW: -#if TEST_AUDIO_DATA_UPLOAD - trans_test_send_audio_data(0); -#endif - break; - - case GATT_COMM_EVENT_SERVER_INDICATION_COMPLETE: - log_info("INDICATION_COMPLETE:con_handle= %04x,att_handle= %04x\n", \ - little_endian_read_16(packet, 0), little_endian_read_16(packet, 2)); - break; - - - case GATT_COMM_EVENT_CONNECTION_COMPLETE: - trans_con_handle = little_endian_read_16(packet, 0); - trans_connection_update_enable = 1; - - log_info("connection_handle:%04x\n", little_endian_read_16(packet, 0)); - log_info("connection_handle:%04x, rssi= %d\n", trans_con_handle, ble_vendor_get_peer_rssi(trans_con_handle)); - log_info("peer_address_info:"); - put_buf(&ext_param[7], 7); - - log_info("con_interval = %d\n", little_endian_read_16(ext_param, 14 + 0)); - log_info("con_latency = %d\n", little_endian_read_16(ext_param, 14 + 2)); - log_info("cnn_timeout = %d\n", little_endian_read_16(ext_param, 14 + 4)); - -#if ATT_MTU_REQUEST_ENALBE - att_server_set_exchange_mtu(trans_con_handle);/*主动请求MTU长度交换*/ -#endif - -#if TCFG_UART0_RX_PORT != NO_CONFIG_PORT - //for test 串口数据直通到蓝牙 - uart_db_regiest_recieve_callback(trans_uart_rx_to_ble); -#endif - -#if CONFIG_BT_GATT_CLIENT_NUM -#if CONFIG_BT_SM_SUPPORT_ENABLE == 0 - trans_client_search_remote_profile(trans_con_handle); -#endif -#endif - -#if ATT_CHECK_REMOTE_REQUEST_ENALBE - att_server_set_check_remote(trans_con_handle, trans_check_remote_result); -#endif - break; - - case GATT_COMM_EVENT_DISCONNECT_COMPLETE: - log_info("disconnect_handle:%04x,reason= %02x\n", little_endian_read_16(packet, 0), packet[2]); - if (trans_con_handle == little_endian_read_16(packet, 0)) { -#if CONFIG_BT_GATT_CLIENT_NUM - trans_client_search_remote_stop(trans_con_handle); -#endif - trans_con_handle = 0; - } - break; - - case GATT_COMM_EVENT_ENCRYPTION_CHANGE: - log_info("ENCRYPTION_CHANGE:handle=%04x,state=%d,process =%d", little_endian_read_16(packet, 0), packet[2], packet[3]); - if (packet[3] == LINK_ENCRYPTION_RECONNECT) { - trans_resume_all_ccc_enable(little_endian_read_16(packet, 0), 1); - } - -#if CONFIG_BT_GATT_CLIENT_NUM - trans_client_search_remote_profile(trans_con_handle); -#endif - break; - - case GATT_COMM_EVENT_CONNECTION_UPDATE_COMPLETE: - log_info("conn_param update_complete:%04x\n", little_endian_read_16(packet, 0)); - log_info("update_interval = %d\n", little_endian_read_16(ext_param, 6 + 0)); - log_info("update_latency = %d\n", little_endian_read_16(ext_param, 6 + 2)); - log_info("update_timeout = %d\n", little_endian_read_16(ext_param, 6 + 4)); - break; - - case GATT_COMM_EVENT_CONNECTION_UPDATE_REQUEST_RESULT: - break; - - case GATT_COMM_EVENT_MTU_EXCHANGE_COMPLETE: - log_info("con_handle= %02x, ATT MTU = %u\n", little_endian_read_16(packet, 0), little_endian_read_16(packet, 2)); - break; - - case GATT_COMM_EVENT_SERVER_STATE: - log_info("server_state: handle=%02x,%02x\n", little_endian_read_16(packet, 1), packet[0]); - break; - - case GATT_COMM_EVENT_SM_PASSKEY_INPUT: { - u32 *key = little_endian_read_32(packet, 2); - *key = 888888; - r_printf("input_key:%6u\n", *key); - } - break; - - default: - break; - } - return 0; -} - - -/*************************************************************************************************/ -/*! - * \brief 处理client 读操作 - * - * \param [in] - * - * \return - * - * \note profile的读属性uuid 有配置 DYNAMIC 关键字,就有read_callback 回调 - */ -/*************************************************************************************************/ -// ATT Client Read Callback for Dynamic Data -// - if buffer == NULL, don't copy data, just return size of value -// - if buffer != NULL, copy data and return number bytes copied -// @param con_handle of hci le connection -// @param attribute_handle to be read -// @param offset defines start of attribute value -// @param buffer -// @param buffer_size -static uint16_t trans_att_read_callback(hci_con_handle_t connection_handle, uint16_t att_handle, uint16_t offset, uint8_t *buffer, uint16_t buffer_size) -{ - uint16_t att_value_len = 0; - uint16_t handle = att_handle; - - log_info("read_callback,conn_handle =%04x, handle=%04x,buffer=%08x\n", connection_handle, handle, (u32)buffer); - - switch (handle) { - case ATT_CHARACTERISTIC_2a00_01_VALUE_HANDLE: { - char *gap_name = ble_comm_get_gap_name(); - att_value_len = strlen(gap_name); - - if ((offset >= att_value_len) || (offset + buffer_size) > att_value_len) { - break; - } - - if (buffer) { - memcpy(buffer, &gap_name[offset], buffer_size); - att_value_len = buffer_size; - log_info("\n------read gap_name: %s\n", gap_name); - } - } - break; - - case ATT_CHARACTERISTIC_ae10_01_VALUE_HANDLE: - att_value_len = sizeof(trans_test_read_write_buf); - if ((offset >= att_value_len) || (offset + buffer_size) > att_value_len) { - break; - } - - if (buffer) { - memcpy(buffer, &trans_test_read_write_buf[offset], buffer_size); - att_value_len = buffer_size; - } - break; - - case ATT_CHARACTERISTIC_ae04_01_CLIENT_CONFIGURATION_HANDLE: - case ATT_CHARACTERISTIC_ae02_01_CLIENT_CONFIGURATION_HANDLE: - case ATT_CHARACTERISTIC_ae05_01_CLIENT_CONFIGURATION_HANDLE: - case ATT_CHARACTERISTIC_ae3c_01_CLIENT_CONFIGURATION_HANDLE: - case ATT_CHARACTERISTIC_2a05_01_CLIENT_CONFIGURATION_HANDLE: - if (buffer) { - buffer[0] = ble_gatt_server_characteristic_ccc_get(connection_handle, handle); - buffer[1] = 0; - } - att_value_len = 2; - break; - - case ATT_CHARACTERISTIC_2a50_01_VALUE_HANDLE: - log_info("read PnP_ID\n"); - att_value_len = sizeof(trans_PNP_ID); - if ((offset >= att_value_len) || (offset + buffer_size) > att_value_len) { - break; - } - if (buffer) { - memcpy(buffer, &trans_PNP_ID[offset], buffer_size); - att_value_len = buffer_size; - } - break; - - default: - break; - } - - log_info("att_value_len= %d\n", att_value_len); - return att_value_len; -} - - -/*************************************************************************************************/ -/*! - * \brief 处理client write操作 - * - * \param [in] - * - * \return - * - * \note profile的写属性uuid 有配置 DYNAMIC 关键字,就有write_callback 回调 - */ -/*************************************************************************************************/ -// ATT Client Write Callback for Dynamic Data -// @param con_handle of hci le connection -// @param attribute_handle to be written -// @param transaction - ATT_TRANSACTION_MODE_NONE for regular writes, ATT_TRANSACTION_MODE_ACTIVE for prepared writes and ATT_TRANSACTION_MODE_EXECUTE -// @param offset into the value - used for queued writes and long attributes -// @param buffer -// @param buffer_size -// @param signature used for signed write commmands -// @returns 0 if write was ok, ATT_ERROR_PREPARE_QUEUE_FULL if no space in queue, ATT_ERROR_INVALID_OFFSET if offset is larger than max buffer - -static int trans_att_write_callback(hci_con_handle_t connection_handle, uint16_t att_handle, uint16_t transaction_mode, uint16_t offset, uint8_t *buffer, uint16_t buffer_size) -{ - int result = 0; - u16 tmp16; - - u16 handle = att_handle; - -#if !TEST_TRANS_CHANNEL_DATA - log_info("write_callback,conn_handle =%04x, handle =%04x,size =%d\n", connection_handle, handle, buffer_size); -#endif - - switch (handle) { - - case ATT_CHARACTERISTIC_2a00_01_VALUE_HANDLE: - break; - - case ATT_CHARACTERISTIC_ae02_01_CLIENT_CONFIGURATION_HANDLE: - case ATT_CHARACTERISTIC_ae04_01_CLIENT_CONFIGURATION_HANDLE: - case ATT_CHARACTERISTIC_ae05_01_CLIENT_CONFIGURATION_HANDLE: - case ATT_CHARACTERISTIC_ae3c_01_CLIENT_CONFIGURATION_HANDLE: - case ATT_CHARACTERISTIC_2a05_01_CLIENT_CONFIGURATION_HANDLE: - trans_send_connetion_updata_deal(connection_handle); - log_info("\n------write ccc:%04x,%02x\n", handle, buffer[0]); - ble_gatt_server_characteristic_ccc_set(connection_handle, handle, buffer[0]); - break; - - case ATT_CHARACTERISTIC_ae10_01_VALUE_HANDLE: - tmp16 = sizeof(trans_test_read_write_buf); - if ((offset >= tmp16) || (offset + buffer_size) > tmp16) { - break; - } - memcpy(&trans_test_read_write_buf[offset], buffer, buffer_size); - log_info("\n-ae10_rx(%d):", buffer_size); - put_buf(buffer, buffer_size); - break; - - case ATT_CHARACTERISTIC_ae01_01_VALUE_HANDLE: - -#if TEST_TRANS_CHANNEL_DATA - /* putchar('R'); */ - trans_recieve_test_count += buffer_size; - break; -#endif - - log_info("\n-ae01_rx(%d):", buffer_size); - put_buf(buffer, buffer_size); - ble_receive_callback(buffer,buffer_size); - //收发测试,自动发送收到的数据;for test - //helloyifa - #if 0 - if (ble_comm_att_check_send(connection_handle, buffer_size) && - ble_gatt_server_characteristic_ccc_get(trans_con_handle, ATT_CHARACTERISTIC_ae02_01_CLIENT_CONFIGURATION_HANDLE)) { - log_info("-loop send1\n"); - ble_comm_att_send_data(connection_handle, ATT_CHARACTERISTIC_ae02_01_VALUE_HANDLE, buffer, buffer_size, ATT_OP_AUTO_READ_CCC); - } - #endif - break; - - case ATT_CHARACTERISTIC_ae03_01_VALUE_HANDLE: - log_info("\n-ae03_rx(%d):", buffer_size); - put_buf(buffer, buffer_size); - - //收发测试,自动发送收到的数据;for test - if (ble_comm_att_check_send(connection_handle, buffer_size) && \ - ble_gatt_server_characteristic_ccc_get(trans_con_handle, ATT_CHARACTERISTIC_ae05_01_CLIENT_CONFIGURATION_HANDLE)) { - log_info("-loop send2\n"); - ble_comm_att_send_data(connection_handle, ATT_CHARACTERISTIC_ae05_01_VALUE_HANDLE, buffer, buffer_size, ATT_OP_AUTO_READ_CCC); - } - break; - -#if RCSP_BTMATE_EN - case ATT_CHARACTERISTIC_ae02_02_CLIENT_CONFIGURATION_HANDLE: - ble_op_latency_skip(connection_handle, 0xffff); // - ble_gatt_server_set_update_send(connection_handle, ATT_CHARACTERISTIC_ae02_02_VALUE_HANDLE, ATT_OP_AUTO_READ_CCC); -#endif - /* trans_send_connetion_updata_deal(connection_handle); */ - log_info("------write ccc:%04x,%02x\n", handle, buffer[0]); - ble_gatt_server_characteristic_ccc_set(connection_handle, handle, buffer[0]); - break; - -#if RCSP_BTMATE_EN - case ATT_CHARACTERISTIC_ae01_02_VALUE_HANDLE: - log_info("rcsp_read:%x\n", buffer_size); - ble_gatt_server_receive_update_data(NULL, buffer, buffer_size); - break; -#endif - - case ATT_CHARACTERISTIC_ae3b_01_VALUE_HANDLE: - log_info("\n-ae3b_rx(%d):", buffer_size); - put_buf(buffer, buffer_size); - -#if TEST_AUDIO_DATA_UPLOAD - if (0 == memcmp(buffer, "start", 5)) { - trans_test_send_audio_data(1); - } -#endif - break; - - default: - break; - } - return 0; -} - - -/*************************************************************************************************/ -/*! - * \brief 组织adv包数据,放入buff - * - * \param [in] - * - * \return - * - * \note - */ -/*************************************************************************************************/ -static u8 adv_name_ok = 0;//name 优先存放在ADV包 -static int trans_make_set_adv_data(void) -{ - u8 offset = 0; - u8 *buf = trans_adv_data; - -#if DOUBLE_BT_SAME_MAC - offset += make_eir_packet_val(&buf[offset], offset, HCI_EIR_DATATYPE_FLAGS, FLAGS_GENERAL_DISCOVERABLE_MODE | FLAGS_LE_AND_EDR_SAME_CONTROLLER, 1); -#else - offset += make_eir_packet_val(&buf[offset], offset, HCI_EIR_DATATYPE_FLAGS, FLAGS_GENERAL_DISCOVERABLE_MODE | FLAGS_EDR_NOT_SUPPORTED, 1); -#endif - - offset += make_eir_packet_val(&buf[offset], offset, HCI_EIR_DATATYPE_COMPLETE_16BIT_SERVICE_UUIDS, 0xAF30, 2); - - char *gap_name = ble_comm_get_gap_name(); - u8 name_len = strlen(gap_name); - u8 vaild_len = ADV_RSP_PACKET_MAX - (offset + 2); - if (name_len < vaild_len) { - offset += make_eir_packet_data(&buf[offset], offset, HCI_EIR_DATATYPE_COMPLETE_LOCAL_NAME, (void *)gap_name, name_len); - adv_name_ok = 1; - } else { - adv_name_ok = 0; - } - - log_info("trans_adv_data @@ (%d):", offset); - //FF - //BBOOEEb 2字节体温 2字节物温 2字节环温 1字节电量 - u8 ff_temp_data[7] = {0}; - offset += make_eir_packet_data(&buf[offset], offset, HCI_EIR_DATATYPE_MANUFACTURER_SPECIFIC_DATA, (void *)ff_temp_data, sizeof(ff_temp_data)); - if (offset > ADV_RSP_PACKET_MAX) { - puts("***trans_adv_data overflow!!!!!!\n"); - return -1; - } - log_info("trans_adv_data(%d):", offset); - log_info_hexdump(buf, offset); - trans_server_adv_config.adv_data_len = offset; - trans_server_adv_config.adv_data = trans_adv_data; - return 0; -} - -int trans_client_adv_data_set_ff(u8*data, int len) -{ - //putchar('L'); - //put_u8hex(adv_cnt); - //ble_module_enable(0); - ble_op_adv_enable(0); - u8 offset = 0; - u8 *buf = trans_adv_data; - -#if DOUBLE_BT_SAME_MAC - offset += make_eir_packet_val(&buf[offset], offset, HCI_EIR_DATATYPE_FLAGS, FLAGS_GENERAL_DISCOVERABLE_MODE | FLAGS_LE_AND_EDR_SAME_CONTROLLER, 1); -#else - offset += make_eir_packet_val(&buf[offset], offset, HCI_EIR_DATATYPE_FLAGS, FLAGS_GENERAL_DISCOVERABLE_MODE | FLAGS_EDR_NOT_SUPPORTED, 1); -#endif - - offset += make_eir_packet_val(&buf[offset], offset, HCI_EIR_DATATYPE_COMPLETE_16BIT_SERVICE_UUIDS, 0xAF30, 2); - - char *gap_name = ble_comm_get_gap_name(); - u8 name_len = strlen(gap_name); - u8 vaild_len = ADV_RSP_PACKET_MAX - (offset + 2); - if (name_len < vaild_len) { - offset += make_eir_packet_data(&buf[offset], offset, HCI_EIR_DATATYPE_COMPLETE_LOCAL_NAME, (void *)gap_name, name_len); - adv_name_ok = 1; - } else { - adv_name_ok = 0; - } - //FF - u8 ff_temp_data[5] = {0}; - offset += make_eir_packet_data(&buf[offset], offset, HCI_EIR_DATATYPE_MANUFACTURER_SPECIFIC_DATA, (void *)data, len); - if (offset > ADV_RSP_PACKET_MAX) { - puts("***trans_adv_data overflow!!!!!!\n"); - return -1; - } - log_info("trans_adv_data(%d):", offset); - log_info_hexdump(buf, offset); - trans_server_adv_config.adv_data_len = offset; - trans_server_adv_config.adv_data = trans_adv_data; - //adv_cnt++; // trans_make_set_adv_data()内引用此变量填充广播包 - //trans_make_set_adv_data(); - //FF offset 为18 - //memcpy(trans_server_adv_config.adv_data[18],data,len); - //trans_server_adv_config.adv_data[18] = - /* trans_make_set_rsp_data(); //看情况是否需要修改rsp包,一起调用即可*/ - //ble_module_enable(1); - ble_op_set_adv_data(trans_server_adv_config.adv_data_len,trans_server_adv_config.adv_data); - ble_op_adv_enable(1); - return 0; -} - -/*************************************************************************************************/ -/*! - * \brief 组织rsp包数据,放入buff - * - * \param [in] - * - * \return - * - * \note - */ -/*************************************************************************************************/ -static int trans_make_set_rsp_data(void) -{ - u8 offset = 0; - u8 *buf = trans_scan_rsp_data; - -#if RCSP_BTMATE_EN - //u8 tag_len = sizeof(user_tag_string); - //offset += make_eir_packet_data(&buf[offset], offset, HCI_EIR_DATATYPE_MANUFACTURER_SPECIFIC_DATA, (void *)user_tag_string, tag_len); -#endif - - if (!adv_name_ok) { - char *gap_name = ble_comm_get_gap_name(); - u8 name_len = strlen(gap_name); - u8 vaild_len = ADV_RSP_PACKET_MAX - (offset + 2); - if (name_len > vaild_len) { - name_len = vaild_len; - } - offset += make_eir_packet_data(&buf[offset], offset, HCI_EIR_DATATYPE_COMPLETE_LOCAL_NAME, (void *)gap_name, name_len); - } - - if (offset > ADV_RSP_PACKET_MAX) { - puts("***rsp_data overflow!!!!!!\n"); - return -1; - } - - log_info("rsp_data(%d):", offset); - log_info_hexdump(buf, offset); - trans_server_adv_config.rsp_data_len = offset; - trans_server_adv_config.rsp_data = trans_scan_rsp_data; - return 0; -} - -/*************************************************************************************************/ -/*! - * \brief 配置广播参数 - * - * \param [in] - * - * \return - * - * \note 开广播前配置都有效 - */ -/*************************************************************************************************/ -static void trans_adv_config_set(void) -{ - int ret = 0; - ret |= trans_make_set_adv_data(); - ret |= trans_make_set_rsp_data(); - - trans_server_adv_config.adv_interval = ADV_INTERVAL_MIN; - trans_server_adv_config.adv_auto_do = 1; - trans_server_adv_config.adv_type = ADV_IND; - trans_server_adv_config.adv_channel = ADV_CHANNEL_ALL; - memset(trans_server_adv_config.direct_address_info, 0, 7); - - if (ret) { - log_info("adv_setup_init fail!!!\n"); - return; - } - ble_gatt_server_set_adv_config(&trans_server_adv_config); -} - -/*************************************************************************************************/ -/*! - * \brief server init初始化 - * - * \param [in] - * - * \return - * - * \note - */ -/*************************************************************************************************/ -void trans_server_init(void) -{ - log_info("%s", __FUNCTION__); - ble_gatt_server_set_profile(trans_profile_data, sizeof(trans_profile_data)); - trans_adv_config_set(); -} - -/*************************************************************************************************/ -/*! - * \brief 断开连接 - * - * \param [in] - * - * \return - * - * \note - */ -/*************************************************************************************************/ -void trans_disconnect(void) -{ - log_info("%s", __FUNCTION__); - if (trans_con_handle) { - ble_comm_disconnect(trans_con_handle); - } -} - - -/*************************************************************************************************/ -/*! - * \brief 协议栈初始化前调用 - * - * \param [in] - * - * \return - * - * \note - */ -/*************************************************************************************************/ - -void bt_ble_before_start_init(void) -{ - log_info("%s", __FUNCTION__); - ble_comm_init(&trans_gatt_control_block); -} - - -/*************************************************************************************************/ -/*! - * \brief - * - * \param [in] - * - * \return - * - * \note - */ -/*************************************************************************************************/ -static void trans_test_send_data(void) -{ -#if TEST_TRANS_CHANNEL_DATA - static u32 count = 0; - static u32 send_index; - - int i, ret = 0; - int send_len = TEST_PAYLOAD_LEN; - u32 time_index_max = 1000 / TEST_TRANS_TIMER_MS; - - if (!trans_con_handle) { - return; - } - - send_index++; - -#if TEST_TRANS_NOTIFY_HANDLE - do { - if (ble_comm_att_check_send(trans_con_handle, send_len) && ble_gatt_server_characteristic_ccc_get(trans_con_handle, TEST_TRANS_NOTIFY_HANDLE + 1)) { - count++; - ret = ble_comm_att_send_data(trans_con_handle, TEST_TRANS_NOTIFY_HANDLE, &count, send_len, ATT_OP_AUTO_READ_CCC); - if (!ret) { - /* putchar('T'); */ - trans_send_test_count += send_len; - } - } else { - break; - } - } while (ret == 0); -#endif - - if (send_index >= time_index_max) { - if (trans_send_test_count) { - log_info(">>>>>> send_rate= %d byte/s\n", trans_send_test_count); - } - send_index = 0; - trans_send_test_count = 0; - - if (trans_recieve_test_count) { - log_info("<<<<<<< recieve_rate= %d byte/s\n", trans_recieve_test_count); - trans_recieve_test_count = 0; - } - } -#endif -} -/*************************************************************************************************/ -/*! - * \brief 控制应答对方READ/WRITE行为的响应包RESPONSE的回复 - * - * \param [in]流控使能 en: 1-停止收数 or 0-继续收数 - * - * \return - * - * \note - */ -/*************************************************************************************************/ -int ble_trans_flow_enable(u8 en) -{ - int ret = -1; - -#if ATT_DATA_RECIEVT_FLOW - if (trans_con_handle) { - att_server_flow_hold(trans_con_handle, en); - ret = 0; - log_info("ble_trans_flow_enable:%d\n", en); - } -#endif - - return ret; -} - -//for test -static void timer_trans_flow_test(void) -{ - static u8 sw = 0; - if (trans_con_handle) { - sw = !sw; - ble_trans_flow_enable(sw); - } -} - -/*************************************************************************************************/ -/*! - * \brief 模块初始化 - * - * \param [in] - * - * \return - * - * \note - */ -/*************************************************************************************************/ -void bt_ble_init(void) -{ - log_info("%s\n", __FUNCTION__); - log_info("ble_file: %s", __FILE__); - -#if DOUBLE_BT_SAME_NAME - ble_comm_set_config_name(bt_get_local_name(), 0); -#else - //helloyifa - //ble_comm_set_config_name(bt_get_local_name(), 1); - //ble_comm_set_config_name("iT12", 1); -#endif - trans_con_handle = 0; - trans_server_init(); - -#if CONFIG_BT_GATT_CLIENT_NUM - trans_client_init(); -#endif - -#if CONFIG_BT_GATT_CLIENT_NUM && CONFIG_BT_SM_SUPPORT_ENABLE - trans_ios_services_init(); -#endif - -#if ATT_DATA_RECIEVT_FLOW - log_info("att_server_flow_enable\n"); - att_server_flow_enable(1); -// sys_timer_add(0, timer_trans_flow_test, 5000); -#endif - - ble_module_enable(1); - -#if TEST_TRANS_CHANNEL_DATA - if (TEST_TRANS_TIMER_MS < 10) { - sys_s_hi_timer_add(0, trans_test_send_data, TEST_TRANS_TIMER_MS); - } else { - sys_timer_add(0, trans_test_send_data, TEST_TRANS_TIMER_MS); - } -#endif - -} - -/*************************************************************************************************/ -/*! - * \brief 模块退出 - * - * \param [in] - * - * \return - * - * \note - */ -/*************************************************************************************************/ -void bt_ble_exit(void) -{ - log_info("%s\n", __FUNCTION__); - -#if CONFIG_BT_GATT_CLIENT_NUM - trans_client_exit(); -#endif - -#if CONFIG_BT_GATT_CLIENT_NUM && CONFIG_BT_SM_SUPPORT_ENABLE - trans_ios_services_exit(); -#endif - - ble_module_enable(0); - ble_comm_exit(); -} - -/*************************************************************************************************/ -/*! - * \brief 模块开发使能 - * - * \param [in] - * - * \return - * - * \note - */ -/*************************************************************************************************/ -void ble_module_enable(u8 en) -{ - ble_comm_module_enable(en); -} - -/*************************************************************************************************/ -/*! - * \brief testbox 按键测试 - * - * \param [in] - * - * \return - * - * \note - */ -/*************************************************************************************************/ -void ble_server_send_test_key_num(u8 key_num) -{ - if (trans_con_handle) { - if (get_remote_test_flag()) { - ble_op_test_key_num(trans_con_handle, key_num); - } else { - log_info("-not conn testbox\n"); - } - } -} - - -#endif - - +/********************************************************************************************* + * Filename : .c + + * Description : + + * Author : JM + + * Email : zh-jieli.com + + * Last modifiled : 2017-01-17 11:14 + + * Copyright:(c)JIELI 2011-2016 @ , All Rights Reserved. +*********************************************************************************************/ +#include "system/app_core.h" +#include "system/includes.h" + +#include "app_config.h" +#include "app_action.h" + +#include "btstack/btstack_task.h" +#include "btstack/bluetooth.h" +#include "user_cfg.h" +#include "vm.h" +#include "btcontroller_modules.h" +#include "bt_common.h" +#include "3th_profile_api.h" +#include "le_common.h" +#include "rcsp_bluetooth.h" +#include "JL_rcsp_api.h" +#include "custom_cfg.h" +#include "btstack/btstack_event.h" +#include "gatt_common/le_gatt_common.h" +#include "ble_trans.h" +#include "ble_trans_profile.h" +#include "app_temperature.h" +#if CONFIG_APP_SPP_LE + +#if LE_DEBUG_PRINT_EN +#define log_info(x, ...) printf("[BLE_TRANS]" x " ", ## __VA_ARGS__) +#define log_info_hexdump put_buf + +#else +#define log_info(...) +#define log_info_hexdump(...) +#endif + +/* + 打开流控使能后,确定使能接口 att_server_flow_enable 被调用 + 然后使用过程 通过接口 att_server_flow_hold 来控制流控开关 + 注意:流控只能控制对方使用带响应READ/WRITE等命令方式 + 例如:ATT_WRITE_REQUEST = 0x12 + */ +#define ATT_DATA_RECIEVT_FLOW 0//流控功能使能 + + +//测试NRF连接,工具不会主动发起交换流程,需要手动操作; 但设备可配置主动发起MTU长度交换请求 +#define ATT_MTU_REQUEST_ENALBE 0 /*配置1,就是设备端主动发起交换*/ + +//检测对方的系统类型,ios or 非ios +#define ATT_CHECK_REMOTE_REQUEST_ENALBE 0 /*配置1,就是设备端主动检查*/ + +//ATT发送的包长, note: 23 <=need >= MTU +#define ATT_LOCAL_MTU_SIZE (512) /*一般是主机发起交换,如果主机没有发起,设备端也可以主动发起(ATT_MTU_REQUEST_ENALBE set 1)*/ + +//ATT缓存的buffer支持缓存数据包个数 +#define ATT_PACKET_NUMS_MAX (2) + +//ATT缓存的buffer大小, note: need >= 23,可修改 +#define ATT_SEND_CBUF_SIZE (ATT_PACKET_NUMS_MAX * (ATT_PACKET_HEAD_SIZE + ATT_LOCAL_MTU_SIZE)) + +// 广播周期 (unit:0.625ms) +#define ADV_INTERVAL_MIN (160 * 5)// + +#define TEST_TRANS_CHANNEL_DATA 0 /*测试记录收发数据速度*/ +#define TEST_TRANS_NOTIFY_HANDLE ATT_CHARACTERISTIC_ae02_01_VALUE_HANDLE /*主动发送hanlde,为空则不测试发数*/ +#if CONFIG_BLE_HIGH_SPEED +#define TEST_TRANS_TIMER_MS 5 +#else +#define TEST_TRANS_TIMER_MS 500 +#endif +#define TEST_PAYLOAD_LEN (244)/*发送配PDU长度是251的包*/ + +static u32 trans_recieve_test_count; +static u32 trans_send_test_count; + +//--------------- +//连接参数更新请求设置 +//是否使能参数请求更新,0--disable, 1--enable +static uint8_t trans_connection_update_enable = 1; ///0--disable, 1--enable + +//请求的参数数组表,排队方式请求;哪组对方接受就用那组 +static const struct conn_update_param_t trans_connection_param_table[] = { + +#if CONFIG_BLE_HIGH_SPEED + {6, 12, 10, 400},// ios fast +#endif + + {16, 24, 10, 600},//11 + {12, 28, 10, 600},//3.7 + {8, 20, 10, 600}, +}; + +//共可用的参数组数 +#define CONN_PARAM_TABLE_CNT (sizeof(trans_connection_param_table)/sizeof(struct conn_update_param_t)) + +#define EIR_TAG_STRING 0xd6, 0x05, 0x08, 0x00, 'J', 'L', 'A', 'I', 'S', 'D','K' +static const char user_tag_string[] = {EIR_TAG_STRING}; + +//定义的产品信息,for test +#define PNP_VID_SOURCE 0x02 +#define PNP_VID 0x05ac //0x05d6 +#define PNP_PID 0x022C // +#define PNP_PID_VERSION 0x011b //1.1.11 + +static const u8 trans_PNP_ID[] = {PNP_VID_SOURCE, PNP_VID & 0xFF, PNP_VID >> 8, PNP_PID & 0xFF, PNP_PID >> 8, PNP_PID_VERSION & 0xFF, PNP_PID_VERSION >> 8}; + +static u8 trans_adv_data[ADV_RSP_PACKET_MAX];//max is 31 +static u8 trans_scan_rsp_data[ADV_RSP_PACKET_MAX];//max is 31 +static u8 trans_test_read_write_buf[4]; +static u16 trans_con_handle; +static adv_cfg_t trans_server_adv_config; +//------------------------------------------------------------------------------------- +static uint16_t trans_att_read_callback(hci_con_handle_t connection_handle, uint16_t att_handle, uint16_t offset, uint8_t *buffer, uint16_t buffer_size); +static int trans_att_write_callback(hci_con_handle_t connection_handle, uint16_t att_handle, uint16_t transaction_mode, uint16_t offset, uint8_t *buffer, uint16_t buffer_size); +static int trans_event_packet_handler(int event, u8 *packet, u16 size, u8 *ext_param); +extern void uart_db_regiest_recieve_callback(void *rx_cb); +//------------------------------------------------------------------------------------- + +//------------------------------------------------------------------------------------- +//输入passkey 加密 +#define PASSKEY_ENABLE 0 + +static const sm_cfg_t trans_sm_init_config = { + .slave_security_auto_req = 0, + .slave_set_wait_security = 0, + +#if PASSKEY_ENABLE + .io_capabilities = IO_CAPABILITY_DISPLAY_ONLY, +#else + .io_capabilities = IO_CAPABILITY_NO_INPUT_NO_OUTPUT, +#endif + + .authentication_req_flags = SM_AUTHREQ_BONDING | SM_AUTHREQ_MITM_PROTECTION, + .min_key_size = 7, + .max_key_size = 16, + .sm_cb_packet_handler = NULL, +}; + +const gatt_server_cfg_t trans_server_init_cfg = { + .att_read_cb = &trans_att_read_callback, + .att_write_cb = &trans_att_write_callback, + .event_packet_handler = &trans_event_packet_handler, +}; + +static gatt_ctrl_t trans_gatt_control_block = { + //public + .mtu_size = ATT_LOCAL_MTU_SIZE, + .cbuffer_size = ATT_SEND_CBUF_SIZE, + .multi_dev_flag = 0, + + //config +#if CONFIG_BT_GATT_SERVER_NUM + .server_config = &trans_server_init_cfg, +#else + .server_config = NULL, +#endif + +#if CONFIG_BT_GATT_CLIENT_NUM + .client_config = &trans_client_init_cfg, +#else + .client_config = NULL, +#endif + +#if CONFIG_BT_SM_SUPPORT_ENABLE + .sm_config = &trans_sm_init_config, +#else + .sm_config = NULL, +#endif + //cbk,event handle + .hci_cb_packet_handler = NULL, +}; + + +#define TEST_AUDIO_DATA_UPLOAD 0//测试文件上传 + +#if TEST_AUDIO_DATA_UPLOAD +static const u8 test_audio_data_file[1024] = { + 1, 2, 3, 4, 5, 6, 7, 8, 9 +}; + +/*************************************************************************************************/ +/*! + * \brief 测试上传文件 + * + * \param [in] + * + * \return + * + * \note + */ +/*************************************************************************************************/ +#define AUDIO_ONE_PACKET_LEN 128 +static void trans_test_send_audio_data(int init_flag) +{ + static u32 send_pt = 0; + static u32 start_flag = 0; + + if (!trans_con_handle) { + return; + } + + if (init_flag) { + log_info("audio send init\n"); + send_pt = 0; + start_flag = 1; + } + + if (!start_flag) { + return; + } + + u32 file_size = sizeof(test_audio_data_file); + u8 *file_ptr = test_audio_data_file; + + if (send_pt >= file_size) { + log_info("audio send Complete\n"); + start_flag = 0; + return; + } + + u32 send_len = file_size - send_pt; + if (send_len > AUDIO_ONE_PACKET_LEN) { + send_len = AUDIO_ONE_PACKET_LEN; + } + + while (1) { + if (ble_comm_cbuffer_vaild_len(trans_con_handle) > send_len) { + log_info("audio send %08x\n", send_pt); + if (ble_comm_att_send_data(trans_con_handle, ATT_CHARACTERISTIC_ae3c_01_VALUE_HANDLE, &file_ptr[send_pt], send_len, ATT_OP_AUTO_READ_CCC)) { + log_info("audio send fail!\n"); + break; + } else { + send_pt += send_len; + } + } else { + break; + } + } +} + +#endif + +/*************************************************************************************************/ +/*! + * \brief 串口接收转发到BLE + * + * \param [in] + * + * \return + * + * \note + */ +/*************************************************************************************************/ +static void trans_uart_rx_to_ble(u8 *packet, u32 size) +{ + if (trans_con_handle && ble_comm_att_check_send(trans_con_handle, size) && + ble_gatt_server_characteristic_ccc_get(trans_con_handle, ATT_CHARACTERISTIC_ae02_01_CLIENT_CONFIGURATION_HANDLE)) { + ble_comm_att_send_data(trans_con_handle, ATT_CHARACTERISTIC_ae02_01_VALUE_HANDLE, packet, size, ATT_OP_AUTO_READ_CCC); + } else { + log_info("drop uart data!!!\n"); + } +} + +/*************************************************************************************************/ +/*! + * \brief 发送请求连接参数表 + * + * \param [in] + * + * \return + * + * \note + */ +/*************************************************************************************************/ +static void trans_send_connetion_updata_deal(u16 conn_handle) +{ + if (trans_connection_update_enable) { + if (0 == ble_gatt_server_connetion_update_request(conn_handle, trans_connection_param_table, CONN_PARAM_TABLE_CNT)) { + trans_connection_update_enable = 0; + } + } +} + +/*************************************************************************************************/ +/*! + * \brief 回连状态,使能所有profile + * + * \param [in] + * + * \return + * + * \note 配对绑定的方式,主机回连不是在使能server的通知开关,需要自己打开 + */ +/*************************************************************************************************/ +static void trans_resume_all_ccc_enable(u16 conn_handle, u8 update_request) +{ + log_info("resume_all_ccc_enable\n"); + +#if RCSP_BTMATE_EN + ble_gatt_server_characteristic_ccc_set(conn_handle, ATT_CHARACTERISTIC_ae02_02_CLIENT_CONFIGURATION_HANDLE, ATT_OP_NOTIFY); +#endif + ble_gatt_server_characteristic_ccc_set(conn_handle, ATT_CHARACTERISTIC_ae02_01_CLIENT_CONFIGURATION_HANDLE, ATT_OP_NOTIFY); + ble_gatt_server_characteristic_ccc_set(conn_handle, ATT_CHARACTERISTIC_ae04_01_CLIENT_CONFIGURATION_HANDLE, ATT_OP_NOTIFY); + ble_gatt_server_characteristic_ccc_set(conn_handle, ATT_CHARACTERISTIC_ae05_01_CLIENT_CONFIGURATION_HANDLE, ATT_OP_INDICATE); + ble_gatt_server_characteristic_ccc_set(conn_handle, ATT_CHARACTERISTIC_ae3c_01_CLIENT_CONFIGURATION_HANDLE, ATT_OP_NOTIFY); + + if (update_request) { + trans_send_connetion_updata_deal(conn_handle); + } +} + +/*************************************************************************************************/ +/*! + * \brief 反馈检查对方的操作系统 + * + * \param [in] + * + * \return + * + * \note 参考识别手机系统 + */ +/*************************************************************************************************/ +static void trans_check_remote_result(u16 con_handle, remote_type_e remote_type) +{ + char *str; + if (REMOTE_TYPE_IOS == remote_type) { + str = "is"; + } else { + str = "not"; + } + + log_info("trans_check %02x:remote_type= %02x, %s ios", con_handle, remote_type, str); +} + +/*************************************************************************************************/ +/*! + * \brief 处理gatt 返回的事件(hci && gatt) + * + * \param [in] + * + * \return + * + * \note + */ +/*************************************************************************************************/ +static int trans_event_packet_handler(int event, u8 *packet, u16 size, u8 *ext_param) +{ + /* log_info("event: %02x,size= %d\n",event,size); */ + + switch (event) { + + case GATT_COMM_EVENT_CAN_SEND_NOW: +#if TEST_AUDIO_DATA_UPLOAD + trans_test_send_audio_data(0); +#endif + break; + + case GATT_COMM_EVENT_SERVER_INDICATION_COMPLETE: + log_info("INDICATION_COMPLETE:con_handle= %04x,att_handle= %04x\n", \ + little_endian_read_16(packet, 0), little_endian_read_16(packet, 2)); + break; + + + case GATT_COMM_EVENT_CONNECTION_COMPLETE: + trans_con_handle = little_endian_read_16(packet, 0); + trans_connection_update_enable = 1; + + log_info("connection_handle:%04x\n", little_endian_read_16(packet, 0)); + log_info("connection_handle:%04x, rssi= %d\n", trans_con_handle, ble_vendor_get_peer_rssi(trans_con_handle)); + log_info("peer_address_info:"); + put_buf(&ext_param[7], 7); + + log_info("con_interval = %d\n", little_endian_read_16(ext_param, 14 + 0)); + log_info("con_latency = %d\n", little_endian_read_16(ext_param, 14 + 2)); + log_info("cnn_timeout = %d\n", little_endian_read_16(ext_param, 14 + 4)); + //helloyifa + ble_on_connect_change(1); +#if ATT_MTU_REQUEST_ENALBE + att_server_set_exchange_mtu(trans_con_handle);/*主动请求MTU长度交换*/ +#endif + +#if TCFG_UART0_RX_PORT != NO_CONFIG_PORT + //for test 串口数据直通到蓝牙 + uart_db_regiest_recieve_callback(trans_uart_rx_to_ble); +#endif + +#if CONFIG_BT_GATT_CLIENT_NUM +#if CONFIG_BT_SM_SUPPORT_ENABLE == 0 + trans_client_search_remote_profile(trans_con_handle); +#endif +#endif + +#if ATT_CHECK_REMOTE_REQUEST_ENALBE + att_server_set_check_remote(trans_con_handle, trans_check_remote_result); +#endif + break; + + case GATT_COMM_EVENT_DISCONNECT_COMPLETE: + log_info("disconnect_handle:%04x,reason= %02x\n", little_endian_read_16(packet, 0), packet[2]); + if (trans_con_handle == little_endian_read_16(packet, 0)) { +#if CONFIG_BT_GATT_CLIENT_NUM + trans_client_search_remote_stop(trans_con_handle); +#endif + trans_con_handle = 0; + //helloyifa + ble_on_connect_change(0); + } + break; + + case GATT_COMM_EVENT_ENCRYPTION_CHANGE: + log_info("ENCRYPTION_CHANGE:handle=%04x,state=%d,process =%d", little_endian_read_16(packet, 0), packet[2], packet[3]); + if (packet[3] == LINK_ENCRYPTION_RECONNECT) { + trans_resume_all_ccc_enable(little_endian_read_16(packet, 0), 1); + } + +#if CONFIG_BT_GATT_CLIENT_NUM + trans_client_search_remote_profile(trans_con_handle); +#endif + break; + + case GATT_COMM_EVENT_CONNECTION_UPDATE_COMPLETE: + log_info("conn_param update_complete:%04x\n", little_endian_read_16(packet, 0)); + log_info("update_interval = %d\n", little_endian_read_16(ext_param, 6 + 0)); + log_info("update_latency = %d\n", little_endian_read_16(ext_param, 6 + 2)); + log_info("update_timeout = %d\n", little_endian_read_16(ext_param, 6 + 4)); + break; + + case GATT_COMM_EVENT_CONNECTION_UPDATE_REQUEST_RESULT: + break; + + case GATT_COMM_EVENT_MTU_EXCHANGE_COMPLETE: + log_info("con_handle= %02x, ATT MTU = %u\n", little_endian_read_16(packet, 0), little_endian_read_16(packet, 2)); + break; + + case GATT_COMM_EVENT_SERVER_STATE: + log_info("server_state: handle=%02x,%02x\n", little_endian_read_16(packet, 1), packet[0]); + break; + + case GATT_COMM_EVENT_SM_PASSKEY_INPUT: { + u32 *key = little_endian_read_32(packet, 2); + *key = 888888; + r_printf("input_key:%6u\n", *key); + } + break; + + default: + break; + } + return 0; +} + + +/*************************************************************************************************/ +/*! + * \brief 处理client 读操作 + * + * \param [in] + * + * \return + * + * \note profile的读属性uuid 有配置 DYNAMIC 关键字,就有read_callback 回调 + */ +/*************************************************************************************************/ +// ATT Client Read Callback for Dynamic Data +// - if buffer == NULL, don't copy data, just return size of value +// - if buffer != NULL, copy data and return number bytes copied +// @param con_handle of hci le connection +// @param attribute_handle to be read +// @param offset defines start of attribute value +// @param buffer +// @param buffer_size +static uint16_t trans_att_read_callback(hci_con_handle_t connection_handle, uint16_t att_handle, uint16_t offset, uint8_t *buffer, uint16_t buffer_size) +{ + uint16_t att_value_len = 0; + uint16_t handle = att_handle; + + log_info("read_callback,conn_handle =%04x, handle=%04x,buffer=%08x\n", connection_handle, handle, (u32)buffer); + + switch (handle) { + case ATT_CHARACTERISTIC_2a00_01_VALUE_HANDLE: { + char *gap_name = ble_comm_get_gap_name(); + att_value_len = strlen(gap_name); + + if ((offset >= att_value_len) || (offset + buffer_size) > att_value_len) { + break; + } + + if (buffer) { + memcpy(buffer, &gap_name[offset], buffer_size); + att_value_len = buffer_size; + log_info("\n------read gap_name: %s\n", gap_name); + } + } + break; + + case ATT_CHARACTERISTIC_ae10_01_VALUE_HANDLE: + att_value_len = sizeof(trans_test_read_write_buf); + if ((offset >= att_value_len) || (offset + buffer_size) > att_value_len) { + break; + } + + if (buffer) { + memcpy(buffer, &trans_test_read_write_buf[offset], buffer_size); + att_value_len = buffer_size; + } + break; + + case ATT_CHARACTERISTIC_ae04_01_CLIENT_CONFIGURATION_HANDLE: + case ATT_CHARACTERISTIC_ae02_01_CLIENT_CONFIGURATION_HANDLE: + case ATT_CHARACTERISTIC_ae05_01_CLIENT_CONFIGURATION_HANDLE: + case ATT_CHARACTERISTIC_ae3c_01_CLIENT_CONFIGURATION_HANDLE: + case ATT_CHARACTERISTIC_2a05_01_CLIENT_CONFIGURATION_HANDLE: + if (buffer) { + buffer[0] = ble_gatt_server_characteristic_ccc_get(connection_handle, handle); + buffer[1] = 0; + } + att_value_len = 2; + break; + + case ATT_CHARACTERISTIC_2a50_01_VALUE_HANDLE: + log_info("read PnP_ID\n"); + att_value_len = sizeof(trans_PNP_ID); + if ((offset >= att_value_len) || (offset + buffer_size) > att_value_len) { + break; + } + if (buffer) { + memcpy(buffer, &trans_PNP_ID[offset], buffer_size); + att_value_len = buffer_size; + } + break; + + default: + break; + } + + log_info("att_value_len= %d\n", att_value_len); + return att_value_len; +} + + +/*************************************************************************************************/ +/*! + * \brief 处理client write操作 + * + * \param [in] + * + * \return + * + * \note profile的写属性uuid 有配置 DYNAMIC 关键字,就有write_callback 回调 + */ +/*************************************************************************************************/ +// ATT Client Write Callback for Dynamic Data +// @param con_handle of hci le connection +// @param attribute_handle to be written +// @param transaction - ATT_TRANSACTION_MODE_NONE for regular writes, ATT_TRANSACTION_MODE_ACTIVE for prepared writes and ATT_TRANSACTION_MODE_EXECUTE +// @param offset into the value - used for queued writes and long attributes +// @param buffer +// @param buffer_size +// @param signature used for signed write commmands +// @returns 0 if write was ok, ATT_ERROR_PREPARE_QUEUE_FULL if no space in queue, ATT_ERROR_INVALID_OFFSET if offset is larger than max buffer + +static int trans_att_write_callback(hci_con_handle_t connection_handle, uint16_t att_handle, uint16_t transaction_mode, uint16_t offset, uint8_t *buffer, uint16_t buffer_size) +{ + int result = 0; + u16 tmp16; + + u16 handle = att_handle; + +#if !TEST_TRANS_CHANNEL_DATA + log_info("write_callback,conn_handle =%04x, handle =%04x,size =%d\n", connection_handle, handle, buffer_size); +#endif + + switch (handle) { + + case ATT_CHARACTERISTIC_2a00_01_VALUE_HANDLE: + break; + + case ATT_CHARACTERISTIC_ae02_01_CLIENT_CONFIGURATION_HANDLE: + case ATT_CHARACTERISTIC_ae04_01_CLIENT_CONFIGURATION_HANDLE: + case ATT_CHARACTERISTIC_ae05_01_CLIENT_CONFIGURATION_HANDLE: + case ATT_CHARACTERISTIC_ae3c_01_CLIENT_CONFIGURATION_HANDLE: + case ATT_CHARACTERISTIC_2a05_01_CLIENT_CONFIGURATION_HANDLE: + trans_send_connetion_updata_deal(connection_handle); + log_info("\n------write ccc:%04x,%02x\n", handle, buffer[0]); + ble_gatt_server_characteristic_ccc_set(connection_handle, handle, buffer[0]); + break; + + case ATT_CHARACTERISTIC_ae10_01_VALUE_HANDLE: + tmp16 = sizeof(trans_test_read_write_buf); + if ((offset >= tmp16) || (offset + buffer_size) > tmp16) { + break; + } + memcpy(&trans_test_read_write_buf[offset], buffer, buffer_size); + log_info("\n-ae10_rx(%d):", buffer_size); + put_buf(buffer, buffer_size); + break; + + case ATT_CHARACTERISTIC_ae01_01_VALUE_HANDLE: + +#if TEST_TRANS_CHANNEL_DATA + /* putchar('R'); */ + trans_recieve_test_count += buffer_size; + break; +#endif + + log_info("\n-ae01_rx(%d):", buffer_size); + put_buf(buffer, buffer_size); + ble_receive_callback(buffer,buffer_size); + //收发测试,自动发送收到的数据;for test + //helloyifa + #if 0 + if (ble_comm_att_check_send(connection_handle, buffer_size) && + ble_gatt_server_characteristic_ccc_get(trans_con_handle, ATT_CHARACTERISTIC_ae02_01_CLIENT_CONFIGURATION_HANDLE)) { + log_info("-loop send1\n"); + ble_comm_att_send_data(connection_handle, ATT_CHARACTERISTIC_ae02_01_VALUE_HANDLE, buffer, buffer_size, ATT_OP_AUTO_READ_CCC); + } + #endif + break; + + case ATT_CHARACTERISTIC_ae03_01_VALUE_HANDLE: + log_info("\n-ae03_rx(%d):", buffer_size); + put_buf(buffer, buffer_size); + + //收发测试,自动发送收到的数据;for test + if (ble_comm_att_check_send(connection_handle, buffer_size) && \ + ble_gatt_server_characteristic_ccc_get(trans_con_handle, ATT_CHARACTERISTIC_ae05_01_CLIENT_CONFIGURATION_HANDLE)) { + log_info("-loop send2\n"); + ble_comm_att_send_data(connection_handle, ATT_CHARACTERISTIC_ae05_01_VALUE_HANDLE, buffer, buffer_size, ATT_OP_AUTO_READ_CCC); + } + break; + +#if RCSP_BTMATE_EN + case ATT_CHARACTERISTIC_ae02_02_CLIENT_CONFIGURATION_HANDLE: + ble_op_latency_skip(connection_handle, 0xffff); // + ble_gatt_server_set_update_send(connection_handle, ATT_CHARACTERISTIC_ae02_02_VALUE_HANDLE, ATT_OP_AUTO_READ_CCC); +#endif + /* trans_send_connetion_updata_deal(connection_handle); */ + log_info("------write ccc:%04x,%02x\n", handle, buffer[0]); + ble_gatt_server_characteristic_ccc_set(connection_handle, handle, buffer[0]); + break; + +#if RCSP_BTMATE_EN + case ATT_CHARACTERISTIC_ae01_02_VALUE_HANDLE: + log_info("rcsp_read:%x\n", buffer_size); + ble_gatt_server_receive_update_data(NULL, buffer, buffer_size); + break; +#endif + + case ATT_CHARACTERISTIC_ae3b_01_VALUE_HANDLE: + log_info("\n-ae3b_rx(%d):", buffer_size); + put_buf(buffer, buffer_size); + +#if TEST_AUDIO_DATA_UPLOAD + if (0 == memcmp(buffer, "start", 5)) { + trans_test_send_audio_data(1); + } +#endif + break; + + default: + break; + } + return 0; +} + + +/*************************************************************************************************/ +/*! + * \brief 组织adv包数据,放入buff + * + * \param [in] + * + * \return + * + * \note + */ +/*************************************************************************************************/ +static u8 adv_name_ok = 0;//name 优先存放在ADV包 +static int trans_make_set_adv_data(void) +{ + u8 offset = 0; + u8 *buf = trans_adv_data; + +#if DOUBLE_BT_SAME_MAC + offset += make_eir_packet_val(&buf[offset], offset, HCI_EIR_DATATYPE_FLAGS, FLAGS_GENERAL_DISCOVERABLE_MODE | FLAGS_LE_AND_EDR_SAME_CONTROLLER, 1); +#else + offset += make_eir_packet_val(&buf[offset], offset, HCI_EIR_DATATYPE_FLAGS, FLAGS_GENERAL_DISCOVERABLE_MODE | FLAGS_EDR_NOT_SUPPORTED, 1); +#endif + + offset += make_eir_packet_val(&buf[offset], offset, HCI_EIR_DATATYPE_COMPLETE_16BIT_SERVICE_UUIDS, 0xAF30, 2); + + char *gap_name = ble_comm_get_gap_name(); + u8 name_len = strlen(gap_name); + u8 vaild_len = ADV_RSP_PACKET_MAX - (offset + 2); + if (name_len < vaild_len) { + offset += make_eir_packet_data(&buf[offset], offset, HCI_EIR_DATATYPE_COMPLETE_LOCAL_NAME, (void *)gap_name, name_len); + adv_name_ok = 1; + } else { + adv_name_ok = 0; + } + + log_info("trans_adv_data @@ (%d):", offset); + //FF + //BBOOEEb 2字节体温 2字节物温 2字节环温 1字节电量 + u8 ff_temp_data[7] = {0}; + offset += make_eir_packet_data(&buf[offset], offset, HCI_EIR_DATATYPE_MANUFACTURER_SPECIFIC_DATA, (void *)ff_temp_data, sizeof(ff_temp_data)); + if (offset > ADV_RSP_PACKET_MAX) { + puts("***trans_adv_data overflow!!!!!!\n"); + return -1; + } + log_info("trans_adv_data(%d):", offset); + log_info_hexdump(buf, offset); + trans_server_adv_config.adv_data_len = offset; + trans_server_adv_config.adv_data = trans_adv_data; + return 0; +} + +int trans_client_adv_data_set_ff(u8*data, int len) +{ + //putchar('L'); + //put_u8hex(adv_cnt); + //ble_module_enable(0); + ble_op_adv_enable(0); + u8 offset = 0; + u8 *buf = trans_adv_data; + +#if DOUBLE_BT_SAME_MAC + offset += make_eir_packet_val(&buf[offset], offset, HCI_EIR_DATATYPE_FLAGS, FLAGS_GENERAL_DISCOVERABLE_MODE | FLAGS_LE_AND_EDR_SAME_CONTROLLER, 1); +#else + offset += make_eir_packet_val(&buf[offset], offset, HCI_EIR_DATATYPE_FLAGS, FLAGS_GENERAL_DISCOVERABLE_MODE | FLAGS_EDR_NOT_SUPPORTED, 1); +#endif + + offset += make_eir_packet_val(&buf[offset], offset, HCI_EIR_DATATYPE_COMPLETE_16BIT_SERVICE_UUIDS, 0xAF30, 2); + + char *gap_name = ble_comm_get_gap_name(); + u8 name_len = strlen(gap_name); + u8 vaild_len = ADV_RSP_PACKET_MAX - (offset + 2); + if (name_len < vaild_len) { + offset += make_eir_packet_data(&buf[offset], offset, HCI_EIR_DATATYPE_COMPLETE_LOCAL_NAME, (void *)gap_name, name_len); + adv_name_ok = 1; + } else { + adv_name_ok = 0; + } + //FF + u8 ff_temp_data[5] = {0}; + offset += make_eir_packet_data(&buf[offset], offset, HCI_EIR_DATATYPE_MANUFACTURER_SPECIFIC_DATA, (void *)data, len); + if (offset > ADV_RSP_PACKET_MAX) { + puts("***trans_adv_data overflow!!!!!!\n"); + return -1; + } + log_info("trans_adv_data(%d):", offset); + log_info_hexdump(buf, offset); + trans_server_adv_config.adv_data_len = offset; + trans_server_adv_config.adv_data = trans_adv_data; + //adv_cnt++; // trans_make_set_adv_data()内引用此变量填充广播包 + //trans_make_set_adv_data(); + //FF offset 为18 + //memcpy(trans_server_adv_config.adv_data[18],data,len); + //trans_server_adv_config.adv_data[18] = + /* trans_make_set_rsp_data(); //看情况是否需要修改rsp包,一起调用即可*/ + //ble_module_enable(1); + ble_op_set_adv_data(trans_server_adv_config.adv_data_len,trans_server_adv_config.adv_data); + ble_op_adv_enable(1); + return 0; +} + +/*************************************************************************************************/ +/*! + * \brief 组织rsp包数据,放入buff + * + * \param [in] + * + * \return + * + * \note + */ +/*************************************************************************************************/ +static int trans_make_set_rsp_data(void) +{ + u8 offset = 0; + u8 *buf = trans_scan_rsp_data; + +#if RCSP_BTMATE_EN + //u8 tag_len = sizeof(user_tag_string); + //offset += make_eir_packet_data(&buf[offset], offset, HCI_EIR_DATATYPE_MANUFACTURER_SPECIFIC_DATA, (void *)user_tag_string, tag_len); +#endif + + if (!adv_name_ok) { + char *gap_name = ble_comm_get_gap_name(); + u8 name_len = strlen(gap_name); + u8 vaild_len = ADV_RSP_PACKET_MAX - (offset + 2); + if (name_len > vaild_len) { + name_len = vaild_len; + } + offset += make_eir_packet_data(&buf[offset], offset, HCI_EIR_DATATYPE_COMPLETE_LOCAL_NAME, (void *)gap_name, name_len); + } + + if (offset > ADV_RSP_PACKET_MAX) { + puts("***rsp_data overflow!!!!!!\n"); + return -1; + } + + log_info("rsp_data(%d):", offset); + log_info_hexdump(buf, offset); + trans_server_adv_config.rsp_data_len = offset; + trans_server_adv_config.rsp_data = trans_scan_rsp_data; + return 0; +} + +/*************************************************************************************************/ +/*! + * \brief 配置广播参数 + * + * \param [in] + * + * \return + * + * \note 开广播前配置都有效 + */ +/*************************************************************************************************/ +static void trans_adv_config_set(void) +{ + int ret = 0; + ret |= trans_make_set_adv_data(); + ret |= trans_make_set_rsp_data(); + + trans_server_adv_config.adv_interval = ADV_INTERVAL_MIN; + trans_server_adv_config.adv_auto_do = 1; + trans_server_adv_config.adv_type = ADV_IND; + trans_server_adv_config.adv_channel = ADV_CHANNEL_ALL; + memset(trans_server_adv_config.direct_address_info, 0, 7); + + if (ret) { + log_info("adv_setup_init fail!!!\n"); + return; + } + ble_gatt_server_set_adv_config(&trans_server_adv_config); +} + +/*************************************************************************************************/ +/*! + * \brief server init初始化 + * + * \param [in] + * + * \return + * + * \note + */ +/*************************************************************************************************/ +void trans_server_init(void) +{ + log_info("%s", __FUNCTION__); + ble_gatt_server_set_profile(trans_profile_data, sizeof(trans_profile_data)); + trans_adv_config_set(); +} + +/*************************************************************************************************/ +/*! + * \brief 断开连接 + * + * \param [in] + * + * \return + * + * \note + */ +/*************************************************************************************************/ +void trans_disconnect(void) +{ + log_info("%s", __FUNCTION__); + if (trans_con_handle) { + ble_comm_disconnect(trans_con_handle); + } +} + + +/*************************************************************************************************/ +/*! + * \brief 协议栈初始化前调用 + * + * \param [in] + * + * \return + * + * \note + */ +/*************************************************************************************************/ + +void bt_ble_before_start_init(void) +{ + log_info("%s", __FUNCTION__); + ble_comm_init(&trans_gatt_control_block); +} + + +/*************************************************************************************************/ +/*! + * \brief + * + * \param [in] + * + * \return + * + * \note + */ +/*************************************************************************************************/ +static void trans_test_send_data(void) +{ +#if TEST_TRANS_CHANNEL_DATA + static u32 count = 0; + static u32 send_index; + + int i, ret = 0; + int send_len = TEST_PAYLOAD_LEN; + u32 time_index_max = 1000 / TEST_TRANS_TIMER_MS; + + if (!trans_con_handle) { + return; + } + + send_index++; + +#if TEST_TRANS_NOTIFY_HANDLE + do { + if (ble_comm_att_check_send(trans_con_handle, send_len) && ble_gatt_server_characteristic_ccc_get(trans_con_handle, TEST_TRANS_NOTIFY_HANDLE + 1)) { + count++; + ret = ble_comm_att_send_data(trans_con_handle, TEST_TRANS_NOTIFY_HANDLE, &count, send_len, ATT_OP_AUTO_READ_CCC); + if (!ret) { + /* putchar('T'); */ + trans_send_test_count += send_len; + } + } else { + break; + } + } while (ret == 0); +#endif + + if (send_index >= time_index_max) { + if (trans_send_test_count) { + log_info(">>>>>> send_rate= %d byte/s\n", trans_send_test_count); + } + send_index = 0; + trans_send_test_count = 0; + + if (trans_recieve_test_count) { + log_info("<<<<<<< recieve_rate= %d byte/s\n", trans_recieve_test_count); + trans_recieve_test_count = 0; + } + } +#endif +} +/*************************************************************************************************/ +/*! + * \brief 控制应答对方READ/WRITE行为的响应包RESPONSE的回复 + * + * \param [in]流控使能 en: 1-停止收数 or 0-继续收数 + * + * \return + * + * \note + */ +/*************************************************************************************************/ +int ble_trans_flow_enable(u8 en) +{ + int ret = -1; + +#if ATT_DATA_RECIEVT_FLOW + if (trans_con_handle) { + att_server_flow_hold(trans_con_handle, en); + ret = 0; + log_info("ble_trans_flow_enable:%d\n", en); + } +#endif + + return ret; +} + +//for test +static void timer_trans_flow_test(void) +{ + static u8 sw = 0; + if (trans_con_handle) { + sw = !sw; + ble_trans_flow_enable(sw); + } +} + +/*************************************************************************************************/ +/*! + * \brief 模块初始化 + * + * \param [in] + * + * \return + * + * \note + */ +/*************************************************************************************************/ +void bt_ble_init(void) +{ + log_info("%s\n", __FUNCTION__); + log_info("ble_file: %s", __FILE__); + +#if DOUBLE_BT_SAME_NAME + ble_comm_set_config_name(bt_get_local_name(), 0); +#else + //helloyifa + //ble_comm_set_config_name(bt_get_local_name(), 1); + //ble_comm_set_config_name("iT12", 1); +#endif + trans_con_handle = 0; + trans_server_init(); + +#if CONFIG_BT_GATT_CLIENT_NUM + trans_client_init(); +#endif + +#if CONFIG_BT_GATT_CLIENT_NUM && CONFIG_BT_SM_SUPPORT_ENABLE + trans_ios_services_init(); +#endif + +#if ATT_DATA_RECIEVT_FLOW + log_info("att_server_flow_enable\n"); + att_server_flow_enable(1); +// sys_timer_add(0, timer_trans_flow_test, 5000); +#endif + + ble_module_enable(1); + +#if TEST_TRANS_CHANNEL_DATA + if (TEST_TRANS_TIMER_MS < 10) { + sys_s_hi_timer_add(0, trans_test_send_data, TEST_TRANS_TIMER_MS); + } else { + sys_timer_add(0, trans_test_send_data, TEST_TRANS_TIMER_MS); + } +#endif + +} + +/*************************************************************************************************/ +/*! + * \brief 模块退出 + * + * \param [in] + * + * \return + * + * \note + */ +/*************************************************************************************************/ +void bt_ble_exit(void) +{ + log_info("%s\n", __FUNCTION__); + +#if CONFIG_BT_GATT_CLIENT_NUM + trans_client_exit(); +#endif + +#if CONFIG_BT_GATT_CLIENT_NUM && CONFIG_BT_SM_SUPPORT_ENABLE + trans_ios_services_exit(); +#endif + + ble_module_enable(0); + ble_comm_exit(); +} + +/*************************************************************************************************/ +/*! + * \brief 模块开发使能 + * + * \param [in] + * + * \return + * + * \note + */ +/*************************************************************************************************/ +void ble_module_enable(u8 en) +{ + ble_comm_module_enable(en); +} + +/*************************************************************************************************/ +/*! + * \brief testbox 按键测试 + * + * \param [in] + * + * \return + * + * \note + */ +/*************************************************************************************************/ +void ble_server_send_test_key_num(u8 key_num) +{ + if (trans_con_handle) { + if (get_remote_test_flag()) { + ble_op_test_key_num(trans_con_handle, key_num); + } else { + log_info("-not conn testbox\n"); + } + } +} + + +#endif + + diff --git a/fw-AC63_BT_SDK/apps/spp_and_le/include/app_temperature.h b/fw-AC63_BT_SDK/apps/spp_and_le/include/app_temperature.h index 16faa08..1dcc899 100644 --- a/fw-AC63_BT_SDK/apps/spp_and_le/include/app_temperature.h +++ b/fw-AC63_BT_SDK/apps/spp_and_le/include/app_temperature.h @@ -1,54 +1,62 @@ -#ifndef _APP_TEMPERATURE_H_ -#define _APP_TEMPERATURE_H_ - -#include "typedef.h" -#include "system/event.h" - -#define BLE_TEMPERATURE_DETECT_INTERVAL 250 -#define BLE_TEMPERATURE_WORK_TIMEOUT 10*1000 -#define BLE_TEMPERATURE_SLEEP_TIMEOUT 3*1000 -#define BLE_TEMPERATURE_DEVICE_NAME "IT12" -#define BLE_TEMPERATURE_LOWPOWER_OFFSIZE 3000 //mV - -#define BLE_TEMPERATURE_DEVICE_NST1002 1002 -#define BLE_TEMPERATURE_DEVICE_NTC 0 - -#define BLE_TEMPERATURE_WORK_LED IO_PORTA_07 - -#define BLE_TEMPERATURE_CHARGE_STATE_CHARGING 1 -#define BLE_TEMPERATURE_CHARGE_STATE_FULL 2 -#define BLE_TEMPERATURE_CHARGE_STATE_IDLE 3 -#define BLE_TEMPERATURE_CHARGE_STATE_LOWPOWER 4 - -//VM用户自定义配置项[1 ~ 49] -#define BLE_TEMPERATURE_VM_DEVICE_CONFIG 2 - -typedef struct -{ - u16 temperature_sensor; - u32 temperature_ntc; - u8 batt_percent; - u16 batt_vat; - u8 is_bat_charge; - u8 is_bat_full; -}app_dev_info_t; - -typedef struct -{ - /* 测温检测间隔 ms 1000ms*/ - int16_t detect_interval; - /* 温度校准 0.1C *1000 = 100 或者 -100*/ - int16_t temperature_offset; -}app_dev_config_t; - -//extern struct app_dev_info_t dev_info; -//extern struct app_dev_config_t dev_config; - -void temperature_ble_init(); -void temperature_init(void); -void ble_receive_callback(u8* data,u16 len); - -void temperature_work_led(u8 on); -void temperature_charge_led(u8 on); -void temperature_charge_state(int state); -#endif //_APP_TEMPERATURE_H_ +#ifndef _APP_TEMPERATURE_H_ +#define _APP_TEMPERATURE_H_ + +#include "typedef.h" +#include "system/event.h" + +/** + * 1.0.1 2025.05.16 + */ +#define BLE_TEMPERATURE_DEVICE_SOFT_VER "1.0.1" + +#define BLE_TEMPERATURE_DETECT_INTERVAL 250 +#define BLE_TEMPERATURE_WORK_TIMEOUT 10*1000 +#define BLE_TEMPERATURE_SLEEP_TIMEOUT 3*1000 +#define BLE_TEMPERATURE_DEVICE_NAME "IT12" +#define BLE_TEMPERATURE_LOWPOWER_OFFSIZE 3000 //mV + +#define BLE_TEMPERATURE_DEVICE_NST1002 1002 +#define BLE_TEMPERATURE_DEVICE_NTC 0 + +#define BLE_TEMPERATURE_WORK_LED IO_PORTA_07 + +#define BLE_TEMPERATURE_CHARGE_STATE_CHARGING 1 +#define BLE_TEMPERATURE_CHARGE_STATE_FULL 2 +#define BLE_TEMPERATURE_CHARGE_STATE_IDLE 3 +#define BLE_TEMPERATURE_CHARGE_STATE_LOWPOWER 4 + +//VM用户自定义配置项[1 ~ 49] +#define BLE_TEMPERATURE_VM_DEVICE_CONFIG 2 + +typedef struct +{ + u16 temperature_sensor; + u16 temperature_ntc; + u8 batt_percent; + u16 batt_val; + u8 is_bat_charge; + u8 is_bat_full; +}app_dev_info_t; + +typedef struct +{ + /* 测温检测间隔 ms 1000ms*/ + int16_t detect_interval; + /* 温度校准 0.1C *1000 = 100 或者 -100*/ + int16_t temperature_offset; +}app_dev_config_t; + +//extern struct app_dev_info_t dev_info; +//extern struct app_dev_config_t dev_config; + +void temperature_ble_init(); +void temperature_init(void); + +void ble_receive_callback(u8* data,u16 len); +void ble_on_connect_change(u8 is_connect); + +void temperature_work_led(u8 on); +void temperature_charge_led(u8 on); +void temperature_charge_state(int state); +void temperature_deinit(void); +#endif //_APP_TEMPERATURE_H_ diff --git a/fw-AC63_BT_SDK/apps/spp_and_le/modules/power/app_charge.c b/fw-AC63_BT_SDK/apps/spp_and_le/modules/power/app_charge.c index 31d65d8..9cb9985 100644 --- a/fw-AC63_BT_SDK/apps/spp_and_le/modules/power/app_charge.c +++ b/fw-AC63_BT_SDK/apps/spp_and_le/modules/power/app_charge.c @@ -1,118 +1,119 @@ -#include "app_config.h" -#include "asm/charge.h" -#include "asm/pwm_led.h" -#include "system/event.h" -#include "system/app_core.h" -#include "system/includes.h" -#include "app_action.h" -#include "asm/wdt.h" -#include "app_main.h" -#include "app_power_manage.h" -#include "app_handshake.h" -#include "app_temperature.h" -#define LOG_TAG_CONST APP_CHARGE -#define LOG_TAG "[APP_CHARGE]" -#define LOG_ERROR_ENABLE -#define LOG_DEBUG_ENABLE -#define LOG_INFO_ENABLE -/* #define LOG_DUMP_ENABLE */ -#define LOG_CLI_ENABLE -#include "debug.h" - -#if TCFG_CHARGE_ENABLE - -#if TCFG_HANDSHAKE_ENABLE -static void handshake_complete(void) -{ - handshake_app_stop(); - if (get_lvcmp_det()) { - charge_start(); - } -} -#endif - -void charge_start_deal(void) -{ - log_info("%s\n", __func__); - power_set_mode(PWR_LDO15); -} - -void ldo5v_keep_deal(void) -{ - log_info("%s\n", __func__); -#if TCFG_HANDSHAKE_ENABLE - handshake_app_start(2, handshake_complete); -#endif - temperature_charge_state(BLE_TEMPERATURE_CHARGE_STATE_CHARGING); -} - -void charge_full_deal(void) -{ - log_info("%s\n", __func__); - charge_close(); - //power_set_soft_poweroff(); - //extern spple_set_soft_poweroff(); - //spple_set_soft_poweroff(); - temperature_charge_state(BLE_TEMPERATURE_CHARGE_STATE_FULL); - -} - -void charge_close_deal(void) -{ - log_info("%s\n", __FUNCTION__); -} - -void charge_ldo5v_in_deal(void) -{ - log_info("%s\n", __FUNCTION__); -#if TCFG_HANDSHAKE_ENABLE - handshake_app_start(2, handshake_complete); -#else - charge_start(); -#endif - temperature_charge_state(BLE_TEMPERATURE_CHARGE_STATE_CHARGING); -} - -void charge_ldo5v_off_deal(void) -{ - log_info("%s\n", __FUNCTION__); -#if TCFG_HANDSHAKE_ENABLE - handshake_app_stop(); -#endif - charge_close(); - power_set_mode(TCFG_LOWPOWER_POWER_SEL); -#if TCFG_SYS_LVD_EN - vbat_check_init(); -#endif - temperature_charge_state(BLE_TEMPERATURE_CHARGE_STATE_IDLE); -} - -int app_charge_event_handler(struct device_event *dev) -{ - switch (dev->event) { - case CHARGE_EVENT_CHARGE_START: - charge_start_deal(); - break; - case CHARGE_EVENT_CHARGE_CLOSE: - charge_close_deal(); - break; - case CHARGE_EVENT_CHARGE_FULL: - charge_full_deal(); - break; - case CHARGE_EVENT_LDO5V_KEEP: - ldo5v_keep_deal(); - break; - case CHARGE_EVENT_LDO5V_IN: - charge_ldo5v_in_deal(); - break; - case CHARGE_EVENT_LDO5V_OFF: - charge_ldo5v_off_deal(); - break; - default: - break; - } - return 0; -} - -#endif - +#include "app_config.h" +#include "asm/charge.h" +#include "asm/pwm_led.h" +#include "system/event.h" +#include "system/app_core.h" +#include "system/includes.h" +#include "app_action.h" +#include "asm/wdt.h" +#include "app_main.h" +#include "app_power_manage.h" +#include "app_handshake.h" +#include "app_temperature.h" +#define LOG_TAG_CONST APP_CHARGE +#define LOG_TAG "[APP_CHARGE]" +#define LOG_ERROR_ENABLE +#define LOG_DEBUG_ENABLE +#define LOG_INFO_ENABLE +/* #define LOG_DUMP_ENABLE */ +#define LOG_CLI_ENABLE +#include "debug.h" + +#if TCFG_CHARGE_ENABLE + +#if TCFG_HANDSHAKE_ENABLE +static void handshake_complete(void) +{ + handshake_app_stop(); + if (get_lvcmp_det()) { + charge_start(); + } +} +#endif + +void charge_start_deal(void) +{ + log_info("%s\n", __func__); + power_set_mode(PWR_LDO15); +} + +void ldo5v_keep_deal(void) +{ + log_info("%s\n", __func__); +#if TCFG_HANDSHAKE_ENABLE + handshake_app_start(2, handshake_complete); +#endif + temperature_charge_state(BLE_TEMPERATURE_CHARGE_STATE_CHARGING); +} + +void charge_full_deal(void) +{ + log_info("%s\n", __func__); + charge_close(); + //power_set_soft_poweroff(); + //extern spple_set_soft_poweroff(); + //spple_set_soft_poweroff(); + temperature_charge_state(BLE_TEMPERATURE_CHARGE_STATE_FULL); + +} + +void charge_close_deal(void) +{ + log_info("%s\n", __FUNCTION__); +} + +void charge_ldo5v_in_deal(void) +{ + log_info("%s\n", __FUNCTION__); +#if TCFG_HANDSHAKE_ENABLE + handshake_app_start(2, handshake_complete); +#else + charge_start(); +#endif + temperature_charge_state(BLE_TEMPERATURE_CHARGE_STATE_CHARGING); +} + +void charge_ldo5v_off_deal(void) +{ + log_info("%s\n", __FUNCTION__); +#if TCFG_HANDSHAKE_ENABLE + handshake_app_stop(); +#endif + charge_close(); + power_set_mode(TCFG_LOWPOWER_POWER_SEL); +#if TCFG_SYS_LVD_EN + vbat_check_init(); +#endif + temperature_charge_state(BLE_TEMPERATURE_CHARGE_STATE_IDLE); +} + +int app_charge_event_handler(struct device_event *dev) +{ + log_info("%s\n %d", __FUNCTION__,dev->event); + switch (dev->event) { + case CHARGE_EVENT_CHARGE_START: + charge_start_deal(); + break; + case CHARGE_EVENT_CHARGE_CLOSE: + charge_close_deal(); + break; + case CHARGE_EVENT_CHARGE_FULL: + charge_full_deal(); + break; + case CHARGE_EVENT_LDO5V_KEEP: + ldo5v_keep_deal(); + break; + case CHARGE_EVENT_LDO5V_IN: + charge_ldo5v_in_deal(); + break; + case CHARGE_EVENT_LDO5V_OFF: + charge_ldo5v_off_deal(); + break; + default: + break; + } + return 0; +} + +#endif + diff --git a/fw-AC63_BT_SDK/apps/spp_and_le/modules/rtc_alarm.c b/fw-AC63_BT_SDK/apps/spp_and_le/modules/rtc_alarm.c index 8e11160..60f1c91 100644 --- a/fw-AC63_BT_SDK/apps/spp_and_le/modules/rtc_alarm.c +++ b/fw-AC63_BT_SDK/apps/spp_and_le/modules/rtc_alarm.c @@ -1,432 +1,434 @@ -#include "rtc_alarm.h" -#include "system/timer.h" -#include "app_config.h" -#include "asm/rtc.h" - -#if TCFG_RTC_ALARM_ENABLE - -#define ALARM_DEBUG_EN 1 - -#if ALARM_DEBUG_EN -#define alarm_printf(x, ...) printf("[RTC_ALARM]" x " ", ## __VA_ARGS__) -#define alarm_printf_buf put_buf -#define alarm_putchar putchar -#else -#define alarm_printf(...) -#define alarm_printf_buf(...) -#define alarm_putchar(...) -#endif - -#define RTC_MASK (0xaa55) -static T_ALARM alarm_tab[M_MAX_ALARM_NUMS]; -static T_ALARM_VM_MASK alarm_mask; -static u8 alarm_pnd_flag = 0; -static void (*_user_isr_cbfun)(u8) = NULL; - -void alarm_send_event(u8 index); -#if TCFG_RTC_ALARM_ENABLE -struct sys_time rtc_read_test; -struct sys_time alm_read_test; -struct sys_time alm_write_test = { - .year = 2024, - .month  =  1, - .day = 1, - .hour = 0, - .min = 0, - .sec = 20, -}; -#endif - - -static u8 alarm_vm_write_mask(u8 alarm_active_index) -{ - alarm_mask.head = RTC_MASK; - alarm_mask.alarm_active_index = alarm_active_index; - int ret = syscfg_write(VM_ALARM_MASK, (u8 *)&alarm_mask, sizeof(T_ALARM_VM_MASK)); - if (ret <= 0) { - alarm_printf("alarm mask write vm err!\n"); - return 1; - } - return 0; -} - -static u8 alarm_vm_read_mask(void) -{ - memset((u8 *)&alarm_mask, 0, sizeof(T_ALARM_VM_MASK)); - int ret = syscfg_read(VM_ALARM_MASK, (u8 *)&alarm_mask, sizeof(T_ALARM_VM_MASK)); - if ((ret <= 0) || (alarm_mask.head != RTC_MASK)) { //第一次读的时候 - alarm_printf("alarm mask read vm err!\n"); - return 1; - } - return 0; -} - -static u8 alarm_vm_write_time_tab(T_ALARM_VM *pAlarm_tab, u8 index) -{ - int ret; - T_ALARM_VM tmp = {0}; - tmp.head = RTC_MASK; - memcpy((u8 *)&tmp.alarm, (u8 *)pAlarm_tab, sizeof(T_ALARM)); - ret = syscfg_write(VM_ALARM_0 + index, (u8 *)&tmp, sizeof(T_ALARM_VM)); - if (ret <= 0) { - alarm_printf("alarm write vm err!\n"); - return 1; - } - return 0; -} - -static u8 alarm_vm_read_time_tab(T_ALARM_VM *pAlarm_tab, u8 index) -{ - T_ALARM_VM tmp = {0}; - int ret = syscfg_read(VM_ALARM_0 + index, (u8 *)&tmp, sizeof(T_ALARM_VM)); - if ((ret <= 0) || (tmp.head != RTC_MASK)) { - alarm_printf("alarm read vm err!\n"); - return 1; - } - memcpy((u8 *)pAlarm_tab, (u8 *)&tmp.alarm, sizeof(T_ALARM)); - return 0; -} - -static void alarm_calculate_next_few_time(struct sys_time *time, u16 days) -{ - if (!days) { - return; - } - u16 tmp_day = ymd_to_day(time); - tmp_day += days; - day_to_ymd(tmp_day, time); -} - -static void alarm_calculate_time_by_week_mode(struct sys_time *pTime, u8 mode) -{ - if (0 == mode) { - return; - } - if ((BIT(0)) == mode) { - return; - } - u16 tmp_mode = ((mode & 0xfe) << 7) | mode ; - u8 alarm_week = caculate_weekday_by_time(pTime); //获取闹钟是周几,1~7 - u8 i; - for (i = 1; i < 15; i++) { - if (tmp_mode & BIT(i)) { - if (i >= alarm_week) { - break; - } - } - } - alarm_calculate_next_few_time(pTime, i - alarm_week); -} -static u8 alarm_update_a_time_tab(struct sys_time *cTime, T_ALARM *pAlarm_tab, u32 *diff) -{ - struct sys_time *pTime = &(pAlarm_tab->time); - u32 c_tmp = (ymd_to_day(cTime) << 17) | ((cTime->hour & 0x1f) << 12) | ((cTime->min & 0x3f) << 6) | (cTime->sec & 0x3f); - u32 p_tmp = (ymd_to_day(pTime) << 17) | ((pTime->hour & 0x1f) << 12) | ((pTime->min & 0x3f) << 6) | (pTime->sec & 0x3f); - if (c_tmp >= p_tmp) { - pTime->year = cTime->year; - pTime->month = cTime->month; - pTime->day = cTime->day; - alarm_calculate_next_few_time(pTime, 1); - alarm_calculate_time_by_week_mode(pTime, pAlarm_tab->mode); - p_tmp = (ymd_to_day(pTime) << 17) | ((pTime->hour & 0x1f) << 12) | ((pTime->min & 0x3f) << 6) | (pTime->sec & 0x3f); - *diff = p_tmp - c_tmp; - return 1; - } else if (pAlarm_tab->mode & 0xfe) { - alarm_calculate_time_by_week_mode(pTime, pAlarm_tab->mode); - p_tmp = (ymd_to_day(pTime) << 17) | ((pTime->hour & 0x1f) << 12) | ((pTime->min & 0x3f) << 6) | (pTime->sec & 0x3f); - *diff = p_tmp - c_tmp; - return 1; - } - *diff = p_tmp - c_tmp; - return 0; -} -static u8 alarm_update_all_time(void) -{ - u8 err = 0; - u32 diff = 0; - u32 diff_min = -1; - u8 closest = -1; - - struct sys_time current_time = {0}; - rtc_ioctl(IOCTL_GET_SYS_TIME, (u32)¤t_time); - for (u8 i = 0; i < M_MAX_ALARM_NUMS; i ++) { - if (alarm_tab[i].en) { - err = alarm_update_a_time_tab(¤t_time, &alarm_tab[i], (u32 *)&diff); - if (err) { //时间有更新 - err = alarm_vm_write_time_tab(&alarm_tab[i], i); - if (err) { - return 1; - } - } - if (diff < diff_min) { - diff_min = diff; - closest = i; - } - } - } - if (closest > M_MAX_ALARM_NUMS) { - set_alarm_ctrl(0); - } - - if ((alarm_tab[closest].en)) { //最接近闹钟号跟记录的不一样,则要重设硬件寄存器,更新记录 - rtc_ioctl(IOCTL_SET_ALARM, (u32)&alarm_tab[closest].time); - if (closest != alarm_mask.alarm_active_index) { //最接近闹钟号跟记录不一样,更新VM - err = alarm_vm_write_mask(closest); - if (err) { - return 1; - } - } - } - - return 0; -} - - -void alarm_init(const struct rtc_dev_platform_data *arg) -{ - rtc_init(arg); - _user_isr_cbfun = arg->cbfun; - - u8 err = alarm_vm_read_mask(); - if (err) { - err = alarm_vm_write_mask(0xff); - if (err) { - alarm_printf("init : alarm mask read & write vm err!\n"); - return; - } - } - for (u8 i = 0; i < M_MAX_ALARM_NUMS; i ++) { - memset(&(alarm_tab[i]), 0, sizeof(T_ALARM)); - alarm_vm_read_time_tab(&(alarm_tab[i]), i); //读出数组 - } - if (alarm_pnd_flag) { //防止初始化前,就已经起闹钟中断了 - alarm_send_event(alarm_mask.alarm_active_index); - } else { - err = alarm_update_all_time(); //更新数组 - if (err) { - alarm_printf("init : update alarm write vm err!\n"); - return; - } - } - alarm_pnd_flag = 1; - - rtc_ioctl(IOCTL_GET_SYS_TIME,  &rtc_read_test); //读时钟 - alarm_printf("rtc_read_sys_time: %d-%d-%d %d:%d:%d\n", - rtc_read_test.year, - rtc_read_test.month, - rtc_read_test.day, - rtc_read_test.hour, - rtc_read_test.min, - rtc_read_test.sec); - - rtc_ioctl(IOCTL_GET_ALARM, &alm_read_test); //读闹钟 - alarm_printf("rtc_read_alarm: %d-%d-%d %d:%d:%d\n", - alm_read_test.year,                         - alm_read_test.month, - alm_read_test.day, - alm_read_test.hour, - alm_read_test.min, - alm_read_test.sec); -} - -void alarm_rtc_stop(void) -{ - set_alarm_ctrl(0); -} - -void alarm_rtc_start(void) -{ - set_alarm_ctrl(1); -} - -u8 alarm_get_active_index(void) -{ - return alarm_mask.alarm_active_index; -} - -u8 alarm_get_en_info(void) -{ - u8 en = 0; - for (u8 i = 0; i < M_MAX_ALARM_NUMS; i ++) { - en |= BIT(!!(alarm_tab[i].en)); - } - return en; -} - -void alarm_get_time_info(T_ALARM *p, u8 index) -{ - memcpy((u8 *)p, (u8 *)&alarm_tab[index], sizeof(T_ALARM)); -} - -u8 alarm_add(T_ALARM *p, u8 index) -{ - if (index > M_MAX_ALARM_INDEX) { - return 1; - } - if (p->mode > M_MAX_ALARM_MODE) { - return 1; - } - memcpy((u8 *)&alarm_tab[index], (u8 *)p, sizeof(T_ALARM)); - u8 err = alarm_vm_write_time_tab(&alarm_tab[index], index); - if (err) { - return 1; - } - err = alarm_update_all_time(); //更新数组 - if (err) { - return 1; - } - return 0; -} - -u8 alarm_en(u8 index, u8 en) -{ - if (index > M_MAX_ALARM_INDEX) { - return 1; - } - if ((!!en) == alarm_tab[index].en) { - return 0; - } - alarm_tab[index].en = !!en; - u8 err = alarm_vm_write_time_tab(&alarm_tab[index], index); - if (err) { - return 1; - } - err = alarm_update_all_time(); //更新数组 - if (err) { - return 1; - } - return 0; -} - -//设备事件响应demo -static void alarm_event_handler(struct sys_event *e) -{ - u8 index; - u8 err; - if ((u32)e->arg == DEVICE_EVENT_FROM_ALM) { - if (e->u.dev.event == DEVICE_EVENT_IN) { - index = (u8)(e->u.dev.value); - if (alarm_tab[index].mode == E_ALARM_MODE_ONCE) { - err = alarm_en(index, 0); - } else { - err = alarm_update_all_time(); //更新数组 - } - if (err) { - alarm_printf("isr : update alarm %d err!\n", index); - return; - } - if (_user_isr_cbfun) { - _user_isr_cbfun(index); - } - } - } -} -SYS_EVENT_HANDLER(SYS_DEVICE_EVENT, alarm_event_handler, 0); - -void alarm_send_event(u8 index) -{ - struct sys_event e; - e.type = SYS_DEVICE_EVENT; - e.arg = (void *)DEVICE_EVENT_FROM_ALM; - e.u.dev.event = DEVICE_EVENT_IN; - e.u.dev.value = index; - sys_event_notify(&e); -} - -void alm_wakeup_isr(void) -{ - if (alarm_pnd_flag) { - alarm_send_event(alarm_mask.alarm_active_index); - } else { - alarm_pnd_flag = 1; - } -} - - -void __attribute__((weak)) alarm_isr_user_cbfun(u8 index) -{ - printf("**** alarm %d : hello world ****\n", index); -} - -//参考的测试代码 -void user_alarm_test(void) -{ - T_ALARM tmp_alarm = {0}; - rtc_ioctl(IOCTL_GET_SYS_TIME, (u32)&tmp_alarm.time); - tmp_alarm.en = 1; //初始化默认打开 -#if 1 - tmp_alarm.mode = E_ALARM_MODE_ONCE; //此闹钟只起作用一次 - tmp_alarm.time.hour = 0; - tmp_alarm.time.min = 1; - alarm_add(&tmp_alarm, 0); -#endif - -#if 1 - tmp_alarm.mode = E_ALARM_MODE_EVERY_DAY; //此闹钟每天都起作用 - tmp_alarm.time.hour = 0; - tmp_alarm.time.min = 2; - alarm_add(&tmp_alarm, 1); -#endif - -#if 1 - tmp_alarm.mode = E_ALARM_MODE_EVERY_MONDAY | E_ALARM_MODE_EVERY_WEDNESDAY | E_ALARM_MODE_EVERY_SATURDAY; //此闹钟周1周3周6起作用 - tmp_alarm.time.hour = 0; - tmp_alarm.time.min = 3; - alarm_add(&tmp_alarm, 2); -#endif - -} - -#if TCFG_RTC_ALARM_ENABLE -//24小时内定时起来 -void rtc_alarm_set_timer(u32 seconds) -{ - alarm_printf("rtc_alarm_set_timer"); - - u8 add_hour = seconds / 3600; - u8 add_min = (seconds % 3600) / 60; - u8 add_sec = seconds % 60; - - rtc_ioctl(IOCTL_GET_SYS_TIME,  &rtc_read_test); //读时钟 - alarm_printf("rtc_read_sys_time: %d-%d-%d %d:%d:%d\n", - rtc_read_test.year, - rtc_read_test.month, - rtc_read_test.day, - rtc_read_test.hour, - rtc_read_test.min, - rtc_read_test.sec); - rtc_ioctl(IOCTL_GET_ALARM, &alm_read_test); //读闹钟 - - u16 tmp = rtc_read_test.sec + add_sec; - rtc_read_test.sec = tmp % 60; - - tmp = rtc_read_test.min + add_min + tmp / 60; - rtc_read_test.min = tmp % 60; - - tmp = rtc_read_test.hour + add_hour + tmp / 60; - rtc_read_test.hour = tmp % 24; - - rtc_read_test.day += (tmp / 24); - - T_ALARM tmp_alarm = {0}; - tmp_alarm.en = 1; //初始化默认打开 - tmp_alarm.mode = E_ALARM_MODE_ONCE; //此闹钟只起作用一次 - - memcpy(&tmp_alarm.time, &rtc_read_test, sizeof(struct sys_time)); - alarm_add(&tmp_alarm, 0); - memset(&rtc_read_test, 0, sizeof(struct sys_time)); - rtc_ioctl(IOCTL_GET_ALARM,  &alm_read_test); //读闹钟,校验是否写成功 - alarm_printf("rtc_read_alarm: %d-%d-%d %d:%d:%d\n", - alm_read_test.year,                         - alm_read_test.month, - alm_read_test.day, - alm_read_test.hour, - alm_read_test.min, - alm_read_test.sec); -} - - -#endif - -#endif - +#include "rtc_alarm.h" +#include "system/timer.h" +#include "app_config.h" +#include "asm/rtc.h" + +#if TCFG_RTC_ALARM_ENABLE + +#define ALARM_DEBUG_EN 1 + +#if ALARM_DEBUG_EN +#define alarm_printf(x, ...) printf("[RTC_ALARM]" x " ", ## __VA_ARGS__) +#define alarm_printf_buf put_buf +#define alarm_putchar putchar +#else +#define alarm_printf(...) +#define alarm_printf_buf(...) +#define alarm_putchar(...) +#endif + +#define RTC_MASK (0xaa55) +static T_ALARM alarm_tab[M_MAX_ALARM_NUMS]; +static T_ALARM_VM_MASK alarm_mask; +static u8 alarm_pnd_flag = 0; +static void (*_user_isr_cbfun)(u8) = NULL; + +void alarm_send_event(u8 index); +#if TCFG_RTC_ALARM_ENABLE +struct sys_time rtc_read_test; +struct sys_time alm_read_test; +struct sys_time alm_write_test = { + .year = 2024, + .month  =  1, + .day = 1, + .hour = 0, + .min = 0, + .sec = 20, +}; +#endif + + +static u8 alarm_vm_write_mask(u8 alarm_active_index) +{ + alarm_mask.head = RTC_MASK; + alarm_mask.alarm_active_index = alarm_active_index; + int ret = syscfg_write(VM_ALARM_MASK, (u8 *)&alarm_mask, sizeof(T_ALARM_VM_MASK)); + if (ret <= 0) { + alarm_printf("alarm mask write vm err!\n"); + return 1; + } + return 0; +} + +static u8 alarm_vm_read_mask(void) +{ + memset((u8 *)&alarm_mask, 0, sizeof(T_ALARM_VM_MASK)); + int ret = syscfg_read(VM_ALARM_MASK, (u8 *)&alarm_mask, sizeof(T_ALARM_VM_MASK)); + if ((ret <= 0) || (alarm_mask.head != RTC_MASK)) { //第一次读的时候 + alarm_printf("alarm mask read vm err!\n"); + return 1; + } + return 0; +} + +static u8 alarm_vm_write_time_tab(T_ALARM_VM *pAlarm_tab, u8 index) +{ + int ret; + T_ALARM_VM tmp = {0}; + tmp.head = RTC_MASK; + memcpy((u8 *)&tmp.alarm, (u8 *)pAlarm_tab, sizeof(T_ALARM)); + ret = syscfg_write(VM_ALARM_0 + index, (u8 *)&tmp, sizeof(T_ALARM_VM)); + if (ret <= 0) { + alarm_printf("alarm write vm err!\n"); + return 1; + } + return 0; +} + +static u8 alarm_vm_read_time_tab(T_ALARM_VM *pAlarm_tab, u8 index) +{ + T_ALARM_VM tmp = {0}; + int ret = syscfg_read(VM_ALARM_0 + index, (u8 *)&tmp, sizeof(T_ALARM_VM)); + if ((ret <= 0) || (tmp.head != RTC_MASK)) { + alarm_printf("alarm read vm err!\n"); + return 1; + } + memcpy((u8 *)pAlarm_tab, (u8 *)&tmp.alarm, sizeof(T_ALARM)); + return 0; +} + +static void alarm_calculate_next_few_time(struct sys_time *time, u16 days) +{ + if (!days) { + return; + } + u16 tmp_day = ymd_to_day(time); + tmp_day += days; + day_to_ymd(tmp_day, time); +} + +static void alarm_calculate_time_by_week_mode(struct sys_time *pTime, u8 mode) +{ + if (0 == mode) { + return; + } + if ((BIT(0)) == mode) { + return; + } + u16 tmp_mode = ((mode & 0xfe) << 7) | mode ; + u8 alarm_week = caculate_weekday_by_time(pTime); //获取闹钟是周几,1~7 + u8 i; + for (i = 1; i < 15; i++) { + if (tmp_mode & BIT(i)) { + if (i >= alarm_week) { + break; + } + } + } + alarm_calculate_next_few_time(pTime, i - alarm_week); +} +static u8 alarm_update_a_time_tab(struct sys_time *cTime, T_ALARM *pAlarm_tab, u32 *diff) +{ + struct sys_time *pTime = &(pAlarm_tab->time); + u32 c_tmp = (ymd_to_day(cTime) << 17) | ((cTime->hour & 0x1f) << 12) | ((cTime->min & 0x3f) << 6) | (cTime->sec & 0x3f); + u32 p_tmp = (ymd_to_day(pTime) << 17) | ((pTime->hour & 0x1f) << 12) | ((pTime->min & 0x3f) << 6) | (pTime->sec & 0x3f); + if (c_tmp >= p_tmp) { + pTime->year = cTime->year; + pTime->month = cTime->month; + pTime->day = cTime->day; + alarm_calculate_next_few_time(pTime, 1); + alarm_calculate_time_by_week_mode(pTime, pAlarm_tab->mode); + p_tmp = (ymd_to_day(pTime) << 17) | ((pTime->hour & 0x1f) << 12) | ((pTime->min & 0x3f) << 6) | (pTime->sec & 0x3f); + *diff = p_tmp - c_tmp; + return 1; + } else if (pAlarm_tab->mode & 0xfe) { + alarm_calculate_time_by_week_mode(pTime, pAlarm_tab->mode); + p_tmp = (ymd_to_day(pTime) << 17) | ((pTime->hour & 0x1f) << 12) | ((pTime->min & 0x3f) << 6) | (pTime->sec & 0x3f); + *diff = p_tmp - c_tmp; + return 1; + } + *diff = p_tmp - c_tmp; + return 0; +} +static u8 alarm_update_all_time(void) +{ + u8 err = 0; + u32 diff = 0; + u32 diff_min = -1; + u8 closest = -1; + + struct sys_time current_time = {0}; + rtc_ioctl(IOCTL_GET_SYS_TIME, (u32)¤t_time); + for (u8 i = 0; i < M_MAX_ALARM_NUMS; i ++) { + if (alarm_tab[i].en) { + err = alarm_update_a_time_tab(¤t_time, &alarm_tab[i], (u32 *)&diff); + if (err) { //时间有更新 + err = alarm_vm_write_time_tab(&alarm_tab[i], i); + if (err) { + return 1; + } + } + if (diff < diff_min) { + diff_min = diff; + closest = i; + } + } + } + if (closest > M_MAX_ALARM_NUMS) { + set_alarm_ctrl(0); + } + + if ((alarm_tab[closest].en)) { //最接近闹钟号跟记录的不一样,则要重设硬件寄存器,更新记录 + rtc_ioctl(IOCTL_SET_ALARM, (u32)&alarm_tab[closest].time); + if (closest != alarm_mask.alarm_active_index) { //最接近闹钟号跟记录不一样,更新VM + err = alarm_vm_write_mask(closest); + if (err) { + return 1; + } + } + } + + return 0; +} + + +void alarm_init(const struct rtc_dev_platform_data *arg) +{ + rtc_init(arg); + _user_isr_cbfun = arg->cbfun; + + u8 err = alarm_vm_read_mask(); + if (err) { + err = alarm_vm_write_mask(0xff); + if (err) { + alarm_printf("init : alarm mask read & write vm err!\n"); + return; + } + } + for (u8 i = 0; i < M_MAX_ALARM_NUMS; i ++) { + memset(&(alarm_tab[i]), 0, sizeof(T_ALARM)); + alarm_vm_read_time_tab(&(alarm_tab[i]), i); //读出数组 + } + if (alarm_pnd_flag) { //防止初始化前,就已经起闹钟中断了 + alarm_send_event(alarm_mask.alarm_active_index); + } else { + err = alarm_update_all_time(); //更新数组 + if (err) { + alarm_printf("init : update alarm write vm err!\n"); + return; + } + } + alarm_pnd_flag = 1; + + rtc_ioctl(IOCTL_GET_SYS_TIME,  &rtc_read_test); //读时钟 + alarm_printf("rtc_read_sys_time: %d-%d-%d %d:%d:%d\n", + rtc_read_test.year, + rtc_read_test.month, + rtc_read_test.day, + rtc_read_test.hour, + rtc_read_test.min, + rtc_read_test.sec); + + rtc_ioctl(IOCTL_GET_ALARM, &alm_read_test); //读闹钟 + alarm_printf("rtc_read_alarm: %d-%d-%d %d:%d:%d\n", + alm_read_test.year,                         + alm_read_test.month, + alm_read_test.day, + alm_read_test.hour, + alm_read_test.min, + alm_read_test.sec); +} + +void alarm_rtc_stop(void) +{ + set_alarm_ctrl(0); +} + +void alarm_rtc_start(void) +{ + set_alarm_ctrl(1); +} + +u8 alarm_get_active_index(void) +{ + return alarm_mask.alarm_active_index; +} + +u8 alarm_get_en_info(void) +{ + u8 en = 0; + for (u8 i = 0; i < M_MAX_ALARM_NUMS; i ++) { + en |= BIT(!!(alarm_tab[i].en)); + } + return en; +} + +void alarm_get_time_info(T_ALARM *p, u8 index) +{ + memcpy((u8 *)p, (u8 *)&alarm_tab[index], sizeof(T_ALARM)); +} + +u8 alarm_add(T_ALARM *p, u8 index) +{ + if (index > M_MAX_ALARM_INDEX) { + return 1; + } + if (p->mode > M_MAX_ALARM_MODE) { + return 1; + } + memcpy((u8 *)&alarm_tab[index], (u8 *)p, sizeof(T_ALARM)); + u8 err = alarm_vm_write_time_tab(&alarm_tab[index], index); + if (err) { + return 1; + } + err = alarm_update_all_time(); //更新数组 + if (err) { + return 1; + } + return 0; +} + +u8 alarm_en(u8 index, u8 en) +{ + if (index > M_MAX_ALARM_INDEX) { + return 1; + } + if ((!!en) == alarm_tab[index].en) { + return 0; + } + alarm_tab[index].en = !!en; + u8 err = alarm_vm_write_time_tab(&alarm_tab[index], index); + if (err) { + return 1; + } + err = alarm_update_all_time(); //更新数组 + if (err) { + return 1; + } + return 0; +} + +//设备事件响应demo +static void alarm_event_handler(struct sys_event *e) +{ + u8 index; + u8 err; + if ((u32)e->arg == DEVICE_EVENT_FROM_ALM) { + if (e->u.dev.event == DEVICE_EVENT_IN) { + index = (u8)(e->u.dev.value); + if (alarm_tab[index].mode == E_ALARM_MODE_ONCE) { + err = alarm_en(index, 0); + } else { + err = alarm_update_all_time(); //更新数组 + } + if (err) { + alarm_printf("isr : update alarm %d err!\n", index); + return; + } + if (_user_isr_cbfun) { + _user_isr_cbfun(index); + } + } + } +} +SYS_EVENT_HANDLER(SYS_DEVICE_EVENT, alarm_event_handler, 0); + +void alarm_send_event(u8 index) +{ + printf("**** rtc alarm_send_event ****\n"); + struct sys_event e; + e.type = SYS_DEVICE_EVENT; + e.arg = (void *)DEVICE_EVENT_FROM_ALM; + e.u.dev.event = DEVICE_EVENT_IN; + e.u.dev.value = index; + sys_event_notify(&e); +} + +void alm_wakeup_isr(void) +{ + printf("**** rtc alm_wakeup_isr ****\n"); + if (alarm_pnd_flag) { + alarm_send_event(alarm_mask.alarm_active_index); + } else { + alarm_pnd_flag = 1; + } +} + + +void __attribute__((weak)) alarm_isr_user_cbfun(u8 index) +{ + printf("**** alarm %d : hello world ****\n", index); +} + +//参考的测试代码 +void user_alarm_test(void) +{ + T_ALARM tmp_alarm = {0}; + rtc_ioctl(IOCTL_GET_SYS_TIME, (u32)&tmp_alarm.time); + tmp_alarm.en = 1; //初始化默认打开 +#if 1 + tmp_alarm.mode = E_ALARM_MODE_ONCE; //此闹钟只起作用一次 + tmp_alarm.time.hour = 0; + tmp_alarm.time.min = 1; + alarm_add(&tmp_alarm, 0); +#endif + +#if 1 + tmp_alarm.mode = E_ALARM_MODE_EVERY_DAY; //此闹钟每天都起作用 + tmp_alarm.time.hour = 0; + tmp_alarm.time.min = 2; + alarm_add(&tmp_alarm, 1); +#endif + +#if 1 + tmp_alarm.mode = E_ALARM_MODE_EVERY_MONDAY | E_ALARM_MODE_EVERY_WEDNESDAY | E_ALARM_MODE_EVERY_SATURDAY; //此闹钟周1周3周6起作用 + tmp_alarm.time.hour = 0; + tmp_alarm.time.min = 3; + alarm_add(&tmp_alarm, 2); +#endif + +} + +#if TCFG_RTC_ALARM_ENABLE +//24小时内定时起来 +void rtc_alarm_set_timer(u32 seconds) +{ + alarm_printf("rtc_alarm_set_timer"); + + u8 add_hour = seconds / 3600; + u8 add_min = (seconds % 3600) / 60; + u8 add_sec = seconds % 60; + + rtc_ioctl(IOCTL_GET_SYS_TIME,  &rtc_read_test); //读时钟 + alarm_printf("rtc_read_sys_time: %d-%d-%d %d:%d:%d\n", + rtc_read_test.year, + rtc_read_test.month, + rtc_read_test.day, + rtc_read_test.hour, + rtc_read_test.min, + rtc_read_test.sec); + rtc_ioctl(IOCTL_GET_ALARM, &alm_read_test); //读闹钟 + + u16 tmp = rtc_read_test.sec + add_sec; + rtc_read_test.sec = tmp % 60; + + tmp = rtc_read_test.min + add_min + tmp / 60; + rtc_read_test.min = tmp % 60; + + tmp = rtc_read_test.hour + add_hour + tmp / 60; + rtc_read_test.hour = tmp % 24; + + rtc_read_test.day += (tmp / 24); + + T_ALARM tmp_alarm = {0}; + tmp_alarm.en = 1; //初始化默认打开 + tmp_alarm.mode = E_ALARM_MODE_ONCE; //此闹钟只起作用一次 + + memcpy(&tmp_alarm.time, &rtc_read_test, sizeof(struct sys_time)); + alarm_add(&tmp_alarm, 0); + memset(&rtc_read_test, 0, sizeof(struct sys_time)); + rtc_ioctl(IOCTL_GET_ALARM,  &alm_read_test); //读闹钟,校验是否写成功 + alarm_printf("rtc_read_alarm: %d-%d-%d %d:%d:%d\n", + alm_read_test.year,                         + alm_read_test.month, + alm_read_test.day, + alm_read_test.hour, + alm_read_test.min, + alm_read_test.sec); +} + + +#endif + +#endif +