esp_eth_mac_dm9051.c
1 // Copyright 2019 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 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 #include <string.h> 15 #include <stdlib.h> 16 #include <sys/cdefs.h> 17 #include "driver/gpio.h" 18 #include "driver/spi_master.h" 19 #include "esp_attr.h" 20 #include "esp_log.h" 21 #include "esp_eth.h" 22 #include "esp_system.h" 23 #include "esp_intr_alloc.h" 24 #include "esp_heap_caps.h" 25 #include "freertos/FreeRTOS.h" 26 #include "freertos/task.h" 27 #include "freertos/semphr.h" 28 #include "hal/cpu_hal.h" 29 #include "dm9051.h" 30 #include "sdkconfig.h" 31 #include "esp_rom_gpio.h" 32 #include "esp_rom_sys.h" 33 34 static const char *TAG = "emac_dm9051"; 35 #define MAC_CHECK(a, str, goto_tag, ret_value, ...) \ 36 do \ 37 { \ 38 if (!(a)) \ 39 { \ 40 ESP_LOGE(TAG, "%s(%d): " str, __FUNCTION__, __LINE__, ##__VA_ARGS__); \ 41 ret = ret_value; \ 42 goto goto_tag; \ 43 } \ 44 } while (0) 45 46 #define DM9051_SPI_LOCK_TIMEOUT_MS (50) 47 #define DM9051_PHY_OPERATION_TIMEOUT_US (1000) 48 49 typedef struct { 50 uint8_t flag; 51 uint8_t status; 52 uint8_t length_low; 53 uint8_t length_high; 54 } dm9051_rx_header_t; 55 56 typedef struct { 57 esp_eth_mac_t parent; 58 esp_eth_mediator_t *eth; 59 spi_device_handle_t spi_hdl; 60 SemaphoreHandle_t spi_lock; 61 TaskHandle_t rx_task_hdl; 62 uint32_t sw_reset_timeout_ms; 63 int int_gpio_num; 64 uint8_t addr[6]; 65 bool packets_remain; 66 bool flow_ctrl_enabled; 67 } emac_dm9051_t; 68 69 static inline bool dm9051_lock(emac_dm9051_t *emac) 70 { 71 return xSemaphoreTake(emac->spi_lock, pdMS_TO_TICKS(DM9051_SPI_LOCK_TIMEOUT_MS)) == pdTRUE; 72 } 73 74 static inline bool dm9051_unlock(emac_dm9051_t *emac) 75 { 76 return xSemaphoreGive(emac->spi_lock) == pdTRUE; 77 } 78 79 /** 80 * @brief write value to dm9051 internal register 81 */ 82 static esp_err_t dm9051_register_write(emac_dm9051_t *emac, uint8_t reg_addr, uint8_t value) 83 { 84 esp_err_t ret = ESP_OK; 85 spi_transaction_t trans = { 86 .cmd = DM9051_SPI_WR, 87 .addr = reg_addr, 88 .length = 8, 89 .flags = SPI_TRANS_USE_TXDATA 90 }; 91 trans.tx_data[0] = value; 92 if (dm9051_lock(emac)) { 93 if (spi_device_polling_transmit(emac->spi_hdl, &trans) != ESP_OK) { 94 ESP_LOGE(TAG, "%s(%d): spi transmit failed", __FUNCTION__, __LINE__); 95 ret = ESP_FAIL; 96 } 97 dm9051_unlock(emac); 98 } else { 99 ret = ESP_ERR_TIMEOUT; 100 } 101 return ret; 102 } 103 104 /** 105 * @brief read value from dm9051 internal register 106 */ 107 static esp_err_t dm9051_register_read(emac_dm9051_t *emac, uint8_t reg_addr, uint8_t *value) 108 { 109 esp_err_t ret = ESP_OK; 110 spi_transaction_t trans = { 111 .cmd = DM9051_SPI_RD, 112 .addr = reg_addr, 113 .length = 8, 114 .flags = SPI_TRANS_USE_TXDATA | SPI_TRANS_USE_RXDATA 115 }; 116 if (dm9051_lock(emac)) { 117 if (spi_device_polling_transmit(emac->spi_hdl, &trans) != ESP_OK) { 118 ESP_LOGE(TAG, "%s(%d): spi transmit failed", __FUNCTION__, __LINE__); 119 ret = ESP_FAIL; 120 } else { 121 *value = trans.rx_data[0]; 122 } 123 dm9051_unlock(emac); 124 } else { 125 ret = ESP_ERR_TIMEOUT; 126 } 127 return ret; 128 } 129 130 /** 131 * @brief write buffer to dm9051 internal memory 132 */ 133 static esp_err_t dm9051_memory_write(emac_dm9051_t *emac, uint8_t *buffer, uint32_t len) 134 { 135 esp_err_t ret = ESP_OK; 136 spi_transaction_t trans = { 137 .cmd = DM9051_SPI_WR, 138 .addr = DM9051_MWCMD, 139 .length = len * 8, 140 .tx_buffer = buffer 141 }; 142 if (dm9051_lock(emac)) { 143 if (spi_device_polling_transmit(emac->spi_hdl, &trans) != ESP_OK) { 144 ESP_LOGE(TAG, "%s(%d): spi transmit failed", __FUNCTION__, __LINE__); 145 ret = ESP_FAIL; 146 } 147 dm9051_unlock(emac); 148 } else { 149 ret = ESP_ERR_TIMEOUT; 150 } 151 return ret; 152 } 153 154 /** 155 * @brief read buffer from dm9051 internal memory 156 */ 157 static esp_err_t dm9051_memory_read(emac_dm9051_t *emac, uint8_t *buffer, uint32_t len) 158 { 159 esp_err_t ret = ESP_OK; 160 spi_transaction_t trans = { 161 .cmd = DM9051_SPI_RD, 162 .addr = DM9051_MRCMD, 163 .length = len * 8, 164 .rx_buffer = buffer 165 }; 166 if (dm9051_lock(emac)) { 167 if (spi_device_polling_transmit(emac->spi_hdl, &trans) != ESP_OK) { 168 ESP_LOGE(TAG, "%s(%d): spi transmit failed", __FUNCTION__, __LINE__); 169 ret = ESP_FAIL; 170 } 171 dm9051_unlock(emac); 172 } else { 173 ret = ESP_ERR_TIMEOUT; 174 } 175 return ret; 176 } 177 178 /** 179 * @brief peek buffer from dm9051 internal memory (without internal cursor moved) 180 */ 181 static esp_err_t dm9051_memory_peek(emac_dm9051_t *emac, uint8_t *buffer, uint32_t len) 182 { 183 esp_err_t ret = ESP_OK; 184 spi_transaction_t trans = { 185 .cmd = DM9051_SPI_RD, 186 .addr = DM9051_MRCMDX1, 187 .length = len * 8, 188 .rx_buffer = buffer 189 }; 190 if (dm9051_lock(emac)) { 191 if (spi_device_polling_transmit(emac->spi_hdl, &trans) != ESP_OK) { 192 ESP_LOGE(TAG, "%s(%d): spi transmit failed", __FUNCTION__, __LINE__); 193 ret = ESP_FAIL; 194 } 195 dm9051_unlock(emac); 196 } else { 197 ret = ESP_ERR_TIMEOUT; 198 } 199 return ret; 200 } 201 202 /** 203 * @brief read mac address from internal registers 204 */ 205 static esp_err_t dm9051_get_mac_addr(emac_dm9051_t *emac) 206 { 207 esp_err_t ret = ESP_OK; 208 for (int i = 0; i < 6; i++) { 209 MAC_CHECK(dm9051_register_read(emac, DM9051_PAR + i, &emac->addr[i]) == ESP_OK, "read PAR failed", err, ESP_FAIL); 210 } 211 return ESP_OK; 212 err: 213 return ret; 214 } 215 216 /** 217 * @brief set new mac address to internal registers 218 */ 219 static esp_err_t dm9051_set_mac_addr(emac_dm9051_t *emac) 220 { 221 esp_err_t ret = ESP_OK; 222 for (int i = 0; i < 6; i++) { 223 MAC_CHECK(dm9051_register_write(emac, DM9051_PAR + i, emac->addr[i]) == ESP_OK, "write PAR failed", err, ESP_FAIL); 224 } 225 return ESP_OK; 226 err: 227 return ret; 228 } 229 230 /** 231 * @brief clear multicast hash table 232 */ 233 static esp_err_t dm9051_clear_multicast_table(emac_dm9051_t *emac) 234 { 235 esp_err_t ret = ESP_OK; 236 /* rx broadcast packet control by bit7 of MAC register 1DH */ 237 MAC_CHECK(dm9051_register_write(emac, DM9051_BCASTCR, 0x00) == ESP_OK, "write BCASTCR failed", err, ESP_FAIL); 238 for (int i = 0; i < 7; i++) { 239 MAC_CHECK(dm9051_register_write(emac, DM9051_MAR + i, 0x00) == ESP_OK, "write MAR failed", err, ESP_FAIL); 240 } 241 /* enable receive broadcast paclets */ 242 MAC_CHECK(dm9051_register_write(emac, DM9051_MAR + 7, 0x80) == ESP_OK, "write MAR failed", err, ESP_FAIL); 243 return ESP_OK; 244 err: 245 return ret; 246 } 247 248 /** 249 * @brief software reset dm9051 internal register 250 */ 251 static esp_err_t dm9051_reset(emac_dm9051_t *emac) 252 { 253 esp_err_t ret = ESP_OK; 254 /* power on phy */ 255 MAC_CHECK(dm9051_register_write(emac, DM9051_GPR, 0x00) == ESP_OK, "write GPR failed", err, ESP_FAIL); 256 /* mac and phy register won't be accesable within at least 1ms */ 257 vTaskDelay(pdMS_TO_TICKS(10)); 258 /* software reset */ 259 uint8_t ncr = NCR_RST; 260 MAC_CHECK(dm9051_register_write(emac, DM9051_NCR, ncr) == ESP_OK, "write NCR failed", err, ESP_FAIL); 261 uint32_t to = 0; 262 for (to = 0; to < emac->sw_reset_timeout_ms / 10; to++) { 263 MAC_CHECK(dm9051_register_read(emac, DM9051_NCR, &ncr) == ESP_OK, "read NCR failed", err, ESP_FAIL); 264 if (!(ncr & NCR_RST)) { 265 break; 266 } 267 vTaskDelay(pdMS_TO_TICKS(10)); 268 } 269 MAC_CHECK(to < emac->sw_reset_timeout_ms / 10, "reset timeout", err, ESP_ERR_TIMEOUT); 270 return ESP_OK; 271 err: 272 return ret; 273 } 274 275 /** 276 * @brief verify dm9051 chip ID 277 */ 278 static esp_err_t dm9051_verify_id(emac_dm9051_t *emac) 279 { 280 esp_err_t ret = ESP_OK; 281 uint8_t id[2]; 282 MAC_CHECK(dm9051_register_read(emac, DM9051_VIDL, &id[0]) == ESP_OK, "read VIDL failed", err, ESP_FAIL); 283 MAC_CHECK(dm9051_register_read(emac, DM9051_VIDH, &id[1]) == ESP_OK, "read VIDH failed", err, ESP_FAIL); 284 MAC_CHECK(0x0A == id[1] && 0x46 == id[0], "wrong Vendor ID", err, ESP_ERR_INVALID_VERSION); 285 MAC_CHECK(dm9051_register_read(emac, DM9051_PIDL, &id[0]) == ESP_OK, "read PIDL failed", err, ESP_FAIL); 286 MAC_CHECK(dm9051_register_read(emac, DM9051_PIDH, &id[1]) == ESP_OK, "read PIDH failed", err, ESP_FAIL); 287 MAC_CHECK(0x90 == id[1] && 0x51 == id[0], "wrong Product ID", err, ESP_ERR_INVALID_VERSION); 288 return ESP_OK; 289 err: 290 return ret; 291 } 292 293 /** 294 * @brief default setup for dm9051 internal registers 295 */ 296 static esp_err_t dm9051_setup_default(emac_dm9051_t *emac) 297 { 298 esp_err_t ret = ESP_OK; 299 /* disable wakeup */ 300 MAC_CHECK(dm9051_register_write(emac, DM9051_NCR, 0x00) == ESP_OK, "write NCR failed", err, ESP_FAIL); 301 MAC_CHECK(dm9051_register_write(emac, DM9051_WCR, 0x00) == ESP_OK, "write WCR failed", err, ESP_FAIL); 302 /* stop transmitting, enable appending pad, crc for packets */ 303 MAC_CHECK(dm9051_register_write(emac, DM9051_TCR, 0x00) == ESP_OK, "write TCR failed", err, ESP_FAIL); 304 /* stop receiving, no promiscuous mode, no runt packet(size < 64bytes), not all multicast packets*/ 305 /* discard long packet(size > 1522bytes) and crc error packet, enable watchdog */ 306 MAC_CHECK(dm9051_register_write(emac, DM9051_RCR, RCR_DIS_LONG | RCR_DIS_CRC) == ESP_OK, "write RCR failed", err, ESP_FAIL); 307 /* retry late collision packet, at most two transmit command can be issued before transmit complete */ 308 MAC_CHECK(dm9051_register_write(emac, DM9051_TCR2, TCR2_RLCP) == ESP_OK, "write TCR2 failed", err, ESP_FAIL); 309 /* enable auto transmit */ 310 MAC_CHECK(dm9051_register_write(emac, DM9051_ATCR, ATCR_AUTO_TX) == ESP_OK, "write ATCR failed", err, ESP_FAIL); 311 /* generate checksum for UDP, TCP and IPv4 packets */ 312 MAC_CHECK(dm9051_register_write(emac, DM9051_TCSCR, TCSCR_IPCSE | TCSCR_TCPCSE | TCSCR_UDPCSE) == ESP_OK, 313 "write TCSCR failed", err, ESP_FAIL); 314 /* disable check sum for receive packets */ 315 MAC_CHECK(dm9051_register_write(emac, DM9051_RCSCSR, 0x00) == ESP_OK, "write RCSCSR failed", err, ESP_FAIL); 316 /* interrupt pin config: push-pull output, active high */ 317 MAC_CHECK(dm9051_register_write(emac, DM9051_INTCR, 0x00) == ESP_OK, "write INTCR failed", err, ESP_FAIL); 318 MAC_CHECK(dm9051_register_write(emac, DM9051_INTCKCR, 0x00) == ESP_OK, "write INTCKCR failed", err, ESP_FAIL); 319 /* no length limitation for rx packets */ 320 MAC_CHECK(dm9051_register_write(emac, DM9051_RLENCR, 0x00) == ESP_OK, "write RLENCR failed", err, ESP_FAIL); 321 /* 3K-byte for TX and 13K-byte for RX */ 322 MAC_CHECK(dm9051_register_write(emac, DM9051_MEMSCR, 0x00) == ESP_OK, "write MEMSCR failed", err, ESP_FAIL); 323 /* reset tx and rx memory pointer */ 324 MAC_CHECK(dm9051_register_write(emac, DM9051_MPTRCR, MPTRCR_RST_RX | MPTRCR_RST_TX) == ESP_OK, 325 "write MPTRCR failed", err, ESP_FAIL); 326 /* clear network status: wakeup event, tx complete */ 327 MAC_CHECK(dm9051_register_write(emac, DM9051_NSR, NSR_WAKEST | NSR_TX2END | NSR_TX1END) == ESP_OK, "write NSR failed", err, ESP_FAIL); 328 /* clear interrupt status */ 329 MAC_CHECK(dm9051_register_write(emac, DM9051_ISR, ISR_CLR_STATUS) == ESP_OK, "write ISR failed", err, ESP_FAIL); 330 return ESP_OK; 331 err: 332 return ret; 333 } 334 335 static esp_err_t dm9051_enable_flow_ctrl(emac_dm9051_t *emac, bool enable) 336 { 337 esp_err_t ret = ESP_OK; 338 if (enable) { 339 /* send jam pattern (duration time = 1.15ms) when rx free space < 3k bytes */ 340 MAC_CHECK(dm9051_register_write(emac, DM9051_BPTR, 0x3F) == ESP_OK, "write BPTR failed", err, ESP_FAIL); 341 /* flow control: high water threshold = 3k bytes, low water threshold = 8k bytes */ 342 MAC_CHECK(dm9051_register_write(emac, DM9051_FCTR, 0x38) == ESP_OK, "write FCTR failed", err, ESP_FAIL); 343 /* enable flow control */ 344 MAC_CHECK(dm9051_register_write(emac, DM9051_FCR, FCR_FLOW_ENABLE) == ESP_OK, "write FCR failed", err, ESP_FAIL); 345 } else { 346 /* disable flow control */ 347 MAC_CHECK(dm9051_register_write(emac, DM9051_FCR, 0) == ESP_OK, "write FCR failed", err, ESP_FAIL); 348 } 349 return ESP_OK; 350 err: 351 return ret; 352 } 353 354 /** 355 * @brief start dm9051: enable interrupt and start receive 356 */ 357 static esp_err_t emac_dm9051_start(esp_eth_mac_t *mac) 358 { 359 esp_err_t ret = ESP_OK; 360 emac_dm9051_t *emac = __containerof(mac, emac_dm9051_t, parent); 361 /* enable interrupt */ 362 MAC_CHECK(dm9051_register_write(emac, DM9051_IMR, IMR_ALL) == ESP_OK, "write IMR failed", err, ESP_FAIL); 363 /* enable rx */ 364 uint8_t rcr = 0; 365 MAC_CHECK(dm9051_register_read(emac, DM9051_RCR, &rcr) == ESP_OK, "read RCR failed", err, ESP_FAIL); 366 rcr |= RCR_RXEN; 367 MAC_CHECK(dm9051_register_write(emac, DM9051_RCR, rcr) == ESP_OK, "write RCR failed", err, ESP_FAIL); 368 return ESP_OK; 369 err: 370 return ret; 371 } 372 373 /** 374 * @brief stop dm9051: disable interrupt and stop receive 375 */ 376 static esp_err_t emac_dm9051_stop(esp_eth_mac_t *mac) 377 { 378 esp_err_t ret = ESP_OK; 379 emac_dm9051_t *emac = __containerof(mac, emac_dm9051_t, parent); 380 /* disable interrupt */ 381 MAC_CHECK(dm9051_register_write(emac, DM9051_IMR, 0x00) == ESP_OK, "write IMR failed", err, ESP_FAIL); 382 /* disable rx */ 383 uint8_t rcr = 0; 384 MAC_CHECK(dm9051_register_read(emac, DM9051_RCR, &rcr) == ESP_OK, "read RCR failed", err, ESP_FAIL); 385 rcr &= ~RCR_RXEN; 386 MAC_CHECK(dm9051_register_write(emac, DM9051_RCR, rcr) == ESP_OK, "write RCR failed", err, ESP_FAIL); 387 return ESP_OK; 388 err: 389 return ret; 390 } 391 392 IRAM_ATTR static void dm9051_isr_handler(void *arg) 393 { 394 emac_dm9051_t *emac = (emac_dm9051_t *)arg; 395 BaseType_t high_task_wakeup = pdFALSE; 396 /* notify dm9051 task */ 397 vTaskNotifyGiveFromISR(emac->rx_task_hdl, &high_task_wakeup); 398 if (high_task_wakeup != pdFALSE) { 399 portYIELD_FROM_ISR(); 400 } 401 } 402 403 static void emac_dm9051_task(void *arg) 404 { 405 emac_dm9051_t *emac = (emac_dm9051_t *)arg; 406 uint8_t status = 0; 407 uint8_t *buffer = NULL; 408 uint32_t length = 0; 409 while (1) { 410 // block indefinitely until some task notifies me 411 ulTaskNotifyTake(pdFALSE, portMAX_DELAY); 412 /* clear interrupt status */ 413 dm9051_register_read(emac, DM9051_ISR, &status); 414 dm9051_register_write(emac, DM9051_ISR, status); 415 /* packet received */ 416 if (status & ISR_PR) { 417 do { 418 length = ETH_MAX_PACKET_SIZE; 419 buffer = heap_caps_malloc(length, MALLOC_CAP_DMA); 420 if (!buffer) { 421 ESP_LOGE(TAG, "no mem for receive buffer"); 422 } else if (emac->parent.receive(&emac->parent, buffer, &length) == ESP_OK) { 423 /* pass the buffer to stack (e.g. TCP/IP layer) */ 424 if (length) { 425 emac->eth->stack_input(emac->eth, buffer, length); 426 } else { 427 free(buffer); 428 } 429 } else { 430 free(buffer); 431 } 432 } while (emac->packets_remain); 433 } 434 } 435 vTaskDelete(NULL); 436 } 437 438 static esp_err_t emac_dm9051_set_mediator(esp_eth_mac_t *mac, esp_eth_mediator_t *eth) 439 { 440 esp_err_t ret = ESP_OK; 441 MAC_CHECK(eth, "can't set mac's mediator to null", err, ESP_ERR_INVALID_ARG); 442 emac_dm9051_t *emac = __containerof(mac, emac_dm9051_t, parent); 443 emac->eth = eth; 444 return ESP_OK; 445 err: 446 return ret; 447 } 448 449 static esp_err_t emac_dm9051_write_phy_reg(esp_eth_mac_t *mac, uint32_t phy_addr, uint32_t phy_reg, uint32_t reg_value) 450 { 451 esp_err_t ret = ESP_OK; 452 emac_dm9051_t *emac = __containerof(mac, emac_dm9051_t, parent); 453 /* check if phy access is in progress */ 454 uint8_t epcr = 0; 455 MAC_CHECK(dm9051_register_read(emac, DM9051_EPCR, &epcr) == ESP_OK, "read EPCR failed", err, ESP_FAIL); 456 MAC_CHECK(!(epcr & EPCR_ERRE), "phy is busy", err, ESP_ERR_INVALID_STATE); 457 MAC_CHECK(dm9051_register_write(emac, DM9051_EPAR, (uint8_t)(((phy_addr << 6) & 0xFF) | phy_reg)) == ESP_OK, 458 "write EPAR failed", err, ESP_FAIL); 459 MAC_CHECK(dm9051_register_write(emac, DM9051_EPDRL, (uint8_t)(reg_value & 0xFF)) == ESP_OK, 460 "write EPDRL failed", err, ESP_FAIL); 461 MAC_CHECK(dm9051_register_write(emac, DM9051_EPDRH, (uint8_t)((reg_value >> 8) & 0xFF)) == ESP_OK, 462 "write EPDRH failed", err, ESP_FAIL); 463 /* select PHY and select write operation */ 464 MAC_CHECK(dm9051_register_write(emac, DM9051_EPCR, EPCR_EPOS | EPCR_ERPRW) == ESP_OK, "write EPCR failed", err, ESP_FAIL); 465 /* polling the busy flag */ 466 uint32_t to = 0; 467 do { 468 esp_rom_delay_us(100); 469 MAC_CHECK(dm9051_register_read(emac, DM9051_EPCR, &epcr) == ESP_OK, "read EPCR failed", err, ESP_FAIL); 470 to += 100; 471 } while ((epcr & EPCR_ERRE) && to < DM9051_PHY_OPERATION_TIMEOUT_US); 472 MAC_CHECK(!(epcr & EPCR_ERRE), "phy is busy", err, ESP_ERR_TIMEOUT); 473 return ESP_OK; 474 err: 475 return ret; 476 } 477 478 static esp_err_t emac_dm9051_read_phy_reg(esp_eth_mac_t *mac, uint32_t phy_addr, uint32_t phy_reg, uint32_t *reg_value) 479 { 480 esp_err_t ret = ESP_OK; 481 MAC_CHECK(reg_value, "can't set reg_value to null", err, ESP_ERR_INVALID_ARG); 482 emac_dm9051_t *emac = __containerof(mac, emac_dm9051_t, parent); 483 /* check if phy access is in progress */ 484 uint8_t epcr = 0; 485 MAC_CHECK(dm9051_register_read(emac, DM9051_EPCR, &epcr) == ESP_OK, "read EPCR failed", err, ESP_FAIL); 486 MAC_CHECK(!(epcr & 0x01), "phy is busy", err, ESP_ERR_INVALID_STATE); 487 MAC_CHECK(dm9051_register_write(emac, DM9051_EPAR, (uint8_t)(((phy_addr << 6) & 0xFF) | phy_reg)) == ESP_OK, 488 "write EPAR failed", err, ESP_FAIL); 489 /* Select PHY and select read operation */ 490 MAC_CHECK(dm9051_register_write(emac, DM9051_EPCR, 0x0C) == ESP_OK, "write EPCR failed", err, ESP_FAIL); 491 /* polling the busy flag */ 492 uint32_t to = 0; 493 do { 494 esp_rom_delay_us(100); 495 MAC_CHECK(dm9051_register_read(emac, DM9051_EPCR, &epcr) == ESP_OK, "read EPCR failed", err, ESP_FAIL); 496 to += 100; 497 } while ((epcr & EPCR_ERRE) && to < DM9051_PHY_OPERATION_TIMEOUT_US); 498 MAC_CHECK(!(epcr & EPCR_ERRE), "phy is busy", err, ESP_ERR_TIMEOUT); 499 uint8_t value_h = 0; 500 uint8_t value_l = 0; 501 MAC_CHECK(dm9051_register_read(emac, DM9051_EPDRH, &value_h) == ESP_OK, "read EPDRH failed", err, ESP_FAIL); 502 MAC_CHECK(dm9051_register_read(emac, DM9051_EPDRL, &value_l) == ESP_OK, "read EPDRL failed", err, ESP_FAIL); 503 *reg_value = (value_h << 8) | value_l; 504 return ESP_OK; 505 err: 506 return ret; 507 } 508 509 static esp_err_t emac_dm9051_set_addr(esp_eth_mac_t *mac, uint8_t *addr) 510 { 511 esp_err_t ret = ESP_OK; 512 MAC_CHECK(addr, "can't set mac addr to null", err, ESP_ERR_INVALID_ARG); 513 emac_dm9051_t *emac = __containerof(mac, emac_dm9051_t, parent); 514 memcpy(emac->addr, addr, 6); 515 MAC_CHECK(dm9051_set_mac_addr(emac) == ESP_OK, "set mac address failed", err, ESP_FAIL); 516 return ESP_OK; 517 err: 518 return ret; 519 } 520 521 static esp_err_t emac_dm9051_get_addr(esp_eth_mac_t *mac, uint8_t *addr) 522 { 523 esp_err_t ret = ESP_OK; 524 MAC_CHECK(addr, "can't set mac addr to null", err, ESP_ERR_INVALID_ARG); 525 emac_dm9051_t *emac = __containerof(mac, emac_dm9051_t, parent); 526 memcpy(addr, emac->addr, 6); 527 return ESP_OK; 528 err: 529 return ret; 530 } 531 532 static esp_err_t emac_dm9051_set_link(esp_eth_mac_t *mac, eth_link_t link) 533 { 534 esp_err_t ret = ESP_OK; 535 emac_dm9051_t *emac = __containerof(mac, emac_dm9051_t, parent); 536 uint8_t nsr = 0; 537 MAC_CHECK(dm9051_register_read(emac, DM9051_NSR, &nsr) == ESP_OK, "read NSR failed", err, ESP_FAIL); 538 switch (link) { 539 case ETH_LINK_UP: 540 MAC_CHECK(nsr & NSR_LINKST, "phy is not link up", err, ESP_ERR_INVALID_STATE); 541 MAC_CHECK(mac->start(mac) == ESP_OK, "dm9051 start failed", err, ESP_FAIL); 542 break; 543 case ETH_LINK_DOWN: 544 MAC_CHECK(!(nsr & NSR_LINKST), "phy is not link down", err, ESP_ERR_INVALID_STATE); 545 MAC_CHECK(mac->stop(mac) == ESP_OK, "dm9051 stop failed", err, ESP_FAIL); 546 break; 547 default: 548 MAC_CHECK(false, "unknown link status", err, ESP_ERR_INVALID_ARG); 549 break; 550 } 551 return ESP_OK; 552 err: 553 return ret; 554 } 555 556 static esp_err_t emac_dm9051_set_speed(esp_eth_mac_t *mac, eth_speed_t speed) 557 { 558 esp_err_t ret = ESP_OK; 559 emac_dm9051_t *emac = __containerof(mac, emac_dm9051_t, parent); 560 uint8_t nsr = 0; 561 MAC_CHECK(dm9051_register_read(emac, DM9051_NSR, &nsr) == ESP_OK, "read NSR failed", err, ESP_FAIL); 562 switch (speed) { 563 case ETH_SPEED_10M: 564 MAC_CHECK(nsr & NSR_SPEED, "phy speed is not at 10Mbps", err, ESP_ERR_INVALID_STATE); 565 ESP_LOGD(TAG, "working in 10Mbps"); 566 break; 567 case ETH_SPEED_100M: 568 MAC_CHECK(!(nsr & NSR_SPEED), "phy speed is not at 100Mbps", err, ESP_ERR_INVALID_STATE); 569 ESP_LOGD(TAG, "working in 100Mbps"); 570 break; 571 default: 572 MAC_CHECK(false, "unknown speed", err, ESP_ERR_INVALID_ARG); 573 break; 574 } 575 return ESP_OK; 576 err: 577 return ret; 578 } 579 580 static esp_err_t emac_dm9051_set_duplex(esp_eth_mac_t *mac, eth_duplex_t duplex) 581 { 582 esp_err_t ret = ESP_OK; 583 emac_dm9051_t *emac = __containerof(mac, emac_dm9051_t, parent); 584 uint8_t ncr = 0; 585 MAC_CHECK(dm9051_register_read(emac, DM9051_NCR, &ncr) == ESP_OK, "read NCR failed", err, ESP_FAIL); 586 switch (duplex) { 587 case ETH_DUPLEX_HALF: 588 ESP_LOGD(TAG, "working in half duplex"); 589 MAC_CHECK(!(ncr & NCR_FDX), "phy is not at half duplex", err, ESP_ERR_INVALID_STATE); 590 break; 591 case ETH_DUPLEX_FULL: 592 ESP_LOGD(TAG, "working in full duplex"); 593 MAC_CHECK(ncr & NCR_FDX, "phy is not at full duplex", err, ESP_ERR_INVALID_STATE); 594 break; 595 default: 596 MAC_CHECK(false, "unknown duplex", err, ESP_ERR_INVALID_ARG); 597 break; 598 } 599 return ESP_OK; 600 err: 601 return ret; 602 } 603 604 static esp_err_t emac_dm9051_set_promiscuous(esp_eth_mac_t *mac, bool enable) 605 { 606 esp_err_t ret = ESP_OK; 607 emac_dm9051_t *emac = __containerof(mac, emac_dm9051_t, parent); 608 uint8_t rcr = 0; 609 MAC_CHECK(dm9051_register_read(emac, DM9051_EPDRL, &rcr) == ESP_OK, "read RCR failed", err, ESP_FAIL); 610 if (enable) { 611 rcr |= RCR_PRMSC; 612 } else { 613 rcr &= ~RCR_PRMSC; 614 } 615 MAC_CHECK(dm9051_register_write(emac, DM9051_RCR, rcr) == ESP_OK, "write RCR failed", err, ESP_FAIL); 616 return ESP_OK; 617 err: 618 return ret; 619 } 620 621 static esp_err_t emac_dm9051_enable_flow_ctrl(esp_eth_mac_t *mac, bool enable) 622 { 623 emac_dm9051_t *emac = __containerof(mac, emac_dm9051_t, parent); 624 emac->flow_ctrl_enabled = enable; 625 return ESP_OK; 626 } 627 628 static esp_err_t emac_dm9051_set_peer_pause_ability(esp_eth_mac_t *mac, uint32_t ability) 629 { 630 emac_dm9051_t *emac = __containerof(mac, emac_dm9051_t, parent); 631 // we want to enable flow control, and peer does support pause function 632 // then configure the MAC layer to enable flow control feature 633 if (emac->flow_ctrl_enabled && ability) { 634 dm9051_enable_flow_ctrl(emac, true); 635 } else { 636 dm9051_enable_flow_ctrl(emac, false); 637 ESP_LOGD(TAG, "Flow control not enabled for the link"); 638 } 639 return ESP_OK; 640 } 641 642 static esp_err_t emac_dm9051_transmit(esp_eth_mac_t *mac, uint8_t *buf, uint32_t length) 643 { 644 esp_err_t ret = ESP_OK; 645 emac_dm9051_t *emac = __containerof(mac, emac_dm9051_t, parent); 646 /* Check if last transmit complete */ 647 uint8_t tcr = 0; 648 MAC_CHECK(dm9051_register_read(emac, DM9051_TCR, &tcr) == ESP_OK, "read TCR failed", err, ESP_FAIL); 649 MAC_CHECK(!(tcr & TCR_TXREQ), "last transmit still in progress", err, ESP_ERR_INVALID_STATE); 650 /* set tx length */ 651 MAC_CHECK(dm9051_register_write(emac, DM9051_TXPLL, length & 0xFF) == ESP_OK, "write TXPLL failed", err, ESP_FAIL); 652 MAC_CHECK(dm9051_register_write(emac, DM9051_TXPLH, (length >> 8) & 0xFF) == ESP_OK, "write TXPLH failed", err, ESP_FAIL); 653 /* copy data to tx memory */ 654 MAC_CHECK(dm9051_memory_write(emac, buf, length) == ESP_OK, "write memory failed", err, ESP_FAIL); 655 /* issue tx polling command */ 656 tcr |= TCR_TXREQ; 657 MAC_CHECK(dm9051_register_write(emac, DM9051_TCR, tcr) == ESP_OK, "write TCR failed", err, ESP_FAIL); 658 return ESP_OK; 659 err: 660 return ret; 661 } 662 663 static esp_err_t emac_dm9051_receive(esp_eth_mac_t *mac, uint8_t *buf, uint32_t *length) 664 { 665 esp_err_t ret = ESP_OK; 666 emac_dm9051_t *emac = __containerof(mac, emac_dm9051_t, parent); 667 uint8_t rxbyte = 0; 668 uint16_t rx_len = 0; 669 __attribute__((aligned(4))) dm9051_rx_header_t header; // SPI driver needs the rx buffer 4 byte align 670 emac->packets_remain = false; 671 /* dummy read, get the most updated data */ 672 MAC_CHECK(dm9051_register_read(emac, DM9051_MRCMDX, &rxbyte) == ESP_OK, "read MRCMDX failed", err, ESP_FAIL); 673 MAC_CHECK(dm9051_register_read(emac, DM9051_MRCMDX, &rxbyte) == ESP_OK, "read MRCMDX failed", err, ESP_FAIL); 674 /* rxbyte must be 0xFF, 0 or 1 */ 675 if (rxbyte > 1) { 676 MAC_CHECK(mac->stop(mac) == ESP_OK, "stop dm9051 failed", err, ESP_FAIL); 677 /* reset rx fifo pointer */ 678 MAC_CHECK(dm9051_register_write(emac, DM9051_MPTRCR, MPTRCR_RST_RX) == ESP_OK, 679 "write MPTRCR failed", err, ESP_FAIL); 680 esp_rom_delay_us(10); 681 MAC_CHECK(mac->start(mac) == ESP_OK, "start dm9051 failed", err, ESP_FAIL); 682 MAC_CHECK(false, "reset rx fifo pointer", err, ESP_FAIL); 683 } else if (rxbyte) { 684 MAC_CHECK(dm9051_memory_peek(emac, (uint8_t *)&header, sizeof(header)) == ESP_OK, 685 "peek rx header failed", err, ESP_FAIL); 686 rx_len = header.length_low + (header.length_high << 8); 687 /* check if the buffer can hold all the incoming data */ 688 if (*length < rx_len - 4) { 689 ESP_LOGE(TAG, "buffer size too small"); 690 /* tell upper layer the size we need */ 691 *length = rx_len - 4; 692 ret = ESP_ERR_INVALID_SIZE; 693 goto err; 694 } 695 MAC_CHECK(*length >= rx_len - 4, "buffer size too small", err, ESP_ERR_INVALID_SIZE); 696 MAC_CHECK(dm9051_memory_read(emac, (uint8_t *)&header, sizeof(header)) == ESP_OK, 697 "read rx header failed", err, ESP_FAIL); 698 MAC_CHECK(dm9051_memory_read(emac, buf, rx_len) == ESP_OK, "read rx data failed", err, ESP_FAIL); 699 MAC_CHECK(!(header.status & 0xBF), "receive status error: %xH", err, ESP_FAIL, header.status); 700 *length = rx_len - 4; // substract the CRC length (4Bytes) 701 /* dummy read, get the most updated data */ 702 MAC_CHECK(dm9051_register_read(emac, DM9051_MRCMDX, &rxbyte) == ESP_OK, "read MRCMDX failed", err, ESP_FAIL); 703 MAC_CHECK(dm9051_register_read(emac, DM9051_MRCMDX, &rxbyte) == ESP_OK, "read MRCMDX failed", err, ESP_FAIL); 704 emac->packets_remain = rxbyte > 0; 705 } 706 return ESP_OK; 707 err: 708 return ret; 709 } 710 711 static esp_err_t emac_dm9051_init(esp_eth_mac_t *mac) 712 { 713 esp_err_t ret = ESP_OK; 714 emac_dm9051_t *emac = __containerof(mac, emac_dm9051_t, parent); 715 esp_eth_mediator_t *eth = emac->eth; 716 esp_rom_gpio_pad_select_gpio(emac->int_gpio_num); 717 gpio_set_direction(emac->int_gpio_num, GPIO_MODE_INPUT); 718 gpio_set_pull_mode(emac->int_gpio_num, GPIO_PULLDOWN_ONLY); 719 gpio_set_intr_type(emac->int_gpio_num, GPIO_INTR_POSEDGE); 720 gpio_intr_enable(emac->int_gpio_num); 721 gpio_isr_handler_add(emac->int_gpio_num, dm9051_isr_handler, emac); 722 MAC_CHECK(eth->on_state_changed(eth, ETH_STATE_LLINIT, NULL) == ESP_OK, "lowlevel init failed", err, ESP_FAIL); 723 /* reset dm9051 */ 724 MAC_CHECK(dm9051_reset(emac) == ESP_OK, "reset dm9051 failed", err, ESP_FAIL); 725 /* verify chip id */ 726 MAC_CHECK(dm9051_verify_id(emac) == ESP_OK, "vefiry chip ID failed", err, ESP_FAIL); 727 /* default setup of internal registers */ 728 MAC_CHECK(dm9051_setup_default(emac) == ESP_OK, "dm9051 default setup failed", err, ESP_FAIL); 729 /* clear multicast hash table */ 730 MAC_CHECK(dm9051_clear_multicast_table(emac) == ESP_OK, "clear multicast table failed", err, ESP_FAIL); 731 /* get emac address from eeprom */ 732 MAC_CHECK(dm9051_get_mac_addr(emac) == ESP_OK, "fetch ethernet mac address failed", err, ESP_FAIL); 733 return ESP_OK; 734 err: 735 gpio_isr_handler_remove(emac->int_gpio_num); 736 gpio_reset_pin(emac->int_gpio_num); 737 eth->on_state_changed(eth, ETH_STATE_DEINIT, NULL); 738 return ret; 739 } 740 741 static esp_err_t emac_dm9051_deinit(esp_eth_mac_t *mac) 742 { 743 emac_dm9051_t *emac = __containerof(mac, emac_dm9051_t, parent); 744 esp_eth_mediator_t *eth = emac->eth; 745 mac->stop(mac); 746 gpio_isr_handler_remove(emac->int_gpio_num); 747 gpio_reset_pin(emac->int_gpio_num); 748 eth->on_state_changed(eth, ETH_STATE_DEINIT, NULL); 749 return ESP_OK; 750 } 751 752 static esp_err_t emac_dm9051_del(esp_eth_mac_t *mac) 753 { 754 emac_dm9051_t *emac = __containerof(mac, emac_dm9051_t, parent); 755 vTaskDelete(emac->rx_task_hdl); 756 vSemaphoreDelete(emac->spi_lock); 757 free(emac); 758 return ESP_OK; 759 } 760 761 esp_eth_mac_t *esp_eth_mac_new_dm9051(const eth_dm9051_config_t *dm9051_config, const eth_mac_config_t *mac_config) 762 { 763 esp_eth_mac_t *ret = NULL; 764 emac_dm9051_t *emac = NULL; 765 MAC_CHECK(dm9051_config, "can't set dm9051 specific config to null", err, NULL); 766 MAC_CHECK(mac_config, "can't set mac config to null", err, NULL); 767 emac = calloc(1, sizeof(emac_dm9051_t)); 768 MAC_CHECK(emac, "calloc emac failed", err, NULL); 769 /* dm9051 receive is driven by interrupt only for now*/ 770 MAC_CHECK(dm9051_config->int_gpio_num >= 0, "error interrupt gpio number", err, NULL); 771 /* bind methods and attributes */ 772 emac->sw_reset_timeout_ms = mac_config->sw_reset_timeout_ms; 773 emac->int_gpio_num = dm9051_config->int_gpio_num; 774 emac->spi_hdl = dm9051_config->spi_hdl; 775 emac->parent.set_mediator = emac_dm9051_set_mediator; 776 emac->parent.init = emac_dm9051_init; 777 emac->parent.deinit = emac_dm9051_deinit; 778 emac->parent.start = emac_dm9051_start; 779 emac->parent.stop = emac_dm9051_stop; 780 emac->parent.del = emac_dm9051_del; 781 emac->parent.write_phy_reg = emac_dm9051_write_phy_reg; 782 emac->parent.read_phy_reg = emac_dm9051_read_phy_reg; 783 emac->parent.set_addr = emac_dm9051_set_addr; 784 emac->parent.get_addr = emac_dm9051_get_addr; 785 emac->parent.set_speed = emac_dm9051_set_speed; 786 emac->parent.set_duplex = emac_dm9051_set_duplex; 787 emac->parent.set_link = emac_dm9051_set_link; 788 emac->parent.set_promiscuous = emac_dm9051_set_promiscuous; 789 emac->parent.set_peer_pause_ability = emac_dm9051_set_peer_pause_ability; 790 emac->parent.enable_flow_ctrl = emac_dm9051_enable_flow_ctrl; 791 emac->parent.transmit = emac_dm9051_transmit; 792 emac->parent.receive = emac_dm9051_receive; 793 /* create mutex */ 794 emac->spi_lock = xSemaphoreCreateMutex(); 795 MAC_CHECK(emac->spi_lock, "create lock failed", err, NULL); 796 /* create dm9051 task */ 797 BaseType_t core_num = tskNO_AFFINITY; 798 if (mac_config->flags & ETH_MAC_FLAG_PIN_TO_CORE) { 799 core_num = cpu_hal_get_core_id(); 800 } 801 BaseType_t xReturned = xTaskCreatePinnedToCore(emac_dm9051_task, "dm9051_tsk", mac_config->rx_task_stack_size, emac, 802 mac_config->rx_task_prio, &emac->rx_task_hdl, core_num); 803 MAC_CHECK(xReturned == pdPASS, "create dm9051 task failed", err, NULL); 804 return &(emac->parent); 805 806 err: 807 if (emac) { 808 if (emac->rx_task_hdl) { 809 vTaskDelete(emac->rx_task_hdl); 810 } 811 if (emac->spi_lock) { 812 vSemaphoreDelete(emac->spi_lock); 813 } 814 free(emac); 815 } 816 return ret; 817 }