Skip to content

cpu/sam0: add support for SAMD5x/SAME5x#11305

Merged
dylad merged 4 commits intoRIOT-OS:masterfrom
benpicco:same54
Jun 6, 2019
Merged

cpu/sam0: add support for SAMD5x/SAME5x#11305
dylad merged 4 commits intoRIOT-OS:masterfrom
benpicco:same54

Conversation

@benpicco
Copy link
Copy Markdown
Contributor

@benpicco benpicco commented Mar 28, 2019

Contribution description

This adds support for the Atmel SAMD51 & SAME54 Cortex M4F MCU from the SAM D5x/E5x family and the SAM E54 Xplained Pro Evaluation Board.

The SAMD5x family shares it's peripherals with other sam0 MCUs like the saml1x on which most of this code is based.

So far, UART, I2C, SPI, Timer, RTC and GPIOs have been tested.

There is an awful lot of copy and paste going on between saml1x/periph and same54/periph with only minor differences in pm.c and timer.c (SAMD5x supports more sleep states and needs to combine two timers to make a 32bit timer).

Testing procedure

Flash an example application (e.g. examples/default or examples/timer_periodic_wakeup) using make BOARD=same54-xpro flash term and observe that the application behaves as expected.

@benpicco
Copy link
Copy Markdown
Contributor Author

@Sizurka found a clever way to automatically generate exti_config from the ASF headers.

I actually used this (with gcc -E) to generate the version used here.

Maybe we can make this common for all sam0 SoCs here too.

@dylad
Copy link
Copy Markdown
Member

dylad commented Mar 28, 2019

@benpicco Nice PR ! I have zero experience with SAM4 but this should not belongs to cpu/sam0
You should rather move it to its own folder and maybe also reuse stuff from cpu/sam_common.

@dylad dylad added Platform: ARM Platform: This PR/issue effects ARM-based platforms Type: new feature The issue requests / The PR implemements a new feature for RIOT labels Mar 28, 2019
@benpicco
Copy link
Copy Markdown
Contributor Author

@dylad I think this has more in common with sam0 than with the older sam parts. saml1x doesn't come with a Cortex-M0+ either, it's pretty much just that but with a Cortex-M4F instead of Cortex-M23.

I feel like the thing that separates the sam0 from the sam is that it comes with the SERCOM peripherals - there are differences in other peripherals too that are different between the sam and the sam0 families but similar across sam0 members, but that's the most prominent difference imho.

@benpicco benpicco force-pushed the same54 branch 2 times, most recently from 8dc03f0 to 23d901e Compare March 29, 2019 12:16
@benpicco benpicco changed the title cpu/sam0: add support for SAME54 cpu/sam0: add support for SAMD5x/SAME5x Mar 29, 2019
@benpicco benpicco marked this pull request as ready for review March 29, 2019 12:49
@benpicco benpicco force-pushed the same54 branch 6 times, most recently from be14127 to b2a9490 Compare March 29, 2019 19:07
while (PM->SLEEPCFG.bit.SLEEPMODE != _mode) {}
}

cortexm_sleep(mode);
Copy link
Copy Markdown
Contributor

@keestux keestux Mar 29, 2019

Choose a reason for hiding this comment

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

There are now four variants of this (see cpu/sam*/periph/pm.c), all have a different approach to call cortexm_sleep. In this implementation it is important to identify that only mode == 0 does a light sleep. The other modes do a deep sleep. I don't see it being documented.

Also the mapping 0->STANDBY, 1->IDLE2, 2->IDLE1, 3->IDLE0 needs explanation or documentation.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Actually all modes but 0 do a light sleep - but just looking at the power consumption, PM_SLEEPCFG_SLEEPMODE_IDLE2 is the default anyway if only cortexm_sleep() is called.

