/* Standard includes. */ #include #include #include #include "fr30xx.h" /* FreeRTOS kernel includes. */ #include "FreeRTOS.h" #include "task.h" #include "fdb_app.h" #include "host.h" #include "app_task.h" #include "app_at.h" /* hardware handlers */ static UART_HandleTypeDef Uart3_handle; static CALI_HandleTypeDef cali_handle; #if ENABLE_RTOS_MONITOR == 1 /* FreeRTOS running status monitor task */ static TaskHandle_t monitor_task_handle; volatile unsigned int CPU_RunTime; static uint8_t CPU_RunInfo[2048]; #endif /* APP task */ TaskHandle_t app_task_handle; void controller_start(void); void host_start(void); #if defined(__CC_ARM) || defined(__ARMCC_VERSION) int fputc(int c, FILE *fp) { uart_transmit(&Uart3_handle, (void *)&c, 1); while(!(Uart3_handle.UARTx->USR.TFE)); return c; } #endif #ifdef __GNUC__ int _write(int file, char *ptr, int len) { uart_transmit(&Uart3_handle, (void *)ptr, len); while(!(Uart3_handle.UARTx->USR.TFE)); return len; } #endif #ifdef __ICCARM__ int putchar(int c) { uart_transmit(&Uart3_handle, (void *)&c, 1); while(!(Uart3_handle.UARTx->USR.TFE)); return c; } #endif #if ENABLE_RTOS_MONITOR == 1 static void monitor_task(void *arg) { while(1) { vTaskDelay(2000000); memset(CPU_RunInfo,0,2048); vTaskList((char *)&CPU_RunInfo); printf("---------------------------------------------\r\n"); printf("name state priority stack seq\r\n"); printf("%s", CPU_RunInfo); printf("---------------------------------------------\r\n"); memset(CPU_RunInfo,0,400); vTaskGetRunTimeStats((char *)&CPU_RunInfo); printf("name counter usage\r\n"); printf("%s", CPU_RunInfo); printf("---------------------------------------------\r\n"); } } #endif void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ) { ( void ) pcTaskName; ( void ) pxTask; assert( 0 ); } void vApplicationTickHook(void) { #if ENABLE_RTOS_MONITOR == 1 CPU_RunTime++; #endif } static void cali_done_handle(CALI_HandleTypeDef *hcali, uint32_t result) { system_set_LPRCCLK(cali_calc_rc_freq(hcali, result)); system_prevent_sleep_clear(SYSTEM_PREVENT_SLEEP_TYPE_CALIBRATION); } __RAM_CODE bool user_deep_sleep_check(void) { return host_before_sleep_check(); } __RAM_CODE void user_entry_before_sleep(void) { ool_write16(PMU_REG_PIN_PULL_EN, 0x3fff); ool_write16(PMU_REG_PIN_PULL_SEL, 0x3fff); /* gpio_PD Wakeup Init */ SYSTEM->PortD_InputCutoffDisable = 0x0000ffff; ool_write(PMU_REG_PMU_GATE_M, ool_read(PMU_REG_PMU_GATE_M) | 0x40); } __RAM_CODE void user_entry_after_sleep(void) { GPIO_InitTypeDef gpio_config; /* * enable pull up of all 3.3v IO, these configuration will be latched by set * BIT6 of PMU_REG_PMU_GATE_M regsiter. used to avoid electric leakage */ SYSTEM->PortA_PullSelect = 0x0000ffff; SYSTEM->PortB_PullSelect = 0x00000fff; SYSTEM->PortC_PullSelect = 0x00000000; SYSTEM->PortD_PullSelect = 0x0000ffff; SYSTEM->PortA_PullEN = 0x00007fff; SYSTEM->PortB_PullEN = 0x00000dff; SYSTEM->PortC_PullEN = 0x00000000; SYSTEM->PortD_PullEN = 0x0000ffff; SYSTEM->QspiPadConfig.QSPI_PullEN = 0x0000000; host_hci_reinit(); ool_write(PMU_REG_PMU_GATE_M, ool_read(PMU_REG_PMU_GATE_M) & (~0x40)); NVIC_SetPriority(UART0_IRQn, 2); NVIC_EnableIRQ(UART0_IRQn); NVIC_SetPriority(PMU_IRQn, 4); NVIC_EnableIRQ(PMU_IRQn); /* configure PA0 and PA1 to UART0 function */ __SYSTEM_GPIOA_CLK_ENABLE(); gpio_config.Pin = GPIO_PIN_4 | GPIO_PIN_5; gpio_config.Mode = GPIO_MODE_AF_PP; gpio_config.Pull = GPIO_PULLUP; gpio_config.Alternate = GPIO_FUNCTION_1; gpio_init(GPIOB, &gpio_config); /* UART0: used for Log and AT command */ __SYSTEM_UART3_CLK_ENABLE(); Uart3_handle.UARTx = UART3; Uart3_handle.Init.BaudRate = 115200; Uart3_handle.Init.DataLength = UART_DATA_LENGTH_8BIT; Uart3_handle.Init.StopBits = UART_STOPBITS_1; Uart3_handle.Init.Parity = UART_PARITY_NONE; Uart3_handle.Init.FIFO_Mode = UART_FIFO_ENABLE; Uart3_handle.TxCpltCallback = NULL; Uart3_handle.RxCpltCallback = app_at_rx_done; uart_init(&Uart3_handle); /* restart calibration */ __SYSTEM_CALI_CLK_ENABLE(); cali_handle.mode = CALI_UP_MODE_NORMAL; cali_handle.rc_cnt = 60; cali_handle.DoneCallback = cali_done_handle; cali_init(&cali_handle); cali_start_IT(&cali_handle); system_prevent_sleep_set(SYSTEM_PREVENT_SLEEP_TYPE_CALIBRATION); NVIC_SetPriority(CALI_IRQn, 2); NVIC_EnableIRQ(CALI_IRQn); } int main( void ) { GPIO_InitTypeDef gpio_config; system_delay_us(1000000); /* configure all interrupt priority to 2 */ *(volatile uint32_t *)0xE000E400 = 0x40404040; *(volatile uint32_t *)0xE000E404 = 0x40404040; *(volatile uint32_t *)0xE000E408 = 0x40404040; *(volatile uint32_t *)0xE000E40C = 0x40404040; *(volatile uint32_t *)0xE000E410 = 0x40404040; *(volatile uint32_t *)0xE000E414 = 0x40404040; *(volatile uint32_t *)0xE000E418 = 0x40404040; *(volatile uint32_t *)0xE000E41C = 0x40404040; *(volatile uint32_t *)0xE000E420 = 0x40404040; *(volatile uint32_t *)0xE000E424 = 0x40404040; *(volatile uint32_t *)0xE000E428 = 0x40404040; *(volatile uint32_t *)0xE000E42C = 0x40404040; *(volatile uint32_t *)0xE000E430 = 0x40404040; *(volatile uint32_t *)0xE000E434 = 0x40404040; *(volatile uint32_t *)0xE000E438 = 0x40404040; *(volatile uint32_t *)0xE000E43C = 0x40404040; *(volatile uint32_t *)0xE000E440 = 0x40404040; pmu_init(); /* Power Keep: 32KB PRAM, 128KB SRAM */ ool_write16(PMU_REG_PKSRAM_GATE, ~0x0063); /* reinit flash controller */ system_cache_enable(true); SYSTEM->QspiPadConfig.QSPI_FuncMux = 0x00000500; flash_enable_quad(QSPI0); flash_init_controller(QSPI0, FLASH_RD_TYPE_DUAL, FLASH_WR_TYPE_SINGLE); flash_set_baudrate(QSPI0, QSPI_BAUDRATE_DIV_4); /* configure PB4 and PB5 to UART3 function */ gpio_config.Pin = GPIO_PIN_4 | GPIO_PIN_5; gpio_config.Mode = GPIO_MODE_AF_PP; gpio_config.Pull = GPIO_PULLUP; gpio_config.Alternate = GPIO_FUNCTION_1; gpio_init(GPIOB, &gpio_config); /* UART2: used for Log and AT command */ __SYSTEM_UART3_CLK_ENABLE(); Uart3_handle.UARTx = UART3; Uart3_handle.Init.BaudRate = 115200; Uart3_handle.Init.DataLength = UART_DATA_LENGTH_8BIT; Uart3_handle.Init.StopBits = UART_STOPBITS_1; Uart3_handle.Init.Parity = UART_PARITY_NONE; Uart3_handle.Init.FIFO_Mode = UART_FIFO_ENABLE; Uart3_handle.TxCpltCallback = NULL; Uart3_handle.RxCpltCallback = app_at_rx_done; uart_init(&Uart3_handle); NVIC_SetPriority(UART3_IRQn, 4); NVIC_EnableIRQ(UART3_IRQn); /* do calibration, get current RC frequency */ __SYSTEM_CALI_CLK_ENABLE(); cali_handle.mode = CALI_UP_MODE_NORMAL; cali_handle.rc_cnt = 200; cali_handle.DoneCallback = cali_done_handle; cali_init(&cali_handle); cali_start_IT(&cali_handle); system_prevent_sleep_set(SYSTEM_PREVENT_SLEEP_TYPE_CALIBRATION); NVIC_SetPriority(CALI_IRQn, 4); NVIC_EnableIRQ(CALI_IRQn); /* init flashdb to store user data */ flashdb_init(); printf("start running\r\n"); /* Create tasks */ #if ENABLE_RTOS_MONITOR == 1 xTaskCreate(monitor_task, "monitor", MONITOR_TASK_STACK_SIZE, NULL, MONITOR_TASK_PRIORITY, &monitor_task_handle); #endif /* create application task */ app_task_init(); /* initialize AT command */ app_at_init(&Uart3_handle); /* * enable pull up of all 3.3v IO, these configuration will be latched by set * BIT6 of PMU_REG_PMU_GATE_M regsiter. used to avoid electric leakage */ SYSTEM->PortA_PullSelect = 0x0000ffff; SYSTEM->PortB_PullSelect = 0x00000fff; SYSTEM->PortC_PullSelect = 0x00000000; SYSTEM->PortD_PullSelect = 0x0000ffff; SYSTEM->PortA_PullEN = 0x00007fff; SYSTEM->PortB_PullEN = 0x00000dff; SYSTEM->PortC_PullEN = 0x00000000; SYSTEM->PortD_PullEN = 0x0000ffff; SYSTEM->QspiPadConfig.QSPI_PullEN = 0x0000000; /* enable sleep */ // system_prevent_sleep_clear(SYSTEM_PREVENT_SLEEP_TYPE_DISABLE); printf("FR5090: BTDM test: 0x%04x.\r\n", ool_read16(PMU_REG_PIN_INPUT_EN)); /* Start the scheduler itself. */ vTaskStartScheduler(); return 0; } void uart3_irq(void) { uart_IRQHandler(&Uart3_handle); } void PMU_GPIO_GROUPH_IRQHandler(void) { struct app_task_event *event; event = app_task_event_alloc(APP_TASK_EVENT_GPIO_PD_WAKEUP, 0, true); app_task_event_post(event, false); system_prevent_sleep_set(SYSTEM_PREVENT_SLEEP_TYPE_DISABLE); } void PMU_GPIO_PMU_IRQHandler(void) { uint16_t data = ool_read16(PMU_REG_PIN_DATA); uint16_t result = ool_read16(PMU_REG_PIN_XOR_RESULT); /* update last value with latest data */ ool_write16(PMU_REG_PIN_LAST_V, data); /* clear last XOR result */ ool_write16(PMU_REG_PIN_XOR_CLR, result); if (((data & PMU_PIN_0) == 0) &(ool_read(PMU_REG_PIN_XOR_EN) & PMU_PIN_0)) { system_prevent_sleep_set(SYSTEM_PREVENT_SLEEP_TYPE_DISABLE); struct app_task_event *event; event = app_task_event_alloc(APP_TASK_EVENT_PMU_WAKEUP, 0, true); app_task_event_post(event, false); return; } if (data & PMU_PIN_9) { system_prevent_sleep_clear(SYSTEM_PREVENT_SLEEP_TYPE_HCI_RX); } else { system_prevent_sleep_set(SYSTEM_PREVENT_SLEEP_TYPE_HCI_RX); } } void cali_irq(void) { cali_IRQHandler(&cali_handle); }