/* 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 "ff.h" #include "app_task.h" #include "app_at.h" #include "audio_scene.h" /* hardware handlers */ static UART_HandleTypeDef Uart3_handle; SD_HandleTypeDef sdio_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 /* file system */ static FATFS fs; /* APP task */ TaskHandle_t app_task_handle; void controller_start(void); void host_start(void); #if defined(__ARMCC_VERSION) || defined(__CC_ARM) int fputc(int c, FILE *fp) { uart_transmit(&Uart3_handle, (void *)&c, 1); return c; } #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(10000); 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 } __RAM_CODE bool user_deep_sleep_check(void) { return host_before_sleep_check(); } __RAM_CODE void user_entry_before_sleep(void) { 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; /* 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; 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_UART2_CLK_ENABLE(); Uart3_handle.UARTx = UART3; Uart3_handle.Init.BaudRate = 921600; 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); app_rpmsg_recover(); } __RAM_CODE void hw_clock_init(void) { System_ClkConfig_t sys_clk_cfg; sys_clk_cfg.AUPLL_CFG.PLL_N = 8; sys_clk_cfg.AUPLL_CFG.PLL_M = 15204; sys_clk_cfg.AUPLL_CFG.PowerEn = 1; sys_clk_cfg.SPLL_CFG.PLL_N = 8; sys_clk_cfg.SPLL_CFG.PLL_M = 0; sys_clk_cfg.SPLL_CFG.PowerEn = 1; sys_clk_cfg.MCU_Clock_Source = MCU_CLK_SEL_SPLL_CLK; sys_clk_cfg.SOC_DIV = 1; sys_clk_cfg.MCU_DIV = 1; sys_clk_cfg.APB0_DIV = 1; sys_clk_cfg.APB1_DIV = 1; sys_clk_cfg.APB2_DIV = 1; sys_clk_cfg.APB3_DIV = 1; System_AUPLL_config(&sys_clk_cfg.AUPLL_CFG, 1000); System_SPLL_config(&sys_clk_cfg.SPLL_CFG, 1000); System_MCU_clock_Config(&sys_clk_cfg); __SYSTEM_SPI_MASTER0_X8_CLK_SELECT_AUPLL(); __SYSTEM_SPI_MASTER1_X8_CLK_SELECT_AUPLL(); __SYSTEM_I2C_CLK_SELECT_SPLL(); __SYSTEM_BLEND_CLK_SELECT_SPLL(); __SYSTEM_UART_CLK_SELECT_SPLL(); } __RAM_CODE __attribute__((noinline)) static void rise_qspi_clock(void) { __SYSTEM_QSPI0_CLK_SELECT_AUPLL(); __QSPI_DELAY_CS_START_SET(QSPI0, 4); __QSPI_DELAY_CS_END_SET(QSPI0, 4); __QSPI_DELAY_CS_DESSERT_SET(QSPI0, 8); __QSPI_READ_CAPTURE_DELAY_SET(QSPI0, 0); // FLASH_ID_PUYA_P25Q32: 4 when div is 2 // FLASH_ID_XMC_XM25LU32: 3 when div is 2 // FLASH_ID_GIANTEC_GT25Q16A: 1 when div is 4 // FLASH_ID_GIANTEC_GT25Q16A: 4 when div is 2 system_delay_us(1000); } __RAM_CODE void hw_xip_flash_init(bool wake_up) { // init internal flash __SYSTEM_PFC_CLK_ENABLE(); __SYSTEM_QSPI0_CLK_ENABLE(); __SYSTEM_APB_CLK_ENABLE(); __SYSTEM_APB1_CLK_ENABLE(); system_cache_enable(true); flash_enable_quad(QSPI0); SYSTEM->QspiPadConfig.QSPI_FuncMux = 0x00000500; flash_init_controller(QSPI0, FLASH_RD_TYPE_QUAD, FLASH_WR_TYPE_SINGLE); if (wake_up == false) { flash_set_IO_DRV(QSPI0, 3); } flash_set_baudrate(QSPI0, QSPI_BAUDRATE_DIV_4); rise_qspi_clock(); } int main( void ) { GPIO_InitTypeDef gpio_config; UART_HandleTypeDef dsp_uart_handle; uint32_t error; uint32_t rand_num; size_t size; 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(); ool_write(0xc3, 0x27); // system_prevent_sleep_clear(SYSTEM_PREVENT_SLEEP_TYPE_DISABLE); /* initial system clock and XIP flash */ hw_clock_init(); hw_xip_flash_init(false); __SYSTEM_GPIOA_CLK_ENABLE(); /* configure PA6 to PA_EN function */ gpio_config.Pin = GPIO_PIN_6; gpio_config.Mode = GPIO_MODE_OUTPUT_PP; gpio_config.Pull = GPIO_PULLUP; gpio_config.Alternate = GPIO_FUNCTION_0; gpio_init(GPIOA, &gpio_config); gpio_write_pin(GPIOA, GPIO_PIN_6, GPIO_PIN_SET); /* initialize uart for DSP UART */ /* ========================================================== */ /* ========= Uart LOG configuration ========= */ /* ========================================================== */ /* configure PA4 and PA5 to UART1 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(GPIOA, &gpio_config); /* UART1: used for Log and AT command */ __SYSTEM_UART1_CLK_ENABLE(); dsp_uart_handle.UARTx = UART1; dsp_uart_handle.Init.BaudRate = 3000000; dsp_uart_handle.Init.DataLength = UART_DATA_LENGTH_8BIT; dsp_uart_handle.Init.StopBits = UART_STOPBITS_1; dsp_uart_handle.Init.Parity = UART_PARITY_NONE; dsp_uart_handle.Init.FIFO_Mode = UART_FIFO_ENABLE; dsp_uart_handle.Init.AUTO_FLOW = false; dsp_uart_handle.TxCpltCallback = NULL; dsp_uart_handle.RxCpltCallback = NULL; uart_init(&dsp_uart_handle); /* 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); /* UART3: used for Log and AT command */ __SYSTEM_UART3_CLK_ENABLE(); Uart3_handle.UARTx = UART3; Uart3_handle.Init.BaudRate = 921600; 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_EnableIRQ(UART3_IRQn); NVIC_SetPriority(UART3_IRQn, 4); /* ========================================================== */ /* ========= I2S interface configuration ======== */ /* ========================================================== */ /* configure PB0~PB3 to I2S0 function */ gpio_config.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3; gpio_config.Mode = GPIO_MODE_AF_PP; gpio_config.Pull = GPIO_PULLUP; gpio_config.Alternate = GPIO_FUNCTION_B; gpio_init(GPIOB, &gpio_config); /* init flashdb to store user data */ flashdb_init(); /* get random seed*/ size = flashdb_get(FDB_KEY_USER_RANDOM_SEED, (void *)&rand_num, 4); printf("flashdb get random seed :%d\r\n",size); if(size == 0){ __SYSTEM_TRNG_CLK_ENABLE(); trng_init(); trng_read_rand_num((uint8_t *)&rand_num,4); flashdb_set(FDB_KEY_USER_RANDOM_SEED,(uint8_t *)&rand_num,4); __SYSTEM_TRNG_CLK_DISABLE(); } printf("flash db get rand num: %x\r\n",rand_num); /* Create tasks */ #if ENABLE_RTOS_MONITOR == 1 xTaskCreate(monitor_task, "monitor", MONITOR_TASK_STACK_SIZE, NULL, MONITOR_TASK_PRIORITY, &monitor_task_handle); #endif app_task_init(); audio_scene_init(AUDIO_SCENE_TASK_STACK_SIZE, AUDIO_SCENE_TASK_PRIORITY); /* initialize AT command */ app_at_init(&Uart3_handle); printf("FR5090: BTDM test.\r\n"); /* Start the scheduler itself. */ vTaskStartScheduler(); return 0; } void uart3_irq(void) { uart_IRQHandler(&Uart3_handle); } 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_9) { system_prevent_sleep_clear(SYSTEM_PREVENT_SLEEP_TYPE_HCI_RX); } else { system_prevent_sleep_set(SYSTEM_PREVENT_SLEEP_TYPE_HCI_RX); } }