Merge branch 'bugfix/stop_mac_can_be_controlled_by_user' into 'master'
ethernet: esp_eth_stop API should stop emac hardware Closes WIFI-2247 and WIFI-2337 See merge request espressif/esp-idf!8664
This commit is contained in:
commit
5e436be77f
8 changed files with 111 additions and 30 deletions
|
@ -73,6 +73,30 @@ struct esp_eth_mac_s {
|
||||||
*/
|
*/
|
||||||
esp_err_t (*deinit)(esp_eth_mac_t *mac);
|
esp_err_t (*deinit)(esp_eth_mac_t *mac);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Start Ethernet MAC
|
||||||
|
*
|
||||||
|
* @param[in] mac: Ethernet MAC instance
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* - ESP_OK: start Ethernet MAC successfully
|
||||||
|
* - ESP_FAIL: start Ethernet MAC failed because some other error occurred
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
esp_err_t (*start)(esp_eth_mac_t *mac);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Stop Ethernet MAC
|
||||||
|
*
|
||||||
|
* @param[in] mac: Ethernet MAC instance
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* - ESP_OK: stop Ethernet MAC successfully
|
||||||
|
* - ESP_FAIL: stop Ethernet MAC failed because some error occurred
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
esp_err_t (*stop)(esp_eth_mac_t *mac);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Transmit packet from Ethernet MAC
|
* @brief Transmit packet from Ethernet MAC
|
||||||
*
|
*
|
||||||
|
|
|
@ -34,7 +34,10 @@ static const char *TAG = "esp_eth";
|
||||||
|
|
||||||
ESP_EVENT_DEFINE_BASE(ETH_EVENT);
|
ESP_EVENT_DEFINE_BASE(ETH_EVENT);
|
||||||
|
|
||||||
#define ESP_ETH_FLAGS_STARTED (1<<0)
|
typedef enum {
|
||||||
|
ESP_ETH_FSM_STOP,
|
||||||
|
ESP_ETH_FSM_START
|
||||||
|
} esp_eth_fsm_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The Ethernet driver mainly consists of PHY, MAC and
|
* @brief The Ethernet driver mainly consists of PHY, MAC and
|
||||||
|
@ -56,7 +59,7 @@ typedef struct {
|
||||||
eth_link_t link;
|
eth_link_t link;
|
||||||
atomic_int ref_count;
|
atomic_int ref_count;
|
||||||
void *priv;
|
void *priv;
|
||||||
uint32_t flags;
|
_Atomic esp_eth_fsm_t fsm;
|
||||||
esp_err_t (*stack_input)(esp_eth_handle_t eth_handle, uint8_t *buffer, uint32_t length, void *priv);
|
esp_err_t (*stack_input)(esp_eth_handle_t eth_handle, uint8_t *buffer, uint32_t length, void *priv);
|
||||||
esp_err_t (*on_lowlevel_init_done)(esp_eth_handle_t eth_handle);
|
esp_err_t (*on_lowlevel_init_done)(esp_eth_handle_t eth_handle);
|
||||||
esp_err_t (*on_lowlevel_deinit_done)(esp_eth_handle_t eth_handle);
|
esp_err_t (*on_lowlevel_deinit_done)(esp_eth_handle_t eth_handle);
|
||||||
|
@ -175,6 +178,7 @@ esp_err_t esp_eth_driver_install(const esp_eth_config_t *config, esp_eth_handle_
|
||||||
esp_eth_driver_t *eth_driver = heap_caps_calloc(1, sizeof(esp_eth_driver_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
|
esp_eth_driver_t *eth_driver = heap_caps_calloc(1, sizeof(esp_eth_driver_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
|
||||||
ETH_CHECK(eth_driver, "request memory for eth_driver failed", err, ESP_ERR_NO_MEM);
|
ETH_CHECK(eth_driver, "request memory for eth_driver failed", err, ESP_ERR_NO_MEM);
|
||||||
atomic_init(ð_driver->ref_count, 1);
|
atomic_init(ð_driver->ref_count, 1);
|
||||||
|
atomic_init(ð_driver->fsm, ESP_ETH_FSM_STOP);
|
||||||
eth_driver->mac = mac;
|
eth_driver->mac = mac;
|
||||||
eth_driver->phy = phy;
|
eth_driver->phy = phy;
|
||||||
eth_driver->link = ETH_LINK_DOWN;
|
eth_driver->link = ETH_LINK_DOWN;
|
||||||
|
@ -221,9 +225,20 @@ esp_err_t esp_eth_driver_uninstall(esp_eth_handle_t hdl)
|
||||||
esp_err_t ret = ESP_OK;
|
esp_err_t ret = ESP_OK;
|
||||||
esp_eth_driver_t *eth_driver = (esp_eth_driver_t *)hdl;
|
esp_eth_driver_t *eth_driver = (esp_eth_driver_t *)hdl;
|
||||||
ETH_CHECK(eth_driver, "ethernet driver handle can't be null", err, ESP_ERR_INVALID_ARG);
|
ETH_CHECK(eth_driver, "ethernet driver handle can't be null", err, ESP_ERR_INVALID_ARG);
|
||||||
|
// check if driver has started
|
||||||
|
esp_eth_fsm_t expected_fsm = ESP_ETH_FSM_STOP;
|
||||||
|
if (!atomic_compare_exchange_strong(ð_driver->fsm, &expected_fsm, ESP_ETH_FSM_STOP)) {
|
||||||
|
ESP_LOGW(TAG, "driver not stopped yet");
|
||||||
|
ret = ESP_ERR_INVALID_STATE;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
// don't uninstall driver unless there's only one reference
|
// don't uninstall driver unless there's only one reference
|
||||||
ETH_CHECK(atomic_load(ð_driver->ref_count) == 1,
|
int expected_ref_count = 1;
|
||||||
"more than one reference to ethernet driver", err, ESP_ERR_INVALID_STATE);
|
if (!atomic_compare_exchange_strong(ð_driver->ref_count, &expected_ref_count, 0)) {
|
||||||
|
ESP_LOGE(TAG, "%d ethernet reference in use", expected_ref_count);
|
||||||
|
ret = ESP_ERR_INVALID_STATE;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
esp_eth_mac_t *mac = eth_driver->mac;
|
esp_eth_mac_t *mac = eth_driver->mac;
|
||||||
esp_eth_phy_t *phy = eth_driver->phy;
|
esp_eth_phy_t *phy = eth_driver->phy;
|
||||||
ETH_CHECK(xTimerDelete(eth_driver->check_link_timer, 0) == pdPASS, "delete eth_link_timer failed", err, ESP_FAIL);
|
ETH_CHECK(xTimerDelete(eth_driver->check_link_timer, 0) == pdPASS, "delete eth_link_timer failed", err, ESP_FAIL);
|
||||||
|
@ -241,12 +256,12 @@ esp_err_t esp_eth_start(esp_eth_handle_t hdl)
|
||||||
esp_eth_driver_t *eth_driver = (esp_eth_driver_t *)hdl;
|
esp_eth_driver_t *eth_driver = (esp_eth_driver_t *)hdl;
|
||||||
ETH_CHECK(eth_driver, "ethernet driver handle can't be null", err, ESP_ERR_INVALID_ARG);
|
ETH_CHECK(eth_driver, "ethernet driver handle can't be null", err, ESP_ERR_INVALID_ARG);
|
||||||
// check if driver has started
|
// check if driver has started
|
||||||
if (eth_driver->flags & ESP_ETH_FLAGS_STARTED) {
|
esp_eth_fsm_t expected_fsm = ESP_ETH_FSM_STOP;
|
||||||
|
if (!atomic_compare_exchange_strong(ð_driver->fsm, &expected_fsm, ESP_ETH_FSM_START)) {
|
||||||
ESP_LOGW(TAG, "driver started already");
|
ESP_LOGW(TAG, "driver started already");
|
||||||
ret = ESP_ERR_INVALID_STATE;
|
ret = ESP_ERR_INVALID_STATE;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
eth_driver->flags |= ESP_ETH_FLAGS_STARTED;
|
|
||||||
ETH_CHECK(eth_driver->phy->reset(eth_driver->phy) == ESP_OK, "reset phy failed", err, ESP_FAIL);
|
ETH_CHECK(eth_driver->phy->reset(eth_driver->phy) == ESP_OK, "reset phy failed", err, ESP_FAIL);
|
||||||
ETH_CHECK(xTimerStart(eth_driver->check_link_timer, 0) == pdPASS,
|
ETH_CHECK(xTimerStart(eth_driver->check_link_timer, 0) == pdPASS,
|
||||||
"start eth_link_timer failed", err, ESP_FAIL);
|
"start eth_link_timer failed", err, ESP_FAIL);
|
||||||
|
@ -265,17 +280,18 @@ esp_err_t esp_eth_stop(esp_eth_handle_t hdl)
|
||||||
esp_eth_driver_t *eth_driver = (esp_eth_driver_t *)hdl;
|
esp_eth_driver_t *eth_driver = (esp_eth_driver_t *)hdl;
|
||||||
ETH_CHECK(eth_driver, "ethernet driver handle can't be null", err, ESP_ERR_INVALID_ARG);
|
ETH_CHECK(eth_driver, "ethernet driver handle can't be null", err, ESP_ERR_INVALID_ARG);
|
||||||
// check if driver has started
|
// check if driver has started
|
||||||
if (eth_driver->flags & ESP_ETH_FLAGS_STARTED) {
|
esp_eth_fsm_t expected_fsm = ESP_ETH_FSM_START;
|
||||||
eth_driver->flags &= ~ESP_ETH_FLAGS_STARTED;
|
if (!atomic_compare_exchange_strong(ð_driver->fsm, &expected_fsm, ESP_ETH_FSM_STOP)) {
|
||||||
ETH_CHECK(xTimerStop(eth_driver->check_link_timer, 0) == pdPASS,
|
|
||||||
"stop eth_link_timer failed", err, ESP_FAIL);
|
|
||||||
ETH_CHECK(esp_event_post(ETH_EVENT, ETHERNET_EVENT_STOP, ð_driver, sizeof(eth_driver), 0) == ESP_OK,
|
|
||||||
"send ETHERNET_EVENT_STOP event failed", err, ESP_FAIL);
|
|
||||||
} else {
|
|
||||||
ESP_LOGW(TAG, "driver not started yet");
|
ESP_LOGW(TAG, "driver not started yet");
|
||||||
ret = ESP_ERR_INVALID_STATE;
|
ret = ESP_ERR_INVALID_STATE;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
esp_eth_mac_t *mac = eth_driver->mac;
|
||||||
|
ETH_CHECK(mac->stop(mac) == ESP_OK, "stop mac failed", err, ESP_FAIL);
|
||||||
|
ETH_CHECK(xTimerStop(eth_driver->check_link_timer, 0) == pdPASS,
|
||||||
|
"stop eth_link_timer failed", err, ESP_FAIL);
|
||||||
|
ETH_CHECK(esp_event_post(ETH_EVENT, ETHERNET_EVENT_STOP, ð_driver, sizeof(eth_driver), 0) == ESP_OK,
|
||||||
|
"send ETHERNET_EVENT_STOP event failed", err, ESP_FAIL);
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
err:
|
err:
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -337,9 +337,10 @@ err:
|
||||||
/**
|
/**
|
||||||
* @brief start dm9051: enable interrupt and start receive
|
* @brief start dm9051: enable interrupt and start receive
|
||||||
*/
|
*/
|
||||||
static esp_err_t dm9051_start(emac_dm9051_t *emac)
|
static esp_err_t emac_dm9051_start(esp_eth_mac_t *mac)
|
||||||
{
|
{
|
||||||
esp_err_t ret = ESP_OK;
|
esp_err_t ret = ESP_OK;
|
||||||
|
emac_dm9051_t *emac = __containerof(mac, emac_dm9051_t, parent);
|
||||||
/* enable interrupt */
|
/* enable interrupt */
|
||||||
MAC_CHECK(dm9051_register_write(emac, DM9051_IMR, IMR_ALL) == ESP_OK, "write IMR failed", err, ESP_FAIL);
|
MAC_CHECK(dm9051_register_write(emac, DM9051_IMR, IMR_ALL) == ESP_OK, "write IMR failed", err, ESP_FAIL);
|
||||||
/* enable rx */
|
/* enable rx */
|
||||||
|
@ -355,9 +356,10 @@ err:
|
||||||
/**
|
/**
|
||||||
* @brief stop dm9051: disable interrupt and stop receive
|
* @brief stop dm9051: disable interrupt and stop receive
|
||||||
*/
|
*/
|
||||||
static esp_err_t dm9051_stop(emac_dm9051_t *emac)
|
static esp_err_t emac_dm9051_stop(esp_eth_mac_t *mac)
|
||||||
{
|
{
|
||||||
esp_err_t ret = ESP_OK;
|
esp_err_t ret = ESP_OK;
|
||||||
|
emac_dm9051_t *emac = __containerof(mac, emac_dm9051_t, parent);
|
||||||
/* disable interrupt */
|
/* disable interrupt */
|
||||||
MAC_CHECK(dm9051_register_write(emac, DM9051_IMR, 0x00) == ESP_OK, "write IMR failed", err, ESP_FAIL);
|
MAC_CHECK(dm9051_register_write(emac, DM9051_IMR, 0x00) == ESP_OK, "write IMR failed", err, ESP_FAIL);
|
||||||
/* disable rx */
|
/* disable rx */
|
||||||
|
@ -519,11 +521,11 @@ static esp_err_t emac_dm9051_set_link(esp_eth_mac_t *mac, eth_link_t link)
|
||||||
switch (link) {
|
switch (link) {
|
||||||
case ETH_LINK_UP:
|
case ETH_LINK_UP:
|
||||||
MAC_CHECK(nsr & NSR_LINKST, "phy is not link up", err, ESP_ERR_INVALID_STATE);
|
MAC_CHECK(nsr & NSR_LINKST, "phy is not link up", err, ESP_ERR_INVALID_STATE);
|
||||||
MAC_CHECK(dm9051_start(emac) == ESP_OK, "dm9051 start failed", err, ESP_FAIL);
|
MAC_CHECK(mac->start(mac) == ESP_OK, "dm9051 start failed", err, ESP_FAIL);
|
||||||
break;
|
break;
|
||||||
case ETH_LINK_DOWN:
|
case ETH_LINK_DOWN:
|
||||||
MAC_CHECK(!(nsr & NSR_LINKST), "phy is not link down", err, ESP_ERR_INVALID_STATE);
|
MAC_CHECK(!(nsr & NSR_LINKST), "phy is not link down", err, ESP_ERR_INVALID_STATE);
|
||||||
MAC_CHECK(dm9051_stop(emac) == ESP_OK, "dm9051 stop failed", err, ESP_FAIL);
|
MAC_CHECK(mac->stop(mac) == ESP_OK, "dm9051 stop failed", err, ESP_FAIL);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
MAC_CHECK(false, "unknown link status", err, ESP_ERR_INVALID_ARG);
|
MAC_CHECK(false, "unknown link status", err, ESP_ERR_INVALID_ARG);
|
||||||
|
@ -633,12 +635,12 @@ static esp_err_t emac_dm9051_receive(esp_eth_mac_t *mac, uint8_t *buf, uint32_t
|
||||||
MAC_CHECK(dm9051_register_read(emac, DM9051_MRCMDX, &rxbyte) == ESP_OK, "read MRCMDX failed", err, ESP_FAIL);
|
MAC_CHECK(dm9051_register_read(emac, DM9051_MRCMDX, &rxbyte) == ESP_OK, "read MRCMDX failed", err, ESP_FAIL);
|
||||||
/* rxbyte must be 0xFF, 0 or 1 */
|
/* rxbyte must be 0xFF, 0 or 1 */
|
||||||
if (rxbyte > 1) {
|
if (rxbyte > 1) {
|
||||||
MAC_CHECK(dm9051_stop(emac) == ESP_OK, "stop dm9051 failed", err, ESP_FAIL);
|
MAC_CHECK(mac->stop(mac) == ESP_OK, "stop dm9051 failed", err, ESP_FAIL);
|
||||||
/* reset rx fifo pointer */
|
/* reset rx fifo pointer */
|
||||||
MAC_CHECK(dm9051_register_write(emac, DM9051_MPTRCR, MPTRCR_RST_RX) == ESP_OK,
|
MAC_CHECK(dm9051_register_write(emac, DM9051_MPTRCR, MPTRCR_RST_RX) == ESP_OK,
|
||||||
"write MPTRCR failed", err, ESP_FAIL);
|
"write MPTRCR failed", err, ESP_FAIL);
|
||||||
ets_delay_us(10);
|
ets_delay_us(10);
|
||||||
MAC_CHECK(dm9051_start(emac) == ESP_OK, "start dm9051 failed", err, ESP_FAIL);
|
MAC_CHECK(mac->start(mac) == ESP_OK, "start dm9051 failed", err, ESP_FAIL);
|
||||||
MAC_CHECK(false, "reset rx fifo pointer", err, ESP_FAIL);
|
MAC_CHECK(false, "reset rx fifo pointer", err, ESP_FAIL);
|
||||||
} else if (rxbyte) {
|
} else if (rxbyte) {
|
||||||
MAC_CHECK(dm9051_memory_peek(emac, (uint8_t *)&header, sizeof(header)) == ESP_OK,
|
MAC_CHECK(dm9051_memory_peek(emac, (uint8_t *)&header, sizeof(header)) == ESP_OK,
|
||||||
|
@ -702,7 +704,7 @@ static esp_err_t emac_dm9051_deinit(esp_eth_mac_t *mac)
|
||||||
{
|
{
|
||||||
emac_dm9051_t *emac = __containerof(mac, emac_dm9051_t, parent);
|
emac_dm9051_t *emac = __containerof(mac, emac_dm9051_t, parent);
|
||||||
esp_eth_mediator_t *eth = emac->eth;
|
esp_eth_mediator_t *eth = emac->eth;
|
||||||
dm9051_stop(emac);
|
mac->stop(mac);
|
||||||
gpio_isr_handler_remove(emac->int_gpio_num);
|
gpio_isr_handler_remove(emac->int_gpio_num);
|
||||||
gpio_reset_pin(emac->int_gpio_num);
|
gpio_reset_pin(emac->int_gpio_num);
|
||||||
eth->on_state_changed(eth, ETH_STATE_DEINIT, NULL);
|
eth->on_state_changed(eth, ETH_STATE_DEINIT, NULL);
|
||||||
|
@ -735,6 +737,8 @@ esp_eth_mac_t *esp_eth_mac_new_dm9051(const eth_dm9051_config_t *dm9051_config,
|
||||||
emac->parent.set_mediator = emac_dm9051_set_mediator;
|
emac->parent.set_mediator = emac_dm9051_set_mediator;
|
||||||
emac->parent.init = emac_dm9051_init;
|
emac->parent.init = emac_dm9051_init;
|
||||||
emac->parent.deinit = emac_dm9051_deinit;
|
emac->parent.deinit = emac_dm9051_deinit;
|
||||||
|
emac->parent.start = emac_dm9051_start;
|
||||||
|
emac->parent.stop = emac_dm9051_stop;
|
||||||
emac->parent.del = emac_dm9051_del;
|
emac->parent.del = emac_dm9051_del;
|
||||||
emac->parent.write_phy_reg = emac_dm9051_write_phy_reg;
|
emac->parent.write_phy_reg = emac_dm9051_write_phy_reg;
|
||||||
emac->parent.read_phy_reg = emac_dm9051_read_phy_reg;
|
emac->parent.read_phy_reg = emac_dm9051_read_phy_reg;
|
||||||
|
|
|
@ -248,8 +248,8 @@ static void emac_esp32_rx_task(void *arg)
|
||||||
uint8_t *buffer = NULL;
|
uint8_t *buffer = NULL;
|
||||||
uint32_t length = 0;
|
uint32_t length = 0;
|
||||||
while (1) {
|
while (1) {
|
||||||
// block indefinitely until some task notifies me
|
// block indefinitely until got notification from underlay event
|
||||||
ulTaskNotifyTake(pdFALSE, portMAX_DELAY);
|
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
|
||||||
do {
|
do {
|
||||||
length = ETH_MAX_PACKET_SIZE;
|
length = ETH_MAX_PACKET_SIZE;
|
||||||
buffer = malloc(length);
|
buffer = malloc(length);
|
||||||
|
@ -340,6 +340,20 @@ static esp_err_t emac_esp32_deinit(esp_eth_mac_t *mac)
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static esp_err_t emac_esp32_start(esp_eth_mac_t *mac)
|
||||||
|
{
|
||||||
|
emac_esp32_t *emac = __containerof(mac, emac_esp32_t, parent);
|
||||||
|
emac_hal_start(&emac->hal);
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static esp_err_t emac_esp32_stop(esp_eth_mac_t *mac)
|
||||||
|
{
|
||||||
|
emac_esp32_t *emac = __containerof(mac, emac_esp32_t, parent);
|
||||||
|
emac_hal_stop(&emac->hal);
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
static esp_err_t emac_esp32_del(esp_eth_mac_t *mac)
|
static esp_err_t emac_esp32_del(esp_eth_mac_t *mac)
|
||||||
{
|
{
|
||||||
emac_esp32_t *emac = __containerof(mac, emac_esp32_t, parent);
|
emac_esp32_t *emac = __containerof(mac, emac_esp32_t, parent);
|
||||||
|
@ -414,6 +428,8 @@ esp_eth_mac_t *esp_eth_mac_new_esp32(const eth_mac_config_t *config)
|
||||||
emac->parent.set_mediator = emac_esp32_set_mediator;
|
emac->parent.set_mediator = emac_esp32_set_mediator;
|
||||||
emac->parent.init = emac_esp32_init;
|
emac->parent.init = emac_esp32_init;
|
||||||
emac->parent.deinit = emac_esp32_deinit;
|
emac->parent.deinit = emac_esp32_deinit;
|
||||||
|
emac->parent.start = emac_esp32_start;
|
||||||
|
emac->parent.stop = emac_esp32_stop;
|
||||||
emac->parent.del = emac_esp32_del;
|
emac->parent.del = emac_esp32_del;
|
||||||
emac->parent.write_phy_reg = emac_esp32_write_phy_reg;
|
emac->parent.write_phy_reg = emac_esp32_write_phy_reg;
|
||||||
emac->parent.read_phy_reg = emac_esp32_read_phy_reg;
|
emac->parent.read_phy_reg = emac_esp32_read_phy_reg;
|
||||||
|
|
|
@ -319,6 +319,18 @@ static esp_err_t emac_opencores_deinit(esp_eth_mac_t *mac)
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static esp_err_t emac_opencores_start(esp_eth_mac_t *mac)
|
||||||
|
{
|
||||||
|
openeth_enable();
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static esp_err_t emac_opencores_stop(esp_eth_mac_t *mac)
|
||||||
|
{
|
||||||
|
openeth_disable();
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
static esp_err_t emac_opencores_del(esp_eth_mac_t *mac)
|
static esp_err_t emac_opencores_del(esp_eth_mac_t *mac)
|
||||||
{
|
{
|
||||||
emac_opencores_t *emac = __containerof(mac, emac_opencores_t, parent);
|
emac_opencores_t *emac = __containerof(mac, emac_opencores_t, parent);
|
||||||
|
@ -366,6 +378,8 @@ esp_eth_mac_t *esp_eth_mac_new_openeth(const eth_mac_config_t *config)
|
||||||
emac->parent.set_mediator = emac_opencores_set_mediator;
|
emac->parent.set_mediator = emac_opencores_set_mediator;
|
||||||
emac->parent.init = emac_opencores_init;
|
emac->parent.init = emac_opencores_init;
|
||||||
emac->parent.deinit = emac_opencores_deinit;
|
emac->parent.deinit = emac_opencores_deinit;
|
||||||
|
emac->parent.start = emac_opencores_start;
|
||||||
|
emac->parent.stop = emac_opencores_stop;
|
||||||
emac->parent.del = emac_opencores_del;
|
emac->parent.del = emac_opencores_del;
|
||||||
emac->parent.write_phy_reg = emac_opencores_write_phy_reg;
|
emac->parent.write_phy_reg = emac_opencores_write_phy_reg;
|
||||||
emac->parent.read_phy_reg = emac_opencores_read_phy_reg;
|
emac->parent.read_phy_reg = emac_opencores_read_phy_reg;
|
||||||
|
|
|
@ -94,6 +94,11 @@ static esp_err_t dm9051_update_link_duplex_speed(phy_dm9051_t *dm9051)
|
||||||
eth_duplex_t duplex = ETH_DUPLEX_HALF;
|
eth_duplex_t duplex = ETH_DUPLEX_HALF;
|
||||||
bmsr_reg_t bmsr;
|
bmsr_reg_t bmsr;
|
||||||
dscsr_reg_t dscsr;
|
dscsr_reg_t dscsr;
|
||||||
|
// BMSR is a latch low register
|
||||||
|
// after power up, the first latched value must be 0, which means down
|
||||||
|
// to speed up power up link speed, double read this register as a workaround
|
||||||
|
PHY_CHECK(eth->phy_reg_read(eth, dm9051->addr, ETH_PHY_BMSR_REG_ADDR, &(bmsr.val)) == ESP_OK,
|
||||||
|
"read BMSR failed", err);
|
||||||
PHY_CHECK(eth->phy_reg_read(eth, dm9051->addr, ETH_PHY_BMSR_REG_ADDR, &(bmsr.val)) == ESP_OK,
|
PHY_CHECK(eth->phy_reg_read(eth, dm9051->addr, ETH_PHY_BMSR_REG_ADDR, &(bmsr.val)) == ESP_OK,
|
||||||
"read BMSR failed", err);
|
"read BMSR failed", err);
|
||||||
eth_link_t link = bmsr.link_status ? ETH_LINK_UP : ETH_LINK_DOWN;
|
eth_link_t link = bmsr.link_status ? ETH_LINK_UP : ETH_LINK_DOWN;
|
||||||
|
|
|
@ -92,7 +92,7 @@ void app_main(void)
|
||||||
.command_bits = 3,
|
.command_bits = 3,
|
||||||
.address_bits = 5,
|
.address_bits = 5,
|
||||||
.mode = 0,
|
.mode = 0,
|
||||||
.clock_speed_hz = 5 * 1000 * 1000,
|
.clock_speed_hz = CONFIG_EXAMPLE_ENC28J60_SPI_CLOCK_MHZ * 1000 * 1000,
|
||||||
.spics_io_num = CONFIG_EXAMPLE_ENC28J60_CS_GPIO,
|
.spics_io_num = CONFIG_EXAMPLE_ENC28J60_CS_GPIO,
|
||||||
.queue_size = 20
|
.queue_size = 20
|
||||||
};
|
};
|
||||||
|
|
|
@ -574,10 +574,10 @@ out:
|
||||||
/**
|
/**
|
||||||
* @brief Start enc28j60: enable interrupt and start receive
|
* @brief Start enc28j60: enable interrupt and start receive
|
||||||
*/
|
*/
|
||||||
static esp_err_t enc28j60_start(emac_enc28j60_t *emac)
|
static esp_err_t emac_enc28j60_start(esp_eth_mac_t *mac)
|
||||||
{
|
{
|
||||||
esp_err_t ret = ESP_OK;
|
esp_err_t ret = ESP_OK;
|
||||||
|
emac_enc28j60_t *emac = __containerof(mac, emac_enc28j60_t, parent);
|
||||||
/* enable interrupt */
|
/* enable interrupt */
|
||||||
MAC_CHECK(enc28j60_do_bitwise_clr(emac, ENC28J60_EIR, 0xFF) == ESP_OK,
|
MAC_CHECK(enc28j60_do_bitwise_clr(emac, ENC28J60_EIR, 0xFF) == ESP_OK,
|
||||||
"clear EIR failed", out, ESP_FAIL);
|
"clear EIR failed", out, ESP_FAIL);
|
||||||
|
@ -598,9 +598,10 @@ out:
|
||||||
/**
|
/**
|
||||||
* @brief Stop enc28j60: disable interrupt and stop receiving packets
|
* @brief Stop enc28j60: disable interrupt and stop receiving packets
|
||||||
*/
|
*/
|
||||||
static esp_err_t enc28j60_stop(emac_enc28j60_t *emac)
|
static esp_err_t emac_enc28j60_stop(esp_eth_mac_t *mac)
|
||||||
{
|
{
|
||||||
esp_err_t ret = ESP_OK;
|
esp_err_t ret = ESP_OK;
|
||||||
|
emac_enc28j60_t *emac = __containerof(mac, emac_enc28j60_t, parent);
|
||||||
/* disable interrupt */
|
/* disable interrupt */
|
||||||
MAC_CHECK(enc28j60_do_bitwise_clr(emac, ENC28J60_EIE, 0xFF) == ESP_OK,
|
MAC_CHECK(enc28j60_do_bitwise_clr(emac, ENC28J60_EIE, 0xFF) == ESP_OK,
|
||||||
"clear EIE failed", out, ESP_FAIL);
|
"clear EIE failed", out, ESP_FAIL);
|
||||||
|
@ -681,13 +682,12 @@ static void emac_enc28j60_task(void *arg)
|
||||||
static esp_err_t emac_enc28j60_set_link(esp_eth_mac_t *mac, eth_link_t link)
|
static esp_err_t emac_enc28j60_set_link(esp_eth_mac_t *mac, eth_link_t link)
|
||||||
{
|
{
|
||||||
esp_err_t ret = ESP_OK;
|
esp_err_t ret = ESP_OK;
|
||||||
emac_enc28j60_t *emac = __containerof(mac, emac_enc28j60_t, parent);
|
|
||||||
switch (link) {
|
switch (link) {
|
||||||
case ETH_LINK_UP:
|
case ETH_LINK_UP:
|
||||||
MAC_CHECK(enc28j60_start(emac) == ESP_OK, "enc28j60 start failed", out, ESP_FAIL);
|
MAC_CHECK(mac->start(mac) == ESP_OK, "enc28j60 start failed", out, ESP_FAIL);
|
||||||
break;
|
break;
|
||||||
case ETH_LINK_DOWN:
|
case ETH_LINK_DOWN:
|
||||||
MAC_CHECK(enc28j60_stop(emac) == ESP_OK, "enc28j60 stop failed", out, ESP_FAIL);
|
MAC_CHECK(mac->stop(mac) == ESP_OK, "enc28j60 stop failed", out, ESP_FAIL);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
MAC_CHECK(false, "unknown link status", out, ESP_ERR_INVALID_ARG);
|
MAC_CHECK(false, "unknown link status", out, ESP_ERR_INVALID_ARG);
|
||||||
|
@ -867,7 +867,7 @@ static esp_err_t emac_enc28j60_deinit(esp_eth_mac_t *mac)
|
||||||
{
|
{
|
||||||
emac_enc28j60_t *emac = __containerof(mac, emac_enc28j60_t, parent);
|
emac_enc28j60_t *emac = __containerof(mac, emac_enc28j60_t, parent);
|
||||||
esp_eth_mediator_t *eth = emac->eth;
|
esp_eth_mediator_t *eth = emac->eth;
|
||||||
enc28j60_stop(emac);
|
mac->stop(mac);
|
||||||
gpio_isr_handler_remove(emac->int_gpio_num);
|
gpio_isr_handler_remove(emac->int_gpio_num);
|
||||||
gpio_reset_pin(emac->int_gpio_num);
|
gpio_reset_pin(emac->int_gpio_num);
|
||||||
eth->on_state_changed(eth, ETH_STATE_DEINIT, NULL);
|
eth->on_state_changed(eth, ETH_STATE_DEINIT, NULL);
|
||||||
|
@ -902,6 +902,8 @@ esp_eth_mac_t *esp_eth_mac_new_enc28j60(const eth_enc28j60_config_t *enc28j60_co
|
||||||
emac->parent.set_mediator = emac_enc28j60_set_mediator;
|
emac->parent.set_mediator = emac_enc28j60_set_mediator;
|
||||||
emac->parent.init = emac_enc28j60_init;
|
emac->parent.init = emac_enc28j60_init;
|
||||||
emac->parent.deinit = emac_enc28j60_deinit;
|
emac->parent.deinit = emac_enc28j60_deinit;
|
||||||
|
emac->parent.start = emac_enc28j60_start;
|
||||||
|
emac->parent.stop = emac_enc28j60_stop;
|
||||||
emac->parent.del = emac_enc28j60_del;
|
emac->parent.del = emac_enc28j60_del;
|
||||||
emac->parent.write_phy_reg = emac_enc28j60_write_phy_reg;
|
emac->parent.write_phy_reg = emac_enc28j60_write_phy_reg;
|
||||||
emac->parent.read_phy_reg = emac_enc28j60_read_phy_reg;
|
emac->parent.read_phy_reg = emac_enc28j60_read_phy_reg;
|
||||||
|
|
Loading…
Reference in a new issue