/* Standard includes. */ #include #include #include #include "fr30xx.h" #include "driver_pmu_iwdt.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" #include "app_ota.h" #include "driver_timer.h" #include "app_hw.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); int fputc(int c, FILE *fp) { uart_transmit(&Uart3_handle, (void *)&c, 1); while(!(Uart3_handle.UARTx->USR.TFE)); return c; } #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); 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); } void wdt_rst_start(void) { iwdt_Init_t iwdt_handle; iwdt_handle.iwdt_int_Enable = WDT_INT_DISABLE; iwdt_handle.iwdt_Timeout = 0xFFF; iwdt_handle.iwdt_Count = 32000 * 3; // 32K, timeout 3s iwdt_init(iwdt_handle); iwdt_Enable(); } void sys_iwdt_start(void) { iwdt_Init_t iwdt_handle; iwdt_handle.iwdt_int_Enable = WDT_INT_DISABLE; iwdt_handle.iwdt_Timeout = 0xFFF; iwdt_handle.iwdt_Count = 32000 * 6; // 32K, timeout 5s iwdt_init(iwdt_handle); iwdt_Enable(); } 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 = 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); /*ota check*/ ota_boot_start(); #if 1 /* set SYSTEM BUCK to 1.35v, set DSP LDO and APP LDO to bypass mode */ ool_write(PMU_REG_SYSBUCK_CTRL_0, 0x04); ool_write(PMU_REG_DSP_DLDO_CTRL, ool_read(PMU_REG_DSP_DLDO_CTRL)| 0x80); ool_write(PMU_REG_APP_DLDO_CTRL, ool_read(PMU_REG_APP_DLDO_CTRL)| 0x40); /* initial system clock and XIP flash */ hw_clock_init(); hw_xip_flash_init(false); uart_init(&Uart3_handle); #endif /*enable uart irq*/ 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"); sys_iwdt_start(); /* 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 */ #if 1 SYSTEM->PortA_PullSelect = 0x0000ff9f; SYSTEM->PortB_PullSelect = 0x00000fff; SYSTEM->PortC_PullSelect = 0x00000000; SYSTEM->PortD_PullSelect = 0x0000ffff; SYSTEM->PortA_PullEN = 0x00007fff; SYSTEM->PortB_PullEN = 0x00000fff; SYSTEM->PortC_PullEN = 0x00000000; SYSTEM->PortD_PullEN = 0x0000ffff; SYSTEM->QspiPadConfig.QSPI_PullSelect = 0x00000000; SYSTEM->QspiPadConfig.QSPI_PullEN = 0xffffffff; SYSTEM->OspiPadConfig.OSPI_PullSelect = 0x00000000; SYSTEM->OspiPadConfig.OSPI_PullEN = 0xffffffff; /* IO33 always on, IO18 off in sleep mode */ ool_write(0x63, 0x08); __SYSTEM_GPIOB_CLK_ENABLE(); gpio_config.Pin = GPIO_PIN_12; gpio_config.Mode = GPIO_MODE_OUTPUT_PP; gpio_config.Pull = GPIO_PULLDOWN; gpio_config.Alternate = GPIO_FUNCTION_0; gpio_init(GPIOB, &gpio_config); gpio_write_pin(GPIOB, GPIO_PIN_12, GPIO_PIN_CLEAR); // motor en: default output low __SYSTEM_GPIOA_CLK_ENABLE(); gpio_config.Pin = GPIO_PIN_5; 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_5, GPIO_PIN_SET); // HR sensor power en: default output high #else 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; #endif /* 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_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); } } void cali_irq(void) { cali_IRQHandler(&cali_handle); }