-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
stm32f4 eth peripheral driver #5643
Conversation
What external hardware is required to use this with an STM32F4 Discovery? I guess it needs an Ethernet PHY? |
Mmm maybe it's not especially for STM32F4Discovery but for STM32F4 in general, look at this board |
@gebart A PHY is not required. One could connect i.e. RMII-RMII as a bord-interconnect, allowing high data throughput. In case a PHY is used, all PHYs have common registers and vendor/model registers. This driver configures the common one regarding duplex and provides an standard interface to read/write registers from/to the PHY. AFAIK all This means: it's not board dependent and requires no extra specific hardware. It has been tested with and without PHY. |
@@ -3,7 +3,7 @@ export CPU = stm32f4 | |||
export CPU_MODEL = stm32f407vg | |||
|
|||
# set default port depending on operating system | |||
PORT_LINUX ?= /dev/ttyUSB0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
unrelated change?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know is not related to the PR. I could open a different one if you prefer :-)
Rationale:
This board appears as ttyACM0
not as ttyUSB0
in my machine the same as most Nucleo boards I've tried. I'm not sure this is kernel or distribution dependent (tried on Ubuntu [kernel 3.13] and arch [kernel 4.4]) or were remaining of board copy-paste.
Updated to use DMA to copy to TX buffers |
@OlegHahm @kaspar030 @gebart how should we proceed here? |
@lebrush The uncrustify and serial changes should go into a seperate cleanup PR. |
@kaspar030 done |
Added a generic Ethernet PHY interface: only read and write registers as well as common register definitions. |
@kaspar030, ping! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice PR, I have only minor comments. (and unfortunately no hardware to test this).
Do you think it makes sense to have this extra peripheral interface, instead of just using netdev2?
cpu/stm32f4/periph/eth.c
Outdated
|
||
switch (opt) { | ||
case NETOPT_ADDRESS: | ||
if (max_len >= ETHERNET_ADDR_LEN) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here, please use assert.
cpu/stm32f4/periph/eth.c
Outdated
|
||
switch (opt) { | ||
case NETOPT_ADDRESS: | ||
if (max_len >= ETHERNET_ADDR_LEN) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would fail silently. Until now we used asserts for checking the length.
cpu/stm32f4/periph/eth.c
Outdated
|
||
int ret = 0, len = 0; | ||
mutex_lock(&send_lock); | ||
for (int i = 0; i < count && ret == 0; i++) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
doesn't eth_send() return != 0 even on success?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It returns the amount of bytes transmitted or -1 in case of error. Since netdev expect to return the amount of bytes transmitted is kind of practical to do it like this. In any case I added a condition in _send
to make sure we don't ignore an error an pass it to netdev.
cpu/stm32f4/periph/eth.c
Outdated
|
||
#include "cpu.h" | ||
#include "mutex.h" | ||
#include "cib.h" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's this used for?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mmm... it's always nice to have unused includes... good catch, will remove ;-)
cpu/stm32f4/periph/eth.c
Outdated
typedef struct eth_dma_desc edma_desc_t; | ||
|
||
/** Update pointer to next descriptor */ | ||
#define _next_desc(x) x = (x->desc_next) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would you mind removing this macro? We're trying to not use macros when possible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
cpu/stm32f4/periph/eth.c
Outdated
return 0; | ||
} | ||
|
||
static int eth_send(char *data, unsigned len) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can data be "const char *"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
@kaspar030 sorry for the delay in the response. I think it makes sense to have it as a netdev2 and not as a separate device since it's OSI layer 2 device and integrates quite nicely with lwip :-) |
@kaspar030 @OlegHahm ping! |
Oops, sorry. Will investigate if I can access the hardware to test. |
Can you rebase? I think some nucleo boards include this is it? |
@kYc0o done |
@kYc0o, I think you can try with a nucleo144-f207. If you want to test, I have one with me (but you'll need to adapt the config). |
Any reason why you didn't test it with GNRC? ;-) |
Not really... we needed a solution with ipv4 and lwip was the way to go.
Unfortunately, I won't be able to drive this any further and I don't have
hardware to test it. Someone else should take over.
|
needs adoption by someone, remove milestone until then. |
I have some hardware with me (from home) so I can test it and maybe we can merge? |
@MrKevinWeiss did you try some testing? ... we should get this done after years, I guess ;) |
I tried but many things need to get adapted after the years, it will require a bit of work to get it up to speed. |
@MrKevinWeiss can you name the things that require adaptation? |
Unfortunately, I've not the hardware anymore but I'll be happy to review it |
@MrKevinWeiss if you have the hardware for testing I can help you with the code. @lebrush is it okay for you that we take this over to get it merged? |
@smlng Sure thing, unfortunately this is low in the priorities list but if you can get it done quick I will run it through the tests and close it off! |
@smlng guide code adaption first? |
I already looked into, it's a bit of work to adapt this to the official DMA interface - but manageable. |
O.K. then good to manage @smlng |
@smlng ping |
Hi All, I just ported this PR to work with the current riot master branch and to use it with the F7 nucleo family. (F767ZI to be specific). I was also able to use gnrc instead of lwip as a network stack and run a small test (icmp and udp echo). I would like to adopt this PR since @lebrush is not working on it anymore. If this is fine for you please answer the following questions and i will try to push this further :)
What i have done so far:
Regards Robin |
By now it stays as a peripheral but i moved the code from the f4 speicific folder to the stm32_common folder
I just added a dynamic macaddr config using luid_get from the luid module in case the configured mac address starts with 0 in the first byte. (according to rfc7042 this region is reserved and thus should be safe to use) |
@crest42 Very nice. I think I looked at this a while back and it ended up being a non-trivial rebase. I think @smlng discovered that too. I think it would be nice to open a new PR (and give whatever credit/reference @lebrush) so that we could review it (especially if you have it working on current master). |
@crest42 nice to hear that. As @MrKevinWeiss already mentioned, I tried my luck with this one, too ... however the main problem was, that I didn't have the board originally used here for testing. It seems there are several differences between the various STM Nucleos with ethernet, i.e. pinout and DMA stream used. Anyway, you can either open a PR or point us your branch so we can have look at your work and discuss how to proceed. Certainly it would be good to utilise the now available DMA API instead of making it hardcoded for the ethernet device. If you have a proper netdev integration all the layers above should come in for "free". |
+1, I think this is the way to go. Feel free to open a new PR so we can review it and test. Thanks for great work! |
Thanks for the fast Feedback. I already put everything in a consumable form. Since i working on top of @lebrush commits anyways credits should be included :) I will open a PR later in the evening and add the open tasks/questions to it. |
Opend #10633 and added a few comments. It would be great if someone could guide me a little bit with my questions :) |
Let's close this then in favor of #10633 |
This is a working stm32f4 ethernet peripheral driver. It has been tested with
lwIP
and works like a charm.I didn't create any header because I'm not sure how to abstract it. I see that there are possibly three public methods:
void eth_netdev_setup(netdev2_t *netdev)
void eth_phy_write(unsigned addr, unsigned reg, unsigned value)
unsigned eth_phy_read(unsigned addr, unsigned reg)
and I'm wondering if it would make sense to create a common header file as for all the peripheral drivers (
periph/eth.h
). The header file could expose these methods. Maybe something to do is to define as well a typeeth_t
for handling multiple of this devices, but I'm not sure that currently an MCU can support multiple eth peripherals.Opinions? Feedback?