emac_main.c 36 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240
  1. // Copyright 2015-2017 Espressif Systems (Shanghai) PTE LTD
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. // http://www.apache.org/licenses/LICENSE-2.0
  7. //
  8. // Unless required by applicable law or agreed to in writing, software
  9. // distributed under the License is distributed on an "AS IS" BASIS,
  10. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  11. // See the License for the specific language governing permissions and
  12. // limitations under the License.
  13. #include <stdio.h>
  14. #include <stdlib.h>
  15. #include <string.h>
  16. #include "rom/ets_sys.h"
  17. #include "rom/gpio.h"
  18. #include "soc/dport_reg.h"
  19. #include "soc/io_mux_reg.h"
  20. #include "soc/rtc.h"
  21. #include "soc/rtc_cntl_reg.h"
  22. #include "soc/gpio_reg.h"
  23. #include "soc/dport_reg.h"
  24. #include "soc/emac_ex_reg.h"
  25. #include "soc/emac_reg_v2.h"
  26. #include "soc/soc.h"
  27. #include "tcpip_adapter.h"
  28. #include "sdkconfig.h"
  29. #include "esp_task_wdt.h"
  30. #include "esp_event.h"
  31. #include "esp_system.h"
  32. #include "esp_err.h"
  33. #include "esp_log.h"
  34. #include "esp_eth.h"
  35. #include "esp_intr_alloc.h"
  36. #include "esp_pm.h"
  37. #include "esp_spiram.h"
  38. #include "driver/periph_ctrl.h"
  39. #include "emac_common.h"
  40. #include "emac_desc.h"
  41. #include "freertos/xtensa_api.h"
  42. #include "freertos/FreeRTOS.h"
  43. #include "freertos/task.h"
  44. #include "freertos/queue.h"
  45. #include "freertos/semphr.h"
  46. #include "freertos/timers.h"
  47. #include "lwip/err.h"
  48. #define EMAC_EVT_QNUM 200
  49. #define EMAC_SIG_MAX 50
  50. static struct emac_config_data emac_config;
  51. static dma_extended_desc_t *emac_dma_rx_chain_buf;
  52. static dma_extended_desc_t *emac_dma_tx_chain_buf;
  53. static uint8_t *emac_dma_rx_buf[DMA_RX_BUF_NUM];
  54. static uint8_t *emac_dma_tx_buf[DMA_TX_BUF_NUM];
  55. static SemaphoreHandle_t emac_g_sem = NULL;
  56. static portMUX_TYPE g_emac_mux = portMUX_INITIALIZER_UNLOCKED;
  57. static xTaskHandle emac_task_hdl = NULL;
  58. static xQueueHandle emac_xqueue = NULL;
  59. static uint8_t emac_sig_cnt[EMAC_SIG_MAX] = {0};
  60. static TimerHandle_t emac_timer = NULL;
  61. static SemaphoreHandle_t emac_rx_xMutex = NULL;
  62. static SemaphoreHandle_t emac_tx_xMutex = NULL;
  63. static intr_handle_t eth_intr_handle = NULL;
  64. static const char *TAG = "emac";
  65. static bool pause_send = false;
  66. #ifdef CONFIG_PM_ENABLE
  67. static esp_pm_lock_handle_t s_pm_lock;
  68. #endif
  69. static esp_err_t emac_ioctl(emac_sig_t sig, emac_par_t par);
  70. esp_err_t emac_post(emac_sig_t sig, emac_par_t par);
  71. static void emac_macaddr_init(void)
  72. {
  73. esp_read_mac(&(emac_config.macaddr[0]), ESP_MAC_ETH);
  74. }
  75. void esp_eth_get_mac(uint8_t mac[6])
  76. {
  77. memcpy(mac, &(emac_config.macaddr[0]), 6);
  78. }
  79. esp_err_t esp_eth_set_mac(const uint8_t mac[6])
  80. {
  81. if (!(mac[0] & 0x01)) {
  82. memcpy(&(emac_config.macaddr[0]), mac, 6);
  83. return ESP_OK;
  84. } else {
  85. return ESP_ERR_INVALID_MAC;
  86. }
  87. }
  88. eth_speed_mode_t esp_eth_get_speed(void)
  89. {
  90. return emac_config.emac_phy_get_speed_mode();
  91. }
  92. static void emac_setup_tx_desc(dma_extended_desc_t *tx_desc, uint32_t size)
  93. {
  94. tx_desc->basic.desc1 = size & 0xfff;
  95. tx_desc->basic.desc0 = EMAC_DESC_TX_OWN | EMAC_DESC_INT_COMPL | EMAC_DESC_LAST_SEGMENT |
  96. EMAC_DESC_FIRST_SEGMENT | EMAC_DESC_SECOND_ADDR_CHAIN;
  97. }
  98. static void emac_clean_tx_desc(dma_extended_desc_t *tx_desc)
  99. {
  100. tx_desc->basic.desc1 = 0;
  101. tx_desc->basic.desc0 = 0;
  102. }
  103. static void emac_clean_rx_desc(dma_extended_desc_t *rx_desc, uint32_t buf_ptr)
  104. {
  105. if (buf_ptr != 0) {
  106. rx_desc->basic.desc2 = buf_ptr;
  107. }
  108. rx_desc->basic.desc1 = EMAC_DESC_RX_SECOND_ADDR_CHAIN | DMA_RX_BUF_SIZE;
  109. rx_desc->basic.desc0 = EMAC_DESC_RX_OWN;
  110. }
  111. static void emac_set_tx_base_reg(void)
  112. {
  113. REG_WRITE(EMAC_DMATXBASEADDR_REG, (uint32_t)(emac_config.dma_etx));
  114. }
  115. static void emac_set_rx_base_reg(void)
  116. {
  117. REG_WRITE(EMAC_DMARXBASEADDR_REG, (uint32_t)(emac_config.dma_erx));
  118. }
  119. /*
  120. * dirty_rx indicates the hardware has been fed with data packets and is the
  121. * first node software needs to handle;
  122. *
  123. * cur_rx indicates the completion of software handling and is the last node
  124. * hardware could use;
  125. *
  126. * cnt_rx is to count the numbers of packets handled by software, passed to
  127. * protocol stack and not been freed.
  128. *
  129. * (1) Initializing the Linked List. Connect the numerable nodes to a circular
  130. * linked list, appoint one of the nodes as the head node, mark* the dirty_rx
  131. * and cur_rx into the node, and mount the node on the hardware base address.
  132. * Initialize cnt_rx into 0.
  133. *
  134. * (2) When hardware receives packets, nodes of linked lists will be fed with
  135. * data packets from the base address by turns, marks the node
  136. * of linked lists as “HARDWARE UNUSABLE” and reports interrupts.
  137. *
  138. * (3) When the software receives the interrupts, it will handle the linked
  139. * lists by turns from dirty_rx, send data packets to protocol
  140. * stack. dirty_rx will deviate backwards by turns and cnt_rx will by turns ++.
  141. *
  142. * (4) After the protocol stack handles all the data and calls the free function,
  143. * it will deviate backwards by turns from cur_rx, mark the * node of linked
  144. * lists as “HARDWARE USABLE” and cnt_rx will by turns --.
  145. *
  146. * (5) Cycle from Step 2 to Step 4 without break and build up circular linked
  147. * list handling.
  148. */
  149. static void emac_reset_dma_chain(void)
  150. {
  151. emac_config.cnt_tx = 0;
  152. emac_config.cur_tx = 0;
  153. emac_config.dirty_tx = 0;
  154. emac_config.cnt_rx = 0;
  155. emac_config.cur_rx = 0;
  156. emac_config.dirty_rx = 0;
  157. }
  158. static void emac_init_dma_chain(void)
  159. {
  160. int i;
  161. uint32_t dma_phy;
  162. dma_extended_desc_t *p = NULL;
  163. //init tx chain
  164. emac_config.dma_etx = emac_dma_tx_chain_buf;
  165. emac_config.cnt_tx = 0;
  166. emac_config.cur_tx = 0;
  167. emac_config.dirty_tx = 0;
  168. dma_phy = (uint32_t)(emac_config.dma_etx);
  169. p = emac_config.dma_etx;
  170. for (i = 0; i < (DMA_TX_BUF_NUM - 1); i++) {
  171. dma_phy += sizeof(dma_extended_desc_t);
  172. emac_clean_tx_desc(p);
  173. p->basic.desc2 = (uint32_t)(emac_dma_tx_buf[i]);
  174. p->basic.desc3 = dma_phy;
  175. p++;
  176. }
  177. emac_clean_tx_desc(p);
  178. p->basic.desc2 = (uint32_t)(emac_dma_tx_buf[i]);
  179. p->basic.desc3 = (uint32_t)(emac_config.dma_etx);
  180. //init rx chain
  181. emac_config.dma_erx = emac_dma_rx_chain_buf;
  182. emac_config.cnt_rx = 0;
  183. emac_config.cur_rx = 0;
  184. emac_config.dirty_rx = 0;
  185. dma_phy = (uint32_t)(emac_config.dma_erx);
  186. p = emac_config.dma_erx;
  187. for (i = 0; i < (DMA_RX_BUF_NUM - 1); i++) {
  188. dma_phy += sizeof(dma_extended_desc_t);
  189. emac_clean_rx_desc(p, (uint32_t)(emac_dma_rx_buf[i]));
  190. p->basic.desc3 = dma_phy;
  191. p++;
  192. }
  193. emac_clean_rx_desc(p, (uint32_t)(emac_dma_rx_buf[i]));
  194. p->basic.desc3 = (uint32_t)(emac_config.dma_erx);
  195. }
  196. void esp_eth_smi_write(uint32_t reg_num, uint16_t value)
  197. {
  198. uint32_t phy_num = emac_config.phy_addr;
  199. while (REG_GET_BIT(EMAC_GMIIADDR_REG, EMAC_MIIBUSY) == 1) {
  200. }
  201. REG_WRITE(EMAC_MIIDATA_REG, value);
  202. REG_WRITE(EMAC_GMIIADDR_REG, 0x3 | ((reg_num & 0x1f) << 6) | ((phy_num & 0x1f) << 11) | ((0x3) << 2));
  203. while (REG_GET_BIT(EMAC_GMIIADDR_REG, EMAC_MIIBUSY) == 1) {
  204. }
  205. }
  206. uint16_t esp_eth_smi_read(uint32_t reg_num)
  207. {
  208. uint32_t phy_num = emac_config.phy_addr;
  209. uint16_t value = 0;
  210. while (REG_GET_BIT(EMAC_GMIIADDR_REG, EMAC_MIIBUSY) == 1) {
  211. }
  212. REG_WRITE(EMAC_GMIIADDR_REG, 0x1 | ((reg_num & 0x1f) << 6) | ((phy_num & 0x1f) << 11) | (0x3 << 2));
  213. while (REG_GET_BIT(EMAC_GMIIADDR_REG, EMAC_MIIBUSY) == 1) {
  214. }
  215. value = (REG_READ(EMAC_MIIDATA_REG) & 0xffff);
  216. return value;
  217. }
  218. esp_err_t esp_eth_smi_wait_value(uint32_t reg_num, uint16_t value, uint16_t value_mask, int timeout_ms)
  219. {
  220. unsigned start = xTaskGetTickCount();
  221. unsigned timeout_ticks = (timeout_ms + portTICK_PERIOD_MS - 1) / portTICK_PERIOD_MS;
  222. uint16_t current_value = 0;
  223. while (timeout_ticks == 0 || (xTaskGetTickCount() - start < timeout_ticks)) {
  224. current_value = esp_eth_smi_read(reg_num);
  225. if ((current_value & value_mask) == (value & value_mask)) {
  226. return ESP_OK;
  227. }
  228. vTaskDelay(1);
  229. }
  230. ESP_LOGE(TAG, "Timed out waiting for PHY register 0x%x to have value 0x%04x(mask 0x%04x). Current value 0x%04x",
  231. reg_num, value, value_mask, current_value);
  232. return ESP_ERR_TIMEOUT;
  233. }
  234. esp_err_t emac_reset(void)
  235. {
  236. REG_SET_BIT(EMAC_DMABUSMODE_REG, EMAC_SW_RST);
  237. if (emac_config.reset_timeout_ms) {
  238. int start = xTaskGetTickCount();
  239. uint32_t timeout_ticks = (emac_config.reset_timeout_ms + portTICK_PERIOD_MS - 1) / portTICK_PERIOD_MS;
  240. while (timeout_ticks == 0 || (xTaskGetTickCount() - start < timeout_ticks)) {
  241. if (REG_GET_BIT(EMAC_DMABUSMODE_REG, EMAC_SW_RST) != EMAC_SW_RST) {
  242. goto reset_ok;
  243. }
  244. vTaskDelay(1);
  245. }
  246. ESP_LOGE(TAG, "Reset EMAC Timeout");
  247. return ESP_ERR_TIMEOUT;
  248. }
  249. /* infinite wait loop */
  250. else {
  251. while (REG_GET_BIT(EMAC_DMABUSMODE_REG, EMAC_SW_RST) == EMAC_SW_RST) {
  252. //nothing to do ,if stop here,maybe emac have not clk input.
  253. ESP_LOGI(TAG, "emac resetting ....");
  254. }
  255. }
  256. reset_ok:
  257. ESP_LOGI(TAG, "emac reset done");
  258. return ESP_OK;
  259. }
  260. static void emac_set_user_config_data(eth_config_t *config)
  261. {
  262. emac_config.phy_addr = config->phy_addr;
  263. emac_config.mac_mode = config->mac_mode;
  264. emac_config.clock_mode = config->clock_mode;
  265. emac_config.phy_init = config->phy_init;
  266. emac_config.emac_tcpip_input = config->tcpip_input;
  267. emac_config.emac_gpio_config = config->gpio_config;
  268. emac_config.emac_phy_check_link = config->phy_check_link;
  269. emac_config.emac_phy_check_init = config->phy_check_init;
  270. emac_config.emac_phy_get_speed_mode = config->phy_get_speed_mode;
  271. emac_config.emac_phy_get_duplex_mode = config->phy_get_duplex_mode;
  272. emac_config.reset_timeout_ms = config->reset_timeout_ms;
  273. #if DMA_RX_BUF_NUM > 9
  274. emac_config.emac_flow_ctrl_enable = config->flow_ctrl_enable;
  275. #else
  276. if (config->flow_ctrl_enable == true) {
  277. ESP_LOGE(TAG, "Can only configure flow_ctrl_enable==true if DMA_RX_BUF_NUM in menuconfig is >9. Disabling flow control.");
  278. }
  279. emac_config.emac_flow_ctrl_enable = false;
  280. #endif
  281. emac_config.emac_phy_get_partner_pause_enable = config->phy_get_partner_pause_enable;
  282. emac_config.emac_phy_power_enable = config->phy_power_enable;
  283. }
  284. static void emac_enable_intr()
  285. {
  286. REG_WRITE(EMAC_DMAIN_EN_REG, EMAC_INTR_ENABLE_BIT);
  287. }
  288. static void emac_disable_intr()
  289. {
  290. REG_WRITE(EMAC_DMAIN_EN_REG, 0);
  291. }
  292. static esp_err_t emac_verify_args(void)
  293. {
  294. esp_err_t ret = ESP_OK;
  295. if (emac_config.phy_addr > PHY31) {
  296. ESP_LOGE(TAG, "phy addr err");
  297. ret = ESP_FAIL;
  298. }
  299. if (emac_config.mac_mode != ETH_MODE_RMII) {
  300. ESP_LOGE(TAG, "mac mode err, currently only support for RMII");
  301. ret = ESP_FAIL;
  302. }
  303. if (emac_config.clock_mode > ETH_CLOCK_GPIO17_OUT) {
  304. ESP_LOGE(TAG, "emac clock mode err");
  305. ret = ESP_FAIL;
  306. }
  307. if (emac_config.phy_init == NULL) {
  308. ESP_LOGE(TAG, "phy_init func is null");
  309. ret = ESP_FAIL;
  310. }
  311. if (emac_config.emac_tcpip_input == NULL) {
  312. ESP_LOGE(TAG, "tcpip_input func is null");
  313. ret = ESP_FAIL;
  314. }
  315. if (emac_config.emac_gpio_config == NULL) {
  316. ESP_LOGE(TAG, "gpio config func is null");
  317. ret = ESP_FAIL;
  318. }
  319. if (emac_config.emac_phy_check_link == NULL) {
  320. ESP_LOGE(TAG, "phy check link func is null");
  321. ret = ESP_FAIL;
  322. }
  323. if (emac_config.emac_phy_check_init == NULL) {
  324. ESP_LOGE(TAG, "phy check init func is null");
  325. ret = ESP_FAIL;
  326. }
  327. if (emac_config.emac_phy_get_speed_mode == NULL) {
  328. ESP_LOGE(TAG, "phy get speed mode func is null");
  329. ret = ESP_FAIL;
  330. }
  331. if (emac_config.emac_phy_get_duplex_mode == NULL) {
  332. ESP_LOGE(TAG, "phy get duplex mode func is null");
  333. ret = ESP_FAIL;
  334. }
  335. if (emac_config.emac_flow_ctrl_enable && !emac_config.emac_phy_get_partner_pause_enable) {
  336. ESP_LOGE(TAG, "phy get partner pause enable func is null");
  337. ret = ESP_FAIL;
  338. }
  339. if (emac_config.emac_phy_power_enable == NULL) {
  340. ESP_LOGE(TAG, "phy power enable func is null");
  341. ret = ESP_FAIL;
  342. }
  343. return ret;
  344. }
  345. static void emac_process_tx(void)
  346. {
  347. uint32_t cur_tx_desc = emac_read_tx_cur_reg();
  348. if (emac_config.emac_status == EMAC_RUNTIME_STOP) {
  349. return;
  350. }
  351. xSemaphoreTakeRecursive(emac_tx_xMutex, portMAX_DELAY);
  352. while (((uint32_t) & (emac_config.dma_etx[emac_config.dirty_tx])) != cur_tx_desc) {
  353. emac_clean_tx_desc(&(emac_config.dma_etx[emac_config.dirty_tx]));
  354. emac_config.dirty_tx = (emac_config.dirty_tx + 1) % DMA_TX_BUF_NUM;
  355. emac_config.cnt_tx--;
  356. if (emac_config.cnt_tx < 0) {
  357. ESP_LOGE(TAG, "emac tx chain err");
  358. }
  359. cur_tx_desc = emac_read_tx_cur_reg();
  360. }
  361. xSemaphoreGiveRecursive(emac_tx_xMutex);
  362. }
  363. void esp_eth_free_rx_buf(void *buf)
  364. {
  365. xSemaphoreTakeRecursive(emac_rx_xMutex, portMAX_DELAY);
  366. emac_clean_rx_desc(&(emac_config.dma_erx[emac_config.cur_rx]), (uint32_t)buf);
  367. emac_config.cur_rx = (emac_config.cur_rx + 1) % DMA_RX_BUF_NUM;
  368. emac_config.cnt_rx--;
  369. if (emac_config.cnt_rx < 0) {
  370. ESP_LOGE(TAG, "emac rx buf err");
  371. }
  372. emac_poll_rx_cmd();
  373. xSemaphoreGiveRecursive(emac_rx_xMutex);
  374. if (emac_config.emac_flow_ctrl_partner_support) {
  375. portENTER_CRITICAL(&g_emac_mux);
  376. if (pause_send && emac_config.cnt_rx < FLOW_CONTROL_LOW_WATERMARK) {
  377. emac_send_pause_zero_frame_enable();
  378. pause_send = false;
  379. }
  380. portEXIT_CRITICAL(&g_emac_mux);
  381. }
  382. }
  383. static uint32_t IRAM_ATTR emac_get_rxbuf_count_in_intr(void)
  384. {
  385. uint32_t cnt = 0;
  386. uint32_t cur_rx_desc = emac_read_rx_cur_reg();
  387. dma_extended_desc_t *cur_desc = (dma_extended_desc_t *)cur_rx_desc;
  388. while (cur_desc->basic.desc0 == EMAC_DESC_RX_OWN && cnt < DMA_RX_BUF_NUM) {
  389. cnt++;
  390. cur_desc = (dma_extended_desc_t *)cur_desc->basic.desc3;
  391. }
  392. return cnt;
  393. }
  394. #if CONFIG_EMAC_L2_TO_L3_RX_BUF_MODE
  395. static void emac_process_rx(void)
  396. {
  397. if (emac_config.emac_status == EMAC_RUNTIME_STOP) {
  398. return;
  399. }
  400. uint32_t cur_rx_desc = emac_read_rx_cur_reg();
  401. while (((uint32_t) & (emac_config.dma_erx[emac_config.dirty_rx])) != cur_rx_desc) {
  402. //copy data to lwip
  403. emac_config.emac_tcpip_input((void *)(emac_config.dma_erx[emac_config.dirty_rx].basic.desc2),
  404. (((emac_config.dma_erx[emac_config.dirty_rx].basic.desc0) >> EMAC_DESC_FRAME_LENGTH_S) &
  405. EMAC_DESC_FRAME_LENGTH), NULL);
  406. emac_clean_rx_desc(&(emac_config.dma_erx[emac_config.dirty_rx]), (emac_config.dma_erx[emac_config.dirty_rx].basic.desc2));
  407. emac_config.dirty_rx = (emac_config.dirty_rx + 1) % DMA_RX_BUF_NUM;
  408. cur_rx_desc = emac_read_rx_cur_reg();
  409. }
  410. emac_enable_rx_intr();
  411. }
  412. static void emac_process_rx_unavail(void)
  413. {
  414. if (emac_config.emac_status == EMAC_RUNTIME_STOP) {
  415. return;
  416. }
  417. uint32_t dirty_cnt = 0;
  418. while (dirty_cnt < DMA_RX_BUF_NUM) {
  419. if (emac_config.dma_erx[emac_config.dirty_rx].basic.desc0 & EMAC_DESC_RX_OWN) {
  420. break;
  421. }
  422. dirty_cnt++;
  423. //copy data to lwip
  424. emac_config.emac_tcpip_input((void *)(emac_config.dma_erx[emac_config.dirty_rx].basic.desc2),
  425. (((emac_config.dma_erx[emac_config.dirty_rx].basic.desc0) >> EMAC_DESC_FRAME_LENGTH_S) &
  426. EMAC_DESC_FRAME_LENGTH), NULL);
  427. emac_clean_rx_desc(&(emac_config.dma_erx[emac_config.dirty_rx]), (emac_config.dma_erx[emac_config.dirty_rx].basic.desc2));
  428. emac_config.dirty_rx = (emac_config.dirty_rx + 1) % DMA_RX_BUF_NUM;
  429. }
  430. emac_enable_rx_intr();
  431. emac_enable_rx_unavail_intr();
  432. emac_poll_rx_cmd();
  433. }
  434. #else
  435. static void emac_process_rx_unavail(void)
  436. {
  437. if (emac_config.emac_status == EMAC_RUNTIME_STOP) {
  438. return;
  439. }
  440. xSemaphoreTakeRecursive(emac_rx_xMutex, portMAX_DELAY);
  441. while (emac_config.cnt_rx < DMA_RX_BUF_NUM) {
  442. if (emac_config.dma_erx[emac_config.dirty_rx].basic.desc0 & EMAC_DESC_RX_OWN) {
  443. break;
  444. }
  445. emac_config.cnt_rx++;
  446. if (emac_config.cnt_rx > DMA_RX_BUF_NUM) {
  447. ESP_LOGE(TAG, "emac rx buf full");
  448. }
  449. uint32_t tmp_dirty = emac_config.dirty_rx;
  450. emac_config.dirty_rx = (emac_config.dirty_rx + 1) % DMA_RX_BUF_NUM;
  451. //copy data to lwip
  452. emac_config.emac_tcpip_input((void *)(emac_config.dma_erx[tmp_dirty].basic.desc2),
  453. (((emac_config.dma_erx[tmp_dirty].basic.desc0) >> EMAC_DESC_FRAME_LENGTH_S) &
  454. EMAC_DESC_FRAME_LENGTH), NULL);
  455. }
  456. emac_enable_rx_intr();
  457. emac_enable_rx_unavail_intr();
  458. xSemaphoreGiveRecursive(emac_rx_xMutex);
  459. }
  460. static void emac_process_rx(void)
  461. {
  462. if (emac_config.emac_status == EMAC_RUNTIME_STOP) {
  463. return;
  464. }
  465. uint32_t cur_rx_desc = emac_read_rx_cur_reg();
  466. xSemaphoreTakeRecursive(emac_rx_xMutex, portMAX_DELAY);
  467. if ((((uint32_t) & (emac_config.dma_erx[emac_config.dirty_rx])) != cur_rx_desc)) {
  468. while ((((uint32_t) & (emac_config.dma_erx[emac_config.dirty_rx])) != cur_rx_desc) &&
  469. emac_config.cnt_rx < DMA_RX_BUF_NUM) {
  470. emac_config.cnt_rx++;
  471. if (emac_config.cnt_rx > DMA_RX_BUF_NUM) {
  472. ESP_LOGE(TAG, "emac rx buf full");
  473. }
  474. uint32_t tmp_dirty = emac_config.dirty_rx;
  475. emac_config.dirty_rx = (emac_config.dirty_rx + 1) % DMA_RX_BUF_NUM;
  476. //copy data to lwip
  477. emac_config.emac_tcpip_input((void *)(emac_config.dma_erx[tmp_dirty].basic.desc2),
  478. (((emac_config.dma_erx[tmp_dirty].basic.desc0) >> EMAC_DESC_FRAME_LENGTH_S) &
  479. EMAC_DESC_FRAME_LENGTH), NULL);
  480. cur_rx_desc = emac_read_rx_cur_reg();
  481. }
  482. } else {
  483. if (emac_config.cnt_rx < DMA_RX_BUF_NUM) {
  484. if (!(emac_config.dma_erx[emac_config.dirty_rx].basic.desc0 & EMAC_DESC_RX_OWN)) {
  485. while (emac_config.cnt_rx < DMA_RX_BUF_NUM) {
  486. if (emac_config.dma_erx[emac_config.dirty_rx].basic.desc0 & EMAC_DESC_RX_OWN) {
  487. break;
  488. }
  489. emac_config.cnt_rx++;
  490. if (emac_config.cnt_rx > DMA_RX_BUF_NUM) {
  491. ESP_LOGE(TAG, "emac rx buf full");
  492. }
  493. uint32_t tmp_dirty = emac_config.dirty_rx;
  494. emac_config.dirty_rx = (emac_config.dirty_rx + 1) % DMA_RX_BUF_NUM;
  495. //copy data to lwip
  496. emac_config.emac_tcpip_input((void *)(emac_config.dma_erx[tmp_dirty].basic.desc2),
  497. (((emac_config.dma_erx[tmp_dirty].basic.desc0) >> EMAC_DESC_FRAME_LENGTH_S) &
  498. EMAC_DESC_FRAME_LENGTH), NULL);
  499. }
  500. }
  501. }
  502. }
  503. emac_enable_rx_intr();
  504. xSemaphoreGiveRecursive(emac_rx_xMutex);
  505. }
  506. #endif
  507. //TODO other events need to do something
  508. static void IRAM_ATTR emac_process_intr(void *arg)
  509. {
  510. uint32_t event;
  511. event = REG_READ(EMAC_DMASTATUS_REG);
  512. //clr intrs
  513. REG_WRITE(EMAC_DMASTATUS_REG, event);
  514. if (event & EMAC_RECV_INT) {
  515. emac_disable_rx_intr();
  516. if (emac_config.emac_flow_ctrl_partner_support) {
  517. if (emac_get_rxbuf_count_in_intr() < FLOW_CONTROL_HIGH_WATERMARK && !pause_send) {
  518. pause_send = true;
  519. emac_send_pause_frame_enable();
  520. }
  521. }
  522. emac_post(SIG_EMAC_RX_DONE, 0);
  523. }
  524. if (event & EMAC_RECV_BUF_UNAVAIL) {
  525. emac_disable_rx_unavail_intr();
  526. emac_post(SIG_EMAC_RX_UNAVAIL, 0);
  527. }
  528. if (event & EMAC_TRANS_INT) {
  529. emac_post(SIG_EMAC_TX_DONE, 0);
  530. }
  531. }
  532. static void emac_set_macaddr_reg(void)
  533. {
  534. REG_SET_FIELD(EMAC_ADDR0HIGH_REG, EMAC_ADDRESS0_HI, (emac_config.macaddr[5] << 8) | (emac_config.macaddr[4]));
  535. REG_WRITE(EMAC_ADDR0LOW_REG, (emac_config.macaddr[3] << 24) | (emac_config.macaddr[2] << 16) |
  536. (emac_config.macaddr[1] << 8) | (emac_config.macaddr[0]));
  537. }
  538. static void emac_check_phy_init(void)
  539. {
  540. emac_config.emac_phy_check_init();
  541. if (emac_config.emac_phy_get_duplex_mode() == ETH_MODE_FULLDUPLEX) {
  542. REG_SET_BIT(EMAC_GMACCONFIG_REG, EMAC_EMACDUPLEX);
  543. } else {
  544. REG_CLR_BIT(EMAC_GMACCONFIG_REG, EMAC_EMACDUPLEX);
  545. }
  546. if (emac_config.emac_phy_get_speed_mode() == ETH_SPEED_MODE_100M) {
  547. REG_SET_BIT(EMAC_GMACCONFIG_REG, EMAC_EMACFESPEED);
  548. } else {
  549. REG_CLR_BIT(EMAC_GMACCONFIG_REG, EMAC_EMACFESPEED);
  550. }
  551. #if CONFIG_EMAC_L2_TO_L3_RX_BUF_MODE
  552. emac_disable_flowctrl();
  553. emac_config.emac_flow_ctrl_partner_support = false;
  554. #else
  555. if (emac_config.emac_flow_ctrl_enable) {
  556. if (emac_config.emac_phy_get_partner_pause_enable() &&
  557. emac_config.emac_phy_get_duplex_mode() == ETH_MODE_FULLDUPLEX) {
  558. emac_enable_flowctrl();
  559. emac_config.emac_flow_ctrl_partner_support = true;
  560. } else {
  561. emac_disable_flowctrl();
  562. emac_config.emac_flow_ctrl_partner_support = false;
  563. }
  564. } else {
  565. emac_disable_flowctrl();
  566. emac_config.emac_flow_ctrl_partner_support = false;
  567. }
  568. #endif
  569. emac_mac_enable_txrx();
  570. }
  571. static void emac_process_link_updown(bool link_status)
  572. {
  573. system_event_t evt;
  574. uint8_t i = 0;
  575. emac_config.phy_link_up = link_status;
  576. if (link_status) {
  577. emac_check_phy_init();
  578. ESP_LOGD(TAG, "eth link_up");
  579. emac_enable_dma_tx();
  580. emac_enable_dma_rx();
  581. for (i = 0; i < PHY_LINK_CHECK_NUM; i++) {
  582. emac_check_phy_init();
  583. }
  584. evt.event_id = SYSTEM_EVENT_ETH_CONNECTED;
  585. } else {
  586. ESP_LOGD(TAG, "eth link_down");
  587. emac_disable_dma_tx();
  588. emac_disable_dma_rx();
  589. evt.event_id = SYSTEM_EVENT_ETH_DISCONNECTED;
  590. }
  591. esp_event_send(&evt);
  592. }
  593. static void emac_hw_init(void)
  594. {
  595. //init chain
  596. emac_init_dma_chain();
  597. //get hw features TODO
  598. //ipc TODO
  599. }
  600. esp_err_t esp_eth_tx(uint8_t *buf, uint16_t size)
  601. {
  602. esp_err_t ret = ESP_OK;
  603. if (emac_config.emac_status != EMAC_RUNTIME_START) {
  604. ESP_LOGE(TAG, "tx netif is not ready, emac_status=%d", emac_config.emac_status);
  605. ret = ESP_ERR_INVALID_STATE;
  606. return ret;
  607. }
  608. xSemaphoreTakeRecursive(emac_tx_xMutex, portMAX_DELAY);
  609. if (emac_config.cnt_tx == DMA_TX_BUF_NUM - 1) {
  610. ESP_LOGD(TAG, "tx buf full");
  611. ret = ESP_ERR_NO_MEM;
  612. goto _exit;
  613. }
  614. memcpy((void *)(emac_config.dma_etx[emac_config.cur_tx].basic.desc2), buf, size);
  615. emac_setup_tx_desc(&(emac_config.dma_etx[emac_config.cur_tx]), size);
  616. emac_config.cnt_tx++;
  617. emac_config.cur_tx = (emac_config.cur_tx + 1) % DMA_TX_BUF_NUM;
  618. emac_poll_tx_cmd();
  619. _exit:
  620. xSemaphoreGiveRecursive(emac_tx_xMutex);
  621. return ret;
  622. }
  623. static void emac_init_default_data(void)
  624. {
  625. memset((void *)&emac_config, 0, sizeof(struct emac_config_data));
  626. }
  627. void emac_process_link_check(void)
  628. {
  629. if (emac_config.emac_status != EMAC_RUNTIME_START) {
  630. return;
  631. }
  632. if (emac_config.emac_phy_check_link()) {
  633. if (!emac_config.phy_link_up) {
  634. emac_process_link_updown(true);
  635. }
  636. } else {
  637. if (emac_config.phy_link_up) {
  638. emac_process_link_updown(false);
  639. }
  640. }
  641. }
  642. void emac_link_check_func(void *pv_parameters)
  643. {
  644. emac_post(SIG_EMAC_CHECK_LINK, 0);
  645. }
  646. static bool emac_link_check_timer_init(void)
  647. {
  648. emac_timer = xTimerCreate("emac_timer",
  649. (CONFIG_EMAC_CHECK_LINK_PERIOD_MS / portTICK_PERIOD_MS),
  650. pdTRUE,
  651. NULL,
  652. emac_link_check_func);
  653. if (emac_timer == NULL) {
  654. return false;
  655. } else {
  656. return true;
  657. }
  658. }
  659. static bool emac_link_check_timer_start(void)
  660. {
  661. if (xTimerStart(emac_timer, portMAX_DELAY) != pdPASS) {
  662. return false;
  663. } else {
  664. return true;
  665. }
  666. }
  667. static bool emac_link_check_timer_stop(void)
  668. {
  669. if (xTimerStop(emac_timer, portMAX_DELAY) != pdPASS) {
  670. return false;
  671. } else {
  672. return true;
  673. }
  674. }
  675. static bool emac_link_check_timer_delete(void)
  676. {
  677. xTimerDelete(emac_timer, portMAX_DELAY);
  678. emac_timer = NULL;
  679. return true;
  680. }
  681. static void emac_start(void *param)
  682. {
  683. struct emac_post_cmd *post_cmd = (struct emac_post_cmd *)param;
  684. struct emac_open_cmd *cmd = (struct emac_open_cmd *)(post_cmd->cmd);
  685. ESP_LOGD(TAG, "emac start");
  686. cmd->err = EMAC_CMD_OK;
  687. if (emac_reset() != ESP_OK) {
  688. return;
  689. }
  690. emac_reset_dma_chain();
  691. emac_dma_init();
  692. emac_set_macaddr_reg();
  693. emac_set_tx_base_reg();
  694. emac_set_rx_base_reg();
  695. emac_mac_init();
  696. emac_enable_intr();
  697. emac_config.emac_status = EMAC_RUNTIME_START;
  698. system_event_t evt;
  699. evt.event_id = SYSTEM_EVENT_ETH_START;
  700. esp_event_send(&evt);
  701. //set a timer to check link up status
  702. if (emac_link_check_timer_init()) {
  703. if (!emac_link_check_timer_start()) {
  704. cmd->err = EMAC_CMD_FAIL;
  705. emac_link_check_timer_delete();
  706. }
  707. } else {
  708. cmd->err = EMAC_CMD_FAIL;
  709. }
  710. if (post_cmd->post_type == EMAC_POST_SYNC) {
  711. xSemaphoreGive(emac_g_sem);
  712. }
  713. ESP_LOGD(TAG, "emac start success");
  714. }
  715. esp_err_t esp_eth_enable(void)
  716. {
  717. struct emac_post_cmd post_cmd;
  718. struct emac_open_cmd open_cmd;
  719. post_cmd.cmd = (void *)(&open_cmd);
  720. open_cmd.err = EMAC_CMD_OK;
  721. if (emac_config.emac_status == EMAC_RUNTIME_START) {
  722. open_cmd.err = EMAC_CMD_OK;
  723. return open_cmd.err;
  724. }
  725. #ifdef CONFIG_PM_ENABLE
  726. esp_err_t err = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "ethernet", &s_pm_lock);
  727. if (err != ESP_OK) {
  728. return err;
  729. }
  730. esp_pm_lock_acquire(s_pm_lock);
  731. #endif //CONFIG_PM_ENABLE
  732. emac_enable_clk(true);
  733. /* init phy device */
  734. if (emac_config.phy_init() != ESP_OK) {
  735. ESP_LOGE(TAG, "Initialise PHY device Timeout");
  736. return ESP_FAIL;
  737. }
  738. if (emac_config.emac_status != EMAC_RUNTIME_NOT_INIT) {
  739. if (emac_ioctl(SIG_EMAC_START, (emac_par_t)(&post_cmd))) {
  740. open_cmd.err = EMAC_CMD_FAIL;
  741. goto cleanup;
  742. }
  743. } else {
  744. open_cmd.err = EMAC_CMD_FAIL;
  745. goto cleanup;
  746. }
  747. return EMAC_CMD_OK;
  748. cleanup:
  749. #ifdef CONFIG_PM_ENABLE
  750. esp_pm_lock_release(s_pm_lock);
  751. esp_pm_lock_delete(s_pm_lock);
  752. s_pm_lock = NULL;
  753. #endif //CONFIG_PM_ENABLE
  754. return open_cmd.err;
  755. }
  756. static void emac_stop(void *param)
  757. {
  758. struct emac_post_cmd *post_cmd = (struct emac_post_cmd *)param;
  759. ESP_LOGD(TAG, "emac stop");
  760. emac_link_check_timer_stop();
  761. emac_link_check_timer_delete();
  762. emac_process_link_updown(false);
  763. emac_disable_intr();
  764. emac_enable_clk(false);
  765. emac_config.emac_status = EMAC_RUNTIME_STOP;
  766. system_event_t evt;
  767. evt.event_id = SYSTEM_EVENT_ETH_STOP;
  768. esp_event_send(&evt);
  769. if (post_cmd->post_type == EMAC_POST_SYNC) {
  770. xSemaphoreGive(emac_g_sem);
  771. }
  772. ESP_LOGD(TAG, "emac stop success");
  773. }
  774. esp_err_t esp_eth_disable(void)
  775. {
  776. struct emac_post_cmd post_cmd;
  777. struct emac_close_cmd close_cmd;
  778. post_cmd.cmd = (void *)(&close_cmd);
  779. close_cmd.err = EMAC_CMD_OK;
  780. if (emac_config.emac_status == EMAC_RUNTIME_STOP) {
  781. close_cmd.err = EMAC_CMD_OK;
  782. return close_cmd.err;
  783. }
  784. #ifdef CONFIG_PM_ENABLE
  785. esp_pm_lock_release(s_pm_lock);
  786. esp_pm_lock_delete(s_pm_lock);
  787. s_pm_lock = NULL;
  788. #endif // CONFIG_PM_ENABLE
  789. if (emac_config.emac_status == EMAC_RUNTIME_START) {
  790. if (emac_ioctl(SIG_EMAC_STOP, (emac_par_t)(&post_cmd)) != 0) {
  791. close_cmd.err = EMAC_CMD_FAIL;
  792. }
  793. } else {
  794. close_cmd.err = EMAC_CMD_FAIL;
  795. }
  796. return close_cmd.err;
  797. }
  798. static esp_err_t emac_ioctl(emac_sig_t sig, emac_par_t par)
  799. {
  800. esp_err_t ret = ESP_OK;
  801. struct emac_post_cmd *post_cmd = (struct emac_post_cmd *)par;
  802. xTaskHandle task_hdl = xTaskGetCurrentTaskHandle();
  803. if (emac_task_hdl != task_hdl) {
  804. post_cmd->post_type = EMAC_POST_SYNC;
  805. if (emac_post(sig, par) != ESP_OK) {
  806. ret = ESP_FAIL;
  807. return ret;
  808. };
  809. if (xSemaphoreTake(emac_g_sem, portMAX_DELAY) == pdTRUE) {
  810. return ret;
  811. }
  812. } else {
  813. post_cmd->post_type = EMAC_POST_ASYNC;
  814. switch (sig) {
  815. case SIG_EMAC_RX_DONE:
  816. emac_process_rx();
  817. break;
  818. case SIG_EMAC_TX_DONE:
  819. emac_process_tx();
  820. break;
  821. case SIG_EMAC_START:
  822. emac_start((void *)par);
  823. break;
  824. case SIG_EMAC_STOP:
  825. emac_stop((void *)par);
  826. break;
  827. default:
  828. ESP_LOGE(TAG, "unexpect sig %d", sig);
  829. break;
  830. }
  831. }
  832. return ret;
  833. }
  834. void emac_task(void *pv)
  835. {
  836. emac_event_t e;
  837. for (;;) {
  838. if (xQueueReceive(emac_xqueue, &e, portMAX_DELAY) == pdTRUE) {
  839. portENTER_CRITICAL(&g_emac_mux);
  840. emac_sig_cnt[e.sig]--;
  841. portEXIT_CRITICAL(&g_emac_mux);
  842. switch (e.sig) {
  843. case SIG_EMAC_RX_DONE:
  844. emac_process_rx();
  845. break;
  846. case SIG_EMAC_RX_UNAVAIL:
  847. emac_process_rx_unavail();
  848. break;
  849. case SIG_EMAC_TX_DONE:
  850. emac_process_tx();
  851. break;
  852. case SIG_EMAC_START:
  853. emac_start((void *)e.par);
  854. break;
  855. case SIG_EMAC_STOP:
  856. emac_stop((void *)e.par);
  857. break;
  858. case SIG_EMAC_CHECK_LINK:
  859. emac_process_link_check();
  860. break;
  861. default:
  862. ESP_LOGE(TAG, "unexpect sig %d", e.sig);
  863. break;
  864. }
  865. }
  866. }
  867. }
  868. esp_err_t IRAM_ATTR emac_post(emac_sig_t sig, emac_par_t par)
  869. {
  870. if (sig <= SIG_EMAC_RX_DONE) {
  871. if (emac_sig_cnt[sig]) {
  872. return ESP_OK;
  873. } else {
  874. emac_sig_cnt[sig]++;
  875. emac_event_t evt;
  876. signed portBASE_TYPE ret;
  877. evt.sig = sig;
  878. evt.par = par;
  879. portBASE_TYPE tmp;
  880. ret = xQueueSendFromISR(emac_xqueue, &evt, &tmp);
  881. if (tmp != pdFALSE) {
  882. portYIELD_FROM_ISR();
  883. }
  884. if (ret != pdPASS) {
  885. return ESP_FAIL;
  886. }
  887. }
  888. } else {
  889. portENTER_CRITICAL(&g_emac_mux);
  890. emac_sig_cnt[sig]++;
  891. portEXIT_CRITICAL(&g_emac_mux);
  892. emac_event_t evt;
  893. evt.sig = sig;
  894. evt.par = par;
  895. if (xQueueSend(emac_xqueue, &evt, 10 / portTICK_PERIOD_MS) != pdTRUE) {
  896. return ESP_FAIL;
  897. }
  898. }
  899. return ESP_OK;
  900. }
  901. esp_err_t esp_eth_init(eth_config_t *config)
  902. {
  903. esp_event_set_default_eth_handlers();
  904. return esp_eth_init_internal(config);
  905. }
  906. esp_err_t esp_eth_init_internal(eth_config_t *config)
  907. {
  908. int i = 0;
  909. esp_err_t ret = ESP_OK;
  910. if (emac_config.emac_status != EMAC_RUNTIME_NOT_INIT) {
  911. goto _initialised;
  912. }
  913. /* dynamically alloc memory for ethernet dma */
  914. emac_dma_rx_chain_buf = (dma_extended_desc_t *)heap_caps_malloc(sizeof(dma_extended_desc_t) * DMA_RX_BUF_NUM, MALLOC_CAP_DMA);
  915. emac_dma_tx_chain_buf = (dma_extended_desc_t *)heap_caps_malloc(sizeof(dma_extended_desc_t) * DMA_TX_BUF_NUM, MALLOC_CAP_DMA);
  916. for (i = 0; i < DMA_RX_BUF_NUM; i++) {
  917. emac_dma_rx_buf[i] = (uint8_t *)heap_caps_malloc(DMA_RX_BUF_SIZE, MALLOC_CAP_DMA);
  918. }
  919. for (i = 0; i < DMA_TX_BUF_NUM; i++) {
  920. emac_dma_tx_buf[i] = (uint8_t *)heap_caps_malloc(DMA_TX_BUF_SIZE, MALLOC_CAP_DMA);
  921. }
  922. emac_init_default_data();
  923. if (config) {
  924. emac_set_user_config_data(config);
  925. }
  926. ret = emac_verify_args();
  927. if (ret != ESP_OK) {
  928. goto _verify_err;
  929. }
  930. emac_config.emac_phy_power_enable(true);
  931. //before set emac reg must enable clk
  932. periph_module_enable(PERIPH_EMAC_MODULE);
  933. if (emac_config.clock_mode != ETH_CLOCK_GPIO0_IN) {
  934. #if CONFIG_SPIRAM_SUPPORT
  935. if (esp_spiram_is_initialized()) {
  936. ESP_LOGE(TAG, "GPIO16 and GPIO17 has been occupied by PSRAM, Only ETH_CLOCK_GPIO_IN is supported!");
  937. ret = ESP_FAIL;
  938. goto _verify_err;
  939. } else {
  940. ESP_LOGW(TAG, "GPIO16/17 is used for clock of EMAC, Please Make Sure you're not using PSRAM.");
  941. }
  942. #endif
  943. // 50 MHz = 40MHz * (6 + 4) / (2 * (2 + 2) = 400MHz / 8
  944. rtc_clk_apll_enable(1, 0, 0, 6, 2);
  945. REG_SET_FIELD(EMAC_EX_CLKOUT_CONF_REG, EMAC_EX_CLK_OUT_H_DIV_NUM, 0);
  946. REG_SET_FIELD(EMAC_EX_CLKOUT_CONF_REG, EMAC_EX_CLK_OUT_DIV_NUM, 0);
  947. if (emac_config.clock_mode == ETH_CLOCK_GPIO16_OUT) {
  948. PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO16_U, FUNC_GPIO16_EMAC_CLK_OUT);
  949. ESP_LOGD(TAG, "EMAC 50MHz clock output on GPIO16");
  950. } else if (emac_config.clock_mode == ETH_CLOCK_GPIO17_OUT) {
  951. PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO17_U, FUNC_GPIO17_EMAC_CLK_OUT_180);
  952. ESP_LOGD(TAG, "EMAC 50MHz inverted clock output on GPIO17");
  953. }
  954. }
  955. emac_enable_clk(true);
  956. REG_SET_FIELD(EMAC_EX_PHYINF_CONF_REG, EMAC_EX_PHY_INTF_SEL, EMAC_EX_PHY_INTF_RMII);
  957. emac_dma_init();
  958. if (emac_config.clock_mode == ETH_CLOCK_GPIO0_IN) {
  959. // external clock on GPIO0
  960. REG_SET_BIT(EMAC_EX_CLK_CTRL_REG, EMAC_EX_EXT_OSC_EN);
  961. REG_CLR_BIT(EMAC_EX_CLK_CTRL_REG, EMAC_EX_INT_OSC_EN);
  962. REG_SET_BIT(EMAC_EX_OSCCLK_CONF_REG, EMAC_EX_OSC_CLK_SEL);
  963. ESP_LOGD(TAG, "External clock input 50MHz on GPIO0");
  964. if (emac_config.mac_mode == ETH_MODE_MII) {
  965. REG_SET_BIT(EMAC_EX_CLK_CTRL_REG, EMAC_EX_MII_CLK_RX_EN);
  966. REG_SET_BIT(EMAC_EX_CLK_CTRL_REG, EMAC_EX_MII_CLK_TX_EN);
  967. }
  968. } else {
  969. // internal clock by APLL
  970. REG_CLR_BIT(EMAC_EX_CLK_CTRL_REG, EMAC_EX_EXT_OSC_EN);
  971. REG_SET_BIT(EMAC_EX_CLK_CTRL_REG, EMAC_EX_INT_OSC_EN);
  972. REG_CLR_BIT(EMAC_EX_OSCCLK_CONF_REG, EMAC_EX_OSC_CLK_SEL);
  973. }
  974. emac_config.emac_gpio_config();
  975. emac_hw_init();
  976. emac_macaddr_init();
  977. //watchdog TODO
  978. //init task for emac
  979. emac_g_sem = xSemaphoreCreateBinary();
  980. emac_rx_xMutex = xSemaphoreCreateRecursiveMutex();
  981. emac_tx_xMutex = xSemaphoreCreateRecursiveMutex();
  982. emac_xqueue = xQueueCreate(EMAC_EVT_QNUM, sizeof(emac_event_t));
  983. xTaskCreate(emac_task,
  984. "emacT",
  985. EMAC_TASK_STACK_SIZE,
  986. NULL,
  987. EMAC_TASK_PRIORITY,
  988. &emac_task_hdl);
  989. esp_intr_alloc(ETS_ETH_MAC_INTR_SOURCE, 0, emac_process_intr, NULL, &eth_intr_handle);
  990. emac_config.emac_status = EMAC_RUNTIME_INIT;
  991. return ESP_OK;
  992. _verify_err:
  993. free(emac_dma_rx_chain_buf);
  994. free(emac_dma_tx_chain_buf);
  995. emac_dma_rx_chain_buf = NULL;
  996. emac_dma_tx_chain_buf = NULL;
  997. for (i = 0; i < DMA_RX_BUF_NUM; i++) {
  998. free(emac_dma_rx_buf[i]);
  999. emac_dma_rx_buf[i] = NULL;
  1000. }
  1001. for (i = 0; i < DMA_TX_BUF_NUM; i++) {
  1002. free(emac_dma_tx_buf[i]);
  1003. emac_dma_tx_buf[i] = NULL;
  1004. }
  1005. _initialised:
  1006. return ret;
  1007. }
  1008. esp_err_t esp_eth_deinit(void)
  1009. {
  1010. esp_err_t ret = ESP_OK;
  1011. int i = 0;
  1012. if (emac_config.emac_status == EMAC_RUNTIME_NOT_INIT) {
  1013. goto _exit;
  1014. }
  1015. if (emac_config.emac_status == EMAC_RUNTIME_START) {
  1016. esp_eth_disable();
  1017. }
  1018. if (!emac_task_hdl) {
  1019. ret = ESP_ERR_INVALID_STATE;
  1020. goto _exit;
  1021. }
  1022. vTaskDelete(emac_task_hdl);
  1023. emac_task_hdl = NULL;
  1024. vQueueDelete(emac_xqueue);
  1025. vSemaphoreDelete(emac_tx_xMutex);
  1026. vSemaphoreDelete(emac_rx_xMutex);
  1027. vSemaphoreDelete(emac_g_sem);
  1028. emac_reset_dma_chain();
  1029. emac_config.emac_phy_power_enable(false);
  1030. periph_module_disable(PERIPH_EMAC_MODULE);
  1031. emac_config.emac_status = EMAC_RUNTIME_NOT_INIT;
  1032. /* free memory that dynamically allocted */
  1033. free(emac_dma_rx_chain_buf);
  1034. free(emac_dma_tx_chain_buf);
  1035. emac_dma_rx_chain_buf = NULL;
  1036. emac_dma_tx_chain_buf = NULL;
  1037. for (i = 0; i < DMA_RX_BUF_NUM; i++) {
  1038. free(emac_dma_rx_buf[i]);
  1039. emac_dma_rx_buf[i] = NULL;
  1040. }
  1041. for (i = 0; i < DMA_TX_BUF_NUM; i++) {
  1042. free(emac_dma_tx_buf[i]);
  1043. emac_dma_tx_buf[i] = NULL;
  1044. }
  1045. esp_intr_free(eth_intr_handle);
  1046. _exit:
  1047. return ret;
  1048. }