mirror of
				https://github.com/espressif/esp-idf.git
				synced 2025-10-31 04:59:55 +00:00 
			
		
		
		
	Merge branch 'bugfix/eth_w5500_4byte_corruption_v4.3' into 'release/v4.3'
esp_eth: Fix w5500 read register operations (v4.3) See merge request espressif/esp-idf!13862
This commit is contained in:
		| @@ -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; |     esp_err_t ret = ESP_OK; | ||||||
|  |  | ||||||
|     spi_transaction_t trans = { |     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), |         .cmd = (address >> W5500_ADDR_OFFSET), | ||||||
|         .addr = ((address & 0xFFFF) | (W5500_ACCESS_MODE_READ << W5500_RWB_OFFSET) | W5500_SPI_OP_MODE_VDM), |         .addr = ((address & 0xFFFF) | (W5500_ACCESS_MODE_READ << W5500_RWB_OFFSET) | W5500_SPI_OP_MODE_VDM), | ||||||
|         .length = 8 * len, |         .length = 8 * len, | ||||||
| @@ -107,6 +108,9 @@ static esp_err_t w5500_read(emac_w5500_t *emac, uint32_t address, void *value, u | |||||||
|     } else { |     } else { | ||||||
|         ret = ESP_ERR_TIMEOUT; |         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; |     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; |     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) | static esp_err_t emac_w5500_transmit(esp_eth_mac_t *mac, uint8_t *buf, uint32_t length) | ||||||
| { | { | ||||||
|     esp_err_t ret = ESP_OK; |     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); |     MAC_CHECK(w5500_send_command(emac, W5500_SCR_SEND, 100) == ESP_OK, "issue SEND command failed", err, ESP_FAIL); | ||||||
|  |  | ||||||
|     // pooling the TX done event |     // pooling the TX done event | ||||||
|  |     int retry = 0; | ||||||
|     uint8_t status = 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); |         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 |     // clear the event bit | ||||||
|     status  = W5500_SIR_SEND; |     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); |     MAC_CHECK(w5500_write(emac, W5500_REG_SOCK_IR(0), &status, sizeof(status)) == ESP_OK, "write SOCK0 IR failed", err, ESP_FAIL); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 David Čermák
					David Čermák