Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.
 
 
 
 

742 Zeilen
16 KiB

  1. /**
  2. *
  3. * \file
  4. *
  5. * \brief This module contains WINC3400 ASIC specific internal APIs.
  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. #include "common/include/nm_common.h"
  35. #include "driver/source/nmbus.h"
  36. #include "bsp/include/nm_bsp.h"
  37. #include "driver/source/nmasic.h"
  38. #define NMI_GLB_RESET_0 (NMI_PERIPH_REG_BASE + 0x400)
  39. #define NMI_INTR_REG_BASE (NMI_PERIPH_REG_BASE + 0xa00)
  40. #define NMI_PIN_MUX_0 (NMI_PERIPH_REG_BASE + 0x408)
  41. #define NMI_INTR_ENABLE (NMI_INTR_REG_BASE)
  42. #define GET_UINT32(X,Y) (X[0+Y] + ((uint32)X[1+Y]<<8) + ((uint32)X[2+Y]<<16) +((uint32)X[3+Y]<<24))
  43. #define TIMEOUT (2000)
  44. #define M2M_DISABLE_PS 0xD0UL
  45. /* Assume initially we're dealing with D0 - we will try other addresses if this
  46. * fails - the addresses are as follows:
  47. * 0x13 - for D0
  48. * 0x0F - for B0
  49. * 0x0E - for A0
  50. */
  51. static uint32 clk_status_reg_adr = 0x13;
  52. sint8 chip_apply_conf(uint32 u32Conf)
  53. {
  54. sint8 ret = M2M_SUCCESS;
  55. uint32 val32 = u32Conf;
  56. #ifdef __ENABLE_PMU__
  57. val32 |= rHAVE_USE_PMU_BIT;
  58. #endif
  59. #ifdef __ENABLE_SLEEP_CLK_SRC_RTC__
  60. val32 |= rHAVE_SLEEP_CLK_SRC_RTC_BIT;
  61. #elif defined __ENABLE_SLEEP_CLK_SRC_XO__
  62. val32 |= rHAVE_SLEEP_CLK_SRC_XO_BIT;
  63. #endif
  64. #ifdef __ENABLE_EXT_PA_INV_TX_RX__
  65. val32 |= rHAVE_EXT_PA_INV_TX_RX;
  66. #endif
  67. #ifdef __ENABLE_LEGACY_RF_SETTINGS__
  68. val32 |= rHAVE_LEGACY_RF_SETTINGS;
  69. #endif
  70. #ifdef __DISABLE_FIRMWARE_LOGS__
  71. val32 |= rHAVE_LOGS_DISABLED_BIT;
  72. #endif
  73. do {
  74. nm_write_reg(rNMI_GP_REG_1, val32);
  75. if(val32 != 0) {
  76. uint32 reg = 0;
  77. ret = nm_read_reg_with_ret(rNMI_GP_REG_1, &reg);
  78. if(ret == M2M_SUCCESS) {
  79. if(reg == val32)
  80. break;
  81. }
  82. } else {
  83. break;
  84. }
  85. } while(1);
  86. return M2M_SUCCESS;
  87. }
  88. /**
  89. * @fn nm_clkless_wake
  90. * @brief Wakeup the chip using clockless registers
  91. * @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
  92. * @author Samer Sarhan
  93. * @date 06 June 2014
  94. * @version 1.0
  95. */
  96. sint8 nm_clkless_wake(void)
  97. {
  98. sint8 ret = M2M_SUCCESS;
  99. uint32 reg, clk_status_reg,trials = 0;
  100. uint32 keeptrying = 200;
  101. /* wait 1ms, spi data read */
  102. nm_bsp_sleep(1);
  103. ret = nm_read_reg_with_ret(0x1, &reg);
  104. if(ret != M2M_SUCCESS) {
  105. M2M_ERR("Bus error (1). Wake up failed\n");
  106. return ret;
  107. }
  108. /*
  109. * At this point, I am not sure whether it is B0 or A0
  110. * If B0, then clks_enabled bit exists in register 0xf
  111. * If A0, then clks_enabled bit exists in register 0xe
  112. */
  113. do
  114. {
  115. /* Set bit 1 */
  116. nm_write_reg(0x1, reg | (1 << 1));
  117. // Search for the correct (clock status) register address
  118. do
  119. {
  120. if (keeptrying) --keeptrying;
  121. /* wait 1ms, spi data read */
  122. nm_bsp_sleep(1);
  123. ret = nm_read_reg_with_ret(clk_status_reg_adr, &clk_status_reg);
  124. if (ret != M2M_SUCCESS || (ret == M2M_SUCCESS && clk_status_reg == 0)) {
  125. switch (clk_status_reg_adr) {
  126. case 0x13: clk_status_reg_adr = 0x0F; break;
  127. case 0x0F: clk_status_reg_adr = 0x0E; break;
  128. default: clk_status_reg_adr = 0x00; break;
  129. }
  130. }
  131. else
  132. break; // we have found the correct register, break out of the search
  133. } while (clk_status_reg_adr && keeptrying);
  134. if (0 == clk_status_reg_adr) {
  135. M2M_ERR("Bus error (2). Wake up failed\n");
  136. return ret;
  137. }
  138. // in case of clocks off, wait 2ms, and check it again.
  139. // if still off, wait for another 2ms, for a total wait of 6ms.
  140. // If still off, redo the wake up sequence
  141. trials = 0;
  142. while( ((clk_status_reg & 0x4) == 0) && (((++trials) %3) == 0) && keeptrying)
  143. {
  144. --keeptrying;
  145. /* Wait for the chip to stabilize*/
  146. nm_bsp_sleep(2);
  147. // Make sure chip is awake. This is an extra step that can be removed
  148. // later to avoid the bus access overhead
  149. nm_read_reg_with_ret(clk_status_reg_adr, &clk_status_reg);
  150. if ((clk_status_reg & 0x4) == 0)
  151. {
  152. M2M_ERR("clocks still OFF. Wake up failed\n");
  153. }
  154. }
  155. // in case of failure, Reset the wakeup bit to introduce a new edge on the next loop
  156. if((clk_status_reg & 0x4) == 0)
  157. {
  158. // Reset bit 0
  159. nm_write_reg(0x1, reg | (1 << 1));
  160. }
  161. } while((clk_status_reg & 0x4) == 0 && keeptrying);
  162. if (!keeptrying)
  163. {
  164. M2M_ERR("Wake up failed - out of retries\n");
  165. ret = M2M_ERR_INIT;
  166. }
  167. return ret;
  168. }
  169. void chip_idle(void)
  170. {
  171. uint32 reg =0;
  172. nm_read_reg_with_ret(0x1, &reg);
  173. if(reg&0x2)
  174. {
  175. reg &=~(1 << 1);
  176. nm_write_reg(0x1, reg);
  177. }
  178. }
  179. void enable_rf_blocks(void)
  180. {
  181. nm_write_reg(0x6, 0xdb);
  182. nm_write_reg(0x7, 0x6);
  183. nm_bsp_sleep(10);
  184. nm_write_reg(0x1480, 0);
  185. nm_write_reg(0x1484, 0);
  186. nm_bsp_sleep(10);
  187. nm_write_reg(0x6, 0x0);
  188. nm_write_reg(0x7, 0x0);
  189. }
  190. sint8 enable_interrupts(void)
  191. {
  192. uint32 reg;
  193. sint8 ret;
  194. /**
  195. interrupt pin mux select
  196. **/
  197. ret = nm_read_reg_with_ret(NMI_PIN_MUX_0, &reg);
  198. if (M2M_SUCCESS != ret) {
  199. return M2M_ERR_BUS_FAIL;
  200. }
  201. reg |= ((uint32) 1 << 8);
  202. ret = nm_write_reg(NMI_PIN_MUX_0, reg);
  203. if (M2M_SUCCESS != ret) {
  204. return M2M_ERR_BUS_FAIL;
  205. }
  206. /**
  207. interrupt enable
  208. **/
  209. ret = nm_read_reg_with_ret(NMI_INTR_ENABLE, &reg);
  210. if (M2M_SUCCESS != ret) {
  211. return M2M_ERR_BUS_FAIL;
  212. }
  213. reg |= ((uint32) 1 << 16);
  214. ret = nm_write_reg(NMI_INTR_ENABLE, reg);
  215. if (M2M_SUCCESS != ret) {
  216. return M2M_ERR_BUS_FAIL;
  217. }
  218. return M2M_SUCCESS;
  219. }
  220. sint8 cpu_start(void) {
  221. uint32 reg;
  222. sint8 ret;
  223. /**
  224. reset regs
  225. */
  226. nm_write_reg(BOOTROM_REG,0);
  227. nm_write_reg(NMI_STATE_REG,0);
  228. nm_write_reg(NMI_REV_REG,0);
  229. /**
  230. Go...
  231. **/
  232. ret = nm_read_reg_with_ret(0x1118, &reg);
  233. if (M2M_SUCCESS != ret) {
  234. ret = M2M_ERR_BUS_FAIL;
  235. M2M_ERR("[nmi start]: fail read reg 0x1118 ...\n");
  236. }
  237. reg |= (1 << 0);
  238. ret = nm_write_reg(0x1118, reg);
  239. ret = nm_write_reg(0x150014, 0x1);
  240. ret += nm_read_reg_with_ret(NMI_GLB_RESET_0, &reg);
  241. if ((reg & (1ul << 10)) == (1ul << 10)) {
  242. reg &= ~(1ul << 10);
  243. ret += nm_write_reg(NMI_GLB_RESET_0, reg);
  244. }
  245. reg |= (1ul << 10);
  246. ret += nm_write_reg(NMI_GLB_RESET_0, reg);
  247. nm_bsp_sleep(1); /* TODO: Why bus error if this delay is not here. */
  248. return ret;
  249. }
  250. uint32 nmi_get_chipid(void)
  251. {
  252. static uint32 chipid = 0;
  253. if (chipid == 0) {
  254. uint32 rfrevid;
  255. if((nm_read_reg_with_ret(0x1000, &chipid)) != M2M_SUCCESS) {
  256. chipid = 0;
  257. return 0;
  258. }
  259. if((nm_read_reg_with_ret(0x13f4, &rfrevid)) != M2M_SUCCESS) {
  260. chipid = 0;
  261. return 0;
  262. }
  263. if(chipid == 0x1002a0) {
  264. if (rfrevid == 0x1) { /* 1002A0 */
  265. } else /* if (rfrevid == 0x2) */ { /* 1002A1 */
  266. chipid = 0x1002a1;
  267. }
  268. } else if(chipid == 0x1002b0) {
  269. if(rfrevid == 3) { /* 1002B0 */
  270. } else if(rfrevid == 4) { /* 1002B1 */
  271. chipid = 0x1002b1;
  272. } else /* if(rfrevid == 5) */ { /* 1002B2 */
  273. chipid = 0x1002b2;
  274. }
  275. } else if(chipid == 0x1000f0) {
  276. /* For 3400, the WiFi chip ID register reads 0x1000f0.
  277. * Therefore using BT chip ID register here which should read 0x3000D0
  278. */
  279. #define rBT_CHIP_ID_REG (0x3b0000)
  280. if((nm_read_reg_with_ret(rBT_CHIP_ID_REG, &chipid)) != M2M_SUCCESS) {
  281. chipid = 0;
  282. return 0;
  283. }
  284. if(chipid == 0x3000d0) {
  285. if(rfrevid == 6) {
  286. chipid = 0x3000d1;
  287. }
  288. else if(rfrevid == 2) {
  289. chipid = 0x3000d2;
  290. }
  291. }
  292. }
  293. //#define PROBE_FLASH
  294. #ifdef PROBE_FLASH
  295. if(chipid) {
  296. UWORD32 flashid;
  297. flashid = probe_spi_flash();
  298. if((chipid & 0xf00000) == 0x300000) {
  299. if(flashid == 0x1440ef) {
  300. chipid &= ~(0x0f0000);
  301. chipid |= 0x040000;
  302. }
  303. } else {
  304. if(flashid == 0x1230ef) {
  305. chipid &= ~(0x0f0000);
  306. chipid |= 0x050000;
  307. }
  308. if(flashid == 0xc21320c2) {
  309. chipid &= ~(0x0f0000);
  310. chipid |= 0x050000;
  311. }
  312. }
  313. }
  314. #else
  315. /*M2M is by default have SPI flash*/
  316. if((chipid & 0xf00000) == 0x300000) {
  317. chipid &= ~(0x0f0000);
  318. chipid |= 0x040000;
  319. } else {
  320. chipid &= ~(0x0f0000);
  321. chipid |= 0x050000;
  322. }
  323. #endif /* PROBE_FLASH */
  324. }
  325. return chipid;
  326. }
  327. uint32 nmi_get_rfrevid(void)
  328. {
  329. uint32 rfrevid;
  330. if((nm_read_reg_with_ret(0x13f4, &rfrevid)) != M2M_SUCCESS) {
  331. rfrevid = 0;
  332. return 0;
  333. }
  334. return rfrevid;
  335. }
  336. void restore_pmu_settings_after_global_reset(void)
  337. {
  338. /*
  339. * Must restore PMU register value after
  340. * global reset if PMU toggle is done at
  341. * least once since the last hard reset.
  342. */
  343. if(REV(nmi_get_chipid()) >= REV_2B0) {
  344. nm_write_reg(0x1e48, 0xb78469ce);
  345. }
  346. }
  347. void nmi_update_pll(void)
  348. {
  349. uint32 pll;
  350. pll = nm_read_reg(0x1428);
  351. pll &= ~0x1ul;
  352. nm_write_reg(0x1428, pll);
  353. pll |= 0x1ul;
  354. nm_write_reg(0x1428, pll);
  355. }
  356. void nmi_set_sys_clk_src_to_xo(void)
  357. {
  358. uint32 val32;
  359. /* Switch system clock source to XO. This will take effect after nmi_update_pll(). */
  360. val32 = nm_read_reg(0x141c);
  361. val32 |= (1 << 2);
  362. nm_write_reg(0x141c, val32);
  363. /* Do PLL update */
  364. nmi_update_pll();
  365. }
  366. sint8 chip_wake(void)
  367. {
  368. sint8 ret = M2M_SUCCESS;
  369. ret = nm_clkless_wake();
  370. if(ret != M2M_SUCCESS) return ret;
  371. // enable_rf_blocks(); MERGEBUG: TEMPORARILY DISABLING
  372. return ret;
  373. }
  374. sint8 chip_reset_and_cpu_halt(void)
  375. {
  376. sint8 ret = M2M_SUCCESS;
  377. uint32 reg = 0;
  378. ret = chip_wake();
  379. if(ret != M2M_SUCCESS) {
  380. return ret;
  381. }
  382. chip_reset();
  383. ret = nm_read_reg_with_ret(0x1118, &reg);
  384. if (M2M_SUCCESS != ret) {
  385. ret = M2M_ERR_BUS_FAIL;
  386. M2M_ERR("[nmi start]: fail read reg 0x1118 ...\n");
  387. }
  388. reg |= (1 << 0);
  389. ret = nm_write_reg(0x1118, reg);
  390. ret += nm_read_reg_with_ret(NMI_GLB_RESET_0, &reg);
  391. if ((reg & (1ul << 10)) == (1ul << 10)) {
  392. reg &= ~(1ul << 10);
  393. ret += nm_write_reg(NMI_GLB_RESET_0, reg);
  394. ret += nm_read_reg_with_ret(NMI_GLB_RESET_0, &reg);
  395. }
  396. #if 0
  397. reg |= (1ul << 10);
  398. ret += nm_write_reg(NMI_GLB_RESET_0, reg);
  399. ret += nm_read_reg_with_ret(NMI_GLB_RESET_0, &reg);
  400. #endif
  401. nm_write_reg(BOOTROM_REG,0);
  402. nm_write_reg(NMI_STATE_REG,0);
  403. nm_write_reg(NMI_REV_REG,0);
  404. nm_write_reg(NMI_PIN_MUX_0, 0x11111000);
  405. return ret;
  406. }
  407. sint8 chip_reset(void)
  408. {
  409. sint8 ret = M2M_SUCCESS;
  410. #if 0
  411. // MERGEBUG: TODO: This causes serial trace from the chip to be garbled - investigate
  412. #ifndef CONF_WINC_USE_UART
  413. nmi_set_sys_clk_src_to_xo();
  414. #endif
  415. #endif
  416. ret += nm_write_reg(NMI_GLB_RESET_0, 0);
  417. nm_bsp_sleep(50);
  418. #ifndef CONF_WINC_USE_UART
  419. restore_pmu_settings_after_global_reset();
  420. #endif
  421. return ret;
  422. }
  423. sint8 wait_for_bootrom(uint8 arg)
  424. {
  425. sint8 ret = M2M_SUCCESS;
  426. uint32 reg = 0, cnt = 0;
  427. reg = 0;
  428. while(1) {
  429. reg = nm_read_reg(0x1014); /* wait for efuse loading done */
  430. if (reg & 0x80000000) {
  431. break;
  432. }
  433. nm_bsp_sleep(1); /* TODO: Why bus error if this delay is not here. */
  434. }
  435. reg = nm_read_reg(M2M_WAIT_FOR_HOST_REG);
  436. reg &= 0x1;
  437. /* check if waiting for the host will be skipped or not */
  438. if(reg == 0)
  439. {
  440. reg = 0;
  441. while(reg != M2M_FINISH_BOOT_ROM)
  442. {
  443. nm_bsp_sleep(1);
  444. reg = nm_read_reg(BOOTROM_REG);
  445. if(++cnt > TIMEOUT)
  446. {
  447. M2M_DBG("failed to load firmware from flash.\n");
  448. ret = M2M_ERR_INIT;
  449. goto ERR2;
  450. }
  451. }
  452. }
  453. if(2 == arg) {
  454. nm_write_reg(NMI_REV_REG, M2M_ATE_FW_START_VALUE);
  455. } else {
  456. /*bypass this step*/
  457. }
  458. if(REV(nmi_get_chipid()) == REV_3A0)
  459. {
  460. chip_apply_conf(rHAVE_USE_PMU_BIT);
  461. }
  462. else
  463. {
  464. chip_apply_conf(0);
  465. }
  466. nm_write_reg(BOOTROM_REG,M2M_START_FIRMWARE);
  467. #ifdef __ROM_TEST__
  468. rom_test();
  469. #endif /* __ROM_TEST__ */
  470. ERR2:
  471. return ret;
  472. }
  473. sint8 wait_for_firmware_start(uint8 arg)
  474. {
  475. sint8 ret = M2M_SUCCESS;
  476. uint32 reg = 0, cnt = 0;
  477. volatile uint32 regAddress = NMI_STATE_REG;
  478. volatile uint32 checkValue = M2M_FINISH_INIT_STATE;
  479. if(2 == arg) {
  480. regAddress = NMI_REV_REG;
  481. checkValue = M2M_ATE_FW_IS_UP_VALUE;
  482. } else {
  483. /*bypass this step*/
  484. }
  485. while (checkValue != reg)
  486. {
  487. nm_bsp_sleep(2); /* TODO: Why bus error if this delay is not here. */
  488. M2M_DBG("%x %x %x\n",(unsigned int)nm_read_reg(0x108c),(unsigned int)nm_read_reg(0x108c),(unsigned int)nm_read_reg(0x14A0));
  489. if (nm_read_reg_with_ret(regAddress, &reg) != M2M_SUCCESS)
  490. {
  491. // ensure reg != checkValue
  492. reg = !checkValue;
  493. }
  494. if(++cnt > TIMEOUT)
  495. {
  496. M2M_DBG("Time out for wait firmware Run\n");
  497. ret = M2M_ERR_INIT;
  498. goto ERR;
  499. }
  500. }
  501. if(M2M_FINISH_INIT_STATE == checkValue)
  502. {
  503. nm_write_reg(NMI_STATE_REG, 0);
  504. }
  505. ERR:
  506. return ret;
  507. }
  508. sint8 chip_deinit(void)
  509. {
  510. uint32 reg = 0;
  511. sint8 ret;
  512. uint8 timeout = 10;
  513. /**
  514. stop the firmware, need a re-download
  515. **/
  516. ret = nm_read_reg_with_ret(NMI_GLB_RESET_0, &reg);
  517. if (ret != M2M_SUCCESS) {
  518. M2M_ERR("failed to de-initialize\n");
  519. }
  520. reg &= ~(1 << 10);
  521. ret = nm_write_reg(NMI_GLB_RESET_0, reg);
  522. if (ret != M2M_SUCCESS) {
  523. M2M_ERR("Error while writing reg\n");
  524. return ret;
  525. }
  526. do {
  527. ret = nm_read_reg_with_ret(NMI_GLB_RESET_0, &reg);
  528. if (ret != M2M_SUCCESS) {
  529. M2M_ERR("Error while reading reg\n");
  530. return ret;
  531. }
  532. /*Workaround to ensure that the chip is actually reset*/
  533. if ((reg & (1 << 10))) {
  534. M2M_DBG("Bit 10 not reset retry %d\n", timeout);
  535. reg &= ~(1 << 10);
  536. ret = nm_write_reg(NMI_GLB_RESET_0, reg);
  537. timeout--;
  538. } else {
  539. break;
  540. }
  541. } while (timeout);
  542. return ret;
  543. }
  544. #ifdef CONF_PERIPH
  545. sint8 set_gpio_dir(uint8 gpio, uint8 dir)
  546. {
  547. uint32 val32;
  548. sint8 ret;
  549. ret = nm_read_reg_with_ret(0x20108, &val32);
  550. if(ret != M2M_SUCCESS) goto _EXIT;
  551. if(dir) {
  552. val32 |= (1ul << gpio);
  553. } else {
  554. val32 &= ~(1ul << gpio);
  555. }
  556. ret = nm_write_reg(0x20108, val32);
  557. _EXIT:
  558. return ret;
  559. }
  560. sint8 set_gpio_val(uint8 gpio, uint8 val)
  561. {
  562. uint32 val32;
  563. sint8 ret;
  564. ret = nm_read_reg_with_ret(0x20100, &val32);
  565. if(ret != M2M_SUCCESS) goto _EXIT;
  566. if(val) {
  567. val32 |= (1ul << gpio);
  568. } else {
  569. val32 &= ~(1ul << gpio);
  570. }
  571. ret = nm_write_reg(0x20100, val32);
  572. _EXIT:
  573. return ret;
  574. }
  575. sint8 get_gpio_val(uint8 gpio, uint8* val)
  576. {
  577. uint32 val32;
  578. sint8 ret;
  579. ret = nm_read_reg_with_ret(0x20104, &val32);
  580. if(ret != M2M_SUCCESS) goto _EXIT;
  581. *val = (uint8)((val32 >> gpio) & 0x01);
  582. _EXIT:
  583. return ret;
  584. }
  585. sint8 pullup_ctrl(uint32 pinmask, uint8 enable)
  586. {
  587. sint8 s8Ret;
  588. uint32 val32;
  589. s8Ret = nm_read_reg_with_ret(0x142c, &val32);
  590. if(s8Ret != M2M_SUCCESS) {
  591. M2M_ERR("[pullup_ctrl]: failed to read\n");
  592. goto _EXIT;
  593. }
  594. if(enable) {
  595. val32 &= ~pinmask;
  596. } else {
  597. val32 |= pinmask;
  598. }
  599. s8Ret = nm_write_reg(0x142c, val32);
  600. if(s8Ret != M2M_SUCCESS) {
  601. M2M_ERR("[pullup_ctrl]: failed to write\n");
  602. goto _EXIT;
  603. }
  604. _EXIT:
  605. return s8Ret;
  606. }
  607. #endif /* CONF_PERIPH */
  608. sint8 nmi_get_otp_mac_address(uint8 *pu8MacAddr, uint8 * pu8IsValid)
  609. {
  610. sint8 ret;
  611. uint32 u32RegValue;
  612. uint8 mac[6];
  613. tstrGpRegs strgp = {0};
  614. ret = nm_read_reg_with_ret(rNMI_GP_REG_0, &u32RegValue);
  615. if(ret != M2M_SUCCESS) goto _EXIT_ERR;
  616. ret = nm_read_block(u32RegValue|0x30000,(uint8*)&strgp,sizeof(tstrGpRegs));
  617. if(ret != M2M_SUCCESS) goto _EXIT_ERR;
  618. u32RegValue = strgp.u32Mac_efuse_mib;
  619. if(!EFUSED_MAC(u32RegValue)) {
  620. M2M_DBG("Default MAC\n");
  621. m2m_memset(pu8MacAddr, 0, 6);
  622. goto _EXIT_ERR;
  623. }
  624. M2M_DBG("OTP MAC\n");
  625. u32RegValue >>=16;
  626. ret = nm_read_block(u32RegValue|0x30000, mac, 6);
  627. m2m_memcpy(pu8MacAddr,mac,6);
  628. if(pu8IsValid) *pu8IsValid = 1;
  629. return ret;
  630. _EXIT_ERR:
  631. if(pu8IsValid) *pu8IsValid = 0;
  632. return ret;
  633. }
  634. sint8 nmi_get_mac_address(uint8 *pu8MacAddr)
  635. {
  636. sint8 ret;
  637. uint32 u32RegValue;
  638. uint8 mac[6];
  639. tstrGpRegs strgp = {0};
  640. ret = nm_read_reg_with_ret(rNMI_GP_REG_0, &u32RegValue);
  641. if(ret != M2M_SUCCESS) goto _EXIT_ERR;
  642. ret = nm_read_block(u32RegValue|0x30000,(uint8*)&strgp,sizeof(tstrGpRegs));
  643. if(ret != M2M_SUCCESS) goto _EXIT_ERR;
  644. u32RegValue = strgp.u32Mac_efuse_mib;
  645. u32RegValue &=0x0000ffff;
  646. ret = nm_read_block(u32RegValue|0x30000, mac, 6);
  647. m2m_memcpy(pu8MacAddr, mac, 6);
  648. return ret;
  649. _EXIT_ERR:
  650. return ret;
  651. }