MXC_A39_20240320/SW/examples/application/bootloader/src/main.c

364 lines
11 KiB
C

/* Standard includes. */
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#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);
}