/* * Copyright (c) 2019-2023 Beijing Hanwei Innovation Technology Ltd. Co. and * its subsidiaries and affiliates (collectly called MKSEMI). * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form, except as embedded into an MKSEMI * integrated circuit in a product or a software update for such product, * must reproduce the above copyright notice, this list of conditions and * the following disclaimer in the documentation and/or other materials * provided with the distribution. * * 3. Neither the name of MKSEMI nor the names of its contributors may be used * to endorse or promote products derived from this software without * specific prior written permission. * * 4. This software, with or without modification, must only be used with a * MKSEMI integrated circuit. * * 5. Any software provided in binary form under this license must not be * reverse engineered, decompiled, modified and/or disassembled. * * THIS SOFTWARE IS PROVIDED BY MKSEMI "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL MKSEMI OR CONTRIBUTORS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "mk_trace.h" #include "mk_wdt.h" #include "mk_reset.h" #include "mk_gpio.h" #include "mk_misc.h" #include "mk_sleep_timer.h" #include "mk_power.h" #include "mk_uwb.h" #include "mk_calib.h" #include "mk_uart.h" #include "mk_spi.h" #include "mk_flash.h" #include "Usart.h" #include #include #include "board.h" #include "pal_sys.h" #include "wsf_os.h" #include "wsf_timer.h" #include "wsf_buf.h" #include "wsf_nvm.h" #include "app.h" #include "ranging_fira.h" #include "uwb_api.h" #include "lib_ranging.h" #include "uci_tl_task.h" #include "libc_rom.h" #ifdef UWB_UCI_TEST_EN #include "uwb_test.h" #endif #ifdef CELL_PHONE_EN #include "mk_efuse.h" #define EFUSE_FLASH_EN_ADDR (0x67) #define EFUSE_FLASH_EN_BIT (0x80) bool check_flash_bit_of_efuse(void); bool program_efuse(void); bool check_flash_bit_of_efuse(void) { uint8_t val; val = efuse_read_byte(EFUSE_FLASH_EN_ADDR); return ((val & EFUSE_FLASH_EN_BIT) ? true : false); } bool program_efuse(void) { efuse_program_byte(EFUSE_FLASH_EN_ADDR, EFUSE_FLASH_EN_BIT); if (check_flash_bit_of_efuse()) { LOG_INFO(TRACE_MODULE_APP, "Program eFuse INT_FLASH bit successfully.\r\n"); return true; } else { LOG_INFO(TRACE_MODULE_APP, "Program eFuse INT_FLASH bit failed.\r\n"); return false; } return true; } #endif //***************************************************************************** // // WSF buffer pools. // //***************************************************************************** #define WSF_BUF_POOLS 5 void Fira_Change_Task(void); extern uint8_t normal_flag,log_4g_enable_flag,lora_tx_flag; extern uint16_t ip0,ip1,ip2,ip3,port; uint8_t group_id,enable_sleep_count; uint32_t dev_id; uint16_t disoffset; uint8_t flag_sleeptimer,flag_secondtask,secondtask_count; float nomove_count; // Default pool descriptor. static wsfBufPoolDesc_t poolDescriptors[WSF_BUF_POOLS] = { {32, 26}, {64, 24}, {128, 4}, {256 + 32, 4}, {1024 + 32, 2}, }; static void sleep_timer_callback(void *dev, uint32_t time) { // LOG_INFO(TRACE_MODULE_APP, "Wake up by sleep timer %d\r\n", time); } static void sleep_timer_callback_normal(void *dev, uint32_t time) { if(secondtask_count++%2==0) { flag_secondtask = 1; }else{ flag_secondtask = 0; } // if(delaysleep_count>0) // delaysleep_count--; } void Program_Init(void) { Usart1ParseDataCallback = UsartParseDataHandler;//Ðè¸ÄΪĬÈÏΪgps´¦Àí£¬UsartParseDataHandlerΪÉý¼¶´¦Àíµ±µ÷ÊÔʱºò¸ÄΪ parameter_init_anchor();//g_com_map±í³õʼ»¯½ÇɫĬÈÏΪ»ùÕ¾ dev_id=g_com_map[DEV_ID];//ÕâÀﲻ̫¶Ô group_id=(uint8_t)g_com_map[GROUP_ID];//×éID // tag_frequency = 1000/g_com_map[COM_INTERVAL];//²â¾àƵÂÊÕâ¸ö´æµÄÊDzâ¾àʱ¼ä memcpy(&disoffset,&g_com_map[DIST_OFFSET],2); // g_com_map[ALARM_DISTANCE1] = 40; // g_com_map[ALARM_DISTANCE2] = 40; // warning_distance=g_com_map[ALARM_DISTANCE1]; // prewarning_distance=g_com_map[ALARM_DISTANCE2]; //g_com_map[SEND_4G_SECOND] // if(g_com_map[SEND_4G_SECOND]<30) // { // gps_open_flag=0; // }else{ // gps_open_flag=1; // } g_com_map[MODBUS_MODE] = 0; log_4g_enable_flag=g_com_map[LOG_4G_ENABLE]; ip0 = (g_com_map[TCP_IP_0]>>12&0xf)*1000+(g_com_map[TCP_IP_0]>>8&0xf)*100+(g_com_map[TCP_IP_0]>>4&0xf)*10+(g_com_map[TCP_IP_0]&0xf); ip1 = (g_com_map[TCP_IP_1]>>12&0xf)*1000+(g_com_map[TCP_IP_1]>>8&0xf)*100+(g_com_map[TCP_IP_1]>>4&0xf)*10+(g_com_map[TCP_IP_1]&0xf); ip2 = (g_com_map[TCP_IP_2]>>12&0xf)*1000+(g_com_map[TCP_IP_2]>>8&0xf)*100+(g_com_map[TCP_IP_2]>>4&0xf)*10+(g_com_map[TCP_IP_2]&0xf); ip3 = (g_com_map[TCP_IP_3]>>12&0xf)*1000+(g_com_map[TCP_IP_3]>>8&0xf)*100+(g_com_map[TCP_IP_3]>>4&0xf)*10+(g_com_map[TCP_IP_3]&0xf); port = g_com_map[TCP_PORT]; g_com_map[VERSION] = (1<<8)|0; LOG_INFO(TRACE_MODULE_APP,"É豸ID: %x .\r\n",dev_id); // if(gpio_pin_get_val(MODE_CHANGE_PIN)) // LOG_INFO(TRACE_MODULE_APP,"¹Ì¼þ°æ±¾:MK_Air_tagģʽ V%d.%d. \r\n",g_com_map[VERSION]>>8,g_com_map[VERSION]&0xff); // else{ // LOG_INFO(TRACE_MODULE_APP,"¹Ì¼þ°æ±¾:MK_Ãâ²¼Ïßģʽ V%d.%d. \r\n",g_com_map[VERSION]>>8,g_com_map[VERSION]&0xff); // } LOG_INFO(TRACE_MODULE_APP,"·þÎñÆ÷µØÖ·: %d.%d.%d.%d:%d.\r\n",ip0,ip1,ip2,ip3,port); } void MinuteTask(void) { // adc_get(&sample[0], NUM_SAMPLES, adc_callback);//adc²ÉÑù } /********************************************************************************************************/ static void Lora_irq_handler(enum IO_PIN_T pin) { RadioIrqProcess(); } void SecondTask(void) {static uint8_t second_count; if(second_count++>60) { second_count = 0; MinuteTask(); } lora_tx_flag=1; //Lora_Tx_Poll(); // //UWB״̬¼ì²â //if(!power_low_flag)//µÍ¹©µçϲ»ÐèÒª¼ì²âÖØÁ¬ // { // if(IfTCPConnected()) // { // TCP_reconnect_timer =0; // flag_TCP_reconnectting = 0; // } else { // if(TCP_reconnect_timer<30)//Èç¹ûTCPûÓÐÁ¬½Ó£¬Ã¿¸ô10·ÖÖÓ³¢ÊÔÁ¬½Ó30Ãë // { // flag_TCP_reconnectting = 1; // } else { // flag_TCP_reconnectting = 0; // } // if(TCP_reconnect_timer++>600) // { // TCP_reconnect_timer = 0; // } // } // } HIDO_TimerTick(); if(nomove_count<=g_com_map[NOMOVESLEEP_TIME])//·ÀÖ¹Òç³ö nomove_count++; else{ nomove_count=g_com_map[NOMOVESLEEP_TIME]+1; } } void spi_init(void) { struct SPI_CFG_T usr_spi_cfg = { .bit_rate = 1000000, .data_bits = 8, //#if TEST_SPI_MASTER .slave = 0, //#else // .slave = 1, //#endif .clk_phase = 0, .clk_polarity = 0, .ti_mode = 0, //#if (TEST_SPI_MODE == TEST_SPI_POLL_MODE) .dma_rx = false, .dma_tx = false, .int_rx = false, .int_tx = false, //#elif (TEST_SPI_MODE == TEST_SPI_INTERUPT_MODE) // .dma_rx = false, // .dma_tx = false, // .int_rx = true, // .int_tx = true, //#elif (TEST_SPI_MODE == TEST_SPI_DMA_MODE) // .dma_rx = true, // .dma_tx = true, // .int_rx = false, // .int_tx = false, //#endif }; spi_open(SPI_ID0, &usr_spi_cfg); } static void board_init(void) { uint32_t internal_flash = (REG_READ(0x40000018) >> 17) & 0x1; uint32_t external_flash = (REG_READ(0x40010030) >> 28) & 0x3; // Clock configuration board_clock_run(); boot_deinit();//ÐÂ¼ÓµÄ // Pin configuration board_pins_config(); // Trace configuration board_debug_console_open(TRACE_PORT_UART1); // Reset reason reset_cause_get(); reset_cause_clear(); #ifndef CELL_PHONE_EN // Load calibration parameters from NVM if (internal_flash || external_flash == 1) { WsfNvmInit(); board_calibration_params_load(); flash_close(FLASH_ID0); } else { board_calibration_params_default(); } #else if (internal_flash) { program_efuse(); } board_calibration_params_default(); #endif // Chip calibration calib_chip(); gpio_open(); #ifdef CELL_PHONE_EN // Configure IO_04 for RF Switch gpio_pin_set_dir(IO_PIN_4, GPIO_DIR_OUT, 0); #else spi_init(); // ģʽÅжϽźÍspi nrst½Å³õʼ»¯ board_mode_pin_init(); Program_Init(); // board_led_on(BOARD_LED_1); #endif Board_LORA_NVIC_Init(Lora_irq_handler); board_configure(); } void app_process_handle(uint8_t msg_id, const void *param) { switch (msg_id) { case APP_TEST_TIMER1_MSG: { #if ANT_DELAY_CAL_EN // stop calibration uwbapi_session_stop(uwb_app_config.session_id); uwbapi_session_deinit(uwb_app_config.session_id); // restart UCI RX uci_tl_rx_restart(); #endif } break; default: break; } } void Fira_Change_Task(void) { } static void uart_receive_callback(void *dev, uint32_t err_code) { uart_receive(UART_ID1,m_EUART_DMA_RXBuf,EUART_RX_BUF_SIZE,uart_receive_callback); } void uart0_receive_callback(void *dev, uint32_t err_code) { uart_receive(UART_ID0,m_EUART0_DMA_RXBuf,EUART0_RX_BUF_SIZE,uart0_receive_callback); } uint8_t bat_percent; uint8_t stationary_flag; void mcu_deep_sleep(void) { uint32_t lock; trace_flush(); lock = int_lock(); sleep_timer_stop(); power_enter_power_down_mode(1); int_unlock(lock); } int main(void) { // Initialize MCU system board_init(); // Disable watchdog timer wdt_close(WDT_ID0); LOG_INFO(TRACE_MODULE_APP, "UCI FiRa example\r\n"); //delay_ms(300);//ʹlog´òÓ¡Íê±Ï if(gpio_pin_get_val(SLEEP_PIN)) { if(gpio_pin_get_val(MODE_CHANGE_PIN))//¼ÇµÃ¸Ä»ØÀ´ÓëÕýʽµÄÏà·´ { LOG_INFO(TRACE_MODULE_APP,"¹Ì¼þ°æ±¾:MK_Air_tagģʽ V%d.%d. \r\n",g_com_map[VERSION]>>8,g_com_map[VERSION]&0xff); // Platform init for WSF PalSysInit(); // Initialize os // // Set up timers for the WSF scheduler. // WsfOsInit(); WsfTimerInit(); sys_tick_callback_set(WsfTimerUpdateTicks); // // Initialize a buffer pool for WSF dynamic memory needs. // uint32_t wsfBufMemLen = WsfBufInit(WSF_BUF_POOLS, poolDescriptors); if (wsfBufMemLen > FREE_MEM_SIZE) { LOG_INFO(TRACE_MODULE_APP, "Memory pool is not enough %d\r\n", wsfBufMemLen - FREE_MEM_SIZE); } // // Create app task // wsfHandlerId_t handlerId = WsfOsSetNextHandler(app_handler); app_init(handlerId); // // Create ranging task or test task // handlerId = WsfOsSetNextHandler(ranging_handler); ranging_init(handlerId); #ifdef UWB_UCI_TEST_EN // Create test task handlerId = WsfOsSetNextHandler(uwb_test_handler); uwb_test_init(handlerId); #endif #ifndef MY_MODE uwb_open(); // set advanced parameters struct PHY_ADV_CONFIG_T adv_config = { // RPM0: 40, RPM3: 60 .thres_fap_detect = 60, // RPM0: 4, RPM3: 8 .nth_scale_factor = 8, // RFrame SP0: 0/1, Others: 0/1/2/3 .ranging_performance_mode = 3, #if RX_ANT_PORTS_NUM == 4 .skip_weakest_port_en = 1, #else .skip_weakest_port_en = 0, #endif }; phy_adv_params_configure(&adv_config); // which RX ports will be used for AoA/PDoA phy_rx_ant_mode_set(RX_ANT_PORTS_COMBINATION); uwbs_init(); uwb_app_config.ranging_flow_mode = (uint8_t)(RANGING_FLOW_FIRA); uwb_app_config.filter_en = (uint8_t)(FILTER_EN); uwb_app_config.session_param.tx_power_level = board_param.tx_power_fcc[CALIB_CH(uwb_app_config.ppdu_params.ch_num)]; uwb_app_config.ppdu_params.rx_ant_id = (uint8_t)(RX_MAIN_ANT_PORT); #elif defined MY_MODE Uwb_init();//ĬÈÏΪÎÒÃDzâ¾àÅäÖà OpenUWB(); uart_receive(UART_ID1,m_EUART_DMA_RXBuf,EUART_RX_BUF_SIZE,uart_receive_callback); #endif // // Create UCI transmission layer task // handlerId = WsfOsSetNextHandler(uci_tl_handler); uci_tl_init(handlerId); // Initialize low power mode power_init(); #if LOW_POWER_EN power_mode_request(POWER_UNIT_USER, POWER_MODE_POWER_DOWN); uwb_app_config.low_power_en = 1; #else power_mode_request(POWER_UNIT_USER, POWER_MODE_SLEEP); uwb_app_config.low_power_en = 0; #endif // Enable sleep timer sleep_timer_open(true, SLEEP_TIMER_MODE_ONESHOT, sleep_timer_callback); while (1) { wsfOsDispatcher(); power_manage(); if(!gpio_pin_get_val(SLEEP_PIN)) { LOG_INFO(TRACE_MODULE_APP, "½øÈëÐÝÃßģʽ\r\n"); mcu_deep_sleep(); } } }else{ LOG_INFO(TRACE_MODULE_APP,"¹Ì¼þ°æ±¾:MK_Ãâ²¼Ïßģʽ V%d.%d. \r\n",g_com_map[VERSION]>>8,g_com_map[VERSION]&0xff); uart0_Init_normal(); Lora_1268_Init(); SwitchLoraSettings(478,7,22); Uwb_init();//ĬÈÏΪÎÒÃDzâ¾àÅäÖà OpenUWB(); uart_receive(UART_ID1,m_EUART_DMA_RXBuf,EUART_RX_BUF_SIZE,uart_receive_callback); uart_receive(UART_ID0,m_EUART0_DMA_RXBuf,EUART0_RX_BUF_SIZE,uart0_receive_callback); power_init(); sleep_timer_open(true, SLEEP_TIMER_MODE_RELOAD, sleep_timer_callback_normal); sleep_timer_start(__MS_TO_32K_CNT(SLEEP_TIMER_NUM));//²âÊÔ while (1) { uwb_app_poll();//ÎÒÃǵIJâ¾àÂß¼­ if(flag_secondtask) { flag_secondtask = 0; SecondTask(); //Lora_Tx_Poll(); } Lora_Tx_Poll(); if(!gpio_pin_get_val(SLEEP_PIN)) { LOG_INFO(TRACE_MODULE_APP, "½øÈëÐÝÃßģʽ\r\n"); mcu_deep_sleep(); } IdleTask(); } } }else{ //delay_ms(300); LOG_INFO(TRACE_MODULE_APP, "½øÈëÐÝÃßģʽ\r\n"); power_init(); mcu_deep_sleep(); } } void app_restore_from_power_down(void) { }