peripheral.c 27 KB

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