-
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
driver/w5500: driver for the W5500 ethernet chip #20301
Conversation
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.
Thank you for the driver!
This looks quite good already, just some comments:
drivers/include/w5500.h
Outdated
*/ | ||
enum { | ||
W5500_ERR_BUS = -1, | ||
}; |
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.
Why do you need this?
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 is returned if the device cannot be accessed via I2C bus
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 mean why a custom error code instead something from errno.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.
Ok, I switch to -ENODEV
drivers/include/w5500.h
Outdated
netdev_t netdev; /**< extends the netdev structure */ | ||
w5500_params_t p; /**< device configuration parameters */ | ||
uint16_t frame_size_to_be_send; | ||
uint16_t frame_size_sent; |
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.
Why would they differ?
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.
My understanding of confirm_send is that this function can be called at any time to get the number of transmitted bytes of the current frame:
- called before a new transmission is started (frame_size_to_be_send = 0): return the transferred size of the previous frame (frame_size_sent)
- called after the new transmission has been started and is still in progress (frame_size_sent = 0): return -EAGAIN
- called after the new transmission terminated -> see 1.
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 think the intention here was that this would only be called after the transmission and that the beginning of a new transmission would invalidate it (returns -EAGAIN
).
So there is no need to store the size of the previous transmission.
But @maribu should know best.
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.
As @benpicco said:
- Call
send()
, it returns right away, the hardware transmits in background - Wait for transmission to complete
- Call
confirm_send()
exactly once to get the number of transmitted bytes or the error code
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.
Note: The is a provision for trivial polling:
send();
while ((result = confirm_send) == -EAGAIN) {
/* polling for TX to complete */
}
/* transmission result is in result */
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.
Ok, I understand. I thought you might be able to poll the current number of transmitted bytes of the frame while the transmission is still ongoing (the hardware might transmit the frame in chunks, so you could get the number of bytes already transmitted)...
I will change the implementation.
|
||
uint8_t tmp = rreg(dev, REG_PHYCFGR); | ||
|
||
if (tmp & PHY_LINK_UP) { |
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 do you need dev->link_up
for then? It's never read.
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 is read in isr() in order to send NETDEV_EVENT_LINK_UP and NETDEV_EVENT_LINK_DOWN only when the status has 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.
Ah so a change in link status does not cause an interrupt on it's own?
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 could not find a way to trigger an interrupt when the PHY state changes. So I poll it in several places.
b423975
to
63d5c41
Compare
drivers/w5500/w5500.c
Outdated
/* Polling mode: W5500_PARAM_EVT == GPIO_UNDEF and polling_interval_ms > 0u */ | ||
/* Interrupt mode: W5500_PARAM_EVT != GPIO_UNDEF and polling_interval_ms == 0u */ | ||
return((dev->p.evt == GPIO_UNDEF && dev->p.polling_interval_ms > 0u) || | ||
(dev->p.evt != GPIO_UNDEF && dev->p.polling_interval_ms == 0u)); | ||
} |
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'd be a bit more graceful here: You could have a valid polling interval always configured by default, but when a IRQ pin is provided use that instead of polling (and instead of producing an unnecessary error on init).
I can't think of a use case where you would want polling if you have an IRQ pin.
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.
Ok. My intention was to point the user to the invalid configuration, but I have softened the edge now :-) And removed the function.
drivers/w5500/w5500.c
Outdated
tmp = read_register(dev, REG_VERSIONR); | ||
if (tmp != CHIP_VERSION) { | ||
spi_release(dev->p.spi); | ||
LOG_ERROR("[w5500] error: no SPI connection\n"); |
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.
LOG_ERROR("[w5500] error: no SPI connection\n"); | |
LOG_ERROR("[w5500] error: invalid chip ID %x\n", tmp); |
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.
Agreed!
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.
Thanks for the PR :)
First round of comments
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.
Sorry for the delay, some more nits:
spi_clk_t clk; /**< clock speed used on the selected SPI bus */ | ||
gpio_t cs; /**< pin connected to the chip select line */ | ||
gpio_t evt; /**< pin connected to the INT line */ | ||
uint32_t polling_interval_ms; /**< interval for polling, 0 if interrupt mode */ |
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.
Have you considered doing a compile-time check, so we don't even need to compile the polling code in if we have a IRQ pin connected?
uint32_t polling_interval_ms; /**< interval for polling, 0 if interrupt mode */ | |
#if W5500_PARAM_EVT == GPIO_UNDEF | |
uint32_t polling_interval_ms; /**< interval for polling, 0 if interrupt mode */ | |
#endif |
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.
The w5500.h header is independent of the configuration, it does not include w5500_params.h. So I do not have the information W5500_PARAM_IRQ == GPIO_UNDEF available in the header
66f961e
to
a109aec
Compare
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.
Sorry for the delay, I think this driver is fine if it works for you.
Just some small nits, please squash directly.
8801a71
to
2eaebc4
Compare
The changes to the example Makefile still apply 😉 |
2eaebc4
to
6924b62
Compare
Hi @benpicco, could you please help me with the failing release-tests? Where do I find information about the "Invalid access token passed." message? |
The issue is that the new test app fails to link on some boards. The CI stopped building on the first instance, which was the ATmega8. This is expected, as some MCUs (like the ATmega8) just have too little RAM and/or ROM to allow running the app. We manually keep a list of boards that are expected to fail linking in the Note: You might need to run |
You can directly squash the update of the Note: I can also run the script tonight. Building an app 200+ times burns a few CPU cycles (we have a lot of boards supported these days 😎) |
Please tick the checkbox that allow maintainers to edit this PR, otherwise I'm unable to push the |
Or alternatively, store this as
Please also note: The commit message is syntactically incorrect. There is missing a mandatory blank line between the header and the body of the commit message. |
I think you are looking at the right spot in the page. It looks like this for me: Are you logged in? In either case, just storing the content from two messages above in a file named Please don't forget to add a blank line after the header (the first line) in the commit message when you |
I will update the makefile.in later or tomorrow... |
a126323
to
87612aa
Compare
Ok, I added the Makefile.in and modified the commit message... Now fingers crossed :-) |
Mmmh, why is it still being build for the atmega8? And also for other cpus/boards in the insufficient-memory list? |
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.
The list of boards to skip the linking step for should go into Makefile.ci
, not Makefile.in
. Sorry for the confusion.
tests/drivers/w5500/Makefile.ci
Outdated
BOARD_INSUFFICIENT_MEMORY := \ | ||
arduino-duemilanove \ | ||
arduino-leonardo \ | ||
arduino-mega2560 \ | ||
arduino-nano \ | ||
arduino-uno \ | ||
atmega328p \ | ||
atmega328p-xplained-mini \ | ||
bluepill-stm32f030c8 \ | ||
i-nucleo-lrwan1 \ | ||
msb-430 \ | ||
msb-430h \ | ||
nucleo-f030r8 \ | ||
nucleo-f031k6 \ | ||
nucleo-f042k6 \ | ||
nucleo-f303k8 \ | ||
nucleo-f334r8 \ | ||
nucleo-l011k4 \ | ||
nucleo-l031k6 \ | ||
nucleo-l053r8 \ | ||
samd10-xmini \ | ||
slstk3400a \ | ||
stk3200 \ | ||
stm32f030f4-demo \ | ||
stm32f0discovery \ | ||
stm32l0538-disco \ | ||
waspmote-pro \ | ||
# |
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.
BOARD_INSUFFICIENT_MEMORY := \ | |
arduino-duemilanove \ | |
arduino-leonardo \ | |
arduino-mega2560 \ | |
arduino-nano \ | |
arduino-uno \ | |
atmega328p \ | |
atmega328p-xplained-mini \ | |
bluepill-stm32f030c8 \ | |
i-nucleo-lrwan1 \ | |
msb-430 \ | |
msb-430h \ | |
nucleo-f030r8 \ | |
nucleo-f031k6 \ | |
nucleo-f042k6 \ | |
nucleo-f303k8 \ | |
nucleo-f334r8 \ | |
nucleo-l011k4 \ | |
nucleo-l031k6 \ | |
nucleo-l053r8 \ | |
samd10-xmini \ | |
slstk3400a \ | |
stk3200 \ | |
stm32f030f4-demo \ | |
stm32f0discovery \ | |
stm32l0538-disco \ | |
waspmote-pro \ | |
# | |
BOARD_INSUFFICIENT_MEMORY := \ | |
arduino-duemilanove \ | |
arduino-leonardo \ | |
arduino-nano \ | |
arduino-uno \ | |
atmega328p \ | |
atmega328p-xplained-mini \ | |
atmega8 \ | |
nucleo-f031k6 \ | |
nucleo-l011k4 \ | |
samd10-xmini \ | |
stk3200 \ | |
stm32f030f4-demo \ | |
# |
tests/drivers/w5500/Makefile.in
Outdated
@@ -0,0 +1,14 @@ | |||
BOARD_INSUFFICIENT_MEMORY := \ |
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 file should be removed
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.
ok, I will do it later today...
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.
Ok, I have modified the Makefile.ci and removed the Makefile.in (I have added the missing boards to the existing Makefile.ci)... If I had used my brain I could have come up with the idea that the Makefile.ci is the relevant file :-)
- driver can be used with interrupt or in polling mode (default)
It finally is in 🎉 Sometimes it really is a bit of a pain to get a PR past the CI 😦 Thanks a lot for your pull request! |
Yeah :-) I am impressed by the RIOT CI chain, I think it is a great (or maybe the best) way to define what is expected from a piece of software before it can be merged into main. I think it is a bit difficult to keep track of what is missing and how things are handled if you are not working 100% of your time on the Repository, but finally it is in the main!!! |
Contribution description
This is a driver for a WIZ5500 ethernet chip. The driver supports interrupt and polling mode. Polling mode is the default, as plugging the Adafruit Ethernet FeatherWing on the Adafruit nrf52840 Feather requires no additional wiring for the interrupt pin.
Provide a definition for W5500_PARAM_EVT to enable the interrupt mode.
Testing procedure
Build:
make BOARD=feather-nrf52840 -C tests/drivers/w5500/ flash term
Ping ipv6.google.com:
2024-01-26 18:08:37,885 # : This is RIOT! (Version: a74a7-driver_w5500)
2024-01-26 18:08:37,887 # Test application for W5500 ethernet device driver
2024-01-26 18:08:37,889 # All up, running the shell now