Skip to content
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

Closed
wants to merge 6 commits into from
Closed

Conversation

lebrush
Copy link
Member

@lebrush lebrush commented Jul 14, 2016

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 type eth_t for handling multiple of this devices, but I'm not sure that currently an MCU can support multiple eth peripherals.

Opinions? Feedback?

@jnohlgard
Copy link
Member

What external hardware is required to use this with an STM32F4 Discovery? I guess it needs an Ethernet PHY?

@kYc0o
Copy link
Contributor

kYc0o commented Jul 16, 2016

Mmm maybe it's not especially for STM32F4Discovery but for STM32F4 in general, look at this board

@OlegHahm OlegHahm added Platform: ARM Platform: This PR/issue effects ARM-based platforms Area: drivers Area: Device drivers labels Jul 16, 2016
@lebrush
Copy link
Member Author

lebrush commented Jul 18, 2016

@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 stm32fxy7 should have a ETH peripheral (maybe as the stm32fx12 as well, thanks @kYc0o!). The stm32f4discovery features a 407 :-)

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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unrelated change?

Copy link
Member Author

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.

@lebrush
Copy link
Member Author

lebrush commented Aug 3, 2016

Updated to use DMA to copy to TX buffers

@lebrush
Copy link
Member Author

lebrush commented Aug 3, 2016

@OlegHahm @kaspar030 @gebart how should we proceed here?

@kaspar030
Copy link
Contributor

@lebrush The uncrustify and serial changes should go into a seperate cleanup PR.

@lebrush
Copy link
Member Author

lebrush commented Aug 3, 2016

@kaspar030 done

@lebrush
Copy link
Member Author

lebrush commented Sep 6, 2016

Added a generic Ethernet PHY interface: only read and write registers as well as common register definitions.

@OlegHahm
Copy link
Member

@kaspar030, ping!

Copy link
Contributor

@kaspar030 kaspar030 left a 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?


switch (opt) {
case NETOPT_ADDRESS:
if (max_len >= ETHERNET_ADDR_LEN) {
Copy link
Contributor

@kaspar030 kaspar030 Sep 24, 2016

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.


switch (opt) {
case NETOPT_ADDRESS:
if (max_len >= ETHERNET_ADDR_LEN) {
Copy link
Contributor

@kaspar030 kaspar030 Sep 24, 2016

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.


int ret = 0, len = 0;
mutex_lock(&send_lock);
for (int i = 0; i < count && ret == 0; i++) {
Copy link
Contributor

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?

Copy link
Member Author

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.


#include "cpu.h"
#include "mutex.h"
#include "cib.h"
Copy link
Contributor

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?

Copy link
Member Author

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 ;-)

typedef struct eth_dma_desc edma_desc_t;

/** Update pointer to next descriptor */
#define _next_desc(x) x = (x->desc_next)
Copy link
Contributor

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.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

return 0;
}

static int eth_send(char *data, unsigned len)
Copy link
Contributor

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 *"?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@lebrush
Copy link
Member Author

lebrush commented Nov 11, 2016

@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 :-)

@lebrush
Copy link
Member Author

lebrush commented Nov 28, 2016

@kaspar030 @OlegHahm ping!

@OlegHahm
Copy link
Member

OlegHahm commented Dec 8, 2016

Oops, sorry. Will investigate if I can access the hardware to test.

@kYc0o
Copy link
Contributor

kYc0o commented Mar 3, 2017

Can you rebase? I think some nucleo boards include this is it?

@lebrush
Copy link
Member Author

lebrush commented Mar 6, 2017

@kYc0o done

@aabadie
Copy link
Contributor

aabadie commented Mar 6, 2017

@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).

@Tenderson
Copy link

Tenderson commented Oct 11, 2017

Hi @lebrush , @aabadie ,

I tried the latest RIOT master with the gnrc_networking example with Nucleo 144-f429, however the ifconfig is still not working. Shall i wait for merging, oder?

@miri64
Copy link
Member

miri64 commented Nov 14, 2017

It has been tested with lwIP and works like a charm.

Any reason why you didn't test it with GNRC? ;-)

@lebrush
Copy link
Member Author

lebrush commented Nov 15, 2017 via email

@smlng
Copy link
Member

smlng commented Jan 12, 2018

needs adoption by someone, remove milestone until then.

@smlng smlng removed this from the Release 2018.01 milestone Jan 12, 2018
@MrKevinWeiss
Copy link
Contributor

I have some hardware with me (from home) so I can test it and maybe we can merge?

@tcschmidt
Copy link
Member

@MrKevinWeiss did you try some testing? ... we should get this done after years, I guess ;)

