Working on port to SODAQ Autonomo (SAMD21)

Hi,

This is a heads up to let you know I'm working on a port of RIOT to SODAQ Autonomo, which has an Atmel samd21 (like Arduino Zero).

First I moved the existing cpu/samd21 tree to cpu/samr21. Then I added the samd21 CMSIS files from Arduino and the board files for the SODAQ Autonomo. For that, I copied several files from samr21-xpro.

In the process I learned how to use the Atmel-ICE and how to debug via openocd. Nice :slight_smile:

At the moment I can step through the hello world example. But I have no idea where the output is going. That's my next challenge.

Meanwhile the changes and additions are available in my fork at

     git@github.com:keestux/RIOT-OS

Branch sodaq-autonomo.

Hi Kees,

nice to see your interest in RIOT! Find some comments inline.

Hi,

This is a heads up to let you know I'm working on a port of RIOT to SODAQ Autonomo, which has an Atmel samd21 (like Arduino Zero).

First I moved the existing cpu/samd21 tree to cpu/samr21. Then

Why? Well *if* there is a need to change the current RIOT code base, you should open a separate PR for that.

This is a question to all: How comes the Atmel samr21-xplained pro board has "samd21" CPU in RIOT?

I added the samd21 CMSIS files from Arduino and the board files for the SODAQ Autonomo. For that, I copied several files from samr21-xpro.

What was wrong with current CMSIS headers?

In the process I learned how to use the Atmel-ICE and how to debug via openocd. Nice :slight_smile:

Yepp :slight_smile:

At the moment I can step through the hello world example. But I have no idea where the output is going. That's my next challenge.

By default the STDIO is mapped to UART_DEV(0) which will generally be the first device defined in the periph_conf.h file of the board. E.g.:

The driver used should be common for samX21 MCUs but is currently not.

https://github.com/RIOT-OS/RIOT/blob/master/cpu/samd21/periph/uart.c

For Kinetis there already is a great code reusability:

https://github.com/RIOT-OS/RIOT/tree/master/cpu/kinetis_common/periph

However, you could try to set up a different STDIO UART device and connect an external UART/USB converter to see if it's about conflicting pins.

Meanwhile the changes and additions are available in my fork at

     git@github.com:keestux/RIOT-OS

Branch sodaq-autonomo.

Best Peter

Hey Peter,

In [1] (Page 9) you can see that the samd21 is the actual microprocessor, while the atsamr21XXXX contains the samd21+transceiver. So I guess it has probably something to do with that (:

Cheers, Cenk

[1] http://www.atmel.com/Images/Atmel-42223–SAM-R21_Summary.pdf

Hi Cenk,

not 100% sure but probably it is related :-)! Thanks for pointing that out. IMO the naming is a bit weird though...

Best Peter

Hey,

Hi,

I was just confused when going through different board- and MCU data sheets on Atmel's website. RIOTs naming scheme is fine after understanding the constellations.

Best Peter

Hi!

Hi Kees,

Hi Peter,

nice to see your interest in RIOT! Find some comments inline.

Hi,

This is a heads up to let you know I'm working on a port of RIOT to SODAQ Autonomo, which has an Atmel samd21 (like Arduino Zero).

First I moved the existing cpu/samd21 tree to cpu/samr21. Then

Why? Well *if* there is a need to change the current RIOT code base, you should open a separate PR for that.

That seems like a good aproach, but I asked a related question before and I was stuck with the answer. The answer was something like: the samr21 processor is the same as the samd21, so for RIOT that's good enough.

This is a question to all: How comes the Atmel samr21-xplained pro board has "samd21" CPU in RIOT?

I don't know the history of how it was added. I like to understand what happened when cpu/samd21 was added. Where did the files come from? I'm guessing they're from ASF 3.18 or 3.19. ASF => Atmel Software Framework

I added the samd21 CMSIS files from Arduino and the board files for the SODAQ Autonomo. For that, I copied several files from samr21-xpro.

What was wrong with current CMSIS headers?

RIOT/cpu/samd21/include at master · RIOT-OS/RIOT · GitHub

Well, these files are from the samr21 tree in ASF, yes samr21, not samd21

SAMR21 and SAMD21 have the same cpu. But there are tens of derivatives. The differences are in memory size (RAM, ROM), peripherals, etc. So if you select a board, you also want to select the particular flavor of the SAMx21.

Another issue here is maintenance. How do we want to follow upgrades from Atmel? New cpu variants, bug fixes, etc. The best would be to have the files in RIOT as close as possible to the original. And a description somewhere how to do an upgrade.

To answer the question why I wanted to move cpu/samd21 to cpu/samr21, it is basically driven by the need for SAMD21J18A.

