hpw422移植新的sdk

This commit is contained in:
xushaoxiang
2026-07-03 18:08:25 +08:00
commit 945a5a5b0b
2583 changed files with 713209 additions and 0 deletions
@@ -0,0 +1,332 @@
/**
****************************************************************************************
*
* @file app_task.h
*
* @brief Header file - APPTASK.
*
* Copyright (C) RivieraWaves 2009-2015
*
*
****************************************************************************************
*/
#ifndef APP_TASK_H_
#define APP_TASK_H_
/**
****************************************************************************************
* @addtogroup APPTASK Task
* @ingroup APP
* @brief Routes ALL messages to/from APP block.
*
* The APPTASK is the block responsible for bridging the final application with
*the RWBLE software host stack. It communicates with the different modules of
*the BLE host, i.e. @ref SMP, @ref GAP and @ref GATT.
*
* @{
****************************************************************************************
*/
#include "co_bt_defines.h"
#include "dbg.h"
#include "gapm_int.h"
#include "gatt_msg_int.h" // GATTC Definitions
#include "ke_task.h" // Kernel Task
#include "rwip_task.h" // Task definitions
#include "xc_gap_api.h"
#include <stdbool.h>
#include <stdint.h> // Standard Integer Definition
#include <stdio.h>
#if (NVDS_SUPPORT)
#include "nvds.h"
#endif // (NVDS_SUPPORT)
#define APP_HANDLERS(subtask) \
{ \
&subtask##_msg_handler_list[0], ARRAY_LEN(subtask##_msg_handler_list) \
}
/// Default Device Name
#define APP_DFLT_DEVICE_NAME ("XinChipUartTest")
#define APP_DFLT_DEVICE_NAME_LEN (sizeof(APP_DFLT_DEVICE_NAME))
#define APP_SINGLEOTA_DEVICE_NAME "OTA_TEST"
#define APP_SINGLEOTA_DEVICE_NAME_LEN (sizeof(APP_SINGLEOTA_DEVICE_NAME))
/// Maximal length of the Device Name value
/*
max name len:
31
-3 (sdk default fix header: 02-01-06)
-2 (dev name AD-structure header: xx-09)
= 26
*/
#define APP_DEVICE_NAME_MAX_LEN (26)
#define APP_MAX_TX_POWER (0)
// Advertising channel map - 37, 38, 39
#define APP_ADV_CHMAP (0x07)
// Advertising minimum interval - 40ms (64*0.625ms)
#define APP_ADV_INT_MIN (64)
// Advertising maximum interval - 40ms (64*0.625ms)
#define APP_ADV_INT_MAX (64)
#define ADV_DATA_MAX_LENGTH 28
#define MANUFACTURER_DATA "\x09\xFF\x00\x60\x52\x57\x2D\x42\x4C\x45"
#define MANUFACTURER_DATA_LEN 10
/// Advertising duration (in unit of 10ms). 0 means that advertising continues
/// until the host disable it
#define ADV_DURATION 0
#define APP_SCAN_INTERVAL (0xa0)
#define APP_SCAN_WINDOW (0x50)
#define APP_CONN_EST_TIME_OUT (0)
#define APP_CONN_SCNA_INTV (32)
#define APP_CONN_SCAN_WD (20)
#define APP_CONN_INTV_MIN (80)
#define APP_CONN_INV_MAX (80)
#define APP_CONN_LATENCY (0)
#define APP_CONN_TIME_OUT (500)
/// Number of APP Task Instances
#define APP_IDX_MAX 1
#define DEV_APPEARANCE 0
#define BLE_UAPDATA_MIN_INTVALUE 8
#define BLE_UAPDATA_MAX_INTVALUE 10
#define BLE_UAPDATA_LATENCY 0
#define BLE_UAPDATA_TIMEOUT 200
#define INVALID_DATA 0xFF
#define TAGET_DEVICE_ADDR ("\x12\x34\x56\x78\x90\xAB")
#define APP_ADDR_MAXLEN 6
#define APP_NAME_MAXLEN 21
struct ADV_INFO{
uint8_t addr[APP_ADDR_MAXLEN];
uint8_t name_length;
uint8_t name[APP_NAME_MAXLEN];
};
/// Application environment structure
struct app_env_tag
{
/// Connection handle
uint16_t conhdl;
/// Connection Index
uint8_t conidx;
/// Current advertising state (@see enum app_adv_state)
uint8_t adv_state;
/// Current advertising state (@see enum app_adv_state)
uint8_t scan_state;
/// Current advertising state (@see enum app_adv_state)
uint8_t init_state;
/// Next expected operation completed event
uint8_t adv_op;
/// Last initialized profile
uint8_t next_svc;
/// Bonding status
bool bonded;
/// Device Name length
uint8_t dev_name_len;
/// Device Name
uint8_t dev_name[APP_DEVICE_NAME_MAX_LEN];
/// Local device IRK
uint8_t loc_irk[KEY_LEN];
/// Secure Connections on current link
bool sec_con_enabled;
/// Counter used to generate IRK
uint8_t rand_cnt;
/// Demonstration type length
uint8_t demo_type_len;
/// Demonstration type
uint8_t demo_type;
/// GATT user local identifier
uint8_t user_lid;
uint8_t adv_actv_idx;
uint8_t slave_conidx;
bool slave_connected;
};
#if (NVDS_SUPPORT)
/// List of Application NVDS TAG identifiers
enum app_nvds_tag
{
/// Device Name
NVDS_TAG_DEVICE_NAME = 0x02,
NVDS_LEN_DEVICE_NAME = 62,
/// BD Address
NVDS_TAG_BD_ADDRESS = 0x01,
NVDS_LEN_BD_ADDRESS = 6,
/// Local device Identity resolving key
NVDS_TAG_LOC_IRK = 0xA0,
NVDS_LEN_LOC_IRK = KEY_LEN,
#if (BLE_APP_PRF)
/// BLE Application Advertising data
NVDS_TAG_APP_BLE_ADV_DATA = 0x0B,
NVDS_LEN_APP_BLE_ADV_DATA = 32,
/// BLE Application Scan response data
NVDS_TAG_APP_BLE_SCAN_RESP_DATA = 0x0C,
NVDS_LEN_APP_BLE_SCAN_RESP_DATA = 32,
/// Mouse Sample Rate
NVDS_TAG_MOUSE_SAMPLE_RATE = 0x38,
NVDS_LEN_MOUSE_SAMPLE_RATE = 1,
/// Peripheral Bonded
NVDS_TAG_PERIPH_BONDED = 0x39,
NVDS_LEN_PERIPH_BONDED = 1,
/// Mouse NTF Cfg
NVDS_TAG_MOUSE_NTF_CFG = 0x3A,
NVDS_LEN_MOUSE_NTF_CFG = 2,
/// Mouse Timeout value
NVDS_TAG_MOUSE_TIMEOUT = 0x3B,
NVDS_LEN_MOUSE_TIMEOUT = 2,
/// Peer Device BD Address
NVDS_TAG_PEER_BD_ADDRESS = 0x3C,
NVDS_LEN_PEER_BD_ADDRESS = 7,
/// Mouse Energy Safe
NVDS_TAG_MOUSE_ENERGY_SAFE = 0x3D,
NVDS_LEN_MOUSE_SAFE_ENERGY = 2,
/// EDIV (2bytes), RAND NB (8bytes), LTK (16 bytes), Key Size (1 byte)
NVDS_TAG_LTK = 0x3E,
NVDS_LEN_LTK = 28,
/// PAIRING
NVDS_TAG_PAIRING = 0x3F,
NVDS_LEN_PAIRING = 54,
/// Audio mode 0 task
NVDS_TAG_AM0_FIRST = 0x90,
NVDS_TAG_AM0_LAST = 0x9F,
/// Peer device Resolving identity key (+identity address)
NVDS_TAG_PEER_IRK = 0xA1,
NVDS_LEN_PEER_IRK = sizeof(struct gapc_irk),
#endif //(BLE_APP_PRF)
};
#endif // (NVDS_SUPPORT)
/// Advertising state machine
enum app_adv_state
{
/// Advertising activity does not exists
APP_ADV_STATE_IDLE = 0,
#if BLE_APP_PRF
/// Creating advertising activity
APP_ADV_STATE_CREATING,
/// Setting advertising data
APP_ADV_STATE_SETTING_ADV_DATA,
/// Setting scan response data
APP_ADV_STATE_SETTING_SCAN_RSP_DATA,
/// Advertising activity created
APP_ADV_STATE_CREATED,
/// Starting advertising activity
APP_ADV_STATE_STARTING,
/// Advertising activity started
APP_ADV_STATE_STARTED,
/// Stopping advertising activity
APP_ADV_STATE_STOPPING,
APP_ADV_STATE_STOPPED,
#endif //(BLE_APP_PRF)
};
/// Scanning state machine
enum app_scan_state
{
APP_SCAN_STATE_IDLE = 0,
APP_SCAN_STATE_CREATING,
APP_SCAN_STATE_CREATED,
APP_SCAN_STATE_STARTING,
APP_SCAN_STATE_STARTED,
APP_SCAN_STATE_STOPPING,
APP_SCAN_STATE_STOPPED,
};
/// initting state machine
enum app_init_state
{
APP_INIT_STATE_IDLE = 0,
APP_INIT_STATE_CREATING,
APP_INIT_STATE_CREATED,
APP_INIT_STATE_STARTING,
APP_INIT_STATE_STARTED,
APP_INIT_STATE_STOPPING,
APP_INIT_STATE_STOPPED,
};
/// States of APP task
enum app_state
{
/// Initialization state
APP_INIT,
/// Database create state
APP_CREATE_DB,
/// Ready State
APP_READY,
/// Connected state
APP_CONNECTED,
/// Number of defined states.
APP_STATE_MAX
};
/// APP Task messages
/*@TRACE*/
enum app_msg_id
{
APP_DUMMY_MSG = TASK_FIRST_MSG(TASK_ID_APP),
#if (BLE_APP_PRF)
#if (BLE_APP_HT)
/// Timer used to refresh the temperature measurement value
APP_HT_MEAS_INTV_TIMER,
#endif //(BLE_APP_HT)
#if (BLE_APP_HID)
/// Timer used to disconnect the moue if no activity is detecter
APP_HID_MOUSE_TIMEOUT_TIMER,
#endif //(BLE_APP_HID)
#endif //(BLE_APP_PRF)
};
struct app_subtask_handlers
{
/// Pointer to the message handler table
const struct ke_msg_handler *p_msg_handler_tab;
/// Number of messages handled
uint16_t msg_cnt;
};
/**
****************************************************************************************
* @brief Initialize the BLE demo application.
****************************************************************************************
*/
extern struct app_env_tag app_env;
void app_init(void);
struct app_env_tag *get_app_env(void);
/// @} APPTASK
#endif // APP_TASK_H_
@@ -0,0 +1,78 @@
/**
****************************************************************************************
*
* @file rwapp_config.h
*
* @brief Application configuration definition
*
* Copyright (C) RivieraWaves 2009-2016
*
****************************************************************************************
*/
#ifndef _RWAPP_CONFIG_H_
#define _RWAPP_CONFIG_H_
/**
****************************************************************************************
* @addtogroup app
* @brief Application configuration definition
*
* @{
****************************************************************************************
*/
/*
* INCLUDE FILES
****************************************************************************************
*/
/*
* DEFINES
****************************************************************************************
*/
#define CFG_APP_BATT
/******************************************************************************************/
/* ------------------------- BLE APPLICATION SETTINGS
* -----------------------------*/
/******************************************************************************************/
/// Application Profile
#if defined(CFG_APP_PRF)
#define BLE_APP_PRF 1
#else // defined(CFG_APP_PRF)
#define BLE_APP_PRF 0
#endif // defined(CFG_APP_PRF)
/// Health Thermometer Application
#if defined(CFG_APP_HT)
#define BLE_APP_HT 1
#else // defined(CFG_APP_HT)
#define BLE_APP_HT 0
#endif // defined(CFG_APP_HT)
/// HID Application
#if defined(CFG_APP_HID)
#define BLE_APP_HID 1
#else // defined(CFG_APP_HID)
#define BLE_APP_HID 0
#endif // defined(CFG_APP_HID)
/// DIS Application
#if defined(CFG_APP_DIS)
#define BLE_APP_DIS 1
#else // defined(CFG_APP_DIS)
#define BLE_APP_DIS 0
#endif // defined(CFG_APP_DIS)
/// Battery Service Application
#if defined(CFG_APP_BATT)
#define BLE_APP_BATT 1
#else
#define BLE_APP_BATT 0
#endif //(BLE_APP_BATT)
/// @} rwapp_config
#endif /* _RWAPP_CONFIG_H_ */
@@ -0,0 +1,153 @@
#ifndef SDK_DRIVER_CONFIG_H
#define SDK_DRIVER_CONFIG_H
// <<< Use Configuration Wizard in Context Menu >>>\n
#ifdef USE_APP_CONFIG
#include "app_config.h"
#endif
// <h> XC_Drivers
// <e> XC_CLOCK_ENABLED
//==========================================================
#ifndef XC_CLOCK_ENABLED
#define XC_CLOCK_ENABLED 1
#endif
// </e>
// <e> XC_PWR_ENABLED
//==========================================================
#ifndef XC_PWR_ENABLED
#define XC_PWR_ENABLED 1
#endif
// </e>
// <e> XC_WDT_ENABLED
//==========================================================
#ifndef XC_WDT_ENABLED
#define XC_WDT_ENABLED 1
#endif
// </e>
// <e> XC_BOR_ENABLED
//==========================================================
#ifndef XC_BOR_ENABLED
#define XC_BOR_ENABLED 1
#endif
// </e>
// <e> XC_SYSTICK_ENABLED
//==========================================================
#ifndef XC_SYSTICK_ENABLED
#define XC_SYSTICK_ENABLED 1
#endif
// </e>
// <e> XC_TIMER_ENABLED
//==========================================================
#ifndef XC_TIMER_ENABLED
#define XC_TIMER_ENABLED 0
#endif
// </e>
// <e> XC_AOTIMER_ENABLED
//==========================================================
#ifndef XC_AOTIMER_ENABLED
#define XC_AOTIMER_ENABLED 0
#endif
// </e>
// <e> XC_GPIO_ENABLED
//==========================================================
#ifndef XC_GPIO_ENABLED
#define XC_GPIO_ENABLED 1
#endif
// </e>
// <e> XC_ADC_ENABLED
//==========================================================
#ifndef XC_ADC_ENABLED
#define XC_ADC_ENABLED 1
#endif
// </e>
// <e> XC_UART_ENABLED
//==========================================================
#ifndef XC_UART_ENABLED
#define XC_UART_ENABLED 1
#endif
// </e>
// <e> XC_PWM_ENABLED
//==========================================================
#ifndef XC_PWM_ENABLED
#define XC_PWM_ENABLED 1
#endif
// </e>
// <e> XC_FMC_SPI_ENABLED
//==========================================================
#ifndef XC_FMC_SPI_ENABLED
#define XC_FMC_SPI_ENABLED 1
#endif
// </e>
// <e> XC_SPI_ENABLED
//==========================================================
#ifndef XC_SPI_ENABLED
#define XC_SPI_ENABLED 0
#endif
// </e>
// <e> XC_IIC_ENABLED
//==========================================================
#ifndef XC_IIC_ENABLED
#define XC_IIC_ENABLED 0
#endif
// </e>
// <e> XC_RTC_ENABLED
//==========================================================
#ifndef XC_RTC_ENABLED
#define XC_RTC_ENABLED 0
#endif
//==========================================================
// <q> XC_RTC_DATE_INT_ENABLED
#ifndef XC_RTC_DATE_INT_ENABLED
#define XC_RTC_DATE_INT_ENABLED 0
#endif
// </e>
// <e> XC_DMA_ENABLED
//==========================================================
#ifndef XC_DMA_ENABLED
#define XC_DMA_ENABLED 0
#endif
// </e>
// <e> XC_PGA_ENABLED
//==========================================================
#ifndef XC_PGA_ENABLED
#define XC_PGA_ENABLED 0
#endif
// </e>
// <e> XC_QDEC_ENABLED
//==========================================================
#ifndef XC_QDEC_ENABLED
#define XC_QDEC_ENABLED 0
#endif
// </e>
// <e> XC_CALIB_ENABLED
//==========================================================
#ifndef XC_CALIB_ENABLED
#define XC_CALIB_ENABLED 0
#endif
// </e>
// <<< end of configuration section >>>
#endif //SDK_DRIVER_CONFIG_H
@@ -0,0 +1,66 @@
/**
****************************************************************************************
* *
* @file aes.c
*
* @brief Definition file for AES crypto module functions
*
* Copyright (C) RivieraWaves 2017-2018
*
****************************************************************************************
*/
#include "aes.h"
#if (RWIP_AES_ENCRYPT)
#define USE_AES_ENCRYPT 0
#define USE_AES_DECRYPT 1
#if USE_AES_ENCRYPT
uint8_t key[16]={0x10,0x0f,0x0e,0x0d,0x0c,0x0b,0x0a,0x09,0x08,0x07,0x06,0x05,0x04,0x0d,0x0c,0x0b};
uint8_t src_val[16]={0x0a,0x0a,0x0e,0x0d,0x0c,0x0b,0x0a,0x13,0x12,0x07,0x06,0x05,0x04,0x0d,0x02,0x01};
uint8_t encrypt_val[16]={0xf7,0x3b,0x9a,0xe6,0x88,0xb0,0x06,0x3e,0x10,0xd4,0x0f,0xb6,0x80,0x4a,0x10,0xee};
#elif USE_AES_DECRYPT
uint8_t key[16]={0x10,0x0f,0x0e,0x0d,0x0c,0x0b,0x0a,0x09,0x08,0x07,0x06,0x05,0x04,0x0d,0x0c,0x0b};
uint8_t src_val[16]={0xf7,0x3b,0x9a,0xe6,0x88,0xb0,0x06,0x3e,0x10,0xd4,0x0f,0xb6,0x80,0x4a,0x10,0xee};
uint8_t encrypt_val[16]={0x0a,0x0a,0x0e,0x0d,0x0c,0x0b,0x0a,0x13,0x12,0x07,0x06,0x05,0x04,0x0d,0x02,0x01};
#endif
aes_func_result_cb aes_res(uint8_t status, const uint8_t* aes_res_data, uint32_t src_info)
{
printf("src_info:0x%x\n",src_info);
printf("aes_res:");
for(int i=0;i<16;i++){
printf("%02x-",aes_res_data[i]);
}printf("\n");
if(!memcmp(aes_res_data,encrypt_val,sizeof(encrypt_val))){
printf("aes right\n");
}else{
printf("aes error\n");
}
}
void aes_test(void)
{
uint8_t copy=0;
static uint8_t cnt;
if(xc_gpio_read_pin(GPIO_1) == GPIO_PIN_SET){
if(cnt++ > 100){
cnt = 0;
#if USE_AES_ENCRYPT
printf("aes_encrypt\n");
aes_encrypt(key, src_val, 1, aes_res, 0xff);
#elif USE_AES_DECRYPT
printf("aes_decrypt\n");
aes_decrypt(key, src_val, copy, aes_res, 0xff);
#endif
}
}else{
cnt = 0;
}
}
#endif
@@ -0,0 +1,186 @@
/**
****************************************************************************************
*
* @file app_batt.c
*
* @brief Battery Application Module entry point
*
* Copyright (C) RivieraWaves 2009-2015
*
*
****************************************************************************************
*/
/**
****************************************************************************************
* @addtogroup APP
* @{
****************************************************************************************
*/
#include "rwip_config.h" // SW configuration
#if (BLE_APP_BATT)
/*
* INCLUDE FILES
****************************************************************************************
*/
#include "app_batt.h" // Battery Application Module Definitions
#include "app_task.h" // application task definitions
#include "arch.h" // Platform Definitions
#include "bass_msg.h" // health thermometer functions
#include "co_bt.h"
#include "co_utils.h"
#include "prf.h"
#include "prf_types.h" // Profile common types definition
#include <string.h>
/*
* DEFINES
****************************************************************************************
*/
/*
* GLOBAL VARIABLE DEFINITIONS
****************************************************************************************
*/
/// Battery Application Module Environment Structure
struct app_batt_env_tag app_batt_env;
/*
* GLOBAL FUNCTION DEFINITIONS
****************************************************************************************
*/
void app_batt_init(void)
{
// Reset the environment
memset(&app_batt_env, 0, sizeof(struct app_batt_env_tag));
// Initial battery level: 100
app_batt_env.batt_lvl = 100;
}
void app_batt_add_bas(void)
{
struct bass_db_cfg *db_cfg;
// Allocate the BASS_CREATE_DB_REQ
struct gapm_profile_task_add_cmd *req =
KE_MSG_ALLOC_DYN(GAPM_PROFILE_TASK_ADD_CMD, TASK_GAPM, TASK_APP,
gapm_profile_task_add_cmd, sizeof(struct bass_db_cfg));
// Fill message
req->operation = GAPM_PROFILE_TASK_ADD;
req->sec_lvl = 0; // PERM(SVC_AUTH, AUTH);
req->prf_api_id = TASK_ID_BASS;
req->app_task = TASK_APP;
req->start_hdl = 0;
// Set parameters
db_cfg = (struct bass_db_cfg *)req->param;
// Add a BAS instance
db_cfg->bas_nb = 1;
// Sending of notifications is supported
db_cfg->features[0] = BAS_BATT_LVL_NTF_SUP;
// Send the message
ke_msg_send(req);
}
void app_batt_enable_prf(uint8_t conidx)
{
app_batt_env.conidx = conidx;
// Allocate the message
struct bass_enable_req *req =
KE_MSG_ALLOC(BASS_ENABLE_REQ, prf_dst_task_get(TASK_ID_BASS), TASK_APP,
bass_enable_req);
// Fill in the parameter structure
req->conidx = conidx;
// NTF initial status - Disabled
req->ntf_cfg = PRF_CLI_START_NTF;
req->old_batt_lvl[0] = 50;
// Send the message
ke_msg_send(req);
}
void app_batt_send_lvl(uint8_t batt_lvl)
{
ASSERT_ERR(batt_lvl <= BAS_BATTERY_LVL_MAX);
// Allocate the message
struct bass_batt_level_upd_req *req =
KE_MSG_ALLOC(BASS_BATT_LEVEL_UPD_REQ, prf_dst_task_get(TASK_ID_BASS),
TASK_APP, bass_batt_level_upd_req);
// Fill in the parameter structure
req->bas_instance = 0;
req->batt_level = batt_lvl;
// Send the message
ke_msg_send(req);
}
static int bass_batt_level_ntf_cfg_ind_handler(
ke_msg_id_t const msgid, struct bass_batt_level_ntf_cfg_ind const *param,
ke_task_id_t const dest_id, ke_task_id_t const src_id)
{
return (KE_MSG_CONSUMED);
}
static int batt_level_upd_handler(ke_msg_id_t const msgid,
struct bass_batt_level_upd_rsp const *param,
ke_task_id_t const dest_id,
ke_task_id_t const src_id)
{
return (KE_MSG_CONSUMED);
}
/**
****************************************************************************************
* @brief
*
* @param[in] msgid Id of the message received.
* @param[in] param Pointer to the parameters of the message.
* @param[in] dest_id ID of the receiving task instance (TASK_GAP).
* @param[in] src_id ID of the sending task instance.
*
* @return If the message was consumed or not.
****************************************************************************************
*/
static int app_batt_msg_dflt_handler(ke_msg_id_t const msgid, void const *param,
ke_task_id_t const dest_id,
ke_task_id_t const src_id)
{
// Drop the message
return (KE_MSG_CONSUMED);
}
/*
* LOCAL VARIABLE DEFINITIONS
****************************************************************************************
*/
/// Default State handlers definition
const struct ke_msg_handler app_batt_msg_handler_list[] = {
// Note: first message is latest message checked by kernel so default is put
// on top.
{KE_MSG_DEFAULT_HANDLER, (ke_msg_func_t)app_batt_msg_dflt_handler},
{BASS_BATT_LEVEL_NTF_CFG_IND,
(ke_msg_func_t)bass_batt_level_ntf_cfg_ind_handler},
{BASS_BATT_LEVEL_UPD_RSP, (ke_msg_func_t)batt_level_upd_handler},
};
const struct app_subtask_handlers app_batt_handlers = APP_HANDLERS(app_batt);
#endif // BLE_APP_BATT
/// @} APP
@@ -0,0 +1,110 @@
/**
****************************************************************************************
*
* @file app_batt.h
*
* @brief Battery Application Module entry point
*
* Copyright (C) RivieraWaves 2009-2015
*
*
****************************************************************************************
*/
#ifndef APP_BATT_H_
#define APP_BATT_H_
/**
****************************************************************************************
* @addtogroup APP
* @ingroup RICOW
*
* @brief Battery Application Module entry point
*
* @{
****************************************************************************************
*/
/*
* INCLUDE FILES
****************************************************************************************
*/
#include "rwip_config.h" // SW configuration
#if (BLE_APP_BATT)
#include <stdint.h> // Standard Integer Definition
#include "ke_task.h" // Kernel Task Definition
/*
* STRUCTURES DEFINITION
****************************************************************************************
*/
/// Battery Application Module Environment Structure
struct app_batt_env_tag
{
/// Connection handle
uint8_t conidx;
/// Current Battery Level
uint8_t batt_lvl;
};
/*
* GLOBAL VARIABLES DECLARATIONS
****************************************************************************************
*/
/// Battery Application environment
extern struct app_batt_env_tag app_batt_env;
/// Table of message handlers
extern const struct app_subtask_handlers app_batt_handlers;
/*
* FUNCTIONS DECLARATION
****************************************************************************************
*/
/**
****************************************************************************************
*
* Health Thermometer Application Functions
*
****************************************************************************************
*/
/**
****************************************************************************************
* @brief Initialize Battery Application Module
****************************************************************************************
*/
void app_batt_init(void);
/**
****************************************************************************************
* @brief Add a Battery Service instance in the DB
****************************************************************************************
*/
void app_batt_add_bas(void);
/**
****************************************************************************************
* @brief Enable the Battery Service
****************************************************************************************
*/
void app_batt_enable_prf(uint8_t conidx);
/**
****************************************************************************************
* @brief Send a Battery level value
****************************************************************************************
*/
void app_batt_send_lvl(uint8_t batt_lvl);
#endif //(BLE_APP_BATT)
/// @} APP
#endif // APP_BATT_H_
@@ -0,0 +1,56 @@
#if 0
/*@TRACE*/
enum basc_msg_id
{
/// Start the Battery Service Client Role - at connection
// BASC_ENABLE_REQ = MSG_ID(BASC, 0x00),
///Confirm that cfg connection has finished with discovery results, or that normal cnx started
BASC_ENABLE_RSP = MSG_ID(BASC, 0x01),
/// Read Characteristic Value Request
// BASC_READ_INFO_REQ = MSG_ID(BASC, 0x02),
/// Read Characteristic Value Request
BASC_READ_INFO_RSP = MSG_ID(BASC, 0x03),
/// Write Battery Level Notification Configuration Value request
// BASC_BATT_LEVEL_NTF_CFG_REQ = MSG_ID(BASC, 0x04),
/// Write Battery Level Notification Configuration Value response
BASC_BATT_LEVEL_NTF_CFG_RSP = MSG_ID(BASC, 0x05),
/// Indicate to APP that the Battery Level value has been received
BASC_BATT_LEVEL_IND = MSG_ID(BASC, 0x06),
};
#endif
void xc_basc_enbale_req()
{
//send msg
BASC_ENABLE_REQ
}
void xc_basc_read_info_req()
{
//send msg
BASC_READ_INFO_REQ
}
void xc_basc_batt_leval_ntf_cfg_req()
{
//send msg
BASC_BATT_LEVEL_NTF_CFG_REQ
}
/// Default State handlers definition
KE_MSG_HANDLER_TAB(basc)
{
// Note: all messages must be sorted in ID ascending order
{BASC_ENABLE_RSP, (ke_msg_func_t) xxx_handler },
{BASC_READ_INFO_RSP, (ke_msg_func_t) xxx_handler },
{BASC_BATT_LEVEL_NTF_CFG_RSP, (ke_msg_func_t) xxx_handler },
{BASC_BATT_LEVEL_IND, (ke_msg_func_t) xxx_handler },
};
@@ -0,0 +1,547 @@
/**
****************************************************************************************
*
* @file app_sec.c
*
* @brief Application Security Entry Point
*
* Copyright (C) RivieraWaves 2009-2015
*
*
****************************************************************************************
*/
/**
****************************************************************************************
* @addtogroup APP
* @{
****************************************************************************************
*/
/*
* INCLUDE FILES
****************************************************************************************
*/
#include "rwip_config.h"
#if (BLE_APP_PRESENT)
#if (BLE_HOST_SUPPORT_SMP)
#include "rwip_config.h"
#include <string.h>
#include "co_utils.h"
#include "co_math.h"
//#include "gapc_task.h" // GAP Controller Task API Definition
#include "gap.h" // GAP Definition
#include "gapc.h" // GAPC Definition
#include "gapc_int.h"
#include "prf_types.h"
#include "app_sec.h" // Application Security API Definition
#include "app_task.h" // Application Manager API Definition
#if (NVDS_SUPPORT)
#include "nvds.h" // NVDS API Definitions
#endif //(NVDS_SUPPORT)
#include "app_task.h"
uint8_t bond_flag = 0;
struct gapc_ltk g_ltk = {0};
/*
* GLOBAL VARIABLE DEFINITIONS
****************************************************************************************
*/
/// Application Security Environment Structure
struct app_sec_env_tag app_sec_env;
/*
* GLOBAL FUNCTION DEFINITIONS
****************************************************************************************
*/
void app_sec_init()
{
/*------------------------------------------------------
* RETRIEVE BOND STATUS
*------------------------------------------------------*/
#if (NVDS_SUPPORT)
uint8_t length = NVDS_LEN_PERIPH_BONDED;
// Get bond status from NVDS
if (nvds_get(NVDS_TAG_PERIPH_BONDED, &length, (uint8_t *)&app_sec_env.bonded) != NVDS_OK)
{
// If read value is invalid, set status to not bonded
app_sec_env.bonded = false;
}
if ((app_sec_env.bonded != true) && (app_sec_env.bonded != false))
{
app_sec_env.bonded = false;
}
LOGI("===bond_state:%d\r\n",app_sec_env.bonded);
#endif //(NVDS_SUPPORT)
}
bool app_sec_get_bond_status(void)
{
return app_sec_env.bonded;
}
#if (NVDS_SUPPORT)
void app_sec_remove_bond(void)
{
#if (BLE_APP_HID)
uint16_t ntf_cfg = PRF_CLI_STOP_NTFIND;
#endif //(BLE_APP_HID)
// Check if we are well bonded
if (app_sec_env.bonded == true)
{
// Update the environment variable
app_sec_env.bonded = false;
if (nvds_put(NVDS_TAG_PERIPH_BONDED, NVDS_LEN_PERIPH_BONDED,
(uint8_t *)&app_sec_env.bonded) != NVDS_OK)
{
ASSERT_ERR(0);
}
if (nvds_del(NVDS_TAG_LTK) != NVDS_OK)
{
ASSERT_ERR(0);
}
if (nvds_del(NVDS_TAG_PEER_BD_ADDRESS) != NVDS_OK)
{
ASSERT_ERR(0);
}
#if (BLE_APP_HID)
if (nvds_put(NVDS_TAG_MOUSE_NTF_CFG, NVDS_LEN_MOUSE_NTF_CFG,
(uint8_t *)&ntf_cfg) != NVDS_OK)
{
ASSERT_ERR(0);
}
#endif //(BLE_APP_HID)
}
}
#endif //(NVDS_SUPPORT)
/*
* MESSAGE HANDLERS
****************************************************************************************
*/
static int app_sec_msg_dflt_handler(ke_msg_id_t const msgid,
void *param,
ke_task_id_t const dest_id,
ke_task_id_t const src_id)
{
// Drop the message
return (KE_MSG_CONSUMED);
}
static int gapc_bond_req_ind_handler(ke_msg_id_t const msgid,
void const * p_param,
ke_task_id_t const dest_id,
ke_task_id_t const src_id)
{
struct gapc_bond_req_ind *param = (struct gapc_bond_req_ind *)p_param;
LOGI(" [debug] gapc_bond_req_ind_handler,request:0x%x \r\n",param->request);
// Prepare the GAPC_BOND_CFM message
struct gapc_bond_cfm *cfm = KE_MSG_ALLOC(GAPC_BOND_CFM,
src_id, TASK_APP,
gapc_bond_cfm);
switch (param->request)
{
case (GAPC_PAIRING_REQ):
{
cfm->request = GAPC_PAIRING_RSP;
{
cfm->accept = true;
#if (BLE_SEC_CON)
cfm->data.pairing_feat.auth = GAP_AUTH_REQ_SEC_CON_BOND;
#else // (BLE_SEC_CON)
cfm->data.pairing_feat.auth = GAP_AUTH_REQ_NO_MITM_BOND;
#endif // (BLE_SEC_CON)
app_env.sec_con_enabled = true;
cfm->data.pairing_feat.iocap = GAP_IO_CAP_NO_INPUT_NO_OUTPUT;//GAP_IO_CAP_KB_ONLY;//GAP_IO_CAP_DISPLAY_ONLY;//GAP_IO_CAP_NO_INPUT_NO_OUTPUT;
cfm->data.pairing_feat.key_size = 16;
cfm->data.pairing_feat.oob = GAP_OOB_AUTH_DATA_NOT_PRESENT;
cfm->data.pairing_feat.sec_req = GAP_SEC1_NOAUTH_PAIR_ENC;//GAP_SEC1_AUTH_PAIR_ENC;//GAP_NO_SEC;
cfm->data.pairing_feat.rkey_dist = GAP_KDIST_ENCKEY | GAP_KDIST_IDKEY;
cfm->data.pairing_feat.ikey_dist = GAP_KDIST_ENCKEY | GAP_KDIST_IDKEY;
}
} break;
case (GAPC_LTK_EXCH):
{
// Counter
uint8_t counter;
cfm->accept = true;
cfm->request = GAPC_LTK_EXCH;
// Generate all the values
cfm->data.ltk.ediv = (uint16_t)co_rand_word();
for (counter = 0; counter < RAND_NB_LEN; counter++)
{
cfm->data.ltk.ltk.key[counter] = (uint8_t)co_rand_word();
cfm->data.ltk.randnb.nb[counter] = (uint8_t)co_rand_word();
}
for (counter = RAND_NB_LEN; counter < KEY_LEN; counter++)
{
cfm->data.ltk.ltk.key[counter] = (uint8_t)co_rand_word();
}
#if (1)
LOGI( "nvds_put cfm->ediv=0x%x\r\nparam_randnb:",cfm->data.ltk.ediv);
for(uint8_t i=0;i<GAP_RAND_NB_LEN;i++)
LOGI( "%x",cfm->data.ltk.randnb.nb[i]);
LOGI("\r\nltk:");
for(uint8_t i=0;i<GAP_KEY_LEN;i++)
LOGI( "%x",cfm->data.ltk.ltk.key[i]);
LOGI("\r\n");
#endif
#if (NVDS_SUPPORT)
uint8_t err = nvds_del(NVDS_TAG_LTK);
LOGI("err2 =%d \n", err);
// Store the generated value in NVDS
if (nvds_put(NVDS_TAG_LTK, NVDS_LEN_LTK, (uint8_t *)&cfm->data.ltk) != NVDS_OK)
{
ASSERT_ERR(0);
}
// uint8_t buff5[10] = {1,2,3,4,5,6,9,8,9,11};
// // LOGI("nvds del:%d \r\n",nvds_del(16));
// if (nvds_put(18, 10, buff5) != NVDS_OK)
// {
// LOGI("77111\r\n");
// ASSERT_ERR(0);
// }
// LOGI("77222\r\n");
#endif // #if (NVDS_SUPPORT)
} break;
case (GAPC_IRK_EXCH):
{
#if (NVDS_SUPPORT)
uint8_t addr_len = BD_ADDR_LEN;
#endif //(NVDS_SUPPORT)
cfm->accept = true;
cfm->request = GAPC_IRK_EXCH;
// Load IRK
memcpy(cfm->data.irk.irk.key, app_env.loc_irk, KEY_LEN);
#if (NVDS_SUPPORT)
if (nvds_get(NVDS_TAG_BD_ADDRESS, &addr_len, cfm->data.irk.addr.addr) != NVDS_OK)
#endif //(NVDS_SUPPORT)
{
ASSERT_ERR(0);
}
// load device address
cfm->data.irk.addr.addr_type = (cfm->data.irk.addr.addr[5] & 0xC0) ? ADDR_RAND : ADDR_PUBLIC;
} break;
//#if (BLE_APP_HT)
case (GAPC_TK_EXCH):
{
// Generate a PIN Code- (Between 100000 and 999999)
uint32_t pin_code = (100000 + (co_rand_word()%900000));
LOGI("app_sec GAPC_TK_EXCH: tk_type=%d\r\n",param->data.tk_type);
cfm->accept = true;
cfm->request = GAPC_TK_EXCH;
// Set the TK value
memset(cfm->data.tk.key, 0, KEY_LEN);
cfm->data.tk.key[0] = (uint8_t)((pin_code & 0x000000FF) >> 0);
cfm->data.tk.key[1] = (uint8_t)((pin_code & 0x0000FF00) >> 8);
cfm->data.tk.key[2] = (uint8_t)((pin_code & 0x00FF0000) >> 16);
cfm->data.tk.key[3] = (uint8_t)((pin_code & 0xFF000000) >> 24);
LOGI("###GAPC_TK_EXCH pincode=%d\r\n", pin_code);
} break;
//#endif //(BLE_APP_HT)
default:
{
ASSERT_ERR(0);
} break;
}
// Send the message
ke_msg_send(cfm);
return (KE_MSG_CONSUMED);
}
static int gapc_bond_ind_handler(ke_msg_id_t const msgid,
void const *p_param,
ke_task_id_t const dest_id,
ke_task_id_t const src_id)
{
struct gapc_bond_ind const *param = (struct gapc_bond_ind const *)p_param;
LOGI(" [debug] gapc_bond_ind_handler : info=%d\r\n", param->info);
switch (param->info)
{
case (GAPC_PAIRING_SUCCEED):
{
// Update the bonding status in the environment
app_sec_env.bonded = true;
bond_flag = 1;
LOGI("GAPC_PAIRING_SUCCEED auth=%d,ltk_present=%d\r\n",
param->data.pairing.level,param->data.pairing.ltk_present);
// Update the bonding status in the environment
#if (PLF_NVDS)
uint8_t err = nvds_del(NVDS_TAG_PERIPH_BONDED);
LOGI("err1 =%d \n", err);
if (nvds_put(NVDS_TAG_PERIPH_BONDED, NVDS_LEN_PERIPH_BONDED,
(uint8_t *)&app_sec_env.bonded) != NVDS_OK)
{
// An error has occurred during access to the NVDS
ASSERT_ERR(0);
LOGI("3\n");
}
LOGI("4\n");
// Set the BD Address of the peer device in NVDS
uint8_t err2 = nvds_del(NVDS_TAG_PEER_BD_ADDRESS);
LOGI("err2 =%d \n", err);
struct app_env_tag *app_env = get_app_env();
if (nvds_put(NVDS_TAG_PEER_BD_ADDRESS, NVDS_LEN_PEER_BD_ADDRESS,
(uint8_t *)gapc_get_bdaddr(app_env->slave_conidx, GAPC_SMP_INFO_PEER)) != NVDS_OK)
{
// An error has occurred during access to the NVDS
ASSERT_ERR(0);
LOGI("5\n");
}
LOGI("6\n");
#endif //(PLF_NVDS)
} break;
case (GAPC_REPEATED_ATTEMPT):
{
// app_disconnect();
} break;
case (GAPC_IRK_EXCH):
{
#if (NVDS_SUPPORT)
// Store peer identity in NVDS
LOGI("GAPC_IRK_EXCH\r\n");
uint8_t err = nvds_del(NVDS_TAG_PEER_IRK);
LOGI("err2 =%d \n", err);
if (nvds_put(NVDS_TAG_PEER_IRK, NVDS_LEN_PEER_IRK, (uint8_t *)&param->data.irk.irk.key[0]) != NVDS_OK)
{
LOGI("1\r\n");
ASSERT_ERR(0);
}
LOGI("2\r\n");
#endif // (NVDS_SUPPORT)
} break;
case (GAPC_PAIRING_FAILED):
{
// app_sec_send_security_req(0);
} break;
// In Secure Connections we get BOND_IND with SMPC calculated LTK
case (GAPC_LTK_EXCH) :
{
LOGI( "GAPC_LTK_EXCH sec_con_enabled=%d\r\n",app_env.sec_con_enabled);
LOGI( " param->ediv=0x%x\r\nparam_randnb:",param->data.ltk.ediv);
for(uint8_t i=0;i<GAP_RAND_NB_LEN;i++)
LOGI( "%x",param->data.ltk.randnb.nb[i]);
LOGI("\r\nltk:");
for(uint8_t i=0;i<GAP_KEY_LEN;i++)
LOGI( "%x",param->data.ltk.ltk.key[i]);
LOGI("\r\n");
#if (0)
if (app_env.sec_con_enabled == true)
{
#if (NVDS_SUPPORT)
// Store LTK in NVDS
if (nvds_put(NVDS_TAG_LTK, NVDS_LEN_LTK,(uint8_t *)&param->data.ltk.ltk.key[0]) != NVDS_OK)
{
ASSERT_ERR(0);
}
#endif // (NVDS_SUPPORT)
}
#endif // (BLE_APP_SEC_CON)
}
break;
default:
{
ASSERT_ERR(0);
} break;
}
return (KE_MSG_CONSUMED);
}
static int gapc_encrypt_req_ind_handler(ke_msg_id_t const msgid,
void const *p_param,
ke_task_id_t const dest_id,
ke_task_id_t const src_id)
{
struct gapc_encrypt_req_ind const *param = (struct gapc_encrypt_req_ind const *)p_param;
LOGI(" [debug] gapc_encrypt_req_ind_handler \r\n");
#if (NVDS_SUPPORT)
// LTK value
struct gapc_ltk ltk;
// Length
uint8_t length = NVDS_LEN_LTK;
#endif // #if (NVDS_SUPPORT)
// Prepare the GAPC_ENCRYPT_CFM message
struct gapc_encrypt_cfm *cfm = KE_MSG_ALLOC(GAPC_ENCRYPT_CFM,
src_id, TASK_APP,
gapc_encrypt_cfm);
cfm->found = false;
LOGI("app_sec gapc_encrypt_req_ind_handler: bonded=%d\r\n", app_sec_env.bonded);
// if (app_sec_env.bonded)
{
#if (NVDS_SUPPORT)
// Retrieve the required informations from NVDS
if (nvds_get(NVDS_TAG_LTK, &length, (uint8_t *)&ltk) == NVDS_OK)
{
LOGI( "nvds_get param->ediv=0x%x,ltk.ediv=0x%x\r\nparam_randnb:",param->ediv,ltk.ediv);
for(uint8_t i=0;i<GAP_RAND_NB_LEN;i++)
LOGI( "%x",param->rand_nb.nb[i]);
LOGI("\r\nltk.randnb.nb:");
for(uint8_t i=0;i<GAP_RAND_NB_LEN;i++)
LOGI( "%x",ltk.randnb.nb[i]);
LOGI("\r\n");
// Check if the provided EDIV and Rand Nb values match with the stored values
if ((param->ediv == ltk.ediv) &&
!memcmp(&param->rand_nb.nb[0], &ltk.randnb.nb[0], sizeof(struct rand_nb)))
{
LOGI("EDIV and randnb are same!!!\r\n");
cfm->found = true;
cfm->key_size = 16;
memcpy(&cfm->ltk, &ltk.ltk, sizeof(struct gap_sec_key));
bond_flag = 1;
}
else
{
LOGI("EDIV and randnb not same!!!\r\n");
}
/*
* else we are bonded with another device, disconnect the link
*/
}
else
{
ASSERT_ERR(0);
}
#endif // #if (NVDS_SUPPORT)
}
/*
* else the peer device is not known, an error should trigger a new pairing procedure.
*/
// Send the message
ke_msg_send(cfm);
return (KE_MSG_CONSUMED);
}
static int gapc_encrypt_ind_handler(ke_msg_id_t const msgid,
void const *p_param,
ke_task_id_t const dest_id,
ke_task_id_t const src_id)
{
struct gapc_encrypt_ind const *param = (struct gapc_encrypt_ind const *)p_param;
LOGI(" [debug] gapc_encrypt_ind_handler \r\n");
// encryption/ re-encryption succeeded
LOGI("app_sec gapc_encrypt_ind_handler: auth=%d\r\n", param->pairing_lvl);
// struct gapc_set_le_pkt_size_cmd *req = KE_MSG_ALLOC(GAPC_SET_LE_PKT_SIZE_CMD,
// KE_BUILD_ID(TASK_GAPC, KE_IDX_GET(src_id)), TASK_APP,
// gapc_set_le_pkt_size_cmd);
// req->operation = GAPC_SET_LE_PKT_SIZE;
// req->tx_octets = 0xFB;
// req->tx_time = 2120;
// // Send the message
// ke_msg_send(req);
return (KE_MSG_CONSUMED);
}
/*
* LOCAL VARIABLE DEFINITIONS
****************************************************************************************
*/
/// Default State handlers definition
const struct ke_msg_handler app_sec_msg_handler_list[] =
{
// Note: first message is latest message checked by kernel so default is put on top.
{KE_MSG_DEFAULT_HANDLER, (ke_msg_func_t)app_sec_msg_dflt_handler},
{GAPC_BOND_REQ_IND, (ke_msg_func_t)gapc_bond_req_ind_handler},
{GAPC_BOND_IND, (ke_msg_func_t)gapc_bond_ind_handler},
{GAPC_ENCRYPT_REQ_IND, (ke_msg_func_t)gapc_encrypt_req_ind_handler},
{GAPC_ENCRYPT_IND, (ke_msg_func_t)gapc_encrypt_ind_handler},
};
const struct app_subtask_handlers app_sec_handlers = {&app_sec_msg_handler_list[0], ARRAY_LEN(app_sec_msg_handler_list)};
#endif
#endif // (BLE_APP_PRESENT)
/// @} APP
@@ -0,0 +1,96 @@
/**
****************************************************************************************
*
* @file app_sec.h
*
* @brief Application Security Entry Point
*
* Copyright (C) RivieraWaves 2009-2015
*
*
****************************************************************************************
*/
/**
****************************************************************************************
* @addtogroup APP_SEC
* @{
****************************************************************************************
*/
#ifndef APP_SEC_H_
#define APP_SEC_H_
/*
* INCLUDE FILES
****************************************************************************************
*/
#include "rwip_config.h"
#include <stdint.h> // Standard Integer Definition
#include <stdbool.h>
/*
* DEFINES
****************************************************************************************
*/
/*
* STRUCTURES DEFINITIONS
****************************************************************************************
*/
struct app_sec_env_tag
{
// Bond status
bool bonded;
};
/*
* GLOBAL VARIABLE DECLARATIONS
****************************************************************************************
*/
/// Application Security Environment
extern struct app_sec_env_tag app_sec_env;
/// Table of message handlers
extern const struct app_subtask_handlers app_sec_handlers;
/*
* GLOBAL FUNCTIONS DECLARATIONS
****************************************************************************************
*/
/**
****************************************************************************************
* @brief Initialize the Application Security Module
****************************************************************************************
*/
void app_sec_init(void);
#if (NVDS_SUPPORT)
/**
****************************************************************************************
* @brief Remove all bond data stored in NVDS
****************************************************************************************
*/
void app_sec_remove_bond(void);
#endif //(NVDS_SUPPORT)
/**
****************************************************************************************
* @brief Send a security request to the peer device. This function is used to require the
* central to start the encryption with a LTK that would have shared during a previous
* bond procedure.
*
* @param[in] - conidx: Connection Index
****************************************************************************************
*/
void app_sec_send_security_req(uint8_t conidx);
#endif // APP_SEC_H_
/// @} APP_SEC
@@ -0,0 +1,624 @@
/**
****************************************************************************************
*
* @file app_task.c
*
* @brief RW APP Task implementation
*
* Copyright (C) RivieraWaves 2009-2015
*
*
****************************************************************************************
*/
#include "rwip_config.h"
#if (BLE_APP_PRESENT)
#include "app_sec.h"
#include "app_task.h" // Application Manager Task API
#include "lld_int.h"
#include "usr_server.h"
#include "xc_gatt_client_api.h"
#include "reg_ipcore.h"
extern struct ADV_INFO adv_info;
extern struct lld_env_tag lld_env;
/// Application Task Descriptor
const struct ke_task_desc TASK_DESC_APP;
/// Application Environment Structure
struct app_env_tag app_env = {
.adv_actv_idx = INVALID_DATA,
.slave_conidx = INVALID_DATA,
.slave_connected = false,
};
struct app_env_tag *get_app_env(void) { return &app_env; }
static uint8_t gapc_callback(ke_msg_id_t const msgid, void const *param,
ke_task_id_t const dest_id,
ke_task_id_t const src_id);
static uint8_t gapm_callback(ke_msg_id_t const msgid, void const *param,
ke_task_id_t const dest_id,
ke_task_id_t const src_id);
void app_init()
{
// Reset the application manager environment
memset(&app_env, 0, sizeof(app_env));
// Create APP task
ke_task_create(TASK_APP, &TASK_DESC_APP);
// Initialize Task state
ke_state_set(TASK_APP, APP_INIT);
#if (NVDS_SUPPORT)
// Get the Device Name to add in the Advertising Data (Default one or NVDS
// one)
// app_env.dev_name_len = APP_DEVICE_NAME_MAX_LEN;
// if (nvds_get(NVDS_TAG_DEVICE_NAME, &(app_env.dev_name_len),
// app_env.dev_name) != NVDS_OK)
#endif //(NVDS_SUPPORT)
{
// Get default Device Name (No name if not enough space)
memcpy(app_env.dev_name, APP_DFLT_DEVICE_NAME,
APP_DFLT_DEVICE_NAME_LEN);
app_env.dev_name_len = APP_DFLT_DEVICE_NAME_LEN;
}
// Reset the stack
xc_ble_gapm_reset();
}
uint8_t app_get_dev_name(uint8_t *name)
{
if ((app_env.dev_name_len > 0) &&
(app_env.dev_name_len <= APP_DEVICE_NAME_MAX_LEN) && (name != NULL)) {
// copy name to provided pointer
memcpy(name, app_env.dev_name, APP_DFLT_DEVICE_NAME_LEN);
// return name length
return app_env.dev_name_len;
} else {
return 0;
}
}
void app_set_dev_name(uint8_t *name, uint8_t name_len)
{
if ((name_len > 0) && (name_len <= APP_DEVICE_NAME_MAX_LEN) &&
(name != NULL)) {
memcpy(app_env.dev_name, name, name_len);
app_env.dev_name_len = name_len;
}
}
// adv
void app_create_advertising(void)
{
if (app_env.adv_state == APP_ADV_STATE_IDLE) {
struct gapm_activity_create_adv_cmd param = {0};
param.own_addr_type = GAPM_STATIC_ADDR;
param.adv_param.type = GAPM_ADV_TYPE_LEGACY;
param.adv_param.disc_mode = GAPM_ADV_MODE_GEN_DISC;
param.adv_param.prop = GAPM_ADV_PROP_UNDIR_CONN_MASK;
param.adv_param.max_tx_pwr = APP_MAX_TX_POWER;
param.adv_param.filter_pol = ADV_ALLOW_SCAN_ANY_CON_ANY;
param.adv_param.prim_cfg.adv_intv_min = APP_ADV_INT_MIN;
param.adv_param.prim_cfg.adv_intv_max = APP_ADV_INT_MAX;
param.adv_param.prim_cfg.chnl_map = APP_ADV_CHMAP;
param.adv_param.prim_cfg.phy = GAP_PHY_1MBPS;
xc_ble_advertise_create(&param);
app_env.adv_state = APP_ADV_STATE_STARTING;
}
}
void app_set_adv_data(void)
{
if (app_env.adv_state == APP_ADV_STATE_STARTING) {
uint8_t adv_data[ADV_DATA_MAX_LENGTH] = {0};
adv_data[0] = APP_DFLT_DEVICE_NAME_LEN + 1;
adv_data[1] = GAP_AD_TYPE_COMPLETE_NAME;
memcpy(&adv_data[2], APP_DFLT_DEVICE_NAME, APP_DFLT_DEVICE_NAME_LEN);
xc_ble_set_adv_data(app_env.adv_actv_idx, APP_DFLT_DEVICE_NAME_LEN + 2,
adv_data);
adv_info.name_length= APP_SINGLEOTA_DEVICE_NAME_LEN;
memcpy(&adv_info.name,APP_SINGLEOTA_DEVICE_NAME,APP_SINGLEOTA_DEVICE_NAME_LEN);
app_env.adv_state = APP_ADV_STATE_SETTING_ADV_DATA;
}
}
void app_set_scan_rsp_data(void)
{
if (app_env.adv_state == APP_ADV_STATE_SETTING_ADV_DATA) {
uint8_t scan_rsp_data[ADV_DATA_MAX_LENGTH] = {0};
scan_rsp_data[0] = MANUFACTURER_DATA_LEN + 1;
scan_rsp_data[1] = GAP_AD_TYPE_MANU_SPECIFIC_DATA;
memcpy(&scan_rsp_data[2], MANUFACTURER_DATA, MANUFACTURER_DATA_LEN);
xc_ble_set_scan_rsp_data(app_env.adv_actv_idx,
MANUFACTURER_DATA_LEN + 2, scan_rsp_data);
app_env.adv_state = APP_ADV_STATE_SETTING_SCAN_RSP_DATA;
}
}
void app_start_advertising(void)
{
if (app_env.adv_state == APP_ADV_STATE_SETTING_ADV_DATA ||
app_env.adv_state == APP_ADV_STATE_SETTING_SCAN_RSP_DATA ||
app_env.adv_state == APP_ADV_STATE_STOPPED) {
struct gapm_activity_start_cmd param = {0};
param.actv_idx = app_env.adv_actv_idx;
param.u_param.adv_add_param.duration = ADV_DURATION;
xc_ble_advertise_start(&param);
app_env.adv_state = APP_ADV_STATE_STARTING;
}
}
void app_stop_advertising(void)
{
if (app_env.adv_state == APP_ADV_STATE_STARTING) {
xc_ble_activity_stop(app_env.adv_actv_idx);
app_env.adv_state = APP_ADV_STATE_STOPPING;
}
}
void app_delete_advertising(void)
{
if (app_env.adv_state == APP_ADV_STATE_STOPPED) {
printf("app_delete_advertising\n");
xc_ble_activity_delete(app_env.adv_actv_idx);
app_env.adv_state = APP_ADV_STATE_IDLE;
}
}
static uint8_t
app_get_handler(const struct app_subtask_handlers *handler_list_desc,
ke_msg_id_t msgid, void *p_param, ke_task_id_t src_id)
{
// Counter
uint8_t counter;
// Get the message handler function by parsing the message table
for (counter = handler_list_desc->msg_cnt; 0 < counter; counter--) {
struct ke_msg_handler handler = (struct ke_msg_handler)(
*(handler_list_desc->p_msg_handler_tab + counter - 1));
if ((handler.id == msgid) || (handler.id == KE_MSG_DEFAULT_HANDLER)) {
// If handler is NULL, message should not have been received in this
// state
ASSERT_ERR(handler.func);
return (uint8_t)(handler.func(msgid, p_param, TASK_APP, src_id));
}
}
// If we are here no handler has been found, drop the message
return (KE_MSG_CONSUMED);
}
/**
****************************************************************************************
* @brief Handles reception of all messages sent from the lower layers to the
*application
* @param[in] msgid Id of the message received.
* @param[in] p_param Pointer to the parameters of the message.
* @param[in] dest_id ID of the receiving task instance
* @param[in] src_id ID of the sending task instance.
*
* @return If the message was consumed or not.
****************************************************************************************
*/
static int app_msg_handler(ke_msg_id_t const msgid, void *p_param,
ke_task_id_t const dest_id,
ke_task_id_t const src_id)
{
// Retrieve identifier of the task from received message
ke_task_id_t src_task_id = MSG_T(msgid);
// Message policy
uint8_t msg_pol = KE_MSG_CONSUMED;
switch (src_task_id) {
case TASK_ID_GAPM: {
msg_pol = gapm_callback(msgid, p_param, dest_id, src_id);
} break;
case TASK_ID_GAPC: {
if ((msgid >= GAPC_BOND_CMD) && (msgid <= GAPC_BOND_DATA_UPDATE_IND)) {
#if ((BLE_HOST_SUPPORT_SMP))
// Call the Security Module
msg_pol =
app_get_handler(&app_sec_handlers, msgid, p_param, src_id);
#endif
} else {
msg_pol = gapc_callback(msgid, p_param, dest_id, src_id);
}
} break;
case TASK_ID_GATT: {
} break;
#if (BLE_APP_HT)
case (TASK_ID_HTPT): {
// Call the Health Thermometer Module
msg_pol = app_get_handler(&app_ht_handlers, msgid, p_param, src_id);
} break;
#endif //(BLE_APP_HT)
#if (BLE_APP_DIS)
case (TASK_ID_DISS): {
// Call the Device Information Module
msg_pol = app_get_handler(&app_dis_handlers, msgid, p_param, src_id);
} break;
#endif //(BLE_APP_DIS)
#if (BLE_APP_HID)
case (TASK_ID_HOGPD): {
// Call the HID Module
msg_pol = app_get_handler(&app_hid_handlers, msgid, p_param, src_id);
} break;
#endif //(BLE_APP_HID)
default:
break;
}
return (msg_pol);
}
/**
****************************************************************************************
* @brief Handles GAP manager command complete events.
*
* @param[in] msgid Id of the message received.
* @param[in] p_param Pointer to the parameters of the message.
* @param[in] dest_id ID of the receiving task instance (TASK_GAP).
* @param[in] src_id ID of the sending task instance.
****************************************************************************************
*/
// const struct le_features llm_local_le_feats_app =
// {{ 0x3, 0x40, 0x0, 0x0,
// 0x0, 0x0, 0x0, 0x0 }};
// void app_features_get(struct le_features *feats)
// {
// uint8_t byte_nb, bit_nb;
//
// memcpy(&feats->feats[0], &llm_local_le_feats_app.feats[0], (0x08));
// LOGI("app_features_get\n");
// }
static void gapm_cmp_evt(ke_msg_id_t const msgid,
struct gapm_cmp_evt const *p_param,
ke_task_id_t const dest_id, ke_task_id_t const src_id)
{
LOGI(" app gapm_cmp_evt operation:0x%02x, status :0x%02x\r\n",
p_param->operation, p_param->status);
if (p_param->status == GAP_ERR_NO_ERROR) {
switch (p_param->operation) {
// Reset completed
case GAPM_RESET: {
struct gapm_set_dev_config_cmd cfg_param = {
.role = GAP_ROLE_PERIPHERAL,
.sugg_max_tx_octets = BLE_MAX_OCTETS,
// .sugg_max_tx_time = BLE_MAX_TIME,
.sugg_max_tx_time = 2120,
// .pairing_mode = GAPM_PAIRING_DISABLE,
#if (BLE_SEC_CON)
.pairing_mode = GAPM_PAIRING_SEC_CON,
#else // (BLE_SEC_CON)
.pairing_mode = GAPM_PAIRING_LEGACY,
#endif // (BLE_SEC_CON)
};
xc_ble_set_dev_config(&cfg_param);
lld_env.dft_slave_md = 0;
#if (CONN_EVENT_NOT_RUN_XIP == 3)
((*(volatile uint32_t *)(0x53000050)) = (0<<15) | (0x7<<8) | (1<< 7) | (0x3 << 0));
#endif // (CONN_EVENT_NOT_RUN_XIP == 3)
// rom_env.llm_le_features_get = app_features_get;
} break;
case GAPM_SET_DEV_CONFIG: {
if(!custom_svc_add())
{
app_create_advertising();
}
} break;
case GAPM_SET_ADV_DATA: {
app_start_advertising();
} break;
case GAPM_STOP_ACTIVITY: {
app_delete_advertising();
} break;
case GAPM_DELETE_ACTIVITY: {
} break;
case GAPM_CREATE_ADV_ACTIVITY:
break;
default:
break;
}
} else {
ASSERT_ERR(0);
}
}
static void gapc_get_device_info_req_ind(
ke_msg_id_t const msgid, struct gapc_get_dev_info_req_ind const *param,
ke_task_id_t const dest_id, ke_task_id_t const src_id)
{
uint8_t conidx = KE_IDX_GET(src_id);
struct gapc_get_dev_info_cfm *pcfm = NULL;
switch (param->req) {
case GAPC_DEV_NAME: {
pcfm = KE_MSG_ALLOC_DYN(
GAPC_GET_DEV_INFO_CFM, KE_BUILD_ID(TASK_GAPC, conidx), TASK_APP,
gapc_get_dev_info_cfm, DEVICE_NAME_MAX_LEN);
pcfm->req = param->req;
pcfm->token = param->token;
pcfm->status = GAP_ERR_NO_ERROR;
pcfm->info.name.value_length = app_get_dev_name(pcfm->info.name.value);
} break;
case GAPC_DEV_APPEARANCE: {
pcfm = KE_MSG_ALLOC_DYN(
GAPC_GET_DEV_INFO_CFM, KE_BUILD_ID(TASK_GAPC, conidx), TASK_APP,
gapc_get_dev_info_cfm, 0);
pcfm->req = param->req;
pcfm->info.appearance = DEV_APPEARANCE;
pcfm->token = param->token;
pcfm->status = GAP_ERR_NO_ERROR;
} break;
case GAPC_DEV_SLV_PREF_PARAMS: {
pcfm = KE_MSG_ALLOC_DYN(
GAPC_GET_DEV_INFO_CFM, KE_BUILD_ID(TASK_GAPC, conidx), TASK_APP,
gapc_get_dev_info_cfm, 0);
pcfm->req = param->req;
pcfm->info.slv_pref_params.con_intv_min = BLE_UAPDATA_MIN_INTVALUE;
// Slave preferred Connection interval Max
pcfm->info.slv_pref_params.con_intv_max = BLE_UAPDATA_MAX_INTVALUE;
// Slave preferred Connection latency
pcfm->info.slv_pref_params.slave_latency = BLE_UAPDATA_LATENCY;
// Slave preferred Link supervision timeout
pcfm->info.slv_pref_params.conn_timeout = BLE_UAPDATA_TIMEOUT;
pcfm->token = param->token;
pcfm->status = GAP_ERR_NO_ERROR;
} break;
default:
break;
}
if (pcfm) {
xc_ble_get_dev_info_cfm(conidx, pcfm);
}
}
static void gapm_profile_add_ind(ke_msg_id_t const msgid, void const *param,
ke_task_id_t const dest_id,
ke_task_id_t const src_id)
{
struct gapm_profile_added_ind *p_param =
(struct gapm_profile_added_ind *)param;
// Current State
ke_state_t state = ke_state_get(dest_id);
LOGI("gapm_profile_add_ind profile_task_id:0x%x,state=0x%x\r\n",
p_param->prf_task_id, state);
switch (p_param->prf_task_id) {
case TASK_ID_BASS: {
} break;
case TASK_ID_BASC: {
} break;
default:
break;
}
}
static void gapm_activity_created_ind(ke_msg_id_t const msgid,
void const *param,
ke_task_id_t const dest_id,
ke_task_id_t const src_id)
{
struct gapm_activity_created_ind *p_param =
(struct gapm_activity_created_ind *)param;
LOGI(" gapm_activity_created_ind actv_idx = %d,actv_type = %d \r\n",
p_param->actv_idx, p_param->actv_type);
switch (p_param->actv_type) {
case GAPM_ACTV_TYPE_ADV: {
app_env.adv_actv_idx = p_param->actv_idx;
app_set_adv_data();
} break;
default:
break;
}
}
static void gapm_activity_stop_ind(ke_msg_id_t const msgid, void const *param,
ke_task_id_t const dest_id,
ke_task_id_t const src_id)
{
struct gapm_activity_stopped_ind *p_param =
(struct gapm_activity_stopped_ind *)param;
LOGI(" actv_id=%d actv_type=%d, reason=0x%x\r\n", p_param->actv_idx,
p_param->actv_type, p_param->reason);
if (p_param->actv_idx == app_env.adv_actv_idx) {
app_env.adv_state = APP_ADV_STATE_STOPPED;
}
}
static uint8_t gapm_callback(ke_msg_id_t const msgid, void const *param,
ke_task_id_t const dest_id,
ke_task_id_t const src_id)
{
switch (msgid) {
case GAPM_CMP_EVT:
gapm_cmp_evt(msgid, param, dest_id, src_id);
break;
case GAPM_DEV_BDADDR_IND:
LOGI("GAPM_DEV_BDADDR_IND\r\n");
break;
case GAPM_GEN_RAND_NB_IND: {
struct gapm_gen_rand_nb_ind *p_param =
(struct gapm_gen_rand_nb_ind *)param;
// First part of IRK
if (app_env.rand_cnt == 1) {
memcpy(&app_env.loc_irk[0], &p_param->randnb.nb[0], 8);
}
// Second part of IRK
else if (app_env.rand_cnt == 2) {
memcpy(&app_env.loc_irk[8], &p_param->randnb.nb[0], 8);
}
} break;
case GAPM_ACTIVITY_CREATED_IND: {
gapm_activity_created_ind(msgid, param, dest_id, src_id);
} break;
case GAPM_ACTIVITY_STOPPED_IND: {
gapm_activity_stop_ind(msgid, param, dest_id, src_id);
} break;
case GAPM_SCAN_REQUEST_IND:
LOGI("GAPM_SCAN_REQUEST_IND\r\n");
break;
case GAPM_PROFILE_ADDED_IND: {
gapm_profile_add_ind(msgid, param, dest_id, src_id);
}
default:
break;
}
return (KE_MSG_CONSUMED);
}
static uint8_t gapc_callback(ke_msg_id_t const msgid, void const *param,
ke_task_id_t const dest_id,
ke_task_id_t const src_id)
{
uint8_t conidx = KE_IDX_GET(src_id);
switch (msgid) {
case GAPC_CMP_EVT: {
struct gapc_cmp_evt const *p_param = (struct gapc_cmp_evt const *)param;
LOGI("GAPC_CMP_EVT operation = 0x%x, status = 0x%x conidx = "
"0x%x\r\n",
p_param->operation, p_param->status, conidx);
} break;
case GAPC_CONNECTION_REQ_IND: {
struct gapc_connection_req_ind *p_param =
(struct gapc_connection_req_ind *)param;
LOGI(" GAPC_CONNECTION_REQ_IND conhdl = x%x, conidx = 0x%x ",
p_param->conhdl, conidx);
LOGI("conn_intv:%d, role=%d addr: ", p_param->con_interval,
p_param->role);
// DUMP_DATA_PRINTF(&(p_param->peer_addr.addr[0]),
// GAP_BD_ADDR_LEN);
// device as slave
if (p_param->role == GAPM_ROLE_SLAVE) {
app_env.slave_conidx = conidx;
app_env.slave_connected = true;
}
// Check if the received connection index is valid
if (conidx != GAP_INVALID_CONIDX) {
struct gapc_connection_cfm cfm = {0};
cfm.pairing_lvl = GAP_PAIRING_UNAUTH;
xc_ble_conn_cfm(conidx, &cfm);
xc_ble_gatt_cli_mtu_exch(conidx, app_env.user_lid);
}
// #if (BLE_SEC_CON)
// xc_ble_req_security(conidx, GAP_AUTH_REQ_SEC_CON_BOND);
// #else // (BLE_SEC_CON)
// xc_ble_req_security(conidx, GAP_AUTH_REQ_NO_MITM_BOND);
// #endif // (BLE_SEC_CON)
// xc_ble_set_pkt_size(conidx, 251, 2120);
} break;
case GAPC_DISCONNECT_IND: {
struct gapc_disconnect_ind *p_param =
(struct gapc_disconnect_ind *)param;
LOGI("GAPC_DISCONNECT_IND conidx = 0x%x, reason = 0x%x\r\n", conidx,
p_param->reason);
if (conidx == app_env.slave_conidx) {
app_env.slave_conidx = INVALID_DATA;
app_env.slave_connected = false;
app_start_advertising();
}
} break;
case GAPC_GET_DEV_INFO_REQ_IND: {
gapc_get_device_info_req_ind(msgid, param, dest_id, src_id);
} break;
case GAPC_SET_DEV_INFO_REQ_IND: {
struct gapc_set_dev_info_req_ind *p_param =
(struct gapc_set_dev_info_req_ind *)param;
struct gapc_set_dev_info_cfm cfm = {0};
LOGI("GAPC_SET_DEV_INFO_REQ_IND param->req=0x%x,conidx=0x%x\r\n",
p_param->req, conidx);
xc_ble_set_dev_info_cfm(conidx, &cfm);
} break;
case GAPC_PARAM_UPDATE_REQ_IND: {
struct gapc_param_update_req_ind *p_param =
(struct gapc_param_update_req_ind *)param;
struct gapc_param_update_cfm cfm = {0};
LOGI("GAPC_PARAM_UPDATE_REQ_IND "
"conidx=0x%x,intv_max=0x%x,intv_min=0x%x",
conidx, p_param->intv_max, p_param->intv_min);
LOGI("latency=0x%x,time_out=0x%x\r\n", p_param->latency,
p_param->time_out);
// Check if the received Connection Handle was valid
if (app_env.conidx != GAP_INVALID_CONIDX) {
cfm.accept = true;
cfm.ce_len_min = CE_LEN_MIN;
cfm.ce_len_max = CE_LEN_MAX;
xc_ble_param_update_cfm(conidx, &cfm);
}
} break;
case GAPC_PARAM_UPDATED_IND: {
struct gapc_param_updated_ind *p_param =
(struct gapc_param_updated_ind *)param;
LOGI("GAPC_PARAM_UPDATED_IND "
"conidx=0x%x,con_interval=0x%x,con_latency=0x%x ",
conidx, p_param->con_interval, p_param->con_latency);
LOGI("sup_to=0x%x\r\n", p_param->sup_to);
} break;
case GAPC_LE_PKT_SIZE_IND: {
struct gapc_le_pkt_size_ind *p_param =
(struct gapc_le_pkt_size_ind *)param;
LOGI("GAPC_LE_PKT_SIZE_IND "
"conidx=0x%x, max_rx_octets:%d",
conidx, p_param->max_rx_octets);
LOGI("max_rx_time:%d,max_tx_octets:%d, "
"max_tx_time :%d\r\n",
p_param->max_rx_time, p_param->max_tx_octets,
p_param->max_tx_time);
} break;
case GAPC_CON_RSSI_IND: {
struct gapc_con_rssi_ind *p_param = (struct gapc_con_rssi_ind *)param;
LOGI("GAPC_CON_RSSI_IND conidx=0x%x,rssi = %d\r\n", conidx,
p_param->rssi);
} break;
case GAPC_LE_PHY_IND: {
struct gapc_le_phy_ind *p_param = (struct gapc_le_phy_ind *)param;
LOGI("GAPC_LE_PHY_IND conidx=0x%x tx phy:%d rx phy:%d \r\n", conidx,
p_param->tx_phy, p_param->rx_phy);
} break;
case GAPC_BOND_REQ_IND:
// gapc_bond_req_ind_handler(msgid, p_param, dest_id,src_id)
break;
case GAPC_BOND_IND:
// gapc_bond_ind_handler(msgid, p_param, dest_id,src_id)
break;
case GAPC_SECURITY_IND:
// gapc_security_ind_handler(msgid, p_param, dest_id,src_id)
break;
case GAPC_ENCRYPT_REQ_IND:
// gapc_encrypt_req_ind_handler(msgid, p_param, dest_id,src_id)
break;
case GAPC_ENCRYPT_IND:
// gapc_encrypt_ind_handler(msgid, p_param, dest_id,src_id)
break;
default:
break;
}
return (KE_MSG_CONSUMED);
}
/* Default State handlers definition. */
KE_MSG_HANDLER_TAB(app){
{KE_MSG_DEFAULT_HANDLER, (ke_msg_func_t)app_msg_handler},
};
/* Defines the place holder for the states of all the task instances. */
ke_state_t app_state[APP_IDX_MAX];
// Application task descriptor
const struct ke_task_desc TASK_DESC_APP = {app_msg_handler_tab, app_state,
APP_IDX_MAX,
ARRAY_LEN(app_msg_handler_tab)};
#endif // (BLE_APP_PRESENT)
/// @} APPTASK
@@ -0,0 +1,863 @@
/**
****************************************************************************************
*
* @file arch_main.c
*
* @brief Main loop of the application.
*
* Copyright (C) RivieraWaves 2009-2015
*
*
****************************************************************************************
*/
/*
* INCLUDES
****************************************************************************************
*/
#include "rwip_config.h" // RW SW configuration
#include "xc_drv_pwr.h"
#if (USE_ROM_FLASH)
#include "xc6xxx_fmc_spi.h"
#endif // (USE_ROM_FLASH)
#include "app_task.h"
#include "rom_port.h"
#include "xc_drv_bor.h"
#if (BLE_TEST_MODE_SUPPORT)
#include "uart.h" // UART initialization
#endif // (BLE_TEST_MODE_SUPPORT)
#if (BLE_EMB_PRESENT || BT_EMB_PRESENT)
#include "rf.h" // RF initialization
#endif // BLE_EMB_PRESENT || BT_EMB_PRESENT
#if (PLF_NVDS)
#include "nvds.h" // NVDS definitions
#endif // PLF_NVDS
#include "core_cm0.h"
#include "xc6xxx.h"
#include "xc6xxx_fmc_spi.h"
#include "xc_drv_fmc_spi.h"
#include "sleep.h"
#include "xc_ring_buffer.h"
#include "useruart.h"
/**
****************************************************************************************
* @addtogroup DRIVERS
* @{
*
*
* ****************************************************************************************
*/
/*
* DEFINES
****************************************************************************************
*/
/// NVDS location in FLASH : 0x000E0000 (896KB (1Mo - 128KB))
#define NVDS_FLASH_ADDRESS (0x0003F800) //((256-2)*1024)
#define BLE_SEND_DATA_SIZE 517
/*
* GLOBAL VARIABLE DEFINITIONS
****************************************************************************************
*/
/*
* MAIN FUNCTION
****************************************************************************************
*/
/**
****************************************************************************************
* @brief RW main function.
*
* This function is called right after the booting process has completed.
*
* @return status exit status
****************************************************************************************
*/
#define clrbit(x, y) ((x) &= ~(1 << (y)))
#define AHB_CTL clrbit(*(uint32_t volatile *)(0x40000000 + 0x130), 0)
#define _TOSTRING(s) #s
#define TOSTRING(s) _TOSTRING(s)
static unsigned char send_length_buff[BLE_SEND_DATA_SIZE] = {0};
static unsigned int read_number = 0;
static xc_ring_buffer_t ble_send_ring_buffer;
static uint8_t ble_send_data[BLE_SEND_DATA_SIZE] = {0x00};
unsigned int read_length = 0;
unsigned int send_length = 0;
static unsigned int last_system_time = 0;
static unsigned int current_system_time = 0;
unsigned int data_count = 0;
uint32_t ticks;
uint32_t told, tnow, tcnt = 0;
extern int BT_BLE_Send(uint8_t *TxBuff, uint16_t TxLen);
extern void clock_init(void);
#if !FAST_OTA
extern uint8_t ota_flag;
#endif
static void uart_process_send_ble_init(void)
{
xc_ring_buffer_init(&ble_send_ring_buffer, ble_send_data, BLE_SEND_DATA_SIZE);
}
static unsigned int uart_process_send_ble(unsigned int length, unsigned char *buff)
{
unsigned int send_length = 0;
if (xc_ring_buffer_bytes_free(&ble_send_ring_buffer) >= length)
{
xc_ring_buffer_write(&ble_send_ring_buffer, buff, length);
send_length = length;
}
else
{
send_length = 0;
}
return send_length;
}
void uart_process_send_ble_loop(void)
{
unsigned int length = 517;
unsigned int need_read_number = 0;
need_read_number = xc_ring_buffer_bytes_available(&ble_send_ring_buffer);
if (need_read_number)
{
need_read_number = need_read_number < length ? need_read_number : length;
xc_ring_buffer_read(&ble_send_ring_buffer, send_length_buff, need_read_number, &read_number);
BT_BLE_Send(send_length_buff, read_number);
}
}
static unsigned char uart_process_send_data(unsigned int length)
{
if (length == 0 || xc_ring_buffer_bytes_free(&ble_send_ring_buffer) < length)
{
return 0;
}
read_length = length;
send_length = hal_console_read(read_length, send_length_buff);
uart_process_send_ble(send_length, send_length_buff);
return 1;
}
unsigned int update_data_count_get(void)
{
return data_count;
}
void uart_process()
{
unsigned int uart_get_rx_length = 0;
current_system_time = update_data_count_get();
if (current_system_time - last_system_time > 30)
{
uart_get_rx_length = hal_console_get_rx_data_length();
if (uart_get_rx_length > 0 && uart_get_rx_length < 517)
{
uart_process_send_data(uart_get_rx_length);
}
else
{
uart_process_send_data(517);
}
last_system_time = current_system_time;
}
}
void update_data_count(void)
{
data_count++;
}
void print_count(void)
{
current_system_time = update_data_count_get();
}
void update_time_ms(void)
{
uint32_t reload = SysTick->LOAD;
tnow = SysTick->VAL;
if (tnow != told)
{
if (tnow < told)
tcnt += told - tnow;
else
tcnt += reload - tnow + told;
told = tnow;
if (tcnt >= ticks)
{
ticks = (xc_clock_hfclk_in_get() / 1000000) * 1000;
told = SysTick->VAL;
tcnt = 0;
update_data_count();
}
}
}
void update_time_ms_init(void)
{
ticks = (xc_clock_hfclk_in_get() / 1000000) * 1000000;
told = SysTick->VAL;
}
void flash_init()
{
uint32_t mid = 0;
uint32_t flash_size;
uint16_t flash_type;
xc_fmc_spi_init_oprt();
xc_fmc_spi_flash_wake_up();
xc_fmc_spi_flash_rdid((uint8_t *)&mid);
LOGI("Flash RDID: 0x%08x\n", mid);
uint8_t ruid[16];
xc_fmc_spi_flash_ruid(ruid);
LOGI("Flash RUID11: ");
for (int i = 0; i < 16; i++)
{
LOGI("%02x ", ruid[i]);
}
LOGI("\n");
#if (PLF_NVDS)
if (false == flash_size_and_type_get(&flash_size, &flash_type))
{
LOGI("Flash Memory size Get ERROR ! ");
while (1)
;
}
nvds_space_init(flash_size);
#endif
// if chip unique get failed,then use flash RUID
if (false == xc_unique_identification_read(co_default_bdaddr.addr))
{
// int iter = 0;
LOGI("The chip does not have unique , then use flash RUID\n");
memset(co_default_bdaddr.addr, 0, 6);
for (int i = 0; i < 16; i++)
{
co_default_bdaddr.addr[i % 6] += ruid[i];
}
}
LOGI("mac addr: %02x %02x %02x %02x %02x %02x\n", co_default_bdaddr.addr[0],
co_default_bdaddr.addr[1], co_default_bdaddr.addr[2],
co_default_bdaddr.addr[3], co_default_bdaddr.addr[4],
co_default_bdaddr.addr[5]);
}
void app_uart_init(void)
{
GPIO_InitCfg_t gpio_cfg = {0};
gpio_cfg.Mux = GPIO_Mux0;
gpio_cfg.Pull = GPIO_PULLUP;
gpio_cfg.Int = NOT_INT;
gpio_cfg.FunSel = UART0_TX;
gpio_cfg.Pin = GPIO_18;
gpio_cfg.Dir = GPIO_DIR_OUTPUT;
xc_gpio_init(&gpio_cfg);
gpio_cfg.FunSel = UART0_RX;
gpio_cfg.Pin = GPIO_19;
gpio_cfg.Dir = GPIO_DIR_INPUT;
xc_gpio_init(&gpio_cfg);
UART_InitCfg_t uart_cfg = {0};
uart_cfg.Parity = UART_PARITY_DISABLE;
uart_cfg.StopBits = UART_STOP_1_BITS;
uart_cfg.WordLength = UART_DATA_8_BITS;
uart_cfg.BaudRate = UART_BAUDRATE_115200;
uart_cfg.HardwareFlowControl = UART_HWFC_DISABLE;
xc_uart_init(UART0_IDX, &uart_cfg);
}
void wdt_init(void)
{
#if XTAL_32K
WDT_InitCfg_t wdt_cfg;
wdt_cfg.WorkMode = WDT_WORK_MODE1;
wdt_cfg.ReloadValue = WDT_CLK_32M_RESET_MODE1_2097152US;
wdt_cfg.PclkSel = WDT_WORK_32M;
xc_ext32k_wdt_init(&wdt_cfg);
xc_ext32k_wdt_start();
NVIC_EnableIRQ(WDT_IRQn);
#else
WDT_InitCfg_t wdt_cfg;
wdt_cfg.WorkMode = WDT_WORK_MODE0;
wdt_cfg.ReloadValue = WDT_CLK_32K_RESET_MODE0_2048MS;
wdt_cfg.PclkSel = WDT_WORK_32K;
xc_wdt_init(&wdt_cfg);
xc_wdt_start();
#endif
}
struct ADV_INFO adv_info;
void set_single_addr_name(uint8_t conidx, uint8_t reason)
{
uint32_t flash_type=0;
uint32_t flash_size=0;
uint8_t spi_idx=0;
int32_t mid = 0;
xc_fmc_spi_flash_rdid((uint8_t *)&mid);
flash_type = (mid & 0xffff);
flash_size = (mid >> 16) & 0xff;
flash_type = (mid & 0xffff);
uint32_t write_addr=0;
switch(flash_size)
{
case FLASH_128K_FLAG:
write_addr = (1024 * 128)-256;
if(flash_type==PURAN_128K_FLASH)
{
write_addr = (1024 * 124)-256;
}
break;
case FLASH_256K_FLAG:
write_addr = (1024 * 256)-256;
break;
case FLASH_512K_FLAG:
write_addr = (1024 * 512)-256;
break;
case FLASH_1M_FLAG:
write_addr = (1024 * 1024)-256;
break;
case FLASH_2M_FLAG:
write_addr = (1024 * 2048)-256;
break;
}
uint8_t para_buf[256];
memset(&para_buf,0xFF,256);
memcpy(&adv_info.addr,&co_default_bdaddr.addr,6);
memcpy(&para_buf,&adv_info,28);
xc_fmc_spi_flash_erase_page(write_addr);
xc_fmc_spi_flash_write_page(write_addr, para_buf,FLASH_PAGE_SIZE);
}
/* Zero the host global variable. */
void rom_env_host_init()
{
uint32_t *ptr = (uint32_t *)(0x10000800);
memset(ptr, 0, 0x10001300 - 0x10000800);
rom_env.prf_cleanup = set_single_addr_name;
rom_env.stack_printf = printf;
}
/* Add a protection field to determine if the stack is overflowing. */
void stack_tag()
{
uint32_t StackPos;
__IO uint32_t *pStack;
StackPos = __get_MSP();
printf("StackPos=0x%x\n", StackPos);
// 0x800 is the size of the stack, which should be changed according to the
// configuration of the project.
pStack = (uint32_t *)(StackPos - 0x800);
*pStack = 0xa5a5a5a5;
}
void board_init()
{
clock_init();
app_uart_init();
#if (POWER_ON)
power_on_check();
#endif // (POWER_ON)
printf("sdk version: %s build time: %s %s\n", TOSTRING(SDK_VERSION), __DATE__,
__TIME__);
// stack_tag();
rom_env_host_init();
#if (SLEEP_ENABLE)
#if XTAL_32K
#else
// xc_rc32k_calib_by_hw();
xc_rc32k_calib_by_soft();
#endif // (XTAL_32K)
#endif // (SLEEP_ENABLE)
rom_env_init();
AHB_CTL;
/*
************************************************************************************
* Platform initialization
************************************************************************************
*/
// // Initialize random process
// srand(1);
}
void bluetooth_init()
{
uint32_t error = RESET_NO_ERROR;
#if (PLF_NVDS)
flash_init();
// Initialize NVDS module
nvds_init(NVDS_FLASH_SIZE);
#endif // PLF_NVDS
/*
************************************************************************************
* RW SW stack initialization
************************************************************************************
*/
NVIC_SetPriority((IRQn_Type)BLE_IRQn, 0);
NVIC_EnableIRQ((IRQn_Type)BLE_IRQn);
#if defined(CFG_RSSI_ENABLE)
// Initialize modem
modem_init(1);
#else
modem_init(0);
#endif // defined(CFG_RSSI_ENABLE)
// Measure the single carrier and configure the correct frequency offset.
// rf_xtal_cal_set(uint8_t set_value);
rf_tx_power_set(TRANS_POWER_0_5DBM);
// Initialize RF
#if (BT_EMB_PRESENT || BLE_EMB_PRESENT)
rf_init(&rwip_rf);
#endif // BT_EMB_PRESENT || BLE_EMB_PRESENT
// Initialize RW SW stack
rwip_init(error);
uint32_t seed;
rwip_time_t current_time = rwip_time_get();
seed = current_time.hs;
seed += current_time.hus;
// Init the random seed
co_random_init(seed);
#if (BLE_TEST_MODE_SUPPORT)
enter_test_mode();
#else // (BLE_TEST_MODE_SUPPORT)
// Initialize APP
app_init();
#endif // (BLE_TEST_MODE_SUPPORT)
// finally start interrupt handling
GLOBAL_INT_START();
}
extern uint8_t adv_evt_start; // adv event
extern uint8_t evt_start; // conn event
extern volatile uint8_t sv_lock;
extern volatile uint8_t sv_txlen;
#if defined(USE_64M_CRYSTAL)
#include "reg_ipcore.h"
#define EVT_TX_EN (0x1)
#define EVT_RX_EN (0x2)
uint32_t fra_base = 0x4b1; // 0x4b1
uint32_t fra_rx_base = 0x4b0; // 0x4b1
uint32_t cur_channel;
__RAM_CODE void tx_channel(void)
{
uint32_t new_val = fra_base;
*((uint32_t volatile *)0x53022050) = new_val;
*((uint32_t volatile *)0x53022064) = *((uint32_t volatile *)0x53022064) & (~(1 << 31));
}
__RAM_CODE void rx_channel(uint8_t channel)
{
uint8_t ch_sel_ofst = 0;
// ҪƫƣӲԶ
switch (channel)
{
case 37:
ch_sel_ofst = 0;
break;
case 38:
ch_sel_ofst = 12;
break;
case 39:
ch_sel_ofst = 39;
break;
default:
{
if (channel <= 10)
{
ch_sel_ofst = channel + 1;
}
else
{
ch_sel_ofst = channel + 2;
}
break;
}
}
uint32_t new_val = fra_rx_base + ch_sel_ofst;
*((uint32_t volatile *)0x53022064) = ((new_val << 16) | 0x80008000);
}
__RAM_CODE void PendSV_Handler(void)
{
ip_diagcntl_pack(0, 0, 1, 0x38, 1, 0x3, 1, 0x20);
if (adv_evt_start)
{ // adv event
#if (ADV_EVENT_NOT_RUN_XIP == 1)
#if defined(USE_64M_CRYSTAL)
tx_channel();
while (!sv_lock)
{
uint8_t val1 = ip_diagstat_diag1stat_getf();
// tx
if ((val1 & 0x01))
{
*((uint32_t volatile *)0x53022064) = *((uint32_t volatile *)0x53022064) & (~(1 << 31));
while (val1 & 0x01)
{
val1 = ip_diagstat_diag1stat_getf();
}
uint8_t val2 = ip_diagstat_diag2stat_getf() & 0x3f;
rx_channel(val2);
}
// rx
if ((val1 & 0x02))
{
uint8_t val2 = ip_diagstat_diag2stat_getf() & 0x3f;
rx_channel(val2);
}
}
#else
while (!sv_lock)
;
#endif
#endif // (ADV_EVENT_NOT_RUN_XIP ==1)
}
else if (evt_start)
{ // conn event
#if defined(USE_64M_CRYSTAL)
uint8_t val1 = 0;
uint8_t val2 = ip_diagstat_diag2stat_getf() & 0x3f;
rx_channel(val2);
*((uint32_t volatile *)0x40000178) = 11;
GLOBAL_INT_DISABLE();
while (1)
{
cur_channel = (ip_diagstat_diag2stat_getf() & 0x3f);
if (val2 != cur_channel)
{
rx_channel(cur_channel);
break;
}
uint8_t val1 = ip_diagstat_diag1stat_getf();
if ((val1 & 0x02))
{
break;
}
}
GLOBAL_INT_RESTORE();
// rx_en tx_en ½л
// while (!sv_lock)
// {
// uint8_t tx_rx_en = 0;
// GLOBAL_INT_DISABLE();
// tx_rx_en = ip_diagstat_diag1stat_getf();
// GLOBAL_INT_RESTORE();
// if (tx_rx_en & EVT_RX_EN)
// {
// while (tx_rx_en & EVT_RX_EN)
// {
// GLOBAL_INT_DISABLE();
// tx_rx_en = ip_diagstat_diag1stat_getf();
// GLOBAL_INT_RESTORE();
// }
// GLOBAL_INT_DISABLE();
// // xc_gpio_write_pin(4, 1);
// *((uint32_t volatile *)0x53022064) = *((uint32_t volatile *)0x53022064) & (~(1 << 31));
// // xc_gpio_write_pin(4, 0);
// GLOBAL_INT_RESTORE();
// // tx delay
// // NVIC_SetPriority((IRQn_Type)PendSV_IRQn, 0x1);
// // tx delay޸
// }
// if (tx_rx_en & EVT_TX_EN)
// {
// while (tx_rx_en & EVT_TX_EN)
// {
// tx_rx_en = ip_diagstat_diag1stat_getf();
// }
// for (int i = 0; i < 10; i++)
// ; // must delay
// rx_channel(cur_channel);
// }
// }
#else
while (!sv_lock)
;
#endif
}
}
__RAM_CODE void tx_rx_freq()
{
uint8_t tx_rx_en = 0;
tx_rx_en = ip_diagstat_diag1stat_getf();
if (tx_rx_en & EVT_RX_EN)
{
*((uint32_t volatile *)0x40000178) = 10;
}
if (tx_rx_en & EVT_TX_EN)
{
*((uint32_t volatile *)0x40000178) = 11;
}
if (evt_start)
{
#if 1
if (tx_rx_en & EVT_RX_EN)
{
// xc_gpio_write_pin(8,1);
while (tx_rx_en & EVT_RX_EN)
{
GLOBAL_INT_DISABLE();
tx_rx_en = ip_diagstat_diag1stat_getf();
GLOBAL_INT_RESTORE();
}
GLOBAL_INT_DISABLE();
*((uint32_t volatile *)0x53022064) = *((uint32_t volatile *)0x53022064) & (~(1 << 31));
GLOBAL_INT_RESTORE();
}
if (tx_rx_en & EVT_TX_EN)
{
// xc_gpio_write_pin(9,1);
while (tx_rx_en & EVT_TX_EN)
{
tx_rx_en = ip_diagstat_diag1stat_getf();
}
for (volatile i = 0; i < 10; i++)
; // must delay
rx_channel(cur_channel);
}
#endif
#if 0
if (tx_rx_en & EVT_TX_EN)
{
*((uint32_t volatile *)0x53022064) = *((uint32_t volatile *)0x53022064) & (~(1 << 31));
while (tx_rx_en & EVT_TX_EN)
{
tx_rx_en = ip_diagstat_diag1stat_getf();
}
for (int i = 0; i < 10; i++)
; // must delay
rx_channel(cur_channel);
}
#endif
}
}
#define __write_hw_reg32(reg, val) ((*reg) = (val))
#define __read_hw_reg32(reg, val) ((val) = (*reg))
#define CPR_CTLAPBCLKEN_GRCTL ((volatile unsigned *)(0x40000000 + 0x070))
#define CPR_AOCLKEN_GRCTL ((volatile unsigned *)(0x40002400 + 0x7C))
#define AO_GPIO_MODE ((volatile unsigned *)(0x40002000 + 0x0044))
#define AO_GPIO_CTL ((volatile unsigned *)(0x40002000 + 0x0048))
void Init_rtc_gpio(uint32_t num, uint8_t inter_mode)
{
uint32_t val;
// if(!((inter_mode>=0x08) &&(inter_mode<=0x0c))) return;
__write_hw_reg32(CPR_CTLAPBCLKEN_GRCTL, 0x20002);
__write_hw_reg32(CPR_AOCLKEN_GRCTL, 0x20002);
__read_hw_reg32(AO_GPIO_MODE, val);
val &= ~(0x0f << (num << 2));
val |= (inter_mode << (num << 2));
__write_hw_reg32(AO_GPIO_MODE, val);
__read_hw_reg32(AO_GPIO_CTL, val);
val |= (1 << (8 + num));
__write_hw_reg32(AO_GPIO_CTL, val);
// rtc_ao_gpio_mode__aogpio_debounce_en3__setf(1);
NVIC_SetPriority(RTC_IRQn, 0x0);
NVIC_EnableIRQ(RTC_IRQn);
}
#else
#if ((ADV_EVENT_NOT_RUN_XIP == 1) || (CONN_EVENT_NOT_RUN_XIP == 0) || (CONN_EVENT_NOT_RUN_XIP == 1))
__RAM_CODE void PendSV_Handler(void)
{
if (adv_evt_start)
{ // adv event
#if (ADV_EVENT_NOT_RUN_XIP == 1)
while (!sv_lock)
;
#endif // (ADV_EVENT_NOT_RUN_XIP ==1)
}
else if (evt_start)
{ // conn event
#if (CONN_EVENT_NOT_RUN_XIP == 0)
uint32_t nus = sv_txlen * 8 + 148;
uint32_t unit = 32;
uint32_t temp;
SysTick->CTRL = 0x00;
SysTick->LOAD = unit * nus - unit + 1;
SysTick->VAL = 0;
SysTick->CTRL = 0x05;
do
{
temp = SysTick->CTRL;
if (sv_lock)
{
break;
}
} while ((temp & 0x01) && (!(temp & (1 << 16))));
#endif // (CONN_EVENT_NOT_RUN_XIP == 0)
#if (CONN_EVENT_NOT_RUN_XIP == 1)
while (!sv_lock)
;
#endif // (CONN_EVENT_NOT_RUN_XIP == 1)
}
}
#endif // ((ADV_EVENT_NOT_RUN_XIP ==1) || (CONN_EVENT_NOT_RUN_XIP == 0) || (CONN_EVENT_NOT_RUN_XIP == 1))
#endif // defined(USE_64M_CRYSTAL)
#if (CONFIG_BT_WAKEUP_VIA_GPIO)
void gpio_intr_callback(uint64_t intr_sta)
{
uint32_t value = ((*(volatile uint32_t *)(0x53022044)));
value |= 1 << 14;
((*(volatile uint32_t *)(0x53022044))) = value;
}
#endif
#if (CONN_EVENT_NOT_RUN_XIP == 3)
#define __write_hw_reg32(reg, val) ((*reg) = (val))
#define __read_hw_reg32(reg, val) ((val) = (*reg))
#define CPR_CTLAPBCLKEN_GRCTL ((volatile unsigned *)(0x40000000 + 0x070))
#define CPR_AOCLKEN_GRCTL ((volatile unsigned *)(0x40002400 + 0x7C))
#define AO_GPIO_MODE ((volatile unsigned *)(0x40002000 + 0x0044))
#define AO_GPIO_CTL ((volatile unsigned *)(0x40002000 + 0x0048))
void Init_rtc_gpio(uint32_t num, uint8_t inter_mode)
{
uint32_t val;
// if(!((inter_mode>=0x08) &&(inter_mode<=0x0c))) return;
__write_hw_reg32(CPR_CTLAPBCLKEN_GRCTL, 0x20002);
__write_hw_reg32(CPR_AOCLKEN_GRCTL, 0x20002);
__read_hw_reg32(AO_GPIO_MODE, val);
val &= ~(0x0f << (num << 2));
val |= (inter_mode << (num << 2));
__write_hw_reg32(AO_GPIO_MODE, val);
__read_hw_reg32(AO_GPIO_CTL, val);
val |= (1 << (8 + num));
__write_hw_reg32(AO_GPIO_CTL, val);
// rtc_ao_gpio_mode__aogpio_debounce_en3__setf(1);
NVIC_SetPriority(RTC_IRQn, 0x0);
NVIC_EnableIRQ(RTC_IRQn);
}
#include "reg_ipcore.h"
#define EVT_TX_EN (0x1)
#define EVT_RX_EN (0x2)
__RAM_CODE void tx_on_delay()
{
uint8_t tx_rx_en = 0;
tx_rx_en = ip_diagstat_diag0stat_getf();
if (tx_rx_en & EVT_TX_EN)
{
while (tx_rx_en & EVT_TX_EN)
{
tx_rx_en = ip_diagstat_diag0stat_getf();
};
}
}
#endif // (CONN_EVENT_NOT_RUN_XIP == 3)
void ble_tx_rx_on_irq_config()
{
#if (defined(USE_64M_CRYSTAL) || defined(NOT_RUN_XIP_TX_ONLY))
writel(0x53022040, 0);
// xc_gpio_fun_sel(3,0);
// xc_gpio_mux_ctl(3,3); // en test_pin[0]
// *((uint32_t volatile*)0x40000170) = 0;
xc_gpio_fun_sel(GPIO_2, 0);
xc_gpio_mux_ctl(GPIO_2, 1); // en test_pin[1]
*((uint32_t volatile *)0x40000178) = 10;
#if defined(NOT_RUN_XIP_TX_ONLY)
*((uint32_t volatile *)0x40000178) = 0;
#endif // defined(NOT_RUN_XIP_TX_ONLY)
xc_pwr_pwrkey_init();
Init_rtc_gpio(GPIO_2, 0x00);
#endif // (defined(USE_64M_CRYSTAL) || defined(NOT_RUN_XIP_TX_ONLY))
}
int main(void)
{
wdt_init();
/* Set the broadcast address of the device. */
board_init();
bluetooth_init();
//lvr bor_intr
Bor_InitCfg_t bor_cfg = {
.mode = BOR_MODE_INTRST,
.rst_volt = BOR_RST_VOLT_1_76V,
};
xc_bor_init(&bor_cfg);
#if ((ADV_EVENT_NOT_RUN_XIP == 1) || (CONN_EVENT_NOT_RUN_XIP == 0) || (CONN_EVENT_NOT_RUN_XIP == 1) || defined(USE_64M_CRYSTAL))
NVIC_SetPriority(PendSV_IRQn, 0xff);
NVIC_EnableIRQ(PendSV_IRQn);
#endif // ((ADV_EVENT_NOT_RUN_XIP ==1) || (CONN_EVENT_NOT_RUN_XIP == 0) || (CONN_EVENT_NOT_RUN_XIP == 1) || defined(USE_64M_CRYSTAL))
#if (CONFIG_BT_WAKEUP_VIA_GPIO)
uint32_t value = ((*(volatile uint32_t *)(0x53022044)));
value |= 1 << 12;
((*(volatile uint32_t *)(0x53022044))) = value;
#endif // (CONFIG_BT_WAKEUP_VIA_GPIO)
printf("ble_peripheral_uart start\n");
ble_tx_rx_on_irq_config();
update_time_ms_init();
hal_console_init(UART_BAUD_SET);
uart_process_send_ble_init();
xc_system_param_check();
#if (BLE_APP_PRESENT)
while (1)
{
// schedule all pending events
rwip_schedule();
update_time_ms();
uart_process();
uart_process_send_ble_loop();
print_count();
#if OTA_AES_USED
process_aes_decrypt();
#endif
xc_wdt_reload();
}
#endif // (BLE_APP_PRESENT)
}
/// @} DRIVERS
@@ -0,0 +1,296 @@
#<SYMDEFS># ARM Linker, 5060750: Last Updated: Tue Sep 05 15:30:26 2023
0x10000808 D co_default_bdaddr
0x00004169 T ke_msg_alloc
0x000041ed T ke_msg_send
0x00004225 T ke_msg_send_basic
0x000042e9 T ke_state_set
0x00004359 T ke_task_create
0x000042b9 T ke_state_get
0x000041af T ke_msg_discard
0x000041b3 T ke_msg_forward
0x000041dd T ke_msg_in_queue
0x00004233 T ke_msg_src_id_get
0x00003e05 T ke_free
0x000041d5 T ke_msg_free
0x00003c21 T ke_check_malloc
0x0000dbf5 T rwip_init
0x0000de79 T rwip_schedule
0x10000938 D rwip_rf
0x00000df9 T BLE_Handler
0x0000238d T co_buf_alloc
0x000024fd T co_buf_copy_data_from_mem
0x00002721 T co_buf_release
0x000028c9 T co_djob_prepare
0x000028d5 T co_djob_reg
0x0000291d T co_djob_unreg
0x00002969 T co_list_extract
0x000029ad T co_list_extract_after
0x00002ac5 T co_list_pop_front
0x00002ae9 T co_list_push_back
0x00002b39 T co_list_push_front
0x00002b55 T co_time_get
0x00002ce5 T co_time_timer_init
0x00002dcd T co_time_timer_set
0x00002df9 T co_time_timer_stop
0x00000e95 T aes_c1
0x00001465 T aes_encrypt
0x000014cd T aes_f4
0x00001521 T aes_f5
0x00001641 T aes_f6
0x000016bd T aes_g2
0x00001c35 T aes_rand
0x000012a1 T aes_cmac
0x000025b1 T co_buf_head_release
0x000025dd T co_buf_head_reserve
0x00002ec5 T co_util_pack
0x000030d5 T co_util_unpack
0x0000ddd9 T rwip_reset
0x00001da5 T aes_rpa_resolve
0x00002799 T co_buf_reuse
0x000027dd T co_buf_size
0x00002489 T co_buf_copy
0x00002569 T co_buf_duplicate
0x000027ed T co_buf_tail_release
0x00002a0d T co_list_init
0x00002285 T ble_util_buf_rx_free
0x00001f69 T ble_util_buf_acl_tx_alloc
0x00002439 T co_buf_cb_free_set
0x00003fad T ke_malloc
0x00002a25 T co_list_insert_after
0x0000459d T ke_timer_active
0x000045ad T ke_timer_clear
0x00004641 T ke_timer_set
0x00002369 T co_buf_acquire
0x00002819 T co_buf_tail_reserve
0x00002531 T co_buf_copy_data_to_mem
0x00002a55 T co_list_insert_before
0x10000e90 D rom_env
0x1000096c D rwip_param
0x0000fe8d D one_bits
0x000039bd T hci_rd_rem_ver_info_cmd_handler
0x00003445 T hci_le_con_upd_cmd_handler
0x00003705 T hci_le_rd_chnl_map_cmd_handler
0x00003761 T hci_le_rd_rem_feats_cmd_handler
0x0000354d T hci_le_en_enc_cmd_handler
0x0000369d T hci_le_ltk_req_reply_cmd_handler
0x0000360d T hci_le_ltk_req_neg_reply_cmd_handler
0x00003851 T hci_le_rem_con_param_req_reply_cmd_handler
0x000037f9 T hci_le_rem_con_param_req_neg_reply_cmd_handler
0x000038d9 T hci_le_set_data_len_cmd_handler
0x00003be5 T hci_vs_set_pref_slave_latency_cmd_handler
0x00003b9d T hci_vs_set_pref_slave_evt_dur_cmd_handler
0x00003ab9 T hci_vs_set_max_rx_size_and_time_cmd_handler
0x00003a39 T hci_rd_rssi_cmd_handler
0x0000d749 T llm_ch_map_update_ind_handler
0x0000650d T llc_loc_llcp_rsp_to_handler
0x00007161 T llc_rem_llcp_rsp_to_handler
0x00005255 T llc_encrypt_ind_handler
0x00006739 T llc_op_ver_exch_ind_handler
0x000066d5 T llc_op_feats_exch_ind_handler
0x00006675 T llc_op_encrypt_ind_handler
0x00006609 T llc_op_dl_upd_ind_handler
0x0000657d T llc_op_con_upd_ind_handler
0x00006525 T llc_op_ch_map_upd_ind_handler
0x0000bda9 T lld_llcp_rx_ind_handler
0x0000bf1d T lld_llcp_tx_cfm_handler
0x00007551 T lld_acl_rx_ind_handler
0x000075dd T lld_acl_tx_cfm_handler
0x00009509 T lld_con_param_upd_cfm_handler
0x00008921 T lld_ch_map_upd_cfm_handler
0x000094cd T lld_con_offset_upd_ind_handler
0x00003435 T hci_command_llc_handler
0x00003385 T hci_acl_data_handler
0x00003cc1 T ke_event_callback_set
0x00003cd9 T ke_event_clear
0x00003db1 T ke_event_set
0x000022e5 T ble_util_nb_good_channels
0x0000230d T ble_util_pkt_dur_in_us
0x0000234d T co_bdaddr_compare
0x000088bd T lld_ch_assess_data_get
0x000088c5 T lld_ch_map_set
0x0000c16d T lld_read_clock
0x0000c30d T lld_res_list_peer_update
0x0000d60d T lld_white_list_add
0x0000dd99 T rwip_prevent_sleep_clear
0x0000ddb9 T rwip_prevent_sleep_set
0x0000f071 T sch_plan_rem
0x00001ce5 T aes_rpa_gen
0x00002029 T ble_util_buf_adv_tx_alloc
0x00002061 T ble_util_buf_adv_tx_free
0x0000feae D co_null_bdaddr
0x0000feb4 D co_null_key
0x000050c9 T llc_con_move_cbk
0x000071d9 T llc_start
0x00007669 T lld_adv_adv_data_update
0x00007ff5 T lld_adv_rand_addr_update
0x00008071 T lld_adv_restart
0x0000817d T lld_adv_scan_rsp_data_update
0x000081c5 T lld_adv_start
0x00008831 T lld_adv_stop
0x0000d6c1 T lld_white_list_rem
0x0000b401 T lld_init_rand_addr_update
0x0000c179 T lld_res_list_add
0x0000c251 T lld_res_list_clear
0x0000c27d T lld_res_list_local_rpa_get
0x0000c2c5 T lld_res_list_peer_rpa_get
0x0000c341 T lld_res_list_priv_mode_update
0x0000c37d T lld_res_list_rem
0x0000cedd T lld_scan_rand_addr_update
0x0000b699 T lld_init_start
0x0000bc9d T lld_init_stop
0x0000f081 T sch_plan_req
0x0000f0d5 T sch_plan_set
0x0000fec4 D co_rate_to_phy
0x0000cb81 T lld_scan_params_update
0x0000d115 T lld_scan_start
0x0000d5c5 T lld_scan_stop
0x0000c3ad T lld_rpa_renew
0x0000408d T ke_mem_init
0x00002609 T co_buf_init
0x0000de9d T rwip_sleep
0x10000810 D em_ble_base_address_table_0
0x10000812 D em_ble_base_address_table_1
0x10000814 D em_ble_base_address_table_2
0x10000816 D em_ble_base_address_table_3
0x10000818 D em_ble_base_address_table_4
0x1000081a D em_ble_base_address_table_5
0x10000822 D em_ble_base_address_table_6
0x1000081c D em_ble_base_address_table_7
0x10000824 D em_ble_base_address_table_8
0x1000081e D em_ble_base_address_table_9
0x10000820 D em_ble_base_address_table_10
0x000021d9 T ble_util_buf_init_env
0x10000978 D PATCH_FUN
0x1000108c D lld_adv_env
0x0000ebe5 T sch_arb_remove
0x0000f739 T sch_slice_fg_remove
0x10000f44 D llc_env
0x0000693d T llc_proc_err_ind
0x000073c1 T llc_stop
0x00004695 T ll_channel_map_ind_handler
0x0000471d T ll_connection_param_req_handler
0x00004809 T ll_connection_param_rsp_handler
0x0000489d T ll_connection_update_ind_handler
0x000049c1 T ll_enc_req_handler
0x00004a85 T ll_enc_rsp_handler
0x00004af9 T ll_feature_req_handler
0x00004b4d T ll_feature_rsp_handler
0x00004ba1 T ll_length_req_handler
0x00004bf9 T ll_length_rsp_handler
0x00004c75 T ll_min_used_channels_ind_handler
0x00004cf1 T ll_pause_enc_req_handler
0x00004d5d T ll_pause_enc_rsp_handler
0x00004db5 T ll_reject_ext_ind_handler
0x00004dd5 T ll_reject_ind_handler
0x00004df5 T ll_slave_feature_req_handler
0x00004e49 T ll_start_enc_req_handler
0x00004e99 T ll_start_enc_rsp_handler
0x00004ee9 T ll_unknown_rsp_handler
0x00004ef9 T ll_version_ind_handler
0x00001fd9 T ble_util_buf_acl_tx_free
0x0000c5c1 T lld_rxdesc_check
0x0000c609 T lld_rxdesc_free
0x0000fee4 D rwip_priority
0x0000e8b1 T sch_arb_insert
0x0000f355 T sch_prog_push
0x0000fde5 T FMC_SPI_Flash_RDID
0x0000fd8d T FMC_SPI_Flash_RUID
0x0000fa71 T FMC_SPI_Flash_WakeUp
0x0000f9f1 T FMC_SPI_Init_Oprt
0x0000fa49 T FMC_SPI_Flash_PowerDown
0x0000fceb T FMC_SPI_FlashRead
0x0000fc1f T FMC_SPI_FlashWrite
0x0000fb09 T FMC_SPI_Flash_Erase_Sector
0x00004fc9 T llc_cleanup
0x00005091 T llc_cmd_stat_send
0x00005a39 T llc_llcp_send
0x00005ac9 T llc_llcp_state_set
0x00006981 T llc_proc_get
0x00006999 T llc_proc_id_get
0x000069b5 T llc_proc_init
0x000069c1 T llc_proc_reg
0x00006a05 T llc_proc_state_get
0x00006a09 T llc_proc_state_set
0x00006a0d T llc_proc_timer_pause_set
0x00006a7d T llc_proc_timer_set
0x00006ae5 T llc_proc_unreg
0x0000a1c1 T lld_con_stop
0x00007869 T lld_adv_evt_start_cbk
0x10000e68 D rwip_env
0x1000080e D rwip_prog_delay
0x0000e041 T rwip_time_get
0x0000e2cd T rwip_wakeup_end
0x1000112c D sch_arb_env
0x00007905 T lld_adv_frm_cbk
0x0000e0b1 T rwip_timer_alarm_handler
0x0000e11d T rwip_timer_arb_handler
0x0000e189 T rwip_timer_co_handler
0x10000f94 D lld_env
0x10000828 D aa_gen
0x00007c25 T lld_adv_init
0x00009301 T lld_con_init
0x0000a7f1 T lld_core_init
0x1000082c D lld_rpa_renew_env
0x00008959 T lld_channel_assess
0x100010dc D lld_con_env
0x0000a4ad T lld_con_tx_len_update
0x10000830 D lld_exp_sync_pos_tab
0x0000bce5 T lld_instant_proc_end
0x1100efad T prf_dst_task_get
0x1100f56d T rom_env_init
0x11004b15 T gapc_get_bdaddr
0x11009521 T gatt_db_svc16_add
0x110096a5 T gatt_db_svc_add
0x11002d53 T _gatt_srv_att_read_get_cfm
0x11002dc7 T _gatt_srv_att_val_set_cfm
0x1100ac11 T gatt_srv_event_send
0x1100afc9 T gatt_user_srv_register
0x110104dc D llc_msg_handler_tab
0x100020f4 D rom_llc_state
0x00008e4d T lld_con_evt_start_cbk
0x00008ddd T lld_con_evt_canceled_cbk
0x0000fe9e D co_sca2ppm
0x00009051 T lld_con_evt_time_update
0x00009415 T lld_con_max_lat_calc
0x00009a69 T lld_con_sched
0x0000f7e1 T sch_slice_per_add
0x0000d801 T rwble_isr
0x0000dc75 T rwip_isr
0x00009189 T lld_con_frm_isr
0x000044f9 T ke_task_schedule
0x00007949 T lld_adv_frm_isr
0x10002115 D sv_lock
0x10002116 D sv_txlen
0x100017d9 T rom_lld_con_rx
0x10001a47 T rom_lld_con_evt_start_cbk
0x10001a9f T rom_lld_con_frm_isr
0x11008f89 T gatt_cli_mtu_exch
0x10002114 D evt_start
0x11004109 T co_rand_word
0x11004111 T co_random_init
0x1000210c D adv_evt_start
0x100020b8 D gatt_srv_read_api_tbl
0x100020cc D gatt_srv_write_api_tbl
0x1100ed59 T modem_init
0x1100f2cd T rf_init
0x1100fb25 T xc_ble_set_dev_info_cfm
0x1100fa75 T xc_ble_get_dev_info_cfm
0x1100f99d T xc_ble_gatt_cli_mtu_exch
0x1100fb4d T xc_ble_update_param
0x1100fa6d T xc_ble_gatt_user_srv_register
0x1100fa5d T xc_ble_gatt_srv_write_cfm
0x1100fa05 T xc_ble_gatt_srv_read_cfm
0x1100f9bb T xc_ble_gatt_srv_notify
0x1100f9a5 T xc_ble_gatt_service16_add
0x1100fa8d T xc_ble_param_update_cfm
0x1100faf9 T xc_ble_set_dev_config
0x1100f981 T xc_ble_gapm_reset
0x1100f955 T xc_ble_conn_cfm
0x1100f929 T xc_ble_advertise_start
0x1100fac1 T xc_ble_set_adv_data
0x1100f901 T xc_ble_advertise_create
0x10001f03 T rom_xc_fmc_spi_flash_erase_page
0x10001fbb T rom_xc_fmc_spi_flash_read_page
0x10001f53 T rom_xc_fmc_spi_flash_write_page
0x1100f535 T rf_xtal_cal_set
0x1100f521 T rf_tx_power_set
@@ -0,0 +1,451 @@
/**
****************************************************************************************
*
* @file arch_main.c
*
* @brief Main loop of the application.
*
* Copyright (C) RivieraWaves 2009-2015
*
*
****************************************************************************************
*/
/*
* INCLUDES
****************************************************************************************
*/
#include "rwip_config.h" // RW SW configuration
#include "arch.h" // architectural platform definitions
#include "boot.h" // boot definition
#include "rwip.h" // RW SW initialization
#include "xc_drv_pwr.h"
#include <stdbool.h> // boolean definition
#include <stddef.h> // standard definitions
#include <stdint.h> // standard integer definition
#include <stdlib.h> // standard lib functions
#if (BLE_TEST_MODE_SUPPORT)
#include "uart.h" // UART initialization
#endif // (BLE_TEST_MODE_SUPPORT)
#if (BLE_EMB_PRESENT || BT_EMB_PRESENT)
#include "rf.h" // RF initialization
#endif // BLE_EMB_PRESENT || BT_EMB_PRESENT
#if (BLE_APP_PRESENT)
// #include "app.h" // application functions
#endif // BLE_APP_PRESENT
#if PLF_DMA
#include "dma.h" // DMA initialization
#endif // PLF_DMA
#if (PLF_NVDS)
#include "nvds.h" // NVDS definitions
#endif // PLF_NVDS
#include "reg_assert_mgr.h"
#if (PLF_PROFILING || PLF_MEM_PROTECTION)
#include "reg_sw_profiling.h"
#endif // (PLF_PROFILING || PLF_MEM_PROTECTION)
#include "platform.h"
#include "sleep.h"
#include "xc6xxx.h"
#include "useruart.h"
// CPU early wake-up time (unit:us)
#define SLEEP_TIME_EARLY (3300)
#define HS_TO_US(frame) (((frame) * SLOT_SIZE) >> 1)
/**
* @brief clock_init
* @details
* @param void
* @retval void
*/
void clock_init(void)
{
CLOCK_InitCfg_t clock_cfg;
clock_cfg.hfclk_src = CLOCK_HFCLK_SRC_XTAL;
clock_cfg.hfclk_in = CLOCK_HFCLK_IN_32M;
#if XTAL_32K
clock_cfg.lfclk_src = CLOCK_LFCLK_SRC_XTAL;
#else
clock_cfg.lfclk_src = CLOCK_LFCLK_SRC_RC;
#endif
// clock_cfg.lfclk_src = CLOCK_LFCLK_SRC_XTAL;
if (clock_cfg.lfclk_src == CLOCK_LFCLK_SRC_XTAL) {
clock_cfg.lfclk_in = CLOCK_LFCLK_IN_32768;
} else if (clock_cfg.lfclk_src == CLOCK_LFCLK_SRC_RC) {
clock_cfg.lfclk_in = CLOCK_LFCLK_IN_32K;
}
xc_clock_init_cfg(&clock_cfg);
SysTick_Config(xc_clock_hfclk_in_get() / 100);
SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk;
}
#if (SLEEP_ENABLE)
void system_sleep_init()
{
uint32_t wake_it_src;
#if (USE_XIP == 1)
#if (USE_ROM_FLASH)
FMC_SPI_Init_Oprt();
#else // (USE_ROM_FLASH)
xc_fmc_spi_init_oprt();
#endif // (USE_ROM_FLASH)
#endif
#if 0
#if (USE_XIP != 1)
SPI_InitCfg_t spi_cfg = {0};
spi_cfg.Mode = SPI_MODE_MASTER;
spi_cfg.DataSize = SSI_CTRL0_DFS_LEN_8BIT;
spi_cfg.Direction = SSI_CTRL0_TMOD_WR;
spi_cfg.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
spi_cfg.CLKPolarity = SSI_CTRL0_SCPOL_LOW;
spi_cfg.CLKPhase = SPI_CPHA_LEAD;
spi_cfg.FirstBit = SPI_FirstBit_MSB;
xc_spi_init(XC_SPI0, &spi_cfg);
SPI_Flash_PowerDown(XC_SPI0);
#endif
#endif
xc_pwr_gpio_sleep_config();
wake_it_src =
GPIO_IRQn_WAKE | RTC_IRQn_WAKE | TIMER_AO0_IRQn_WAKE | TIMER0_IRQn_WAKE | MPU_IRQn_WAKE;
xc_pwr_wake_it_set(wake_it_src);
}
void system_lightsleep_cfg()
{
#if (USE_XIP != 1)
cprao_aon_puctrl1_set(0x4); /* puctrl1= 0x4 , SSI0RX must pulldown*/
#endif
cprao_aon_sys_time_set((RST_READY_TIME << 12) | (OSC32_STABLE_TIME));
xc_pwr_pd_lightsleep_set();
xc_pwr_sleepsrc_mask_set(0x1e001e);
xc_pwr_osc_off();
}
void cpu_switch_16M()
{
// M0_FCLK
cpr_m0_fclk_ctl__m0_fclk_div_p__setf(0x1);
cpr_m0_fclk_ctl__m0_fclk_direct_sw__setf(0x1);
// CTL_PCLK
cpr_ctl_pclk_grctl__ctl_pclk_gr__setf(0x8);
cpr_ctl_pclk_grctl__ctl_pclk_gr_upd__setf(0x1);
cprao_aon_bbldo_adj_set(0x3c);
/* The value needs to be configured to 7,
otherwise the current drop will be slower during sleep
and the clock accuracy of the rc32k will be affected.
*/
cprao_aon_lpoldo_adj_set(0x7);
}
void sleep_init(void)
{
system_sleep_init();
system_lightsleep_cfg();
/* Timer for sleep-wake*/
Timer_InitCfg_t timer_cfg;
timer_cfg.timer_src_clk = TIMER_CLK_SRC_32K;
timer_cfg.timer_div_clk = TIMER_DIV_CLK_32000Hz;
timer_cfg.timer_mode = TIMER_MODE_SINGLE;
xc_timer_init(TIMER0_IDX, &timer_cfg);
}
__RAM_CODE void xc_ble_sleep(void)
{
xc_adc_powerdown();
xc_pwr_usb_off();
xc_pwr_rc16m_off();
xc_pwr_rc32k_calib_off();
xc_pwr_opa_tempsensor_off();
xc_pwr_opa_volr_off();
xc_pwr_revddldo_off();
xc_pwr_dcdc_close();
xc_pwr_rfdigital_off();
xc_pwr_rc32k_calib_off();
cprao_aon_reg4__bb_coreldo_normal_sw_mux__setf(0);
xc_pwr_modem_off();
xc_pwr_pd_lightsleep_set();
#if (USE_XIP == 1)
#if (USE_ROM_FLASH)
FMC_SPI_Flash_PowerDown();
#else // (USE_ROM_FLASH)
// xc_fmc_spi_flash_power_down();
#endif // (USE_ROM_FLASH)
xc_pwr_rom_off();
__NOP();
__NOP();
__NOP();
__NOP();
__NOP();
__NOP();
__NOP();
__NOP();
__NOP();
__NOP();
__NOP();
__NOP();
// cpr_fmc_ctl_set(0x3000 | (1 << 9)); // close FMC
for (int i = 0; i < 10; i++) {
__NOP();
__NOP();
__NOP();
}
#endif
// __disable_irq();
__NOP();
__NOP();
__NOP();
__NOP();
__NOP();
__NOP();
__WFI();
__NOP();
__NOP();
__NOP();
__NOP();
__NOP();
__NOP();
__NOP();
__NOP();
__NOP();
__NOP();
__NOP();
__NOP();
// cpr_fmc_ctl_set(0x3503);
__NOP();
__NOP();
__NOP();
__NOP();
__NOP();
__NOP();
__NOP();
__NOP();
__NOP();
__NOP();
__NOP();
__NOP();
xc_pwr_rom_on();
#if (USE_ROM_FLASH)
FMC_SPI_Flash_WakeUp();
#else // (USE_ROM_FLASH)
// xc_fmc_spi_flash_wake_up();
#endif // (USE_ROM_FLASH)
xc_pwr_ao_timer_pclk32m_Set();
// __enable_irq();
#ifdef USED_DCDC
xc_pwr_dcdc_open();
#endif
xc_pwr_modem_on();
xc_pwr_rfdigital_on();
xc_adc_wakeup();
}
void enter_cpu_sleep()
{
cpr_ctlapbclken_grctl__uart0_pclk_en__setf(0);
cpr_ahbclken_grctl__dmas_hclk_en__setf(0);
cpr_slp_src_mask_set(0x1e000e);
__NOP();
__NOP();
__NOP();
__NOP();
__NOP();
__NOP();
__WFI();
__NOP();
__NOP();
__NOP();
__NOP();
__NOP();
__NOP();
cpr_slp_src_mask_set(0x1e001e);
// open uart clk
cpr_ctlapbclken_grctl__uart0_pclk_en__setf(1);
}
void sleep_schedule()
{
// Checks for sleep have to be done with interrupt disabled
GLOBAL_INT_DISABLE();
// Check if the processor clock can be gated
uint32_t duration = 0;
uint32_t duration_timer = 0;
switch (rwip_sleep(&duration, 2, 0x7D00, RWIP_MINIMUM_SLEEP_TIME)) {
case RWIP_DEEP_SLEEP: {
duration_timer = (HS_TO_US(duration) - SLEEP_TIME_EARLY);
xc_timer_set_value(TIMER0_IDX, duration_timer);
xc_timer_start(TIMER0_IDX);
// Before you sleep, turn off the peripheral to make sure it doesn't generate interrupts,
// and then turn it on again after you sleep up.
// For example, timer interrupts
xc_rc32k_soft_calib_disable();
xc_ble_sleep();
xc_timer_stop(TIMER0_IDX);
xc_rc32k_soft_calib_enable();
}
// no break
case RWIP_CPU_SLEEP: {
// enter_cpu_sleep();
} break;
case RWIP_ACTIVE:
default: {
// nothing to do.
} break;
}
// Checks for sleep have to be done with interrupt disabled
GLOBAL_INT_RESTORE();
#if (POWER_ON)
power_off_check();
#endif // (POWER_ON)
}
#endif // (SLEEP_ENABLE)
#if (POWER_ON)
void system_deepsleep_init()
{
uint32_t wake_it_src;
#if (USE_XIP == 1)
xc_fmc_spi_init_oprt();
#endif
xc_pwr_gpio_sleep_config();
wake_it_src = GPIO_IRQn_WAKE | RTC_IRQn_WAKE;
xc_pwr_wake_it_set(wake_it_src);
}
void system_deepsleep_cfg()
{
#if (USE_XIP != 1)
cprao_aon_puctrl1_set(0xf);
#endif
cprao_aon_sys_time_set((RST_READY_TIME << 12) | (OSC32_STABLE_TIME));
xc_pwr_pd_deepsleep_set();
xc_pwr_sleepsrc_mask_set(0x1e001e);
xc_pwr_osc_off();
}
void cpu_enter_deepsleep()
{
system_deepsleep_init();
// PWRKEY Initialization is required after deep sleep wakeup
xc_pwr_pwrkey_init();
xc_pwr_pwrkey_deepsleep_wake_config(TOUCH_KEY,
DEEP_SLEEP_GPIO_WAKE_HIGH_LEVEL);
// xc_pwr_pwrkey_deepsleep_wake_config(TOUCH_KEY,
// DEEP_SLEEP_GPIO_WAKE_LOW_LEVEL);
system_deepsleep_cfg();
xc_deep_sleep();
}
void power_on_check()
{
uint16_t power_key_scan = 0;
uint16_t resleep_count = 0;
uint16_t power_on_count = 0;
while (1) {
if (power_key_scan == POWER_KEY_SCAN_COUNT) {
power_key_scan = 0;
if (xc_gpio_read_pin(TOUCH_KEY) == 0) {
if (resleep_count >= GENERAL_RESLEEP_TIME_COUNT) {
cpu_enter_deepsleep();
}
resleep_count++;
power_on_count = 0;
} else {
if (power_on_count == POWER_ON_TIME) {
break;
}
power_on_count++;
resleep_count = 0;
}
}
power_key_scan++;
}
xc_pwr_pwrkey_init();
}
void power_off_check()
{
if (xc_gpio_read_pin(TOUCH_KEY) == 1) {
uint16_t power_key_scan = 0;
uint16_t resleep_count = 0;
uint16_t power_off_count = 0;
while (1) {
if (power_key_scan == POWER_KEY_SCAN_COUNT) {
power_key_scan = 0;
if (xc_gpio_read_pin(TOUCH_KEY) == 0) {
if (resleep_count >= GENERAL_RESLEEP_TIME_COUNT) {
break;
}
resleep_count++;
power_off_count = 0;
} else {
if (power_off_count == POWER_OFF_TIME) {
cpu_enter_deepsleep();
}
power_off_count++;
resleep_count = 0;
}
}
power_key_scan++;
}
xc_pwr_pwrkey_init();
}
}
#endif // (POWER_ON)
// Timer 0 is occupied by sleep and cannot register interrupt functions.
__RAM_CODE void timer0_callback(void *context)
{
}
@@ -0,0 +1,17 @@
#ifndef _SLEEP_H_
#define _SLEEP_H_
#if (POWER_ON)
#define POWER_KEY_SCAN_COUNT 4000
#define GENERAL_RESLEEP_TIME_COUNT 30
#define POWER_ON_TIME 1200
#define POWER_OFF_TIME 1200
#define TOUCH_KEY GPIO_4
#endif //(POWER_ON)
void sleep_init(void);
void sleep_schedule(void);
#endif //_SLEEP_H_
@@ -0,0 +1,245 @@
;/*****************************************************************************
; * @file: startup_xinc.s
; * @purpose: CMSIS Cortex-M0 Core Device Startup File for the
; * Device xinc.
; *****************************************************************************/
Stack_Size EQU 0x000006f0
AREA STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem SPACE Stack_Size
__initial_sp
Heap_Size EQU 0x00000000
AREA HEAP, NOINIT, READWRITE, ALIGN=3
__heap_base
Heap_Mem SPACE Heap_Size
__heap_limit
PRESERVE8
THUMB
; Vector Table Mapped to Address 0 at Reset
AREA RESET, DATA, READONLY
EXPORT __Vectors
EXPORT __Vectors_End
EXPORT __Vectors_Size
__Vectors DCD __initial_sp ; Top of Stack
DCD Reset_Handler ; Reset Handler
DCD NMI_Handler ; NMI Handler
DCD HardFault_Handler ; Hard Fault Handler
DCD MemManage_Handler ; MPU Fault Handler
DCD BusFault_Handler ; Bus Fault Handler
DCD UsageFault_Handler ; Usage Fault Handler
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD SVC_Handler ; SVCall Handler
DCD DebugMon_Handler ; Debug Monitor Handler
DCD 0 ; Reserved
DCD PendSV_Handler ; PendSV Handler
DCD SysTick_Handler ; SysTick Handler
; External Interrupts
; ToDo: Add here the vectors for the device specific external interrupts handler
DCD BLE_Handler ; 0
DCD DMA_Handler ; 1
DCD CPR_Handler ; 2
DCD GPIO_Handler ; 3
DCD RTC_Handler ; 4
DCD TIMER0_Handler ; 5
DCD TIMER1_Handler ; 6
DCD TIMER2_Handler ; 7
DCD TIMER3_Handler ; 8
DCD WDT_Handler ; 9
DCD I2C_Handler ; 10
DCD UART0_Handler ; 11
DCD UART1_Handler ; 12
DCD SPI0_Handler ; 13
DCD SPI1_Handler ; 14
DCD 0 ; 15
DCD 0 ; 16
DCD GADC_Handler ; 17
DCD PWM_Handler ; 18
DCD AES_Handler ; 19
DCD USB_Handler ; 20
DCD AUDIO_Handler ; 21
DCD RF24G_Handler ; 22
DCD SPI2_Handler ; 23
DCD MPU_Handler ; 24
DCD UART2_Handler ; 25
DCD I2S_Handler ; 26
DCD AOTIMER0_Handler ; 27
DCD AOTIMER1_Handler ; 28
DCD CMP_Handler ; 29
DCD FMC_Handler ; 30
DCD CAN_Handler ; 31
__Vectors_End
__Vectors_Size EQU __Vectors_End - __Vectors
AREA |.text|, CODE, READONLY
; Reset Handler
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT SystemInit
IMPORT __main
LDR r0, =0x4000013C ; remap
LDR r1, =0x10000001
STR r1, [r0]
LDR R0, =SystemInit
BLX R0
LDR R0, =__main
BX R0
ENDP
; Dummy Exception Handlers (infinite loops which can be modified)
NMI_Handler PROC
EXPORT NMI_Handler [WEAK]
B .
ENDP
HardFault_Handler\
PROC
EXPORT HardFault_Handler [WEAK]
B .
ENDP
MemManage_Handler\
PROC
EXPORT MemManage_Handler [WEAK]
B .
ENDP
BusFault_Handler\
PROC
EXPORT BusFault_Handler [WEAK]
B .
ENDP
UsageFault_Handler\
PROC
EXPORT UsageFault_Handler [WEAK]
B .
ENDP
SVC_Handler PROC
EXPORT SVC_Handler [WEAK]
B .
ENDP
DebugMon_Handler\
PROC
EXPORT DebugMon_Handler [WEAK]
B .
ENDP
Default_Handler PROC
EXPORT BLE_Handler [WEAK]
EXPORT DMA_Handler [WEAK]
EXPORT CPR_Handler [WEAK]
EXPORT GPIO_Handler [WEAK]
EXPORT RTC_Handler [WEAK]
EXPORT TIMER0_Handler [WEAK]
EXPORT TIMER1_Handler [WEAK]
EXPORT TIMER2_Handler [WEAK]
EXPORT TIMER3_Handler [WEAK]
EXPORT WDT_Handler [WEAK]
EXPORT I2C_Handler [WEAK]
EXPORT UART0_Handler [WEAK]
EXPORT UART1_Handler [WEAK]
EXPORT SPI0_Handler [WEAK]
EXPORT SPI1_Handler [WEAK]
;EXPORT KBS_Handler [WEAK]
;EXPORT QDEC_Handler [WEAK]
EXPORT GADC_Handler [WEAK]
EXPORT PWM_Handler [WEAK]
EXPORT AES_Handler [WEAK]
EXPORT PendSV_Handler [WEAK]
EXPORT SysTick_Handler [WEAK]
EXPORT USB_Handler [WEAK];20
EXPORT AUDIO_Handler [WEAK];21
EXPORT RF24G_Handler [WEAK];22
EXPORT SPI2_Handler [WEAK];23
EXPORT MPU_Handler [WEAK];24
EXPORT UART2_Handler [WEAK];25
EXPORT I2S_Handler [WEAK];26
EXPORT AOTIMER0_Handler [WEAK];27
EXPORT AOTIMER1_Handler [WEAK];28
EXPORT CMP_Handler [WEAK];29
EXPORT FMC_Handler [WEAK];30
EXPORT CAN_Handler [WEAK];31
PendSV_Handler
SysTick_Handler
BLE_Handler
RF24G_Handler
DMA_Handler
CPR_Handler
GPIO_Handler
RTC_Handler
TIMER0_Handler
TIMER1_Handler
TIMER2_Handler
TIMER3_Handler
WDT_Handler
I2C_Handler
I2S_Handler
UART0_Handler
UART1_Handler
UART2_Handler
SPI0_Handler
SPI1_Handler
SPI2_Handler
MPU_Handler
;KBS_Handler
;QDEC_Handler
GADC_Handler
PWM_Handler
AUDIO_Handler
;SIM_Handler
AES_Handler
AOTIMER0_Handler
AOTIMER1_Handler
CMP_Handler
FMC_Handler
CAN_Handler
USB_Handler
B .
ENDP
ALIGN
; User Initial Stack & Heap
IMPORT __use_two_region_memory
EXPORT __user_initial_stackheap
__user_initial_stackheap
LDR R0, = Heap_Mem
LDR R1, = (Stack_Mem + Stack_Size)
LDR R2, = (Heap_Mem + Heap_Size)
LDR R3, = Stack_Mem
BX LR
ALIGN
END
@@ -0,0 +1,128 @@
/**
* Initialize the system
*
* @param none
* @return none
*
* @brief Setup the microcontroller system
*
*/
/*-----------------------------------------------------------------------------------
INCLUDE HEADE FILES
------------------------------------------------------------------------------------*/
#include <stdio.h>
#include "xc6xxx.h"
/*------------------------------------------------------------------------------------
Macros
-------------------------------------------------------------------------------------*/
#define __DEBUG_OUT_PORT 0
/*------------------------------------------------------------------------------------
Functions
-------------------------------------------------------------------------------------*/
#define VECTOR_NUM 48
#if SINGLE_OTA
#define LOADING_ADDR 0x11015000
#else
#define LOADING_ADDR 0x11012000
#endif
void set_vector(void)
{
#if (USE_XIP == 1)
GLOBAL_INT_DISABLE();
for (uint32_t i = 0, *Pvector = (uint32_t *)(LOADING_ADDR + 0),
*_vector_table = (uint32_t *)(0x10000000);
i < VECTOR_NUM; i++) // copy vertor table
{
_vector_table[i] = *Pvector++;
}
*((volatile unsigned int *)(0x4000013C)) =
0x10000001; // inter vertor table remap
GLOBAL_INT_RESTORE();
#endif
}
static void WDT_ResetInit(void)
{
cpr_ctlapbclken_grctl__wdt_pclk_en__setf(ENABLE);
cpr_rstctl_ctlapb_sw__wdt_rstn__setf(RSTCTL_ENABLE);
cpr_rstctl_ctlapb_sw__wdt_rstn__setf(RSTCTL_DISABLE);
cpr_rstctl_wdtrst_mask_set(
(WDT_SYS_RSTN_MASK_DISABLE | WDT_M0_RSTN_MASK_ENABLE));
cpr_lp_ctl__wdt_tclk_en__setf(DISABLE);
wdt_cr__wdt_en__setf(DISABLE);
}
#if (SCATTER_LOAD_RAM_EM)
#define readl(addr) (*(volatile unsigned int *)(addr))
#define writel(addr, value) (*(volatile unsigned int *)(addr) = (value))
#endif
void SystemInit(void)
{
WDT_ResetInit();
#if (USE_XIP == 1)
set_vector();
#endif
#if (SCATTER_LOAD_RAM_EM)
// enable BT CLK
writel(0x40000040, readl(0x40000040) | (0x01 << 4) | 0xFFFF0000);
#endif
}
__RAM_CODE int sendchar(int c)
{
unsigned int status;
#if (__DEBUG_OUT_PORT == 1)
for (;;) {
status = (*((volatile unsigned *)(0x40011000 + 0x14)));
status &= 0x20;
if (status == 0x20)
break;
}
(*((volatile unsigned *)(0x40011000 + 0x00))) = c;
return (1);
#else
for (;;) {
status = (*((volatile unsigned *)(0x40010000 + 0x14)));
status &= 0x20;
if (status == 0x20)
break;
}
(*((volatile unsigned *)(0x40010000 + 0x00))) = c;
return (1);
#endif
}
struct __FILE
{
int handle; /* Add whatever you need here */
};
FILE __stdout;
__RAM_CODE int fputc(int ch, FILE *f) { return (sendchar(ch)); }
int ferror(FILE *f)
{
/* Your implementation of ferror */
return EOF;
}
void _ttywrch(int ch) { sendchar(ch); }
void _sys_exit(int return_code)
{
label:
goto label; /* endless loop */
}
@@ -0,0 +1,172 @@
/**
****************************************************************************************
*
* @file usr_server.c
*
* @brief Custom Server profile database definitions.
*
* Copyright (c) 2022 - 2025, XinChip
* All rights reserved.p
*
****************************************************************************************
*/
#include "usr_server.h"
#if (BLE_APP_PRESENT)
uint8_t srv_user_lid = GATT_INVALID_USER_LID;
uint16_t custom_svc_start_hdl = GATT_INVALID_HDL;
uint8_t custom_svc_tx_char_notify = DISABLE;
__RAM_CODE int BT_BLE_Send(uint8_t *TxBuff, uint16_t TxLen)
{
int ret_val = 0;
ret_val = TxLen;
slave_send_data(TxBuff, TxLen, CUSTOM_SVC_TX_CHAR_VAL);
return (ret_val);
}
static const gatt_att16_desc_t custom_server_atts[] = {
[CUSTOM_SVC_DECL] =
{
.uuid16 = GATT_DECL_PRIMARY_SERVICE,
.info = GATT_ATT_RD_BIT,
.ext_info = 0,
},
[CUSTOM_SVC_RX_CHAR_DECL_CHAR] =
{
.uuid16 = GATT_DECL_CHARACTERISTIC,
.info = GATT_ATT_RD_BIT,
.ext_info = 0,
},
[CUSTOM_SVC_RX_CHAR_VAL] =
{
.uuid16 = CUSTOM_SVC_RX_CHAR_UUID,
.info = GATT_ATT_RD_BIT | GATT_ATT_WC_BIT | GATT_ATT_WR_BIT,
.ext_info =
GATT_ATT_NO_OFFSET_BIT | CUSTOM_SVC_RX_CHAR_VAL_MAX_LENGTH,
},
[CUSTOM_SVC_TX_CHAR_DECL_CHAR] =
{
.uuid16 = GATT_DECL_CHARACTERISTIC,
.info = GATT_ATT_RD_BIT,
.ext_info = 0,
},
[CUSTOM_SVC_TX_CHAR_VAL] =
{
.uuid16 = CUSTOM_SVC_TX_CHAR_UUID,
.info = GATT_ATT_RD_BIT | GATT_ATT_N_BIT,
.ext_info =
GATT_ATT_NO_OFFSET_BIT | CUSTOM_SVC_TX_CHAR_VAL_MAX_LENGTH,
},
[CUSTOM_SVC_TX_CHAR_CFG] =
{
.uuid16 = GATT_DESC_CLIENT_CHAR_CFG,
.info = GATT_ATT_RD_BIT | GATT_ATT_WR_BIT,
.ext_info = 0,
},
};
uint8_t slave_send_data(uint8_t *data, uint8_t len, uint8_t att_idx);
uint16_t srv_get_hdl_from_att_idx(uint8_t idx)
{
return custom_svc_start_hdl + idx;
}
// This function is called when GATT server user has initiated event send to
// peer device or if an error occurs.
__STATIC void custom_svc_cb_event_sent(uint8_t conidx, uint8_t user_lid,
uint16_t dummy, uint16_t status)
{
LOGI("[%s] conidx:%d, usr_lid:%d, dummy:%d, status:%d \r\n", __func__,
conidx, user_lid, dummy, status);
}
// This function is called when peer want to read local attribute database
// value.
__STATIC void custom_svc_cb_att_read_get(uint8_t conidx, uint8_t user_lid,
uint16_t token, uint16_t hdl,
uint16_t offset, uint16_t max_length)
{
uint16_t status;
uint8_t data[512] = {0x12, 0x15, 0x46, 0x62};
LOGI("[%s] conidx:%d, usr_lid:%d, token:%d, hdl:%d, offset:%d, "
"max_length:%d \r\n",
__func__, conidx, user_lid, token, hdl, offset, max_length);
// Send result to peer device
status = xc_ble_gatt_srv_read_cfm(conidx, user_lid, token, GAP_ERR_NO_ERROR,
sizeof(data), sizeof(data), data);
if (status != GATT_NO_ERROR) {
LOGI_ERR("gatt_srv_read_cfm error 0x%x", status);
}
}
// This function is called during a write procedure to modify attribute handle.
__STATIC void custom_svc_cb_att_val_set(uint8_t conidx, uint8_t user_lid,
uint16_t token, uint16_t hdl,
uint16_t offset, co_buf_t *p_data)
{
uint16_t length = co_buf_data_len(p_data);
uint16_t status;
LOGI("[%s] conidx:%d, usr_lid:%d, token:%d, hdl:%d, offset:%d \r\n",
__func__, conidx, user_lid, token, hdl, offset);
status =
xc_ble_gatt_srv_write_cfm(conidx, user_lid, token, GAP_ERR_NO_ERROR);
if (status != GATT_NO_ERROR) {
LOGI_ERR("gatt_srv_write_cfm error 0x%x", status);
}
LOGI("length:%d data:\r\n", length);
// DUMP_DATA_PRINTF(&(co_buf_data(p_data)[0]), length);
xc_uart_send_data(1,&(co_buf_data(p_data)[0]),length);
if (hdl == srv_get_hdl_from_att_idx(CUSTOM_SVC_TX_CHAR_CFG)) {
if ((co_buf_data(p_data)[0] == 0) && (co_buf_data(p_data)[1] == 0)) {
custom_svc_tx_char_notify = DISABLE;
} else {
custom_svc_tx_char_notify = ENABLE;
uint8_t data[] = {0x12, 0x13, 0x14};
slave_send_data(data, sizeof(data), CUSTOM_SVC_TX_CHAR_VAL);
}
}
}
static const gatt_srv_cb_t custom_src_cb = {
.cb_event_sent = custom_svc_cb_event_sent,
.cb_att_read_get = custom_svc_cb_att_read_get,
.cb_att_val_set = custom_svc_cb_att_val_set,
};
uint8_t custom_svc_add(void)
{
int nb_att = sizeof(custom_server_atts) / sizeof(custom_server_atts[0]);
uint16_t status;
uint16_t custom_svc_uuid = CUSTOM_SVC_UUID;
status =
xc_ble_gatt_user_srv_register(133, 0, &custom_src_cb, &srv_user_lid);
if (status != GATT_NO_ERROR) {
LOGI_ERR("gatt_user_srv_register error 0x%x", status);
}
status = xc_ble_gatt_service16_add(
srv_user_lid, GATT_UUID_16 << GATT_SVC_UUID_TYPE_LSB, custom_svc_uuid,
nb_att, NULL, &(custom_server_atts[0]), nb_att, &custom_svc_start_hdl);
if (status != GATT_NO_ERROR) {
LOGI_ERR("gatt_service16_add error 0x%x", status);
}
return status;
}
uint8_t slave_send_data(uint8_t *data, uint8_t len, uint8_t att_idx)
{
uint16_t status = INVALID_DATA;
struct app_env_tag *app_env = get_app_env();
if (app_env->slave_connected && custom_svc_tx_char_notify) {
status = xc_ble_gatt_srv_notify(app_env->slave_conidx, srv_user_lid, 0,
srv_get_hdl_from_att_idx(att_idx), len,
data);
if (status != GATT_NO_ERROR) {
LOGI_ERR("gatt_srv_notify error 0x%x", status);
}
}
return status;
}
#endif // (BLE_APP_PRESENT)
@@ -0,0 +1,40 @@
/**
****************************************************************************************
*
* @file usr_server.h
*
* @brief Custom Server profile database definitions.
*
* Copyright (c) 2022 - 2025, XinChip
* All rights reserved.
*
****************************************************************************************
*/
#ifndef _USR_SERVER_H_
#define _USR_SERVER_H_
#include "app_task.h"
#include "dbg.h"
#include "gatt.h"
#include "gatt_msg.h"
#include "rwble_hl_config.h"
#include "xc_gatt_server_api.h"
#define CUSTOM_SVC_UUID 0xFFF0
#define CUSTOM_SVC_RX_CHAR_UUID 0xFFF3
#define CUSTOM_SVC_TX_CHAR_UUID 0xFFF4
#define CUSTOM_SVC_RX_CHAR_VAL_MAX_LENGTH 20
#define CUSTOM_SVC_TX_CHAR_VAL_MAX_LENGTH 20
enum cust_svc
{
CUSTOM_SVC_DECL = 0,
CUSTOM_SVC_RX_CHAR_DECL_CHAR,
CUSTOM_SVC_RX_CHAR_VAL,
CUSTOM_SVC_TX_CHAR_DECL_CHAR,
CUSTOM_SVC_TX_CHAR_VAL,
CUSTOM_SVC_TX_CHAR_CFG,
};
uint8_t custom_svc_add(void);
uint8_t slave_send_data(uint8_t *data, uint8_t len, uint8_t att_idx);
#endif // _USR_SERVER_H_
@@ -0,0 +1,200 @@
#include "useruart.h"
#include "xc_drv_uart.h"
#include "xc_ring_buffer.h"
#if 1
#define UART_RX_DATA_SIZE 1024
#define UART_RX_IO GPIO_21
static uint8_t uart_rx_data[UART_RX_DATA_SIZE] = {0x00};
static xc_ring_buffer_t uart_rx_ring_buffer;
uint8_t uart_handle = UART1_IDX;
static unsigned int count_1 = 0;
static unsigned int count_2 = 0;
void count_1_add(unsigned char add_len)
{
count_1 += add_len;
}
void count_2_add(unsigned char add_len)
{
count_2 += add_len;
}
__RAM_CODE void uart1_Handler(uint8_t *buff, uint16_t len)
{
if (xc_ring_buffer_bytes_free(&uart_rx_ring_buffer))
{
xc_ring_buffer_write(&uart_rx_ring_buffer, buff, 1);
count_1_add(1);
}
else
{
}
count_2_add(1);
}
#endif
unsigned int hal_console_init(unsigned long baud_rate)
{
GPIO_InitCfg_t gpio_cfg = {0};
unsigned long xc_baud_rate = UART_BAUDRATE_115200; /*default baud rate 115200*/
switch (baud_rate)
{
case 2400:
xc_baud_rate = UART_BAUDRATE_2400;
break;
case 4800:
xc_baud_rate = UART_BAUDRATE_4800;
break;
case 9600:
xc_baud_rate = UART_BAUDRATE_9600;
break;
case 12800:
xc_baud_rate = UART_BAUDRATE_12800;
break;
case 14400:
xc_baud_rate = UART_BAUDRATE_14400;
break;
case 19200:
xc_baud_rate = UART_BAUDRATE_19200;
break;
case 23040:
xc_baud_rate = UART_BAUDRATE_23040;
break;
case 38400:
xc_baud_rate = UART_BAUDRATE_38400;
break;
case 57600:
xc_baud_rate = UART_BAUDRATE_57600;
break;
case 115200:
xc_baud_rate = UART_BAUDRATE_115200;
break;
case 128000:
xc_baud_rate = UART_BAUDRATE_128000;
break;
case 230400:
xc_baud_rate = UART_BAUDRATE_230400;
break;
case 256000:
xc_baud_rate = UART_BAUDRATE_256000;
break;
case 460800:
xc_baud_rate = UART_BAUDRATE_460800;
break;
case 921600:
xc_baud_rate = UART_BAUDRATE_921600;
break;
case 1000000:
xc_baud_rate = UART_BAUDRATE_1M;
break;
default:
break;
}
gpio_cfg.Mux = GPIO_Mux0;
gpio_cfg.Pull = GPIO_PULLUP;
gpio_cfg.Int = NOT_INT;
gpio_cfg.Pin = GPIO_20;
gpio_cfg.Dir = GPIO_DIR_OUTPUT;
gpio_cfg.FunSel = UART1_TX;
xc_gpio_init(&gpio_cfg);
gpio_cfg.Pin = UART_RX_IO;
gpio_cfg.Dir = GPIO_DIR_INPUT;
gpio_cfg.FunSel = UART1_RX;
xc_gpio_init(&gpio_cfg);
UART_InitCfg_t uart_cfg = {0};
uart_cfg.Parity = UART_PARITY_DISABLE;
uart_cfg.StopBits = UART_TCR_STOP_1BITS;
uart_cfg.WordLength = UART_DATA_8_BITS;
uart_cfg.BaudRate = xc_baud_rate;
uart_cfg.HardwareFlowControl = UART_HWFC_ENABLE;
xc_uart_init(uart_handle, &uart_cfg);
xc_uart_enable_rx_it(uart_handle);
if (uart_handle == UART0_IDX)
{
NVIC_EnableIRQ(UART0_IRQn);
}
else if (uart_handle == UART1_IDX)
{
NVIC_EnableIRQ(UART1_IRQn);
}
else if (uart_handle == UART2_IDX)
{
NVIC_EnableIRQ(UART2_IRQn);
}
xc_ring_buffer_init(&uart_rx_ring_buffer, uart_rx_data, UART_RX_DATA_SIZE);
xc_uart_register_receive_cb(UART1_IDX, uart1_Handler);
return (0);
}
unsigned int hal_console_get_rx_space(void)
{
return xc_ring_buffer_bytes_free(&uart_rx_ring_buffer);
}
unsigned int hal_console_get_rx_data_length(void)
{
return xc_ring_buffer_bytes_available(&uart_rx_ring_buffer);
}
void hal_console_clear_rx_fifo(void)
{
xc_ring_buffer_reset(&uart_rx_ring_buffer);
}
unsigned int hal_console_write(unsigned char *buffer, unsigned int length)
{
unsigned int ret_val;
if ((length) && (buffer))
{
xc_uart_send_data(uart_handle, buffer, length);
ret_val = length;
}
else
ret_val = 0;
return (ret_val);
}
unsigned int hal_console_read(unsigned int length, unsigned char *buffer)
{
unsigned int ret_val;
unsigned int read_number = 0;
unsigned int need_read_number = 0;
if ((length) && (buffer))
{
need_read_number = xc_ring_buffer_bytes_available(&uart_rx_ring_buffer);
if (need_read_number)
{
need_read_number = need_read_number < length ? need_read_number : length;
xc_ring_buffer_read(&uart_rx_ring_buffer, buffer, need_read_number, &read_number);
ret_val = read_number;
}
else
{
ret_val = 0;
}
}
else
ret_val = 0;
return (ret_val);
}
@@ -0,0 +1,22 @@
#ifndef _USER_UART_H
#define _USER_UART_H
// int User_Uart_Init(unsigned long baud_rate);
// int HAL_ConsoleWrite(int Length, unsigned char *Buffer);
// int HAL_ConsoleRead(int Length, unsigned char *Buffer);
// void HAL_UART_Int_Init(unsigned long baud_rate);
// unsigned short HAL_UART_Int_Send(unsigned char *Data, unsigned short Length);
// unsigned short HAL_UART_Int_Recv(unsigned char *Data, unsigned short Length);
// unsigned short HAL_UART_Int_GetRxCount(void);
// unsigned short HAL_UART_Int_GetRxFree(void);
// void HAL_UART_Int_ClearRxFifo(void);
unsigned int hal_console_init(unsigned long baud_rate);
unsigned int hal_console_write(unsigned char *buffer, unsigned int length);
unsigned int hal_console_read(unsigned int length, unsigned char *buffer);
unsigned int hal_console_get_rx_space(void);
unsigned int hal_console_get_rx_data_length(void);
void hal_console_clear_rx_fifo(void);
#define UART_BAUD_SET 115200
#endif
@@ -0,0 +1,139 @@
#define BTSTACK_FILE__ "xc_ring_buffer.h"
#include "usr_server.h"
#include <string.h>
#include "xc_ring_buffer.h"
#define ERROR_CODE_MEMORY_CAPACITY_EXCEEDED 0x07
uint32_t xc_min(uint32_t a, uint32_t b)
{
return a < b ? a : b;
}
uint32_t xc_max(uint32_t a, uint32_t b)
{
return a > b ? a : b;
}
// init ring buffer
void xc_ring_buffer_init(xc_ring_buffer_t *ring_buffer, uint8_t *storage, uint32_t storage_size)
{
ring_buffer->storage = storage;
ring_buffer->size = storage_size;
xc_ring_buffer_reset(ring_buffer);
}
void xc_ring_buffer_reset(xc_ring_buffer_t *ring_buffer)
{
ring_buffer->last_read_index = 0;
ring_buffer->last_written_index = 0;
ring_buffer->full = 0;
}
uint32_t xc_ring_buffer_bytes_available(xc_ring_buffer_t *ring_buffer)
{
if (ring_buffer->full)
return ring_buffer->size;
int diff = ring_buffer->last_written_index - ring_buffer->last_read_index;
if (diff >= 0)
return diff;
return diff + ring_buffer->size;
}
// test if ring buffer is empty
int xc_ring_buffer_empty(xc_ring_buffer_t *ring_buffer)
{
return xc_ring_buffer_bytes_available(ring_buffer) == 0u;
}
//
__RAM_CODE uint32_t xc_ring_buffer_bytes_free(xc_ring_buffer_t *ring_buffer)
{
return ring_buffer->size - xc_ring_buffer_bytes_available(ring_buffer);
}
// add byte block to ring buffer,
__RAM_CODE int xc_ring_buffer_write(xc_ring_buffer_t *ring_buffer, uint8_t *data, uint32_t data_length)
{
if (xc_ring_buffer_bytes_free(ring_buffer) < data_length)
{
return ERROR_CODE_MEMORY_CAPACITY_EXCEEDED;
}
// simplify logic below by asserting data_length > 0
if (data_length == 0u)
return 0u;
uint32_t remaining_data_length = data_length;
const uint8_t *remaining_data = data;
// copy first chunk
unsigned int bytes_until_end = ring_buffer->size - ring_buffer->last_written_index;
unsigned int bytes_to_copy = xc_min(bytes_until_end, remaining_data_length);
(void)memcpy(&ring_buffer->storage[ring_buffer->last_written_index], remaining_data, bytes_to_copy);
remaining_data_length -= bytes_to_copy;
remaining_data += bytes_to_copy;
// update last written index
ring_buffer->last_written_index += bytes_to_copy;
if (ring_buffer->last_written_index == ring_buffer->size)
{
ring_buffer->last_written_index = 0;
}
// copy second chunk
if (remaining_data_length != 0)
{
(void)memcpy(&ring_buffer->storage[0], remaining_data, remaining_data_length);
ring_buffer->last_written_index += remaining_data_length;
}
// mark buffer as full
if (ring_buffer->last_written_index == ring_buffer->last_read_index)
{
ring_buffer->full = 1;
}
return 0;
}
// fetch data_length bytes from ring buffer
__RAM_CODE void xc_ring_buffer_read(xc_ring_buffer_t *ring_buffer, uint8_t *data, uint32_t data_length, uint32_t *number_of_bytes_read)
{
// limit data to get and report
uint32_t remaining_data_length = xc_min(data_length, xc_ring_buffer_bytes_available(ring_buffer));
*number_of_bytes_read = remaining_data_length;
// simplify logic below by asserting remaining_data_length > 0
if (remaining_data_length == 0u)
return;
uint8_t *remaining_data = data;
// copy first chunk
unsigned int bytes_until_end = ring_buffer->size - ring_buffer->last_read_index;
unsigned int bytes_to_copy = xc_min(bytes_until_end, remaining_data_length);
(void)memcpy(remaining_data, &ring_buffer->storage[ring_buffer->last_read_index],
bytes_to_copy);
remaining_data_length -= bytes_to_copy;
remaining_data += bytes_to_copy;
// update last read index
ring_buffer->last_read_index += bytes_to_copy;
if (ring_buffer->last_read_index == ring_buffer->size)
{
ring_buffer->last_read_index = 0;
}
// copy second chunk
if (remaining_data_length != 0)
{
(void)memcpy(remaining_data, &ring_buffer->storage[0], remaining_data_length);
ring_buffer->last_read_index += remaining_data_length;
}
// clear full flag
ring_buffer->full = 0;
}
@@ -0,0 +1,81 @@
#ifndef XC_RING_BUFFER_H
#define XC_RING_BUFFER_H
#if defined __cplusplus
extern "C"
{
#endif
#include <stdint.h>
typedef struct xc_ring_buffer
{
uint8_t *storage;
uint32_t size;
uint32_t last_read_index;
uint32_t last_written_index;
uint8_t full;
} xc_ring_buffer_t;
/* API_START */
/**
* Init ring buffer
* @param ring_buffer object
* @param storage
* @param storage_size in bytes
*/
void xc_ring_buffer_init(xc_ring_buffer_t *ring_buffer, uint8_t *storage, uint32_t storage_size);
/**
* Reset ring buffer to initial state (empty)
* @param ring_buffer object
*/
void xc_ring_buffer_reset(xc_ring_buffer_t *ring_buffer);
/**
* Check if ring buffer is empty
* @param ring_buffer object
* @return TRUE if empty
*/
int xc_ring_buffer_empty(xc_ring_buffer_t *ring_buffer);
/**
* Get number of bytes available for read
* @param ring_buffer object
* @return number of bytes available for read
*/
uint32_t xc_ring_buffer_bytes_available(xc_ring_buffer_t *ring_buffer);
/**
* Get free space available for write
* @param ring_buffer object
* @return number of bytes available for write
*/
uint32_t xc_ring_buffer_bytes_free(xc_ring_buffer_t *ring_buffer);
/**
* Write bytes into ring buffer
* @param ring_buffer object
* @param data to store
* @param data_length
* @return 0 if ok, ERROR_CODE_MEMORY_CAPACITY_EXCEEDED if not enough space in buffer
*/
int xc_ring_buffer_write(xc_ring_buffer_t *ring_buffer, uint8_t *data, uint32_t data_length);
/**
* Read from ring buffer
* @param ring_buffer object
* @param buffer to store read data
* @param length to read
* @param number_of_bytes_read
*/
void xc_ring_buffer_read(xc_ring_buffer_t *ring_buffer, uint8_t *buffer, uint32_t length, uint32_t *number_of_bytes_read);
/* API_END */
#if defined __cplusplus
}
#endif
#endif