add SPI ethernet

This commit is contained in:
Philippe G
2021-10-31 14:47:28 -07:00
parent 97ae01b89f
commit 2805629c4b
5 changed files with 180 additions and 61 deletions

View File

@@ -25,10 +25,10 @@
#define CONFIG_AIRPLAY_NAME "ESP32-AirPlay" #define CONFIG_AIRPLAY_NAME "ESP32-AirPlay"
#endif #endif
typedef struct { static EXT_RAM_ATTR struct raop_cb_s {
raop_cmd_vcb_t cmd; raop_cmd_vcb_t cmd;
raop_data_cb_t data; raop_data_cb_t data;
} raop_cb_t; } raop_cbs;
log_level raop_loglevel = lINFO; log_level raop_loglevel = lINFO;
log_level util_loglevel; log_level util_loglevel;
@@ -204,10 +204,8 @@ static bool raop_sink_start(raop_cmd_vcb_t cmd_cb, raop_data_cb_t data_cb) {
* Airplay sink timer handler * Airplay sink timer handler
*/ */
static void raop_start_handler( TimerHandle_t xTimer ) { static void raop_start_handler( TimerHandle_t xTimer ) {
raop_cb_t *cbs = (raop_cb_t*) pvTimerGetTimerID (xTimer); if (raop_sink_start(raop_cbs.cmd, raop_cbs.data)) {
if (raop_sink_start(cbs->cmd, cbs->data)) {
xTimerDelete(xTimer, portMAX_DELAY); xTimerDelete(xTimer, portMAX_DELAY);
free(cbs);
} }
} }
@@ -216,10 +214,9 @@ static void raop_start_handler( TimerHandle_t xTimer ) {
*/ */
void raop_sink_init(raop_cmd_vcb_t cmd_cb, raop_data_cb_t data_cb) { void raop_sink_init(raop_cmd_vcb_t cmd_cb, raop_data_cb_t data_cb) {
if (!raop_sink_start(cmd_cb, data_cb)) { if (!raop_sink_start(cmd_cb, data_cb)) {
raop_cb_t *cbs = (raop_cb_t*) malloc(sizeof(raop_cb_t)); raop_cbs.cmd = cmd_cb;
cbs->cmd = cmd_cb; raop_cbs.data = data_cb;
cbs->data = data_cb; TimerHandle_t timer = xTimerCreate("raopStart", 5000 / portTICK_RATE_MS, pdTRUE, NULL, raop_start_handler);
TimerHandle_t timer = xTimerCreate("raopStart", 1000 / portTICK_RATE_MS, pdTRUE, cbs, raop_start_handler);
xTimerStart(timer, portMAX_DELAY); xTimerStart(timer, portMAX_DELAY);
LOG_INFO( "delaying AirPlay start"); LOG_INFO( "delaying AirPlay start");
} }

View File

@@ -118,7 +118,7 @@ static void set_i2s_pin(char *config, i2s_pin_config_t *pin_config) {
* Get i2s config structure from config string * Get i2s config structure from config string
*/ */
const i2s_platform_config_t * config_get_i2s_from_str(char * dac_config ){ const i2s_platform_config_t * config_get_i2s_from_str(char * dac_config ){
static i2s_platform_config_t i2s_dac_pin = { static EXT_RAM_ATTR i2s_platform_config_t i2s_dac_pin = {
.i2c_addr = -1, .i2c_addr = -1,
.sda= -1, .sda= -1,
.scl = -1, .scl = -1,
@@ -146,16 +146,26 @@ const i2s_platform_config_t * config_get_i2s_from_str(char * dac_config ){
* Get eth config structure from config string * Get eth config structure from config string
*/ */
const eth_config_t * config_get_eth_from_str(char * eth_config ){ const eth_config_t * config_get_eth_from_str(char * eth_config ){
static eth_config_t eth_pin = { static EXT_RAM_ATTR eth_config_t eth_pin = {
.mdc = -1, .rmii = false,
.mdio = -1, .model = "",
.rst = -1,
}; };
char * p=NULL; char * p=NULL;
if ((p = strcasestr(eth_config, "model")) != NULL) sscanf(p, "%*[^=]=%15[^,]", eth_pin.model);
if ((p = strcasestr(eth_config, "mdc")) != NULL) eth_pin.mdc = atoi(strchr(p, '=') + 1); if ((p = strcasestr(eth_config, "mdc")) != NULL) eth_pin.mdc = atoi(strchr(p, '=') + 1);
if ((p = strcasestr(eth_config, "mdio")) != NULL) eth_pin.mdio = atoi(strchr(p, '=') + 1); if ((p = strcasestr(eth_config, "mdio")) != NULL) eth_pin.mdio = atoi(strchr(p, '=') + 1);
if ((p = strcasestr(eth_config, "rst")) != NULL) eth_pin.rst = atoi(strchr(p, '=') + 1); if ((p = strcasestr(eth_config, "rst")) != NULL) eth_pin.rst = atoi(strchr(p, '=') + 1);
if ((p = strcasestr(eth_config, "mosi")) != NULL) eth_pin.mosi = atoi(strchr(p, '=') + 1);
if ((p = strcasestr(eth_config, "miso")) != NULL) eth_pin.miso = atoi(strchr(p, '=') + 1);
if ((p = strcasestr(eth_config, "intr")) != NULL) eth_pin.intr = atoi(strchr(p, '=') + 1);
if ((p = strcasestr(eth_config, "cs")) != NULL) eth_pin.cs = atoi(strchr(p, '=') + 1);
if ((p = strcasestr(eth_config, "speed")) != NULL) eth_pin.speed = atoi(strchr(p, '=') + 1);
if ((p = strcasestr(eth_config, "clk")) != NULL) eth_pin.clk = atoi(strchr(p, '=') + 1);
if ((p = strcasestr(eth_config, "host")) != NULL) eth_pin.host = atoi(strchr(p, '=') + 1);
if (strcasestr(eth_pin.model, "lan8720")) eth_pin.rmii = true;
return &eth_pin; return &eth_pin;
} }
@@ -164,7 +174,7 @@ const eth_config_t * config_get_eth_from_str(char * eth_config ){
*/ */
const i2s_platform_config_t * config_spdif_get( ){ const i2s_platform_config_t * config_spdif_get( ){
char * spdif_config = config_spdif_get_string(); char * spdif_config = config_spdif_get_string();
static i2s_platform_config_t i2s_dac_config; static EXT_RAM_ATTR i2s_platform_config_t i2s_dac_config;
memcpy(&i2s_dac_config, config_get_i2s_from_str(spdif_config), sizeof(i2s_dac_config)); memcpy(&i2s_dac_config, config_get_i2s_from_str(spdif_config), sizeof(i2s_dac_config));
free(spdif_config); free(spdif_config);
return &i2s_dac_config; return &i2s_dac_config;
@@ -175,7 +185,7 @@ const i2s_platform_config_t * config_spdif_get( ){
*/ */
const i2s_platform_config_t * config_dac_get(){ const i2s_platform_config_t * config_dac_get(){
char * spdif_config = get_dac_config_string(); char * spdif_config = get_dac_config_string();
static i2s_platform_config_t i2s_dac_config; static EXT_RAM_ATTR i2s_platform_config_t i2s_dac_config;
memcpy(&i2s_dac_config, config_get_i2s_from_str(spdif_config), sizeof(i2s_dac_config)); memcpy(&i2s_dac_config, config_get_i2s_from_str(spdif_config), sizeof(i2s_dac_config));
free(spdif_config); free(spdif_config);
return &i2s_dac_config; return &i2s_dac_config;
@@ -185,9 +195,19 @@ const i2s_platform_config_t * config_dac_get(){
* Get ethernet config structure * Get ethernet config structure
*/ */
const eth_config_t * config_eth_get( ){ const eth_config_t * config_eth_get( ){
char * config = config_alloc_get_str("eth_config", CONFIG_ETH_CONFIG, "mdc=" STR(CONFIG_MDC_IO) char * config = config_alloc_get_str("eth_config", CONFIG_ETH_CONFIG, "rst=" STR(CONFIG_ETH_PHY_RST_IO)
",mdio=" STR(CONFIG_MDIO_IO) ",do=" STR(CONFIG_PHY_RST_IO)); #if defined(CONFIG_ETH_LAN8720)
static eth_config_t eth_config; ",model=lan8720"
#elif defined(CONFIG_ETH_DM9051)
",model=dm9051"
#endif
",mdc=" STR(CONFIG_ETH_MDC_IO) ",mdio=" STR(CONFIG_ETH_MDIO_IO)
",host=" STR(CONFIG_ETH_SPI_HOST) ",cs=" STR(CONFIG_ETH_SPI_CS_IO)
",mosi=" STR(CONFIG_ETH_SPI_MOSI_IO) ",miso=" STR(CONFIG_ETH_SPI_MISO_IO)
",intr=" STR(CONFIG_ETH_SPI_INTR_IO)
",clk=" STR(CONFIG_ETH_SPI_CLK_IO) ",speed=" STR(CONFIG_ETH_SPI_SPEED) );
static EXT_RAM_ATTR eth_config_t eth_config;
ESP_LOGD(TAG, "Ethernet config string %s", config);
memcpy(&eth_config, config_get_eth_from_str(config), sizeof(eth_config)); memcpy(&eth_config, config_get_eth_from_str(config), sizeof(eth_config));
free(config); free(config);
return &eth_config; return &eth_config;

View File

@@ -31,9 +31,13 @@ typedef struct {
} display_config_t; } display_config_t;
typedef struct { typedef struct {
int mdc; bool rmii;
int mdio; char model[16];
int rst; int rst;
int mdc, mdio;
int host;
int cs, mosi, miso, intr, clk;
int speed;
} eth_config_t; } eth_config_t;
typedef struct { typedef struct {

View File

@@ -295,6 +295,94 @@ static void eth_event_handler(void *arg, esp_event_base_t event_base,
} }
} }
static void eth_init(void) {
esp_eth_mac_t *mac;
esp_eth_phy_t *phy;
esp_err_t err = ESP_OK;
eth_config_t const *eth = config_eth_get( );
// quick check if we have a valid ethernet configuration
if ((eth->mdc == -1 && eth->mosi == -1) || !*eth->model) {
ESP_LOGI(TAG, "No ethernet");
return;
}
tcpip_adapter_set_default_eth_handlers();
esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, &eth_event_handler, NULL);
eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG();
eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG();
phy_config.phy_addr = 1;
phy_config.reset_gpio_num = eth->rst;
if (eth->rmii) {
#ifdef CONFIG_ETH_USE_ESP32_EMAC
mac_config.smi_mdc_gpio_num = eth->mdc;
mac_config.smi_mdio_gpio_num = eth->mdio;
mac = esp_eth_mac_new_esp32(&mac_config);
phy = esp_eth_phy_new_lan8720(&phy_config);
ESP_LOGI(TAG, "Adding ethernet RMII with mdc %d and mdio %d", eth->mdc, eth->mdio);
#else
ESP_LOGE(TAG, "Ethernet RMII set but not included in compilation");
return;
#endif
} else {
#ifdef CONFIG_ETH_SPI_ETHERNET_DM9051
spi_device_handle_t spi_handle = NULL;
spi_host_device_t host = SPI3_HOST;
if (eth->host != -1) {
// don't use system's shared SPI
spi_bus_config_t buscfg = {
.miso_io_num = eth->miso,
.mosi_io_num = eth->mosi,
.sclk_io_num = eth->clk,
.quadwp_io_num = -1,
.quadhd_io_num = -1,
};
// can't use SPI0
if (eth->host == 1) host = SPI2_HOST;
err |= spi_bus_initialize(host, &buscfg, 1);
} else {
// when we use shared SPI, we assume it has been initialized
host = spi_system_host;
}
spi_device_interface_config_t devcfg = {
.command_bits = 1,
.address_bits = 7,
.mode = 0,
.clock_speed_hz = eth->speed,
.spics_io_num = eth->cs,
.queue_size = 20
};
err |= spi_bus_add_device(host, &devcfg, &spi_handle);
// dm9051 ethernet driver is based on spi driver
eth_dm9051_config_t dm9051_config = ETH_DM9051_DEFAULT_CONFIG(spi_handle);
// we assume that isr has been installed already
dm9051_config.int_gpio_num = eth->intr;
mac = esp_eth_mac_new_dm9051(&dm9051_config, &mac_config);
phy = esp_eth_phy_new_dm9051(&phy_config);
ESP_LOGI(TAG, "Adding ethernet SPI on host %d with mosi %d and miso %d", host, eth->mosi, eth->miso);
#else
ESP_LOGE(TAG, "Ethernet SPI set but not included in compilation");
return;
#endif
}
esp_eth_config_t config = ETH_DEFAULT_CONFIG(mac, phy);
esp_eth_handle_t eth_handle = NULL;
err |= esp_eth_driver_install(&config, &eth_handle);
err |= esp_eth_start(eth_handle);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Can't install Ethernet driver %d", err);
}
}
void wifi_manager_init_wifi(){ void wifi_manager_init_wifi(){
/* event handler and event group for the wifi driver */ /* event handler and event group for the wifi driver */
ESP_LOGD(TAG, "Initializing wifi. Creating event group"); ESP_LOGD(TAG, "Initializing wifi. Creating event group");
@@ -317,31 +405,7 @@ void wifi_manager_init_wifi(){
ESP_LOGD(TAG, "Initializing wifi. Starting wifi"); ESP_LOGD(TAG, "Initializing wifi. Starting wifi");
ESP_ERROR_CHECK( esp_wifi_start() ); ESP_ERROR_CHECK( esp_wifi_start() );
//ETH eth_init();
eth_config_t const *eth = config_eth_get( );
ESP_LOGE(TAG, "ETH MDC %d", eth->mdc);
ESP_LOGE(TAG, "ETH MDIO %d", eth->mdio);
ESP_LOGE(TAG, "ETH RST %d", eth->rst);
ESP_ERROR_CHECK(tcpip_adapter_set_default_eth_handlers());
ESP_ERROR_CHECK(esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, &eth_event_handler, NULL));
eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG();
eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG();
phy_config.phy_addr = 1;
phy_config.reset_gpio_num = eth->rst;
mac_config.smi_mdc_gpio_num = eth->mdc;
mac_config.smi_mdio_gpio_num = eth->mdio;
esp_eth_mac_t *mac = esp_eth_mac_new_esp32(&mac_config);
esp_eth_phy_t *phy = esp_eth_phy_new_lan8720(&phy_config);
esp_eth_config_t config = ETH_DEFAULT_CONFIG(mac, phy);
esp_eth_handle_t eth_handle = NULL;
ESP_ERROR_CHECK(esp_eth_driver_install(&config, &eth_handle));
ESP_ERROR_CHECK(esp_eth_start(eth_handle));
//END_ETH
taskYIELD(); taskYIELD();
ESP_LOGD(TAG, "Initializing wifi. done"); ESP_LOGD(TAG, "Initializing wifi. done");

View File

@@ -98,7 +98,7 @@ menu "Squeezelite-ESP32"
default "" default ""
config ETH_CONFIG config ETH_CONFIG
string string
default "" default ""
config DAC_CONTROLSET config DAC_CONTROLSET
string string
default "{ \"init\": [ {\"reg\":41, \"val\":128}, {\"reg\":18, \"val\":255} ], \"poweron\": [ {\"reg\":18, \"val\":64, \"mode\":\"or\"} ], \"poweroff\": [ {\"reg\":18, \"val\":191, \"mode\":\"and\"} ] }" if TWATCH2020 default "{ \"init\": [ {\"reg\":41, \"val\":128}, {\"reg\":18, \"val\":255} ], \"poweron\": [ {\"reg\":18, \"val\":64, \"mode\":\"or\"} ], \"poweroff\": [ {\"reg\":18, \"val\":191, \"mode\":\"and\"} ] }" if TWATCH2020
@@ -107,23 +107,57 @@ menu "Squeezelite-ESP32"
endmenu endmenu
menu "Ethernet Options" menu "Ethernet Options"
visible if BASIC_I2C_BT && ETH_USE_ESP32_EMAC visible if BASIC_I2C_BT && (ETH_USE_ESP32_EMAC || ETH_USE_SPI_ETHERNET)
config ETH_MDC_IO choice
int "SMI MDC GPIO number" prompt "Ethernet Chipset"
default 23 default ETH_NODRIVER
help config ETH_NODRIVER
Set the GPIO number used by SMI MDC. bool "Defined in NVS"
config ETH_MDIO_IO config ETH_LAN8720
int "SMI MDIO GPIO number" bool "Microchip LAN8720 (RMII)"
default 18 config ETH_DM9051
help bool "Davicom 9051 (SPI)"
Set the GPIO number used by SMI MDIO. endchoice
config ETH_PHY_RST_IO config ETH_PHY_RST_IO
int "PHY Reset GPIO number" int "PHY Reset GPIO number" if !ETH_NODRIVER
default 4 default -1
help help
Set the GPIO number used to reset PHY chip. Set the GPIO number used to reset PHY chip.
Set to -1 to disable PHY chip hardware reset. Set to -1 to disable PHY chip hardware reset.
config ETH_MDC_IO
int "SMI MDC GPIO number" if ETH_LAN8720
default -1
help
Set the GPIO number used by SMI MDC.
config ETH_MDIO_IO
int "SMI MDIO GPIO number" if ETH_LAN8720
default -1
help
Set the GPIO number used by SMI MDIO.
config ETH_SPI_HOST
int "SPI host number (-1,1 or 2)" if ETH_DM9051
default -1
help
Set to -1 to use system's SPI config (see Various I/O)
Set to 2 or 3 to use a dedicated bus
config ETH_SPI_INTR_IO
int "interrupt" if ETH_DM9051
default -1
config ETH_SPI_CS_IO
int "Chip Select" if ETH_DM9051
default -1
config ETH_SPI_CLK_IO
int "SPI clock" if ETH_SPI_HOST != -1 && ETH_DM9051
default -1
config ETH_SPI_MOSI_IO
int "Data Out" if ETH_SPI_HOST != -1 && ETH_DM9051
default -1
config ETH_SPI_MISO_IO
int "Data In" if ETH_SPI_HOST != -1 && ETH_DM9051
default -1
config ETH_SPI_SPEED
int "SPI speed (Hz)" if ETH_SPI_HOST != -1 && ETH_DM9051
default 20000000
endmenu endmenu
menu "Audio settings" menu "Audio settings"