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.
 
 
 
 

586 Zeilen
13 KiB

  1. /**
  2. *
  3. * \file
  4. *
  5. * \brief This module contains WINC3400 UART protocol bus APIs implementation.
  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. #ifdef CONF_WINC_USE_UART
  36. #include "driver/source/nmuart.h"
  37. #include "bus_wrapper/include/nm_bus_wrapper.h"
  38. #define HDR_SZ 12
  39. static uint8 get_cs(uint8* b, uint8 sz){
  40. int i;
  41. uint8 cs = 0;
  42. for(i = 0; i < sz; i++)
  43. cs ^= b[i];
  44. return cs;
  45. }
  46. /*
  47. * @fn nm_uart_sync_cmd
  48. * @brief Check COM Port
  49. * @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
  50. * @author Dina El Sissy
  51. * @date 13 AUG 2012
  52. * @version 1.0
  53. */
  54. sint8 nm_uart_sync_cmd(void)
  55. {
  56. tstrNmUartDefault strUart;
  57. sint8 s8Ret = M2M_ERR_BUS_FAIL;
  58. uint8 b [HDR_SZ+1];
  59. uint8 onchip = 0;
  60. int escape = 3;
  61. // send query char up to 3 times
  62. while (escape-- && (s8Ret != M2M_SUCCESS))
  63. {
  64. b[0] = 0x12;
  65. strUart.pu8Buf = b;
  66. strUart.u16Sz = 1;
  67. // then read back all chars in the buffer if any, is last char what we are looking for
  68. s8Ret = nm_bus_ioctl(NM_BUS_IOCTL_W, &strUart);
  69. if (M2M_SUCCESS == s8Ret)
  70. {
  71. uint8 lastchar;
  72. // drain buffer
  73. while (M2M_SUCCESS == s8Ret)
  74. {
  75. lastchar = b[0];
  76. s8Ret = nm_bus_ioctl(NM_BUS_IOCTL_R, &strUart);
  77. }
  78. switch (lastchar)
  79. {
  80. case 0x5a:
  81. onchip = 1;
  82. M2M_INFO("Built-in WINCxx00 UART Found\n");
  83. s8Ret = M2M_SUCCESS;
  84. break;
  85. case 0x5b:
  86. onchip = 0;
  87. M2M_INFO("WINCxx00 Serial Bridge Found\n");
  88. s8Ret = M2M_SUCCESS;
  89. break;
  90. case 0x5c:
  91. onchip = 2;
  92. M2M_INFO("WINCxx00 Serial Bridge + AT CMD app Found\n");
  93. s8Ret = M2M_SUCCESS;
  94. break;
  95. case 0x12:
  96. M2M_INFO("failed to read Serial Bridge ID response\n");
  97. s8Ret = M2M_ERR_BUS_FAIL;
  98. break;
  99. default:
  100. M2M_INFO("Non Serial Bridge Found\n");
  101. s8Ret = M2M_ERR_BUS_FAIL;
  102. break;
  103. }
  104. }
  105. else
  106. {
  107. M2M_ERR("failed to send Serial Bridge ID Query\n");
  108. }
  109. }
  110. if(s8Ret == M2M_SUCCESS)
  111. s8Ret = (sint8)onchip;
  112. return s8Ret;
  113. }
  114. /*
  115. * @fn nm_uart_reboot_cmd
  116. * @brief Sends a command to the MCU to force reboot
  117. * @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
  118. * @version 1.0
  119. */
  120. sint8 nm_uart_reboot_cmd(void)
  121. {
  122. tstrNmUartDefault strUart;
  123. sint8 s8Ret = M2M_SUCCESS;
  124. uint8 b[HDR_SZ + 1];
  125. uint8 rsz;
  126. uint8 onchip = 0;
  127. /*read reg*/
  128. b[0] = 0x13;
  129. rsz = 1;
  130. strUart.pu8Buf = b;
  131. strUart.u16Sz = 1;
  132. if (M2M_SUCCESS != nm_bus_ioctl(NM_BUS_IOCTL_W, &strUart))
  133. {
  134. M2M_ERR("failed to send reboot cmd\n");
  135. s8Ret = M2M_ERR_BUS_FAIL;
  136. }
  137. return s8Ret;
  138. }
  139. sint8 nm_uart_read_reg_with_ret(uint32 u32Addr, uint32* pu32RetVal)
  140. {
  141. tstrNmUartDefault strUart;
  142. sint8 s8Ret = M2M_SUCCESS;
  143. uint8 b [HDR_SZ+1];
  144. uint8 rsz;
  145. /*read reg*/
  146. b[0] = 0xa5;
  147. b[1] = 0;
  148. b[2] = 0;
  149. b[3] = 0;
  150. b[4] = 0;
  151. b[5] = (uint8)(u32Addr & 0x000000ff);
  152. b[6] = (uint8)((u32Addr & 0x0000ff00)>>8);
  153. b[7] = (uint8)((u32Addr & 0x00ff0000)>>16);
  154. b[8] = (uint8)((u32Addr & 0xff000000)>>24);
  155. b[9] = 0;
  156. b[10] = 0;
  157. b[11] = 0;
  158. b[12] = 0;
  159. b[2] = get_cs(&b[1],HDR_SZ);
  160. rsz = 4;
  161. strUart.pu8Buf = b;
  162. strUart.u16Sz = sizeof(b);
  163. if(M2M_SUCCESS == nm_bus_ioctl(NM_BUS_IOCTL_W, &strUart))
  164. {
  165. if(!nm_bus_get_chip_type())
  166. {
  167. strUart.u16Sz = 1;
  168. if(M2M_SUCCESS != nm_bus_ioctl(NM_BUS_IOCTL_R, &strUart))
  169. {
  170. s8Ret = M2M_ERR_BUS_FAIL;
  171. }
  172. if(b[0] == 0xAC)
  173. {
  174. M2M_DBG("Successfully sent the command\n");
  175. strUart.u16Sz = rsz;
  176. if(M2M_SUCCESS != nm_bus_ioctl(NM_BUS_IOCTL_R, &strUart))
  177. {
  178. s8Ret = M2M_ERR_BUS_FAIL;
  179. }
  180. }
  181. else
  182. {
  183. s8Ret = M2M_ERR_BUS_FAIL;
  184. }
  185. }
  186. else
  187. {
  188. strUart.u16Sz = rsz;
  189. if(M2M_SUCCESS != nm_bus_ioctl(NM_BUS_IOCTL_R, &strUart))
  190. {
  191. s8Ret = M2M_ERR_BUS_FAIL;
  192. }
  193. }
  194. }
  195. else
  196. {
  197. M2M_ERR("failed to send cfg bytes\n");
  198. s8Ret = M2M_ERR_BUS_FAIL;
  199. }
  200. *pu32RetVal = ((uint32)b[0] << 24) | ((uint32)b[1] << 16) | ((uint32)b[2] << 8) | b[3];
  201. return s8Ret;
  202. }
  203. /*
  204. * @fn nm_uart_read_reg
  205. * @brief Read register
  206. * @param [in] u32Addr
  207. * Register address
  208. * @return Register value
  209. * @author Dina El Sissy
  210. * @date 13 AUG 2012
  211. * @version 1.0
  212. */
  213. uint32 nm_uart_read_reg(uint32 u32Addr)
  214. {
  215. uint32 val;
  216. nm_uart_read_reg_with_ret(u32Addr , &val);
  217. return val;
  218. }
  219. /*
  220. * @fn nm_uart_write_reg
  221. * @brief write register
  222. * @param [in] u32Addr
  223. * Register address
  224. * @param [in] u32Val
  225. * Value to be written to the register
  226. * @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
  227. * @author Dina El Sissy
  228. * @date 13 AUG 2012
  229. * @version 1.0
  230. */
  231. sint8 nm_uart_write_reg(uint32 u32Addr, uint32 u32Val)
  232. {
  233. tstrNmUartDefault strUart;
  234. sint8 s8Ret = M2M_SUCCESS;
  235. uint8 b[HDR_SZ+1];
  236. /*write reg*/
  237. b[0] = 0xa5;
  238. b[1] = 1;
  239. b[2] = 0;
  240. b[3] = 0;
  241. b[4] = 0;
  242. b[5] = (uint8)(u32Addr & 0x000000ff);
  243. b[6] = (uint8)((u32Addr & 0x0000ff00)>>8);
  244. b[7] = (uint8)((u32Addr & 0x00ff0000)>>16);
  245. b[8] = (uint8)((u32Addr & 0xff000000)>>24);
  246. b[9] = (uint8)(u32Val & 0x000000ff);
  247. b[10] = (uint8)((u32Val & 0x0000ff00)>>8);
  248. b[11] = (uint8)((u32Val & 0x00ff0000)>>16);
  249. b[12] = (uint8)((u32Val & 0xff000000)>>24);
  250. b[2] = get_cs(&b[1],HDR_SZ);
  251. get_cs(&b[1],HDR_SZ);
  252. strUart.pu8Buf = b;
  253. strUart.u16Sz = sizeof(b);
  254. if(M2M_SUCCESS != nm_bus_ioctl(NM_BUS_IOCTL_W, &strUart))
  255. {
  256. M2M_ERR("write error\n");
  257. s8Ret = M2M_ERR_BUS_FAIL;
  258. }
  259. else
  260. {
  261. if(!nm_bus_get_chip_type())
  262. {
  263. //check for the ack from the SAMD21 for the packet reception.
  264. strUart.u16Sz = 1;
  265. if(M2M_SUCCESS != nm_bus_ioctl(NM_BUS_IOCTL_R, &strUart))
  266. {
  267. s8Ret = M2M_ERR_BUS_FAIL;
  268. }
  269. if(b[0] == 0xAC)
  270. {
  271. M2M_DBG("Successfully sent the reg write command\n");
  272. }
  273. else
  274. {
  275. M2M_ERR("write error\n");
  276. s8Ret = M2M_ERR_BUS_FAIL;
  277. }
  278. }
  279. }
  280. return s8Ret;
  281. }
  282. /**
  283. * @fn nm_uart_read_block
  284. * @brief Read block of data
  285. * @param [in] u32Addr
  286. * Start address
  287. * @param [out] puBuf
  288. * Pointer to a buffer used to return the read data
  289. * @param [in] u16Sz
  290. * Number of bytes to read. The buffer size must be >= u16Sz
  291. * @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
  292. * @author Dina El Sissy
  293. * @date 13 AUG 2012
  294. * @version 1.0
  295. */
  296. sint8 nm_uart_read_block(uint32 u32Addr, uint8 *pu8Buf, uint16 u16Sz)
  297. {
  298. tstrNmUartDefault strUart;
  299. sint8 s8Ret = M2M_SUCCESS;
  300. uint8 au8Buf[HDR_SZ+1];
  301. au8Buf[0] = 0xa5;
  302. au8Buf[1] = 2;
  303. au8Buf[2] = 0;
  304. au8Buf[3] = (uint8)(u16Sz & 0x00ff);
  305. au8Buf[4] = (uint8)((u16Sz & 0xff00)>>8);
  306. au8Buf[5] = (uint8)(u32Addr & 0x000000ff);
  307. au8Buf[6] = (uint8)((u32Addr & 0x0000ff00)>>8);
  308. au8Buf[7] = (uint8)((u32Addr & 0x00ff0000)>>16);
  309. au8Buf[8] = (uint8)((u32Addr & 0xff000000)>>24);
  310. au8Buf[9] = 0;
  311. au8Buf[10] = 0;
  312. au8Buf[11] = 0;
  313. au8Buf[12] = 0;
  314. au8Buf[2] = get_cs(&au8Buf[1],HDR_SZ);
  315. strUart.pu8Buf = au8Buf;
  316. strUart.u16Sz = sizeof(au8Buf);
  317. if(M2M_SUCCESS != nm_bus_ioctl(NM_BUS_IOCTL_W, &strUart))
  318. {
  319. M2M_ERR("write error\n");
  320. s8Ret = M2M_ERR_BUS_FAIL;
  321. }
  322. else
  323. {
  324. if(!nm_bus_get_chip_type())
  325. {
  326. //check for the ack from the SAMD21 for the packet reception.
  327. strUart.u16Sz = 1;
  328. if(M2M_SUCCESS != nm_bus_ioctl(NM_BUS_IOCTL_R, &strUart))
  329. {
  330. s8Ret = M2M_ERR_BUS_FAIL;
  331. }
  332. if(au8Buf[0] == 0xAC)
  333. {
  334. M2M_DBG("Successfully sent the block read command\n");
  335. strUart.pu8Buf = pu8Buf;
  336. strUart.u16Sz = u16Sz;
  337. if(M2M_SUCCESS != nm_bus_ioctl(NM_BUS_IOCTL_R, &strUart))
  338. {
  339. M2M_ERR("read error\n");
  340. s8Ret = M2M_ERR_BUS_FAIL;
  341. }
  342. }
  343. else
  344. {
  345. M2M_ERR("write error (Error sending the block read command)\n");
  346. s8Ret = M2M_ERR_BUS_FAIL;
  347. }
  348. }
  349. else
  350. {
  351. strUart.pu8Buf = pu8Buf;
  352. strUart.u16Sz = u16Sz;
  353. if(M2M_SUCCESS != nm_bus_ioctl(NM_BUS_IOCTL_R, &strUart))
  354. {
  355. M2M_ERR("read error\n");
  356. s8Ret = M2M_ERR_BUS_FAIL;
  357. }
  358. }
  359. }
  360. return s8Ret;
  361. }
  362. /**
  363. * @fn nm_uart_write_block
  364. * @brief Write block of data
  365. * @param [in] u32Addr
  366. * Start address
  367. * @param [in] puBuf
  368. * Pointer to the buffer holding the data to be written
  369. * @param [in] u16Sz
  370. * Number of bytes to write. The buffer size must be >= u16Sz
  371. * @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
  372. * @author Dina El Sissy
  373. * @date 13 AUG 2012
  374. * @version 1.0
  375. */
  376. sint8 nm_uart_write_block(uint32 u32Addr, uint8 *puBuf, uint16 u16Sz)
  377. {
  378. tstrNmUartDefault strUart;
  379. sint8 s8Ret = M2M_SUCCESS;
  380. static uint8 au8Buf[HDR_SZ+1];
  381. au8Buf[0] = 0xa5;
  382. au8Buf[1] = 3;
  383. au8Buf[2] = 0;
  384. au8Buf[3] = (uint8)(u16Sz & 0x00ff);
  385. au8Buf[4] = (uint8)((u16Sz & 0xff00)>>8);
  386. au8Buf[5] = (uint8)(u32Addr & 0x000000ff);
  387. au8Buf[6] = (uint8)((u32Addr & 0x0000ff00)>>8);
  388. au8Buf[7] = (uint8)((u32Addr & 0x00ff0000)>>16);
  389. au8Buf[8] = (uint8)((u32Addr & 0xff000000)>>24);
  390. au8Buf[9] = 0;
  391. au8Buf[10] = 0;
  392. au8Buf[11] = 0;
  393. au8Buf[12] = 0;
  394. au8Buf[2] = get_cs(&au8Buf[1],HDR_SZ);
  395. strUart.pu8Buf = au8Buf;
  396. strUart.u16Sz = sizeof(au8Buf);
  397. if(M2M_SUCCESS != nm_bus_ioctl(NM_BUS_IOCTL_W, &strUart))
  398. {
  399. M2M_ERR("write error\n");
  400. s8Ret = M2M_ERR_BUS_FAIL;
  401. }
  402. else
  403. {
  404. if(!nm_bus_get_chip_type())
  405. {
  406. //check for the ack from the SAMD21 for the packet reception.
  407. strUart.u16Sz = 1;
  408. if(M2M_SUCCESS != nm_bus_ioctl(NM_BUS_IOCTL_R, &strUart))
  409. {
  410. s8Ret = M2M_ERR_BUS_FAIL;
  411. }
  412. if(au8Buf[0] == 0xAC)
  413. {
  414. M2M_DBG("Successfully sent the block Write command\n");
  415. strUart.pu8Buf = puBuf;
  416. strUart.u16Sz = u16Sz;
  417. if(M2M_SUCCESS != nm_bus_ioctl(NM_BUS_IOCTL_W, &strUart))
  418. {
  419. M2M_ERR("write error\n");
  420. s8Ret = M2M_ERR_BUS_FAIL;
  421. }
  422. else
  423. {
  424. //check for the ack from the SAMD21 for the payload reception.
  425. strUart.pu8Buf = au8Buf;
  426. strUart.u16Sz = 1;
  427. if(M2M_SUCCESS != nm_bus_ioctl(NM_BUS_IOCTL_R, &strUart))
  428. {
  429. s8Ret = M2M_ERR_BUS_FAIL;
  430. }
  431. if(au8Buf[0] == 0xAC)
  432. {
  433. M2M_DBG("Successfully sent the data payload\n");
  434. }
  435. else
  436. {
  437. M2M_ERR("write error\n");
  438. s8Ret = M2M_ERR_BUS_FAIL;
  439. }
  440. }
  441. }
  442. else
  443. {
  444. M2M_ERR("write error (Error sending the block write command)\n");
  445. s8Ret = M2M_ERR_BUS_FAIL;
  446. }
  447. }
  448. else
  449. {
  450. strUart.pu8Buf = puBuf;
  451. strUart.u16Sz = u16Sz;
  452. if(M2M_SUCCESS != nm_bus_ioctl(NM_BUS_IOCTL_W, &strUart))
  453. {
  454. M2M_ERR("write error\n");
  455. s8Ret = M2M_ERR_BUS_FAIL;
  456. }
  457. }
  458. }
  459. return s8Ret;
  460. }
  461. /**
  462. * @fn nm_uart_reconfigure
  463. * @brief Reconfigures the UART interface
  464. * @param [in] ptr
  465. * Pointer to a DWORD containing baudrate at this moment.
  466. * @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
  467. * @author Viswanathan Murugesan
  468. * @date 22 OCT 2014
  469. * @version 1.0
  470. */
  471. sint8 nm_uart_reconfigure(void *ptr)
  472. {
  473. tstrNmUartDefault strUart;
  474. sint8 s8Ret = M2M_SUCCESS;
  475. uint8 b[HDR_SZ+1];
  476. if (ptr == NULL)
  477. {
  478. M2M_ERR("port not open\n");
  479. return M2M_ERR_BUS_FAIL;
  480. }
  481. /*write reg*/
  482. b[0] = 0xa5;
  483. b[1] = 5;
  484. b[2] = 0;
  485. b[3] = 0;
  486. b[4] = 0;
  487. b[5] = 0;
  488. b[6] = 0;
  489. b[7] = 0;
  490. b[8] = 0;
  491. b[9] = (uint8)((*(unsigned long *)ptr) & 0x000000ff);
  492. b[10] = (uint8)(((*(unsigned long *)ptr) & 0x0000ff00)>>8);
  493. b[11] = (uint8)(((*(unsigned long *)ptr) & 0x00ff0000)>>16);
  494. b[12] = (uint8)(((*(unsigned long *)ptr) & 0xff000000)>>24);
  495. b[2] = get_cs(&b[1],HDR_SZ);
  496. get_cs(&b[1],HDR_SZ);
  497. strUart.pu8Buf = b;
  498. strUart.u16Sz = sizeof(b);
  499. if(M2M_SUCCESS != nm_bus_ioctl(NM_BUS_IOCTL_W, &strUart))
  500. {
  501. M2M_ERR("write error\n");
  502. s8Ret = M2M_ERR_BUS_FAIL;
  503. }
  504. else
  505. {
  506. if(!nm_bus_get_chip_type())
  507. {
  508. //check for the ack from the SAMD21 for the packet reception.
  509. strUart.u16Sz = 1;
  510. if(M2M_SUCCESS != nm_bus_ioctl(NM_BUS_IOCTL_R, &strUart))
  511. {
  512. s8Ret = M2M_ERR_BUS_FAIL;
  513. }
  514. if(b[0] == 0xAC)
  515. {
  516. M2M_DBG("Successfully sent the UART reconfigure command\n");
  517. }
  518. else
  519. {
  520. M2M_ERR("write error\n");
  521. s8Ret = M2M_ERR_BUS_FAIL;
  522. }
  523. }
  524. }
  525. return s8Ret;
  526. }
  527. #endif
  528. /* EOF */