22#include "esp_eth_phy_802_3.h" 
   23#include "freertos/FreeRTOS.h" 
   24#include "freertos/task.h" 
   25#include "driver/gpio.h" 
   26#include "esp_rom_gpio.h" 
   27#include "esp_rom_sys.h" 
   28#include "esp_idf_version.h" 
   30#if defined(USE_ARDUINO) || ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 4, 2) 
   32static const char *TAG = 
"jl1101";
 
   33#define PHY_CHECK(a, str, goto_tag, ...) \ 
   36      ESP_LOGE(TAG, "%s(%d): " str, __FUNCTION__, __LINE__, ##__VA_ARGS__); \ 
   49    uint16_t page_select : 8; 
 
   54#define ETH_PHY_PSR_REG_ADDR (0x1F) 
   58  esp_eth_mediator_t *eth;
 
   62  eth_link_t link_status;
 
   66static esp_err_t jl1101_page_select(phy_jl1101_t *jl1101, uint32_t page) {
 
   67  esp_eth_mediator_t *eth = jl1101->eth;
 
   68  psr_reg_t psr = {.page_select = page};
 
   69  PHY_CHECK(eth->phy_reg_write(eth, jl1101->addr, ETH_PHY_PSR_REG_ADDR, psr.val) == ESP_OK, 
"write PSR failed", err);
 
   75static esp_err_t jl1101_update_link_duplex_speed(phy_jl1101_t *jl1101) {
 
   76  esp_eth_mediator_t *eth = jl1101->eth;
 
   77  eth_speed_t 
speed = ETH_SPEED_10M;
 
   78  eth_duplex_t duplex = ETH_DUPLEX_HALF;
 
   83  PHY_CHECK(jl1101_page_select(jl1101, 0) == ESP_OK, 
"select page 0 failed", err);
 
   84  PHY_CHECK(eth->phy_reg_read(eth, jl1101->addr, ETH_PHY_BMSR_REG_ADDR, &(bmsr.val)) == ESP_OK, 
"read BMSR failed",
 
   86  PHY_CHECK(eth->phy_reg_read(eth, jl1101->addr, ETH_PHY_ANLPAR_REG_ADDR, &(anlpar.val)) == ESP_OK,
 
   87            "read ANLPAR failed", err);
 
   88  eth_link_t link = bmsr.link_status ? ETH_LINK_UP : ETH_LINK_DOWN;
 
   90  if (jl1101->link_status != link) {
 
   92    if (link == ETH_LINK_UP) {
 
   93      PHY_CHECK(eth->phy_reg_read(eth, jl1101->addr, ETH_PHY_BMCR_REG_ADDR, &(bmcr.val)) == ESP_OK, 
"read BMCR failed",
 
   95      if (bmcr.speed_select) {
 
   96        speed = ETH_SPEED_100M;
 
   98        speed = ETH_SPEED_10M;
 
  100      if (bmcr.duplex_mode) {
 
  101        duplex = ETH_DUPLEX_FULL;
 
  103        duplex = ETH_DUPLEX_HALF;
 
  105      PHY_CHECK(eth->on_state_changed(eth, ETH_STATE_SPEED, (
void *) 
speed) == ESP_OK, 
"change speed failed", err);
 
  106      PHY_CHECK(eth->on_state_changed(eth, ETH_STATE_DUPLEX, (
void *) duplex) == ESP_OK, 
"change duplex failed", err);
 
  108      if (duplex == ETH_DUPLEX_FULL && anlpar.symmetric_pause) {
 
  109        peer_pause_ability = 1;
 
  111        peer_pause_ability = 0;
 
  113      PHY_CHECK(eth->on_state_changed(eth, ETH_STATE_PAUSE, (
void *) peer_pause_ability) == ESP_OK,
 
  114                "change pause ability failed", err);
 
  116    PHY_CHECK(eth->on_state_changed(eth, ETH_STATE_LINK, (
void *) link) == ESP_OK, 
"change link failed", err);
 
  117    jl1101->link_status = link;
 
  124static esp_err_t jl1101_set_mediator(esp_eth_phy_t *phy, esp_eth_mediator_t *eth) {
 
  125  PHY_CHECK(eth, 
"can't set mediator to null", err);
 
  126  phy_jl1101_t *jl1101 = __containerof(phy, phy_jl1101_t, parent);
 
  130  return ESP_ERR_INVALID_ARG;
 
  133static esp_err_t jl1101_get_link(esp_eth_phy_t *phy) {
 
  134  phy_jl1101_t *jl1101 = __containerof(phy, phy_jl1101_t, parent);
 
  136  PHY_CHECK(jl1101_update_link_duplex_speed(jl1101) == ESP_OK, 
"update link duplex speed failed", err);
 
  142static esp_err_t jl1101_reset(esp_eth_phy_t *phy) {
 
  143  phy_jl1101_t *jl1101 = __containerof(phy, phy_jl1101_t, parent);
 
  144  jl1101->link_status = ETH_LINK_DOWN;
 
  145  esp_eth_mediator_t *eth = jl1101->eth;
 
  146  bmcr_reg_t bmcr = {.reset = 1};
 
  147  PHY_CHECK(eth->phy_reg_write(eth, jl1101->addr, ETH_PHY_BMCR_REG_ADDR, bmcr.val) == ESP_OK, 
"write BMCR failed", err);
 
  150  for (to = 0; to < jl1101->reset_timeout_ms / 50; to++) {
 
  151    vTaskDelay(pdMS_TO_TICKS(50));
 
  152    PHY_CHECK(eth->phy_reg_read(eth, jl1101->addr, ETH_PHY_BMCR_REG_ADDR, &(bmcr.val)) == ESP_OK, 
"read BMCR failed",
 
  158  PHY_CHECK(to < jl1101->reset_timeout_ms / 50, 
"reset timeout", err);
 
  164static esp_err_t jl1101_reset_hw(esp_eth_phy_t *phy) {
 
  165  phy_jl1101_t *jl1101 = __containerof(phy, phy_jl1101_t, parent);
 
  166  if (jl1101->reset_gpio_num >= 0) {
 
  167    esp_rom_gpio_pad_select_gpio(jl1101->reset_gpio_num);
 
  168    gpio_set_direction(jl1101->reset_gpio_num, GPIO_MODE_OUTPUT);
 
  169    gpio_set_level(jl1101->reset_gpio_num, 0);
 
  170    esp_rom_delay_us(100);  
 
  171    gpio_set_level(jl1101->reset_gpio_num, 1);
 
  176static esp_err_t jl1101_negotiate(esp_eth_phy_t *phy, eth_phy_autoneg_cmd_t cmd, 
bool *nego_state) {
 
  177  phy_jl1101_t *jl1101 = __containerof(phy, phy_jl1101_t, parent);
 
  178  esp_eth_mediator_t *eth = jl1101->eth;
 
  180  jl1101->link_status = ETH_LINK_DOWN;
 
  186      .restart_auto_nego = 1 
 
  188  PHY_CHECK(eth->phy_reg_write(eth, jl1101->addr, ETH_PHY_BMCR_REG_ADDR, bmcr.val) == ESP_OK, 
"write BMCR failed", err);
 
  192  for (to = 0; to < jl1101->autonego_timeout_ms / 100; to++) {
 
  193    vTaskDelay(pdMS_TO_TICKS(100));
 
  194    PHY_CHECK(eth->phy_reg_read(eth, jl1101->addr, ETH_PHY_BMSR_REG_ADDR, &(bmsr.val)) == ESP_OK, 
"read BMSR failed",
 
  196    if (bmsr.auto_nego_complete) {
 
  201  if (to >= jl1101->autonego_timeout_ms / 100) {
 
  202    ESP_LOGW(TAG, 
"auto negotiation timeout");
 
  209static esp_err_t jl1101_pwrctl(esp_eth_phy_t *phy, 
bool enable) {
 
  210  phy_jl1101_t *jl1101 = __containerof(phy, phy_jl1101_t, parent);
 
  211  esp_eth_mediator_t *eth = jl1101->eth;
 
  213  PHY_CHECK(eth->phy_reg_read(eth, jl1101->addr, ETH_PHY_BMCR_REG_ADDR, &(bmcr.val)) == ESP_OK, 
"read BMCR failed",
 
  222  PHY_CHECK(eth->phy_reg_write(eth, jl1101->addr, ETH_PHY_BMCR_REG_ADDR, bmcr.val) == ESP_OK, 
"write BMCR failed", err);
 
  224    PHY_CHECK(eth->phy_reg_read(eth, jl1101->addr, ETH_PHY_BMCR_REG_ADDR, &(bmcr.val)) == ESP_OK, 
"read BMCR failed",
 
  226    PHY_CHECK(bmcr.power_down == 1, 
"power down failed", err);
 
  230    for (to = 0; to < jl1101->reset_timeout_ms / 10; to++) {
 
  231      vTaskDelay(pdMS_TO_TICKS(10));
 
  232      PHY_CHECK(eth->phy_reg_read(eth, jl1101->addr, ETH_PHY_BMCR_REG_ADDR, &(bmcr.val)) == ESP_OK, 
"read BMCR failed",
 
  234      if (bmcr.power_down == 0) {
 
  238    PHY_CHECK(to < jl1101->reset_timeout_ms / 10, 
"power up timeout", err);
 
  245static esp_err_t jl1101_set_addr(esp_eth_phy_t *phy, uint32_t addr) {
 
  246  phy_jl1101_t *jl1101 = __containerof(phy, phy_jl1101_t, parent);
 
  251static esp_err_t jl1101_get_addr(esp_eth_phy_t *phy, uint32_t *addr) {
 
  252  PHY_CHECK(addr, 
"addr can't be null", err);
 
  253  phy_jl1101_t *jl1101 = __containerof(phy, phy_jl1101_t, parent);
 
  254  *addr = jl1101->addr;
 
  257  return ESP_ERR_INVALID_ARG;
 
  260static esp_err_t jl1101_del(esp_eth_phy_t *phy) {
 
  261  phy_jl1101_t *jl1101 = __containerof(phy, phy_jl1101_t, parent);
 
  266static esp_err_t jl1101_advertise_pause_ability(esp_eth_phy_t *phy, uint32_t ability) {
 
  267  phy_jl1101_t *jl1101 = __containerof(phy, phy_jl1101_t, parent);
 
  268  esp_eth_mediator_t *eth = jl1101->eth;
 
  271  PHY_CHECK(eth->phy_reg_read(eth, jl1101->addr, ETH_PHY_ANAR_REG_ADDR, &(anar.val)) == ESP_OK, 
"read ANAR failed",
 
  274    anar.asymmetric_pause = 1;
 
  275    anar.symmetric_pause = 1;
 
  277    anar.asymmetric_pause = 0;
 
  278    anar.symmetric_pause = 0;
 
  280  PHY_CHECK(eth->phy_reg_write(eth, jl1101->addr, ETH_PHY_ANAR_REG_ADDR, anar.val) == ESP_OK, 
"write ANAR failed", err);
 
  286static esp_err_t jl1101_init(esp_eth_phy_t *phy) {
 
  287  phy_jl1101_t *jl1101 = __containerof(phy, phy_jl1101_t, parent);
 
  288  esp_eth_mediator_t *eth = jl1101->eth;
 
  290  if (jl1101->addr == ESP_ETH_PHY_ADDR_AUTO) {
 
  291    PHY_CHECK(esp_eth_phy_802_3_detect_phy_addr(eth, &jl1101->addr) == ESP_OK, 
"Detect PHY address failed", err);
 
  294  PHY_CHECK(jl1101_pwrctl(phy, 
true) == ESP_OK, 
"power control failed", err);
 
  296  PHY_CHECK(jl1101_reset(phy) == ESP_OK, 
"reset failed", err);
 
  300  PHY_CHECK(eth->phy_reg_read(eth, jl1101->addr, ETH_PHY_IDR1_REG_ADDR, &(id1.val)) == ESP_OK, 
"read ID1 failed", err);
 
  301  PHY_CHECK(eth->phy_reg_read(eth, jl1101->addr, ETH_PHY_IDR2_REG_ADDR, &(id2.val)) == ESP_OK, 
"read ID2 failed", err);
 
  302  PHY_CHECK(id1.oui_msb == 0x937C && id2.oui_lsb == 0x10 && id2.vendor_model == 0x2, 
"wrong chip ID", err);
 
  308static esp_err_t jl1101_deinit(esp_eth_phy_t *phy) {
 
  310  PHY_CHECK(jl1101_pwrctl(phy, 
false) == ESP_OK, 
"power control failed", err);
 
  317  PHY_CHECK(config, 
"can't set phy config to null", err);
 
  318  phy_jl1101_t *jl1101 = calloc(1, 
sizeof(phy_jl1101_t));
 
  319  PHY_CHECK(jl1101, 
"calloc jl1101 failed", err);
 
  320  jl1101->addr = config->phy_addr;
 
  321  jl1101->reset_gpio_num = config->reset_gpio_num;
 
  322  jl1101->reset_timeout_ms = config->reset_timeout_ms;
 
  323  jl1101->link_status = ETH_LINK_DOWN;
 
  324  jl1101->autonego_timeout_ms = config->autonego_timeout_ms;
 
  325  jl1101->parent.reset = jl1101_reset;
 
  326  jl1101->parent.reset_hw = jl1101_reset_hw;
 
  327  jl1101->parent.init = jl1101_init;
 
  328  jl1101->parent.deinit = jl1101_deinit;
 
  329  jl1101->parent.set_mediator = jl1101_set_mediator;
 
  330  jl1101->parent.autonego_ctrl = jl1101_negotiate;
 
  331  jl1101->parent.get_link = jl1101_get_link;
 
  332  jl1101->parent.pwrctl = jl1101_pwrctl;
 
  333  jl1101->parent.get_addr = jl1101_get_addr;
 
  334  jl1101->parent.set_addr = jl1101_set_addr;
 
  335  jl1101->parent.advertise_pause_ability = jl1101_advertise_pause_ability;
 
  336  jl1101->parent.del = jl1101_del;
 
  338  return &(jl1101->parent);
 
 
esp_eth_phy_t * esp_eth_phy_new_jl1101(const eth_phy_config_t *config)