Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.
 
 
 
 

410 строки
12 KiB

  1. /*******************************************************************************
  2. File Name:
  3. nmdrv.c
  4. Summary:
  5. This module contains WINC3400 M2M driver APIs implementation.
  6. Description:
  7. This module contains WINC3400 M2M driver APIs implementation.
  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 "nm_bsp.h"
  35. #include "nmdrv.h"
  36. #include "nmasic.h"
  37. #include "m2m_types.h"
  38. #include "nmspi.h"
  39. static tenuNmState genuNmState = NM_STATE_DEINIT;
  40. /**
  41. * @fn nm_get_hif_info(uint16_t *pu16FwHifInfo, uint16_t *pu16OtaHifInfo);
  42. * @brief Get Hif info of images in both partitions (Firmware and Ota).
  43. * @param[out] pu16FwHifInfo
  44. * Pointer holding Hif info of image in the active partition.
  45. * @param[out] pu16OtaHifInfo
  46. * Pointer holding Hif info of image in the inactive partition.
  47. * @return @ref M2M_SUCCESS in case of success and Negative error code in case of failure
  48. */
  49. int8_t nm_get_hif_info(uint16_t *pu16FwHifInfo, uint16_t *pu16OtaHifInfo)
  50. {
  51. int8_t ret = M2M_SUCCESS;
  52. uint32_t reg = 0;
  53. ret = nm_read_reg_with_ret(NMI_REV_REG, &reg);
  54. if(ret == M2M_SUCCESS)
  55. {
  56. if(pu16FwHifInfo != NULL)
  57. {
  58. *pu16FwHifInfo = (uint16_t)reg;
  59. }
  60. if(pu16OtaHifInfo)
  61. {
  62. *pu16OtaHifInfo = (uint16_t)(reg>>16);
  63. }
  64. }
  65. return ret;
  66. }
  67. /**
  68. * @fn nm_get_firmware_full_info(tstrM2mRev* M2mRev)
  69. * @brief Get Firmware version info
  70. * @param[out] M2mRev
  71. * Pointer holds address of structure @ref tstrM2mRev that contains the firmware version parameters
  72. */
  73. int8_t nm_get_firmware_full_info(tstrM2mRev *pstrRev)
  74. {
  75. uint16_t fw_hif_info = 0;
  76. uint32_t reg = 0;
  77. int8_t ret = M2M_SUCCESS;
  78. tstrGpRegs strgp = {0};
  79. memset((uint8_t*)pstrRev, 0, sizeof(tstrM2mRev));
  80. nm_get_hif_info(&fw_hif_info, NULL);
  81. M2M_INFO("Fw HIF: %04x\r\n", fw_hif_info);
  82. if(M2M_GET_HIF_BLOCK(fw_hif_info) == M2M_HIF_BLOCK_VALUE)
  83. {
  84. ret = nm_read_reg_with_ret(rNMI_GP_REG_0, &reg);
  85. if(ret == M2M_SUCCESS)
  86. {
  87. if(reg != 0)
  88. {
  89. ret = nm_read_block(reg|0x30000, (uint8_t*)&strgp, sizeof(tstrGpRegs));
  90. if(ret == M2M_SUCCESS)
  91. {
  92. reg = strgp.u32Firmware_Ota_rev;
  93. reg &= 0x0000ffff;
  94. if(reg != 0)
  95. {
  96. ret = nm_read_block(reg|0x30000, (uint8_t*)pstrRev, sizeof(tstrM2mRev));
  97. if(ret == M2M_SUCCESS)
  98. {
  99. M2M_INFO("Firmware HIF (%u) : %u.%u\r\n", M2M_GET_HIF_BLOCK(pstrRev->u16FirmwareHifInfo), M2M_GET_HIF_MAJOR(pstrRev->u16FirmwareHifInfo), M2M_GET_HIF_MINOR(pstrRev->u16FirmwareHifInfo));
  100. M2M_INFO("Firmware ver : %u.%u.%u\r\n", pstrRev->u8FirmwareMajor, pstrRev->u8FirmwareMinor, pstrRev->u8FirmwarePatch);
  101. M2M_INFO("Firmware Build %s Time %s\r\n", pstrRev->BuildDate, pstrRev->BuildTime);
  102. /* Check Hif info is consistent */
  103. if(fw_hif_info != pstrRev->u16FirmwareHifInfo)
  104. {
  105. ret = M2M_ERR_FAIL;
  106. M2M_ERR("Inconsistent Firmware Version\r\n");
  107. }
  108. }
  109. }
  110. else
  111. {
  112. ret = M2M_ERR_FAIL;
  113. }
  114. }
  115. }
  116. else
  117. {
  118. ret = M2M_ERR_FAIL;
  119. }
  120. }
  121. }
  122. else
  123. {
  124. ret = M2M_ERR_FAIL;
  125. }
  126. if(ret != M2M_SUCCESS)
  127. {
  128. M2M_ERR("Unknown Firmware Version\r\n");
  129. }
  130. return ret;
  131. }
  132. /**
  133. * @fn nm_get_ota_firmware_info(tstrM2mRev* pstrRev)
  134. * @brief Get Firmware version info
  135. * @param[out] M2mRev
  136. * Pointer holds address of structure @ref tstrM2mRev that contains the firmware version parameters
  137. */
  138. int8_t nm_get_ota_firmware_info(tstrM2mRev *pstrRev)
  139. {
  140. uint16_t ota_hif_info = 0;
  141. uint32_t reg = 0;
  142. int8_t ret = M2M_SUCCESS;
  143. tstrGpRegs strgp = {0};
  144. memset((uint8_t*)pstrRev, 0, sizeof(tstrM2mRev));
  145. nm_get_hif_info(NULL, &ota_hif_info);
  146. M2M_INFO("OTA HIF: %04x\r\n", ota_hif_info);
  147. if(M2M_GET_HIF_BLOCK(ota_hif_info) == M2M_HIF_BLOCK_VALUE)
  148. {
  149. ret = nm_read_reg_with_ret(rNMI_GP_REG_0, &reg);
  150. if(ret == M2M_SUCCESS)
  151. {
  152. if(reg != 0)
  153. {
  154. ret = nm_read_block(reg|0x30000, (uint8_t*)&strgp, sizeof(tstrGpRegs));
  155. if(ret == M2M_SUCCESS)
  156. {
  157. reg = strgp.u32Firmware_Ota_rev;
  158. reg >>= 16;
  159. if(reg != 0)
  160. {
  161. ret = nm_read_block(reg|0x30000, (uint8_t*)pstrRev, sizeof(tstrM2mRev));
  162. if(ret == M2M_SUCCESS)
  163. {
  164. M2M_INFO("OTA HIF (%u) : %u.%u\r\n", M2M_GET_HIF_BLOCK(pstrRev->u16FirmwareHifInfo), M2M_GET_HIF_MAJOR(pstrRev->u16FirmwareHifInfo), M2M_GET_HIF_MINOR(pstrRev->u16FirmwareHifInfo));
  165. M2M_INFO("OTA ver : %u.%u.%u\r\n", pstrRev->u8FirmwareMajor, pstrRev->u8FirmwareMinor, pstrRev->u8FirmwarePatch);
  166. M2M_INFO("OTA Build %s Time %s\r\n", pstrRev->BuildDate, pstrRev->BuildTime);
  167. /* Check Hif info is consistent */
  168. if(ota_hif_info != pstrRev->u16FirmwareHifInfo)
  169. {
  170. ret = M2M_ERR_FAIL;
  171. M2M_ERR("Inconsistent OTA Version\r\n");
  172. }
  173. }
  174. }
  175. else
  176. {
  177. ret = M2M_ERR_FAIL;
  178. }
  179. }
  180. }
  181. else
  182. {
  183. ret = M2M_ERR_FAIL;
  184. }
  185. }
  186. }
  187. else
  188. {
  189. ret = M2M_ERR_FAIL;
  190. }
  191. if(ret != M2M_SUCCESS)
  192. {
  193. M2M_INFO("No valid OTA image\r\n");
  194. }
  195. return ret;
  196. }
  197. /**
  198. * @fn nm_drv_init_download_mode
  199. * @brief Initialize NMC1000 driver in download mode
  200. * @return @ref M2M_SUCCESS in case of success and Negative error code in case of failure
  201. */
  202. int8_t nm_drv_init_download_mode(void)
  203. {
  204. int8_t ret = M2M_SUCCESS;
  205. ret = nm_bus_iface_init(NULL);
  206. if (M2M_SUCCESS != ret) {
  207. M2M_ERR("[nmi start]: fail init bus\r\n");
  208. goto ERR1;
  209. }
  210. nm_spi_lock_init();
  211. /* Must do this after global reset to set SPI data packet size. */
  212. nm_spi_init();
  213. M2M_INFO("Chip ID %lx\r\n", nmi_get_chipid());
  214. /*disable all interrupt in ROM (to disable uart) in 2b0 chip*/
  215. nm_write_reg(0x20300, 0);
  216. genuNmState = NM_STATE_INIT;
  217. ERR1:
  218. return ret;
  219. }
  220. int8_t nm_drv_init_hold(void)
  221. {
  222. int8_t ret = M2M_SUCCESS;
  223. nm_spi_lock_init();
  224. ret = nm_bus_iface_init(NULL);
  225. if (M2M_SUCCESS != ret) {
  226. M2M_ERR("[nmi start]: fail init bus\r\n");
  227. goto ERR1;
  228. }
  229. #ifdef BUS_ONLY
  230. return;
  231. #endif
  232. #ifdef NO_HW_CHIP_EN
  233. ret = chip_wake();
  234. nm_sleep(10);
  235. if (M2M_SUCCESS != ret) {
  236. M2M_ERR("[nmi start]: fail chip_wakeup\r\n");
  237. goto ERR2;
  238. }
  239. /**
  240. Go...
  241. **/
  242. ret = chip_reset();
  243. if (M2M_SUCCESS != ret) {
  244. goto ERR2;
  245. }
  246. #endif
  247. M2M_INFO("Chip ID %lx\r\n", nmi_get_chipid());
  248. /* Must do this after global reset to set SPI data packet size. */
  249. nm_spi_init();
  250. /*return power save to default value*/
  251. chip_idle();
  252. genuNmState = NM_STATE_INIT;
  253. return ret;
  254. #ifdef NO_HW_CHIP_EN
  255. ERR2:
  256. nm_bus_iface_deinit();
  257. #endif
  258. ERR1:
  259. return ret;
  260. }
  261. int8_t nm_drv_init_start(void * arg)
  262. {
  263. int8_t ret = M2M_SUCCESS;
  264. uint8_t u8Mode = M2M_WIFI_MODE_NORMAL;
  265. if(NULL != arg)
  266. {
  267. u8Mode = *((uint8_t *)arg);
  268. if(u8Mode < M2M_WIFI_MODE_NORMAL || u8Mode >= M2M_WIFI_MODE_MAX)
  269. u8Mode = M2M_WIFI_MODE_NORMAL;
  270. }
  271. ret = cpu_start();
  272. if (M2M_SUCCESS != ret) {
  273. goto ERR2;
  274. }
  275. ret = wait_for_bootrom(u8Mode);
  276. if (M2M_SUCCESS != ret) {
  277. goto ERR2;
  278. }
  279. ret = wait_for_firmware_start(u8Mode);
  280. if (M2M_SUCCESS != ret) {
  281. goto ERR2;
  282. }
  283. if(M2M_WIFI_MODE_CONFIG == u8Mode) {
  284. goto ERR1;
  285. } else {
  286. /*continue running*/
  287. }
  288. ret = enable_interrupts();
  289. if (M2M_SUCCESS != ret) {
  290. M2M_ERR("failed to enable interrupts..\r\n");
  291. goto ERR2;
  292. }
  293. genuNmState = NM_STATE_START;
  294. return ret;
  295. ERR2:
  296. nm_bus_iface_deinit();
  297. nm_spi_deinit();
  298. ERR1:
  299. return ret;
  300. }
  301. /**
  302. * @fn nm_drv_init
  303. * @brief Initialize NMC1000 driver
  304. * @param[in] arg
  305. * Generic argument passed on to nm_drv_init_start
  306. * @return @ref M2M_SUCCESS in case of success and Negative error code in case of failure
  307. */
  308. int8_t nm_drv_init(void* arg)
  309. {
  310. int8_t ret = M2M_SUCCESS;
  311. ret = nm_drv_init_hold();
  312. if(ret == M2M_SUCCESS)
  313. ret = nm_drv_init_start(arg);
  314. return ret;
  315. }
  316. /**
  317. * @fn nm_drv_deinit
  318. * @brief Deinitialize NMC1000 driver
  319. */
  320. int8_t nm_drv_deinit(void* arg)
  321. {
  322. int8_t ret;
  323. ret = chip_deinit();
  324. if (M2M_SUCCESS != ret) {
  325. M2M_ERR("[nmi stop]: chip_deinit fail\r\n");
  326. goto ERR1;
  327. }
  328. ret = nm_bus_iface_deinit();
  329. if (M2M_SUCCESS != ret) {
  330. M2M_ERR("[nmi stop]: fail init bus\r\n");
  331. goto ERR1;
  332. }
  333. /* Must do this after global reset to set SPI data packet size. */
  334. nm_spi_deinit();
  335. ERR1:
  336. genuNmState = NM_STATE_DEINIT;
  337. return ret;
  338. }
  339. /**
  340. * @fn nm_cpu_start(void)
  341. * @brief Start CPU from the WINC module
  342. * @return @ref M2M_SUCCESS in case of success and Negative error code in case of failure
  343. */
  344. int8_t nm_cpu_start(void)
  345. {
  346. int8_t ret;
  347. ret = cpu_start();
  348. return ret;
  349. }
  350. /**
  351. * @fn nm_get_state(void)
  352. * @brief Get the current state of the WINC module
  353. * @return The current state of the WINC module
  354. */
  355. tenuNmState nm_get_state(void)
  356. {
  357. return genuNmState;
  358. }
  359. //DOM-IGNORE-END