|
|
@@ -1,26 +1,70 @@
|
|
|
-
|
|
|
+// Copyright 2015-2017 Espressif Systems (Shanghai) PTE LTD
|
|
|
+//
|
|
|
+// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
+// you may not use this file except in compliance with the License.
|
|
|
+// You may obtain a copy of the License at
|
|
|
+
|
|
|
+// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
+//
|
|
|
+// Unless required by applicable law or agreed to in writing, software
|
|
|
+// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
+// See the License for the specific language governing permissions and
|
|
|
+// limitations under the License.
|
|
|
#include "esp_attr.h"
|
|
|
#include "esp_log.h"
|
|
|
#include "esp_eth.h"
|
|
|
|
|
|
-#include "tlk110_phy.h"
|
|
|
+#include "eth_phy/phy_tlk110.h"
|
|
|
+#include "eth_phy/phy_reg.h"
|
|
|
|
|
|
-#define DEFAULT_PHY_CONFIG (AUTO_MDIX_ENABLE|AUTO_NEGOTIATION_ENABLE|AN_1|AN_0|LED_CFG)
|
|
|
-void phy_dump_tlk110_registers();
|
|
|
+#include "freertos/FreeRTOS.h"
|
|
|
+#include "freertos/task.h"
|
|
|
|
|
|
-static const char *TAG = "tlk110";
|
|
|
+/* Value of MII_PHY_IDENTIFIER_REG for TI TLK110,
|
|
|
+ Excluding bottom 4 bytes of ID2, used for model revision
|
|
|
+ */
|
|
|
+#define TLK110_PHY_ID1 0x2000
|
|
|
+#define TLK110_PHY_ID2 0xa210
|
|
|
+
|
|
|
+/* TLK110-specific registers */
|
|
|
+#define SW_STRAP_CONTROL_REG (0x9)
|
|
|
+#define SW_STRAP_CONFIG_DONE BIT(15)
|
|
|
+#define AUTO_MDIX_ENABLE BIT(14)
|
|
|
+#define AUTO_NEGOTIATION_ENABLE BIT(13)
|
|
|
+#define AN_1 BIT(12)
|
|
|
+#define AN_0 BIT(11)
|
|
|
+#define LED_CFG BIT(10)
|
|
|
+#define RMII_ENHANCED_MODE BIT(9)
|
|
|
+
|
|
|
+#define DEFAULT_STRAP_CONFIG (AUTO_MDIX_ENABLE|AUTO_NEGOTIATION_ENABLE|AN_1|AN_0|LED_CFG)
|
|
|
+
|
|
|
+#define PHY_STATUS_REG (0x10)
|
|
|
+#define AUTO_NEGOTIATION_STATUS BIT(4)
|
|
|
+#define DUPLEX_STATUS BIT(2)
|
|
|
+#define SPEED_STATUS BIT(1)
|
|
|
+
|
|
|
+#define CABLE_DIAGNOSTIC_CONTROL_REG (0x1e)
|
|
|
+#define DIAGNOSTIC_DONE BIT(1)
|
|
|
|
|
|
+#define PHY_RESET_CONTROL_REG (0x1f)
|
|
|
+#define SOFTWARE_RESET BIT(15)
|
|
|
+
|
|
|
+static const char *TAG = "tlk110";
|
|
|
|
|
|
void phy_tlk110_check_phy_init(void)
|
|
|
{
|
|
|
- phy_dump_tlk110_registers();
|
|
|
-
|
|
|
- while((esp_eth_smi_read(BASIC_MODE_STATUS_REG) & AUTO_NEGOTIATION_COMPLETE ) != AUTO_NEGOTIATION_COMPLETE)
|
|
|
- {};
|
|
|
- while((esp_eth_smi_read(PHY_STATUS_REG) & AUTO_NEGTIATION_STATUS ) != AUTO_NEGTIATION_STATUS)
|
|
|
- {};
|
|
|
- while((esp_eth_smi_read(CABLE_DIAGNOSTIC_CONTROL_REG) & DIAGNOSTIC_DONE ) != DIAGNOSTIC_DONE)
|
|
|
- {};
|
|
|
+ phy_tlk110_dump_registers();
|
|
|
+
|
|
|
+ while((esp_eth_smi_read(MII_BASIC_MODE_STATUS_REG) & MII_AUTO_NEGOTIATION_COMPLETE ) == 0) {
|
|
|
+ vTaskDelay(1);
|
|
|
+ }
|
|
|
+ while((esp_eth_smi_read(PHY_STATUS_REG) & AUTO_NEGOTIATION_STATUS ) == 0) {
|
|
|
+ vTaskDelay(1);
|
|
|
+ }
|
|
|
+ while((esp_eth_smi_read(CABLE_DIAGNOSTIC_CONTROL_REG) & DIAGNOSTIC_DONE ) == 0) {
|
|
|
+ vTaskDelay(1);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
eth_speed_mode_t phy_tlk110_get_speed_mode(void)
|
|
|
@@ -38,74 +82,65 @@ eth_duplex_mode_t phy_tlk110_get_duplex_mode(void)
|
|
|
{
|
|
|
if((esp_eth_smi_read(PHY_STATUS_REG) & DUPLEX_STATUS ) == DUPLEX_STATUS) {
|
|
|
ESP_LOGD(TAG, "phy_tlk110_get_duplex_mode(FULL)");
|
|
|
- return ETH_MDOE_FULLDUPLEX;
|
|
|
+ return ETH_MODE_FULLDUPLEX;
|
|
|
} else {
|
|
|
ESP_LOGD(TAG, "phy_tlk110_get_duplex_mode(HALF)");
|
|
|
return ETH_MODE_HALFDUPLEX;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-bool phy_tlk110_check_phy_link_status(void)
|
|
|
+void phy_tlk110_power_enable(bool enable)
|
|
|
{
|
|
|
- if ((esp_eth_smi_read(BASIC_MODE_STATUS_REG) & LINK_STATUS) == LINK_STATUS) {
|
|
|
- ESP_LOGD(TAG, "phy_tlk110_check_phy_link_status(UP)");
|
|
|
- return true;
|
|
|
- } else {
|
|
|
- ESP_LOGD(TAG, "phy_tlk110_check_phy_link_status(DOWN)");
|
|
|
- return false;
|
|
|
- }
|
|
|
-}
|
|
|
+ if (enable) {
|
|
|
+ esp_eth_smi_write(SW_STRAP_CONTROL_REG, DEFAULT_STRAP_CONFIG | SW_STRAP_CONFIG_DONE);
|
|
|
|
|
|
-bool phy_tlk110_get_partner_pause_enable(void)
|
|
|
-{
|
|
|
- if((esp_eth_smi_read(PHY_LINK_PARTNER_ABILITY_REG) & PARTNER_PAUSE) == PARTNER_PAUSE) {
|
|
|
- ESP_LOGD(TAG, "phy_tlk110_get_partner_pause_enable(TRUE)");
|
|
|
- return true;
|
|
|
- } else {
|
|
|
- ESP_LOGD(TAG, "phy_tlk110_get_partner_pause_enable(FALSE)");
|
|
|
- return false;
|
|
|
+ // TODO: only do this if config.flow_ctrl_enable == true
|
|
|
+ phy_mii_enable_flow_ctrl();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-void phy_enable_flow_ctrl(void)
|
|
|
-{
|
|
|
- uint32_t data = 0;
|
|
|
- data = esp_eth_smi_read(AUTO_NEG_ADVERTISEMENT_REG);
|
|
|
- esp_eth_smi_write(AUTO_NEG_ADVERTISEMENT_REG,data|ASM_DIR|PAUSE);
|
|
|
-}
|
|
|
-
|
|
|
void phy_tlk110_init(void)
|
|
|
{
|
|
|
ESP_LOGD(TAG, "phy_tlk110_init()");
|
|
|
- phy_dump_tlk110_registers();
|
|
|
+ phy_tlk110_dump_registers();
|
|
|
|
|
|
esp_eth_smi_write(PHY_RESET_CONTROL_REG, SOFTWARE_RESET);
|
|
|
|
|
|
- while (esp_eth_smi_read(PHY_IDENTIFIER_REG) != OUI_MSB_21TO6_DEF) {
|
|
|
- }
|
|
|
+ unsigned phy_id1, phy_id2;
|
|
|
+ do {
|
|
|
+ vTaskDelay(1);
|
|
|
+ phy_id1 = esp_eth_smi_read(MII_PHY_IDENTIFIER_1_REG);
|
|
|
+ phy_id2 = esp_eth_smi_read(MII_PHY_IDENTIFIER_2_REG);
|
|
|
+ ESP_LOGD(TAG, "PHY ID 0x%04x 0x%04x", phy_id1, phy_id2);
|
|
|
+ phy_id2 &= 0xFFF0; // Remove model revision code
|
|
|
+ } while (phy_id1 != TLK110_PHY_ID1 && phy_id2 != TLK110_PHY_ID2);
|
|
|
|
|
|
- esp_eth_smi_write(SOFTWARE_STRAP_CONTROL_REG, DEFAULT_PHY_CONFIG |SW_STRAP_CONFIG_DONE);
|
|
|
+ esp_eth_smi_write(SW_STRAP_CONTROL_REG,
|
|
|
+ DEFAULT_STRAP_CONFIG | SW_STRAP_CONFIG_DONE);
|
|
|
|
|
|
ets_delay_us(300);
|
|
|
|
|
|
- //if config.flow_ctrl_enable == true ,enable this
|
|
|
- phy_enable_flow_ctrl();
|
|
|
+ // TODO: only do this if config.flow_ctrl_enable == true
|
|
|
+ phy_mii_enable_flow_ctrl();
|
|
|
}
|
|
|
|
|
|
-const eth_config_t tlk110_default_ethernet_phy_config = {
|
|
|
- .phy_addr = CONFIG_PHY_ID,
|
|
|
+const eth_config_t phy_tlk110_default_ethernet_config = {
|
|
|
+ // PHY address configured by PHYADx pins. Default value of 0x1
|
|
|
+ // is used if all pins are unconnected.
|
|
|
+ .phy_addr = 0x1,
|
|
|
.mac_mode = ETH_MODE_RMII,
|
|
|
//Only FULLDUPLEX mode support flow ctrl now!
|
|
|
.flow_ctrl_enable = true,
|
|
|
.phy_init = phy_tlk110_init,
|
|
|
.phy_check_init = phy_tlk110_check_phy_init,
|
|
|
- .phy_check_link = phy_tlk110_check_phy_link_status,
|
|
|
+ .phy_check_link = phy_mii_check_link_status,
|
|
|
.phy_get_speed_mode = phy_tlk110_get_speed_mode,
|
|
|
.phy_get_duplex_mode = phy_tlk110_get_duplex_mode,
|
|
|
- .phy_get_partner_pause_enable = phy_tlk110_get_partner_pause_enable
|
|
|
+ .phy_get_partner_pause_enable = phy_mii_get_partner_pause_enable,
|
|
|
+ .phy_power_enable = phy_tlk110_power_enable,
|
|
|
};
|
|
|
|
|
|
-void phy_dump_tlk110_registers()
|
|
|
+void phy_tlk110_dump_registers()
|
|
|
{
|
|
|
ESP_LOGD(TAG, "TLK110 Registers:");
|
|
|
ESP_LOGD(TAG, "BMCR 0x%04x", esp_eth_smi_read(0x0));
|