mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Merge branch 'bugfix/eth_w5500_4byte_corruption' into 'master'
esp_eth: Fix w5500 read register operations Closes IDFGH-4776 and IDFGH-4400 See merge request espressif/esp-idf!13060
This commit is contained in:
commit
0f36a2dd16
@ -93,6 +93,7 @@ static esp_err_t w5500_read(emac_w5500_t *emac, uint32_t address, void *value, u
|
||||
esp_err_t ret = ESP_OK;
|
||||
|
||||
spi_transaction_t trans = {
|
||||
.flags = len <= 4 ? SPI_TRANS_USE_RXDATA : 0, // use direct reads for registers to prevent overwrites by 4-byte boundary writes
|
||||
.cmd = (address >> W5500_ADDR_OFFSET),
|
||||
.addr = ((address & 0xFFFF) | (W5500_ACCESS_MODE_READ << W5500_RWB_OFFSET) | W5500_SPI_OP_MODE_VDM),
|
||||
.length = 8 * len,
|
||||
@ -107,6 +108,9 @@ static esp_err_t w5500_read(emac_w5500_t *emac, uint32_t address, void *value, u
|
||||
} else {
|
||||
ret = ESP_ERR_TIMEOUT;
|
||||
}
|
||||
if ((trans.flags&SPI_TRANS_USE_RXDATA) && len <= 4) {
|
||||
memcpy(value, trans.rx_data, len); // copy register values to output
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -498,6 +502,16 @@ static esp_err_t emac_w5500_set_peer_pause_ability(esp_eth_mac_t *mac, uint32_t
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
static inline bool is_w5500_sane_for_rxtx(emac_w5500_t *emac)
|
||||
{
|
||||
uint8_t phycfg;
|
||||
/* phy is ok for rx and tx operations if bits RST and LNK are set (no link down, no reset) */
|
||||
if (w5500_read(emac, W5500_REG_PHYCFGR, &phycfg, 1) == ESP_OK && (phycfg & 0x8001)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static esp_err_t emac_w5500_transmit(esp_eth_mac_t *mac, uint8_t *buf, uint32_t length)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
@ -521,10 +535,14 @@ static esp_err_t emac_w5500_transmit(esp_eth_mac_t *mac, uint8_t *buf, uint32_t
|
||||
MAC_CHECK(w5500_send_command(emac, W5500_SCR_SEND, 100) == ESP_OK, "issue SEND command failed", err, ESP_FAIL);
|
||||
|
||||
// pooling the TX done event
|
||||
int retry = 0;
|
||||
uint8_t status = 0;
|
||||
do {
|
||||
while (!(status & W5500_SIR_SEND)) {
|
||||
MAC_CHECK(w5500_read(emac, W5500_REG_SOCK_IR(0), &status, sizeof(status)) == ESP_OK, "read SOCK0 IR failed", err, ESP_FAIL);
|
||||
} while (!(status & W5500_SIR_SEND));
|
||||
if ((retry++ > 3 && !is_w5500_sane_for_rxtx(emac)) || retry > 10) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
}
|
||||
// clear the event bit
|
||||
status = W5500_SIR_SEND;
|
||||
MAC_CHECK(w5500_write(emac, W5500_REG_SOCK_IR(0), &status, sizeof(status)) == ESP_OK, "write SOCK0 IR failed", err, ESP_FAIL);
|
||||
|
Loading…
x
Reference in New Issue
Block a user