-
Notifications
You must be signed in to change notification settings - Fork 7.1k
/
esp_eth.h
316 lines (293 loc) · 13.3 KB
/
esp_eth.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
// Copyright 2019 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.
#pragma once
#include "esp_eth_com.h"
#include "esp_eth_mac.h"
#include "esp_eth_phy.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Handle of Ethernet driver
*
*/
typedef void *esp_eth_handle_t;
/**
* @brief Configuration of Ethernet driver
*
*/
typedef struct {
/**
* @brief Ethernet MAC object
*
*/
esp_eth_mac_t *mac;
/**
* @brief Ethernet PHY object
*
*/
esp_eth_phy_t *phy;
/**
* @brief Period time of checking Ethernet link status
*
*/
uint32_t check_link_period_ms;
/**
* @brief Input frame buffer to user's stack
*
* @param[in] eth_handle: handle of Ethernet driver
* @param[in] buffer: frame buffer that will get input to upper stack
* @param[in] length: length of the frame buffer
*
* @return
* - ESP_OK: input frame buffer to upper stack successfully
* - ESP_FAIL: error occurred when inputting buffer to upper stack
*
*/
esp_err_t (*stack_input)(esp_eth_handle_t eth_handle, uint8_t *buffer, uint32_t length, void *priv);
/**
* @brief Callback function invoked when lowlevel initialization is finished
*
* @param[in] eth_handle: handle of Ethernet driver
*
* @return
* - ESP_OK: process extra lowlevel initialization successfully
* - ESP_FAIL: error occurred when processing extra lowlevel initialization
*/
esp_err_t (*on_lowlevel_init_done)(esp_eth_handle_t eth_handle);
/**
* @brief Callback function invoked when lowlevel deinitialization is finished
*
* @param[in] eth_handle: handle of Ethernet driver
*
* @return
* - ESP_OK: process extra lowlevel deinitialization successfully
* - ESP_FAIL: error occurred when processing extra lowlevel deinitialization
*/
esp_err_t (*on_lowlevel_deinit_done)(esp_eth_handle_t eth_handle);
/**
* @brief Read PHY register
*
* @note Usually the PHY register read/write function is provided by MAC (SMI interface),
* but if the PHY device is managed by other interface (e.g. I2C), then user needs to
* implement the corresponding read/write.
* Setting this to NULL means your PHY device is managed by MAC's SMI interface.
*
* @param[in] eth_handle: handle of Ethernet driver
* @param[in] phy_addr: PHY chip address (0~31)
* @param[in] phy_reg: PHY register index code
* @param[out] reg_value: PHY register value
*
* @return
* - ESP_OK: read PHY register successfully
* - ESP_ERR_INVALID_ARG: read PHY register failed because of invalid argument
* - ESP_ERR_TIMEOUT: read PHY register failed because of timeout
* - ESP_FAIL: read PHY register failed because some other error occurred
*/
esp_err_t (*read_phy_reg)(esp_eth_handle_t eth_handle, uint32_t phy_addr, uint32_t phy_reg, uint32_t *reg_value);
/**
* @brief Write PHY register
*
* @note Usually the PHY register read/write function is provided by MAC (SMI interface),
* but if the PHY device is managed by other interface (e.g. I2C), then user needs to
* implement the corresponding read/write.
* Setting this to NULL means your PHY device is managed by MAC's SMI interface.
*
* @param[in] eth_handle: handle of Ethernet driver
* @param[in] phy_addr: PHY chip address (0~31)
* @param[in] phy_reg: PHY register index code
* @param[in] reg_value: PHY register value
*
* @return
* - ESP_OK: write PHY register successfully
* - ESP_ERR_INVALID_ARG: read PHY register failed because of invalid argument
* - ESP_ERR_TIMEOUT: write PHY register failed because of timeout
* - ESP_FAIL: write PHY register failed because some other error occurred
*/
esp_err_t (*write_phy_reg)(esp_eth_handle_t eth_handle, uint32_t phy_addr, uint32_t phy_reg, uint32_t reg_value);
} esp_eth_config_t;
/**
* @brief Default configuration for Ethernet driver
*
*/
#define ETH_DEFAULT_CONFIG(emac, ephy) \
{ \
.mac = emac, \
.phy = ephy, \
.check_link_period_ms = 2000, \
.stack_input = NULL, \
.on_lowlevel_init_done = NULL, \
.on_lowlevel_deinit_done = NULL, \
.read_phy_reg = NULL, \
.write_phy_reg = NULL, \
}
/**
* @brief Install Ethernet driver
*
* @param[in] config: configuration of the Ethernet driver
* @param[out] out_hdl: handle of Ethernet driver
*
* @return
* - ESP_OK: install esp_eth driver successfully
* - ESP_ERR_INVALID_ARG: install esp_eth driver failed because of some invalid argument
* - ESP_ERR_NO_MEM: install esp_eth driver failed because there's no memory for driver
* - ESP_FAIL: install esp_eth driver failed because some other error occurred
*/
esp_err_t esp_eth_driver_install(const esp_eth_config_t *config, esp_eth_handle_t *out_hdl);
/**
* @brief Uninstall Ethernet driver
* @note It's not recommended to uninstall Ethernet driver unless it won't get used any more in application code.
* To uninstall Ethernet driver, you have to make sure, all references to the driver are released.
* Ethernet driver can only be uninstalled successfully when reference counter equals to one.
*
* @param[in] hdl: handle of Ethernet driver
*
* @return
* - ESP_OK: uninstall esp_eth driver successfully
* - ESP_ERR_INVALID_ARG: uninstall esp_eth driver failed because of some invalid argument
* - ESP_ERR_INVALID_STATE: uninstall esp_eth driver failed because it has more than one reference
* - ESP_FAIL: uninstall esp_eth driver failed because some other error occurred
*/
esp_err_t esp_eth_driver_uninstall(esp_eth_handle_t hdl);
/**
* @brief Start Ethernet driver **ONLY** in standalone mode (i.e. without TCP/IP stack)
*
* @note This API will start driver state machine and internal software timer (for checking link status).
*
* @param[in] hdl handle of Ethernet driver
*
* @return
* - ESP_OK: start esp_eth driver successfully
* - ESP_ERR_INVALID_ARG: start esp_eth driver failed because of some invalid argument
* - ESP_ERR_INVALID_STATE: start esp_eth driver failed because driver has started already
* - ESP_FAIL: start esp_eth driver failed because some other error occurred
*/
esp_err_t esp_eth_start(esp_eth_handle_t hdl);
/**
* @brief Stop Ethernet driver
*
* @note This function does the oppsite operation of `esp_eth_start`.
*
* @param[in] hdl handle of Ethernet driver
* @return
* - ESP_OK: stop esp_eth driver successfully
* - ESP_ERR_INVALID_ARG: stop esp_eth driver failed because of some invalid argument
* - ESP_ERR_INVALID_STATE: stop esp_eth driver failed because driver has not started yet
* - ESP_FAIL: stop esp_eth driver failed because some other error occurred
*/
esp_err_t esp_eth_stop(esp_eth_handle_t hdl);
/**
* @brief Update Ethernet data input path (i.e. specify where to pass the input buffer)
*
* @note After install driver, Ethernet still don't know where to deliver the input buffer.
* In fact, this API registers a callback function which get invoked when Ethernet received new packets.
*
* @param[in] hdl handle of Ethernet driver
* @param[in] stack_input function pointer, which does the actual process on incoming packets
* @param[in] priv private resource, which gets passed to `stack_input` callback without any modification
* @return
* - ESP_OK: update input path successfully
* - ESP_ERR_INVALID_ARG: update input path failed because of some invalid argument
* - ESP_FAIL: update input path failed because some other error occurred
*/
esp_err_t esp_eth_update_input_path(
esp_eth_handle_t hdl,
esp_err_t (*stack_input)(esp_eth_handle_t hdl, uint8_t *buffer, uint32_t length, void *priv),
void *priv);
/**
* @brief General Transmit
*
* @param[in] hdl: handle of Ethernet driver
* @param[in] buf: buffer of the packet to transfer
* @param[in] length: length of the buffer to transfer
*
* @return
* - ESP_OK: transmit frame buffer successfully
* - ESP_ERR_INVALID_ARG: transmit frame buffer failed because of some invalid argument
* - ESP_FAIL: transmit frame buffer failed because some other error occurred
*/
esp_err_t esp_eth_transmit(esp_eth_handle_t hdl, void *buf, size_t length);
/**
* @brief General Receive is deprecated and shall not be accessed from app code,
* as polling is not supported by Ethernet.
*
* @param[in] hdl: handle of Ethernet driver
* @param[out] buf: buffer to preserve the received packet
* @param[out] length: length of the received packet
*
* @note Before this function got invoked, the value of "length" should set by user, equals the size of buffer.
* After the function returned, the value of "length" means the real length of received data.
* @note This API was exposed by accident, users should not use this API in their applications.
* Ethernet driver is interrupt driven, and doesn't support polling mode.
* Instead, users should register input callback with ``esp_eth_update_input_path``.
*
* @return
* - ESP_OK: receive frame buffer successfully
* - ESP_ERR_INVALID_ARG: receive frame buffer failed because of some invalid argument
* - ESP_ERR_INVALID_SIZE: input buffer size is not enough to hold the incoming data.
* in this case, value of returned "length" indicates the real size of incoming data.
* - ESP_FAIL: receive frame buffer failed because some other error occurred
*/
esp_err_t esp_eth_receive(esp_eth_handle_t hdl, uint8_t *buf, uint32_t *length) __attribute__((deprecated("Ethernet driver is interrupt driven only, please register input callback with esp_eth_update_input_path")));
/**
* @brief Misc IO function of Etherent driver
*
* @param[in] hdl: handle of Ethernet driver
* @param[in] cmd: IO control command
* @param[in, out] data: address of data for `set` command or address where to store the data when used with `get` command
*
* @return
* - ESP_OK: process io command successfully
* - ESP_ERR_INVALID_ARG: process io command failed because of some invalid argument
* - ESP_FAIL: process io command failed because some other error occurred
*
* The following IO control commands are supported:
* @li @c ETH_CMD_S_MAC_ADDR sets Ethernet interface MAC address. @c data argument is pointer to MAC address buffer with expected size of 6 bytes.
* @li @c ETH_CMD_G_MAC_ADDR gets Ethernet interface MAC address. @c data argument is pointer to a buffer to which MAC address is to be copied. The buffer size must be at least 6 bytes.
* @li @c ETH_CMD_S_PHY_ADDR sets PHY address in range of <0-31>. @c data argument is pointer to memory of uint32_t datatype from where the configuration option is read.
* @li @c ETH_CMD_G_PHY_ADDR gets PHY address. @c data argument is pointer to memory of uint32_t datatype to which the PHY address is to be stored.
* @li @c ETH_CMD_G_SPEED gets current Ethernet link speed. @c data argument is pointer to memory of eth_speed_t datatype to which the speed is to be stored.
* @li @c ETH_CMD_S_PROMISCUOUS sets/resets Ethernet interface promiscuous mode. @c data argument is pointer to memory of bool datatype from which the configuration option is read.
* @li @c ETH_CMD_S_FLOW_CTRL sets/resets Ethernet interface flow control. @c data argument is pointer to memory of bool datatype from which the configuration option is read.
* @li @c ETH_CMD_G_DUPLEX_MODE gets current Ethernet link duplex mode. @c data argument is pointer to memory of eth_duplex_t datatype to which the duplex mode is to be stored.
* @li @c ETH_CMD_S_PHY_LOOPBACK sets/resets PHY to/from loopback mode. @c data argument is pointer to memory of bool datatype from which the configuration option is read.
*
*/
esp_err_t esp_eth_ioctl(esp_eth_handle_t hdl, esp_eth_io_cmd_t cmd, void *data);
/**
* @brief Increase Ethernet driver reference
* @note Ethernet driver handle can be obtained by os timer, netif, etc.
* It's dangerous when thread A is using Ethernet but thread B uninstall the driver.
* Using reference counter can prevent such risk, but care should be taken, when you obtain Ethernet driver,
* this API must be invoked so that the driver won't be uninstalled during your using time.
*
*
* @param[in] hdl: handle of Ethernet driver
* @return
* - ESP_OK: increase reference successfully
* - ESP_ERR_INVALID_ARG: increase reference failed because of some invalid argument
*/
esp_err_t esp_eth_increase_reference(esp_eth_handle_t hdl);
/**
* @brief Decrease Ethernet driver reference
*
* @param[in] hdl: handle of Ethernet driver
* @return
* - ESP_OK: increase reference successfully
* - ESP_ERR_INVALID_ARG: increase reference failed because of some invalid argument
*/
esp_err_t esp_eth_decrease_reference(esp_eth_handle_t hdl);
#ifdef __cplusplus
}
#endif