drv_eth.c 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867
  1. /*
  2. * Copyright (c) 2006-2024 RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2024-09-23 LZerro first version
  9. */
  10. #include <netif/ethernetif.h>
  11. #include <lwipopts.h>
  12. #include "drv_eth.h"
  13. #include "eth_config.h"
  14. #include <rtdbg.h>
  15. #define DBG_TAG "drv"
  16. #define DBG_LVL DBG_INFO
  17. #define cy_ecm_log_msg(a,b,c,...) rt_kprintf(c, __VA_ARGS__)
  18. #define cy_rtos_delay_milliseconds rt_thread_mdelay
  19. #define SLEEP_ETHERNET_PHY_STATUS (500) /* Sleep time in milliseconds. */
  20. #define Eth_Mempool_Num 40
  21. #define MAX_ADDR_LEN 6
  22. /********************************************************/
  23. /******************EMAC configuration********************/
  24. /********************************************************/
  25. #define EMAC_MII 0
  26. #define EMAC_RMII 1
  27. #define EMAC_GMII 2
  28. #define EMAC_RGMII 3
  29. /********************************************************/
  30. /** PHY Mode Selection */
  31. #define EMAC_INTERFACE EMAC_RGMII
  32. /********************************************************/
  33. /* INTERRUPT */
  34. #define ETH_INTR_SRC (CY_GIG_ETH_IRQN0)
  35. #define ETH_INTR_SRC_Q1 (CY_GIG_ETH_IRQN1)
  36. #define ETH_INTR_SRC_Q2 (CY_GIG_ETH_IRQN2)
  37. /* TX_DATA_PIN */
  38. #define ETHx_TD0_PORT CY_GIG_ETH_TD0_PORT
  39. #define ETHx_TD0_PIN CY_GIG_ETH_TD0_PIN
  40. #define ETHx_TD0_PIN_MUX CY_GIG_ETH_TD0_PIN_MUX
  41. #define ETHx_TD1_PORT CY_GIG_ETH_TD1_PORT
  42. #define ETHx_TD1_PIN CY_GIG_ETH_TD1_PIN
  43. #define ETHx_TD1_PIN_MUX CY_GIG_ETH_TD1_PIN_MUX
  44. #define ETHx_TD2_PORT CY_GIG_ETH_TD2_PORT
  45. #define ETHx_TD2_PIN CY_GIG_ETH_TD2_PIN
  46. #define ETHx_TD2_PIN_MUX CY_GIG_ETH_TD2_PIN_MUX
  47. #define ETHx_TD3_PORT CY_GIG_ETH_TD3_PORT
  48. #define ETHx_TD3_PIN CY_GIG_ETH_TD3_PIN
  49. #define ETHx_TD3_PIN_MUX CY_GIG_ETH_TD3_PIN_MUX
  50. /* TX_CTRL_PIN */
  51. #define ETHx_TX_CTL_PORT CY_GIG_ETH_TX_CLK_PORT
  52. #define ETHx_TX_CTL_PIN CY_GIG_ETH_TX_CTL_PIN
  53. #define ETHx_TX_CTL_PIN_MUX CY_GIG_ETH_TX_CTL_PIN_MUX
  54. /* RX_DATA_PIN */
  55. #define ETHx_RD0_PORT CY_GIG_ETH_RD0_PORT
  56. #define ETHx_RD0_PIN CY_GIG_ETH_RD0_PIN
  57. #define ETHx_RD0_PIN_MUX CY_GIG_ETH_RD0_PIN_MUX
  58. #define ETHx_RD1_PORT CY_GIG_ETH_RD1_PORT
  59. #define ETHx_RD1_PIN CY_GIG_ETH_RD1_PIN
  60. #define ETHx_RD1_PIN_MUX CY_GIG_ETH_RD1_PIN_MUX
  61. #define ETHx_RD2_PORT CY_GIG_ETH_RD2_PORT
  62. #define ETHx_RD2_PIN CY_GIG_ETH_RD2_PIN
  63. #define ETHx_RD2_PIN_MUX CY_GIG_ETH_RD2_PIN_MUX
  64. #define ETHx_RD3_PORT CY_GIG_ETH_RD3_PORT
  65. #define ETHx_RD3_PIN CY_GIG_ETH_RD3_PIN
  66. #define ETHx_RD3_PIN_MUX CY_GIG_ETH_RD3_PIN_MUX
  67. /* RX_CTRL_PIN */
  68. #define ETHx_RX_CTL_PORT CY_GIG_ETH_RX_CTL_PORT
  69. #define ETHx_RX_CTL_PIN CY_GIG_ETH_RX_CTL_PIN
  70. #define ETHx_RX_CTL_PIN_MUX CY_GIG_ETH_RX_CTL_PIN_MUX
  71. /* CLK_PORT_PIN */
  72. #define ETHx_TX_CLK_PORT CY_GIG_ETH_TX_CLK_PORT
  73. #define ETHx_TX_CLK_PIN CY_GIG_ETH_TX_CLK_PIN
  74. #define ETHx_TX_CLK_PIN_MUX CY_GIG_ETH_TX_CLK_PIN_MUX
  75. #define ETHx_RX_CLK_PORT CY_GIG_ETH_RX_CLK_PORT
  76. #define ETHx_RX_CLK_PIN CY_GIG_ETH_RX_CLK_PIN
  77. #define ETHx_RX_CLK_PIN_MUX CY_GIG_ETH_RX_CLK_PIN_MUX
  78. /* REF_CLK */
  79. #define ETHx_REF_CLK_PORT CY_GIG_ETH_REF_CLK_PORT
  80. #define ETHx_REF_CLK_PIN CY_GIG_ETH_REF_CLK_PIN
  81. #define ETHx_REF_CLK_PIN_MUX CY_GIG_ETH_REF_CLK_PIN_MUX
  82. /* Management Data Clock */
  83. #define ETHx_MDC_PORT CY_GIG_ETH_MDC_PORT
  84. #define ETHx_MDC_PIN CY_GIG_ETH_MDC_PIN
  85. #define ETHx_MDC_PIN_MUX CY_GIG_ETH_MDC_PIN_MUX
  86. /* Management Data Input/Output */
  87. #define ETHx_MDIO_PORT CY_GIG_ETH_MDIO_PORT
  88. #define ETHx_MDIO_PIN CY_GIG_ETH_MDIO_PIN
  89. #define ETHx_MDIO_PIN_MUX CY_GIG_ETH_MDIO_PIN_MUX
  90. /* Bits masks to verify auto negotiation configured speed */
  91. #define ANLPAR_10_Msk (0x00000020UL) /**< 10BASE-Te Support */
  92. #define ANLPAR_10_Pos (5UL) /**< 10BASE-Te bit position */
  93. #define ANLPAR_10FD_Msk (0x00000040UL) /**< 10BASE-Te Full Duplex Support */
  94. #define ANLPAR_10FD_Pos (6UL) /**< 10BASE-Te Full Duplex bit position */
  95. #define ANLPAR_TX_Msk (0x00000080UL) /**< 100BASE-TX Support */
  96. #define ANLPAR_TX_Pos (7UL) /**< 100BASE-TX bit position */
  97. #define ANLPAR_TXFD_Msk (0x00000100UL) /**< 100BASE-TX Full Duplex Support */
  98. #define ANLPAR_TXFD_Pos (8UL) /**< 100BASE-TX Full Duplex bit position */
  99. #define ANLPAR_T4_Msk (0x00000200UL) /**< 100BASE-T4 Support */
  100. #define ANLPAR_T4_Pos (9UL) /**< 100BASE-T4 bit position */
  101. #define STS1_1000BASE_T_HALFDUPLEX_Msk (0x00000400UL) /**< 1000BASE-T Half-Duplex Capable */
  102. #define STS1_1000BASE_T_HALFDUPLEX_Pos (10UL) /**< 1000BASE-T Half-Duplex bit position */
  103. #define STS1_1000BASE_T_FULLDUPLEX_Msk (0x00000800UL) /**< 1000BASE-T Full-Duplex Capable */
  104. #define STS1_1000BASE_T_FULLDUPLEX_Pos (11UL) /**< 1000BASE-T Full-Duplex bit position */
  105. /********************************************************/
  106. /** PHY related constants */
  107. #define PHY_ADDR (0) /* Value depends on PHY and its hardware configurations */
  108. #define PHY_ID_DP83867IR (0x2000A231) /* PHYIDR1=0x2000 PHYIDR2=0xA231 */
  109. /************************START********************************/
  110. struct rt_ifx_eth
  111. {
  112. /* inherit from ethernet device */
  113. struct eth_device parent;
  114. #ifndef PHY_USING_INTERRUPT_MODE
  115. rt_timer_t poll_link_timer;
  116. #endif
  117. /* interface address info, hw address */
  118. rt_uint8_t dev_addr[MAX_ADDR_LEN];
  119. /* ETH_Speed */
  120. rt_uint32_t ETH_Speed;
  121. /* ETH_Duplex_Mode */
  122. rt_uint32_t ETH_Mode;
  123. cy_stc_ephy_t phy_obj;
  124. ETH_Type *eth_base_type;
  125. };
  126. typedef struct rt_ifx_eth* rt_ifx_eth_t;
  127. static cy_stc_ethif_wrapper_config_t stcWrapperConfig;
  128. uint8_t *pRx_Q_buff_pool[CY_ETH_DEFINE_TOTAL_BD_PER_RXQUEUE];
  129. static struct rt_ifx_eth ifx_eth_device;
  130. static bool is_driver_configured = false;
  131. static rt_uint8_t eth_mempool[Eth_Mempool_Num][CY_ETH_SIZE_MAX_FRAME];
  132. static rt_uint8_t mempool_index = 0;
  133. static rt_mailbox_t recv_frame_buffer_addr_mb = RT_NULL;
  134. /************************END********************************/
  135. /************************START********************************/
  136. static void Cy_Ethx_InterruptHandler (void);
  137. void cy_process_ethernet_data_cb( ETH_Type *eth_type, uint8_t *rx_buffer, uint32_t length );
  138. void cy_notify_ethernet_rx_data_cb(ETH_Type *base, uint8_t **u8RxBuffer, uint32_t *u32Length);
  139. struct pbuf *rt_ifx_eth_rx(rt_device_t dev);
  140. rt_err_t rt_ifx_eth_tx(rt_device_t dev, struct pbuf *p);
  141. static rt_err_t rt_ifx_eth_open(rt_device_t dev, rt_uint16_t oflag);
  142. static rt_err_t rt_ifx_eth_close(rt_device_t dev);
  143. static rt_ssize_t rt_ifx_eth_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size);
  144. static rt_ssize_t rt_ifx_eth_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size);
  145. static rt_err_t rt_ifx_eth_control(rt_device_t dev, int cmd, void *args);
  146. static void phy_monitor_thread_entry(void *parameter);
  147. static cy_en_ethif_speed_sel_t ecm_config_to_speed_sel( cy_ecm_phy_config_t *config);
  148. static void eth_clock_config(cy_en_ethif_speed_sel_t speed_sel, cy_ecm_phy_speed_t phy_speed);
  149. void phyRead(uint32_t phyId, uint32_t regAddress, uint32_t *value);
  150. void phyWrite(uint32_t phyId, uint32_t regAddress, uint32_t value);
  151. static void ethernet_portpins_init (cy_ecm_speed_type_t interface_speed_type);
  152. static void init_phy_DP83867IR (ETH_Type *reg_base, cy_ecm_phy_config_t *ecm_phy_config, cy_stc_ephy_t *phy_obj);
  153. cy_rslt_t cy_eth_driver_initialization(ETH_Type *reg_base, cy_ecm_phy_config_t *ecm_phy_config, cy_stc_ephy_t *phy_obj);
  154. static void enable_phy_DP83867IR_extended_reg(ETH_Type *reg_base, cy_ecm_phy_config_t *ecm_phy_config);
  155. static rt_err_t rt_ifx_eth_init(rt_device_t dev);
  156. /************************END********************************/
  157. /************************START********************************/
  158. /** General Ethernet configuration */
  159. static cy_stc_ethif_mac_config_t stcENETConfig = {
  160. .bintrEnable = 1, /** Interrupt enable */
  161. .dmaDataBurstLen = CY_ETHIF_DMA_DBUR_LEN_4,
  162. .u8dmaCfgFlags = CY_ETHIF_CFG_DMA_FRCE_TX_BRST,
  163. .mdcPclkDiv = CY_ETHIF_MDC_DIV_BY_48, /** source clock is 80 MHz and MDC must be less than 2.5MHz */
  164. .u8rxLenErrDisc = 0, /** Length error frame not discarded */
  165. .u8disCopyPause = 0,
  166. .u8chkSumOffEn = 0, /** Checksum for both Tx and Rx disabled */
  167. .u8rx1536ByteEn = 1, /** Enable receive frame up to 1536 */
  168. .u8rxJumboFrEn = 0,
  169. .u8enRxBadPreamble = 1,
  170. .u8ignoreIpgRxEr = 0,
  171. .u8storeUdpTcpOffset = 0,
  172. .u8aw2wMaxPipeline = 2, /** Value must be > 0 */
  173. .u8ar2rMaxPipeline = 2, /** Value must be > 0 */
  174. .u8pfcMultiQuantum = 0,
  175. .pstcWrapperConfig = &stcWrapperConfig,
  176. .pstcTSUConfig = NULL, //&stcTSUConfig, /** TSU settings */
  177. .btxq0enable = 1, /** Tx Q0 Enabled */
  178. .btxq1enable = 0, /** Tx Q1 Disabled */
  179. .btxq2enable = 0, /** Tx Q2 Disabled */
  180. .brxq0enable = 1, /** Rx Q0 Enabled */
  181. .brxq1enable = 0, /** Rx Q1 Disabled */
  182. .brxq2enable = 0, /** Rx Q2 Disabled */
  183. };
  184. /** Interrupt configurations */
  185. static cy_stc_ethif_intr_config_t stcInterruptConfig = {
  186. .btsu_time_match = 0, /** Timestamp unit time match event */
  187. .bwol_rx = 0, /** Wake-on-LAN event received */
  188. .blpi_ch_rx = 0, /** LPI indication status bit change received */
  189. .btsu_sec_inc = 0, /** TSU seconds register increment */
  190. .bptp_tx_pdly_rsp = 0, /** PTP pdelay_resp frame transmitted */
  191. .bptp_tx_pdly_req = 0, /** PTP pdelay_req frame transmitted */
  192. .bptp_rx_pdly_rsp = 0, /** PTP pdelay_resp frame received */
  193. .bptp_rx_pdly_req = 0, /** PTP pdelay_req frame received */
  194. .bptp_tx_sync = 0, /** PTP sync frame transmitted */
  195. .bptp_tx_dly_req = 0, /** PTP delay_req frame transmitted */
  196. .bptp_rx_sync = 0, /** PTP sync frame received */
  197. .bptp_rx_dly_req = 0, /** PTP delay_req frame received */
  198. .bext_intr = 0, /** External input interrupt detected */
  199. .bpause_frame_tx = 0, /** Pause frame transmitted */
  200. .bpause_time_zero = 0, /** Pause time reaches zero or zero pause frame received */
  201. .bpause_nz_qu_rx = 0, /** Pause frame with non-zero quantum received */
  202. .bhresp_not_ok = 0, /** DMA HRESP not OK */
  203. .brx_overrun = 1, /** Rx overrun error */
  204. .bpcs_link_change_det = 0, /** Link status change detected by PCS */
  205. .btx_complete = 1, /** Frame has been transmitted successfully */
  206. .btx_fr_corrupt = 1, /** Tx frame corrupted */
  207. .btx_retry_ex_late_coll = 1, /** Retry limit exceeded or late collision */
  208. .btx_underrun = 1, /** Tx underrun */
  209. .btx_used_read = 1, /** Used bit set has been read in Tx descriptor list */
  210. .brx_used_read = 1, /** Used bit set has been read in Rx descriptor list */
  211. .brx_complete = 1, /** Frame received successfully and stored */
  212. .bman_frame = 0, /** Management frame sent */
  213. };
  214. //回调函数注册
  215. static cy_stc_ethif_cb_t stcInterruptCB = {
  216. /** Callback functions */
  217. .rxframecb = cy_process_ethernet_data_cb, //接收处理回调函数
  218. .txerrorcb = NULL, //发送错误回调函数
  219. .txcompletecb = NULL, //发送完成回调函数
  220. .tsuSecondInccb = NULL, //TSU 计时器每秒递增时触发的回调
  221. .rxgetbuff = cy_notify_ethernet_rx_data_cb //获取空闲缓冲区
  222. };
  223. /************************END********************************/
  224. /************************START********************************/
  225. /** PortPinName.outVal|| driveMode hsiom ||intEdge||intMask||vtrip||slewRate||driveSel||vregEn||ibufMode||vtripSel||vrefSel||vohSel*/
  226. static cy_stc_gpio_pin_config_t ethx_tx0 = {0x00, CY_GPIO_DM_STRONG_IN_OFF, ETHx_TD0_PIN_MUX, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
  227. static cy_stc_gpio_pin_config_t ethx_tx1 = {0x00, CY_GPIO_DM_STRONG_IN_OFF, ETHx_TD1_PIN_MUX, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
  228. static cy_stc_gpio_pin_config_t ethx_tx2 = {0x00, CY_GPIO_DM_STRONG_IN_OFF, ETHx_TD2_PIN_MUX, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
  229. static cy_stc_gpio_pin_config_t ethx_tx3 = {0x00, CY_GPIO_DM_STRONG_IN_OFF, ETHx_TD3_PIN_MUX, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
  230. static cy_stc_gpio_pin_config_t ethx_txctl = {0x00, CY_GPIO_DM_STRONG_IN_OFF, ETHx_TX_CTL_PIN_MUX, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
  231. static cy_stc_gpio_pin_config_t ethx_rx0 = {0x00, CY_GPIO_DM_HIGHZ, ETHx_RD0_PIN_MUX, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
  232. static cy_stc_gpio_pin_config_t ethx_rx1 = {0x00, CY_GPIO_DM_HIGHZ, ETHx_RD1_PIN_MUX, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
  233. static cy_stc_gpio_pin_config_t ethx_rx2 = {0x00, CY_GPIO_DM_HIGHZ, ETHx_RD2_PIN_MUX, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
  234. static cy_stc_gpio_pin_config_t ethx_rx3 = {0x00, CY_GPIO_DM_HIGHZ, ETHx_RD3_PIN_MUX, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
  235. static cy_stc_gpio_pin_config_t ethx_rxctl = {0x00, CY_GPIO_DM_HIGHZ, ETHx_RX_CTL_PIN_MUX, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
  236. static cy_stc_gpio_pin_config_t ethx_txclk = {0x00, CY_GPIO_DM_STRONG_IN_OFF, ETHx_TX_CLK_PIN_MUX, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
  237. static cy_stc_gpio_pin_config_t ethx_rxclk = {0x00, CY_GPIO_DM_HIGHZ, ETHx_RX_CLK_PIN_MUX, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
  238. static cy_stc_gpio_pin_config_t ethx_refclk = {0x00, CY_GPIO_DM_HIGHZ, ETHx_REF_CLK_PIN_MUX, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
  239. static cy_stc_gpio_pin_config_t ethx_mdc = {0x00, CY_GPIO_DM_STRONG_IN_OFF, ETHx_MDC_PIN_MUX, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0};
  240. static cy_stc_gpio_pin_config_t ethx_mdio = {0x00, CY_GPIO_DM_STRONG, ETHx_MDIO_PIN_MUX, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0};
  241. /** Enable Ethernet interrupts */
  242. static const cy_stc_sysint_t irq_cfg_ethx_q0 = {.intrSrc = ((NvicMux3_IRQn << 16) | ETH_INTR_SRC), .intrPriority=3UL};
  243. static const cy_stc_sysint_t irq_cfg_ethx_q1 = {.intrSrc = ((NvicMux3_IRQn << 16) | ETH_INTR_SRC_Q1), .intrPriority=3UL};
  244. static const cy_stc_sysint_t irq_cfg_ethx_q2 = {.intrSrc = ((NvicMux3_IRQn << 16) | ETH_INTR_SRC_Q2), .intrPriority=3UL};
  245. /************************END********************************/
  246. /** Interrupt handlers for Ethernet 1 */
  247. static void Cy_Ethx_InterruptHandler (void)
  248. {
  249. /* enter interrupt */
  250. rt_interrupt_enter();
  251. Cy_ETHIF_DecodeEvent(ETH_REG_BASE);
  252. /* leave interrupt */
  253. rt_interrupt_leave();
  254. }
  255. void cy_process_ethernet_data_cb( ETH_Type *eth_type, uint8_t *rx_buffer, uint32_t length )
  256. {
  257. rt_err_t result;
  258. result = rt_mb_send(recv_frame_buffer_addr_mb, (rt_ubase_t)rx_buffer);
  259. if (result != RT_EOK)
  260. {
  261. LOG_I("Send_Recv_Buffer_Adder_MB err = %d", result);
  262. }
  263. result = eth_device_ready(&(ifx_eth_device.parent));
  264. if (result != RT_EOK)
  265. {
  266. LOG_I("RxCpltCallback err = %d", result);
  267. }
  268. }
  269. void cy_notify_ethernet_rx_data_cb(ETH_Type *base, uint8_t **u8RxBuffer, uint32_t *u32Length)
  270. {
  271. *u8RxBuffer = eth_mempool[mempool_index++];
  272. if(mempool_index >= Eth_Mempool_Num)
  273. {
  274. mempool_index = 0;
  275. }
  276. *u32Length = CY_ETH_SIZE_MAX_FRAME;
  277. }
  278. struct pbuf *rt_ifx_eth_rx(rt_device_t dev)
  279. {
  280. rt_err_t result;
  281. rt_uint32_t *rx_buffer;
  282. rt_uint32_t length = CY_ETH_SIZE_MAX_FRAME;
  283. struct pbuf *recv_frame = RT_NULL;
  284. struct pbuf *temp = RT_NULL;
  285. rt_uint32_t bufferoffset = 0;
  286. rt_uint32_t payloadlength = 0;
  287. result = rt_mb_recv(recv_frame_buffer_addr_mb, (rt_ubase_t *)&rx_buffer, 1000);
  288. if(result != RT_EOK)
  289. {
  290. LOG_I("Recv_Recv_Buffer_Adder_MB err = %d", result);
  291. }
  292. recv_frame = pbuf_alloc(PBUF_RAW, length, PBUF_POOL);
  293. if(recv_frame != RT_NULL)
  294. {
  295. if(rx_buffer != RT_NULL)
  296. {
  297. for(temp = recv_frame; temp != RT_NULL; temp = temp->next)
  298. {
  299. payloadlength = temp->len;
  300. rt_memcpy((uint8_t *)((uint8_t *)temp->payload), (uint8_t *)((uint8_t *)rx_buffer + bufferoffset), (payloadlength < length ? payloadlength : length));
  301. bufferoffset = bufferoffset + payloadlength;
  302. length = length - payloadlength;
  303. }
  304. }
  305. }
  306. return recv_frame;
  307. }
  308. rt_err_t rt_ifx_eth_tx(rt_device_t dev, struct pbuf *p)
  309. {
  310. struct pbuf *q;
  311. cy_en_ethif_status_t eth_status;
  312. rt_uint32_t framelen = 0;
  313. rt_uint8_t data_buffer[CY_ETH_SIZE_MAX_FRAME];
  314. rt_ifx_eth_t ifx_device = (rt_ifx_eth_t)dev;
  315. if (p->tot_len > (u16_t)CY_ETH_SIZE_MAX_FRAME)
  316. {
  317. return -RT_ERROR;
  318. }
  319. for(q = p; q != NULL; q = q->next)
  320. {
  321. rt_memcpy(data_buffer + framelen, q->payload, q->len);
  322. framelen += (uint32_t)q->len;
  323. }
  324. eth_status = Cy_ETHIF_TransmitFrame(ifx_device->eth_base_type, data_buffer, framelen, CY_ETH_QS0_0, true);
  325. if(eth_status != CY_ETHIF_SUCCESS)
  326. {
  327. rt_kprintf("failed to send outgoing packet:[%d]\n", eth_status);
  328. }
  329. return RT_EOK;
  330. }
  331. static rt_err_t rt_ifx_eth_open(rt_device_t dev, rt_uint16_t oflag)
  332. {
  333. LOG_D("emac open");
  334. return RT_EOK;
  335. }
  336. static rt_err_t rt_ifx_eth_close(rt_device_t dev)
  337. {
  338. LOG_D("emac close");
  339. return RT_EOK;
  340. }
  341. static rt_ssize_t rt_ifx_eth_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
  342. {
  343. LOG_D("emac read");
  344. rt_set_errno(-RT_ENOSYS);
  345. return 0;
  346. }
  347. static rt_ssize_t rt_ifx_eth_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
  348. {
  349. LOG_D("emac write");
  350. rt_set_errno(-RT_ENOSYS);
  351. return 0;
  352. }
  353. static rt_err_t rt_ifx_eth_control(rt_device_t dev, int cmd, void *args)
  354. {
  355. rt_ifx_eth_t eth_device = (rt_ifx_eth_t)dev;
  356. switch (cmd)
  357. {
  358. case NIOCTL_GADDR:
  359. /* get mac address */
  360. if (args)
  361. {
  362. SMEMCPY(args, eth_device->dev_addr, 6);
  363. }
  364. else
  365. {
  366. return -RT_ERROR;
  367. }
  368. break;
  369. default :
  370. break;
  371. }
  372. return RT_EOK;
  373. }
  374. static void phy_monitor_thread_entry(void *parameter)
  375. {
  376. static rt_uint32_t phy_status = 0;
  377. rt_uint32_t phy_status_now = 0;
  378. while (1)
  379. {
  380. phy_status_now = Cy_EPHY_GetLinkStatus(&ifx_eth_device.phy_obj);
  381. if(phy_status_now != phy_status)
  382. {
  383. if(phy_status_now == 1UL)
  384. {
  385. rt_kprintf("Link Up\n");
  386. eth_device_linkchange(&ifx_eth_device.parent, RT_TRUE);
  387. }
  388. else
  389. {
  390. rt_kprintf("Link Dowm\n");
  391. eth_device_linkchange(&ifx_eth_device.parent, RT_FALSE);
  392. }
  393. phy_status = phy_status_now;
  394. }
  395. rt_thread_mdelay(1000);
  396. }
  397. }
  398. static cy_en_ethif_speed_sel_t ecm_config_to_speed_sel( cy_ecm_phy_config_t *config)
  399. {
  400. cy_en_ethif_speed_sel_t speed_sel;
  401. if( config->interface_speed_type == CY_ECM_SPEED_TYPE_MII)
  402. {
  403. speed_sel = (cy_en_ethif_speed_sel_t)config->phy_speed;
  404. }
  405. else if( config->interface_speed_type == CY_ECM_SPEED_TYPE_GMII)
  406. {
  407. speed_sel = CY_ETHIF_CTL_GMII_1000;
  408. }
  409. else if( config->interface_speed_type == CY_ECM_SPEED_TYPE_RGMII)
  410. {
  411. if(config->phy_speed == CY_ECM_PHY_SPEED_10M)
  412. {
  413. speed_sel = CY_ETHIF_CTL_RGMII_10;
  414. }
  415. else if(config->phy_speed == CY_ECM_PHY_SPEED_100M)
  416. {
  417. speed_sel = CY_ETHIF_CTL_RGMII_100;
  418. }
  419. else
  420. {
  421. speed_sel = CY_ETHIF_CTL_RGMII_1000;
  422. }
  423. }
  424. else
  425. {
  426. speed_sel = (config->phy_speed == CY_ECM_PHY_SPEED_10M)?CY_ETHIF_CTL_RMII_10 : CY_ETHIF_CTL_RMII_100;
  427. }
  428. return speed_sel;
  429. }
  430. static void eth_clock_config(cy_en_ethif_speed_sel_t speed_sel, cy_ecm_phy_speed_t phy_speed)
  431. {
  432. if((speed_sel == CY_ETHIF_CTL_MII_10) && (phy_speed == CY_ECM_PHY_SPEED_10M))
  433. stcWrapperConfig.stcInterfaceSel = CY_ETHIF_CTL_MII_10; /** 10 Mbps MII */
  434. else if((speed_sel == CY_ETHIF_CTL_MII_100) && (phy_speed == CY_ECM_PHY_SPEED_100M))
  435. stcWrapperConfig.stcInterfaceSel = CY_ETHIF_CTL_MII_100; /** 100 Mbps MII */
  436. else if((speed_sel == CY_ETHIF_CTL_GMII_1000) && (phy_speed == CY_ECM_PHY_SPEED_1000M))
  437. stcWrapperConfig.stcInterfaceSel = CY_ETHIF_CTL_GMII_1000; /** 1000 Mbps GMII */
  438. else if((speed_sel == CY_ETHIF_CTL_RGMII_10) && (phy_speed == CY_ECM_PHY_SPEED_10M))
  439. stcWrapperConfig.stcInterfaceSel = CY_ETHIF_CTL_RGMII_10; /** 10 Mbps RGMII */
  440. else if((speed_sel == CY_ETHIF_CTL_RGMII_100) && (phy_speed == CY_ECM_PHY_SPEED_100M))
  441. stcWrapperConfig.stcInterfaceSel = CY_ETHIF_CTL_RGMII_100; /** 100 Mbps RGMII */
  442. else if((speed_sel == CY_ETHIF_CTL_RGMII_1000) && (phy_speed == CY_ECM_PHY_SPEED_1000M))
  443. stcWrapperConfig.stcInterfaceSel = CY_ETHIF_CTL_RGMII_1000; /** 1000 Mbps RGMII */
  444. else if((speed_sel == CY_ETHIF_CTL_RMII_10) && (phy_speed == CY_ECM_PHY_SPEED_10M))
  445. stcWrapperConfig.stcInterfaceSel = CY_ETHIF_CTL_RMII_10; /** 10 Mbps RMII */
  446. else if((speed_sel == CY_ETHIF_CTL_RMII_100) && (phy_speed == CY_ECM_PHY_SPEED_100M))
  447. stcWrapperConfig.stcInterfaceSel = CY_ETHIF_CTL_RMII_100; /** 100 Mbps RMII */
  448. else
  449. stcWrapperConfig.stcInterfaceSel = CY_ETHIF_CTL_RGMII_1000; /** Error in configuration */
  450. stcWrapperConfig.bRefClockSource = CY_ETHIF_EXTERNAL_HSIO; /** Assigning Ref_Clk to HSIO clock; use an external clock from HSIO */
  451. if(phy_speed == CY_ECM_PHY_SPEED_10M)
  452. stcWrapperConfig.u8RefClkDiv = 10; /** RefClk: 25 MHz; divide Refclock by 10 to have a 2.5-MHz Tx clock */
  453. else if(phy_speed == CY_ECM_PHY_SPEED_100M)
  454. stcWrapperConfig.u8RefClkDiv = 1; /** RefClk: 25 MHz; divide Refclock by 1 to have a 25-MHz Tx clock */
  455. else if(phy_speed == CY_ECM_PHY_SPEED_1000M)
  456. stcWrapperConfig.u8RefClkDiv = 1; /** RefClk: 25 MHz; divide Refclock by 1 to have a 25-MHz Tx clock */
  457. else /*(phy_speed == CY_ECM_PHY_SPEED_1000M)*/
  458. stcWrapperConfig.u8RefClkDiv = 1; /** RefClk: 125 MHz; divide Refclock by 1 to have a 125-MHz Tx clock || Although only relevant in RGMII/GMII modes */
  459. return;
  460. }
  461. /* 读取PHY芯片函数 */
  462. void phyRead(uint32_t phyId, uint32_t regAddress, uint32_t *value)
  463. {
  464. *value = Cy_ETHIF_PhyRegRead(ETH_REG_BASE, regAddress, phyId);
  465. }
  466. /* 写入PHY芯片函数 */
  467. void phyWrite(uint32_t phyId, uint32_t regAddress, uint32_t value)
  468. {
  469. Cy_ETHIF_PhyRegWrite(ETH_REG_BASE, regAddress, value, phyId);
  470. }
  471. /* GPIO 初始化 */
  472. static void ethernet_portpins_init (cy_ecm_speed_type_t interface_speed_type)
  473. {
  474. (void)interface_speed_type;
  475. Cy_GPIO_Pin_Init(ETHx_TD0_PORT, ETHx_TD0_PIN, &ethx_tx0); /** TX0 */
  476. Cy_GPIO_Pin_Init(ETHx_TD1_PORT, ETHx_TD1_PIN, &ethx_tx1); /** TX1 */
  477. Cy_GPIO_Pin_Init(ETHx_TD2_PORT, ETHx_TD2_PIN, &ethx_tx2); /** TX2 */
  478. Cy_GPIO_Pin_Init(ETHx_TD3_PORT, ETHx_TD3_PIN, &ethx_tx3); /** TX3 */
  479. Cy_GPIO_Pin_Init(ETHx_TX_CTL_PORT, ETHx_TX_CTL_PIN, &ethx_txctl); /** TX_CTL */
  480. Cy_GPIO_Pin_Init(ETHx_RD0_PORT, ETHx_RD0_PIN, &ethx_rx0); /** RX0 */
  481. Cy_GPIO_Pin_Init(ETHx_RD1_PORT, ETHx_RD1_PIN, &ethx_rx1); /** RX1 */
  482. Cy_GPIO_Pin_Init(ETHx_RD2_PORT, ETHx_RD2_PIN, &ethx_rx2); /** RX2 */
  483. Cy_GPIO_Pin_Init(ETHx_RD3_PORT, ETHx_RD3_PIN, &ethx_rx3); /** RX3 */
  484. Cy_GPIO_Pin_Init(ETHx_RX_CTL_PORT, ETHx_RX_CTL_PIN, &ethx_rxctl); /** RX_CTL */
  485. Cy_GPIO_Pin_Init(ETHx_REF_CLK_PORT, ETHx_REF_CLK_PIN, &ethx_refclk); /** REF_CLK */
  486. Cy_GPIO_Pin_Init(ETHx_TX_CLK_PORT, ETHx_TX_CLK_PIN, &ethx_txclk); /** TX_CLK */
  487. Cy_GPIO_Pin_Init(ETHx_RX_CLK_PORT, ETHx_RX_CLK_PIN, &ethx_rxclk); /** RX_CLK */
  488. Cy_GPIO_Pin_Init(ETHx_MDC_PORT, ETHx_MDC_PIN, &ethx_mdc); /** MDC */
  489. Cy_GPIO_Pin_Init(ETHx_MDIO_PORT, ETHx_MDIO_PIN, &ethx_mdio); /** MDIO */
  490. }
  491. /* PHY芯片初始化 */
  492. static void init_phy_DP83867IR (ETH_Type *reg_base, cy_ecm_phy_config_t *ecm_phy_config, cy_stc_ephy_t *phy_obj)
  493. {
  494. cy_stc_ephy_config_t phyConfig;
  495. cy_en_ethif_speed_sel_t speed_sel;
  496. uint32_t value = 0;
  497. uint16_t configured_hw_speed;
  498. cy_en_ethif_status_t eth_status;
  499. /* Driver configuration is already done */
  500. if(is_driver_configured == true)
  501. {
  502. /* Initialize the PHY */
  503. Cy_EPHY_Init(phy_obj, phyRead, phyWrite);
  504. /* If driver already configured and the auto negotiation is enabled, replace the speed and mode by the auto negotiated values decided during driver initialization */
  505. if(ecm_phy_config->mode == CY_ECM_DUPLEX_AUTO || ecm_phy_config->phy_speed == CY_ECM_PHY_SPEED_AUTO)
  506. {
  507. phyRead( 0, REGISTER_ADDRESS_PHY_REG_BMCR, &value );
  508. cy_ecm_log_msg( CYLF_MIDDLEWARE, CY_LOG_ERR, "REGISTER_ADDRESS_PHY_REG_BMCR = 0x%X\n", (unsigned long)value );
  509. ecm_phy_config->mode = ((value & (REGISTER_PHY_REG_DUPLEX_MASK)) == 0) ? CY_ECM_DUPLEX_HALF : CY_ECM_DUPLEX_FULL;
  510. configured_hw_speed = value & (REGISTER_PHY_REG_SPEED_MASK);
  511. if(configured_hw_speed == REGISTER_PHY_REG_SPEED_MASK_10M)
  512. {
  513. ecm_phy_config->phy_speed = CY_ECM_PHY_SPEED_10M;
  514. }
  515. else if (configured_hw_speed == REGISTER_PHY_REG_SPEED_MASK_100M)
  516. {
  517. ecm_phy_config->phy_speed = CY_ECM_PHY_SPEED_100M;
  518. }
  519. else if(configured_hw_speed == REGISTER_PHY_REG_SPEED_MASK_1000M)
  520. {
  521. ecm_phy_config->phy_speed = CY_ECM_PHY_SPEED_1000M;
  522. }
  523. }
  524. }
  525. if(!is_driver_configured)
  526. {
  527. /* Auto Negotiation enable */
  528. if(ecm_phy_config->phy_speed == CY_ECM_PHY_SPEED_AUTO || ecm_phy_config->mode == CY_ECM_DUPLEX_AUTO)
  529. {
  530. eth_status = Cy_ETHIF_MdioInit(reg_base, &stcENETConfig);
  531. if (CY_ETHIF_SUCCESS != eth_status)
  532. {
  533. cy_ecm_log_msg( CYLF_MIDDLEWARE, CY_LOG_DEBUG, "Ethernet MAC Pre-Init failed with ethStatus=0x%X \n", eth_status );
  534. return;
  535. }
  536. cy_ecm_log_msg( CYLF_MIDDLEWARE, CY_LOG_DEBUG, "Ethernet MAC Pre-Init success \n", 0);
  537. /* Start auto negotiation */
  538. phyConfig.speed = (cy_en_ephy_speed_t)CY_ECM_PHY_SPEED_AUTO;
  539. phyConfig.duplex = (cy_en_ephy_duplex_t)CY_ECM_DUPLEX_AUTO;
  540. /* Initialize the PHY */
  541. Cy_EPHY_Init(phy_obj, phyRead, phyWrite);
  542. Cy_EPHY_Configure( phy_obj, &phyConfig );
  543. /* Required some delay to get PHY back to Run state */
  544. cy_rtos_delay_milliseconds(100);
  545. while (Cy_EPHY_GetAutoNegotiationStatus(phy_obj) != true)
  546. {
  547. cy_rtos_delay_milliseconds(100);
  548. }
  549. Cy_EPHY_getLinkPartnerCapabilities(phy_obj, &phyConfig);
  550. ecm_phy_config->phy_speed = (cy_ecm_phy_speed_t)phyConfig.speed;
  551. ecm_phy_config->mode = (cy_ecm_duplex_t)phyConfig.duplex;
  552. }
  553. speed_sel = ecm_config_to_speed_sel(ecm_phy_config);
  554. /* Update the configuration based on user input */
  555. eth_clock_config(speed_sel, ecm_phy_config->phy_speed);
  556. /** Initialize ENET MAC */
  557. eth_status = Cy_ETHIF_Init(reg_base, &stcENETConfig, &stcInterruptConfig);
  558. if (CY_ETHIF_SUCCESS != eth_status)
  559. {
  560. cy_ecm_log_msg( CYLF_MIDDLEWARE, CY_LOG_DEBUG, "Ethernet MAC Init failed with ethStatus=0x%X \n", eth_status );
  561. return;
  562. }
  563. if(!(ecm_phy_config->phy_speed == CY_ECM_PHY_SPEED_AUTO || ecm_phy_config->mode == CY_ECM_DUPLEX_AUTO))
  564. {
  565. /* Initialize the PHY */
  566. Cy_EPHY_Init(phy_obj, phyRead, phyWrite);
  567. }
  568. is_driver_configured = true;
  569. }
  570. cy_ecm_log_msg( CYLF_MIDDLEWARE, CY_LOG_DEBUG, "Register driver callbacks \n", 0);
  571. stcInterruptCB.rxframecb = cy_process_ethernet_data_cb;
  572. /* Reset the PHY */
  573. Cy_EPHY_Reset(phy_obj);
  574. Cy_ETHIF_PhyRegWrite(reg_base, 0x1F, 0x8000, PHY_ADDR); /* Ext-Reg CTRl: Perform a full reset, including all registers */
  575. cy_rtos_delay_milliseconds(30); /* Required delay of 30 ms to get PHY back to Run state after reset */
  576. Cy_EPHY_Discover(phy_obj);
  577. /* Check for supported PHYs */
  578. if (PHY_ID_DP83867IR != phy_obj->phyId)
  579. {
  580. cy_ecm_log_msg( CYLF_MIDDLEWARE, CY_LOG_DEBUG, "Not supported physical ID \n", 0);
  581. return;
  582. }
  583. phyConfig.duplex = ecm_phy_config->mode;
  584. phyConfig.speed = ecm_phy_config->phy_speed;
  585. Cy_EPHY_Configure(phy_obj, &phyConfig);
  586. /* Enable PHY extended registers */
  587. enable_phy_DP83867IR_extended_reg(reg_base, ecm_phy_config);
  588. }
  589. cy_rslt_t cy_eth_driver_initialization(ETH_Type *reg_base, cy_ecm_phy_config_t *ecm_phy_config, cy_stc_ephy_t *phy_obj)
  590. {
  591. cy_rslt_t result = CY_RSLT_SUCCESS;
  592. uint32_t retry_count = 0;
  593. cy_ecm_log_msg( CYLF_MIDDLEWARE, CY_LOG_DEBUG, "%s(): START \n", __FUNCTION__ );
  594. /** Configure Ethernet port pins */
  595. ethernet_portpins_init(ecm_phy_config->interface_speed_type);
  596. cy_ecm_log_msg( CYLF_MIDDLEWARE, CY_LOG_DEBUG, "GPIO_INIT_FINISH \n", __FUNCTION__ );
  597. Cy_SysInt_Init(&irq_cfg_ethx_q0, Cy_Ethx_InterruptHandler);
  598. Cy_SysInt_Init(&irq_cfg_ethx_q1, Cy_Ethx_InterruptHandler);
  599. Cy_SysInt_Init(&irq_cfg_ethx_q2, Cy_Ethx_InterruptHandler);
  600. cy_ecm_log_msg( CYLF_MIDDLEWARE, CY_LOG_DEBUG, "ETH_REG_BASE=[%p] reg_base = [%p] \n", ETH_REG_BASE, reg_base );
  601. /* rx Q0 buffer pool */
  602. stcENETConfig.pRxQbuffPool[0] = (cy_ethif_buffpool_t *)&pRx_Q_buff_pool;
  603. stcENETConfig.pRxQbuffPool[1] = NULL;
  604. /** Initialize PHY */
  605. init_phy_DP83867IR(reg_base, ecm_phy_config, phy_obj);
  606. NVIC_ClearPendingIRQ(NvicMux3_IRQn);
  607. NVIC_EnableIRQ(NvicMux3_IRQn);
  608. Cy_ETHIF_RegisterCallbacks(reg_base, &stcInterruptCB);
  609. cy_ecm_log_msg( CYLF_MIDDLEWARE, CY_LOG_DEBUG, "%s():retry_count:[%d] END \n", __FUNCTION__, retry_count );
  610. return result;
  611. }
  612. static void enable_phy_DP83867IR_extended_reg(ETH_Type *reg_base, cy_ecm_phy_config_t *ecm_phy_config)
  613. {
  614. if(ecm_phy_config->phy_speed == CY_ECM_PHY_SPEED_100M)
  615. {
  616. Cy_ETHIF_PhyRegWrite(reg_base, 0x10, 0x5028, PHY_ADDR); /** Disable auto negotiation for MDI/MDI-X **/
  617. }
  618. else if(ecm_phy_config->phy_speed == CY_ECM_PHY_SPEED_1000M || ecm_phy_config->phy_speed == CY_ECM_PHY_SPEED_AUTO)
  619. {
  620. uint32_t u32ReadData;
  621. Cy_ETHIF_PhyRegWrite(reg_base, 0x0D, 0x001F, PHY_ADDR); /** Begin write access to the extended register */
  622. Cy_ETHIF_PhyRegWrite(reg_base, 0x0E, 0x0170, PHY_ADDR);
  623. Cy_ETHIF_PhyRegWrite(reg_base, 0x0D, 0x401F, PHY_ADDR);
  624. u32ReadData = Cy_ETHIF_PhyRegRead(reg_base, (uint8_t)0x0E, PHY_ADDR);
  625. u32ReadData = u32ReadData & 0x0000; /** Change the I/O impedance on the PHY */
  626. u32ReadData = u32ReadData | 0x010C;
  627. Cy_ETHIF_PhyRegWrite(reg_base, 0x0E, u32ReadData, PHY_ADDR); /** Enable clock from the PHY -> Route it to the MCU */
  628. u32ReadData = Cy_ETHIF_PhyRegRead(reg_base, (uint8_t)0x0E, PHY_ADDR);
  629. }
  630. else
  631. {
  632. /* Do nothing */
  633. }
  634. /** Disable RGMII by accessing the extended register set || Please read datasheet section 8.4.2.1 for the procedure in detail */
  635. Cy_ETHIF_PhyRegWrite(reg_base, 0x0D, 0x001F, PHY_ADDR); /** REGCR */
  636. Cy_ETHIF_PhyRegWrite(reg_base, 0x0E, 0x0032, PHY_ADDR); /** ADDAR, 0x0032 RGMII config register */
  637. Cy_ETHIF_PhyRegWrite(reg_base, 0x0D, 0x401F, PHY_ADDR); /** REGCR; will force the next write/read access non-incremental */
  638. if(ecm_phy_config->interface_speed_type != CY_ECM_SPEED_TYPE_RGMII)
  639. {
  640. Cy_ETHIF_PhyRegWrite(reg_base, 0x0E, 0x0000, PHY_ADDR); /** Disable RGMII */
  641. Cy_ETHIF_PhyRegRead(reg_base, (uint8_t)0x0E, PHY_ADDR); /** Read RGMII mode status */
  642. }
  643. else
  644. {
  645. Cy_ETHIF_PhyRegWrite(reg_base, 0x0E, 0x00D3, PHY_ADDR); /** Enable Tx and RX clock delay in the RGMII configuration register */
  646. Cy_ETHIF_PhyRegWrite(reg_base, 0x0D, 0x001F, PHY_ADDR); /** REGCR */
  647. Cy_ETHIF_PhyRegWrite(reg_base, 0x0E, 0x0086, PHY_ADDR); /** ADDAR; 0x0086 delay config register */
  648. Cy_ETHIF_PhyRegWrite(reg_base, 0x0D, 0x401F, PHY_ADDR); /** REGCR; will force the next write/read access non-incremental */
  649. Cy_ETHIF_PhyRegWrite(reg_base, 0x0E, 0x0066, PHY_ADDR); /** Adjust Tx and Rx clock delays in the PHY */
  650. }/* EMAC_INTERFACE != EMAC_RGMII */
  651. Cy_ETHIF_PhyRegWrite(reg_base, 0x1F, 0x4000, PHY_ADDR); /** CTRL */
  652. cy_rtos_delay_milliseconds(30);/** Some more delay to get the PHY adapted to new interface */
  653. Cy_ETHIF_PhyRegRead(reg_base, (uint8_t)0x11, PHY_ADDR);
  654. }
  655. static rt_err_t rt_ifx_eth_init(rt_device_t dev)
  656. {
  657. rt_err_t state = RT_EOK;
  658. cy_ecm_phy_config_t phy_interface_type;
  659. ifx_eth_device.eth_base_type = ETH_INTERFACE_TYPE;
  660. cy_ecm_log_msg( CYLF_MIDDLEWARE, CY_LOG_INFO, "Device's eth_base_type is:%d\n", ETH_INTERFACE_TYPE);
  661. phy_interface_type.interface_speed_type = CY_ECM_SPEED_TYPE_RGMII;
  662. phy_interface_type.phy_speed = CY_ECM_PHY_SPEED_1000M;
  663. phy_interface_type.mode = CY_ECM_DUPLEX_FULL;
  664. cy_ecm_log_msg( CYLF_MIDDLEWARE, CY_LOG_INFO, "Using default phy_interface_type\nType :%d\nSpeed :%d\nMode :%d\n"
  665. ,phy_interface_type.interface_speed_type
  666. ,phy_interface_type.phy_speed
  667. ,phy_interface_type.mode);
  668. cy_eth_driver_initialization(ifx_eth_device.eth_base_type, &phy_interface_type, &(ifx_eth_device.phy_obj));
  669. return state;
  670. }
  671. static int rt_hw_ifx_eth_init(void)
  672. {
  673. rt_err_t result = RT_EOK;
  674. recv_frame_buffer_addr_mb = rt_mb_create("Eth_rx_mb", Eth_Mempool_Num, RT_IPC_FLAG_PRIO);
  675. if(recv_frame_buffer_addr_mb == RT_NULL)
  676. {
  677. LOG_I("Eth MailBox Init Fail");
  678. }
  679. for(rt_uint8_t i = 0; i < CY_ETH_DEFINE_TOTAL_BD_PER_RXQUEUE; i++)
  680. {
  681. pRx_Q_buff_pool[i] = rt_malloc(sizeof(uint8) * CY_ETH_SIZE_MAX_FRAME);
  682. }
  683. ifx_eth_device.dev_addr[0] = 0x00;
  684. ifx_eth_device.dev_addr[1] = 0x03;
  685. ifx_eth_device.dev_addr[2] = 0x19;
  686. ifx_eth_device.dev_addr[3] = 0x45;
  687. ifx_eth_device.dev_addr[4] = 0x00;
  688. ifx_eth_device.dev_addr[5] = 0x00;
  689. cy_ecm_log_msg( CYLF_MIDDLEWARE, CY_LOG_INFO, "Assigning default MAC address 00-03-19-45-00-00\n", 0);
  690. ifx_eth_device.parent.parent.init = rt_ifx_eth_init;
  691. ifx_eth_device.parent.parent.open = rt_ifx_eth_open;
  692. ifx_eth_device.parent.parent.close = rt_ifx_eth_close;
  693. ifx_eth_device.parent.parent.read = rt_ifx_eth_read;
  694. ifx_eth_device.parent.parent.write = rt_ifx_eth_write;
  695. ifx_eth_device.parent.parent.control = rt_ifx_eth_control;
  696. ifx_eth_device.parent.parent.user_data = RT_NULL;
  697. ifx_eth_device.parent.eth_rx = rt_ifx_eth_rx;
  698. ifx_eth_device.parent.eth_tx = rt_ifx_eth_tx;
  699. result = eth_device_init(&(ifx_eth_device.parent), "e0");
  700. if(result != RT_EOK)
  701. {
  702. LOG_E("emac device init faild: %d", result);
  703. result = -RT_ERROR;
  704. return result;
  705. }
  706. else
  707. {
  708. LOG_D("emac device init success");
  709. }
  710. rt_thread_t tid;
  711. tid = rt_thread_create("phy",
  712. phy_monitor_thread_entry,
  713. RT_NULL,
  714. 1024,
  715. RT_THREAD_PRIORITY_MAX - 2,
  716. 2);
  717. if (tid != RT_NULL)
  718. {
  719. rt_thread_startup(tid);
  720. }
  721. else
  722. {
  723. LOG_E("phy thread init faild: %d", result);
  724. result = -RT_ERROR;
  725. return result;
  726. }
  727. return result;
  728. }
  729. INIT_DEVICE_EXPORT(rt_hw_ifx_eth_init);