33
33
#include "esp_idf_version.h"
34
34
35
35
// LAN only for ESP32 (not ESP32S2) and only for ESP-IDF v4.1 and higher
36
- #if ( ESP_IDF_VERSION_MAJOR == 4 ) && ( ESP_IDF_VERSION_MINOR >= 1 ) && ( CONFIG_IDF_TARGET_ESP32 )
36
+ #if MICROPY_PY_NETWORK_LAN
37
37
38
38
#include "esp_eth.h"
39
39
#include "esp_eth_mac.h"
40
40
#include "esp_event.h"
41
41
#include "esp_log.h"
42
42
#include "esp_netif.h"
43
+ #if CONFIG_ETH_USE_SPI_ETHERNET
44
+ #include "driver/spi_master.h"
45
+ #endif
43
46
44
47
#include "modnetwork.h"
45
48
@@ -48,9 +51,11 @@ typedef struct _lan_if_obj_t {
48
51
int if_id ; // MUST BE FIRST to match wlan_if_obj_t
49
52
bool initialized ;
50
53
bool active ;
51
- uint8_t mdc_pin ;
52
- uint8_t mdio_pin ;
54
+ int8_t mdc_pin ;
55
+ int8_t mdio_pin ;
53
56
int8_t phy_power_pin ;
57
+ int8_t phy_cs_pin ;
58
+ int8_t phy_int_pin ;
54
59
uint8_t phy_addr ;
55
60
uint8_t phy_type ;
56
61
esp_eth_phy_t * phy ;
@@ -98,19 +103,22 @@ STATIC mp_obj_t get_lan(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_ar
98
103
}
99
104
100
105
enum { ARG_id , ARG_mdc , ARG_mdio , ARG_power , ARG_phy_addr , ARG_phy_type ,
101
- ARG_ref_clk_mode , ARG_ref_clk };
106
+ ARG_ref_clk_mode , ARG_ref_clk , ARG_spi , ARG_cs , ARG_int };
102
107
static const mp_arg_t allowed_args [] = {
103
108
{ MP_QSTR_id , MP_ARG_OBJ , {.u_obj = mp_const_none } },
104
- { MP_QSTR_mdc , MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_OBJ },
105
- { MP_QSTR_mdio , MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_OBJ },
109
+ { MP_QSTR_mdc , MP_ARG_KW_ONLY | MP_ARG_OBJ , {. u_obj = mp_const_none } },
110
+ { MP_QSTR_mdio , MP_ARG_KW_ONLY | MP_ARG_OBJ , {. u_obj = mp_const_none } },
106
111
{ MP_QSTR_power , MP_ARG_KW_ONLY | MP_ARG_OBJ , {.u_obj = mp_const_none } },
107
112
{ MP_QSTR_phy_addr , MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_INT },
108
113
{ MP_QSTR_phy_type , MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_INT },
109
- // Dynamic ref_clk configuration available at v4.4
110
114
#if ESP_IDF_VERSION_MINOR >= 4
115
+ // Dynamic ref_clk configuration available at v4.4
111
116
{ MP_QSTR_ref_clk_mode , MP_ARG_KW_ONLY | MP_ARG_INT , {.u_int = -1 } },
112
117
{ MP_QSTR_ref_clk , MP_ARG_KW_ONLY | MP_ARG_OBJ , {.u_obj = mp_const_none } },
113
118
#endif
119
+ { MP_QSTR_spi , MP_ARG_KW_ONLY | MP_ARG_OBJ , {.u_obj = mp_const_none } },
120
+ { MP_QSTR_cs , MP_ARG_KW_ONLY | MP_ARG_OBJ , {.u_obj = mp_const_none } },
121
+ { MP_QSTR_int , MP_ARG_KW_ONLY | MP_ARG_OBJ , {.u_obj = mp_const_none } },
114
122
};
115
123
116
124
mp_arg_val_t args [MP_ARRAY_SIZE (allowed_args )];
@@ -122,9 +130,13 @@ STATIC mp_obj_t get_lan(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_ar
122
130
}
123
131
}
124
132
125
- self -> mdc_pin = machine_pin_get_id (args [ARG_mdc ].u_obj );
126
- self -> mdio_pin = machine_pin_get_id (args [ARG_mdio ].u_obj );
127
- self -> phy_power_pin = args [ARG_power ].u_obj == mp_const_none ? -1 : machine_pin_get_id (args [ARG_power ].u_obj );
133
+ #define GET_PIN (XXX ) args[XXX].u_obj == mp_const_none ? -1 : machine_pin_get_id(args[XXX].u_obj);
134
+
135
+ self -> mdc_pin = GET_PIN (ARG_mdc );
136
+ self -> mdio_pin = GET_PIN (ARG_mdio );
137
+ self -> phy_power_pin = GET_PIN (ARG_power );
138
+ self -> phy_cs_pin = GET_PIN (ARG_cs );
139
+ self -> phy_int_pin = GET_PIN (ARG_int );
128
140
129
141
if (args [ARG_phy_addr ].u_int < 0x00 || args [ARG_phy_addr ].u_int > 0x1f ) {
130
142
mp_raise_ValueError (MP_ERROR_TEXT ("invalid phy address" ));
@@ -138,13 +150,24 @@ STATIC mp_obj_t get_lan(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_ar
138
150
#if ESP_IDF_VERSION_MINOR >= 3 // KSZ8041 is new in ESP-IDF v4.3
139
151
args [ARG_phy_type ].u_int != PHY_KSZ8041 &&
140
152
#endif
153
+ #if CONFIG_ETH_USE_SPI_ETHERNET
154
+ #if CONFIG_ETH_SPI_ETHERNET_KSZ8851SNL
155
+ args [ARG_phy_type ].u_int != PHY_KSZ8851SNL &&
156
+ #endif
157
+ #if CONFIG_ETH_SPI_ETHERNET_DM9051
158
+ args [ARG_phy_type ].u_int != PHY_DM9051 &&
159
+ #endif
160
+ #if CONFIG_ETH_SPI_ETHERNET_W5500
161
+ args [ARG_phy_type ].u_int != PHY_W5500 &&
162
+ #endif
163
+ #endif
141
164
args [ARG_phy_type ].u_int != PHY_DP83848 ) {
142
165
mp_raise_ValueError (MP_ERROR_TEXT ("invalid phy type" ));
143
166
}
144
167
145
168
eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG ();
146
- mac_config . smi_mdc_gpio_num = self -> mdc_pin ;
147
- mac_config . smi_mdio_gpio_num = self -> mdio_pin ;
169
+ esp_eth_mac_t * mac = NULL ;
170
+
148
171
// Dynamic ref_clk configuration available at v4.4
149
172
#if ESP_IDF_VERSION_MINOR >= 4
150
173
if (args [ARG_ref_clk_mode ].u_int != -1 ) {
@@ -156,14 +179,46 @@ STATIC mp_obj_t get_lan(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_ar
156
179
mac_config .clock_config .rmii .clock_gpio = machine_pin_get_id (args [ARG_ref_clk ].u_obj );
157
180
}
158
181
#endif
159
- esp_eth_mac_t * mac = esp_eth_mac_new_esp32 (& mac_config );
160
182
161
183
eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG ();
162
184
phy_config .phy_addr = self -> phy_addr ;
163
185
phy_config .reset_gpio_num = self -> phy_power_pin ;
164
186
self -> phy = NULL ;
165
187
188
+ #if CONFIG_ETH_USE_SPI_ETHERNET
189
+ spi_device_handle_t spi_handle = NULL ;
190
+ if (IS_SPI_PHY (args [ARG_phy_type ].u_int )) {
191
+ spi_device_interface_config_t devcfg = {
192
+ .mode = 0 ,
193
+ .clock_speed_hz = MICROPY_PY_NETWORK_LAN_SPI_CLOCK_SPEED_MZ * 1000 * 1000 ,
194
+ .queue_size = 20 ,
195
+ .spics_io_num = self -> phy_cs_pin ,
196
+ };
197
+ switch (args [ARG_phy_type ].u_int ) {
198
+ #if CONFIG_ETH_SPI_ETHERNET_DM9051
199
+ case PHY_DM9051 : {
200
+ devcfg .command_bits = 1 ;
201
+ devcfg .address_bits = 7 ;
202
+ break ;
203
+ }
204
+ #endif
205
+ #if CONFIG_ETH_SPI_ETHERNET_W5500
206
+ case PHY_W5500 : {
207
+ devcfg .command_bits = 16 ;
208
+ devcfg .address_bits = 8 ;
209
+ break ;
210
+ }
211
+ #endif
212
+ }
213
+ spi_host_device_t host = machine_hw_spi_get_host (args [ARG_spi ].u_obj );
214
+ if (spi_bus_add_device (host , & devcfg , & spi_handle ) != ESP_OK ) {
215
+ mp_raise_msg (& mp_type_OSError , MP_ERROR_TEXT ("spi_bus_add_device failed" ));
216
+ }
217
+ }
218
+ #endif
219
+
166
220
switch (args [ARG_phy_type ].u_int ) {
221
+ #if CONFIG_IDF_TARGET_ESP32
167
222
case PHY_LAN8710 :
168
223
case PHY_LAN8720 :
169
224
self -> phy = esp_eth_phy_new_lan8720 (& phy_config );
@@ -177,15 +232,54 @@ STATIC mp_obj_t get_lan(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_ar
177
232
case PHY_DP83848 :
178
233
self -> phy = esp_eth_phy_new_dp83848 (& phy_config );
179
234
break ;
235
+ #if ESP_IDF_VERSION_MINOR >= 3 // KSZ8041 is new in ESP-IDF v4.3
180
236
case PHY_KSZ8041 :
181
- #if ESP_IDF_VERSION_MINOR >= 3 // KSZ8041 is new in ESP-IDF v4.3
182
237
self -> phy = esp_eth_phy_new_ksz8041 (& phy_config );
183
238
break ;
184
- #endif
185
- default :
186
- mp_raise_ValueError (MP_ERROR_TEXT ("unknown phy" ));
239
+ #endif
240
+ #endif
241
+ #if CONFIG_ETH_USE_SPI_ETHERNET
242
+ #if CONFIG_ETH_SPI_ETHERNET_KSZ8851SNL
243
+ case PHY_KSZ8851SNL : {
244
+ eth_ksz8851snl_config_t chip_config = ETH_KSZ8851SNL_DEFAULT_CONFIG (spi_handle );
245
+ chip_config .int_gpio_num = self -> phy_int_pin ;
246
+ mac = esp_eth_mac_new_ksz8851snl (& chip_config , & mac_config );
247
+ self -> phy = esp_eth_phy_new_ksz8851snl (& phy_config );
248
+ break ;
249
+ }
250
+ #endif
251
+ #if CONFIG_ETH_SPI_ETHERNET_DM9051
252
+ case PHY_DM9051 : {
253
+ eth_dm9051_config_t chip_config = ETH_DM9051_DEFAULT_CONFIG (spi_handle );
254
+ chip_config .int_gpio_num = self -> phy_int_pin ;
255
+ mac = esp_eth_mac_new_dm9051 (& chip_config , & mac_config );
256
+ self -> phy = esp_eth_phy_new_dm9051 (& phy_config );
257
+ break ;
258
+ }
259
+ #endif
260
+ #if CONFIG_ETH_SPI_ETHERNET_W5500
261
+ case PHY_W5500 : {
262
+ eth_w5500_config_t chip_config = ETH_W5500_DEFAULT_CONFIG (spi_handle );
263
+ chip_config .int_gpio_num = self -> phy_int_pin ;
264
+ mac = esp_eth_mac_new_w5500 (& chip_config , & mac_config );
265
+ self -> phy = esp_eth_phy_new_w5500 (& phy_config );
266
+ break ;
267
+ }
268
+ #endif
269
+ #endif
187
270
}
188
271
272
+ #if CONFIG_IDF_TARGET_ESP32
273
+ if (!IS_SPI_PHY (args [ARG_phy_type ].u_int )) {
274
+ if (self -> mdc_pin == -1 || self -> mdio_pin == -1 ) {
275
+ mp_raise_ValueError (MP_ERROR_TEXT ("mdc and mdio must be specified" ));
276
+ }
277
+ mac_config .smi_mdc_gpio_num = self -> mdc_pin ;
278
+ mac_config .smi_mdio_gpio_num = self -> mdio_pin ;
279
+ mac = esp_eth_mac_new_esp32 (& mac_config );
280
+ }
281
+ #endif
282
+
189
283
if (esp_netif_init () != ESP_OK ) {
190
284
mp_raise_msg (& mp_type_OSError , MP_ERROR_TEXT ("esp_netif_init failed" ));
191
285
}
0 commit comments