drv_ethernet.c 35 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330
  1. /***************************************************************************//**
  2. * @file drv_ethernet.c
  3. * @brief Ethernet driver (SPI mode) of RT-Thread RTOS for using EFM32 USART
  4. * module
  5. * This driver is tested by using the Microchip ENC28J60 stand-alone Ethernet
  6. * controller with SPI interface.
  7. * COPYRIGHT (C) 2012, RT-Thread Development Team
  8. * @author onelife
  9. * @version 1.0
  10. *******************************************************************************
  11. * @section License
  12. * The license and distribution terms for this file may be found in the file
  13. * LICENSE in this distribution or at http://www.rt-thread.org/license/LICENSE
  14. *******************************************************************************
  15. * @section Change Logs
  16. * Date Author Notes
  17. * 2011-06-22 onelife Initial creation for using EFM32 USART module
  18. * 2011-07-25 onelife Add lock (semaphore) to prevent simultaneously
  19. * access
  20. * 2011-07-28 onelife Add get_ip() and update_ip() utilities
  21. ******************************************************************************/
  22. /***************************************************************************//**
  23. * @addtogroup efm32_eth
  24. * @{
  25. ******************************************************************************/
  26. /* Includes ------------------------------------------------------------------*/
  27. #include "board.h"
  28. #include "drv_usart.h"
  29. #include "hdl_interrupt.h"
  30. #include "drv_ethernet.h"
  31. #if defined(EFM32_USING_ETHERNET)
  32. #include <netif/ethernetif.h>
  33. /* Private typedef -----------------------------------------------------------*/
  34. /* Private define ------------------------------------------------------------*/
  35. /* Private macro -------------------------------------------------------------*/
  36. #ifdef EFM32_ETHERNET_DEBUG
  37. #define eth_debug(format,args...) rt_kprintf(format, ##args)
  38. #else
  39. #define eth_debug(format,args...)
  40. #endif
  41. /* Private constants ---------------------------------------------------------*/
  42. static const rt_uint8_t eth_addr[ETH_ADDR_LEN] = ETH_ADDR_DEFAULT;
  43. /* Private variables ---------------------------------------------------------*/
  44. static struct eth_device eth_dev;
  45. static struct rt_semaphore ethLock;
  46. static rt_uint8_t ethBank;
  47. static rt_uint16_t ethNxtPkt;
  48. static rt_device_t spi = RT_NULL;
  49. static rt_bool_t ethAutoCs = true;
  50. /* Private function prototypes -----------------------------------------------*/
  51. /* Private functions ---------------------------------------------------------*/
  52. /***************************************************************************//**
  53. * @brief
  54. * Set/Clear chip select
  55. *
  56. * @details
  57. *
  58. * @note
  59. *
  60. * @param[in] enable
  61. * Chip select pin setting
  62. ******************************************************************************/
  63. static void efm_eth_cs(rt_uint8_t enable)
  64. {
  65. if (!ethAutoCs)
  66. {
  67. if (enable)
  68. {
  69. GPIO_PinOutClear(ETH_CS_PORT, ETH_CS_PIN);
  70. }
  71. else
  72. {
  73. GPIO_PinOutSet(ETH_CS_PORT, ETH_CS_PIN);
  74. }
  75. }
  76. }
  77. /***************************************************************************//**
  78. * @brief
  79. * Send command to Ethernet device
  80. *
  81. * @details
  82. *
  83. * @note
  84. *
  85. * @param[in] cmd
  86. * Command index
  87. *
  88. * @param[in] addr
  89. * Register address
  90. *
  91. * @param[in/out] data
  92. * Pointer to the buffer of register value
  93. *
  94. * @return
  95. * Error code
  96. ******************************************************************************/
  97. static rt_err_t efm_eth_cmd(
  98. rt_uint8_t cmd,
  99. rt_uint8_t addr,
  100. rt_uint8_t *data)
  101. {
  102. RT_ASSERT(spi != RT_NULL);
  103. rt_uint8_t buf_ins[6], buf_res[2];
  104. rt_uint8_t len_ins, len_res;
  105. len_ins = 0;
  106. do
  107. {
  108. /* Build instruction buffer */
  109. /* Check if need to read back */
  110. if (cmd == ENC28J60_READ_CTRL_REG)
  111. {
  112. buf_ins[len_ins++] = 1; /* Instruction length */
  113. }
  114. /* Byte 0: Check if no address section */
  115. if (cmd == ENC28J60_READ_BUF_MEM || cmd == ENC28J60_WRITE_BUF_MEM || \
  116. cmd == ENC28J60_SOFT_RESET)
  117. {
  118. buf_ins[len_ins++] = cmd;
  119. }
  120. else
  121. {
  122. buf_ins[len_ins++] = cmd | (addr & ADDR_MASK);
  123. }
  124. /* Byte 1: Check if data section is present */
  125. if (cmd == ENC28J60_WRITE_CTRL_REG || cmd == ENC28J60_BIT_FIELD_SET || \
  126. cmd == ENC28J60_BIT_FIELD_CLR || cmd == ENC28J60_WRITE_BUF_MEM)
  127. {
  128. buf_ins[len_ins++] = *data;
  129. }
  130. /* Check if reading */
  131. if (cmd == ENC28J60_READ_CTRL_REG)
  132. {
  133. *(rt_uint8_t **)(&buf_ins[len_ins]) = buf_res; /* Pointer to RX buffer */
  134. len_ins += 4;
  135. /* Check if MAC or MII register */
  136. if (addr & SPRD_MASK)
  137. {
  138. len_res = 2;
  139. }
  140. else
  141. {
  142. len_res = 1;
  143. }
  144. /* Send command and get response */
  145. efm_eth_cs(1);
  146. if (spi->read(spi, ETH_SPI_RX_SKIP, buf_ins, len_res) == 0)
  147. {
  148. break;
  149. }
  150. *data = buf_res[len_res - 1];
  151. // eth_debug("ETH: read RX %x %x (%d)\n", buf_res[0], buf_res[1], len_res);
  152. // eth_debug("ETH: ** read RX %x %x (%d)\n",
  153. // buf_res[0], buf_res[1], buf_res[2], buf_res[3], buf_res[4],
  154. // buf_res[5], buf_res[6], buf_res[7], buf_res[8], buf_res[9],
  155. // len_res);
  156. }
  157. else
  158. {
  159. // eth_debug("ETH: ** write TX %x %x %x %x %x %x (%d) \n", buf_ins[0],
  160. // buf_ins[1], buf_ins[2], buf_ins[3], buf_ins[4], buf_ins[5],
  161. // len_ins);
  162. /* Send command and get response */
  163. efm_eth_cs(1);
  164. if (spi->write(spi, EFM32_NO_DATA, buf_ins, len_ins) == 0)
  165. {
  166. break;
  167. }
  168. }
  169. if (!(cmd == ENC28J60_READ_BUF_MEM || cmd == ENC28J60_WRITE_BUF_MEM))
  170. {
  171. efm_eth_cs(0);
  172. }
  173. return RT_EOK;
  174. } while(0);
  175. eth_debug("ETH: Send command failed!\n");
  176. efm_eth_cs(0);
  177. return -RT_ERROR;
  178. }
  179. /***************************************************************************//**
  180. * @brief
  181. * Wrapper function of send command to Ethernet device
  182. *
  183. * @details
  184. *
  185. * @note
  186. *
  187. * @param[in] cmd
  188. * Command index
  189. *
  190. * @param[in] addr
  191. * Register address
  192. *
  193. * @param[in/out] data
  194. * Pointer to the buffer of register value
  195. *
  196. * @return
  197. * Error code
  198. ******************************************************************************/
  199. static rt_err_t efm_eth_sendCmd(
  200. rt_uint8_t cmd,
  201. rt_uint8_t addr,
  202. rt_uint8_t *data)
  203. {
  204. rt_err_t ret;
  205. eth_debug("ETH: Send command %x (%x %x)\n", cmd, addr, *data);
  206. do
  207. {
  208. /* Change bank */
  209. if(((addr & BANK_MASK) != ethBank) && ((addr < EIE) || (addr > ECON1)))
  210. {
  211. rt_uint8_t temp;
  212. if ((ret = efm_eth_cmd(ENC28J60_READ_CTRL_REG, ECON1, &temp)) != RT_EOK)
  213. {
  214. break;
  215. }
  216. temp &= 0xFC;
  217. ethBank = (addr & BANK_MASK);
  218. temp |= ethBank >> BANK_SHIFT;
  219. if ((ret = efm_eth_cmd(ENC28J60_WRITE_CTRL_REG, ECON1, &temp)) != RT_EOK)
  220. {
  221. break;
  222. }
  223. }
  224. /* Send command */
  225. ret = efm_eth_cmd(cmd, addr, data);
  226. } while(0);
  227. return ret;
  228. }
  229. /***************************************************************************//**
  230. * @brief
  231. * Read register of Ethernet device
  232. *
  233. * @details
  234. *
  235. * @note
  236. *
  237. * @param[in] addr
  238. * Register address
  239. *
  240. * @return
  241. * Register value
  242. ******************************************************************************/
  243. static rt_uint8_t efm_eth_readReg(rt_uint8_t addr)
  244. {
  245. rt_uint8_t data;
  246. efm_eth_sendCmd(ENC28J60_READ_CTRL_REG, addr, &data);
  247. return data;
  248. }
  249. /***************************************************************************//**
  250. * @brief
  251. * Write register of Ethernet device
  252. *
  253. * @details
  254. *
  255. * @note
  256. *
  257. * @param[in] addr
  258. * Register address
  259. *
  260. * @param[in] data
  261. * Register value
  262. ******************************************************************************/
  263. static void efm_eth_writeReg(rt_uint8_t addr, rt_uint8_t data)
  264. {
  265. efm_eth_sendCmd(ENC28J60_WRITE_CTRL_REG, addr, &data);
  266. }
  267. /***************************************************************************//**
  268. * @brief
  269. * Read PHY register of Ethernet device
  270. *
  271. * @details
  272. *
  273. * @note
  274. *
  275. * @param[in] addr
  276. * Register address
  277. *
  278. * @return
  279. * Register value
  280. ******************************************************************************/
  281. static rt_uint16_t efm_eth_readPhy(rt_uint8_t addr)
  282. {
  283. rt_uint16_t ret;
  284. eth_debug("ETH: *** read PHY %x\n", addr);
  285. /* Set PHY register address */
  286. efm_eth_writeReg(MIREGADR, addr);
  287. /* Start read operation */
  288. efm_eth_writeReg(MICMD, MICMD_MIIRD);
  289. /* Waiting for at least 10.24 uS */
  290. while(efm_eth_readReg(MISTAT) & MISTAT_BUSY);
  291. /* Stop read operation */
  292. efm_eth_writeReg(MICMD, 0x00);
  293. /* Get the result */
  294. ret = (rt_uint16_t)efm_eth_readReg(MIRDL);
  295. ret |= (rt_uint16_t)efm_eth_readReg(MIRDH) << 8;
  296. return ret;
  297. }
  298. /***************************************************************************//**
  299. * @brief
  300. * Write PHY register of Ethernet device
  301. *
  302. * @details
  303. *
  304. * @note
  305. *
  306. * @param[in] addr
  307. * Register address
  308. *
  309. * @param[in] data
  310. * Register value
  311. ******************************************************************************/
  312. static void efm_eth_writePhy(rt_uint8_t addr, rt_uint16_t data)
  313. {
  314. eth_debug("ETH: *** write PHY %x (%x)\n", addr, data);
  315. /* Set PHY register address */
  316. efm_eth_writeReg(MIREGADR, addr);
  317. /* Set data */
  318. efm_eth_writeReg(MIWRL, data);
  319. efm_eth_writeReg(MIWRH, data >> 8);
  320. /* Waiting for at least 10.24 uS */
  321. while(efm_eth_readReg(MISTAT) & MISTAT_BUSY);
  322. }
  323. /***************************************************************************//**
  324. * @brief
  325. * Interrupt handler of Ethernet device
  326. *
  327. * @details
  328. *
  329. * @note
  330. *
  331. * @param[in] dev
  332. * Pointer to device descriptor
  333. ******************************************************************************/
  334. void efm_eth_isr(rt_device_t dev)
  335. {
  336. rt_uint8_t reg_eir, data;
  337. volatile rt_uint8_t cnt;
  338. /* Disable RX and other interrutps */
  339. data = EIE_PKTIE | EIE_INTIE;
  340. efm_eth_sendCmd(ENC28J60_BIT_FIELD_CLR, EIE, &data);
  341. /* Get interrupt flag */
  342. efm_eth_sendCmd(ENC28J60_READ_CTRL_REG, EIR, &reg_eir);
  343. data = 0;
  344. /* DMA completed */
  345. if (reg_eir & EIR_DMAIF)
  346. {
  347. data |= (rt_uint8_t)EIR_DMAIF;
  348. }
  349. /* Link Changed */
  350. if (reg_eir & EIR_LINKIF)
  351. {
  352. /* Read PHIR to clear the flag */
  353. efm_eth_readPhy(PHIR);
  354. }
  355. /* TX done */
  356. if (reg_eir & EIR_TXIF)
  357. {
  358. data |= (rt_uint8_t)EIR_TXIF;
  359. }
  360. /* TX error */
  361. if (reg_eir & EIR_TXERIF)
  362. {
  363. data |= (rt_uint8_t)EIR_TXERIF;
  364. }
  365. /* RX error */
  366. if (reg_eir & EIR_RXERIF)
  367. {
  368. data |= (rt_uint8_t)EIR_RXERIF;
  369. }
  370. /* Clear flags */
  371. efm_eth_sendCmd(ENC28J60_BIT_FIELD_CLR, EIR, &data);
  372. /* Get packet counter (Errata 6) */
  373. efm_eth_sendCmd(ENC28J60_READ_CTRL_REG, EPKTCNT, (rt_uint8_t *)&cnt);
  374. if (cnt)
  375. {
  376. /* Inform Ethernet thread */
  377. eth_device_ready(&eth_dev);
  378. }
  379. /* Enable other interrupts */
  380. data = EIE_INTIE;
  381. efm_eth_sendCmd(ENC28J60_BIT_FIELD_SET, EIE, &data);
  382. }
  383. /***************************************************************************//**
  384. * @brief
  385. * Initialize Ethernet device
  386. *
  387. * @details
  388. *
  389. * @note
  390. *
  391. * @param[in] dev
  392. * Pointer to device descriptor
  393. *
  394. * @return
  395. * Error code
  396. ******************************************************************************/
  397. static rt_err_t efm_eth_init(rt_device_t dev)
  398. {
  399. rt_uint16_t reg_phy;
  400. rt_uint8_t data;
  401. /* Reset chip select */
  402. efm_eth_cs(0);
  403. /* Software reset */
  404. efm_eth_sendCmd(ENC28J60_SOFT_RESET, EFM32_NO_DATA, EFM32_NO_POINTER);
  405. /* Waiting for at least 1 ms (Errata 2) */
  406. rt_thread_delay(ETH_PERIOD_WAIT_INIT);
  407. ethNxtPkt = RXSTART_INIT;
  408. ethBank = 0;
  409. /* Init RX buffer */
  410. efm_eth_writeReg(ERXSTL, RXSTART_INIT & 0xFF);
  411. efm_eth_writeReg(ERXSTH, RXSTART_INIT >> 8);
  412. efm_eth_writeReg(ERXNDL, RXSTOP_INIT & 0xFF);
  413. efm_eth_writeReg(ERXNDH, RXSTOP_INIT >> 8);
  414. efm_eth_writeReg(ERXRDPTL, RXSTOP_INIT & 0xFF);
  415. efm_eth_writeReg(ERXRDPTH, RXSTOP_INIT >> 8);
  416. /* Init TX buffer */
  417. efm_eth_writeReg(ETXSTL, TXSTART_INIT & 0xFF);
  418. efm_eth_writeReg(ETXSTH, TXSTART_INIT >> 8);
  419. efm_eth_writeReg(ETXNDL, TXSTOP_INIT & 0xFF);
  420. efm_eth_writeReg(ETXNDH, TXSTOP_INIT >> 8);
  421. efm_eth_writeReg(EWRPTL, TXSTART_INIT & 0xFF);
  422. efm_eth_writeReg(EWRPTH, TXSTART_INIT >> 8);
  423. /* Init RX filters */
  424. /* For broadcast packets we allow only ARP packtets
  425. All other packets should be unicast only for our mac (MAADR)
  426. The pattern to match on is therefore
  427. Type ETH.DST
  428. ARP BROADCAST
  429. 06 08 -- -- -- -- -- -- ff ff ff ff ff ff
  430. These poitions are: 11 0000 0011 1111 in binary and 30 3f in hex
  431. Checksum for theses bytes is: f7 f9 */
  432. efm_eth_writeReg(EPMM0, 0x3f);
  433. efm_eth_writeReg(EPMM1, 0x30);
  434. efm_eth_writeReg(EPMCSL, 0xf9);
  435. efm_eth_writeReg(EPMCSH, 0xf7);
  436. efm_eth_writeReg(ERXFCON, ERXFCON_UCEN | ERXFCON_CRCEN | ERXFCON_PMEN);
  437. //efm_eth_writeReg(ERXFCON, ERXFCON_UCEN | ERXFCON_CRCEN | ERXFCON_BCEN);
  438. /* Waiting For OST: The OST does not expire until 7500 OSC1 clock cycles (300 uS)
  439. pass after Power-on Reset or wake-up from Power-Down mode occurs */
  440. /* Init MAC */
  441. /* Enable RX, IEEE defined flow control */
  442. efm_eth_writeReg(MACON1, MACON1_MARXEN | MACON1_TXPAUS | MACON1_RXPAUS);
  443. /* Enable padding to 60 bytes, CRC and frame length status reporting */
  444. #if defined(ETH_HALF_DUPLEX)
  445. efm_eth_writeReg(MACON3, MACON3_PADCFG0 | MACON3_TXCRCEN | MACON3_FRMLNEN);
  446. efm_eth_writeReg(MACON4, MACON4_DEFER);
  447. #else
  448. efm_eth_writeReg(MACON3, \
  449. MACON3_PADCFG0 | MACON3_TXCRCEN | MACON3_FRMLNEN | MACON3_FULDPX);
  450. #endif
  451. /* Set the maximum packet length */
  452. efm_eth_writeReg(MAMXFLL, MAX_FRAMELEN & 0xFF);
  453. efm_eth_writeReg(MAMXFLH, MAX_FRAMELEN >> 8);
  454. /* Set inter-packet gap (back-to-back). Full-Duplex: 0x15, Half-Duplex: 0x12 */
  455. #if defined(ETH_HALF_DUPLEX)
  456. efm_eth_writeReg(MABBIPG, 0x12);
  457. #else
  458. efm_eth_writeReg(MABBIPG, 0x15);
  459. #endif
  460. /* Set inter-packet gap (non-back-to-back).
  461. Full-Duplex: 0x0012, Half-Duplex: 0x0C12 */
  462. efm_eth_writeReg(MAIPGL, 0x12);
  463. #if defined(ETH_HALF_DUPLEX)
  464. efm_eth_writeReg(MAIPGH, 0x0C);
  465. /* Set retransmission and collision window */
  466. efm_eth_writeReg(MACLCON1, 0x0F);
  467. efm_eth_writeReg(MACLCON2, 0x37);
  468. #endif
  469. /* Set MAC address
  470. NOTE: MAC address in ENC28J60 is byte-backward */
  471. efm_eth_writeReg(MAADR1, eth_addr[0]);
  472. efm_eth_writeReg(MAADR2, eth_addr[1]);
  473. efm_eth_writeReg(MAADR3, eth_addr[2]);
  474. efm_eth_writeReg(MAADR4, eth_addr[3]);
  475. efm_eth_writeReg(MAADR5, eth_addr[4]);
  476. efm_eth_writeReg(MAADR6, eth_addr[5]);
  477. /* Init PHY */
  478. #if defined(ETH_HALF_DUPLEX)
  479. reg_phy = efm_eth_readPhy(PHCON2);
  480. efm_eth_writePhy(PHCON2, reg_phy | PHCON2_HDLDIS);
  481. #else
  482. reg_phy = efm_eth_readPhy(PHCON1);
  483. efm_eth_writePhy(PHCON1, reg_phy | PHCON1_PDPXMD);
  484. #endif
  485. /* LEDA: Display link status;
  486. LEDB: Display transmit and receive activity */
  487. reg_phy = efm_eth_readPhy(PHLCON);
  488. efm_eth_writePhy(PHLCON, (reg_phy & 0xF00F) | 0x0470);
  489. /* Disable clock output */
  490. efm_eth_writeReg(ECOCON, 0x00);
  491. /* Clear interrutp flags */
  492. data = EIR_DMAIF | EIR_TXIF | EIR_TXERIF | EIR_RXERIF;
  493. efm_eth_sendCmd(ENC28J60_BIT_FIELD_CLR, EIR, &data);
  494. /* Enable interrutps */
  495. data = EIE_INTIE | EIE_PKTIE | EIE_TXIE;
  496. efm_eth_sendCmd(ENC28J60_BIT_FIELD_SET, EIE, &data);
  497. /* Enable RX */
  498. data = ECON1_RXEN;
  499. efm_eth_sendCmd(ENC28J60_BIT_FIELD_SET, ECON1, &data);
  500. eth_debug("ETH: Init OK\n");
  501. return RT_EOK;
  502. }
  503. /***************************************************************************//**
  504. * @brief
  505. * Open Ethernet device
  506. *
  507. * @details
  508. *
  509. * @note
  510. *
  511. * @param[in] dev
  512. * Pointer to device descriptor
  513. *
  514. * @param[in] oflag
  515. * Device open flag
  516. *
  517. * @return
  518. * Error code
  519. ******************************************************************************/
  520. static rt_err_t efm_eth_open(rt_device_t dev, rt_uint16_t oflag)
  521. {
  522. eth_debug("ETH: Open, flag %x\n", eth_dev.parent.flag);
  523. return RT_EOK;
  524. }
  525. /***************************************************************************//**
  526. * @brief
  527. * Close Ethernet device
  528. *
  529. * @details
  530. *
  531. * @note
  532. *
  533. * @param[in] dev
  534. * Pointer to device descriptor
  535. *
  536. * @return
  537. * Error code
  538. ******************************************************************************/
  539. static rt_err_t efm_eth_close(rt_device_t dev)
  540. {
  541. eth_debug("ETH: Close, flag %x\n", eth_dev.parent.flag);
  542. return RT_EOK;
  543. }
  544. /***************************************************************************//**
  545. * @brief
  546. * Read from Ethernet device (Dummy function)
  547. *
  548. * @details
  549. *
  550. * @note
  551. *
  552. * @param[in] dev
  553. * Pointer to device descriptor
  554. *
  555. * @param[in] pos
  556. * Offset
  557. *
  558. * @param[in] buffer
  559. * Poniter to the buffer
  560. *
  561. * @param[in] size
  562. * Buffer size in byte
  563. *
  564. * @return
  565. * Number of read bytes
  566. ******************************************************************************/
  567. static rt_size_t efm_eth_read(
  568. rt_device_t dev,
  569. rt_off_t pos,
  570. void *buffer,
  571. rt_size_t size)
  572. {
  573. rt_set_errno(-RT_ENOSYS);
  574. return 0;
  575. }
  576. /***************************************************************************//**
  577. * @brief
  578. * Write to Ethernet device (Dummy function)
  579. *
  580. * @details
  581. *
  582. * @note
  583. *
  584. * @param[in] dev
  585. * Pointer to device descriptor
  586. *
  587. * @param[in] pos
  588. * Offset
  589. *
  590. * @param[in] buffer
  591. * Poniter to the buffer
  592. *
  593. * @param[in] size
  594. * Buffer size in byte
  595. *
  596. * @return
  597. * Number of written bytes
  598. ******************************************************************************/
  599. static rt_size_t efm_eth_write (
  600. rt_device_t dev,
  601. rt_off_t pos,
  602. const void *buffer,
  603. rt_size_t size)
  604. {
  605. rt_set_errno(-RT_ENOSYS);
  606. return 0;
  607. }
  608. /***************************************************************************//**
  609. * @brief
  610. * Configure Ethernet device
  611. *
  612. * @details
  613. *
  614. * @note
  615. *
  616. * @param[in] dev
  617. * Pointer to device descriptor
  618. *
  619. * @param[in] cmd
  620. * Ethernet control command
  621. *
  622. * @param[in] args
  623. * Arguments
  624. *
  625. * @return
  626. * Error code
  627. ******************************************************************************/
  628. static rt_err_t efm_eth_control (
  629. rt_device_t dev,
  630. rt_uint8_t cmd,
  631. void *args)
  632. {
  633. rt_err_t ret;
  634. ret = -RT_ERROR;
  635. switch(cmd)
  636. {
  637. case NIOCTL_GADDR:
  638. /* Get MAC address */
  639. if(args)
  640. {
  641. rt_memcpy(args, eth_addr, sizeof(eth_addr));
  642. ret = RT_EOK;
  643. }
  644. break;
  645. default :
  646. break;
  647. }
  648. return RT_EOK;
  649. }
  650. /***************************************************************************//**
  651. * @brief
  652. * Packet receiving function
  653. *
  654. * @details
  655. *
  656. * @note
  657. *
  658. * @param[in] dev
  659. * Pointer to device descriptor
  660. *
  661. * @return
  662. * Pointer to packet buffer
  663. ******************************************************************************/
  664. struct pbuf *efm_eth_rx(rt_device_t dev)
  665. {
  666. rt_uint8_t buf_ins[5], buf_read[6];
  667. rt_uint8_t data, reg_eie;
  668. rt_uint16_t len_rx, sta_rx;
  669. struct pbuf* p;
  670. /* Lock device */
  671. rt_sem_take(&ethLock, RT_WAITING_FOREVER);
  672. /* Disable interrupts */
  673. data = EIE_INTIE;
  674. efm_eth_sendCmd(ENC28J60_BIT_FIELD_CLR, EIE, &data);
  675. p = RT_NULL;
  676. reg_eie = 0;
  677. if (efm_eth_readReg(EPKTCNT))
  678. {
  679. /* Set read pointer to the start of RX packet */
  680. efm_eth_writeReg(ERDPTL, ethNxtPkt & 0xFF);
  681. efm_eth_writeReg(ERDPTH, ethNxtPkt >> 8);
  682. /* Send read buffer command */
  683. efm_eth_sendCmd(ENC28J60_READ_BUF_MEM, EFM32_NO_DATA, EFM32_NO_POINTER);
  684. /* Build instruction buffer */
  685. buf_ins[0] = 0x00;
  686. *(rt_uint8_t **)(&buf_ins[1]) = buf_read;
  687. /* Read packet header */
  688. if (spi->read(spi, EFM32_NO_DATA, buf_ins, sizeof(buf_read)) == 0)
  689. {
  690. eth_debug("ETH: RX header failed!\n");
  691. }
  692. ethNxtPkt = buf_read[0] | (buf_read[1] << 8);
  693. len_rx = buf_read[2] | (buf_read[3] << 8);
  694. sta_rx = buf_read[4] | (buf_read[5] << 8);
  695. eth_debug("ETH: RX header ethNxtPkt %x, len_rx %x, sta_rx %x\n",
  696. ethNxtPkt, len_rx, sta_rx);
  697. /* Check if OK */
  698. if (sta_rx & 0x80)
  699. {
  700. /* Allocate pbuf */
  701. p = pbuf_alloc(PBUF_LINK, len_rx - 4, PBUF_RAM);
  702. if (p != RT_NULL)
  703. {
  704. struct pbuf* q;
  705. for (q = p; q != RT_NULL; q= q->next)
  706. {
  707. /* Build instruction buffer */
  708. buf_ins[0] = 0x00;
  709. *(rt_uint8_t **)(&buf_ins[1]) = q->payload;
  710. /* Read packet header */
  711. if (spi->read(spi, EFM32_NO_DATA, buf_ins, q->len) == 0)
  712. {
  713. eth_debug("ETH: RX payload failed!\n");
  714. }
  715. #ifdef EFM32_ETHERNET_DEBUG
  716. {
  717. rt_uint8_t *temp = (rt_uint8_t *)q->payload;
  718. rt_uint32_t i;
  719. eth_debug("ETH: ***** read RX (q->len %x) *****\n", q->len);
  720. for (i = 0; i < q->len; i += 8)
  721. {
  722. eth_debug("%02x %02x %02x %02x %02x %02x %02x %02x | %c %c %c %c %c %c %c %c\n",
  723. temp[i], temp[i + 1], temp[i + 2], temp[i + 3],
  724. temp[i + 4], temp[i + 5], temp[i + 6], temp[i + 7],
  725. temp[i], temp[i + 1], temp[i + 2], temp[i + 3],
  726. temp[i + 4], temp[i + 5], temp[i + 6], temp[i + 7]);
  727. }
  728. }
  729. #endif
  730. }
  731. }
  732. else
  733. {
  734. eth_debug("ETH: No memory for pbuf!!!\n");
  735. }
  736. }
  737. else
  738. {
  739. eth_debug("ETH: Invalid CRC or symbol error occurred!\n");
  740. }
  741. efm_eth_cs(0);
  742. /* Free buffer */
  743. efm_eth_writeReg(ERXRDPTL, ethNxtPkt & 0xFF);
  744. efm_eth_writeReg(ERXRDPTH, ethNxtPkt >> 8);
  745. /* Decrease counter */
  746. data = ECON2_PKTDEC;
  747. efm_eth_sendCmd(ENC28J60_BIT_FIELD_SET, ECON2, &data);
  748. }
  749. else
  750. {
  751. /* Enable RX */
  752. data = ECON1_RXEN;
  753. efm_eth_sendCmd(ENC28J60_BIT_FIELD_SET, ECON1, &data);
  754. reg_eie |= EIE_PKTIE;
  755. eth_debug("ETH: Enable RX interrupt\n");
  756. }
  757. eth_debug("ETH: RX counter %x\n", efm_eth_readReg(EPKTCNT));
  758. /* Enable interrupts */
  759. reg_eie |= EIE_INTIE;
  760. efm_eth_sendCmd(ENC28J60_BIT_FIELD_SET, EIE, &reg_eie);
  761. /* Unlock device */
  762. rt_sem_release(&ethLock);
  763. return p;
  764. }
  765. /***************************************************************************//**
  766. * @brief
  767. * Packet transmission function
  768. *
  769. * @details
  770. *
  771. * @note
  772. *
  773. * @param[in] dev
  774. * Pointer to device descriptor
  775. *
  776. * @param[in] p
  777. * Pointer to packet buffer
  778. *
  779. * @return
  780. * Error code
  781. ******************************************************************************/
  782. rt_err_t efm_eth_tx(rt_device_t dev, struct pbuf* p)
  783. {
  784. rt_uint8_t data;
  785. struct pbuf* q;
  786. /* Lock device */
  787. rt_sem_take(&ethLock, RT_WAITING_FOREVER);
  788. /* Disable interrupts */
  789. data = EIE_INTIE;
  790. efm_eth_sendCmd(ENC28J60_BIT_FIELD_CLR, EIE, &data);
  791. /* Set write pointer to the start of TX buffer */
  792. efm_eth_writeReg(EWRPTL, TXSTART_INIT & 0xFF);
  793. efm_eth_writeReg(EWRPTH, TXSTART_INIT >> 8);
  794. /* Set buffer end pointer according to the packet size */
  795. efm_eth_writeReg(ETXNDL, (TXSTART_INIT + p->tot_len + 1) & 0xFF);
  796. efm_eth_writeReg(ETXNDH, (TXSTART_INIT + p->tot_len + 1) >> 8);
  797. /* Send write buffer command */
  798. data = 0x00; /* Control byte */
  799. efm_eth_sendCmd(ENC28J60_WRITE_BUF_MEM, EFM32_NO_DATA, &data);
  800. /* Send data */
  801. for (q = p; q != NULL; q = q->next)
  802. {
  803. if (spi->write(spi, EFM32_NO_DATA, q->payload, q->len) == 0)
  804. {
  805. eth_debug("ETH: TX failed!\n");
  806. return -RT_ERROR;
  807. }
  808. #ifdef EFM32_ETHERNET_DEBUG
  809. {
  810. rt_uint8_t *temp = (rt_uint8_t *)q->payload;
  811. rt_uint32_t i;
  812. eth_debug("ETH: ***** write TX (len %d) *****\n", p->len);
  813. for (i = 0; i < q->len; i += 8)
  814. {
  815. eth_debug("%02x %02x %02x %02x %02x %02x %02x %02x | %c %c %c %c %c %c %c %c\n",
  816. temp[i], temp[i + 1], temp[i + 2], temp[i + 3],
  817. temp[i + 4], temp[i + 5], temp[i + 6], temp[i + 7],
  818. temp[i], temp[i + 1], temp[i + 2], temp[i + 3],
  819. temp[i + 4], temp[i + 5], temp[i + 6], temp[i + 7]);
  820. }
  821. }
  822. #endif
  823. }
  824. efm_eth_cs(0);
  825. /* Start TX */
  826. data = ECON1_TXRTS;
  827. efm_eth_sendCmd(ENC28J60_BIT_FIELD_SET, ECON1, &data);
  828. /* Errata 12 */
  829. if (efm_eth_readReg(EIR) & EIR_TXERIF)
  830. {
  831. efm_eth_sendCmd(ENC28J60_BIT_FIELD_CLR, ECON1, &data);
  832. data = EIR_TXERIF;
  833. efm_eth_sendCmd(ENC28J60_BIT_FIELD_CLR, EIR, &data);
  834. data = ECON1_TXRTS;
  835. efm_eth_sendCmd(ENC28J60_BIT_FIELD_SET, ECON1, &data);
  836. }
  837. /* Waiting for a while */
  838. rt_thread_delay(ETH_PERIOD_WAIT_INIT);
  839. /* Enable interrupts */
  840. data = EIE_INTIE;
  841. efm_eth_sendCmd(ENC28J60_BIT_FIELD_SET, EIE, &data);
  842. /* Unlock device */
  843. rt_sem_release(&ethLock);
  844. return RT_EOK;
  845. }
  846. /***************************************************************************//**
  847. * @brief
  848. * Initialize all Ethernet related hardware and register the device to kernel
  849. *
  850. * @details
  851. *
  852. * @note
  853. *
  854. * @return
  855. * Error code
  856. ******************************************************************************/
  857. rt_err_t efm_hw_eth_init(void)
  858. {
  859. struct efm32_usart_device_t *usart;
  860. efm32_irq_hook_init_t hook;
  861. do
  862. {
  863. /* Find SPI device */
  864. spi = rt_device_find(ETH_USING_DEVICE_NAME);
  865. if (spi == RT_NULL)
  866. {
  867. eth_debug("ETH: Can't find device %s!\n",
  868. ETH_USING_DEVICE_NAME);
  869. break;
  870. }
  871. eth_debug("ETH: Find device %s\n", ETH_USING_DEVICE_NAME);
  872. /* Config chip slect pin */
  873. usart = (struct efm32_usart_device_t *)(spi->user_data);
  874. if (!(usart->state & USART_STATE_AUTOCS))
  875. {
  876. GPIO_PinModeSet(ETH_CS_PORT, ETH_CS_PIN, gpioModePushPull, 1);
  877. ethAutoCs = false;
  878. }
  879. /* Config reset pin */
  880. GPIO_PinModeSet(ETH_RESET_PORT, ETH_RESET_PIN, gpioModePushPull, 0);
  881. /* Config interrupt pin */
  882. GPIO_PinModeSet(ETH_INT_PORT, ETH_INT_PIN, gpioModeInput, 1);
  883. /* Config interrupt */
  884. hook.type = efm32_irq_type_gpio;
  885. hook.unit = ETH_INT_PIN;
  886. hook.cbFunc = efm_eth_isr;
  887. hook.userPtr = RT_NULL;
  888. efm32_irq_hook_register(&hook);
  889. /* Clear pending interrupt */
  890. BITBAND_Peripheral(&(GPIO->IFC), ETH_INT_PIN, 0x1UL);
  891. /* Set falling edge interrupt and clear/enable it */
  892. GPIO_IntConfig(
  893. ETH_INT_PORT,
  894. ETH_INT_PIN,
  895. false,
  896. true,
  897. true);
  898. if ((rt_uint8_t)ETH_INT_PIN % 2)
  899. {
  900. NVIC_ClearPendingIRQ(GPIO_ODD_IRQn);
  901. NVIC_SetPriority(GPIO_ODD_IRQn, EFM32_IRQ_PRI_DEFAULT);
  902. NVIC_EnableIRQ(GPIO_ODD_IRQn);
  903. }
  904. else
  905. {
  906. NVIC_ClearPendingIRQ(GPIO_EVEN_IRQn);
  907. NVIC_SetPriority(GPIO_EVEN_IRQn, EFM32_IRQ_PRI_DEFAULT);
  908. NVIC_EnableIRQ(GPIO_EVEN_IRQn);
  909. }
  910. /* Set SPI speed */
  911. USART_BaudrateSyncSet(usart->usart_device, 0, ETH_CLK_MAX);
  912. /* Initialize semaphore */
  913. rt_sem_init(&ethLock, ETH_DEVICE_NAME, 1, RT_IPC_FLAG_FIFO);
  914. /* Register Ethernet device */
  915. eth_dev.parent.init = efm_eth_init;
  916. eth_dev.parent.open = efm_eth_open;
  917. eth_dev.parent.close = efm_eth_close;
  918. eth_dev.parent.read = efm_eth_read;
  919. eth_dev.parent.write = efm_eth_write;
  920. eth_dev.parent.control = efm_eth_control;
  921. eth_dev.eth_rx = efm_eth_rx;
  922. eth_dev.eth_tx = efm_eth_tx;
  923. eth_device_init(&eth_dev, ETH_DEVICE_NAME);
  924. /* Start device */
  925. GPIO_PinOutSet(ETH_RESET_PORT, ETH_RESET_PIN);
  926. eth_debug("ETH: HW init OK\n");
  927. return RT_EOK;
  928. } while (0);
  929. /* Release buffer */
  930. rt_kprintf("ETH: HW init failed!\n");
  931. return -RT_ERROR;
  932. }
  933. /*******************************************************************************
  934. * Export to FINSH
  935. ******************************************************************************/
  936. #if defined(EFM32_USING_ETH_UTILS)
  937. #ifdef RT_USING_FINSH
  938. #include <finsh.h>
  939. void list_eth(void)
  940. {
  941. rt_uint16_t reg_phy;
  942. rt_uint8_t data;
  943. rt_kprintf(" ENC28J60 on %s\n", ETH_USING_DEVICE_NAME);
  944. rt_kprintf(" ------------------------------\n");
  945. reg_phy = efm_eth_readPhy(PHSTAT2);
  946. if (reg_phy & PHSTAT2_PLRITY)
  947. {
  948. rt_kprintf(" Cable polarity is reversed\n");
  949. }
  950. else
  951. {
  952. rt_kprintf(" Cable polarity is correct\n");
  953. }
  954. if (reg_phy & PHSTAT2_DPXSTAT)
  955. {
  956. rt_kprintf(" Full-duplex mode\n");
  957. }
  958. else
  959. {
  960. rt_kprintf(" Half-duplex mode\n");
  961. }
  962. if (reg_phy & PHSTAT2_LSTAT)
  963. {
  964. rt_kprintf(" Link is up\n");
  965. }
  966. else
  967. {
  968. rt_kprintf(" Link is down\n");
  969. }
  970. if (reg_phy & PHSTAT2_COLSTAT)
  971. {
  972. rt_kprintf(" Collision is occuring\n");
  973. }
  974. else
  975. {
  976. rt_kprintf(" No collision\n");
  977. }
  978. if (reg_phy & PHSTAT2_RXSTAT)
  979. {
  980. rt_kprintf(" RX is busy\n");
  981. }
  982. else
  983. {
  984. rt_kprintf(" RX is idle\n");
  985. }
  986. if (reg_phy & PHSTAT2_TXSTAT)
  987. {
  988. rt_kprintf(" TX is busy\n");
  989. }
  990. else
  991. {
  992. rt_kprintf(" TX is idle\n");
  993. }
  994. }
  995. FINSH_FUNCTION_EXPORT(list_eth, list the Ethernet device status.)
  996. #include "lwip\api.h"
  997. rt_err_t get_ip(char *ip)
  998. {
  999. err_t ret;
  1000. struct ip_addr server_ip;
  1001. struct netconn *conn;
  1002. struct netbuf *buf;
  1003. char *rq, *rq2;
  1004. u16_t len;
  1005. const char query[] = "GET / HTTP/1.0\r\nHOST: checkip.dyndns.com\r\n\r\n";
  1006. const char find[] = "body";
  1007. do
  1008. {
  1009. #if defined(RT_LWIP_DNS)
  1010. ret = netconn_gethostbyname("checkip.dyndns.com", &server_ip);
  1011. if (ret != ERR_OK)
  1012. {
  1013. break;
  1014. }
  1015. #else
  1016. IP4_ADDR(&server_ip, 216,146,38,70); // IP address of "checkip.dyndns.com"
  1017. #endif
  1018. conn = netconn_new(NETCONN_TCP);
  1019. if (conn == NULL)
  1020. {
  1021. break;
  1022. }
  1023. ret = netconn_connect(conn, &server_ip, 80);
  1024. if (ret != ERR_OK)
  1025. {
  1026. break;
  1027. }
  1028. /* Send the query */
  1029. ret = netconn_write(conn, query, sizeof(query) - 1, 0);
  1030. if (ret != ERR_OK)
  1031. {
  1032. break;
  1033. }
  1034. buf = netconn_recv(conn);
  1035. if (buf != NULL)
  1036. {
  1037. /* Get the response */
  1038. ret = netbuf_data(buf, (void **)&rq, &len);
  1039. if (ret != ERR_OK)
  1040. {
  1041. break;
  1042. }
  1043. /* Find the IP address */
  1044. rq = rt_strstr(rq, find);
  1045. if (rq == RT_NULL)
  1046. {
  1047. break;
  1048. }
  1049. rq += 5;
  1050. rq2 = rq;
  1051. rq2 = rt_strstr(rq2, find);
  1052. if (rq2 == RT_NULL)
  1053. {
  1054. break;
  1055. }
  1056. rq2 -= 2;
  1057. *rq2 = 0x0;
  1058. // rt_kprintf("[%s]\n", rq);
  1059. }
  1060. else
  1061. {
  1062. break;
  1063. }
  1064. /* Copy the IP address to buffer */
  1065. if (ip != NULL)
  1066. {
  1067. while(*rq < '0' || *rq > '9')
  1068. {
  1069. rq++;
  1070. }
  1071. rt_memcpy(ip, rq, rq2 - rq + 1);
  1072. }
  1073. netconn_delete(conn);
  1074. netbuf_delete(buf);
  1075. return RT_EOK;
  1076. } while (0);
  1077. netconn_delete(conn);
  1078. netbuf_delete(buf);
  1079. return -RT_ERROR;
  1080. }
  1081. void list_myip(void)
  1082. {
  1083. rt_uint8_t ip[20];
  1084. if (get_ip(ip) != RT_EOK)
  1085. {
  1086. rt_kprintf("Get IP failed!\n");
  1087. return;
  1088. }
  1089. rt_kprintf("Current IP: [%s]\n", ip);
  1090. }
  1091. FINSH_FUNCTION_EXPORT(list_myip, list the current IP address.)
  1092. #if !defined(hostName) || !defined(userPwdB64)
  1093. #error "The 'hostName' and 'userPwdB64' must be defined to use update_ip() function"
  1094. #endif
  1095. rt_err_t update_ip(char *ip)
  1096. {
  1097. err_t ret;
  1098. struct ip_addr server_ip;
  1099. struct netconn *conn;
  1100. struct netbuf *buf;
  1101. char *rq;
  1102. u16_t len, len2;
  1103. char query[200] = "GET /nic/update?hostname=";
  1104. const char query2[] = "&myip=";
  1105. const char query3[] = " HTTP/1.0\r\nHost: members.dyndns.org\r\nAuthorization: Basic ";
  1106. const char query4[] = "\r\nUser-Agent: onelife - EFM32 - 0.4\r\n\r\n";
  1107. const char find[] = "good";
  1108. /* Make the query */
  1109. len = rt_strlen(query);
  1110. len2 = sizeof(hostName) - 1;
  1111. rt_memcpy(&query[len], hostName, len2);
  1112. len += len2;
  1113. len2 = sizeof(query2) - 1;
  1114. rt_memcpy(&query[len], query2, len2);
  1115. len += len2;
  1116. len2 = rt_strlen(ip);
  1117. rt_memcpy(&query[len], ip, len2);
  1118. len += len2;
  1119. len2 = sizeof(query3) - 1;
  1120. rt_memcpy(&query[len], query3, len2);
  1121. len += len2;
  1122. len2 = sizeof(userPwdB64) - 1;
  1123. rt_memcpy(&query[len], userPwdB64, len2);
  1124. len += len2;
  1125. len2 = sizeof(query4) - 1;
  1126. rt_memcpy(&query[len], query4, len2);
  1127. len += len2;
  1128. query[len] = 0x0;
  1129. // rt_kprintf("Query: %s\n", &query[100]);
  1130. do
  1131. {
  1132. #if defined(RT_LWIP_DNS)
  1133. ret = netconn_gethostbyname("members.dyndns.org", &server_ip);
  1134. if (ret != ERR_OK)
  1135. {
  1136. break;
  1137. }
  1138. #else
  1139. IP4_ADDR(&server_ip, 204,13,248,112); // IP address of "members.dyndns.org"
  1140. #endif
  1141. conn = netconn_new(NETCONN_TCP);
  1142. if (conn == NULL)
  1143. {
  1144. break;
  1145. }
  1146. ret = netconn_connect(conn, &server_ip, 80);
  1147. if (ret != ERR_OK)
  1148. {
  1149. break;
  1150. }
  1151. /* Send the query */
  1152. ret = netconn_write(conn, query, len, 0);
  1153. if (ret != ERR_OK)
  1154. {
  1155. break;
  1156. }
  1157. /* Get the response */
  1158. buf = netconn_recv(conn);
  1159. if (buf != NULL)
  1160. {
  1161. ret = netbuf_data(buf, (void **)&rq, &len);
  1162. if (ret != ERR_OK)
  1163. {
  1164. break;
  1165. }
  1166. /* Find the result */
  1167. rq = rt_strstr(rq, find);
  1168. if (rq == RT_NULL)
  1169. {
  1170. break;
  1171. }
  1172. // rt_kprintf("[%s]\n", rq);
  1173. }
  1174. else
  1175. {
  1176. break;
  1177. }
  1178. netconn_delete(conn);
  1179. netbuf_delete(buf);
  1180. return RT_EOK;
  1181. } while (0);
  1182. netconn_delete(conn);
  1183. netbuf_delete(buf);
  1184. return -RT_ERROR;
  1185. }
  1186. void update_myip(char *ip)
  1187. {
  1188. rt_kprintf("Update host, \"%s\", to new IP address %s: ", hostName, ip);
  1189. if (update_ip(ip) != RT_EOK)
  1190. {
  1191. rt_kprintf("failed!\n");
  1192. return;
  1193. }
  1194. rt_kprintf("succeeded.\n", ip);
  1195. }
  1196. FINSH_FUNCTION_EXPORT(update_myip, update DDNS with specified IP address.)
  1197. #endif /* RT_USING_FINSH */
  1198. #endif /* defined(EFM32_USING_ETH_UTILS) */
  1199. #endif /* defined(EFM32_USING_ETHERNET) */
  1200. /******************************************************************//**
  1201. * @}
  1202. ******************************************************************************/