In the process I learned how to use the Atmel-ICE and how to debug via openocd. Nice :slight_smile:

Yepp :slight_smile:

At the moment I can step through the hello world example. But I have no idea where the output is going. That's my next challenge.

By default the STDIO is mapped to UART_DEV(0) which will generally be the first device defined in the periph_conf.h file of the board. E.g.:

RIOT/boards/samr21-xpro/include/periph_conf.h at master · RIOT-OS/RIOT · GitHub

The driver used should be common for samX21 MCUs but is currently not.

https://github.com/RIOT-OS/RIOT/blob/master/cpu/samd21/periph/uart.c

For Kinetis there already is a great code reusability:

https://github.com/RIOT-OS/RIOT/tree/master/cpu/kinetis_common/periph

However, you could try to set up a different STDIO UART device and connect an external UART/USB converter to see if it's about conflicting pins.

That is more or less already what I did. I filled in uart_config with two devices and I have a serial line connect to my PC. This configuration works with the Arduino setup. But not yet with RIOT.

Hey Kaspar,

You added initial commit for saml21. Do you remember the origin of the saml21 include files?

And now that we mention it, shouldn't we think about a structure that would nicely fit SAMD21, SAML21 and SAMR21? And move common stuff in cpu/sam21_common?

Hi Kees,

honestly just now I got your actual problem and I remember what I stumbled upon this morning:

# define the cpu used by SAMR21 Xplained Pro board export CPU = samd21 export CPU_MODEL = samr21x18a

https://github.com/RIOT-OS/RIOT/blob/master/boards/samr21-xpro/Makefile.include

However, I won't say "for RIOT that's good enough". To summarize: The main questions are (i) how to split different CPUs/MCUs with rather small differences and (ii) how to reuse most of the code. Right? For (ii) it would obviously be the best way to have drivers and stuff in the common folder. Personally I have no idea if this is possible or not, it depends on the differences. If these are too big, one needs to stay with a separate CPU folder for each "family". For (i) won't it be enough to export the CPU_MODEL by the board and adjust the include paths properly, as done e.g. here?

https://github.com/RIOT-OS/RIOT/blob/master/cpu/stm32f3/include/cpu_conf.h#L27

One other question is the need for changing the CPU name of the Atmel samr21-xpro board from "samd21" to "samr21". In your regards I think it could make sense but with a solution as described in (i) above, there won't be a need for that. Do I see that correctly?

Generally I'm not too much into Atmels product series and I would like to hear Kaspar's opinion as he knows RIOTs architecture much better than me.

Best Peter

I almost gave up ..., but then ...

�main(): This is RIOT! (Version: 2016.07-devel-191-g42127-rapper-sodaq-autonomo) Hello World! You are running RIOT on a(n) sodaq-autonomo board. This board features a(n) samd21 MCU.

Yeah, it's working. Well, hello world is. (( It's getting too late now. I'll explain later this week what was needed to make it work. ))

Congrats! Looking forward to hear the trick that did it :-).

Good night Peter

Hi Kees,

honestly just now I got your actual problem and I remember what I stumbled upon this morning:

# define the cpu used by SAMR21 Xplained Pro board export CPU = samd21 export CPU_MODEL = samr21x18a

RIOT/boards/samr21-xpro/Makefile.include at master · RIOT-OS/RIOT · GitHub

However, I won't say "for RIOT that's good enough". To summarize: The main questions are (i) how to split different CPUs/MCUs with rather small differences and (ii) how to reuse most of the code. Right?

Correct.

For (ii) it would obviously be the best way to have drivers and stuff in the common folder. Personally I have no idea if this is possible or not, it depends on the differences. If these are too big, one needs to stay with a separate CPU folder for each "family".

Yes, that is certainly possible. All these SAM devices can be handled with a common code base. Someone already started such a common place: cpu/sam21_common. We should continue with that.

If you ask me, I'd say that already a lot of files from cpu/samd21/periph can be moved to cpu/sam21_common.

For (i) won't it be enough to export the CPU_MODEL by the board and adjust the include paths properly, as done e.g. here?

Yes, that is the right thing to do. For Atmel there is one more thing: CFLAGS must have a define like -D__SAMD21J18A__, otherwise the correct include files aren't selected.

https://github.com/RIOT-OS/RIOT/blob/master/cpu/stm32f3/include/cpu_conf.h#L27

One other question is the need for changing the CPU name of the Atmel samr21-xpro board from "samd21" to "samr21". In your regards I think it could make sense but with a solution as described in (i) above, there won't be a need for that. Do I see that correctly?

