init: DLD110SV4 单线圈蓝牙车检器原始代码 (CH591R, BLE OTA 三段式)
This commit is contained in:
@@ -0,0 +1,110 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : ota.h
|
||||
* Author : WCH
|
||||
* Version : V1.10
|
||||
* Date : 2018/12/14
|
||||
* Description : oad相关配置定义
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
|
||||
/******************************************************************************/
|
||||
#ifndef __OTA_H
|
||||
#define __OTA_H
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* OTA FLASH
|
||||
* ------------------------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/* 整个用户code区分成四块,依次为4K,44K,16K,128K 后三块分别叫做imageA(APP),imageB(IAP),LIB */
|
||||
|
||||
/* FLASH定义 */
|
||||
|
||||
#define FLASH_BLOCK_SIZE EEPROM_BLOCK_SIZE
|
||||
|
||||
/* imageA定义 */
|
||||
#define IMAGE_A_FLAG 0x01
|
||||
#define IMAGE_A_START_ADD 0x1000
|
||||
#define IMAGE_A_SIZE 44 * 1024
|
||||
|
||||
/* imageB定义 */
|
||||
#define IMAGE_B_FLAG 0x02
|
||||
#define IMAGE_B_START_ADD (IMAGE_A_START_ADD + IMAGE_A_SIZE)
|
||||
#define IMAGE_B_SIZE 16 * 1024
|
||||
|
||||
#define IMAGE_OTA_FLAG 0x03
|
||||
|
||||
#define jumpApp ((void (*)(void))((uint32_t *)IMAGE_A_START_ADD))
|
||||
|
||||
/* IAP定义 */
|
||||
/* 以下为IAP下载命令定义 */
|
||||
#define CMD_IAP_PROM 0x80 // IAP编程命令
|
||||
#define CMD_IAP_ERASE 0x81 // IAP擦除命令
|
||||
#define CMD_IAP_VERIFY 0x82 // IAP校验命令
|
||||
#define CMD_IAP_END 0x83 // IAP结束标志
|
||||
#define CMD_IAP_INFO 0x84 // IAP获取设备信息
|
||||
|
||||
/* 数据帧长度定义 */
|
||||
#define IAP_LEN 247
|
||||
|
||||
/* 存放在DataFlash地址,不能占用蓝牙的位置 */
|
||||
#define OTA_DATAFLASH_ADD 0x00077000 - FLASH_ROM_MAX_SIZE
|
||||
|
||||
/* 存放在DataFlash里的OTA信息 */
|
||||
typedef struct
|
||||
{
|
||||
unsigned char ImageFlag; //记录的当前的image标志
|
||||
unsigned char Revd[3];
|
||||
} OTADataFlashInfo_t;
|
||||
|
||||
/* OTA IAP通讯协议定义 */
|
||||
/* 地址使用4倍偏移 */
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
unsigned char cmd; /* 命令码 0x81 */
|
||||
unsigned char len; /* 后续数据长度 */
|
||||
unsigned char addr[2]; /* 擦除地址 */
|
||||
unsigned char block_num[2]; /* 擦除块数 */
|
||||
|
||||
} erase; /* 擦除命令 */
|
||||
struct
|
||||
{
|
||||
unsigned char cmd; /* 命令码 0x83 */
|
||||
unsigned char len; /* 后续数据长度 */
|
||||
unsigned char status[2]; /* 两字节状态,保留 */
|
||||
} end; /* 结束命令 */
|
||||
struct
|
||||
{
|
||||
unsigned char cmd; /* 命令码 0x82 */
|
||||
unsigned char len; /* 后续数据长度 */
|
||||
unsigned char addr[2]; /* 校验地址 */
|
||||
unsigned char buf[IAP_LEN - 4]; /* 校验数据 */
|
||||
} verify; /* 校验命令 */
|
||||
struct
|
||||
{
|
||||
unsigned char cmd; /* 命令码 0x80 */
|
||||
unsigned char len; /* 后续数据长度 */
|
||||
unsigned char addr[2]; /* 地址 */
|
||||
unsigned char buf[IAP_LEN - 4]; /* 后续数据 */
|
||||
} program; /* 编程命令 */
|
||||
struct
|
||||
{
|
||||
unsigned char cmd; /* 命令码 0x84 */
|
||||
unsigned char len; /* 后续数据长度 */
|
||||
unsigned char buf[IAP_LEN - 2]; /* 后续数据 */
|
||||
} info; /* 编程命令 */
|
||||
struct
|
||||
{
|
||||
unsigned char buf[IAP_LEN]; /* 接收数据包*/
|
||||
} other;
|
||||
} OTA_IAP_CMD_t;
|
||||
|
||||
/* 记录当前的Image */
|
||||
extern unsigned char CurrImageFlag;
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,58 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : peripheral.h
|
||||
* Author : WCH
|
||||
* Version : V1.0
|
||||
* Date : 2018/12/11
|
||||
* Description :
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef PERIPHERAL_H
|
||||
#define PERIPHERAL_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
* INCLUDES
|
||||
*/
|
||||
|
||||
/*********************************************************************
|
||||
* CONSTANTS
|
||||
*/
|
||||
|
||||
// Simple BLE Peripheral Task Events
|
||||
#define SBP_START_DEVICE_EVT 0x0001
|
||||
#define SBP_PERIODIC_EVT 0x0002
|
||||
#define OTA_FLASH_ERASE_EVT 0x0004 //OTA Flash²Á³ýÈÎÎñ
|
||||
|
||||
/*********************************************************************
|
||||
* MACROS
|
||||
*/
|
||||
|
||||
/*********************************************************************
|
||||
* FUNCTIONS
|
||||
*/
|
||||
|
||||
/*
|
||||
* Task Initialization for the BLE Application
|
||||
*/
|
||||
extern void Peripheral_Init(void);
|
||||
|
||||
/*
|
||||
* Task Event Processor for the BLE Application
|
||||
*/
|
||||
extern uint16_t Peripheral_ProcessEvent(uint8_t task_id, uint16_t events);
|
||||
|
||||
/*********************************************************************
|
||||
*********************************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,695 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : Peripheral.C
|
||||
* Author : WCH
|
||||
* Version : V1.0
|
||||
* Date : 2018/12/10
|
||||
* Description : 外设从机应用程序,初始化广播连接参数,然后广播,直至连接主机后,通过自定义服务传输数据
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
|
||||
/*********************************************************************
|
||||
* INCLUDES
|
||||
*/
|
||||
#include "CONFIG.h"
|
||||
#include "GATTprofile.h"
|
||||
#include "Peripheral.h"
|
||||
#include "OTA.h"
|
||||
#include "OTAprofile.h"
|
||||
|
||||
/*********************************************************************
|
||||
* MACROS
|
||||
*/
|
||||
|
||||
/*********************************************************************
|
||||
* CONSTANTS
|
||||
*/
|
||||
|
||||
// How often to perform periodic event
|
||||
#define SBP_PERIODIC_EVT_PERIOD 1000
|
||||
|
||||
// What is the advertising interval when device is discoverable (units of 625us, 32=20ms)
|
||||
#define DEFAULT_ADVERTISING_INTERVAL 32
|
||||
|
||||
// Limited discoverable mode advertises for 30.72s, and then stops
|
||||
// General discoverable mode advertises indefinitely
|
||||
|
||||
#define DEFAULT_DISCOVERABLE_MODE GAP_ADTYPE_FLAGS_GENERAL
|
||||
|
||||
// Minimum connection interval (units of 1.25ms, 6=7.5ms) if automatic parameter update request is enabled
|
||||
#define DEFAULT_DESIRED_MIN_CONN_INTERVAL 6
|
||||
|
||||
// Maximum connection interval (units of 1.25ms, 12=15ms) if automatic parameter update request is enabled
|
||||
#define DEFAULT_DESIRED_MAX_CONN_INTERVAL 12
|
||||
|
||||
// Slave latency to use if automatic parameter update request is enabled
|
||||
#define DEFAULT_DESIRED_SLAVE_LATENCY 0
|
||||
|
||||
// Supervision timeout value (units of 10ms, 1000=10s) if automatic parameter update request is enabled
|
||||
#define DEFAULT_DESIRED_CONN_TIMEOUT 1000
|
||||
|
||||
// Whether to enable automatic parameter update request when a connection is formed
|
||||
#define DEFAULT_ENABLE_UPDATE_REQUEST TRUE
|
||||
|
||||
// Connection Pause Peripheral time value (in seconds)
|
||||
#define DEFAULT_CONN_PAUSE_PERIPHERAL 6
|
||||
|
||||
// Company Identifier: WCH
|
||||
#define WCH_COMPANY_ID 0x07D7
|
||||
|
||||
#define INVALID_CONNHANDLE 0xFFFF
|
||||
|
||||
// Length of bd addr as a string
|
||||
#define B_ADDR_STR_LEN 15
|
||||
|
||||
/*********************************************************************
|
||||
* TYPEDEFS
|
||||
*/
|
||||
|
||||
/*********************************************************************
|
||||
* GLOBAL VARIABLES
|
||||
*/
|
||||
|
||||
/*********************************************************************
|
||||
* EXTERNAL VARIABLES
|
||||
*/
|
||||
|
||||
/*********************************************************************
|
||||
* EXTERNAL FUNCTIONS
|
||||
*/
|
||||
|
||||
/*********************************************************************
|
||||
* LOCAL VARIABLES
|
||||
*/
|
||||
static uint8_t Peripheral_TaskID = INVALID_TASK_ID; // Task ID for internal task/event processing
|
||||
|
||||
// GAP - SCAN RSP data (max size = 31 bytes)
|
||||
static uint8_t scanRspData[31] = {
|
||||
// complete name
|
||||
0x12, // length of this data
|
||||
GAP_ADTYPE_LOCAL_NAME_COMPLETE,
|
||||
'O', 'T', 'A', 'O', 'T', 'A', '_', 'O', 'T', 'A', 'O', 'T', 'A', '_', 'O', 'T', 'A',
|
||||
// connection interval range
|
||||
0x05, // length of this data
|
||||
GAP_ADTYPE_SLAVE_CONN_INTERVAL_RANGE,
|
||||
LO_UINT16(DEFAULT_DESIRED_MIN_CONN_INTERVAL), // 100ms
|
||||
HI_UINT16(DEFAULT_DESIRED_MIN_CONN_INTERVAL),
|
||||
LO_UINT16(DEFAULT_DESIRED_MAX_CONN_INTERVAL), // 1s
|
||||
HI_UINT16(DEFAULT_DESIRED_MAX_CONN_INTERVAL),
|
||||
|
||||
// Tx power level
|
||||
0x02, // length of this data
|
||||
GAP_ADTYPE_POWER_LEVEL,
|
||||
0 // 0dBm
|
||||
};
|
||||
|
||||
// GAP - Advertisement data (max size = 31 bytes, though this is
|
||||
// best kept short to conserve power while advertisting)
|
||||
static uint8_t advertData[] = {
|
||||
// Flags; this sets the device to use limited discoverable
|
||||
// mode (advertises for 30 seconds at a time) instead of general
|
||||
// discoverable mode (advertises indefinitely)
|
||||
0x02, // length of this data
|
||||
GAP_ADTYPE_FLAGS,
|
||||
DEFAULT_DISCOVERABLE_MODE | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,
|
||||
|
||||
// service UUID, to notify central devices what services are included
|
||||
// in this peripheral
|
||||
0x03, // length of this data
|
||||
GAP_ADTYPE_16BIT_MORE, // some of the UUID's, but not all
|
||||
LO_UINT16(SIMPLEPROFILE_SERV_UUID),
|
||||
HI_UINT16(SIMPLEPROFILE_SERV_UUID)
|
||||
|
||||
};
|
||||
|
||||
// GAP GATT Attributes
|
||||
static uint8_t attDeviceName[GAP_DEVICE_NAME_LEN] = "OTAOTA_OTAOTA_OTA";
|
||||
|
||||
// OTA IAP VARIABLES
|
||||
/* OTA通讯的帧 */
|
||||
OTA_IAP_CMD_t iap_rec_data;
|
||||
|
||||
/* OTA解析结果 */
|
||||
uint32_t OpParaDataLen = 0;
|
||||
uint32_t OpAdd = 0;
|
||||
|
||||
/* flash的数据临时存储 */
|
||||
__attribute__((aligned(8))) uint8_t block_buf[16];
|
||||
|
||||
/* Image跳转函数地址定义 */
|
||||
typedef int (*pImageTaskFn)(void);
|
||||
pImageTaskFn user_image_tasks;
|
||||
|
||||
/* Flash 擦除过程 */
|
||||
uint32_t EraseAdd = 0; //擦除地址
|
||||
uint32_t EraseBlockNum = 0; //需要擦除的块数
|
||||
uint32_t EraseBlockCnt = 0; //擦除的块计数
|
||||
|
||||
/* FLASH 校验过程 */
|
||||
uint8_t VerifyStatus = 0;
|
||||
|
||||
/*********************************************************************
|
||||
* LOCAL FUNCTIONS
|
||||
*/
|
||||
static void Peripheral_ProcessTMOSMsg(tmos_event_hdr_t *pMsg);
|
||||
static void peripheralStateNotificationCB(gapRole_States_t newState, gapRoleEvent_t *pEvent);
|
||||
static void performPeriodicTask(void);
|
||||
|
||||
void OTA_IAPReadDataComplete(unsigned char index);
|
||||
void OTA_IAPWriteData(unsigned char index, unsigned char *p_data, unsigned char w_len);
|
||||
void Rec_OTA_IAP_DataDeal(void);
|
||||
void OTA_IAP_SendCMDDealSta(uint8_t deal_status);
|
||||
|
||||
/*********************************************************************
|
||||
* PROFILE CALLBACKS
|
||||
*/
|
||||
|
||||
// GAP Role Callbacks
|
||||
static gapRolesCBs_t Peripheral_PeripheralCBs = {
|
||||
peripheralStateNotificationCB, // Profile State Change Callbacks
|
||||
NULL, // When a valid RSSI is read from controller (not used by application)
|
||||
NULL};
|
||||
|
||||
// GAP Bond Manager Callbacks
|
||||
static gapBondCBs_t Peripheral_BondMgrCBs = {
|
||||
NULL, // Passcode callback (not used by application)
|
||||
NULL // Pairing / Bonding state Callback (not used by application)
|
||||
};
|
||||
|
||||
// Simple GATT Profile Callbacks
|
||||
static OTAProfileCBs_t Peripheral_OTA_IAPProfileCBs = {
|
||||
OTA_IAPReadDataComplete, // Charactersitic value change callback
|
||||
OTA_IAPWriteData};
|
||||
|
||||
// Callback when the connection parameteres are updated.
|
||||
void PeripheralParamUpdate(uint16_t connInterval, uint16_t connSlaveLatency, uint16_t connTimeout);
|
||||
|
||||
gapRolesParamUpdateCB_t PeripheralParamUpdate_t = NULL;
|
||||
|
||||
/*********************************************************************
|
||||
* PUBLIC FUNCTIONS
|
||||
*/
|
||||
|
||||
/*********************************************************************
|
||||
* @fn Peripheral_Init
|
||||
*
|
||||
* @brief Initialization function for the Peripheral App Task.
|
||||
* This is called during initialization and should contain
|
||||
* any application specific initialization (ie. hardware
|
||||
* initialization/setup, table initialization, power up
|
||||
* notificaiton ... ).
|
||||
*
|
||||
* @param task_id - the ID assigned by TMOS. This ID should be
|
||||
* used to send messages and set timers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void Peripheral_Init()
|
||||
{
|
||||
Peripheral_TaskID = TMOS_ProcessEventRegister(Peripheral_ProcessEvent);
|
||||
|
||||
// Setup the GAP Peripheral Role Profile
|
||||
{
|
||||
// For other hardware platforms, device starts advertising upon initialization
|
||||
uint8_t initial_advertising_enable = TRUE;
|
||||
|
||||
// Set the GAP Role Parameters
|
||||
GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t), &initial_advertising_enable);
|
||||
GAPRole_SetParameter(GAPROLE_SCAN_RSP_DATA, sizeof(scanRspData), scanRspData);
|
||||
GAPRole_SetParameter(GAPROLE_ADVERT_DATA, sizeof(advertData), advertData);
|
||||
}
|
||||
|
||||
// Set the GAP Characteristics
|
||||
GGS_SetParameter(GGS_DEVICE_NAME_ATT, GAP_DEVICE_NAME_LEN, attDeviceName);
|
||||
|
||||
// Set advertising interval
|
||||
{
|
||||
uint16_t advInt = DEFAULT_ADVERTISING_INTERVAL;
|
||||
|
||||
GAP_SetParamValue(TGAP_DISC_ADV_INT_MIN, advInt);
|
||||
GAP_SetParamValue(TGAP_DISC_ADV_INT_MAX, advInt);
|
||||
}
|
||||
|
||||
// Initialize GATT attributes
|
||||
GGS_AddService(GATT_ALL_SERVICES); // GAP
|
||||
GATTServApp_AddService(GATT_ALL_SERVICES); // GATT attributes
|
||||
OTAProfile_AddService(GATT_ALL_SERVICES);
|
||||
|
||||
// Register callback with OTAGATTprofile
|
||||
OTAProfile_RegisterAppCBs(&Peripheral_OTA_IAPProfileCBs);
|
||||
|
||||
// Setup a delayed profile startup
|
||||
tmos_set_event(Peripheral_TaskID, SBP_START_DEVICE_EVT);
|
||||
}
|
||||
|
||||
void PeripheralParamUpdate(uint16_t connInterval, uint16_t connSlaveLatency, uint16_t connTimeout)
|
||||
{
|
||||
PRINT("update %d %d %d \n", connInterval, connSlaveLatency, connTimeout);
|
||||
|
||||
// GAPRole_SendUpdateParam( DEFAULT_DESIRED_MIN_CONN_INTERVAL, DEFAULT_DESIRED_MAX_CONN_INTERVAL,
|
||||
// DEFAULT_DESIRED_SLAVE_LATENCY, DEFAULT_DESIRED_CONN_TIMEOUT, GAPROLE_NO_ACTION );
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn Peripheral_ProcessEvent
|
||||
*
|
||||
* @brief Peripheral Application Task event processor. This function
|
||||
* is called to process all events for the task. Events
|
||||
* include timers, messages and any other user defined events.
|
||||
*
|
||||
* @param task_id - The TMOS assigned task ID.
|
||||
* @param events - events to process. This is a bit map and can
|
||||
* contain more than one event.
|
||||
*
|
||||
* @return events not processed
|
||||
*/
|
||||
uint16_t Peripheral_ProcessEvent(uint8_t task_id, uint16_t events)
|
||||
{
|
||||
// VOID task_id; // TMOS required parameter that isn't used in this function
|
||||
|
||||
if(events & SYS_EVENT_MSG)
|
||||
{
|
||||
uint8_t *pMsg;
|
||||
|
||||
if((pMsg = tmos_msg_receive(Peripheral_TaskID)) != NULL)
|
||||
{
|
||||
Peripheral_ProcessTMOSMsg((tmos_event_hdr_t *)pMsg);
|
||||
// Release the TMOS message
|
||||
tmos_msg_deallocate(pMsg);
|
||||
}
|
||||
// return unprocessed events
|
||||
return (events ^ SYS_EVENT_MSG);
|
||||
}
|
||||
|
||||
if(events & SBP_START_DEVICE_EVT)
|
||||
{
|
||||
// Start the Device
|
||||
GAPRole_PeripheralStartDevice(Peripheral_TaskID, &Peripheral_BondMgrCBs, &Peripheral_PeripheralCBs);
|
||||
// Set timer for first periodic event
|
||||
tmos_start_task(Peripheral_TaskID, SBP_PERIODIC_EVT, SBP_PERIODIC_EVT_PERIOD);
|
||||
return (events ^ SBP_START_DEVICE_EVT);
|
||||
}
|
||||
|
||||
if(events & SBP_PERIODIC_EVT)
|
||||
{
|
||||
// Restart timer
|
||||
if(SBP_PERIODIC_EVT_PERIOD)
|
||||
{
|
||||
tmos_start_task(Peripheral_TaskID, SBP_PERIODIC_EVT, SBP_PERIODIC_EVT_PERIOD);
|
||||
}
|
||||
// Perform periodic application task
|
||||
performPeriodicTask();
|
||||
return (events ^ SBP_PERIODIC_EVT);
|
||||
}
|
||||
|
||||
//OTA_FLASH_ERASE_EVT
|
||||
if(events & OTA_FLASH_ERASE_EVT)
|
||||
{
|
||||
uint8_t status;
|
||||
|
||||
PRINT("ERASE:%08x num:%d\r\n", (int)(EraseAdd + EraseBlockCnt * FLASH_BLOCK_SIZE), (int)EraseBlockCnt);
|
||||
status = FLASH_ROM_ERASE(EraseAdd + EraseBlockCnt * FLASH_BLOCK_SIZE, FLASH_BLOCK_SIZE);
|
||||
|
||||
/* 擦除失败 */
|
||||
if(status != SUCCESS)
|
||||
{
|
||||
OTA_IAP_SendCMDDealSta(status);
|
||||
return (events ^ OTA_FLASH_ERASE_EVT);
|
||||
}
|
||||
|
||||
EraseBlockCnt++;
|
||||
|
||||
/* 擦除结束 */
|
||||
if(EraseBlockCnt >= EraseBlockNum)
|
||||
{
|
||||
PRINT("ERASE Complete\r\n");
|
||||
OTA_IAP_SendCMDDealSta(status);
|
||||
return (events ^ OTA_FLASH_ERASE_EVT);
|
||||
}
|
||||
|
||||
return (events);
|
||||
}
|
||||
|
||||
// Discard unknown events
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn Peripheral_ProcessTMOSMsg
|
||||
*
|
||||
* @brief Process an incoming task message.
|
||||
*
|
||||
* @param pMsg - message to process
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void Peripheral_ProcessTMOSMsg(tmos_event_hdr_t *pMsg)
|
||||
{
|
||||
switch(pMsg->event)
|
||||
{
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn peripheralStateNotificationCB
|
||||
*
|
||||
* @brief Notification from the profile of a state change.
|
||||
*
|
||||
* @param newState - new state
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void peripheralStateNotificationCB(gapRole_States_t newState, gapRoleEvent_t *pEvent)
|
||||
{
|
||||
switch(newState & GAPROLE_STATE_ADV_MASK)
|
||||
{
|
||||
case GAPROLE_STARTED:
|
||||
PRINT("Initialized..\n");
|
||||
break;
|
||||
|
||||
case GAPROLE_ADVERTISING:
|
||||
PRINT("Advertising..\n");
|
||||
break;
|
||||
|
||||
case GAPROLE_CONNECTED:
|
||||
{
|
||||
gapEstLinkReqEvent_t *event = (gapEstLinkReqEvent_t *)pEvent;
|
||||
uint16_t conn_interval = 0;
|
||||
|
||||
conn_interval = event->connInterval;
|
||||
PRINT("Connected.. \n");
|
||||
|
||||
if(conn_interval > DEFAULT_DESIRED_MAX_CONN_INTERVAL)
|
||||
{
|
||||
PRINT("Send Update\r\n");
|
||||
GAPRole_PeripheralConnParamUpdateReq(event->connectionHandle,
|
||||
DEFAULT_DESIRED_MIN_CONN_INTERVAL,
|
||||
DEFAULT_DESIRED_MAX_CONN_INTERVAL,
|
||||
DEFAULT_DESIRED_SLAVE_LATENCY,
|
||||
DEFAULT_DESIRED_CONN_TIMEOUT,
|
||||
Peripheral_TaskID);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GAPROLE_CONNECTED_ADV:
|
||||
PRINT("Connected Advertising..\n");
|
||||
break;
|
||||
case GAPROLE_WAITING:
|
||||
{
|
||||
uint8_t initial_advertising_enable = TRUE;
|
||||
|
||||
// Set the GAP Role Parameters
|
||||
GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t), &initial_advertising_enable);
|
||||
PRINT("Disconnected..\n");
|
||||
}
|
||||
break;
|
||||
|
||||
case GAPROLE_ERROR:
|
||||
PRINT("Error..\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn performPeriodicTask
|
||||
*
|
||||
* @brief Perform a periodic application task. This function gets
|
||||
* called every five seconds as a result of the SBP_PERIODIC_EVT
|
||||
* TMOS event. In this example, the value of the third
|
||||
* characteristic in the SimpleGATTProfile service is retrieved
|
||||
* from the profile, and then copied into the value of the
|
||||
* the fourth characteristic.
|
||||
*
|
||||
* @param none
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void performPeriodicTask(void)
|
||||
{
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn OTA_IAP_SendData
|
||||
*
|
||||
* @brief OTA IAP发送数据,使用时限制20字节以内
|
||||
*
|
||||
* @param p_send_data - 发送数据的指针
|
||||
* @param send_len - 发送数据的长度
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void OTA_IAP_SendData(uint8_t *p_send_data, uint8_t send_len)
|
||||
{
|
||||
OTAProfile_SendData(OTAPROFILE_CHAR, p_send_data, send_len);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn OTA_IAP_SendCMDDealSta
|
||||
*
|
||||
* @brief OTA IAP执行的状态返回
|
||||
*
|
||||
* @param deal_status - 返回的状态
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void OTA_IAP_SendCMDDealSta(uint8_t deal_status)
|
||||
{
|
||||
uint8_t send_buf[2];
|
||||
|
||||
send_buf[0] = deal_status;
|
||||
send_buf[1] = 0;
|
||||
OTA_IAP_SendData(send_buf, 2);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn OTA_IAP_CMDErrDeal
|
||||
*
|
||||
* @brief OTA IAP异常命令码处理
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void OTA_IAP_CMDErrDeal(void)
|
||||
{
|
||||
OTA_IAP_SendCMDDealSta(0xfe);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SwitchImageFlag
|
||||
*
|
||||
* @brief 切换dataflash里的ImageFlag
|
||||
*
|
||||
* @param new_flag - 切换的ImageFlag
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void SwitchImageFlag(uint8_t new_flag)
|
||||
{
|
||||
uint16_t i;
|
||||
uint32_t ver_flag;
|
||||
|
||||
/* 读取第一块 */
|
||||
EEPROM_READ(OTA_DATAFLASH_ADD, (uint32_t *)&block_buf[0], 4);
|
||||
|
||||
/* 擦除第一块 */
|
||||
EEPROM_ERASE(OTA_DATAFLASH_ADD, EEPROM_PAGE_SIZE);
|
||||
|
||||
/* 更新Image信息 */
|
||||
block_buf[0] = new_flag;
|
||||
|
||||
/* 编程DataFlash */
|
||||
EEPROM_WRITE(OTA_DATAFLASH_ADD, (uint32_t *)&block_buf[0], 4);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn DisableAllIRQ
|
||||
*
|
||||
* @brief 关闭所有的中断
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void DisableAllIRQ(void)
|
||||
{
|
||||
SYS_DisableAllIrq(NULL);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn Rec_OTA_IAP_DataDeal
|
||||
*
|
||||
* @brief 接收到OTA数据包处理
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void Rec_OTA_IAP_DataDeal(void)
|
||||
{
|
||||
switch(iap_rec_data.other.buf[0])
|
||||
{
|
||||
/* 编程 */
|
||||
case CMD_IAP_PROM:
|
||||
{
|
||||
uint32_t i;
|
||||
uint8_t status;
|
||||
|
||||
OpParaDataLen = iap_rec_data.program.len;
|
||||
OpAdd = (uint32_t)(iap_rec_data.program.addr[0]);
|
||||
OpAdd |= ((uint32_t)(iap_rec_data.program.addr[1]) << 8);
|
||||
OpAdd = OpAdd * 16;
|
||||
|
||||
PRINT("IAP_PROM: %08x len:%d \r\n", (int)OpAdd, (int)OpParaDataLen);
|
||||
|
||||
/* 当前是ImageA,直接编程 */
|
||||
status = FLASH_ROM_WRITE(OpAdd, iap_rec_data.program.buf, (uint16_t)OpParaDataLen);
|
||||
OTA_IAP_SendCMDDealSta(status);
|
||||
break;
|
||||
}
|
||||
/* 擦除 -- 蓝牙擦除由主机控制 */
|
||||
case CMD_IAP_ERASE:
|
||||
{
|
||||
OpAdd = (uint32_t)(iap_rec_data.erase.addr[0]);
|
||||
OpAdd |= ((uint32_t)(iap_rec_data.erase.addr[1]) << 8);
|
||||
OpAdd = OpAdd * 16;
|
||||
|
||||
EraseBlockNum = (uint32_t)(iap_rec_data.erase.block_num[0]);
|
||||
EraseBlockNum |= ((uint32_t)(iap_rec_data.erase.block_num[1]) << 8);
|
||||
EraseAdd = OpAdd;
|
||||
EraseBlockCnt = 0;
|
||||
|
||||
/* 检验就放在擦除里清0 */
|
||||
VerifyStatus = 0;
|
||||
|
||||
PRINT("IAP_ERASE start:%08x num:%d\r\n", (int)OpAdd, (int)EraseBlockNum);
|
||||
|
||||
if(EraseAdd < IMAGE_A_START_ADD || (EraseAdd + (EraseBlockNum - 1) * FLASH_BLOCK_SIZE) > IMAGE_B_START_ADD)
|
||||
{
|
||||
OTA_IAP_SendCMDDealSta(0xFF);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* 修改DataFlash,切换至ImageB */
|
||||
SwitchImageFlag(IMAGE_B_FLAG);
|
||||
|
||||
/* 启动擦除 */
|
||||
tmos_set_event(Peripheral_TaskID, OTA_FLASH_ERASE_EVT);
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* 校验 */
|
||||
case CMD_IAP_VERIFY:
|
||||
{
|
||||
uint32_t i;
|
||||
uint8_t status = 0;
|
||||
|
||||
OpParaDataLen = iap_rec_data.verify.len;
|
||||
|
||||
OpAdd = (uint32_t)(iap_rec_data.verify.addr[0]);
|
||||
OpAdd |= ((uint32_t)(iap_rec_data.verify.addr[1]) << 8);
|
||||
OpAdd = OpAdd * 16;
|
||||
|
||||
PRINT("IAP_VERIFY: %08x len:%d \r\n", (int)OpAdd, (int)OpParaDataLen);
|
||||
|
||||
status = FLASH_ROM_VERIFY(OpAdd, iap_rec_data.verify.buf, OpParaDataLen);
|
||||
VerifyStatus |= status;
|
||||
OTA_IAP_SendCMDDealSta(VerifyStatus);
|
||||
break;
|
||||
}
|
||||
/* 编程结束 */
|
||||
case CMD_IAP_END:
|
||||
{
|
||||
PRINT("IAP_END \r\n");
|
||||
|
||||
/* 关闭当前所有使用中断,或者方便一点直接全部关闭 */
|
||||
DisableAllIRQ();
|
||||
|
||||
/* 修改DataFlash,切换至ImageA */
|
||||
SwitchImageFlag(IMAGE_A_FLAG);
|
||||
|
||||
/* 等待打印完成 ,跳转ImageB*/
|
||||
mDelaymS(10);
|
||||
jumpApp();
|
||||
|
||||
/* 不会执行到这 */
|
||||
SYS_ResetExecute();
|
||||
|
||||
break;
|
||||
}
|
||||
case CMD_IAP_INFO:
|
||||
{
|
||||
uint8_t send_buf[20];
|
||||
|
||||
PRINT("IAP_INFO \r\n");
|
||||
|
||||
/* IMAGE FLAG */
|
||||
send_buf[0] = IMAGE_B_FLAG;
|
||||
|
||||
/* IMAGE_B_START_ADD */
|
||||
send_buf[1] = (uint8_t)(IMAGE_B_START_ADD & 0xff);
|
||||
send_buf[2] = (uint8_t)((IMAGE_B_START_ADD >> 8) & 0xff);
|
||||
send_buf[3] = (uint8_t)((IMAGE_B_START_ADD >> 16) & 0xff);
|
||||
send_buf[4] = (uint8_t)((IMAGE_B_START_ADD >> 24) & 0xff);
|
||||
|
||||
/* BLOCK SIZE */
|
||||
send_buf[5] = (uint8_t)(FLASH_BLOCK_SIZE & 0xff);
|
||||
send_buf[6] = (uint8_t)((FLASH_BLOCK_SIZE >> 8) & 0xff);
|
||||
|
||||
send_buf[7] = CHIP_ID&0xFF;
|
||||
send_buf[8] = (CHIP_ID>>8)&0xFF;
|
||||
/* 有需要再增加 */
|
||||
|
||||
/* 发送信息 */
|
||||
OTA_IAP_SendData(send_buf, 20);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
OTA_IAP_CMDErrDeal();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn OTA_IAPReadDataComplete
|
||||
*
|
||||
* @brief OTA 数据读取完成处理
|
||||
*
|
||||
* @param index - OTA 通道序号
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void OTA_IAPReadDataComplete(unsigned char index)
|
||||
{
|
||||
PRINT("OTA Send Comp \r\n");
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn OTA_IAPWriteData
|
||||
*
|
||||
* @brief OTA 通道数据接收完成处理
|
||||
*
|
||||
* @param index - OTA 通道序号
|
||||
* @param p_data - 写入的数据
|
||||
* @param w_len - 写入的长度
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void OTA_IAPWriteData(unsigned char index, unsigned char *p_data, unsigned char w_len)
|
||||
{
|
||||
unsigned char rec_len;
|
||||
unsigned char *rec_data;
|
||||
|
||||
rec_len = w_len;
|
||||
rec_data = p_data;
|
||||
tmos_memcpy((unsigned char *)&iap_rec_data, rec_data, rec_len);
|
||||
Rec_OTA_IAP_DataDeal();
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*********************************************************************/
|
||||
@@ -0,0 +1,132 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : main.c
|
||||
* Author : WCH
|
||||
* Version : V1.1
|
||||
* Date : 2019/11/05
|
||||
* Description : 升级从机应用主函数及任务系统初始化
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
|
||||
/******************************************************************************/
|
||||
/* 头文件包含 */
|
||||
#include "CONFIG.h"
|
||||
#include "HAL.h"
|
||||
#include "Peripheral.h"
|
||||
#include "OTA.h"
|
||||
#include "OTAprofile.h"
|
||||
|
||||
/* 记录当前的Image */
|
||||
unsigned char CurrImageFlag = 0xff;
|
||||
|
||||
/*********************************************************************
|
||||
* GLOBAL TYPEDEFS
|
||||
*/
|
||||
__attribute__((aligned(4))) uint32_t MEM_BUF[BLE_MEMHEAP_SIZE / 4];
|
||||
|
||||
#if(defined(BLE_MAC)) && (BLE_MAC == TRUE)
|
||||
const uint8_t MacAddr[6] = {0x84, 0xC2, 0xE4, 0x03, 0x02, 0x02};
|
||||
#endif
|
||||
|
||||
/* 注意:关于程序升级后flash的操作必须先执行,不开启任何中断,防止操作中断和失败 */
|
||||
/*********************************************************************
|
||||
* @fn ReadImageFlag
|
||||
*
|
||||
* @brief 读取当前的程序的Image标志,DataFlash如果为空,就默认是ImageA,如果为ImageA,则跳转ImageA
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void ReadImageFlag(void)
|
||||
{
|
||||
OTADataFlashInfo_t p_image_flash;
|
||||
|
||||
EEPROM_READ(OTA_DATAFLASH_ADD, &p_image_flash, 4);
|
||||
CurrImageFlag = p_image_flash.ImageFlag;
|
||||
|
||||
/* 程序第一次执行,或者没有更新过,以后更新后在擦除DataFlash */
|
||||
if((CurrImageFlag != IMAGE_B_FLAG) && (CurrImageFlag != IMAGE_A_FLAG) && (CurrImageFlag != IMAGE_OTA_FLAG))
|
||||
{
|
||||
CurrImageFlag = IMAGE_A_FLAG;
|
||||
}
|
||||
|
||||
PRINT("Image Flag %02x\n", CurrImageFlag);
|
||||
|
||||
if(CurrImageFlag == IMAGE_A_FLAG)
|
||||
{
|
||||
PRINT("jump App \n");
|
||||
mDelaymS(5);
|
||||
jumpApp();
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn Main_Circulation
|
||||
*
|
||||
* @brief 主循环
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
__HIGH_CODE
|
||||
__attribute__((noinline))
|
||||
void Main_Circulation()
|
||||
{
|
||||
while(1)
|
||||
{
|
||||
TMOS_SystemProcess();
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn main
|
||||
*
|
||||
* @brief 主函数
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
int main(void)
|
||||
{
|
||||
#if(defined(DCDC_ENABLE)) && (DCDC_ENABLE == TRUE)
|
||||
PWR_DCDCCfg(ENABLE);
|
||||
#endif
|
||||
SetSysClock(CLK_SOURCE_PLL_60MHz);
|
||||
#if(defined(HAL_SLEEP)) && (HAL_SLEEP == TRUE)
|
||||
GPIOA_ModeCfg(GPIO_Pin_All, GPIO_ModeIN_PU);
|
||||
GPIOB_ModeCfg(GPIO_Pin_All, GPIO_ModeIN_PU);
|
||||
#endif
|
||||
#ifdef DEBUG
|
||||
// GPIOA_SetBits(bTXD1);
|
||||
// GPIOA_ModeCfg(bTXD1, GPIO_ModeOut_PP_5mA);
|
||||
// UART1_DefInit();
|
||||
#endif
|
||||
/* 配置串口0:先配置IO口模式,再配置串口 */
|
||||
GPIOPinRemap(ENABLE, RB_PIN_UART0);
|
||||
GPIOA_SetBits(GPIO_Pin_14);
|
||||
GPIOA_ModeCfg(GPIO_Pin_15, GPIO_ModeIN_PU); // RXD-配置上拉输入
|
||||
GPIOA_ModeCfg(GPIO_Pin_14, GPIO_ModeOut_PP_5mA); // TXD-配置推挽输出,注意先让IO口输出高电平
|
||||
UART0_DefInit();
|
||||
|
||||
PRINT("%s\n", VER_LIB);
|
||||
ReadImageFlag();
|
||||
if((R8_RESET_STATUS & RB_RESET_FLAG) == RST_FLAG_SW)
|
||||
{
|
||||
// 软复位不跳APP
|
||||
}
|
||||
else
|
||||
{
|
||||
if(CurrImageFlag == IMAGE_OTA_FLAG)
|
||||
{
|
||||
PRINT("jump App \n");
|
||||
mDelaymS(5);
|
||||
jumpApp();
|
||||
}
|
||||
}
|
||||
CH59x_BLEInit();
|
||||
HAL_Init();
|
||||
GAPRole_PeripheralInit();
|
||||
Peripheral_Init();
|
||||
Main_Circulation();
|
||||
}
|
||||
|
||||
/******************************** endfile @ main ******************************/
|
||||
Reference in New Issue
Block a user