M
如下
/*
* INCLUDE FILES
****************************************************************************************
*/
#include <stdio.h>
#include <string.h>
#include "gap_api.h"
#include "gatt_api.h"
#include "ble_stack.h"
#include "app_config.h"
#include "jump_table.h"
#include "co_log.h"
#include "plf.h"
#include "driver_system.h"
#include "driver_pmu.h"
#include "driver_uart.h"
#include "ble_simple_peripheral.h"
#include "simple_gatt_service.h"
#undef LOG_LOCAL_LEVEL
#define LOG_LOCAL_LEVEL (LOG_LEVEL_INFO)
const char *app_tag = "project";
#define SYSTEM_STACK_SIZE 0x800
void patch_init(void);
void disable_ch_sel_2(void);
void conn_req_rssi_filter(int8_t rssi_value);
void systick_init(void);
void systick_delay_ms(uint32_t ms);
void systick_delay_us(uint32_t us);
uint32_t systick_get_ms(void);
/*
* LOCAL VARIABLES
*/
static volatile uint32_t g_systick_ms = 0;
__attribute__((section("stack_section"))) static uint32_t system_stack[SYSTEM_STACK_SIZE/sizeof(uint32_t)];
const struct jump_table_version_t _jump_table_version __attribute__((section("jump_table_3"))) =
{
.stack_top_address = &system_stack[SYSTEM_STACK_SIZE/sizeof(uint32_t)],
.firmware_version = 0x00000000,
};
const struct jump_table_image_t _jump_table_image __attribute__((section("jump_table_1"))) =
{
.image_type = IMAGE_TYPE_APP,
.image_size = 0x20000,
};
/*********************************************************************
* @fn SysTick_Handler
*
* @brief 1ms tick. Overrides the WEAK handler in boot_vectors.
*/
void SysTick_Handler(void)
{
g_systick_ms++;
}
/*********************************************************************
* @fn systick_init
*
* @brief Start SysTick at 1ms. Must be called after system_set_clock().
*/
void systick_init(void)
{
uint32_t ticks = system_get_clock() / 1000;
if ((ticks == 0) || ((ticks - 1) > SysTick_LOAD_RELOAD_Msk)) {
return;
}
SysTick_Config(ticks);
}
/*********************************************************************
* @fn systick_get_ms
*
* @brief Milliseconds since systick_init. Does not advance in sleep.
*/
uint32_t systick_get_ms(void)
{
return g_systick_ms;
}
/*********************************************************************
* @fn systick_delay_ms
*
* @brief Blocking delay. Do not call with interrupts disabled.
*/
void systick_delay_ms(uint32_t ms)
{
uint32_t start = g_systick_ms;
while ((uint32_t)(g_systick_ms - start) < ms) {
}
}
/*********************************************************************
* @fn systick_delay_us
*
* @brief Blocking us delay. Temporarily uses SysTick as a one-shot,
* then restores the 1ms tick.
*/
void systick_delay_us(uint32_t us)
{
uint32_t clk = system_get_clock();
uint32_t ticks_per_us;
uint32_t max_us;
if ((us == 0) || (clk < 1000000)) {
return;
}
ticks_per_us = clk / 1000000;
max_us = SysTick_LOAD_RELOAD_Msk / ticks_per_us;
while (us) {
uint32_t chunk = (us > max_us) ? max_us : us;
SysTick->CTRL = 0;
SysTick->LOAD = ticks_per_us * chunk - 1;
SysTick->VAL = 0;
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk;
while ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0) {
}
us -= chunk;
}
systick_init();
}
/*********************************************************************
* @fn user_entry_before_sleep_imp
*
* @brief Before system goes to sleep mode, user_entry_before_sleep_imp()
* will be called, MCU peripherals can be configured properly before
* system goes to sleep, for example, some MCU peripherals need to be
* used during the system is in sleep mode.
*
* @param None.
*
*
* @return None.
*/
__attribute__((section("ram_code"))) void user_entry_before_sleep_imp(void)
{
/* SysTick uses CPU clock and would wake the core every 1ms */
SysTick->CTRL = 0;
pmu_calibration_stop();
uart_putc_noint_no_wait(UART0, 's');
co_delay_100us(1);
pmu_set_pin_to_PMU(GPIO_PORT_A, (1<<GPIO_BIT_1));
pmu_set_pin_to_PMU(GPIO_PORT_A, (1<<GPIO_BIT_0)|(1<<GPIO_BIT_4));
pmu_set_pin_dir(GPIO_PORT_A, (1<<GPIO_BIT_0)|(1<<GPIO_BIT_4),GPIO_DIR_IN);
pmu_set_pin_pull(GPIO_PORT_A, (1<<GPIO_BIT_0)|(1<<GPIO_BIT_4),GPIO_PULL_NONE);
pmu_oscap_set(0);
}
/*********************************************************************
* @fn user_entry_after_sleep_imp
*
* @brief After system wakes up from sleep mode, user_entry_after_sleep_imp()
* will be called, MCU peripherals need to be initialized again,
* this can be done in user_entry_after_sleep_imp(). MCU peripherals
* status will not be kept during the sleep.
*
* @param None.
*
*
* @return None.
*/
__attribute__((section("ram_code"))) void user_entry_after_sleep_imp(void)
{
pmu_set_pin_to_CPU(GPIO_PORT_A, (1<<GPIO_BIT_0));
system_set_port_mux(GPIO_PORT_A, GPIO_BIT_0, PORTA0_FUNC_UART0_RXD);
system_set_port_mux(GPIO_PORT_A, GPIO_BIT_1, PORTA1_FUNC_UART0_TXD);
uart_init(UART0, 1152);
fr_uart_enableIrq(UART0, Uart_irq_erbfi);
/* RC calibration start. Ensure the accuracy of sleep wake time */
pmu_calibration_start(PMU_CALI_SEL_RCLFOSC, LP_RC_CALIB_CNT);
uart_putc_noint_no_wait(UART0, 'w');
co_delay_100us(1);
NVIC_EnableIRQ(PMU_IRQn);
systick_init();
}
__attribute__((section("ram_code"))) void main_loop(void)
{
while(1)
{
if(ble_stack_schedule_allow())
{
/*user code should be add here*/
/* schedule internal stack event */
ble_stack_schedule();
}
GLOBAL_INT_DISABLE();
switch(ble_stack_sleep_check())
{
case 2:
{
ble_stack_enter_sleep();
}
break;
default:
break;
}
GLOBAL_INT_RESTORE();
ble_stack_schedule_backward();
}
}
/*********************************************************************
* @fn proj_init
*
* @brief Main entrancy of user application. This function is called after BLE stack
* is initialized, and all the application code will be executed from here.
* In that case, application layer initializtion can be startd here.
*
* @param None.
*
*
* @return None.
*/
void proj_init(void)
{
LOG_INFO(app_tag, "BLE Peripheral\r\n");
co_printf("%s\r\n",__func__);
systick_delay_ms(500);
co_printf("%s\r\n",__TIME__);
// Application layer initialization, can included bond manager init,
// advertising parameters init, scanning parameter init, GATT service adding, etc.
simple_peripheral_init();
}