I don't care too much how the CPU is called. But maybe it is useful to know which CPU variant it is, like SAMD21J18A.

Generally I'm not too much into Atmels product series and I would like to hear Kaspar's opinion as he knows RIOTs architecture much better than me.

I'd be interested to know what Kaspar thinks about it.

As promissed ...

The final change to make it work was selecting the correct "mux". There were a few hardcoded things in * boards/samr21-xpro/include/periph_conf.h * cpu/samd21/periph/uart.c

SAMR21_XPRO has the first serial connected to:    RX - PA5    TX - PA4 static const uart_conf_t uart_config = {      /* device, RX pin, TX pin, mux */      {&SERCOM0->USART, GPIO_PIN(PA,5), GPIO_PIN(PA,4), GPIO_MUX_D},

My SODAQ Autonomo board has the first serial connected to:    RX - PA9    TX - PA10 static const uart_conf_t uart_config = {      /* device, RX pin, TX pin, mux */      {&SERCOM0->USART, GPIO_PIN(PA,9), GPIO_PIN(PA,10), GPIO_MUX_C},

Is that all? No, welcome to the SERCOM world of ARM Cortex M0. In cpu/sam???/periph/uart.c some changes are needed too. In the next diff, the samr21 is the "old" samd21.

--- cpu/samd21/periph/uart.c 2016-06-13 22:41:15.358773522 +0200 +++ cpu/samr21/periph/uart.c 2016-05-31 19:57:02.788554067 +0200 @@ -86,10 +86,9 @@       /* reset the UART device */       dev->CTRLA.reg = SERCOM_USART_CTRLA_SWRST;       while (dev->SYNCBUSY.reg & SERCOM_USART_SYNCBUSY_SWRST) {} - /* set asynchronous mode w/o parity, LSB first, PAD2 to TX, PAD1 to RX, sample rate 16x and + /* set asynchronous mode w/o parity, LSB first, PAD0 to TX, PAD1 to RX and        * use internal clock */       dev->CTRLA.reg = (SERCOM_USART_CTRLA_DORD | - SERCOM_USART_CTRLA_TXPO(0x1) |                         SERCOM_USART_CTRLA_RXPO(0x1) |                         SERCOM_USART_CTRLA_SAMPR(0x1) |                         SERCOM_USART_CTRLA_MODE_USART_INT_CLK);

Notice the TXPO and RXPO. These indicate which "pads" the pin can use on a certain SERCOM. So, what we can learn from this is that we need to expand uart_conf_t. We need PAD configuration too. (BTW, Arduino Core is doing similar things.)

Was this a TL;DR? Sorry about it then. -- Kees

Hi,

Following this thread, I better understand the problems I had when I tried to port RIOT on Arduino/Genuino Zero in [1]. I'll test your changes in cpu/samd21/periph/uart.c to see if they fix them. Note that it uses an Atmel ATSAMD21G18 MCU which is again another variant of samd21.

Alex

[1] https://github.com/RIOT-OS/RIOT/pull/5475

----- Mail original -----

Hi, I'm piping in from the sidelines

The silicon vendors group their soc families with mcu families and board families, making all this somewhat complex. I'd like to reflect this grouping with the naming and grouping in RIOT.

The boards have pretty little in common as boards but they are deeply related via the mcu and/or soc families. This does not need have any automation as the board level peripherals can be individually configured in the board definitions and just needs to follow the vendor naming scheme to identify the boards.

Soc and mcu family relations and naming schemes should be respected as well. The relationships do not need to be elaborately reflected in build automation as just following the naming schemes is enough to tell the reader how they are related.

So basically I'm suggesting a little less automation with more rigor in following the already named names and not renaming existing things with our own naming schemes. Definitely we need some automation but as RIOT is written for a compiler not a build toolkit we should keep the external to source complexity minimal and easy to follow for fresh readers ie. new porters.

I'm personally more familiar with ST and their Nucleo64 family of boards and STM32 family of MCU, so I cannot suggest anything specific detail for this particular discussion.

- t

Hi Kees,

if you volunteer you could start with moving code to samd21_common and open PR(s) for that :-). Seems like a step in the right direction. I personally won't find time for that unfortunately. On our side we could test your PR(s) with the samr21-xpro board and AFAIK Kaspar has a saml21-xpro board.

Regarding the UART issue, could you give some more insights about the pad you want to add to uart_conf_t? I just gave it a quick look into the reference manual

http://www.atmel.com/images/atmel-42181-sam-d21_datasheet.pdf

but on the first sight I didn't see a difference to

http://www.atmel.com/Images/Atmel-42223–SAM-R21_Datasheet.pdf

Best Peter

Hey,

Hey,

Hey!