peripheral.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851
  1. /********************************** (C) COPYRIGHT *******************************
  2. * File Name : Peripheral.C
  3. * Author : WCH
  4. * Version : V1.0
  5. * Date : 2018/12/10
  6. * Description : Peripheral slave multi-connection application, initialize
  7. * broadcast connection parameters, then broadcast, after connecting
  8. * to the host, request to update connection parameters,
  9. * and transmit data through custom services.
  10. *********************************************************************************
  11. * Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
  12. * Attention: This software (modified or not) and binary are used for
  13. * microcontroller manufactured by Nanjing Qinheng Microelectronics.
  14. *******************************************************************************/
  15. /*********************************************************************
  16. * INCLUDES
  17. */
  18. #include "CONFIG.h"
  19. #include "GATTprofile.h"
  20. #include "Peripheral.h"
  21. #include "OTA.h"
  22. #include "OTAprofile.h"
  23. #include "led.h"
  24. #include "user_upgrade.h"
  25. /*********************************************************************
  26. * MACROS
  27. */
  28. /*********************************************************************
  29. * CONSTANTS
  30. */
  31. // How often to perform periodic event
  32. #define SBP_PERIODIC_EVT_PERIOD 1000
  33. // What is the advertising interval when device is discoverable (units of 625us, 32=20ms)
  34. #define DEFAULT_ADVERTISING_INTERVAL 32
  35. // Limited discoverable mode advertises for 30.72s, and then stops
  36. // General discoverable mode advertises indefinitely
  37. #define DEFAULT_DISCOVERABLE_MODE GAP_ADTYPE_FLAGS_GENERAL
  38. // Minimum connection interval (units of 1.25ms, 6=7.5ms) if automatic parameter update request is enabled
  39. #define DEFAULT_DESIRED_MIN_CONN_INTERVAL 6
  40. // Maximum connection interval (units of 1.25ms, 12=15ms) if automatic parameter update request is enabled
  41. #define DEFAULT_DESIRED_MAX_CONN_INTERVAL 12
  42. // Slave latency to use if automatic parameter update request is enabled
  43. #define DEFAULT_DESIRED_SLAVE_LATENCY 0
  44. // Supervision timeout value (units of 10ms, 1000=10s) if automatic parameter update request is enabled
  45. #define DEFAULT_DESIRED_CONN_TIMEOUT 1000
  46. // Whether to enable automatic parameter update request when a connection is formed
  47. #define DEFAULT_ENABLE_UPDATE_REQUEST TRUE
  48. // Connection Pause Peripheral time value (in seconds)
  49. #define DEFAULT_CONN_PAUSE_PERIPHERAL 6
  50. // Company Identifier: WCH
  51. #define WCH_COMPANY_ID 0x07D7
  52. #define INVALID_CONNHANDLE 0xFFFF
  53. // Length of bd addr as a string
  54. #define B_ADDR_STR_LEN 15
  55. /*********************************************************************
  56. * TYPEDEFS
  57. */
  58. /*********************************************************************
  59. * GLOBAL VARIABLES
  60. */
  61. /*********************************************************************
  62. * EXTERNAL VARIABLES
  63. */
  64. /*********************************************************************
  65. * EXTERNAL FUNCTIONS
  66. */
  67. /*********************************************************************
  68. * LOCAL VARIABLES
  69. */
  70. static uint8_t Peripheral_TaskID = INVALID_TASK_ID; // Task ID for internal task/event processing
  71. // GAP - SCAN RSP data (max size = 31 bytes)
  72. static uint8_t scanRspData[31] = {
  73. // complete name
  74. 0x0D, // length of this data
  75. GAP_ADTYPE_LOCAL_NAME_COMPLETE,
  76. 'L', 'O', 'C', 'K', 'B', 'A', 'S', 'E', '_', 'O', 'T', 'A',
  77. // connection interval range
  78. 0x05, // length of this data
  79. GAP_ADTYPE_SLAVE_CONN_INTERVAL_RANGE,
  80. LO_UINT16(DEFAULT_DESIRED_MIN_CONN_INTERVAL), // 100ms
  81. HI_UINT16(DEFAULT_DESIRED_MIN_CONN_INTERVAL),
  82. LO_UINT16(DEFAULT_DESIRED_MAX_CONN_INTERVAL), // 1s
  83. HI_UINT16(DEFAULT_DESIRED_MAX_CONN_INTERVAL),
  84. // Tx power level
  85. 0x02, // length of this data
  86. GAP_ADTYPE_POWER_LEVEL,
  87. 0 // 0dBm
  88. };
  89. // GAP - Advertisement data (max size = 31 bytes, though this is
  90. // best kept short to conserve power while advertisting)
  91. static uint8_t advertData[] = {
  92. // Flags; this sets the device to use limited discoverable
  93. // mode (advertises for 30 seconds at a time) instead of general
  94. // discoverable mode (advertises indefinitely)
  95. 0x02, // length of this data
  96. GAP_ADTYPE_FLAGS,
  97. DEFAULT_DISCOVERABLE_MODE | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,
  98. // service UUID, to notify central devices what services are included
  99. // in this peripheral
  100. 0x03, // length of this data
  101. GAP_ADTYPE_16BIT_MORE, // some of the UUID's, but not all
  102. LO_UINT16(SIMPLEPROFILE_SERV_UUID),
  103. HI_UINT16(SIMPLEPROFILE_SERV_UUID)
  104. };
  105. // GAP GATT Attributes
  106. static uint8_t attDeviceName[GAP_DEVICE_NAME_LEN] = "LOCKBASE_OTA";
  107. // OTA IAP VARIABLES
  108. /* OTA communication frame */
  109. OTA_IAP_CMD_t iap_rec_data;
  110. /* OTA analysis results */
  111. uint32_t OpParaDataLen = 0;
  112. uint32_t OpAdd = 0;
  113. uint16_t block_buf_len=0;
  114. uint32_t prom_addr=0;
  115. /* Flash data temporary storage */
  116. __attribute__((aligned(8))) uint8_t block_buf[512];
  117. /* IMAGE jump function address definition */
  118. typedef int (*pImageTaskFn)(void);
  119. pImageTaskFn user_image_tasks;
  120. /* Flash erase */
  121. uint32_t EraseAdd = 0; //Removal address
  122. uint32_t EraseBlockNum = 0; //Number of blocks that need to be erased
  123. uint32_t EraseBlockCnt = 0; //Scratching block count
  124. /* FLASH verification status */
  125. uint8_t VerifyStatus = 0;
  126. /*********************************************************************
  127. * LOCAL FUNCTIONS
  128. */
  129. static void Peripheral_ProcessTMOSMsg(tmos_event_hdr_t *pMsg);
  130. static void peripheralStateNotificationCB(gapRole_States_t newState, gapRoleEvent_t *pEvent);
  131. static void performPeriodicTask(void);
  132. void OTA_IAPReadDataComplete(unsigned char index);
  133. void OTA_IAPWriteData(unsigned char index, unsigned char *p_data, unsigned char w_len);
  134. void Rec_OTA_IAP_DataDeal(void);
  135. void OTA_IAP_SendCMDDealSta(uint8_t deal_status);
  136. /*********************************************************************
  137. * PROFILE CALLBACKS
  138. */
  139. // GAP Role Callbacks
  140. static gapRolesCBs_t Peripheral_PeripheralCBs = {
  141. peripheralStateNotificationCB, // Profile State Change Callbacks
  142. NULL, // When a valid RSSI is read from controller (not used by application)
  143. NULL};
  144. // GAP Bond Manager Callbacks
  145. static gapBondCBs_t Peripheral_BondMgrCBs = {
  146. NULL, // Passcode callback (not used by application)
  147. NULL // Pairing / Bonding state Callback (not used by application)
  148. };
  149. // Simple GATT Profile Callbacks
  150. static OTAProfileCBs_t Peripheral_OTA_IAPProfileCBs = {
  151. OTA_IAPReadDataComplete, // Charactersitic value change callback
  152. OTA_IAPWriteData};
  153. // Callback when the connection parameteres are updated.
  154. void PeripheralParamUpdate(uint16_t connInterval, uint16_t connSlaveLatency, uint16_t connTimeout);
  155. gapRolesParamUpdateCB_t PeripheralParamUpdate_t = NULL;
  156. /*********************************************************************
  157. * PUBLIC FUNCTIONS
  158. */
  159. /*********************************************************************
  160. * @fn Peripheral_Init
  161. *
  162. * @brief Initialization function for the Peripheral App Task.
  163. * This is called during initialization and should contain
  164. * any application specific initialization (ie. hardware
  165. * initialization/setup, table initialization, power up
  166. * notificaiton ... ).
  167. *
  168. * @param task_id - the ID assigned by TMOS. This ID should be
  169. * used to send messages and set timers.
  170. *
  171. * @return none
  172. */
  173. void Peripheral_Init()
  174. {
  175. Peripheral_TaskID = TMOS_ProcessEventRegister(Peripheral_ProcessEvent);
  176. // Setup the GAP Peripheral Role Profile
  177. {
  178. // For other hardware platforms, device starts advertising upon initialization
  179. uint8_t initial_advertising_enable = TRUE;
  180. // Set the GAP Role Parameters
  181. GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t), &initial_advertising_enable);
  182. GAPRole_SetParameter(GAPROLE_SCAN_RSP_DATA, sizeof(scanRspData), scanRspData);
  183. GAPRole_SetParameter(GAPROLE_ADVERT_DATA, sizeof(advertData), advertData);
  184. }
  185. // Set advertising interval
  186. {
  187. uint16_t advInt = DEFAULT_ADVERTISING_INTERVAL;
  188. GAP_SetParamValue(TGAP_DISC_ADV_INT_MIN, advInt);
  189. GAP_SetParamValue(TGAP_DISC_ADV_INT_MAX, advInt);
  190. }
  191. // Initialize GATT attributes
  192. GGS_AddService(GATT_ALL_SERVICES); // GAP
  193. GATTServApp_AddService(GATT_ALL_SERVICES); // GATT attributes
  194. OTAProfile_AddService(GATT_ALL_SERVICES);
  195. // Set the GAP Characteristics
  196. GGS_SetParameter(GGS_DEVICE_NAME_ATT, GAP_DEVICE_NAME_LEN, attDeviceName);
  197. // Register callback with OTAGATTprofile
  198. OTAProfile_RegisterAppCBs(&Peripheral_OTA_IAPProfileCBs);
  199. // Setup a delayed profile startup
  200. tmos_set_event(Peripheral_TaskID, SBP_START_DEVICE_EVT);
  201. }
  202. void PeripheralParamUpdate(uint16_t connInterval, uint16_t connSlaveLatency, uint16_t connTimeout)
  203. {
  204. PRINT("update %d %d %d \n", connInterval, connSlaveLatency, connTimeout);
  205. // GAPRole_SendUpdateParam( DEFAULT_DESIRED_MIN_CONN_INTERVAL, DEFAULT_DESIRED_MAX_CONN_INTERVAL,
  206. // DEFAULT_DESIRED_SLAVE_LATENCY, DEFAULT_DESIRED_CONN_TIMEOUT, GAPROLE_NO_ACTION );
  207. }
  208. /*********************************************************************
  209. * @fn Peripheral_ProcessEvent
  210. *
  211. * @brief Peripheral Application Task event processor. This function
  212. * is called to process all events for the task. Events
  213. * include timers, messages and any other user defined events.
  214. *
  215. * @param task_id - The TMOS assigned task ID.
  216. * @param events - events to process. This is a bit map and can
  217. * contain more than one event.
  218. *
  219. * @return events not processed
  220. */
  221. uint16_t Peripheral_ProcessEvent(uint8_t task_id, uint16_t events)
  222. {
  223. // VOID task_id; // TMOS required parameter that isn't used in this function
  224. if(events & SYS_EVENT_MSG)
  225. {
  226. uint8_t *pMsg;
  227. if((pMsg = tmos_msg_receive(Peripheral_TaskID)) != NULL)
  228. {
  229. Peripheral_ProcessTMOSMsg((tmos_event_hdr_t *)pMsg);
  230. // Release the TMOS message
  231. tmos_msg_deallocate(pMsg);
  232. }
  233. // return unprocessed events
  234. return (events ^ SYS_EVENT_MSG);
  235. }
  236. if(events & SBP_START_DEVICE_EVT)
  237. {
  238. // Start the Device
  239. GAPRole_PeripheralStartDevice(Peripheral_TaskID, &Peripheral_BondMgrCBs, &Peripheral_PeripheralCBs);
  240. // Set timer for first periodic event
  241. tmos_start_task(Peripheral_TaskID, SBP_PERIODIC_EVT, SBP_PERIODIC_EVT_PERIOD);
  242. return (events ^ SBP_START_DEVICE_EVT);
  243. }
  244. if(events & SBP_PERIODIC_EVT)
  245. {
  246. // Restart timer
  247. if(SBP_PERIODIC_EVT_PERIOD)
  248. {
  249. tmos_start_task(Peripheral_TaskID, SBP_PERIODIC_EVT, SBP_PERIODIC_EVT_PERIOD);
  250. }
  251. // Perform periodic application task
  252. performPeriodicTask();
  253. return (events ^ SBP_PERIODIC_EVT);
  254. }
  255. //OTA_FLASH_ERASE_EVT
  256. if(events & OTA_FLASH_ERASE_EVT)
  257. {
  258. uint8_t status;
  259. PRINT("ERASE:%08x num:%d\r\n", (int)(EraseAdd + EraseBlockCnt * FLASH_BLOCK_SIZE), (int)EraseBlockCnt);
  260. FLASH_Unlock();
  261. status = FLASH_ErasePage(EraseAdd + EraseBlockCnt * FLASH_BLOCK_SIZE);
  262. FLASH_Lock();
  263. /* Erase failed */
  264. if(status != FLASH_COMPLETE)
  265. {
  266. OTA_IAP_SendCMDDealSta(status);
  267. return (events ^ OTA_FLASH_ERASE_EVT);
  268. }
  269. EraseBlockCnt++;
  270. /* End of erasing */
  271. if(EraseBlockCnt >= EraseBlockNum)
  272. {
  273. PRINT("ERASE Complete\r\n");
  274. OTA_IAP_SendCMDDealSta(SUCCESS);
  275. return (events ^ OTA_FLASH_ERASE_EVT);
  276. }
  277. return (events);
  278. }
  279. // Discard unknown events
  280. return 0;
  281. }
  282. /*********************************************************************
  283. * @fn Peripheral_ProcessTMOSMsg
  284. *
  285. * @brief Process an incoming task message.
  286. *
  287. * @param pMsg - message to process
  288. *
  289. * @return none
  290. */
  291. static void Peripheral_ProcessTMOSMsg(tmos_event_hdr_t *pMsg)
  292. {
  293. switch(pMsg->event)
  294. {
  295. default:
  296. break;
  297. }
  298. }
  299. /*********************************************************************
  300. * @fn peripheralStateNotificationCB
  301. *
  302. * @brief Notification from the profile of a state change.
  303. *
  304. * @param newState - new state
  305. *
  306. * @return none
  307. */
  308. static void peripheralStateNotificationCB(gapRole_States_t newState, gapRoleEvent_t *pEvent)
  309. {
  310. switch(newState & GAPROLE_STATE_ADV_MASK)
  311. {
  312. case GAPROLE_STARTED:
  313. PRINT("Initialized..\n");
  314. break;
  315. case GAPROLE_ADVERTISING:
  316. PRINT("Advertising..\n");
  317. break;
  318. case GAPROLE_CONNECTED:
  319. {
  320. gapEstLinkReqEvent_t *event = (gapEstLinkReqEvent_t *)pEvent;
  321. uint16_t conn_interval = 0;
  322. conn_interval = event->connInterval;
  323. PRINT("Connected.. \n");
  324. ota_timeout_task_start(false);
  325. if(conn_interval > DEFAULT_DESIRED_MAX_CONN_INTERVAL)
  326. {
  327. PRINT("Send Update\r\n");
  328. GAPRole_PeripheralConnParamUpdateReq(event->connectionHandle,
  329. DEFAULT_DESIRED_MIN_CONN_INTERVAL,
  330. DEFAULT_DESIRED_MAX_CONN_INTERVAL,
  331. DEFAULT_DESIRED_SLAVE_LATENCY,
  332. DEFAULT_DESIRED_CONN_TIMEOUT,
  333. Peripheral_TaskID);
  334. }
  335. break;
  336. }
  337. case GAPROLE_CONNECTED_ADV:
  338. PRINT("Connected Advertising..\n");
  339. break;
  340. case GAPROLE_WAITING:
  341. {
  342. uint8_t initial_advertising_enable = TRUE;
  343. // Set the GAP Role Parameters
  344. GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t), &initial_advertising_enable);
  345. PRINT("Disconnected..\n");
  346. ota_timeout_task_start(true);
  347. }
  348. break;
  349. case GAPROLE_ERROR:
  350. PRINT("Error..\n");
  351. break;
  352. default:
  353. break;
  354. }
  355. }
  356. /*********************************************************************
  357. * @fn performPeriodicTask
  358. *
  359. * @brief Perform a periodic application task. This function gets
  360. * called every five seconds as a result of the SBP_PERIODIC_EVT
  361. * TMOS event. In this example, the value of the third
  362. * characteristic in the SimpleGATTProfile service is retrieved
  363. * from the profile, and then copied into the value of the
  364. * the fourth characteristic.
  365. *
  366. * @param none
  367. *
  368. * @return none
  369. */
  370. static void performPeriodicTask(void)
  371. {
  372. }
  373. /*********************************************************************
  374. * @fn OTA_IAP_SendData
  375. *
  376. * @brief OTA IAP sends data, limits within 20 bytes when used
  377. *
  378. * @param p_send_data - Poems of sending data
  379. * @param send_len - Send data length
  380. *
  381. * @return none
  382. */
  383. void OTA_IAP_SendData(uint8_t *p_send_data, uint8_t send_len)
  384. {
  385. OTAProfile_SendData(OTAPROFILE_CHAR, p_send_data, send_len);
  386. }
  387. /*********************************************************************
  388. * @fn OTA_IAP_SendCMDDealSta
  389. *
  390. * @brief OTA IAP execution status returns
  391. *
  392. * @param deal_status - Return state
  393. *
  394. * @return none
  395. */
  396. void OTA_IAP_SendCMDDealSta(uint8_t deal_status)
  397. {
  398. uint8_t send_buf[2];
  399. send_buf[0] = deal_status;
  400. send_buf[1] = 0;
  401. OTA_IAP_SendData(send_buf, 2);
  402. }
  403. /*********************************************************************
  404. * @fn OTA_IAP_CMDErrDeal
  405. *
  406. * @brief OTA IAP abnormal command code processing
  407. *
  408. * @return none
  409. */
  410. void OTA_IAP_CMDErrDeal(void)
  411. {
  412. OTA_IAP_SendCMDDealSta(0xfe);
  413. }
  414. /*********************************************************************
  415. * @fn SwitchImageFlag
  416. *
  417. * @brief Switch the ImageFlag in DataFlash
  418. *
  419. * @param new_flag - Switching ImageFlag
  420. *
  421. * @return none
  422. */
  423. void SwitchImageFlag(uint8_t new_flag)
  424. {
  425. uint16_t i;
  426. uint32_t ver_flag;
  427. /* Read the first block */
  428. FLASH_read(OTA_DATAFLASH_ADDR, &block_buf[0], 4);
  429. FLASH_Unlock_Fast();
  430. /* Erase the first block */
  431. FLASH_ErasePage_Fast(OTA_DATAFLASH_ADDR);
  432. /* Update Image information */
  433. block_buf[0] = new_flag;
  434. block_buf[1] = IMAGE_FLAG_1;
  435. block_buf[2] = IMAGE_FLAG_2;
  436. block_buf[3] = IMAGE_FLAG_3;
  437. /* Program DataFlash */
  438. FLASH_ProgramPage_Fast( OTA_DATAFLASH_ADDR, (uint32_t *)&block_buf[0]);
  439. FLASH_Lock_Fast();
  440. }
  441. /*********************************************************************
  442. * @fn DisableAllIRQ
  443. *
  444. * @brief Turn off all the interrupts
  445. *
  446. * @return none
  447. */
  448. void DisableAllIRQ(void)
  449. {
  450. __disable_irq();
  451. }
  452. /*********************************************************************
  453. * @fn IWDG_Init
  454. *
  455. * @brief Initializes IWDG.
  456. *
  457. * @param IWDG_Prescaler: specifies the IWDG Prescaler value.
  458. * IWDG_Prescaler_4: IWDG prescaler set to 4.
  459. * IWDG_Prescaler_8: IWDG prescaler set to 8.
  460. * IWDG_Prescaler_16: IWDG prescaler set to 16.
  461. * IWDG_Prescaler_32: IWDG prescaler set to 32.
  462. * IWDG_Prescaler_64: IWDG prescaler set to 64.
  463. * IWDG_Prescaler_128: IWDG prescaler set to 128.
  464. * IWDG_Prescaler_256: IWDG prescaler set to 256.
  465. * Reload: specifies the IWDG Reload value.
  466. * This parameter must be a number between 0 and 0x0FFF.
  467. *
  468. * @return none
  469. */
  470. void IWDG_Feed_Init(uint16_t prer, uint16_t rlr)
  471. {
  472. IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
  473. IWDG_SetPrescaler(prer);
  474. IWDG_SetReload(rlr);
  475. IWDG_ReloadCounter();
  476. IWDG_Enable();
  477. }
  478. void app_start(void)
  479. {
  480. IWDG_Feed_Init(IWDG_Prescaler_32, 4000);
  481. jumpApp();
  482. }
  483. /*********************************************************************
  484. * @fn FLASH_read
  485. *
  486. * @brief Read flash
  487. *
  488. * @return none
  489. */
  490. void IAP_FLASH_read(uint32_t addr, uint8_t *pData, uint32_t len)
  491. {
  492. uint32_t i;
  493. for(i=0;i<len;i++)
  494. {
  495. *pData++ = *(uint8_t*)addr++;
  496. }
  497. }
  498. //static void user_ota_finish(void)
  499. //{
  500. // uint32_t addr = USER_OTA_ADDR * FLASH_SECTOR_SIZE;
  501. //
  502. // upgrade_ota_s upgrade_ota;
  503. // upgrade_ota.flag = IMAGE_A_FLAG;
  504. //
  505. // Flash_Write((uint8_t *)&upgrade_ota, addr, sizeof(upgrade_ota_s));
  506. //}
  507. /*********************************************************************
  508. * @fn Rec_OTA_IAP_DataDeal
  509. *
  510. * @brief Receive OTA packet processing
  511. *
  512. * @return none
  513. */
  514. void Rec_OTA_IAP_DataDeal(void)
  515. {
  516. switch(iap_rec_data.other.buf[0])
  517. {
  518. /* Programming */
  519. case CMD_IAP_PROM:
  520. {
  521. uint32_t i;
  522. uint8_t status;
  523. OpParaDataLen = iap_rec_data.program.len;
  524. OpAdd = (uint32_t)(iap_rec_data.program.addr[0]);
  525. OpAdd |= ((uint32_t)(iap_rec_data.program.addr[1]) << 8);
  526. OpAdd = OpAdd * 16;
  527. PRINT("IAP_PROM: %08x len:%d \r\n", (int)OpAdd, (int)OpParaDataLen);
  528. /* Current is ImageA, programming directly */
  529. tmos_memcpy(&block_buf[block_buf_len], iap_rec_data.program.buf, OpParaDataLen);
  530. block_buf_len += OpParaDataLen;
  531. if( block_buf_len >= FLASH_PAGE_SIZE )
  532. {
  533. FLASH_Unlock_Fast();
  534. FLASH_ProgramPage_Fast(prom_addr, (uint32_t*)block_buf);
  535. FLASH_Lock_Fast();
  536. tmos_memcpy(block_buf, &block_buf[FLASH_PAGE_SIZE], block_buf_len-FLASH_PAGE_SIZE);
  537. block_buf_len -= FLASH_PAGE_SIZE;
  538. prom_addr+=FLASH_PAGE_SIZE;
  539. }
  540. OTA_IAP_SendCMDDealSta(status);
  541. break;
  542. }
  543. /* Erase -- Bluetooth erase is controlled by the host */
  544. case CMD_IAP_ERASE:
  545. {
  546. OpAdd = (uint32_t)(iap_rec_data.erase.addr[0]);
  547. OpAdd |= ((uint32_t)(iap_rec_data.erase.addr[1]) << 8);
  548. OpAdd = OpAdd * 16;
  549. OpAdd += 0x08000000;
  550. EraseBlockNum = (uint32_t)(iap_rec_data.erase.block_num[0]);
  551. EraseBlockNum |= ((uint32_t)(iap_rec_data.erase.block_num[1]) << 8);
  552. EraseAdd = OpAdd;
  553. EraseBlockCnt = 0;
  554. /* The inspection is placed in the era of clearing 0 */
  555. VerifyStatus = 0;
  556. prom_addr = IMAGE_A_START_ADD;
  557. PRINT("IAP_ERASE start:%08x num:%d\r\n", (int)OpAdd, (int)EraseBlockNum);
  558. if(EraseAdd < IMAGE_A_START_ADD || (EraseAdd + (EraseBlockNum - 1) * FLASH_BLOCK_SIZE) > (IMAGE_A_START_ADD + IMAGE_A_SIZE))
  559. {
  560. OTA_IAP_SendCMDDealSta(0xFF);
  561. }
  562. else
  563. {
  564. /* Modify DataFlash, switch to ImageB */
  565. SwitchImageFlag(IMAGE_IAP_FLAG);
  566. /* Start erasing */
  567. tmos_set_event(Peripheral_TaskID, OTA_FLASH_ERASE_EVT);
  568. }
  569. break;
  570. }
  571. /* Verify */
  572. case CMD_IAP_VERIFY:
  573. {
  574. uint32_t i;
  575. uint8_t status = 0;
  576. uint8_t verifyData[iap_rec_data.verify.len];
  577. if( block_buf_len )
  578. {
  579. FLASH_Unlock_Fast();
  580. FLASH_ProgramPage_Fast(prom_addr, (uint32_t*)block_buf);
  581. FLASH_Lock_Fast();
  582. block_buf_len = 0;
  583. prom_addr = 0;
  584. }
  585. OpParaDataLen = iap_rec_data.verify.len;
  586. OpAdd = (uint32_t)(iap_rec_data.verify.addr[0]);
  587. OpAdd |= ((uint32_t)(iap_rec_data.verify.addr[1]) << 8);
  588. OpAdd = OpAdd * 16;
  589. OpAdd += 0x08000000;
  590. PRINT("IAP_VERIFY: %08x len:%d \r\n", (int)OpAdd, (int)OpParaDataLen);
  591. IAP_FLASH_read(OpAdd, verifyData, OpParaDataLen);
  592. /* It is currently ImageA, read the ImageB check directly */
  593. status = tmos_memcmp(verifyData, iap_rec_data.verify.buf, OpParaDataLen);
  594. if(status == FALSE)
  595. {
  596. PRINT("IAP_VERIFY err \r\n");
  597. VerifyStatus = 0xFF;
  598. }
  599. OTA_IAP_SendCMDDealSta(VerifyStatus);
  600. break;
  601. }
  602. /* End of rogramming */
  603. case CMD_IAP_END:
  604. {
  605. PRINT("IAP_END \r\n");
  606. /* Close all the current use interrupt, or it is convenient to directly close */
  607. DisableAllIRQ();
  608. /* Modify data flash, switch to ImageA */
  609. SwitchImageFlag(IMAGE_A_FLAG);
  610. /* Waiting for printing, jump to ImageB*/
  611. PRINT("jump App \n");
  612. Delay_Ms(10);
  613. app_start();
  614. /* Will not execute here */
  615. NVIC_SystemReset();
  616. break;
  617. }
  618. case CMD_IAP_INFO:
  619. {
  620. uint8_t send_buf[20];
  621. PRINT("IAP_INFO \r\n");
  622. /* IMAGE FLAG */
  623. send_buf[0] = IMAGE_IAP_FLAG;
  624. /* IMAGE_IAP_START_ADD */
  625. send_buf[1] = (uint8_t)(IMAGE_IAP_START_ADD & 0xff);
  626. send_buf[2] = (uint8_t)((IMAGE_IAP_START_ADD >> 8) & 0xff);
  627. send_buf[3] = (uint8_t)((IMAGE_IAP_START_ADD >> 16) & 0xff);
  628. send_buf[4] = (uint8_t)((IMAGE_IAP_START_ADD >> 24) & 0xff);
  629. /* BLOCK SIZE */
  630. send_buf[5] = (uint8_t)(FLASH_BLOCK_SIZE & 0xff);
  631. send_buf[6] = (uint8_t)((FLASH_BLOCK_SIZE >> 8) & 0xff);
  632. send_buf[7] = CHIP_ID&0xFF;
  633. send_buf[8] = (CHIP_ID>>8)&0xFF;
  634. /* Add more if necessary */
  635. /* send message */
  636. OTA_IAP_SendData(send_buf, 20);
  637. break;
  638. }
  639. default:
  640. {
  641. OTA_IAP_CMDErrDeal();
  642. break;
  643. }
  644. }
  645. }
  646. /*********************************************************************
  647. * @fn OTA_IAPReadDataComplete
  648. *
  649. * @brief OTA data reading complete processing
  650. *
  651. * @param index - OTA channel serial number
  652. *
  653. * @return none
  654. */
  655. void OTA_IAPReadDataComplete(unsigned char index)
  656. {
  657. PRINT("OTA Send Comp \r\n");
  658. }
  659. /*********************************************************************
  660. * @fn OTA_IAPWriteData
  661. *
  662. * @brief OTA channel data receiving complete processing
  663. *
  664. * @param index - OTA channel serial number
  665. * @param p_data - Written data
  666. * @param w_len - Length
  667. *
  668. * @return none
  669. */
  670. void OTA_IAPWriteData(unsigned char index, unsigned char *p_data, unsigned char w_len)
  671. {
  672. unsigned char rec_len;
  673. unsigned char *rec_data;
  674. rec_len = w_len;
  675. rec_data = p_data;
  676. tmos_memcpy((unsigned char *)&iap_rec_data, rec_data, rec_len);
  677. Rec_OTA_IAP_DataDeal();
  678. vUser_led_set_view_stat(LED_VIEW_OTA);
  679. }
  680. void Upgrade_IAP_Erase(uint16_t addr)
  681. {
  682. iap_rec_data.erase.cmd = CMD_IAP_ERASE;
  683. iap_rec_data.erase.len = 0;
  684. iap_rec_data.erase.addr[0] = (uint8_t)(addr / 16);
  685. iap_rec_data.erase.addr[1] = (addr / 16) >> 8;
  686. uint16_t block_num = IMAGE_A_SIZE / FLASH_BLOCK_SIZE;
  687. iap_rec_data.erase.block_num[0] = block_num;
  688. iap_rec_data.erase.block_num[1] = block_num >> 8;
  689. Rec_OTA_IAP_DataDeal();
  690. }
  691. void Upgrade_IAP_Program(uint16_t addr, uint8_t *pData, uint32_t len)
  692. {
  693. iap_rec_data.program.cmd = CMD_IAP_PROM;
  694. iap_rec_data.program.len = len;
  695. iap_rec_data.program.addr[0] = (uint8_t)(addr / 16);
  696. iap_rec_data.program.addr[1] = (addr / 16) >> 8;
  697. memcpy(iap_rec_data.program.buf, pData, len);
  698. Rec_OTA_IAP_DataDeal();
  699. }
  700. void Upgrade_IAP_End(void)
  701. {
  702. iap_rec_data.end.cmd = CMD_IAP_END;
  703. iap_rec_data.end.len = 0;
  704. iap_rec_data.end.status[0] = 0;
  705. iap_rec_data.end.status[1] = 0;
  706. Rec_OTA_IAP_DataDeal();
  707. }
  708. /*********************************************************************
  709. * @fn FLASH_read
  710. *
  711. * @brief Read flash
  712. *
  713. * @return none
  714. */
  715. void FLASH_read(uint32_t addr, uint8_t *pData, uint32_t len)
  716. {
  717. uint32_t i;
  718. for(i = 0; i < len; i++)
  719. {
  720. *pData++ = *(uint8_t*)addr++;
  721. }
  722. }
  723. /*********************************************************************
  724. *********************************************************************/