From e06c240191c5c975fc9e2fb539e6b8503a656766 Mon Sep 17 00:00:00 2001 From: helloyifa Date: Fri, 30 May 2025 09:13:42 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8F=90=E4=BA=A4=E6=9C=80=E6=96=B0=20RTC?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=E9=AA=8C=E8=AF=81=E6=88=90=E5=8A=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../apps/hid/board/bd19/board_ac6323a_demo.c | 1161 +++++++++-------- fw-AC63_BT_SDK/apps/hid/modules/rtc_alarm.c | 866 ++++++------ .../apps/spp_and_le/app_temperature.c | 41 +- fw-AC63_BT_SDK/iT12 腋温计BLE 通讯协议.txt | 21 + 4 files changed, 1064 insertions(+), 1025 deletions(-) create mode 100644 fw-AC63_BT_SDK/iT12 腋温计BLE 通讯协议.txt diff --git a/fw-AC63_BT_SDK/apps/hid/board/bd19/board_ac6323a_demo.c b/fw-AC63_BT_SDK/apps/hid/board/bd19/board_ac6323a_demo.c index c5a92cd..e51ffe2 100644 --- a/fw-AC63_BT_SDK/apps/hid/board/bd19/board_ac6323a_demo.c +++ b/fw-AC63_BT_SDK/apps/hid/board/bd19/board_ac6323a_demo.c @@ -1,579 +1,582 @@ -#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, +}; + +/************************** 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, + .trim_t = 1, //软关机情况下,1min唤醒一次trim 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/hid/modules/rtc_alarm.c b/fw-AC63_BT_SDK/apps/hid/modules/rtc_alarm.c index 1ecfd13..3a518c6 100644 --- a/fw-AC63_BT_SDK/apps/hid/modules/rtc_alarm.c +++ b/fw-AC63_BT_SDK/apps/hid/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 0 - -#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 0 + +#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) +{ + printf("**** alarm_event_handler****\n"); + 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) +{ + printf("**** 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 + 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 e023899..2b57c3b 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 @@ -127,8 +127,8 @@ void ble_receive_callback(u8* data,u16 len){ } } /** - * - *当有蓝牙连接1 蓝牙断开 + * + *当有蓝牙连接1 蓝牙断开 */ void ble_on_connect_change(u8 is_connect){ printf("ble_on_connect_change :(state:%d) \n",is_connect); @@ -427,21 +427,19 @@ static uint8_t reversal(uint8_t data) //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); } @@ -449,7 +447,7 @@ static uint8_t reversal(uint8_t data) /** * 更新BLE广播信息 * //BBOOEEbs 2字节体温 2字节物温 2字节环温 1字节电量 1字节状态 - * 状态:00 正常模式 01 进入充电 + * 状态: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; @@ -494,12 +492,12 @@ void rtc_test_demo() //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 @@ -516,7 +514,7 @@ void temperature_charge_lowpower(u8 on){ } void temperature_work_led(u8 on){ - + if(on){ gpio_set_hd0(BLE_TEMPERATURE_WORK_LED, 1); gpio_direction_output(BLE_TEMPERATURE_WORK_LED, 1); @@ -659,9 +657,24 @@ void alarm_isr_user_cbfun(u8 index) */ void timer_sleep_callback(void) { - //关机开启闹钟 + //关机开启闹钟 printf(">>>>>>>>>>>>>>>>> timer_sleep_callback ...\n"); - rtc_alarm_set_timer(10); + //先查明当前连接的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); + } + + if( charge_state == 1){ + printf("charging !! do not sleep\n"); + return ; + } + + rtc_alarm_set_timer(5); temperature_set_soft_poweroff(); } @@ -706,7 +719,7 @@ void temperature_init(void) gpio_direction_output(IO_PORTB_06, 1); - + // NTC VDD //gpio_set_direction(IO_PORTB_05,0); //gpio_direction_output(IO_PORTB_05, 1); diff --git a/fw-AC63_BT_SDK/iT12 腋温计BLE 通讯协议.txt b/fw-AC63_BT_SDK/iT12 腋温计BLE 通讯协议.txt new file mode 100644 index 0000000..e4ad1c1 --- /dev/null +++ b/fw-AC63_BT_SDK/iT12 腋温计BLE 通讯协议.txt @@ -0,0 +1,21 @@ +iT12 腋温计通讯协议 + +1.搜索蓝牙iT12_XXXX 并连接设备 ( 使用时建议申请ble 通讯的MTU 为254 否则会数据分包;) + +2.iT12的通讯Service UUID为 0xAE30的 +3.监听UUID为 0xAE02 的Characteristic 可以实时监听回传数据 +4.指令通过UUID为 0xAE01 的Characteristic发送 + +5.指令CMD +5.1 获取温度 :AT+TEMP=? + 回复:AT+TEMP=255,265,365 (255表示环境温度, 265表示物体温度 , 365表示体温) + +5.2 获取电池电量百分百 :AT+BATP=? + 回复:AT+BATP=80 (88表示电量为80%) + +5.3 获取电池电压 :AT+BATT=? + 回复:AT+BATT=333 (333 表示3.33V) + +5.4 获取固件版本 :AT+VER=? + 回复:AT+VER=1.0.1 (版本号 1.0.1) + \ No newline at end of file