Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 
 

551 linhas
16 KiB

  1. /**
  2. *
  3. * \file
  4. *
  5. * \brief WINC Flash Interface.
  6. *
  7. * Copyright (c) 2017-2018 Microchip Technology Inc. and its subsidiaries.
  8. *
  9. * \asf_license_start
  10. *
  11. * \page License
  12. *
  13. * Subject to your compliance with these terms, you may use Microchip
  14. * software and any derivatives exclusively with Microchip products.
  15. * It is your responsibility to comply with third party license terms applicable
  16. * to your use of third party software (including open source software) that
  17. * may accompany Microchip software.
  18. *
  19. * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
  20. * WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
  21. * INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
  22. * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
  23. * LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
  24. * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
  25. * SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
  26. * POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
  27. * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
  28. * RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
  29. * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
  30. *
  31. * \asf_license_stop
  32. *
  33. */
  34. /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
  35. INCLUDES
  36. *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
  37. #include "driver/include/m2m_flash.h"
  38. #include "driver/include/m2m_wifi.h"
  39. #include "driver/source/nmflash.h"
  40. #include "driver/source/m2m_hif.h"
  41. #include "spi_flash/include/spi_flash.h"
  42. #include "nmdrv.h"
  43. /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
  44. GLOBALS
  45. *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
  46. static tpfDataAccessFn gpfAppFn = NULL;
  47. static uint8 gau8ItemIdentifier[20] = {0};
  48. /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
  49. FUNCTIONS
  50. *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
  51. static sint8 transfer_init(void)
  52. {
  53. sint8 ret = FLASH_RETURN_OK;
  54. /* Check module was initialized. */
  55. if (gu8Init == 0)
  56. ret = FLASH_ERR_UNINIT;
  57. return ret;
  58. }
  59. static sint8 init_access(void)
  60. {
  61. sint8 ret = FLASH_RETURN_OK;
  62. gu8Reset = 0;
  63. if (m2m_wifi_reinit_hold() != M2M_SUCCESS)
  64. ret = FLASH_ERR_WINC_ACCESS;
  65. return ret;
  66. }
  67. static sint8 commit_access(tstrFlashAccess *pstrFlashAccess)
  68. {
  69. sint8 ret = FLASH_RETURN_OK;
  70. sint8 status = M2M_ERR_FAIL;
  71. tstrFlashAccessPersistent *pstrPersistentInfo = &pstrFlashAccess->strPersistentInfo;
  72. /*
  73. * To begin with, flash is unchanged. Later, when first flash erase/write occurs, this flag
  74. * will be cleared.
  75. */
  76. pstrPersistentInfo->u8ModeFlags |= FLASH_MODE_FLAGS_UNCHANGED;
  77. if (pstrPersistentInfo->u8ModeFlags & FLASH_MODE_FLAGS_CS_SWITCH)
  78. {
  79. uint8 target = 0;
  80. if (image_get_target(&target) != M2M_SUCCESS)
  81. {
  82. ret = FLASH_ERR_WINC_ACCESS;
  83. goto ERR;
  84. }
  85. if (target > 0)
  86. pstrPersistentInfo->u8ModeFlags |= FLASH_MODE_FLAGS_CS_SWITCH_TARGET;
  87. }
  88. status = spi_flash_read((uint8*)pstrPersistentInfo, HOST_CONTROL_FLASH_OFFSET, FLASH_SIG_STA_SZ);
  89. if (status == M2M_SUCCESS)
  90. {
  91. if ((pstrPersistentInfo->u32Signature != FLASH_SIGNATURE) || (pstrPersistentInfo->enuTransferStatus != FLASH_STATUS_EMPTY))
  92. status = spi_flash_erase(HOST_CONTROL_FLASH_OFFSET, HOST_CONTROL_FLASH_SZ);
  93. }
  94. if (status == M2M_SUCCESS)
  95. {
  96. pstrPersistentInfo->u32Signature = FLASH_SIGNATURE;
  97. pstrPersistentInfo->enuTransferStatus = FLASH_STATUS_NOT_ACTIVE;
  98. status = winc_flash_write_verify((uint8*)pstrPersistentInfo, HOST_CONTROL_FLASH_OFFSET, FLASH_SIG_STA_SZ);
  99. if (status == M2M_SUCCESS)
  100. {
  101. status = winc_flash_write_verify((uint8*)pstrPersistentInfo, HOST_CONTROL_FLASH_OFFSET, sizeof(tstrFlashAccessPersistent));
  102. if (status == M2M_SUCCESS)
  103. {
  104. pstrPersistentInfo->enuTransferStatus = FLASH_STATUS_ACTIVE;
  105. status = winc_flash_write_verify((uint8*)pstrPersistentInfo, HOST_CONTROL_FLASH_OFFSET, FLASH_SIG_STA_SZ);
  106. gu16LastAccessId = pstrPersistentInfo->u16AppId;
  107. gu8Success = 0;
  108. gu8Changed = 0;
  109. }
  110. }
  111. }
  112. if (status != M2M_SUCCESS)
  113. {
  114. ret = FLASH_ERR_WINC_ACCESS;
  115. goto ERR;
  116. }
  117. ret = transfer_run(pstrFlashAccess);
  118. ERR:
  119. return ret;
  120. }
  121. static sint8 register_app_fn(tpfDataAccessFn pfFn)
  122. {
  123. sint8 ret = FLASH_RETURN_OK;
  124. if (pfFn == NULL)
  125. ret = FLASH_ERR_PARAM;
  126. gpfAppFn = pfFn;
  127. return ret;
  128. }
  129. static sint8 app_data_access(tenuFlashDataFnCtl enuCtl, void *pvStr)
  130. {
  131. tstrDataAccessInitParamsApp init_params_app;
  132. tstrDataAccessParamsApp params_app;
  133. switch (enuCtl)
  134. {
  135. case FLASH_DATA_FN_INITIALIZE:
  136. {
  137. tstrDataAccessInitParams *init_params = (tstrDataAccessInitParams*)pvStr;
  138. init_params_app.u32TotalSize = init_params->u32TotalSize;
  139. if (init_params->u8Flags & FLASH_FN_FLAGS_READ)
  140. init_params_app.enuRW = FLASH_DATA_FN_READ;
  141. else if (init_params->u8Flags & FLASH_FN_FLAGS_WRITE)
  142. init_params_app.enuRW = FLASH_DATA_FN_WRITE;
  143. pvStr = &init_params_app;
  144. }
  145. break;
  146. case FLASH_DATA_FN_DATA:
  147. {
  148. tstrDataAccessParams *params = (tstrDataAccessParams*)pvStr;
  149. params_app.pu8Data = params->pu8Buf + params->u32DataOffset;
  150. params_app.u32DataSize = params->u32DataSize;
  151. pvStr = &params_app;
  152. }
  153. break;
  154. case FLASH_DATA_FN_COMPLETE:
  155. case FLASH_DATA_FN_TERMINATE:
  156. break;
  157. }
  158. return gpfAppFn(enuCtl, pvStr);
  159. }
  160. sint8 m2m_flash_readimage(uint8 enuImageId, uint16 u16Id, tpfDataAccessFn pfDestFn, uint32 u32DestSize)
  161. {
  162. sint8 ret = FLASH_RETURN_OK;
  163. M2M_INFO("FA RdImage %d\n", enuImageId);
  164. ret = transfer_init();
  165. if (ret < 0)
  166. goto ERR;
  167. ret = register_app_fn(pfDestFn);
  168. if (ret < 0)
  169. goto ERR;
  170. if (u32DestSize < OTA_IMAGE_SIZE)
  171. {
  172. ret = FLASH_ERR_SIZE;
  173. goto ERR;
  174. }
  175. if (enuImageId > FLASH_IMAGE_INACTIVE)
  176. {
  177. ret = FLASH_ERR_PARAM;
  178. goto ERR;
  179. }
  180. ret = init_access();
  181. if (ret == FLASH_RETURN_OK)
  182. {
  183. /* Set parameters for whole transfer. */
  184. tstrFlashAccess strFlashAccess;
  185. m2m_memset((uint8*)&strFlashAccess, 0, sizeof(tstrFlashAccess));
  186. strFlashAccess.strPersistentInfo.u16AppId = u16Id;
  187. strFlashAccess.pfDestinationFn = app_data_access;
  188. switch (enuImageId)
  189. {
  190. case FLASH_IMAGE_ACTIVE:
  191. set_internal_info(&strFlashAccess.pfSourceFn, MEM_ID_WINC_ACTIVE);
  192. break;
  193. case FLASH_IMAGE_INACTIVE:
  194. set_internal_info(&strFlashAccess.pfSourceFn, MEM_ID_WINC_INACTIVE);
  195. break;
  196. }
  197. strFlashAccess.u32Size = OTA_IMAGE_SIZE;
  198. ret = commit_access(&strFlashAccess);
  199. }
  200. ERR:
  201. M2M_INFO("FAState:%d\n", ret);
  202. return ret;
  203. }
  204. sint8 m2m_flash_updateimage(uint8 u8Options, uint16 u16Id, tpfDataAccessFn pfSourceFn, uint32 u32SourceSize)
  205. {
  206. sint8 ret = FLASH_RETURN_OK;
  207. M2M_INFO("FA Image %d\n", u8Options);
  208. ret = transfer_init();
  209. if (ret < 0)
  210. goto ERR;
  211. if (u8Options & FLASH_UPDATEIMAGE_OPTION_UPDATE)
  212. {
  213. uint8 au8ImageStart[4];
  214. uint8 au8ImageCheck[] = {'N','M','I','S'};
  215. tstrDataAccessInitParams init_params = {sizeof(au8ImageStart), FLASH_FN_FLAGS_READ};
  216. sint8 status = M2M_SUCCESS;
  217. /* Check input parameters. */
  218. ret = register_app_fn(pfSourceFn);
  219. if (ret < 0)
  220. goto ERR;
  221. if (u32SourceSize != OTA_IMAGE_SIZE)
  222. {
  223. ret = FLASH_ERR_PARAM;
  224. goto ERR;
  225. }
  226. status = app_data_access(FLASH_DATA_FN_INITIALIZE, &init_params);
  227. if (status == M2M_SUCCESS)
  228. {
  229. tstrDataAccessParams params = {au8ImageStart, sizeof(au8ImageStart), 0, sizeof(au8ImageStart)};
  230. status = app_data_access(FLASH_DATA_FN_DATA, &params);
  231. }
  232. if (status != M2M_SUCCESS)
  233. {
  234. ret = FLASH_ERR_LOCAL_ACCESS;
  235. goto ERR;
  236. }
  237. if (m2m_memcmp(au8ImageStart, au8ImageCheck, sizeof(au8ImageStart)))
  238. {
  239. ret = FLASH_ERR_WINC_CONFLICT;
  240. goto ERR;
  241. }
  242. }
  243. ret = init_access();
  244. if (ret == FLASH_RETURN_OK)
  245. {
  246. /* Set parameters for whole transfer. */
  247. tstrFlashAccess strFlashAccess;
  248. m2m_memset((uint8*)&strFlashAccess, 0, sizeof(tstrFlashAccess));
  249. strFlashAccess.strPersistentInfo.u16AppId = u16Id;
  250. if (u8Options & FLASH_UPDATEIMAGE_OPTION_UPDATE)
  251. {
  252. strFlashAccess.strPersistentInfo.u8AccessFlags = FLASH_ACCESS_WINC_MASK | FLASH_ACCESS_OPTION_ERASE_FIRST;
  253. strFlashAccess.pfSourceFn = app_data_access;
  254. set_internal_info(&strFlashAccess.pfDestinationFn, MEM_ID_WINC_INACTIVE);
  255. strFlashAccess.u32Size = OTA_IMAGE_SIZE;
  256. }
  257. else
  258. strFlashAccess.u32Size = 0;
  259. if (u8Options & FLASH_UPDATEIMAGE_OPTION_VALIDATE)
  260. strFlashAccess.strPersistentInfo.u8ModeFlags |= FLASH_MODE_FLAGS_CS_VALIDATE_IMAGE;
  261. if (u8Options & FLASH_UPDATEIMAGE_OPTION_SWITCH)
  262. strFlashAccess.strPersistentInfo.u8ModeFlags |= FLASH_MODE_FLAGS_CS_SWITCH;
  263. strFlashAccess.strPersistentInfo.u8ModeFlags |= FLASH_MODE_FLAGS_CS;
  264. ret = commit_access(&strFlashAccess);
  265. }
  266. ERR:
  267. M2M_INFO("FAState:%d\n", ret);
  268. return ret;
  269. }
  270. static sint8 m2m_flash_rootcert_access(tenuFlashAccessItemMode enuMode, uint8 u8ModeOptions, uint8 u8AccessOptions, uint16 u16Id, tpfDataAccessFn pfFn, uint32 u32Size)
  271. {
  272. sint8 ret = FLASH_RETURN_OK;
  273. tstrRootCertEntryHeader strRootCertEntry;
  274. uint16 u16EntrySz = 0;
  275. M2M_INFO("FA Rootcert %d\n", enuMode);
  276. ret = transfer_init();
  277. if (ret < 0)
  278. goto ERR;
  279. switch (enuMode)
  280. {
  281. case FLASH_ITEM_ADD:
  282. {
  283. sint8 status = M2M_SUCCESS;
  284. tstrDataAccessInitParams init_params = {sizeof(strRootCertEntry), FLASH_FN_FLAGS_READ};
  285. // Read the entry header
  286. if (u32Size < sizeof(strRootCertEntry))
  287. {
  288. ret = FLASH_ERR_PARAM;
  289. goto ERR;
  290. }
  291. status = pfFn(FLASH_DATA_FN_INITIALIZE, &init_params);
  292. if (status == M2M_SUCCESS)
  293. {
  294. tstrDataAccessParams params = {(uint8*)&strRootCertEntry, sizeof(strRootCertEntry), 0, sizeof(strRootCertEntry)};
  295. status = pfFn(FLASH_DATA_FN_DATA, &params);
  296. }
  297. if (status != M2M_SUCCESS)
  298. {
  299. ret = FLASH_ERR_LOCAL_ACCESS;
  300. goto ERR;
  301. }
  302. // Check source size matches size calculated from entry header.
  303. status = rootcert_get_size(&strRootCertEntry, &u16EntrySz);
  304. if ((status != M2M_SUCCESS) || (u32Size != u16EntrySz))
  305. {
  306. ret = FLASH_ERR_PARAM;
  307. goto ERR;
  308. }
  309. }
  310. break;
  311. case FLASH_ITEM_READ:
  312. case FLASH_ITEM_REMOVE:
  313. m2m_memcpy(strRootCertEntry.au8SHA1NameHash, gau8ItemIdentifier, sizeof(gau8ItemIdentifier));
  314. m2m_memset(gau8ItemIdentifier, 0, sizeof(gau8ItemIdentifier));
  315. break;
  316. case FLASH_ITEM_READIDX:
  317. // Hack strRootCertEntry to carry the index from u8ModeOptions.
  318. *(uint32*)&strRootCertEntry = u8ModeOptions;
  319. break;
  320. default:
  321. /* No other item modes supported. */
  322. ret = FLASH_ERR_PARAM;
  323. goto ERR;
  324. break;
  325. }
  326. ret = init_access();
  327. if (ret == FLASH_RETURN_OK)
  328. {
  329. /* Now we can access the items in flash. */
  330. uint8 *pu8Buff = malloc(M2M_TLS_ROOTCER_FLASH_SZ);
  331. uint32 u32Offset = 0;
  332. if (pu8Buff == NULL)
  333. {
  334. ret = FLASH_ERR_INTERNAL;
  335. goto ERR;
  336. }
  337. ret = rootcert_access(enuMode, &strRootCertEntry, &u16EntrySz, pu8Buff, &u32Offset);
  338. if (ret == FLASH_RETURN_OK)
  339. {
  340. /* Set parameters for whole transfer, according to enuMode. */
  341. sint8 status = M2M_SUCCESS;
  342. tstrDataAccessInitParams init_params = {u16EntrySz, 0};
  343. tstrDataAccessParams data_params = {pu8Buff + u32Offset, u16EntrySz, 0, u16EntrySz};
  344. tstrFlashAccess strFlashAccess;
  345. m2m_memset((uint8*)&strFlashAccess, 0, sizeof(tstrFlashAccess));
  346. strFlashAccess.strPersistentInfo.u16AppId = u16Id;
  347. strFlashAccess.strPersistentInfo.u8AccessFlags = u8AccessOptions;
  348. switch (enuMode)
  349. {
  350. case FLASH_ITEM_ADD:
  351. init_params.u8Flags = FLASH_FN_FLAGS_READ;
  352. status = pfFn(FLASH_DATA_FN_INITIALIZE, &init_params);
  353. if (status == M2M_SUCCESS)
  354. status = pfFn(FLASH_DATA_FN_DATA, &data_params);
  355. if (status != M2M_SUCCESS)
  356. {
  357. ret = FLASH_ERR_LOCAL_ACCESS;
  358. pfFn(FLASH_DATA_FN_TERMINATE, NULL);
  359. break;
  360. }
  361. u32Offset += u16EntrySz;
  362. // intentional fallthrough.
  363. case FLASH_ITEM_REMOVE:
  364. status = spi_flash_erase(M2M_BACKUP_FLASH_OFFSET, M2M_BACKUP_FLASH_SZ);
  365. if (status == M2M_SUCCESS)
  366. status = winc_flash_write_verify(pu8Buff, M2M_BACKUP_FLASH_OFFSET, u32Offset);
  367. if (status != M2M_SUCCESS)
  368. {
  369. ret = FLASH_ERR_WINC_ACCESS;
  370. break;
  371. }
  372. set_internal_info(NULL, M2M_TLS_ROOTCER_FLASH_OFFSET);
  373. strFlashAccess.strPersistentInfo.u8ModeFlags |= FLASH_MODE_FLAGS_DATA_IN_BACKUP;
  374. break;
  375. case FLASH_ITEM_READ:
  376. case FLASH_ITEM_READIDX:
  377. // Check source size is sufficient for reading entry.
  378. if (u32Size < u16EntrySz)
  379. {
  380. ret = FLASH_ERR_SIZE;
  381. break;
  382. }
  383. init_params.u8Flags = FLASH_FN_FLAGS_WRITE;
  384. status = pfFn(FLASH_DATA_FN_INITIALIZE, &init_params);
  385. if (status == M2M_SUCCESS)
  386. status = pfFn(FLASH_DATA_FN_DATA, &data_params);
  387. if (status != M2M_SUCCESS)
  388. {
  389. ret = FLASH_ERR_LOCAL_ACCESS;
  390. pfFn(FLASH_DATA_FN_TERMINATE, NULL);
  391. break;
  392. }
  393. break;
  394. }
  395. if (ret == 0)
  396. {
  397. ret = commit_access(&strFlashAccess);
  398. if (enuMode != FLASH_ITEM_REMOVE)
  399. pfFn(FLASH_DATA_FN_COMPLETE, NULL);
  400. }
  401. }
  402. free(pu8Buff);
  403. }
  404. ERR:
  405. M2M_INFO("FAState:%d\n", ret);
  406. return ret;
  407. }
  408. sint8 m2m_flash_rootcert_add(uint16 u16Id, tpfDataAccessFn pfSourceFn, uint32 u32SourceSize)
  409. {
  410. sint8 ret = FLASH_RETURN_OK;
  411. ret = register_app_fn(pfSourceFn);
  412. if (ret == FLASH_RETURN_OK)
  413. ret = m2m_flash_rootcert_access(FLASH_ITEM_ADD, 0, FLASH_ACCESS_OPTION_COMPARE_AFTER, u16Id, app_data_access, u32SourceSize);
  414. return ret;
  415. }
  416. sint8 m2m_flash_rootcert_remove(uint16 u16Id, uint8 *pu8Identifier, uint32 u32IdentifierSz)
  417. {
  418. sint8 ret = FLASH_ERR_PARAM;
  419. if ((pu8Identifier != NULL) && (u32IdentifierSz == 20))
  420. {
  421. m2m_memcpy(gau8ItemIdentifier, pu8Identifier, u32IdentifierSz);
  422. ret = m2m_flash_rootcert_access(FLASH_ITEM_REMOVE, 0, FLASH_ACCESS_OPTION_COMPARE_AFTER, u16Id, NULL, 0);
  423. }
  424. return ret;
  425. }
  426. sint8 m2m_flash_rootcert_read(uint16 u16Id, tpfDataAccessFn pfDestFn, uint32 u32DestSize, uint8 *pu8Identifier, uint32 u32IdentifierSz)
  427. {
  428. sint8 ret = FLASH_RETURN_OK;
  429. ret = register_app_fn(pfDestFn);
  430. if (ret == FLASH_RETURN_OK)
  431. {
  432. ret = FLASH_ERR_PARAM;
  433. if ((pu8Identifier != NULL) && (u32IdentifierSz == 20))
  434. {
  435. m2m_memcpy(gau8ItemIdentifier, pu8Identifier, u32IdentifierSz);
  436. ret = m2m_flash_rootcert_access(FLASH_ITEM_READ, 0, 0, u16Id, app_data_access, u32DestSize);
  437. }
  438. }
  439. return ret;
  440. }
  441. sint8 m2m_flash_rootcert_readidx(uint16 u16Id, tpfDataAccessFn pfDestFn, uint32 u32DestSize, uint8 u8Index)
  442. {
  443. sint8 ret = FLASH_RETURN_OK;
  444. ret = register_app_fn(pfDestFn);
  445. if (ret == FLASH_RETURN_OK)
  446. ret = m2m_flash_rootcert_access(FLASH_ITEM_READIDX, u8Index, 0, u16Id, app_data_access, u32DestSize);
  447. return ret;
  448. }
  449. void m2m_flash_get_state(tstrFlashState *pstrState)
  450. {
  451. if (gu8Reset == 0)
  452. {
  453. sint8 status = M2M_ERR_FAIL;
  454. tstrFlashAccessPersistent strSavedFlashAccess;
  455. status = spi_flash_read((uint8*)&strSavedFlashAccess, HOST_CONTROL_FLASH_OFFSET, sizeof(tstrFlashAccessPersistent));
  456. if ((status == M2M_SUCCESS) && (strSavedFlashAccess.u32Signature == FLASH_SIGNATURE))
  457. {
  458. switch (strSavedFlashAccess.enuTransferStatus)
  459. {
  460. case FLASH_STATUS_ACTIVE:
  461. if (strSavedFlashAccess.u8ModeFlags & FLASH_MODE_FLAGS_CS_SWITCH)
  462. {
  463. // Check to see if switch happened before we were interrupted. If so we had actually completed.
  464. uint8 target;
  465. if (image_get_target(&target) == M2M_SUCCESS)
  466. {
  467. if ((target == 0) && (strSavedFlashAccess.u8ModeFlags & FLASH_MODE_FLAGS_CS_SWITCH_TARGET))
  468. gu8Success = 1;
  469. if ((target > 0) && !(strSavedFlashAccess.u8ModeFlags & FLASH_MODE_FLAGS_CS_SWITCH_TARGET))
  470. gu8Success = 1;
  471. }
  472. }
  473. gu16LastAccessId = strSavedFlashAccess.u16AppId;
  474. gu8Changed = !(strSavedFlashAccess.u8ModeFlags & FLASH_MODE_FLAGS_UNCHANGED);
  475. if (gu8Success == 1)
  476. {
  477. strSavedFlashAccess.enuTransferStatus = FLASH_STATUS_DONE;
  478. winc_flash_write_verify((uint8*)&strSavedFlashAccess, HOST_CONTROL_FLASH_OFFSET, FLASH_SIG_STA_SZ);
  479. }
  480. break;
  481. case FLASH_STATUS_DONE:
  482. gu16LastAccessId = strSavedFlashAccess.u16AppId;
  483. gu8Changed = !(strSavedFlashAccess.u8ModeFlags & FLASH_MODE_FLAGS_UNCHANGED);
  484. gu8Success = 1;
  485. break;
  486. default:
  487. break;
  488. }
  489. }
  490. }
  491. m2m_memset((uint8*)pstrState, 0, sizeof(tstrFlashState));
  492. if (gu16LastAccessId)
  493. {
  494. pstrState->u16LastAccessId = gu16LastAccessId;
  495. pstrState->u8Success = gu8Success;
  496. pstrState->u8Changed = gu8Changed;
  497. }
  498. pstrState->u8Init = gu8Init;
  499. pstrState->u8Reset = gu8Reset;
  500. }
  501. sint8 m2m_flash_init(void)
  502. {
  503. if (gu8Reset == 0)
  504. {
  505. // WINC backup recovery may be needed.
  506. if (recover_backup() == FLASH_RETURN_OK)
  507. {
  508. gu8Init = 1;
  509. gu8Reset = 1;
  510. return M2M_SUCCESS;
  511. }
  512. }
  513. return M2M_ERR_FAIL;
  514. }