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.
 
 
 
 

857 linhas
28 KiB

  1. /*******************************************************************************
  2. File Name:
  3. m2m_hif.c
  4. Summary:
  5. This module contains M2M host interface API implementations.
  6. Description:
  7. This module contains M2M host interface API implementations.
  8. *******************************************************************************/
  9. //DOM-IGNORE-BEGIN
  10. /*******************************************************************************
  11. * Copyright (C) 2021 Microchip Technology Inc. and its subsidiaries.
  12. *
  13. * Subject to your compliance with these terms, you may use Microchip software
  14. * and any derivatives exclusively with Microchip products. It is your
  15. * responsibility to comply with third party license terms applicable to your
  16. * use of third party software (including open source software) that may
  17. * accompany Microchip software.
  18. *
  19. * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER
  20. * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED
  21. * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A
  22. * PARTICULAR PURPOSE.
  23. *
  24. * IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE,
  25. * INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND
  26. * WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS
  27. * BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE
  28. * FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN
  29. * ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
  30. * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
  31. *******************************************************************************/
  32. #include "nm_common.h"
  33. #include "nmbus.h"
  34. #include "nmdrv.h"
  35. #include "nm_bsp.h"
  36. #include "m2m_hif.h"
  37. #include "m2m_types.h"
  38. #include "nmasic.h"
  39. #include "m2m_periph.h"
  40. //#include "wdrv_winc_common.h"
  41. //#include "osal/osal.h"
  42. #define NMI_AHB_DATA_MEM_BASE 0x30000
  43. #define NMI_AHB_SHARE_MEM_BASE 0xd0000
  44. #define WIFI_HOST_RCV_CTRL_0 (0x1070)
  45. #define WIFI_HOST_RCV_CTRL_1 (0x1084)
  46. #define WIFI_HOST_RCV_CTRL_2 (0x1078)
  47. #define WIFI_HOST_RCV_CTRL_3 (0x106c)
  48. #define WIFI_HOST_RCV_CTRL_4 (0x150400)
  49. #define INTERRUPT_CORTUS_0_3000D0 (0x10a8)
  50. #define INTERRUPT_CORTUS_1_3000D0 (0x10ac)
  51. #define INTERRUPT_CORTUS_2_3000D0 (0x10b0)
  52. #define INTERRUPT_CORTUS_3_3000D0 (0x10b4)
  53. //static OSAL_SEM_HANDLE_TYPE hifSemaphore;
  54. typedef struct {
  55. uint8_t u8ChipMode;
  56. uint8_t u8ChipSleep;
  57. uint8_t u8HifRXDone;
  58. uint8_t u8Interrupt;
  59. uint32_t u32RxAddr;
  60. uint32_t u32RxSize;
  61. tpfHifCallBack pfWifiCb;
  62. tpfHifCallBack pfIpCb;
  63. tpfHifCallBack pfOtaCb;
  64. tpfHifCallBack pfSigmaCb;
  65. tpfHifCallBack pfHifCb;
  66. //tpfHifCallBack pfCryptoCb;
  67. tpfHifCallBack pfSslCb;
  68. } tstrHifContext;
  69. volatile tstrHifContext gstrHifCxt;
  70. /*
  71. Special codes for managing HIF restriction to OTA rollback/switch only
  72. */
  73. #define HIF_OTA_RB_ONLY 0xFFFF
  74. #define HIFCODE_OTA_RB ((M2M_REQ_GROUP_OTA << 8) | M2M_OTA_REQ_ROLLBACK)
  75. #define HIFCODE_OTA_SW ((M2M_REQ_GROUP_OTA << 8) | M2M_OTA_REQ_SWITCH_FIRMWARE)
  76. /*
  77. Codes for new HIF messages (since last HIF major increase).
  78. Only need ones which are host->winc.
  79. Each entry is formed of ((GroupId << 8) | OpCode)
  80. */
  81. #define HIFCODE_SSL_WRITECERT ((M2M_REQ_GROUP_SSL << 8) | M2M_SSL_REQ_WRITE_OWN_CERTS)
  82. #define HIFCODE_WIFI_PASSIVESCAN ((M2M_REQ_GROUP_WIFI << 8) | M2M_WIFI_REQ_PASSIVE_SCAN)
  83. #define HIFCODE_WIFI_CONN ((M2M_REQ_GROUP_WIFI << 8) | M2M_WIFI_REQ_CONN)
  84. #define HIFCODE_WIFI_CONN_PARAM ((M2M_REQ_GROUP_WIFI << 8) | M2M_WIFI_IND_CONN_PARAM)
  85. #define HIFCODE_WIFI_DELETE_CRED ((M2M_REQ_GROUP_WIFI << 8) | M2M_WIFI_REQRSP_DELETE_APID)
  86. #define HIFCODE_WIFI_START_PROV_MODE ((M2M_REQ_GROUP_WIFI << 8) | M2M_WIFI_REQ_START_PROVISION_MODE)
  87. #define HIFCODE_WIFI_ENABLE_AP ((M2M_REQ_GROUP_WIFI << 8) | M2M_WIFI_REQ_ENABLE_AP)
  88. #define HIFCODE_IP_RAW_SOCK_OPT ((M2M_REQ_GROUP_IP << 8) | SOCKET_CMD_RAW_SET_SOCK_OPT)
  89. #define HIFCODE_WIFI_ROAMING ((M2M_REQ_GROUP_WIFI << 8) | M2M_WIFI_REQ_ROAMING)
  90. #define HIFCODE_IP_SECURE ((M2M_REQ_GROUP_IP << 8) | SOCKET_CMD_SECURE)
  91. #define HIFCODE_WIFI_SCAN_SSID_LIST ((M2M_REQ_GROUP_WIFI << 8) | M2M_WIFI_REQ_SCAN_SSID_LIST)
  92. #define HIFCODE_WIFI_SET_STOP_SCAN_OPTION ((M2M_REQ_GROUP_WIFI << 8) | M2M_WIFI_REQ_SET_STOP_SCAN_OPTION)
  93. /*
  94. List of new HIF messages (since last HIF major increase).
  95. Only need to list ones which are host->winc.
  96. Additionally, entry 0 used to indicate OTA RB/SW only.
  97. */
  98. #define NEW_HIF_LIST \
  99. HIF_OTA_RB_ONLY, \
  100. HIFCODE_SSL_WRITECERT, \
  101. HIFCODE_WIFI_PASSIVESCAN, \
  102. HIFCODE_WIFI_CONN, \
  103. HIFCODE_WIFI_CONN_PARAM, \
  104. HIFCODE_WIFI_DELETE_CRED, \
  105. HIFCODE_WIFI_START_PROV_MODE, \
  106. HIFCODE_WIFI_ENABLE_AP, \
  107. HIFCODE_IP_RAW_SOCK_OPT, \
  108. HIFCODE_WIFI_ROAMING, \
  109. HIFCODE_IP_SECURE, \
  110. HIFCODE_WIFI_SCAN_SSID_LIST, \
  111. HIFCODE_WIFI_SET_STOP_SCAN_OPTION
  112. /*
  113. Array of HIF messages which are not supported by Firmware.
  114. During hif_init() this array is rebased using an offset determined by Firmware HIF level.
  115. */
  116. static uint16_t gau16HifBlacklist[] = {NEW_HIF_LIST};
  117. #define HIF_BLACKLIST_SZ (sizeof(gau16HifBlacklist)/sizeof(gau16HifBlacklist[0]))
  118. static uint8_t gu8HifBlOffset = 0;
  119. static int8_t hif_set_rx_done(void)
  120. {
  121. uint32_t reg;
  122. int8_t ret = M2M_SUCCESS;
  123. gstrHifCxt.u8HifRXDone = 0;
  124. if (ISNMC3400(nmi_get_chipid())) {
  125. ret = nm_write_reg(INTERRUPT_CORTUS_0_3000D0, 1);
  126. if(ret != M2M_SUCCESS)goto ERR1;
  127. } else {
  128. ret = nm_read_reg_with_ret(WIFI_HOST_RCV_CTRL_0, &reg);
  129. if(ret != M2M_SUCCESS)goto ERR1;
  130. /* Set RX Done */
  131. reg |= NBIT1;
  132. ret = nm_write_reg(WIFI_HOST_RCV_CTRL_0, reg);
  133. if(ret != M2M_SUCCESS)goto ERR1;
  134. }
  135. ERR1:
  136. return ret;
  137. }
  138. /**
  139. * @fn static void m2m_hif_cb(uint8_t u8OpCode, uint16_t u16DataSize, uint32_t u32Addr)
  140. * @brief WiFi call back function
  141. * @param[in] u8OpCode
  142. * HIF Opcode type.
  143. * @param[in] u16DataSize
  144. * HIF data length.
  145. * @param[in] u32Addr
  146. * HIF address.
  147. */
  148. static void m2m_hif_cb(uint8_t u8OpCode, uint16_t u16DataSize, uint32_t u32Addr)
  149. {
  150. }
  151. /**
  152. * @fn int8_t hif_chip_wake(void);
  153. * @brief To Wakeup the chip.
  154. * @return The function shall return ZERO for successful operation and a negative value otherwise.
  155. */
  156. int8_t hif_chip_wake(void)
  157. {
  158. int8_t ret = M2M_SUCCESS;
  159. if(gstrHifCxt.u8HifRXDone)
  160. {
  161. /* chip already wake for the rx not done no need to send wake request */
  162. return ret;
  163. }
  164. if(gstrHifCxt.u8ChipSleep == 0)
  165. {
  166. if(gstrHifCxt.u8ChipMode != M2M_NO_PS)
  167. {
  168. ret = chip_wake();
  169. if(ret != M2M_SUCCESS)goto ERR1;
  170. }
  171. }
  172. gstrHifCxt.u8ChipSleep++;
  173. ERR1:
  174. return ret;
  175. }
  176. /*!
  177. @fn \
  178. void hif_set_sleep_mode(uint8_t u8Pstype);
  179. @brief
  180. Set the sleep mode of the HIF layer.
  181. @param [in] u8Pstype
  182. Sleep mode.
  183. @return
  184. The function SHALL return 0 for success and a negative value otherwise.
  185. */
  186. void hif_set_sleep_mode(uint8_t u8Pstype)
  187. {
  188. gstrHifCxt.u8ChipMode = u8Pstype;
  189. }
  190. /*!
  191. @fn \
  192. uint8_t hif_get_sleep_mode(void);
  193. @brief
  194. Get the sleep mode of the HIF layer.
  195. @return
  196. The function SHALL return the sleep mode of the HIF layer.
  197. */
  198. uint8_t hif_get_sleep_mode(void)
  199. {
  200. return gstrHifCxt.u8ChipMode;
  201. }
  202. /**
  203. * @fn int8_t hif_chip_sleep_sc(void);
  204. * @brief To clear the chip sleep but keep the chip sleep
  205. * @return The function shall return ZERO for successful operation and a negative value otherwise.
  206. */
  207. static int8_t hif_chip_sleep_sc(void)
  208. {
  209. if(gstrHifCxt.u8ChipSleep >= 1)
  210. {
  211. gstrHifCxt.u8ChipSleep--;
  212. }
  213. return M2M_SUCCESS;
  214. }
  215. /**
  216. * @fn int8_t hif_chip_sleep(void);
  217. * @brief To make the chip sleep.
  218. * @return The function shall return ZERO for successful operation and a negative value otherwise.
  219. */
  220. int8_t hif_chip_sleep(void)
  221. {
  222. int8_t ret = M2M_SUCCESS;
  223. if(gstrHifCxt.u8ChipSleep >= 1)
  224. {
  225. gstrHifCxt.u8ChipSleep--;
  226. }
  227. if(gstrHifCxt.u8ChipSleep == 0)
  228. {
  229. if(gstrHifCxt.u8ChipMode != M2M_NO_PS)
  230. ret = chip_sleep();
  231. }
  232. return ret;
  233. }
  234. /**
  235. * @fn int8_t hif_init(void * arg);
  236. * @brief To initialize HIF layer.
  237. * @param[in] arg
  238. * Pointer to the arguments.
  239. * @return The function shall return ZERO for successful operation and a negative value otherwise.
  240. */
  241. int8_t hif_init(void *arg)
  242. {
  243. memset((uint8_t*)&gstrHifCxt, 0, sizeof(tstrHifContext));
  244. // if (OSAL_RESULT_TRUE != OSAL_SEM_Create(&hifSemaphore, OSAL_SEM_TYPE_BINARY, 1, 1))
  245. // return M2M_ERR_INIT;
  246. hif_register_cb(M2M_REQ_GROUP_HIF, m2m_hif_cb);
  247. return hif_chip_sleep();
  248. }
  249. /**
  250. * @fn int8_t hif_deinit(void * arg);
  251. * @brief To Deinitialize HIF layer.
  252. * @param[in] arg
  253. * Pointer to the arguments.
  254. * @return The function shall return ZERO for successful operation and a negative value otherwise.
  255. */
  256. int8_t hif_deinit(void *arg)
  257. {
  258. int8_t ret = M2M_SUCCESS;
  259. ret = hif_chip_wake();
  260. memset((uint8_t*)&gstrHifCxt, 0, sizeof(tstrHifContext));
  261. return ret;
  262. }
  263. /**
  264. * @fn int8_t hif_check_compatibility(uint16_t u16HifInfo);
  265. * @brief
  266. * To check the compatibility of an image with the current driver.
  267. * @param [in] u16HifInfo
  268. * HIF info of image to be checked.
  269. * @return The function shall return ZERO for compatible image and a negative value otherwise.
  270. */
  271. int8_t hif_check_compatibility(uint16_t u16HifInfo)
  272. {
  273. int8_t ret = M2M_ERR_FW_VER_MISMATCH;
  274. if((M2M_GET_HIF_BLOCK(u16HifInfo) == M2M_HIF_BLOCK_VALUE) && (M2M_GET_HIF_MAJOR(u16HifInfo) == M2M_HIF_MAJOR_VALUE))
  275. {
  276. ret = M2M_SUCCESS;
  277. }
  278. return ret;
  279. }
  280. /**
  281. * @fn int8_t hif_enable_access(void);
  282. * @brief
  283. * To enable access to HIF layer, based on HIF level of Firmware.
  284. * This function reads HIF level directly from a register written by Firmware.
  285. * @return The function shall return ZERO for full match operation and a negative value if operation is restricted.
  286. */
  287. int8_t hif_enable_access(void)
  288. {
  289. int8_t ret = M2M_SUCCESS;
  290. uint16_t fw_hif_info = 0;
  291. ret = nm_get_hif_info(&fw_hif_info, NULL);
  292. if(ret == M2M_SUCCESS)
  293. {
  294. ret = hif_check_compatibility(fw_hif_info);
  295. if(ret == M2M_SUCCESS)
  296. {
  297. switch(M2M_GET_HIF_MINOR(fw_hif_info))
  298. {
  299. case 0:
  300. gu8HifBlOffset = 1;
  301. break;
  302. case 1:
  303. gu8HifBlOffset = 2;
  304. break;
  305. case 2:
  306. gu8HifBlOffset = 2;
  307. break;
  308. case 3:
  309. gu8HifBlOffset = 3;
  310. break;
  311. case 4:
  312. gu8HifBlOffset = 10;
  313. break;
  314. case 5:
  315. gu8HifBlOffset = 13;
  316. break;
  317. // Additional case to be added each time hif minor increments.
  318. // All additional cases to be removed in the event of a hif major increment.
  319. // Default catches all cases in which hif minor is greater in Firmware than in Driver.
  320. default:
  321. gu8HifBlOffset = HIF_BLACKLIST_SZ;
  322. break;
  323. }
  324. }
  325. else
  326. {
  327. gu8HifBlOffset = 0;
  328. M2M_ERR("HIF access limited to OTA Switch/Rollback only\r\n");
  329. }
  330. }
  331. return ret;
  332. }
  333. /**
  334. * @fn int8_t hif_check_code(uint8_t u8Gid, uint8_t u8OpCode);
  335. * @brief
  336. * To check that a particular hif message is supported with the current driver/firmware pair.
  337. * @param[in] u8Gid
  338. * Group ID.
  339. * @param[in] u8Opcode
  340. * Operation ID.
  341. * @return The function shall return @ref M2M_SUCCESS for success and a negative value otherwise.
  342. */
  343. int8_t hif_check_code(uint8_t u8Gid, uint8_t u8OpCode)
  344. {
  345. uint8_t u8BlId;
  346. uint16_t u16HifCode = ((uint16_t)u8Gid<<8) | u8OpCode;
  347. if((u16HifCode == HIFCODE_OTA_RB) || (u16HifCode == HIFCODE_OTA_SW))
  348. {
  349. return M2M_SUCCESS;
  350. }
  351. if(gu8HifBlOffset == 0)
  352. {
  353. M2M_ERR("HIF OTA rb/sw only\r\n");
  354. return M2M_ERR_SEND;
  355. }
  356. for(u8BlId = gu8HifBlOffset; u8BlId < HIF_BLACKLIST_SZ; u8BlId++)
  357. {
  358. if(u16HifCode == gau16HifBlacklist[u8BlId])
  359. {
  360. M2M_ERR("HIF message unsupported\r\n");
  361. return M2M_ERR_SEND;
  362. }
  363. }
  364. return M2M_SUCCESS;
  365. }
  366. /**
  367. * @fn int8_t hif_send(uint8_t u8Gid,uint8_t u8Opcode,uint8_t *pu8CtrlBuf,uint16_t u16CtrlBufSize,
  368. * uint8_t *pu8DataBuf,uint16_t u16DataSize, uint16_t u16DataOffset)
  369. * @brief Send packet using host interface.
  370. *
  371. * @param[in] u8Gid
  372. * Group ID.
  373. * @param[in] u8Opcode
  374. * Operation ID.
  375. * @param[in] pu8CtrlBuf
  376. * Pointer to the Control buffer.
  377. * @param[in] u16CtrlBufSize
  378. * Control buffer size.
  379. * @param[in] u16DataOffset
  380. * Packet Data offset.
  381. * @param[in] pu8DataBuf
  382. * Packet buffer Allocated by the caller.
  383. * @param[in] u16DataSize
  384. * Packet buffer size (including the HIF header).
  385. * @return The function shall return @ref M2M_SUCCESS for successful operation and a negative value otherwise.
  386. */
  387. int8_t hif_send(uint8_t u8Gid, uint8_t u8Opcode, uint8_t *pu8CtrlBuf, uint16_t u16CtrlBufSize,
  388. uint8_t *pu8DataBuf, uint16_t u16DataSize, uint16_t u16DataOffset)
  389. {
  390. int8_t ret = M2M_ERR_SEND;
  391. tstrHifHdr strHif;
  392. uint32_t u32CtrlDataGap = u16DataOffset;
  393. // while (OSAL_RESULT_FALSE == OSAL_SEM_Pend(&hifSemaphore, OSAL_WAIT_FOREVER))
  394. {
  395. }
  396. strHif.u8Opcode = u8Opcode&(~NBIT7);
  397. strHif.u8Gid = u8Gid;
  398. strHif.u16Length = M2M_HIF_HDR_OFFSET;
  399. if(pu8CtrlBuf != NULL)
  400. {
  401. if(u16CtrlBufSize > M2M_HIF_MAX_PACKET_SIZE-M2M_HIF_HDR_OFFSET)
  402. {
  403. M2M_ERR("HIF %s (%dB) exceeds max (%dB)\n", "Ctrl", u16CtrlBufSize, M2M_HIF_MAX_PACKET_SIZE-M2M_HIF_HDR_OFFSET);
  404. goto ERR2;
  405. }
  406. strHif.u16Length += u16CtrlBufSize;
  407. u32CtrlDataGap -= u16CtrlBufSize;
  408. }
  409. if(pu8DataBuf != NULL)
  410. {
  411. if((uint32_t)u16DataOffset + u16DataSize > M2M_HIF_MAX_PACKET_SIZE-M2M_HIF_HDR_OFFSET)
  412. {
  413. M2M_ERR("HIF %s (%luB) exceeds max (%luB)\n", "Data", (uint32_t)u16DataOffset + u16DataSize, (uint32_t)M2M_HIF_MAX_PACKET_SIZE-M2M_HIF_HDR_OFFSET);
  414. goto ERR2;
  415. }
  416. strHif.u16Length += u32CtrlDataGap + u16DataSize;
  417. }
  418. ret = hif_check_code(strHif.u8Gid, strHif.u8Opcode);
  419. if(ret != M2M_SUCCESS)
  420. {
  421. goto ERR2;
  422. }
  423. if(strHif.u16Length <= M2M_HIF_MAX_PACKET_SIZE)
  424. {
  425. ret = hif_chip_wake();
  426. if(ret == M2M_SUCCESS)
  427. {
  428. volatile uint32_t reg, dma_addr = 0;
  429. volatile uint16_t cnt = 0;
  430. reg = 0UL;
  431. reg |= (uint32_t)u8Gid;
  432. reg |= ((uint32_t)u8Opcode<<8);
  433. reg |= ((uint32_t)strHif.u16Length<<16);
  434. ret = nm_write_reg(NMI_STATE_REG, reg);
  435. if(M2M_SUCCESS != ret) goto ERR1;
  436. reg = 0UL;
  437. reg |= NBIT1;
  438. ret = nm_write_reg(WIFI_HOST_RCV_CTRL_2, reg);
  439. if(M2M_SUCCESS != ret) goto ERR1;
  440. if (ISNMC3400(nmi_get_chipid())) {
  441. ret = nm_write_reg(INTERRUPT_CORTUS_1_3000D0, 1);
  442. if(M2M_SUCCESS != ret) goto ERR1;
  443. }
  444. dma_addr = 0;
  445. for(cnt = 0; cnt < 1000*5; cnt ++)
  446. {
  447. ret = nm_read_reg_with_ret(WIFI_HOST_RCV_CTRL_2, (uint32_t *)&reg);
  448. if(ret != M2M_SUCCESS) break;
  449. /*
  450. * If it takes too long to get a response, the slow down to
  451. * avoid back-to-back register read operations.
  452. */
  453. if(cnt >= 1000) {
  454. if(cnt == 1000) {
  455. M2M_INFO("Slowing down...\n");
  456. }
  457. nm_sleep(5);
  458. }
  459. if(!(reg & NBIT1))
  460. {
  461. ret = nm_read_reg_with_ret(WIFI_HOST_RCV_CTRL_4, (uint32_t *)&dma_addr);
  462. if(ret != M2M_SUCCESS) {
  463. /*in case of read error clear the DMA address and return error*/
  464. dma_addr = 0;
  465. goto ERR1;
  466. }
  467. /*in case of success break */
  468. break;
  469. }
  470. }
  471. if (dma_addr != 0)
  472. {
  473. volatile uint32_t u32CurrAddr;
  474. u32CurrAddr = dma_addr;
  475. strHif.u16Length=NM_BSP_B_L_16(strHif.u16Length);
  476. M2M_DBG("Writing into %" PRIx32 " %d\r\n", dma_addr, strHif.u16Length);
  477. ret = nm_write_block(u32CurrAddr, (uint8_t*)&strHif, M2M_HIF_HDR_OFFSET);
  478. if(M2M_SUCCESS != ret) goto ERR1;
  479. u32CurrAddr += M2M_HIF_HDR_OFFSET;
  480. if(pu8CtrlBuf != NULL)
  481. {
  482. ret = nm_write_block(u32CurrAddr, pu8CtrlBuf, u16CtrlBufSize);
  483. if(M2M_SUCCESS != ret) goto ERR1;
  484. u32CurrAddr += u16CtrlBufSize;
  485. }
  486. if(pu8DataBuf != NULL)
  487. {
  488. u32CurrAddr += u32CtrlDataGap;
  489. ret = nm_write_block(u32CurrAddr, pu8DataBuf, u16DataSize);
  490. if(M2M_SUCCESS != ret) goto ERR1;
  491. u32CurrAddr += u16DataSize;
  492. }
  493. reg = dma_addr << 2;
  494. /* Following line of code is to generate the interrupt which is not strictly needed for 3400,
  495. but has no noticeable side effects
  496. */
  497. reg |= NBIT1;
  498. ret = nm_write_reg(WIFI_HOST_RCV_CTRL_3, reg);
  499. if(M2M_SUCCESS != ret) goto ERR1;
  500. if (ISNMC3400(nmi_get_chipid())) {
  501. ret = nm_write_reg(INTERRUPT_CORTUS_2_3000D0, 1);
  502. if(M2M_SUCCESS != ret) goto ERR1;
  503. }
  504. }
  505. else
  506. {
  507. ret = hif_chip_sleep();
  508. M2M_DBG("Failed to alloc rx size\r\n");
  509. ret = M2M_ERR_MEM_ALLOC;
  510. goto ERR2;
  511. }
  512. }
  513. else
  514. {
  515. M2M_ERR("(HIF)Failed to wakeup the chip\r\n");
  516. goto ERR2;
  517. }
  518. }
  519. else
  520. {
  521. M2M_ERR("HIF message length (%d) exceeds max length (%d)\r\n", strHif.u16Length, M2M_HIF_MAX_PACKET_SIZE);
  522. ret = M2M_ERR_SEND;
  523. goto ERR2;
  524. }
  525. // OSAL_SEM_Post(&hifSemaphore);
  526. /*actual sleep ret = M2M_SUCCESS*/
  527. ret = hif_chip_sleep();
  528. return ret;
  529. ERR1:
  530. /*reset the count but no actual sleep as it already bus error*/
  531. hif_chip_sleep_sc();
  532. ERR2:
  533. /*logical error*/
  534. // OSAL_SEM_Post(&hifSemaphore);
  535. return ret;
  536. }
  537. /**
  538. * @fn hif_isr
  539. * @brief Host interface interrupt service routine
  540. * @return @ref M2M_SUCCESS in case of success or a negative vale otherwise
  541. */
  542. static int8_t hif_isr(void)
  543. {
  544. int8_t ret = M2M_SUCCESS;
  545. uint32_t reg;
  546. volatile tstrHifHdr strHif;
  547. // while (OSAL_RESULT_FALSE == OSAL_SEM_Pend(&hifSemaphore, OSAL_WAIT_FOREVER))
  548. {
  549. }
  550. ret = nm_read_reg_with_ret(WIFI_HOST_RCV_CTRL_0, &reg);
  551. if(M2M_SUCCESS == ret)
  552. {
  553. if(reg & 0x1) /* New interrupt has been received */
  554. {
  555. uint16_t size;
  556. /*Clearing RX interrupt*/
  557. ret = nm_read_reg_with_ret(WIFI_HOST_RCV_CTRL_0, &reg);
  558. if(ret != M2M_SUCCESS)goto ERR1;
  559. reg &= ~NBIT0;
  560. ret = nm_write_reg(WIFI_HOST_RCV_CTRL_0, reg);
  561. if(ret != M2M_SUCCESS)goto ERR1;
  562. /* read the rx size */
  563. ret = nm_read_reg_with_ret(WIFI_HOST_RCV_CTRL_0, &reg);
  564. if(M2M_SUCCESS != ret)
  565. {
  566. M2M_ERR("(hif) WIFI_HOST_RCV_CTRL_0 bus fail\r\n");
  567. goto ERR1;
  568. }
  569. gstrHifCxt.u8HifRXDone = 1;
  570. size = (uint16_t)((reg >> 2) & 0xfff);
  571. if (size > 0) {
  572. uint32_t address = 0;
  573. /**
  574. start bus transfer
  575. **/
  576. ret = nm_read_reg_with_ret(WIFI_HOST_RCV_CTRL_1, &address);
  577. if(M2M_SUCCESS != ret)
  578. {
  579. M2M_ERR("(hif) WIFI_HOST_RCV_CTRL_1 bus fail\r\n");
  580. goto ERR1;
  581. }
  582. gstrHifCxt.u32RxAddr = address;
  583. gstrHifCxt.u32RxSize = size;
  584. ret = nm_read_block(address, (uint8_t*)&strHif, sizeof(tstrHifHdr));
  585. strHif.u16Length = NM_BSP_B_L_16(strHif.u16Length);
  586. if(M2M_SUCCESS != ret)
  587. {
  588. M2M_ERR("(hif) address bus fail\r\n");
  589. goto ERR1;
  590. }
  591. if(strHif.u16Length != size)
  592. {
  593. if((size - strHif.u16Length) > 4)
  594. {
  595. M2M_ERR("(hif) Corrupted packet Size = %u <L = %u, G = %u, OP = %02X>\r\n",
  596. size, strHif.u16Length, strHif.u8Gid, strHif.u8Opcode);
  597. ret = M2M_ERR_BUS_FAIL;
  598. goto ERR1;
  599. }
  600. }
  601. // OSAL_SEM_Post(&hifSemaphore);
  602. if(M2M_REQ_GROUP_WIFI == strHif.u8Gid)
  603. {
  604. if(gstrHifCxt.pfWifiCb)
  605. gstrHifCxt.pfWifiCb(strHif.u8Opcode, strHif.u16Length - M2M_HIF_HDR_OFFSET, address + M2M_HIF_HDR_OFFSET);
  606. else
  607. M2M_ERR("WIFI callback is not registered\r\n");
  608. }
  609. else if(M2M_REQ_GROUP_IP == strHif.u8Gid)
  610. {
  611. if(gstrHifCxt.pfIpCb)
  612. gstrHifCxt.pfIpCb(strHif.u8Opcode, strHif.u16Length - M2M_HIF_HDR_OFFSET, address + M2M_HIF_HDR_OFFSET);
  613. else
  614. M2M_ERR("Socket callback is not registered\r\n");
  615. }
  616. else if(M2M_REQ_GROUP_OTA == strHif.u8Gid)
  617. {
  618. if(gstrHifCxt.pfOtaCb)
  619. gstrHifCxt.pfOtaCb(strHif.u8Opcode, strHif.u16Length - M2M_HIF_HDR_OFFSET, address + M2M_HIF_HDR_OFFSET);
  620. else
  621. M2M_ERR("OTA callback is not registered\r\n");
  622. }
  623. else if(M2M_REQ_GROUP_SIGMA == strHif.u8Gid)
  624. {
  625. if(gstrHifCxt.pfSigmaCb)
  626. gstrHifCxt.pfSigmaCb(strHif.u8Opcode, strHif.u16Length - M2M_HIF_HDR_OFFSET, address + M2M_HIF_HDR_OFFSET);
  627. else
  628. M2M_ERR("Sigma callback is not registered\r\n");
  629. }
  630. else if(M2M_REQ_GROUP_SSL == strHif.u8Gid)
  631. {
  632. if(gstrHifCxt.pfSslCb)
  633. gstrHifCxt.pfSslCb(strHif.u8Opcode, strHif.u16Length - M2M_HIF_HDR_OFFSET, address + M2M_HIF_HDR_OFFSET);
  634. else
  635. M2M_ERR("SSL callback is not registered\r\n");
  636. }
  637. else
  638. {
  639. M2M_ERR("(hif) invalid group ID\r\n");
  640. return M2M_ERR_BUS_FAIL;
  641. }
  642. if(gstrHifCxt.u8HifRXDone)
  643. {
  644. M2M_ERR("(hif) host app didn't set RX Done <%u><%X>\n", strHif.u8Gid, strHif.u8Opcode);
  645. return hif_set_rx_done();
  646. }
  647. return M2M_SUCCESS;
  648. }
  649. else
  650. {
  651. ret = M2M_ERR_RCV;
  652. M2M_ERR("(hif) Wrong Size\r\n");
  653. goto ERR1;
  654. }
  655. }
  656. else
  657. {
  658. M2M_ERR("(hif) False interrupt %lx\r\n",reg);
  659. ret = M2M_ERR_FAIL;
  660. }
  661. }
  662. else
  663. {
  664. M2M_ERR("(hif) Failed to read interrupt reg\r\n");
  665. }
  666. ERR1:
  667. // OSAL_SEM_Post(&hifSemaphore);
  668. return ret;
  669. }
  670. /**
  671. * @fn hif_handle_isr(void)
  672. * @brief Handle interrupt received from WINC3400 firmware.
  673. * @return The function SHALL return 0 for success and a negative value otherwise.
  674. */
  675. int8_t hif_handle_isr(void)
  676. {
  677. int8_t ret = M2M_SUCCESS;
  678. ret = hif_isr();
  679. if (M2M_SUCCESS != ret)
  680. {
  681. M2M_ERR("(hif) Failed to handle interrupt %d try Again..\r\n",ret);
  682. }
  683. return ret;
  684. }
  685. /**
  686. * @fn hif_receive
  687. * @brief Host interface interrupt service routine
  688. * @param[in] u32Addr
  689. * Receive start address
  690. * @param[out] pu8Buf
  691. * Pointer to receive buffer. Allocated by the caller
  692. * @param[in] u16Sz
  693. * Receive buffer size
  694. * @param[in] isDone
  695. * If you don't need any more packets send True otherwise send false
  696. * @return The function shall return ZERO for successful operation and a negative value otherwise.
  697. */
  698. int8_t hif_receive(uint32_t u32Addr, uint8_t *pu8Buf, uint16_t u16Sz, uint8_t isDone)
  699. {
  700. int8_t ret = M2M_SUCCESS;
  701. if((u32Addr == 0) || (pu8Buf == NULL) || (u16Sz == 0))
  702. {
  703. if(isDone)
  704. {
  705. ret = hif_set_rx_done();
  706. }
  707. else
  708. {
  709. ret = M2M_ERR_FAIL;
  710. M2M_ERR(" hif_receive: Invalid argument\r\n");
  711. }
  712. goto ERR1;
  713. }
  714. if(u16Sz > gstrHifCxt.u32RxSize)
  715. {
  716. ret = M2M_ERR_FAIL;
  717. M2M_ERR("APP Requested Size is larger than the received buffer size <%d><%" PRId32 ">\r\n", u16Sz, gstrHifCxt.u32RxSize);
  718. goto ERR1;
  719. }
  720. if((u32Addr < gstrHifCxt.u32RxAddr)||((u32Addr + u16Sz)>(gstrHifCxt.u32RxAddr+gstrHifCxt.u32RxSize)))
  721. {
  722. ret = M2M_ERR_FAIL;
  723. M2M_ERR("APP Requested Address beyond the received buffer address and length\r\n");
  724. goto ERR1;
  725. }
  726. /* Receive the payload */
  727. ret = nm_read_block(u32Addr, pu8Buf, u16Sz);
  728. if(ret != M2M_SUCCESS)goto ERR1;
  729. /* check if this is the last packet */
  730. if(
  731. isDone
  732. || (((gstrHifCxt.u32RxAddr+gstrHifCxt.u32RxSize) - (u32Addr+u16Sz)) <= 3)
  733. /* Length in the RCV CTRL 0 register is rounded off to 4 by the firmware,
  734. but length inside the HIF header is not, hence consider done if fewer than
  735. 4 bytes left to read */
  736. )
  737. {
  738. /* set RX done */
  739. ret = hif_set_rx_done();
  740. }
  741. ERR1:
  742. return ret;
  743. }
  744. /**
  745. * @fn hif_register_cb
  746. * @brief To set Callback function for every component
  747. * @param[in] u8Grp
  748. * Group to which the Callback function should be set.
  749. * @param[in] fn
  750. * function to be set
  751. * @return The function shall return ZERO for successful operation and a negative value otherwise.
  752. */
  753. int8_t hif_register_cb(uint8_t u8Grp, tpfHifCallBack fn)
  754. {
  755. int8_t ret = M2M_SUCCESS;
  756. switch(u8Grp)
  757. {
  758. case M2M_REQ_GROUP_IP:
  759. gstrHifCxt.pfIpCb = fn;
  760. break;
  761. case M2M_REQ_GROUP_WIFI:
  762. gstrHifCxt.pfWifiCb = fn;
  763. break;
  764. case M2M_REQ_GROUP_OTA:
  765. gstrHifCxt.pfOtaCb = fn;
  766. break;
  767. case M2M_REQ_GROUP_HIF:
  768. gstrHifCxt.pfHifCb = fn;
  769. break;
  770. case M2M_REQ_GROUP_SIGMA:
  771. gstrHifCxt.pfSigmaCb = fn;
  772. break;
  773. case M2M_REQ_GROUP_SSL:
  774. gstrHifCxt.pfSslCb = fn;
  775. break;
  776. default:
  777. M2M_ERR("GRp ? %d\r\n", u8Grp);
  778. ret = M2M_ERR_FAIL;
  779. break;
  780. }
  781. return ret;
  782. }
  783. //DOM-IGNORE-END