This MCU also supports three deep sleep states (STANDBY, HIBERNATE & BACKUP) but since pm_layered only supports 4 sleep modes (and on all other sam0 boards modes 1-3 are used for light sleep / idle and I wanted to keep the semantics the same), only the deepest one is exposed. The RTC still can wake the MCU in this mode which is good enough for me.

Since all the sam0s expose different sets of sleep states I think the pain of light code duplication is still less than that that of a confusing mess of #ifdefs in a common version.

Copy link
Copy Markdown
Contributor Author

@benpicco benpicco Apr 17, 2019

Choose a reason for hiding this comment

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

Ok, so BACKUP only works if Vbat is connected (but allows to retain some RAM) whereas HIBERNATE always works, so I'm switching to that by default.

Apparently they both work fine, just not right after flashing the device - I have to disconnect the power and reconnect it again after I flash the device, then it's working.

@keestux
Copy link
Copy Markdown
Contributor

keestux commented Mar 29, 2019

The two "sam0_common:" commits should preferably have their own PullRequest. No? Even if this PR depends on it.

@keestux keestux closed this Mar 29, 2019
@keestux keestux reopened this Mar 29, 2019
@keestux
Copy link
Copy Markdown
Contributor

keestux commented Mar 29, 2019

(( Shit, these buttons are too close :-(

@benpicco
Copy link
Copy Markdown
Contributor Author

This keeps puzzling me.
If I source the GCLK5 from e.g. FDPLL1 configured to tun at at 16MHz with prescaler 16, all test run fine and the offset in xtimer_usleep is ~33µs, but this is at the expense of a higher power consumption of around 2 mA.

When I use the 48 MHz DFLL I get

  • Offset: ~4300µs with GCLK_GENCTRL_DIV(12) & TC_CTRLA_PRESCALER_DIV4
  • Offset: ~4300µs with GCLK_GENCTRL_DIV(6) & TC_CTRLA_PRESCALER_DIV8
  • Offset: ~5µs with with GCLK_GENCTRL_DIV(3) & TC_CTRLA_PRESCALER_DIV16 but with bursts of 5000µs

With 120 MHz DPLL0 :

  • Offset: ~5000µs with GCLK_GENCTRL_DIV(120) & TC_CTRLA_PRESCALER_DIV1
  • Offset: ~5000µs with GCLK_GENCTRL_DIV(15) & TC_CTRLA_PRESCALER_DIV8
  • Offset: ~5µs with GCLK_GENCTRL_DIV(4) & TC_CTRLA_PRESCALER_DIV16 but with burst of 4600µs - and the clock is wrong.
  • Offset: 6µs with GCLK_GENCTRL_DIV(2) & TC_CTRLA_PRESCALER_DIV64 - but now the clock is wrong

Only when I overclock the CPU to 128 MHz I get both a stable and correct clock.

@dylad
Copy link
Copy Markdown
Member

dylad commented May 29, 2019

If I source the GCLK5 from e.g. FDPLL1 configured to tun at at 16MHz with prescaler 16, all test run fine and the offset in xtimer_usleep is ~33µs, but this is at the expense of a higher power consumption of around 2 mA.

Enabling a second PLL may not be the best solution especially for the power consumption.

Offset: ~5µs with GCLK_GENCTRL_DIV(4) & TC_CTRLA_PRESCALER_DIV16 but with burst of 4600µs - and the clock is wrong

Could you elaborate which clock and what is wrong there ? I also tried this conf but I don't have a burst of 4600us.

Offset: ~5000µs with GCLK_GENCTRL_DIV(120) & TC_CTRLA_PRESCALER_DIV1

I don't get why we have a so much offset with this config...

@benpicco
Copy link
Copy Markdown
Contributor Author

Could you elaborate which clock and what is wrong there?

(120 MHz / 4) / 16 = 1.875 MHz - but xtimer expects a 1MHz clock.

same for

(120 MHz / 2) / 64 = 0.9375 MHz

I can't explain the offset either - especially since we are using the same timer to set the alarm and measure the offset.

@benpicco
Copy link
Copy Markdown
Contributor Author

benpicco commented Jun 3, 2019

periph_flashpage should work now.
I made some changes to cpu/sam0_common/include/cpu_conf.h to use values from ASF instead of relying on hard-coded numbers.

I've tested the change on both the same54-xpro & samr21-xpro, the output of info looks correct for both and test_last_raw is working and so is erase.

Interestingly, LOCK_REGIONS differs for each sam0 MCU, but RIOT doesn't seem to use this (or care) at all - it just unlocks each 16 byte block individually, no matter what.

@benpicco
Copy link
Copy Markdown
Contributor Author

benpicco commented Jun 5, 2019

An update on the xtimer situation:

When I add static inline TcCount32 *dev(tim_t tim) __attribute__ ((optimize(0))); to sam0_common/periph/timer.c, the tests are working.

edit: unsigned int timer_read(tim_t tim) __attribute__ ((optimize(0))); works too.

In fact, it looks like a delay is needed between writing TC_CTRLBSET_CMD_READSYNC and reading SYNCBUSY.

I found for (volatile int i = 8; i; --i); to work well enough for that.

@benpicco
Copy link
Copy Markdown
Contributor Author

benpicco commented Jun 5, 2019

The timer tests should work now with #11610 applied.

@benpicco benpicco force-pushed the same54 branch 2 times, most recently from cae1013 to c400894 Compare June 6, 2019 09:50
@dylad dylad added the Reviewed: 3-testing The PR was tested according to the maintainer guidelines label Jun 6, 2019
Copy link
Copy Markdown
Member

@dylad dylad left a comment

Choose a reason for hiding this comment

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

ACK.
Please squash

@dylad dylad added the State: waiting for other PR State: The PR requires another PR to be merged first label Jun 6, 2019
@benpicco benpicco force-pushed the same54 branch 2 times, most recently from 72b1ac1 to b990da0 Compare June 6, 2019 13:34
@dylad dylad removed the CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR label Jun 6, 2019
@benpicco benpicco force-pushed the same54 branch 2 times, most recently from a5b726e to 2e6df02 Compare June 6, 2019 14:05
@dylad dylad added CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR and removed State: waiting for other PR State: The PR requires another PR to be merged first labels Jun 6, 2019
@dylad dylad added this to the Release 2019.07 milestone Jun 6, 2019
benpicco added 4 commits June 6, 2019 16:47
Atmel Software Framework (ASF) provides a set of low-level header
files that give access to different hardware peripherals of Atmel's
ICs.

Origin: Atmel SAME54 Series Device Support (1.0.87)
License: Apache-2.0
URL: http://packs.download.atmel.com/Atmel.SAME54_DFP.1.0.87.atpack
Atmel Software Framework (ASF) provides a set of low-level header files
that give access to different hardware peripherals of Atmel's ICs.

Origin: Atmel SAMD51 Series Device Support (1.1.96)
License: Apache-2.0
URL: http://packs.download.atmel.com/Atmel.SAMD51_DFP.1.1.96.atpack
This adds supoprt for the Atmel SAMD51 & SAME54 SoC.
The SAME5x/SAMD5x is a line of Cortex-M4F MCUs that share peripherals
with the samd2x Cortex-M0+ and saml1x Cortex-M23 parts.
This adds support for the Atmel SAM E54 Xplained Pro Evaluation Kit.

Only basic functionality has been enabled.
@dylad
Copy link
Copy Markdown
Member

dylad commented Jun 6, 2019

Here we go

@dylad dylad merged commit 87f59b4 into RIOT-OS:master Jun 6, 2019
@benpicco benpicco deleted the same54 branch June 6, 2019 15:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR Platform: ARM Platform: This PR/issue effects ARM-based platforms Reviewed: 3-testing The PR was tested according to the maintainer guidelines Type: new feature The issue requests / The PR implemements a new feature for RIOT

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants