forked from espressif/esp-idf
Merge branch 'master' into feature/cmake
This commit is contained in:
@@ -13,6 +13,7 @@
|
||||
// limitations under the License.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "rom/ets_sys.h"
|
||||
@@ -58,15 +59,15 @@
|
||||
|
||||
static struct emac_config_data emac_config;
|
||||
|
||||
static uint8_t emac_dma_rx_chain_buf[sizeof(struct dma_extended_desc) * DMA_RX_BUF_NUM];
|
||||
static uint8_t emac_dma_tx_chain_buf[sizeof(struct dma_extended_desc) * DMA_TX_BUF_NUM];
|
||||
static uint8_t emac_dma_rx_buf[DMA_RX_BUF_SIZE * DMA_RX_BUF_NUM];
|
||||
static uint8_t emac_dma_tx_buf[DMA_TX_BUF_SIZE * DMA_TX_BUF_NUM];
|
||||
static dma_extended_desc_t *emac_dma_rx_chain_buf[DMA_RX_BUF_NUM];
|
||||
static dma_extended_desc_t *emac_dma_tx_chain_buf[DMA_TX_BUF_NUM];
|
||||
static uint8_t *emac_dma_rx_buf[DMA_RX_BUF_NUM];
|
||||
static uint8_t *emac_dma_tx_buf[DMA_TX_BUF_NUM];
|
||||
|
||||
static SemaphoreHandle_t emac_g_sem;
|
||||
static SemaphoreHandle_t emac_g_sem = NULL;
|
||||
static portMUX_TYPE g_emac_mux = portMUX_INITIALIZER_UNLOCKED;
|
||||
static xTaskHandle emac_task_hdl;
|
||||
static xQueueHandle emac_xqueue;
|
||||
static xTaskHandle emac_task_hdl = NULL;
|
||||
static xQueueHandle emac_xqueue = NULL;
|
||||
static uint8_t emac_sig_cnt[EMAC_SIG_MAX] = {0};
|
||||
static TimerHandle_t emac_timer = NULL;
|
||||
static SemaphoreHandle_t emac_rx_xMutex = NULL;
|
||||
@@ -92,19 +93,23 @@ void esp_eth_get_mac(uint8_t mac[6])
|
||||
|
||||
esp_err_t esp_eth_set_mac(const uint8_t mac[6])
|
||||
{
|
||||
if((mac[0] & 0x01) == 0) {
|
||||
memcpy(&(emac_config.macaddr[0]),mac, 6);
|
||||
if ((mac[0] & 0x01) == 0) {
|
||||
memcpy(&(emac_config.macaddr[0]), mac, 6);
|
||||
return ESP_OK;
|
||||
} else {
|
||||
return ESP_ERR_INVALID_MAC;
|
||||
}
|
||||
}
|
||||
|
||||
static void emac_setup_tx_desc(struct dma_extended_desc *tx_desc , uint32_t size)
|
||||
static void emac_setup_tx_desc(struct dma_extended_desc *tx_desc, uint32_t size)
|
||||
{
|
||||
tx_desc->basic.desc1 = size & 0xfff;
|
||||
tx_desc->basic.desc0 = EMAC_DESC_INT_COMPL | EMAC_DESC_LAST_SEGMENT | EMAC_DESC_FIRST_SEGMENT | EMAC_DESC_SECOND_ADDR_CHAIN;
|
||||
tx_desc->basic.desc0 = EMAC_DESC_TX_OWN | EMAC_DESC_INT_COMPL | EMAC_DESC_LAST_SEGMENT | EMAC_DESC_FIRST_SEGMENT | EMAC_DESC_SECOND_ADDR_CHAIN;
|
||||
tx_desc->basic.desc0 = EMAC_DESC_INT_COMPL | EMAC_DESC_LAST_SEGMENT |
|
||||
EMAC_DESC_FIRST_SEGMENT |
|
||||
EMAC_DESC_SECOND_ADDR_CHAIN;
|
||||
tx_desc->basic.desc0 = EMAC_DESC_TX_OWN | EMAC_DESC_INT_COMPL |
|
||||
EMAC_DESC_LAST_SEGMENT | EMAC_DESC_FIRST_SEGMENT |
|
||||
EMAC_DESC_SECOND_ADDR_CHAIN;
|
||||
}
|
||||
|
||||
static void emac_clean_tx_desc(struct dma_extended_desc *tx_desc)
|
||||
@@ -113,7 +118,8 @@ static void emac_clean_tx_desc(struct dma_extended_desc *tx_desc)
|
||||
tx_desc->basic.desc0 = 0;
|
||||
}
|
||||
|
||||
static void emac_clean_rx_desc(struct dma_extended_desc *rx_desc , uint32_t buf_ptr)
|
||||
static void emac_clean_rx_desc(struct dma_extended_desc *rx_desc,
|
||||
uint32_t buf_ptr)
|
||||
{
|
||||
if (buf_ptr != 0) {
|
||||
rx_desc->basic.desc2 = buf_ptr;
|
||||
@@ -133,23 +139,34 @@ static void emac_set_rx_base_reg(void)
|
||||
}
|
||||
|
||||
/*
|
||||
* dirty_rx indicates the hardware has been fed with data packets and is the first node software needs to handle;
|
||||
* dirty_rx indicates the hardware has been fed with data packets and is the
|
||||
* first node software needs to handle;
|
||||
*
|
||||
* cur_rx indicates the completion of software handling and is the last node hardware could use;
|
||||
* cur_rx indicates the completion of software handling and is the last node
|
||||
* hardware could use;
|
||||
*
|
||||
* cnt_rx is to count the numbers of packets handled by software, passed to protocol stack and not been freed.
|
||||
* cnt_rx is to count the numbers of packets handled by software, passed to
|
||||
* protocol stack and not been freed.
|
||||
*
|
||||
* (1) Initializing the Linked List. Connect the numerable nodes to a circular linked list, appoint one of the nodes as the head node, mark* the dirty_rx and cur_rx into the node, and mount the node on the hardware base address. Initialize cnt_rx into 0.
|
||||
* (1) Initializing the Linked List. Connect the numerable nodes to a circular
|
||||
* linked list, appoint one of the nodes as the head node, mark* the dirty_rx
|
||||
* and cur_rx into the node, and mount the node on the hardware base address.
|
||||
* Initialize cnt_rx into 0.
|
||||
*
|
||||
* (2) When hardware receives packets, nodes of linked lists will be fed with data packets from the base address by turns, marks the node
|
||||
* (2) When hardware receives packets, nodes of linked lists will be fed with
|
||||
* data packets from the base address by turns, marks the node
|
||||
* of linked lists as “HARDWARE UNUSABLE” and reports interrupts.
|
||||
*
|
||||
* (3) When the software receives the interrupts, it will handle the linked lists by turns from dirty_rx, send data packets to protocol
|
||||
* (3) When the software receives the interrupts, it will handle the linked
|
||||
* lists by turns from dirty_rx, send data packets to protocol
|
||||
* stack. dirty_rx will deviate backwards by turns and cnt_rx will by turns ++.
|
||||
*
|
||||
* (4) After the protocol stack handles all the data and calls the free function, it will deviate backwards by turns from cur_rx, mark the * node of linked lists as “HARDWARE USABLE” and cnt_rx will by turns --.
|
||||
* (4) After the protocol stack handles all the data and calls the free function,
|
||||
* it will deviate backwards by turns from cur_rx, mark the * node of linked
|
||||
* lists as “HARDWARE USABLE” and cnt_rx will by turns --.
|
||||
*
|
||||
* (5) Cycle from Step 2 to Step 4 without break and build up circular linked list handling.
|
||||
* (5) Cycle from Step 2 to Step 4 without break and build up circular linked
|
||||
* list handling.
|
||||
*/
|
||||
static void emac_reset_dma_chain(void)
|
||||
{
|
||||
@@ -165,48 +182,46 @@ static void emac_reset_dma_chain(void)
|
||||
static void emac_init_dma_chain(void)
|
||||
{
|
||||
int i;
|
||||
uint32_t dma_phy;
|
||||
struct dma_extended_desc *p = NULL;
|
||||
dma_extended_desc_t *p = NULL;
|
||||
|
||||
//init tx chain
|
||||
emac_config.dma_etx = (struct dma_extended_desc *)(&emac_dma_tx_chain_buf[0]);
|
||||
emac_config.dma_etx = emac_dma_tx_chain_buf[0];
|
||||
emac_config.cnt_tx = 0;
|
||||
emac_config.cur_tx = 0;
|
||||
emac_config.dirty_tx = 0;
|
||||
|
||||
dma_phy = (uint32_t)(emac_config.dma_etx);
|
||||
p = emac_config.dma_etx;
|
||||
|
||||
for (i = 0; i < (DMA_TX_BUF_NUM - 1); i++ ) {
|
||||
dma_phy += sizeof(struct dma_extended_desc);
|
||||
p = emac_dma_tx_chain_buf[0];
|
||||
for (i = 0; i < (DMA_TX_BUF_NUM - 1); i++) {
|
||||
emac_clean_tx_desc(p);
|
||||
p->basic.desc3 = dma_phy;
|
||||
p->basic.desc2 = (uint32_t)(&emac_dma_tx_buf[0]) + (i * DMA_TX_BUF_SIZE);
|
||||
p++;
|
||||
/* point to the buffer */
|
||||
p->basic.desc2 = (uint32_t)(emac_dma_tx_buf[i]);
|
||||
/* point to next descriptor */
|
||||
p->basic.desc3 = (uint32_t)(emac_dma_tx_chain_buf[i + 1]);
|
||||
p = emac_dma_tx_chain_buf[i + 1];
|
||||
}
|
||||
p->basic.desc3 = (uint32_t)(emac_config.dma_etx);
|
||||
p->basic.desc2 = (uint32_t)(&emac_dma_tx_buf[0]) + (i * DMA_TX_BUF_SIZE);
|
||||
|
||||
//init desc0 desc1
|
||||
emac_clean_tx_desc(p);
|
||||
/* point to the buffer */
|
||||
p->basic.desc2 = (uint32_t)(emac_dma_tx_buf[i]);
|
||||
/* point to first descriptor */
|
||||
p->basic.desc3 = (uint32_t)(emac_config.dma_etx);
|
||||
|
||||
//init rx chain
|
||||
emac_config.dma_erx = (struct dma_extended_desc *)(&emac_dma_rx_chain_buf[0]);
|
||||
emac_config.dma_erx = emac_dma_rx_chain_buf[0];
|
||||
emac_config.cnt_rx = 0;
|
||||
emac_config.cur_rx = 0;
|
||||
emac_config.dirty_rx = 0;
|
||||
|
||||
dma_phy = (uint32_t)(emac_config.dma_erx);
|
||||
p = emac_config.dma_erx;
|
||||
|
||||
for (i = 0; i < (DMA_RX_BUF_NUM - 1); i++ ) {
|
||||
dma_phy += sizeof(struct dma_extended_desc);
|
||||
emac_clean_rx_desc(p, (uint32_t)(&emac_dma_rx_buf[0]) + (i * DMA_RX_BUF_SIZE));
|
||||
p->basic.desc3 = dma_phy;
|
||||
p++;
|
||||
p = emac_dma_rx_chain_buf[0];
|
||||
for (i = 0; i < (DMA_RX_BUF_NUM - 1); i++) {
|
||||
emac_clean_rx_desc(p, (uint32_t)(emac_dma_rx_buf[i]));
|
||||
/* point to the buffer */
|
||||
p->basic.desc3 = (uint32_t)(emac_dma_rx_chain_buf[i + 1]);
|
||||
/* point to next descriptor */
|
||||
p = emac_dma_rx_chain_buf[i + 1];
|
||||
}
|
||||
|
||||
emac_clean_rx_desc(p, (uint32_t)(&emac_dma_rx_buf[0]) + (i * DMA_RX_BUF_SIZE));
|
||||
/* point to the buffer */
|
||||
emac_clean_rx_desc(p, (uint32_t)(emac_dma_rx_buf[i]));
|
||||
/* point to first descriptor */
|
||||
p->basic.desc3 = (uint32_t)(emac_config.dma_erx);
|
||||
}
|
||||
|
||||
@@ -214,13 +229,14 @@ void esp_eth_smi_write(uint32_t reg_num, uint16_t value)
|
||||
{
|
||||
uint32_t phy_num = emac_config.phy_addr;
|
||||
|
||||
while (REG_GET_BIT(EMAC_GMIIADDR_REG, EMAC_MIIBUSY) == 1 ) {
|
||||
while (REG_GET_BIT(EMAC_GMIIADDR_REG, EMAC_MIIBUSY) == 1) {
|
||||
}
|
||||
|
||||
REG_WRITE(EMAC_MIIDATA_REG, value);
|
||||
REG_WRITE(EMAC_GMIIADDR_REG, 0x3 | ((reg_num & 0x1f) << 6) | ((phy_num & 0x1f) << 11) | ((0x3) << 2));
|
||||
REG_WRITE(EMAC_GMIIADDR_REG, 0x3 | ((reg_num & 0x1f) << 6) |
|
||||
((phy_num & 0x1f) << 11) | ((0x3) << 2));
|
||||
|
||||
while (REG_GET_BIT(EMAC_GMIIADDR_REG, EMAC_MIIBUSY) == 1 ) {
|
||||
while (REG_GET_BIT(EMAC_GMIIADDR_REG, EMAC_MIIBUSY) == 1) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -229,21 +245,24 @@ uint16_t esp_eth_smi_read(uint32_t reg_num)
|
||||
uint32_t phy_num = emac_config.phy_addr;
|
||||
uint16_t value = 0;
|
||||
|
||||
while (REG_GET_BIT(EMAC_GMIIADDR_REG, EMAC_MIIBUSY) == 1 ) {
|
||||
while (REG_GET_BIT(EMAC_GMIIADDR_REG, EMAC_MIIBUSY) == 1) {
|
||||
}
|
||||
|
||||
REG_WRITE(EMAC_GMIIADDR_REG, 0x1 | ((reg_num & 0x1f) << 6) | ((phy_num & 0x1f) << 11) | (0x3 << 2));
|
||||
while (REG_GET_BIT(EMAC_GMIIADDR_REG, EMAC_MIIBUSY) == 1 ) {
|
||||
REG_WRITE(EMAC_GMIIADDR_REG, 0x1 | ((reg_num & 0x1f) << 6) |
|
||||
((phy_num & 0x1f) << 11) | (0x3 << 2));
|
||||
while (REG_GET_BIT(EMAC_GMIIADDR_REG, EMAC_MIIBUSY) == 1) {
|
||||
}
|
||||
value = (REG_READ(EMAC_MIIDATA_REG) & 0xffff);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
esp_err_t esp_eth_smi_wait_value(uint32_t reg_num, uint16_t value, uint16_t value_mask, int timeout_ms)
|
||||
esp_err_t esp_eth_smi_wait_value(uint32_t reg_num, uint16_t value,
|
||||
uint16_t value_mask, int timeout_ms)
|
||||
{
|
||||
unsigned start = xTaskGetTickCount();
|
||||
unsigned timeout_ticks = (timeout_ms + portTICK_PERIOD_MS - 1) / portTICK_PERIOD_MS;
|
||||
unsigned timeout_ticks = (timeout_ms + portTICK_PERIOD_MS - 1) /
|
||||
portTICK_PERIOD_MS;
|
||||
uint16_t current_value = 0;
|
||||
|
||||
while (timeout_ticks == 0 || (xTaskGetTickCount() - start < timeout_ticks)) {
|
||||
@@ -253,13 +272,12 @@ esp_err_t esp_eth_smi_wait_value(uint32_t reg_num, uint16_t value, uint16_t valu
|
||||
}
|
||||
vTaskDelay(1);
|
||||
}
|
||||
ESP_LOGE(TAG, "Timed out waiting for PHY register 0x%x to have value 0x%04x (mask 0x%04x). Current value 0x%04x",
|
||||
ESP_LOGE(TAG, "Timed out waiting for PHY register 0x%x to have value 0x%04x(mask 0x%04x). Current value 0x%04x",
|
||||
reg_num, value, value_mask, current_value);
|
||||
return ESP_ERR_TIMEOUT;
|
||||
}
|
||||
|
||||
|
||||
static void emac_set_user_config_data(eth_config_t *config )
|
||||
static void emac_set_user_config_data(eth_config_t *config)
|
||||
{
|
||||
emac_config.phy_addr = config->phy_addr;
|
||||
emac_config.mac_mode = config->mac_mode;
|
||||
@@ -275,11 +293,12 @@ static void emac_set_user_config_data(eth_config_t *config )
|
||||
emac_config.emac_flow_ctrl_enable = config->flow_ctrl_enable;
|
||||
#else
|
||||
if(config->flow_ctrl_enable == true) {
|
||||
ESP_LOGE(TAG, "eth flow ctrl init err!!! Please run menuconfig and make sure DMA_RX_BUF_NUM > 9 .");
|
||||
ESP_LOGE(TAG, "Can only configure flow_ctrl_enable==true if DMA_RX_BUF_NUM in menuconfig is >9. Disabling flow control.");
|
||||
}
|
||||
emac_config.emac_flow_ctrl_enable = false;
|
||||
#endif
|
||||
emac_config.emac_phy_get_partner_pause_enable = config->phy_get_partner_pause_enable;
|
||||
emac_config.emac_phy_get_partner_pause_enable =
|
||||
config->phy_get_partner_pause_enable;
|
||||
emac_config.emac_phy_power_enable = config->phy_power_enable;
|
||||
}
|
||||
|
||||
@@ -347,12 +366,13 @@ static esp_err_t emac_verify_args(void)
|
||||
ret = ESP_FAIL;
|
||||
}
|
||||
|
||||
if (emac_config.emac_flow_ctrl_enable == true && emac_config.emac_phy_get_partner_pause_enable == NULL) {
|
||||
if (emac_config.emac_flow_ctrl_enable == true &&
|
||||
emac_config.emac_phy_get_partner_pause_enable == NULL) {
|
||||
ESP_LOGE(TAG, "phy get partner pause enable func is null");
|
||||
ret = ESP_FAIL;
|
||||
}
|
||||
|
||||
if(emac_config.emac_phy_power_enable == NULL) {
|
||||
if (emac_config.emac_phy_power_enable == NULL) {
|
||||
ESP_LOGE(TAG, "phy power enable func is null");
|
||||
ret = ESP_FAIL;
|
||||
}
|
||||
@@ -368,12 +388,12 @@ static void emac_process_tx(void)
|
||||
return;
|
||||
}
|
||||
|
||||
xSemaphoreTakeRecursive( emac_tx_xMutex, ( TickType_t ) portMAX_DELAY );
|
||||
xSemaphoreTakeRecursive(emac_tx_xMutex, portMAX_DELAY);
|
||||
|
||||
while (((uint32_t) & (emac_config.dma_etx[emac_config.dirty_tx].basic.desc0) != cur_tx_desc)) {
|
||||
emac_clean_tx_desc(&(emac_config.dma_etx[emac_config.dirty_tx]));
|
||||
while ((uint32_t)(emac_dma_tx_chain_buf[emac_config.dirty_tx]) != cur_tx_desc) {
|
||||
emac_clean_tx_desc(emac_dma_tx_chain_buf[emac_config.dirty_tx]);
|
||||
emac_config.dirty_tx = (emac_config.dirty_tx + 1) % DMA_TX_BUF_NUM;
|
||||
emac_config.cnt_tx --;
|
||||
emac_config.cnt_tx--;
|
||||
|
||||
if (emac_config.cnt_tx < 0) {
|
||||
ESP_LOGE(TAG, "emac tx chain err");
|
||||
@@ -381,14 +401,14 @@ static void emac_process_tx(void)
|
||||
cur_tx_desc = emac_read_tx_cur_reg();
|
||||
}
|
||||
|
||||
xSemaphoreGiveRecursive( emac_tx_xMutex );
|
||||
xSemaphoreGiveRecursive(emac_tx_xMutex);
|
||||
}
|
||||
|
||||
void esp_eth_free_rx_buf(void *buf)
|
||||
{
|
||||
xSemaphoreTakeRecursive( emac_rx_xMutex, ( TickType_t ) portMAX_DELAY );
|
||||
xSemaphoreTakeRecursive(emac_rx_xMutex, portMAX_DELAY);
|
||||
|
||||
emac_clean_rx_desc(&(emac_config.dma_erx[emac_config.cur_rx]), (uint32_t) buf);
|
||||
emac_clean_rx_desc(emac_dma_rx_chain_buf[emac_config.cur_rx], (uint32_t)buf);
|
||||
emac_config.cur_rx = (emac_config.cur_rx + 1) % DMA_RX_BUF_NUM;
|
||||
emac_config.cnt_rx--;
|
||||
if (emac_config.cnt_rx < 0) {
|
||||
@@ -396,11 +416,12 @@ void esp_eth_free_rx_buf(void *buf)
|
||||
}
|
||||
emac_poll_rx_cmd();
|
||||
|
||||
xSemaphoreGiveRecursive( emac_rx_xMutex );
|
||||
xSemaphoreGiveRecursive(emac_rx_xMutex);
|
||||
|
||||
if (emac_config.emac_flow_ctrl_partner_support == true) {
|
||||
portENTER_CRITICAL(&g_emac_mux);
|
||||
if (pause_send == true && emac_config.cnt_rx < FLOW_CONTROL_LOW_WATERMARK) {
|
||||
if (pause_send == true && emac_config.cnt_rx <
|
||||
FLOW_CONTROL_LOW_WATERMARK) {
|
||||
emac_send_pause_zero_frame_enable();
|
||||
pause_send = false;
|
||||
}
|
||||
@@ -412,7 +433,7 @@ static uint32_t IRAM_ATTR emac_get_rxbuf_count_in_intr(void)
|
||||
{
|
||||
uint32_t cnt = 0;
|
||||
uint32_t cur_rx_desc = emac_read_rx_cur_reg();
|
||||
struct dma_extended_desc *cur_desc = (struct dma_extended_desc *)cur_rx_desc;
|
||||
struct dma_extended_desc *cur_desc = (dma_extended_desc_t *)cur_rx_desc;
|
||||
|
||||
while (cur_desc->basic.desc0 == EMAC_DESC_RX_OWN && cnt < DMA_RX_BUF_NUM) {
|
||||
cnt++;
|
||||
@@ -429,12 +450,16 @@ static void emac_process_rx(void)
|
||||
}
|
||||
uint32_t cur_rx_desc = emac_read_rx_cur_reg();
|
||||
|
||||
while (((uint32_t) & (emac_config.dma_erx[emac_config.dirty_rx].basic.desc0) != cur_rx_desc)) {
|
||||
while (((uint32_t)(emac_dma_rx_chain_buf[emac_config.dirty_rx]) != cur_rx_desc)) {
|
||||
//copy data to lwip
|
||||
emac_config.emac_tcpip_input((void *)(emac_config.dma_erx[emac_config.dirty_rx].basic.desc2),
|
||||
(((emac_config.dma_erx[emac_config.dirty_rx].basic.desc0) >> EMAC_DESC_FRAME_LENGTH_S) & EMAC_DESC_FRAME_LENGTH) , NULL);
|
||||
emac_config.emac_tcpip_input((emac_dma_rx_buf[emac_config.dirty_rx]),
|
||||
(((emac_dma_rx_chain_buf[emac_config.dirty_rx]->basic.desc0) >>
|
||||
EMAC_DESC_FRAME_LENGTH_S) &
|
||||
EMAC_DESC_FRAME_LENGTH),
|
||||
NULL);
|
||||
|
||||
emac_clean_rx_desc(&(emac_config.dma_erx[emac_config.dirty_rx]), (emac_config.dma_erx[emac_config.dirty_rx].basic.desc2));
|
||||
emac_clean_rx_desc(emac_dma_rx_chain_buf[emac_config.dirty_rx],
|
||||
(uint32_t)(emac_dma_rx_buf[emac_config.dirty_rx]));
|
||||
emac_config.dirty_rx = (emac_config.dirty_rx + 1) % DMA_RX_BUF_NUM;
|
||||
|
||||
//if open this ,one intr can do many intrs ?
|
||||
@@ -453,16 +478,20 @@ static void emac_process_rx_unavail(void)
|
||||
uint32_t dirty_cnt = 0;
|
||||
while (dirty_cnt < DMA_RX_BUF_NUM) {
|
||||
|
||||
if (emac_config.dma_erx[emac_config.dirty_rx].basic.desc0 == EMAC_DESC_RX_OWN) {
|
||||
if (emac_dma_rx_chain_buf[emac_config.dirty_rx]->basic.desc0 == EMAC_DESC_RX_OWN) {
|
||||
break;
|
||||
}
|
||||
|
||||
dirty_cnt ++;
|
||||
dirty_cnt++;
|
||||
//copy data to lwip
|
||||
emac_config.emac_tcpip_input((void *)(emac_config.dma_erx[emac_config.dirty_rx].basic.desc2),
|
||||
(((emac_config.dma_erx[emac_config.dirty_rx].basic.desc0) >> EMAC_DESC_FRAME_LENGTH_S) & EMAC_DESC_FRAME_LENGTH) , NULL);
|
||||
emac_config.emac_tcpip_input((emac_dma_rx_buf[emac_config.dirty_rx]),
|
||||
(((emac_dma_rx_chain_buf[emac_config.dirty_rx]->basic.desc0) >>
|
||||
EMAC_DESC_FRAME_LENGTH_S) &
|
||||
EMAC_DESC_FRAME_LENGTH),
|
||||
NULL);
|
||||
|
||||
emac_clean_rx_desc(&(emac_config.dma_erx[emac_config.dirty_rx]), (emac_config.dma_erx[emac_config.dirty_rx].basic.desc2));
|
||||
emac_clean_rx_desc(emac_dma_rx_chain_buf[emac_config.dirty_rx],
|
||||
(uint32_t)(emac_dma_rx_buf[emac_config.dirty_rx]));
|
||||
emac_config.dirty_rx = (emac_config.dirty_rx + 1) % DMA_RX_BUF_NUM;
|
||||
}
|
||||
emac_enable_rx_intr();
|
||||
@@ -477,11 +506,11 @@ static void emac_process_rx_unavail(void)
|
||||
return;
|
||||
}
|
||||
|
||||
xSemaphoreTakeRecursive( emac_rx_xMutex, ( TickType_t ) portMAX_DELAY );
|
||||
xSemaphoreTakeRecursive(emac_rx_xMutex, portMAX_DELAY);
|
||||
|
||||
while (emac_config.cnt_rx < DMA_RX_BUF_NUM) {
|
||||
|
||||
if (emac_config.dma_erx[emac_config.dirty_rx].basic.desc0 == EMAC_DESC_RX_OWN) {
|
||||
if (emac_dma_rx_chain_buf[emac_config.dirty_rx]->basic.desc0 == EMAC_DESC_RX_OWN) {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -493,13 +522,15 @@ static void emac_process_rx_unavail(void)
|
||||
emac_config.dirty_rx = (emac_config.dirty_rx + 1) % DMA_RX_BUF_NUM;
|
||||
|
||||
//copy data to lwip
|
||||
emac_config.emac_tcpip_input((void *)(emac_config.dma_erx[tmp_dirty].basic.desc2),
|
||||
(((emac_config.dma_erx[tmp_dirty].basic.desc0) >> EMAC_DESC_FRAME_LENGTH_S) & EMAC_DESC_FRAME_LENGTH) , NULL);
|
||||
|
||||
}
|
||||
emac_config.emac_tcpip_input((emac_dma_rx_buf[tmp_dirty]),
|
||||
(((emac_dma_rx_chain_buf[tmp_dirty]->basic.desc0) >>
|
||||
EMAC_DESC_FRAME_LENGTH_S) &
|
||||
EMAC_DESC_FRAME_LENGTH),
|
||||
NULL);
|
||||
}
|
||||
emac_enable_rx_intr();
|
||||
emac_enable_rx_unavail_intr();
|
||||
xSemaphoreGiveRecursive( emac_rx_xMutex );
|
||||
xSemaphoreGiveRecursive(emac_rx_xMutex);
|
||||
}
|
||||
|
||||
static void emac_process_rx(void)
|
||||
@@ -510,31 +541,36 @@ static void emac_process_rx(void)
|
||||
|
||||
uint32_t cur_rx_desc = emac_read_rx_cur_reg();
|
||||
|
||||
xSemaphoreTakeRecursive( emac_rx_xMutex, ( TickType_t ) portMAX_DELAY );
|
||||
xSemaphoreTakeRecursive(emac_rx_xMutex, portMAX_DELAY);
|
||||
|
||||
if (((uint32_t) & (emac_config.dma_erx[emac_config.dirty_rx].basic.desc0) != cur_rx_desc)) {
|
||||
if (((uint32_t)(emac_dma_rx_chain_buf[emac_config.dirty_rx])) !=
|
||||
cur_rx_desc) {
|
||||
|
||||
while (((uint32_t) & (emac_config.dma_erx[emac_config.dirty_rx].basic.desc0) != cur_rx_desc) && emac_config.cnt_rx < DMA_RX_BUF_NUM ) {
|
||||
while (((uint32_t)(emac_dma_rx_chain_buf[emac_config.dirty_rx]) != cur_rx_desc) &&
|
||||
emac_config.cnt_rx < DMA_RX_BUF_NUM) {
|
||||
emac_config.cnt_rx++;
|
||||
if (emac_config.cnt_rx > DMA_RX_BUF_NUM ) {
|
||||
if (emac_config.cnt_rx > DMA_RX_BUF_NUM) {
|
||||
ESP_LOGE(TAG, "emac rx buf err!!\n");
|
||||
}
|
||||
uint32_t tmp_dirty = emac_config.dirty_rx;
|
||||
emac_config.dirty_rx = (emac_config.dirty_rx + 1) % DMA_RX_BUF_NUM;
|
||||
|
||||
|
||||
//copy data to lwip
|
||||
emac_config.emac_tcpip_input((void *)(emac_config.dma_erx[tmp_dirty].basic.desc2),
|
||||
(((emac_config.dma_erx[tmp_dirty].basic.desc0) >> EMAC_DESC_FRAME_LENGTH_S) & EMAC_DESC_FRAME_LENGTH) , NULL);
|
||||
emac_config.emac_tcpip_input((emac_dma_rx_buf[tmp_dirty]),
|
||||
(((emac_dma_rx_chain_buf[tmp_dirty]->basic.desc0) >>
|
||||
EMAC_DESC_FRAME_LENGTH_S) &
|
||||
EMAC_DESC_FRAME_LENGTH),
|
||||
NULL);
|
||||
|
||||
cur_rx_desc = emac_read_rx_cur_reg();
|
||||
}
|
||||
} else {
|
||||
if (emac_config.cnt_rx < DMA_RX_BUF_NUM) {
|
||||
if ((emac_config.dma_erx[emac_config.dirty_rx].basic.desc0 & EMAC_DESC_RX_OWN) == 0) {
|
||||
if ((emac_dma_rx_chain_buf[emac_config.dirty_rx]->basic.desc0 &
|
||||
EMAC_DESC_RX_OWN) == 0) {
|
||||
while (emac_config.cnt_rx < DMA_RX_BUF_NUM) {
|
||||
|
||||
if (emac_config.dma_erx[emac_config.dirty_rx].basic.desc0 == EMAC_DESC_RX_OWN) {
|
||||
if (emac_dma_rx_chain_buf[emac_config.dirty_rx]->basic.desc0 == EMAC_DESC_RX_OWN) {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -543,18 +579,21 @@ static void emac_process_rx(void)
|
||||
ESP_LOGE(TAG, "emac rx buf err!!!\n");
|
||||
}
|
||||
uint32_t tmp_dirty = emac_config.dirty_rx;
|
||||
emac_config.dirty_rx = (emac_config.dirty_rx + 1) % DMA_RX_BUF_NUM;
|
||||
emac_config.dirty_rx = (emac_config.dirty_rx + 1) %
|
||||
DMA_RX_BUF_NUM;
|
||||
|
||||
//copy data to lwip
|
||||
emac_config.emac_tcpip_input((void *)(emac_config.dma_erx[tmp_dirty].basic.desc2),
|
||||
(((emac_config.dma_erx[tmp_dirty].basic.desc0) >> EMAC_DESC_FRAME_LENGTH_S) & EMAC_DESC_FRAME_LENGTH) , NULL);
|
||||
|
||||
}
|
||||
emac_config.emac_tcpip_input((emac_dma_rx_buf[tmp_dirty]),
|
||||
(((emac_dma_rx_chain_buf[tmp_dirty]->basic.desc0) >>
|
||||
EMAC_DESC_FRAME_LENGTH_S) &
|
||||
EMAC_DESC_FRAME_LENGTH),
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
emac_enable_rx_intr();
|
||||
xSemaphoreGiveRecursive( emac_rx_xMutex );
|
||||
xSemaphoreGiveRecursive(emac_rx_xMutex);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -570,7 +609,8 @@ static void IRAM_ATTR emac_process_intr(void *arg)
|
||||
if (event & EMAC_RECV_INT) {
|
||||
emac_disable_rx_intr();
|
||||
if (emac_config.emac_flow_ctrl_partner_support == true) {
|
||||
if (emac_get_rxbuf_count_in_intr() < FLOW_CONTROL_HIGH_WATERMARK && pause_send == false ) {
|
||||
if (emac_get_rxbuf_count_in_intr() < FLOW_CONTROL_HIGH_WATERMARK &&
|
||||
pause_send == false) {
|
||||
pause_send = true;
|
||||
emac_send_pause_frame_enable();
|
||||
}
|
||||
@@ -591,7 +631,9 @@ static void IRAM_ATTR emac_process_intr(void *arg)
|
||||
static void emac_set_macaddr_reg(void)
|
||||
{
|
||||
REG_SET_FIELD(EMAC_ADDR0HIGH_REG, EMAC_ADDRESS0_HI, (emac_config.macaddr[0] << 8) | (emac_config.macaddr[1]));
|
||||
REG_WRITE(EMAC_ADDR0LOW_REG, (emac_config.macaddr[2] << 24) | (emac_config.macaddr[3] << 16) | (emac_config.macaddr[4] << 8) | (emac_config.macaddr[5]));
|
||||
REG_WRITE(EMAC_ADDR0LOW_REG, (emac_config.macaddr[2] << 24) |
|
||||
(emac_config.macaddr[3] << 16) | (emac_config.macaddr[4] << 8) |
|
||||
(emac_config.macaddr[5]));
|
||||
}
|
||||
|
||||
static void emac_check_phy_init(void)
|
||||
@@ -612,7 +654,8 @@ static void emac_check_phy_init(void)
|
||||
emac_config.emac_flow_ctrl_partner_support = false;
|
||||
#else
|
||||
if (emac_config.emac_flow_ctrl_enable == true) {
|
||||
if (emac_config.emac_phy_get_partner_pause_enable() == true && emac_config.emac_phy_get_duplex_mode() == ETH_MODE_FULLDUPLEX) {
|
||||
if (emac_config.emac_phy_get_partner_pause_enable() == true &&
|
||||
emac_config.emac_phy_get_duplex_mode() == ETH_MODE_FULLDUPLEX) {
|
||||
emac_enable_flowctrl();
|
||||
emac_config.emac_flow_ctrl_partner_support = true;
|
||||
} else {
|
||||
@@ -635,7 +678,7 @@ static void emac_process_link_updown(bool link_status)
|
||||
|
||||
if (link_status == true) {
|
||||
emac_check_phy_init();
|
||||
ESP_LOGI(TAG, "eth link_up!!!");
|
||||
ESP_LOGD(TAG, "eth link_up");
|
||||
emac_enable_dma_tx();
|
||||
emac_enable_dma_rx();
|
||||
for (i = 0; i < PHY_LINK_CHECK_NUM; i++) {
|
||||
@@ -644,7 +687,7 @@ static void emac_process_link_updown(bool link_status)
|
||||
|
||||
evt.event_id = SYSTEM_EVENT_ETH_CONNECTED;
|
||||
} else {
|
||||
ESP_LOGI(TAG, "eth link_down!!!");
|
||||
ESP_LOGD(TAG, "eth link_down");
|
||||
emac_disable_dma_tx();
|
||||
emac_disable_dma_rx();
|
||||
evt.event_id = SYSTEM_EVENT_ETH_DISCONNECTED;
|
||||
@@ -667,31 +710,32 @@ esp_err_t esp_eth_tx(uint8_t *buf, uint16_t size)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
|
||||
if (emac_config.emac_status != EMAC_RUNTIME_START || emac_config.emac_status == EMAC_RUNTIME_NOT_INIT) {
|
||||
ESP_LOGI(TAG, "tx netif close");
|
||||
if (emac_config.emac_status != EMAC_RUNTIME_START) {
|
||||
ESP_LOGE(TAG, "tx netif is not ready, emac_status=%d",
|
||||
emac_config.emac_status);
|
||||
ret = ERR_IF;
|
||||
return ret;
|
||||
}
|
||||
|
||||
xSemaphoreTakeRecursive( emac_tx_xMutex, ( TickType_t ) portMAX_DELAY );
|
||||
xSemaphoreTakeRecursive(emac_tx_xMutex, portMAX_DELAY);
|
||||
if (emac_config.cnt_tx == DMA_TX_BUF_NUM - 1) {
|
||||
ESP_LOGD(TAG, "tx buf full");
|
||||
ret = ERR_MEM;
|
||||
goto _exit;
|
||||
}
|
||||
|
||||
memcpy((uint8_t *)(emac_config.dma_etx[emac_config.cur_tx].basic.desc2), (uint8_t *)buf, size);
|
||||
memcpy(emac_dma_tx_buf[emac_config.cur_tx], buf, size);
|
||||
|
||||
emac_setup_tx_desc(&(emac_config.dma_etx[emac_config.cur_tx]), size);
|
||||
emac_setup_tx_desc(emac_dma_tx_chain_buf[emac_config.cur_tx], size);
|
||||
|
||||
emac_config.cnt_tx ++;
|
||||
emac_config.cur_tx = (emac_config.cur_tx + 1) % DMA_TX_BUF_NUM ;
|
||||
emac_config.cnt_tx++;
|
||||
emac_config.cur_tx = (emac_config.cur_tx + 1) % DMA_TX_BUF_NUM;
|
||||
|
||||
emac_poll_tx_cmd();
|
||||
|
||||
_exit:
|
||||
|
||||
xSemaphoreGiveRecursive( emac_tx_xMutex );
|
||||
xSemaphoreGiveRecursive(emac_tx_xMutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -702,17 +746,16 @@ static void emac_init_default_data(void)
|
||||
|
||||
void emac_process_link_check(void)
|
||||
{
|
||||
if (emac_config.emac_status != EMAC_RUNTIME_START ||
|
||||
emac_config.emac_status == EMAC_RUNTIME_NOT_INIT) {
|
||||
if (emac_config.emac_status != EMAC_RUNTIME_START) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (emac_config.emac_phy_check_link() == true ) {
|
||||
if (emac_config.phy_link_up == false) {
|
||||
if (emac_config.emac_phy_check_link()) {
|
||||
if (!emac_config.phy_link_up) {
|
||||
emac_process_link_updown(true);
|
||||
}
|
||||
} else {
|
||||
if (emac_config.phy_link_up == true) {
|
||||
if (emac_config.phy_link_up) {
|
||||
emac_process_link_updown(false);
|
||||
}
|
||||
}
|
||||
@@ -725,8 +768,12 @@ void emac_link_check_func(void *pv_parameters)
|
||||
|
||||
static bool emac_link_check_timer_init(void)
|
||||
{
|
||||
emac_timer = xTimerCreate("emac_timer", (2000 / portTICK_PERIOD_MS),
|
||||
pdTRUE, (void *)rand(), emac_link_check_func);
|
||||
emac_timer = xTimerCreate("emac_timer",
|
||||
(CONFIG_EMAC_CHECK_LINK_PERIOD_MS /
|
||||
portTICK_PERIOD_MS),
|
||||
pdTRUE,
|
||||
NULL,
|
||||
emac_link_check_func);
|
||||
if (emac_timer == NULL) {
|
||||
return false;
|
||||
} else {
|
||||
@@ -761,10 +808,10 @@ static bool emac_link_check_timer_delete(void)
|
||||
|
||||
static void emac_start(void *param)
|
||||
{
|
||||
struct emac_post_cmd *post_cmd = (struct emac_post_cmd *)param;
|
||||
struct emac_post_cmd *post_cmd = (struct emac_post_cmd *)param;
|
||||
struct emac_open_cmd *cmd = (struct emac_open_cmd *)(post_cmd->cmd);
|
||||
|
||||
ESP_LOGI(TAG , "emac start !!!\n");
|
||||
ESP_LOGD(TAG, "emac start");
|
||||
cmd->err = EMAC_CMD_OK;
|
||||
emac_enable_clk(true);
|
||||
|
||||
@@ -803,7 +850,7 @@ static void emac_start(void *param)
|
||||
xSemaphoreGive(emac_g_sem);
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "emac start success !!!");
|
||||
ESP_LOGD(TAG, "emac start success");
|
||||
}
|
||||
|
||||
esp_err_t esp_eth_enable(void)
|
||||
@@ -849,8 +896,8 @@ cleanup:
|
||||
|
||||
static void emac_stop(void *param)
|
||||
{
|
||||
struct emac_post_cmd *post_cmd = (struct emac_post_cmd *)param;
|
||||
ESP_LOGI(TAG, "emac stop");
|
||||
struct emac_post_cmd *post_cmd = (struct emac_post_cmd *)param;
|
||||
ESP_LOGD(TAG, "emac stop");
|
||||
|
||||
emac_link_check_timer_stop();
|
||||
emac_link_check_timer_delete();
|
||||
@@ -871,7 +918,7 @@ static void emac_stop(void *param)
|
||||
xSemaphoreGive(emac_g_sem);
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "emac stop success !!!");
|
||||
ESP_LOGD(TAG, "emac stop success");
|
||||
}
|
||||
|
||||
esp_err_t esp_eth_disable(void)
|
||||
@@ -906,7 +953,7 @@ esp_err_t esp_eth_disable(void)
|
||||
static esp_err_t emac_ioctl(emac_sig_t sig, emac_par_t par)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
struct emac_post_cmd *post_cmd = (struct emac_post_cmd *)par;
|
||||
struct emac_post_cmd *post_cmd = (struct emac_post_cmd *)par;
|
||||
xTaskHandle task_hdl = xTaskGetCurrentTaskHandle();
|
||||
|
||||
if (emac_task_hdl != task_hdl) {
|
||||
@@ -948,7 +995,7 @@ void emac_task(void *pv)
|
||||
emac_event_t e;
|
||||
|
||||
for (;;) {
|
||||
if (xQueueReceive(emac_xqueue, &e, (portTickType)portMAX_DELAY) == pdTRUE) {
|
||||
if (xQueueReceive(emac_xqueue, &e, portMAX_DELAY) == pdTRUE) {
|
||||
portENTER_CRITICAL(&g_emac_mux);
|
||||
emac_sig_cnt[e.sig]--;
|
||||
portEXIT_CRITICAL(&g_emac_mux);
|
||||
@@ -1020,8 +1067,18 @@ esp_err_t IRAM_ATTR emac_post(emac_sig_t sig, emac_par_t par)
|
||||
|
||||
esp_err_t esp_eth_init(eth_config_t *config)
|
||||
{
|
||||
esp_event_set_default_eth_handlers();
|
||||
return esp_eth_init_internal(config);
|
||||
/* dynamically alloc memory for ethernet dma */
|
||||
for (int i = 0; i < DMA_RX_BUF_NUM; i++) {
|
||||
emac_dma_rx_chain_buf[i] = (struct dma_extended_desc *)heap_caps_malloc(sizeof(struct dma_extended_desc), MALLOC_CAP_DMA);
|
||||
emac_dma_rx_buf[i] = (uint8_t *)heap_caps_malloc(DMA_RX_BUF_SIZE, MALLOC_CAP_DMA);
|
||||
}
|
||||
for (int i = 0; i < DMA_TX_BUF_NUM; i++) {
|
||||
emac_dma_tx_chain_buf[i] = (struct dma_extended_desc *)heap_caps_malloc(sizeof(struct dma_extended_desc), MALLOC_CAP_DMA);
|
||||
emac_dma_tx_buf[i] = (uint8_t *)heap_caps_malloc(DMA_TX_BUF_SIZE, MALLOC_CAP_DMA);
|
||||
}
|
||||
|
||||
esp_event_set_default_eth_handlers();
|
||||
return esp_eth_init_internal(config);
|
||||
}
|
||||
|
||||
esp_err_t esp_eth_init_internal(eth_config_t *config)
|
||||
@@ -1033,7 +1090,7 @@ esp_err_t esp_eth_init_internal(eth_config_t *config)
|
||||
|
||||
emac_init_default_data();
|
||||
|
||||
if (config != NULL ) {
|
||||
if (config != NULL) {
|
||||
emac_set_user_config_data(config);
|
||||
}
|
||||
|
||||
@@ -1051,31 +1108,28 @@ esp_err_t esp_eth_init_internal(eth_config_t *config)
|
||||
if (emac_config.clock_mode != ETH_CLOCK_GPIO0_IN) {
|
||||
// 50 MHz = 40MHz * (6 + 4) / (2 * (2 + 2) = 400MHz / 8
|
||||
rtc_clk_apll_enable(1, 0, 0, 6, 2);
|
||||
// the next to values have to be set AFTER "periph_module_enable" is called
|
||||
REG_SET_FIELD(EMAC_EX_CLKOUT_CONF_REG, EMAC_EX_CLK_OUT_H_DIV_NUM, 0);
|
||||
REG_SET_FIELD(EMAC_EX_CLKOUT_CONF_REG, EMAC_EX_CLK_OUT_DIV_NUM, 0);
|
||||
|
||||
if (emac_config.clock_mode == ETH_CLOCK_GPIO0_OUT) {
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO0_U, FUNC_GPIO0_CLK_OUT1);
|
||||
REG_WRITE(PIN_CTRL, 6);
|
||||
ESP_LOGD(TAG, "EMAC 50MHz clock output on GPIO0");
|
||||
} else if (emac_config.clock_mode == ETH_CLOCK_GPIO16_OUT) {
|
||||
if (emac_config.clock_mode == ETH_CLOCK_GPIO16_OUT) {
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO16_U, FUNC_GPIO16_EMAC_CLK_OUT);
|
||||
ESP_LOGD(TAG, "EMAC 50MHz clock output on GPIO16");
|
||||
} else if (emac_config.clock_mode == ETH_CLOCK_GPIO17_OUT) {
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO17_U, FUNC_GPIO17_EMAC_CLK_OUT_180);
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO17_U,
|
||||
FUNC_GPIO17_EMAC_CLK_OUT_180);
|
||||
ESP_LOGD(TAG, "EMAC 50MHz inverted clock output on GPIO17");
|
||||
}
|
||||
}
|
||||
|
||||
emac_enable_clk(true);
|
||||
REG_SET_FIELD(EMAC_EX_PHYINF_CONF_REG, EMAC_EX_PHY_INTF_SEL, EMAC_EX_PHY_INTF_RMII);
|
||||
REG_SET_FIELD(EMAC_EX_PHYINF_CONF_REG, EMAC_EX_PHY_INTF_SEL,
|
||||
EMAC_EX_PHY_INTF_RMII);
|
||||
emac_dma_init();
|
||||
|
||||
if (emac_config.clock_mode == ETH_CLOCK_GPIO0_IN) {
|
||||
// external clock on GPIO0
|
||||
REG_SET_BIT(EMAC_EX_CLK_CTRL_REG, EMAC_EX_EXT_OSC_EN);
|
||||
REG_CLR_BIT(EMAC_EX_CLK_CTRL_REG, EMAC_EX_INT_OSC_EN);
|
||||
REG_SET_BIT(EMAC_EX_CLK_CTRL_REG, EMAC_EX_EXT_OSC_EN);
|
||||
REG_CLR_BIT(EMAC_EX_CLK_CTRL_REG, EMAC_EX_INT_OSC_EN);
|
||||
REG_SET_BIT(EMAC_EX_OSCCLK_CONF_REG, EMAC_EX_OSC_CLK_SEL);
|
||||
ESP_LOGD(TAG, "External clock input 50MHz on GPIO0");
|
||||
if (emac_config.mac_mode == ETH_MODE_MII) {
|
||||
@@ -1084,8 +1138,8 @@ esp_err_t esp_eth_init_internal(eth_config_t *config)
|
||||
}
|
||||
} else {
|
||||
// internal clock by APLL
|
||||
REG_CLR_BIT(EMAC_EX_CLK_CTRL_REG, EMAC_EX_EXT_OSC_EN);
|
||||
REG_SET_BIT(EMAC_EX_CLK_CTRL_REG, EMAC_EX_INT_OSC_EN);
|
||||
REG_CLR_BIT(EMAC_EX_CLK_CTRL_REG, EMAC_EX_EXT_OSC_EN);
|
||||
REG_SET_BIT(EMAC_EX_CLK_CTRL_REG, EMAC_EX_INT_OSC_EN);
|
||||
REG_CLR_BIT(EMAC_EX_OSCCLK_CONF_REG, EMAC_EX_OSC_CLK_SEL);
|
||||
}
|
||||
|
||||
@@ -1101,7 +1155,8 @@ esp_err_t esp_eth_init_internal(eth_config_t *config)
|
||||
emac_rx_xMutex = xSemaphoreCreateRecursiveMutex();
|
||||
emac_tx_xMutex = xSemaphoreCreateRecursiveMutex();
|
||||
emac_xqueue = xQueueCreate(EMAC_EVT_QNUM, sizeof(emac_event_t));
|
||||
xTaskCreate(emac_task, "emacT", 2048, NULL, EMAC_TASK_PRIORITY, &emac_task_hdl);
|
||||
xTaskCreate(emac_task, "emacT", 2048, NULL, EMAC_TASK_PRIORITY,
|
||||
&emac_task_hdl);
|
||||
|
||||
emac_enable_clk(false);
|
||||
esp_intr_alloc(ETS_ETH_MAC_INTR_SOURCE, 0, emac_process_intr, NULL, NULL);
|
||||
@@ -1111,3 +1166,43 @@ esp_err_t esp_eth_init_internal(eth_config_t *config)
|
||||
_exit:
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t esp_eth_deinit(void)
|
||||
{
|
||||
esp_err_t ret = ESP_FAIL;
|
||||
|
||||
if (!emac_task_hdl) {
|
||||
ret = ESP_ERR_INVALID_STATE;
|
||||
goto _exit;
|
||||
}
|
||||
|
||||
vTaskDelete(emac_task_hdl);
|
||||
emac_task_hdl = NULL;
|
||||
|
||||
vQueueDelete(emac_xqueue);
|
||||
vSemaphoreDelete(emac_tx_xMutex);
|
||||
vSemaphoreDelete(emac_rx_xMutex);
|
||||
vSemaphoreDelete(emac_g_sem);
|
||||
emac_reset_dma_chain();
|
||||
emac_config.emac_phy_power_enable(false);
|
||||
periph_module_disable(PERIPH_EMAC_MODULE);
|
||||
emac_config.emac_status = EMAC_RUNTIME_NOT_INIT;
|
||||
|
||||
/* free memory that dynamically allocted */
|
||||
for (int i = 0; i < DMA_RX_BUF_NUM; i++) {
|
||||
free(emac_dma_rx_chain_buf[i]);
|
||||
free(emac_dma_rx_buf[i]);
|
||||
emac_dma_rx_chain_buf[i] = NULL;
|
||||
emac_dma_rx_buf[i] = NULL;
|
||||
}
|
||||
for (int i = 0; i < DMA_TX_BUF_NUM; i++) {
|
||||
free(emac_dma_tx_chain_buf[i]);
|
||||
free(emac_dma_tx_buf[i]);
|
||||
emac_dma_tx_chain_buf[i] = NULL;
|
||||
emac_dma_tx_buf[i] = NULL;
|
||||
}
|
||||
ret = ESP_OK;
|
||||
|
||||
_exit:
|
||||
return ret;
|
||||
}
|
||||
|
Reference in New Issue
Block a user