You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

380 lines
11 KiB

  1. /**
  2. *
  3. * \file
  4. *
  5. * \brief This module contains NMC1000 M2M driver APIs implementation.
  6. *
  7. * Copyright (c) 2015 - 2017 Atmel Corporation. All rights reserved.
  8. *
  9. * \asf_license_start
  10. *
  11. * \page License
  12. *
  13. * Redistribution and use in source and binary forms, with or without
  14. * modification, are permitted provided that the following conditions are met:
  15. *
  16. * 1. Redistributions of source code must retain the above copyright notice,
  17. * this list of conditions and the following disclaimer.
  18. *
  19. * 2. Redistributions in binary form must reproduce the above copyright notice,
  20. * this list of conditions and the following disclaimer in the documentation
  21. * and/or other materials provided with the distribution.
  22. *
  23. * 3. The name of Atmel may not be used to endorse or promote products derived
  24. * from this software without specific prior written permission.
  25. *
  26. * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
  27. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  28. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
  29. * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
  30. * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  31. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  32. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  33. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  34. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  35. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  36. * POSSIBILITY OF SUCH DAMAGE.
  37. *
  38. * \asf_license_stop
  39. *
  40. */
  41. #include "common/include/nm_common.h"
  42. #include "driver/source/nmbus.h"
  43. #include "bsp/include/nm_bsp.h"
  44. #include "driver/source/nmdrv.h"
  45. #include "driver/source/nmasic.h"
  46. #include "driver/include/m2m_types.h"
  47. #include "spi_flash/include/spi_flash.h"
  48. #ifdef CONF_WINC_USE_SPI
  49. #include "driver/source/nmspi.h"
  50. #endif
  51. /**
  52. * @fn nm_get_firmware_info(tstrM2mRev* M2mRev)
  53. * @brief Get Firmware version info
  54. * @param [out] M2mRev
  55. * pointer holds address of structure "tstrM2mRev" that contains the firmware version parameters
  56. * @version 1.0
  57. */
  58. sint8 nm_get_firmware_info(tstrM2mRev *M2mRev)
  59. {
  60. uint16 curr_drv_ver, min_req_drv_ver, curr_firm_ver;
  61. uint32 reg = 0;
  62. sint8 ret = M2M_SUCCESS;
  63. ret = nm_read_reg_with_ret(NMI_REV_REG, &reg);
  64. // In case the Firmware running is ATE fw
  65. if (M2M_ATE_FW_IS_UP_VALUE == reg) {
  66. // Read FW info again from the register specified for ATE
  67. ret = nm_read_reg_with_ret(NMI_REV_REG_ATE, &reg);
  68. }
  69. M2mRev->u8DriverMajor = M2M_GET_DRV_MAJOR(reg);
  70. M2mRev->u8DriverMinor = M2M_GET_DRV_MINOR(reg);
  71. M2mRev->u8DriverPatch = M2M_GET_DRV_PATCH(reg);
  72. M2mRev->u8FirmwareMajor = M2M_GET_FW_MAJOR(reg);
  73. M2mRev->u8FirmwareMinor = M2M_GET_FW_MINOR(reg);
  74. M2mRev->u8FirmwarePatch = M2M_GET_FW_PATCH(reg);
  75. M2mRev->u32Chipid = nmi_get_chipid();
  76. M2mRev->u16FirmwareSvnNum = 0;
  77. curr_firm_ver = M2M_MAKE_VERSION(M2mRev->u8FirmwareMajor, M2mRev->u8FirmwareMinor, M2mRev->u8FirmwarePatch);
  78. curr_drv_ver
  79. = M2M_MAKE_VERSION(M2M_RELEASE_VERSION_MAJOR_NO, M2M_RELEASE_VERSION_MINOR_NO, M2M_RELEASE_VERSION_PATCH_NO);
  80. min_req_drv_ver = M2M_MAKE_VERSION(M2mRev->u8DriverMajor, M2mRev->u8DriverMinor, M2mRev->u8DriverPatch);
  81. if (curr_drv_ver < min_req_drv_ver) {
  82. /*The current driver version should be larger or equal
  83. than the min driver that the current firmware support */
  84. ret = M2M_ERR_FW_VER_MISMATCH;
  85. }
  86. if (curr_drv_ver > curr_firm_ver) {
  87. /*The current driver should be equal or less than the firmware version*/
  88. ret = M2M_ERR_FW_VER_MISMATCH;
  89. }
  90. return ret;
  91. }
  92. /**
  93. * @fn nm_get_firmware_info(tstrM2mRev* M2mRev)
  94. * @brief Get Firmware version info
  95. * @param [out] M2mRev
  96. * pointer holds address of structure "tstrM2mRev" that contains the firmware version parameters
  97. * @version 1.0
  98. */
  99. sint8 nm_get_firmware_full_info(tstrM2mRev *pstrRev)
  100. {
  101. uint16 curr_drv_ver, min_req_drv_ver, curr_firm_ver;
  102. uint32 reg = 0;
  103. sint8 ret = M2M_SUCCESS;
  104. tstrGpRegs strgp = {0};
  105. if (pstrRev != NULL) {
  106. m2m_memset((uint8 *)pstrRev, 0, sizeof(tstrM2mRev));
  107. ret = nm_read_reg_with_ret(rNMI_GP_REG_2, &reg);
  108. if (ret == M2M_SUCCESS) {
  109. if (reg != 0) {
  110. ret = nm_read_block(reg | 0x30000, (uint8 *)&strgp, sizeof(tstrGpRegs));
  111. if (ret == M2M_SUCCESS) {
  112. reg = strgp.u32Firmware_Ota_rev;
  113. reg &= 0x0000ffff;
  114. if (reg != 0) {
  115. ret = nm_read_block(reg | 0x30000, (uint8 *)pstrRev, sizeof(tstrM2mRev));
  116. if (ret == M2M_SUCCESS) {
  117. curr_firm_ver = M2M_MAKE_VERSION(
  118. pstrRev->u8FirmwareMajor, pstrRev->u8FirmwareMinor, pstrRev->u8FirmwarePatch);
  119. curr_drv_ver = M2M_MAKE_VERSION(M2M_RELEASE_VERSION_MAJOR_NO,
  120. M2M_RELEASE_VERSION_MINOR_NO,
  121. M2M_RELEASE_VERSION_PATCH_NO);
  122. min_req_drv_ver = M2M_MAKE_VERSION(
  123. pstrRev->u8DriverMajor, pstrRev->u8DriverMinor, pstrRev->u8DriverPatch);
  124. if ((curr_firm_ver == 0) || (min_req_drv_ver == 0) || (min_req_drv_ver == 0)) {
  125. ret = M2M_ERR_FAIL;
  126. goto EXIT;
  127. }
  128. if (curr_drv_ver < min_req_drv_ver) {
  129. /*The current driver version should be larger or equal
  130. than the min driver that the current firmware support */
  131. ret = M2M_ERR_FW_VER_MISMATCH;
  132. goto EXIT;
  133. }
  134. if (curr_drv_ver > curr_firm_ver) {
  135. /*The current driver should be equal or less than the firmware version*/
  136. ret = M2M_ERR_FW_VER_MISMATCH;
  137. goto EXIT;
  138. }
  139. }
  140. } else {
  141. ret = M2M_ERR_FAIL;
  142. }
  143. }
  144. } else {
  145. ret = M2M_ERR_FAIL;
  146. }
  147. }
  148. }
  149. EXIT:
  150. return ret;
  151. }
  152. /**
  153. * @fn nm_get_ota_firmware_info(tstrM2mRev* pstrRev)
  154. * @brief Get Firmware version info
  155. * @param [out] M2mRev
  156. * pointer holds address of structure "tstrM2mRev" that contains the firmware version parameters
  157. * @version 1.0
  158. */
  159. sint8 nm_get_ota_firmware_info(tstrM2mRev *pstrRev)
  160. {
  161. uint16 curr_drv_ver, min_req_drv_ver, curr_firm_ver;
  162. uint32 reg = 0;
  163. sint8 ret;
  164. tstrGpRegs strgp = {0};
  165. if (pstrRev != NULL) {
  166. m2m_memset((uint8 *)pstrRev, 0, sizeof(tstrM2mRev));
  167. ret = nm_read_reg_with_ret(rNMI_GP_REG_2, &reg);
  168. if (ret == M2M_SUCCESS) {
  169. if (reg != 0) {
  170. ret = nm_read_block(reg | 0x30000, (uint8 *)&strgp, sizeof(tstrGpRegs));
  171. if (ret == M2M_SUCCESS) {
  172. reg = strgp.u32Firmware_Ota_rev;
  173. reg >>= 16;
  174. if (reg != 0) {
  175. ret = nm_read_block(reg | 0x30000, (uint8 *)pstrRev, sizeof(tstrM2mRev));
  176. if (ret == M2M_SUCCESS) {
  177. curr_firm_ver = M2M_MAKE_VERSION(
  178. pstrRev->u8FirmwareMajor, pstrRev->u8FirmwareMinor, pstrRev->u8FirmwarePatch);
  179. curr_drv_ver = M2M_MAKE_VERSION(M2M_RELEASE_VERSION_MAJOR_NO,
  180. M2M_RELEASE_VERSION_MINOR_NO,
  181. M2M_RELEASE_VERSION_PATCH_NO);
  182. min_req_drv_ver = M2M_MAKE_VERSION(
  183. pstrRev->u8DriverMajor, pstrRev->u8DriverMinor, pstrRev->u8DriverPatch);
  184. if ((curr_firm_ver == 0) || (min_req_drv_ver == 0) || (min_req_drv_ver == 0)) {
  185. ret = M2M_ERR_FAIL;
  186. goto EXIT;
  187. }
  188. if (curr_drv_ver < min_req_drv_ver) {
  189. /*The current driver version should be larger or equal
  190. than the min driver that the current firmware support */
  191. ret = M2M_ERR_FW_VER_MISMATCH;
  192. }
  193. if (curr_drv_ver > curr_firm_ver) {
  194. /*The current driver should be equal or less than the firmware version*/
  195. ret = M2M_ERR_FW_VER_MISMATCH;
  196. }
  197. }
  198. } else {
  199. ret = M2M_ERR_INVALID;
  200. }
  201. }
  202. } else {
  203. ret = M2M_ERR_FAIL;
  204. }
  205. }
  206. } else {
  207. ret = M2M_ERR_INVALID_ARG;
  208. }
  209. EXIT:
  210. return ret;
  211. }
  212. /*
  213. * @fn nm_drv_init_download_mode
  214. * @brief Initialize NMC1000 driver
  215. * @return M2M_SUCCESS in case of success and Negative error code in case of failure
  216. * @param [in] arg
  217. * Generic argument
  218. * @author Viswanathan Murugesan
  219. * @date 10 Oct 2014
  220. * @version 1.0
  221. */
  222. sint8 nm_drv_init_download_mode()
  223. {
  224. sint8 ret = M2M_SUCCESS;
  225. ret = nm_bus_iface_init(NULL);
  226. if (M2M_SUCCESS != ret) {
  227. M2M_ERR("[nmi start]: fail init bus\n");
  228. goto ERR1;
  229. }
  230. /**
  231. TODO:reset the chip and halt the cpu in case of no wait efuse is set (add the no wait effuse check)
  232. */
  233. if (!ISNMC3000(GET_CHIPID())) {
  234. /*Execuate that function only for 1500A/B, no room in 3000, but it may be needed in 3400 no wait*/
  235. chip_reset_and_cpu_halt();
  236. }
  237. #ifdef CONF_WINC_USE_SPI
  238. /* Must do this after global reset to set SPI data packet size. */
  239. nm_spi_init();
  240. #endif
  241. M2M_INFO("Chip ID %lx\n", nmi_get_chipid());
  242. /*disable all interrupt in ROM (to disable uart) in 2b0 chip*/
  243. nm_write_reg(0x20300, 0);
  244. ERR1:
  245. return ret;
  246. }
  247. /*
  248. * @fn nm_drv_init
  249. * @brief Initialize NMC1000 driver
  250. * @return M2M_SUCCESS in case of success and Negative error code in case of failure
  251. * @param [in] arg
  252. * Generic argument
  253. * @author M. Abdelmawla
  254. * @date 15 July 2012
  255. * @version 1.0
  256. */
  257. sint8 nm_drv_init(void *arg)
  258. {
  259. sint8 ret = M2M_SUCCESS;
  260. uint8 u8Mode;
  261. if (NULL != arg) {
  262. u8Mode = *((uint8 *)arg);
  263. if ((u8Mode < M2M_WIFI_MODE_NORMAL) || (u8Mode >= M2M_WIFI_MODE_MAX)) {
  264. u8Mode = M2M_WIFI_MODE_NORMAL;
  265. }
  266. } else {
  267. u8Mode = M2M_WIFI_MODE_NORMAL;
  268. }
  269. ret = nm_bus_iface_init(NULL);
  270. if (M2M_SUCCESS != ret) {
  271. M2M_ERR("[nmi start]: fail init bus\n");
  272. goto ERR1;
  273. }
  274. #ifdef BUS_ONLY
  275. return;
  276. #endif
  277. #ifdef NO_HW_CHIP_EN
  278. ret = chip_wake();
  279. if (M2M_SUCCESS != ret) {
  280. M2M_ERR("[nmi start]: fail chip_wakeup\n");
  281. goto ERR2;
  282. }
  283. /**
  284. Go...
  285. **/
  286. ret = chip_reset();
  287. if (M2M_SUCCESS != ret) {
  288. goto ERR2;
  289. }
  290. #endif
  291. // M2M_INFO("Chip ID %lx\n", nmi_get_chipid());
  292. #ifdef CONF_WINC_USE_SPI
  293. /* Must do this after global reset to set SPI data packet size. */
  294. nm_spi_init();
  295. #endif
  296. ret = wait_for_bootrom(u8Mode);
  297. if (M2M_SUCCESS != ret) {
  298. goto ERR2;
  299. }
  300. ret = wait_for_firmware_start(u8Mode);
  301. if (M2M_SUCCESS != ret) {
  302. goto ERR2;
  303. }
  304. if ((M2M_WIFI_MODE_ATE_HIGH == u8Mode) || (M2M_WIFI_MODE_ATE_LOW == u8Mode)) {
  305. goto ERR1;
  306. } else {
  307. /*continue running*/
  308. }
  309. ret = enable_interrupts();
  310. if (M2M_SUCCESS != ret) {
  311. M2M_ERR("failed to enable interrupts..\n");
  312. goto ERR2;
  313. }
  314. return ret;
  315. ERR2:
  316. nm_bus_iface_deinit();
  317. ERR1:
  318. return ret;
  319. }
  320. /*
  321. * @fn nm_drv_deinit
  322. * @brief Deinitialize NMC1000 driver
  323. * @author M. Abdelmawla
  324. * @date 17 July 2012
  325. * @version 1.0
  326. */
  327. sint8 nm_drv_deinit(void *arg)
  328. {
  329. sint8 ret;
  330. ret = chip_deinit();
  331. if (M2M_SUCCESS != ret) {
  332. M2M_ERR("[nmi stop]: chip_deinit fail\n");
  333. goto ERR1;
  334. }
  335. /* Disable SPI flash to save power when the chip is off */
  336. ret = spi_flash_enable(0);
  337. if (M2M_SUCCESS != ret) {
  338. M2M_ERR("[nmi stop]: SPI flash disable fail\n");
  339. goto ERR1;
  340. }
  341. ret = nm_bus_iface_deinit();
  342. if (M2M_SUCCESS != ret) {
  343. M2M_ERR("[nmi stop]: fail init bus\n");
  344. goto ERR1;
  345. }
  346. #ifdef CONF_WINC_USE_SPI
  347. /* Must do this after global reset to set SPI data packet size. */
  348. nm_spi_deinit();
  349. #endif
  350. ERR1:
  351. return ret;
  352. }