/*---------------------------------------------------------------------------- * Copyright (c) Fenda Technologies Co., Ltd. 2021. All rights reserved. * * Description: task_radio.c * * Author: saimen * * Create: 2022-08-08 *--------------------------------------------------------------------------*/ #include "sys_typedef.h" #include "wsf_types.h" #include "wsf_trace.h" #include "wsf_buf.h" #include "wsf_timer.h" #include "hci_handler.h" #include "dm_handler.h" #include "l2c_handler.h" #include "att_handler.h" #include "smp_handler.h" #include "l2c_api.h" #include "att_api.h" #include "smp_api.h" #include "app_api.h" #include "hci_core.h" #include "hci_drv.h" #include "hci_drv_apollo.h" #include "hci_drv_cooper.h" #include "FreeRTOS.h" #include "task.h" #include "queue.h" #include "timers.h" #include "am_mcu_apollo.h" #include "am_util.h" #include "wsf_msg.h" #include "amota_api.h" #include "amotas_api.h" #include "app_ui.h" #include "user_adapter.h" #define ENABLE_STATIC_PRINT false extern uint32_t am_util_stdio_printf(const char *pcFmt, ...); #define static_print_remind(...) am_util_stdio_printf(__VA_ARGS__) #if ENABLE_STATIC_PRINT #define static_print_info(...) am_util_stdio_printf(__VA_ARGS__) #else #define static_print_info(...) #endif #define WSF_BUF_POOLS 4 TaskHandle_t radio_task_handle; // Important note: the size of g_pui32BufMem should includes both overhead of internal // buffer management structure, wsfBufPool_t (up to 16 bytes for each pool), and pool // description (e.g. g_psPoolDescriptors below). // Memory for the buffer pool // extra AMOTA_PACKET_SIZE bytes for OTA handling static uint32_t g_pui32BufMem[ (WSF_BUF_POOLS*16 + 16*8 + 32*4 + 64*6 + 280*14) / sizeof(uint32_t)]; // Default pool descriptor. static wsfBufPoolDesc_t g_psPoolDescriptors[WSF_BUF_POOLS] = { { 16, 8 }, { 32, 4 }, { 64, 6 }, { 280, 14 } }; void exactle_stack_init(void); //***************************************************************************** // // Tracking variable for the scheduler timer. // //***************************************************************************** void radio_timer_handler(void); //***************************************************************************** // // Initialization for the ExactLE stack. // //***************************************************************************** void exactle_stack_init(void) { wsfHandlerId_t handlerId; uint16_t wsfBufMemLen; // // Set up timers for the WSF scheduler. // WsfOsInit(); WsfTimerInit(); // // Initialize a buffer pool for WSF dynamic memory needs. // wsfBufMemLen = WsfBufInit(sizeof(g_pui32BufMem), (uint8_t *)g_pui32BufMem, WSF_BUF_POOLS, g_psPoolDescriptors); if (wsfBufMemLen > sizeof(g_pui32BufMem)) { static_print_remind("Memory pool is too small by %d\r\n", wsfBufMemLen - sizeof(g_pui32BufMem)); } // // Initialize the WSF security service. // SecInit(); SecAesInit(); SecCmacInit(); SecEccInit(); // // Set up callback functions for the various layers of the ExactLE stack. // handlerId = WsfOsSetNextHandler(HciHandler); HciHandlerInit(handlerId); handlerId = WsfOsSetNextHandler(DmHandler); DmDevVsInit(0); DmAdvInit(); DmPhyInit(); DmConnInit(); DmConnSlaveInit(); DmSecInit(); DmSecLescInit(); DmPrivInit(); DmHandlerInit(handlerId); handlerId = WsfOsSetNextHandler(L2cSlaveHandler); L2cSlaveHandlerInit(handlerId); L2cInit(); L2cSlaveInit(); handlerId = WsfOsSetNextHandler(AttHandler); AttHandlerInit(handlerId); AttsInit(); AttsIndInit(); AttcInit(); handlerId = WsfOsSetNextHandler(SmpHandler); SmpHandlerInit(handlerId); SmprInit(); SmprScInit(); HciSetMaxRxAclLen(251); handlerId = WsfOsSetNextHandler(AppHandler); AppHandlerInit(handlerId); handlerId = WsfOsSetNextHandler(AmotaHandler); AmotaHandlerInit(handlerId); handlerId = WsfOsSetNextHandler(HciDrvHandler); HciDrvHandlerInit(handlerId); } //***************************************************************************** // // GPIO interrupt handler. // //***************************************************************************** void am_cooper_irq_isr(void) { uint32_t ui32IntStatus; am_hal_gpio_interrupt_irq_status_get(AM_COOPER_IRQn, false, &ui32IntStatus); am_hal_gpio_interrupt_irq_clear(AM_COOPER_IRQn, ui32IntStatus); am_hal_gpio_interrupt_service(AM_COOPER_IRQn, ui32IntStatus); } //***************************************************************************** // // UART interrupt handler. // //***************************************************************************** //void //am_uart_isr(void) //{ // uint32_t ui32Status; // // // // Read and save the interrupt status, but clear out the status register. // // // ui32Status = UARTn(0)->MIS; // UARTn(0)->IEC = ui32Status; //} //***************************************************************************** // // Perform initial setup for the radio task. // //***************************************************************************** void task_radio_steup(void) { static_print_remind("RadioTask: setup\r\n"); NVIC_SetPriority(COOPER_IOM_IRQn, NVIC_configMAX_SYSCALL_INTERRUPT_PRIORITY); NVIC_SetPriority(AM_COOPER_IRQn, NVIC_configMAX_SYSCALL_INTERRUPT_PRIORITY); } //***************************************************************************** // // Short Description. // //***************************************************************************** void task_radio_suspend(void) { vTaskSuspend(radio_task_handle); } //***************************************************************************** // // Short Description. // //***************************************************************************** void task_radio_entry(void *pvParameters) { #if WSF_TRACE_ENABLED == TRUE // // Enable ITM // static_print_remind("task_radio_entry \r\n"); #endif task_radio_steup(); // // Boot the radio. // HciDrvRadioBoot(1); // // Initialize the main ExactLE stack. // exactle_stack_init(); // uncomment the following to set custom Bluetooth address here // { // uint8_t bd_addr[6] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; // HciVscSetCustom_BDAddr(&bd_addr); // } // // Start the "Amota" profile. // AmotaStart(); uint8_t mac_addr_str[18] = {0}; memset(mac_addr_str, 0, sizeof(mac_addr_str)); user_format_ble_mac(mac_addr_str, 17); static_print_remind("BLE MAC: %s\r\n", mac_addr_str); while (1) { // // Calculate the elapsed time from our free-running timer, and update // the software timers in the WSF scheduler. // wsfOsDispatcher(); } } void task_radio_init(uint16_t stack_depth, uint16_t priority) { // // Create task_radio_entry. // xTaskCreate(task_radio_entry, "task_radio_entry", stack_depth, 0, priority, &radio_task_handle); }