MXC-A36-Demo/MCU/examples/application/ble_simple_periphreal/Src/main.c

332 lines
9.6 KiB
C

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