@MrKevinWeiss
Copy link
Contributor

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.

@tcschmidt
Copy link
Member

@MrKevinWeiss can you name the things that require adaptation?
@lebrush would you take up then?

@lebrush
Copy link
Member Author

lebrush commented Jun 3, 2018

Unfortunately, I've not the hardware anymore but I'll be happy to review it

@smlng
Copy link
Member

smlng commented Jun 4, 2018

@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?

@MrKevinWeiss
Copy link
Contributor

@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!

@tcschmidt
Copy link
Member

@smlng guide code adaption first?

@smlng
Copy link
Member

smlng commented Jun 11, 2018

I already looked into, it's a bit of work to adapt this to the official DMA interface - but manageable.

@tcschmidt
Copy link
Member

tcschmidt commented Jul 4, 2018

bit of work ,,, but manageable.

O.K. then good to manage @smlng

@tcschmidt
Copy link
Member

@smlng ping

@crest42
Copy link
Contributor

crest42 commented Dec 15, 2018

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 :)

  1. What are the blockers? In the last messages there was something about an adaption to an official DMA Interface. Can i do something to help you there?
  2. What is the "best" way to implement this as a network driver. As a peripheral driver as in the original work or as a netdev driver under drivers/ ?
  3. How should i commit my work? Open a new PR or can i push my additional stuff on this PR somehow?
  4. Does it make sense to add this network interface as a default interface for the nucleo boards with on board ethernet to make the usage easier?
  5. Does it make sense to rewrite the hardcoded macaddr to something more dynamic?

What i have done so far:

  1. Rework the example from lwip to gnrc
  2. Update the driver to match the new vendor header definitions für nucleo boards
  3. Update the driver to use iolist instead of iovec (a little bit hacky but i will fix this)
  4. Add Support for f7 family
  5. Testing on the f7 family

Regards Robin

@crest42
Copy link
Contributor

crest42 commented Dec 15, 2018

What is the "best" way to implement this as a network driver. As a peripheral driver as in the original work or as a netdev driver under drivers/ ?

By now it stays as a peripheral but i moved the code from the f4 speicific folder to the stm32_common folder

Does it make sense to rewrite the hardcoded macaddr to something more dynamic?

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)

@MrKevinWeiss
Copy link
Contributor

@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).

@smlng
Copy link
Member

smlng commented Dec 17, 2018

@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".

@aabadie
Copy link
Contributor

aabadie commented Dec 17, 2018

By now it stays as a peripheral but i moved the code from the f4 speicific folder to the stm32_common folder

+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!

@crest42
Copy link
Contributor

crest42 commented Dec 17, 2018

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.

@crest42
Copy link
Contributor

crest42 commented Dec 18, 2018

Opend #10633 and added a few comments. It would be great if someone could guide me a little bit with my questions :)

@miri64
Copy link
Member

miri64 commented Dec 18, 2018

Let's close this then in favor of #10633

@miri64 miri64 closed this Dec 18, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: drivers Area: Device drivers Platform: ARM Platform: This PR/issue effects ARM-based platforms State: waiting for other PR State: The PR requires another PR to be merged first
Projects
None yet
Development

Successfully merging this pull request may close these issues.