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

Support for ATSAM arm processors #189

Closed
CrustyAuklet opened this issue Apr 4, 2019 · 15 comments · Fixed by #194
Closed

Support for ATSAM arm processors #189

CrustyAuklet opened this issue Apr 4, 2019 · 15 comments · Fixed by #194

Comments

@CrustyAuklet
Copy link

The Atmel (Microchip) ATSAM line of ARM microprocessors are very nice microcontrollers. The SAMD21 is used on Arduino boards. Adafruit has SAMD21 and SAMD51 based feather boards. Peripherals are conceptually similar to the nicer AVR peripherals (SERCOM, timers, etc) and there is a lot of code/pinout compatibility between models.

I actually use the SAML21 processor on a few projects, which is a very low power M0+. I build very low power data-loggers for physiological experiments, and it seems like my use case has a large overlap with modm.

Perhaps I can help add support for these processors?

@salkinium
Copy link
Member

salkinium commented Apr 4, 2019

modm relies heavily on the data in modm-devices to generate the HAL. In order to properly support the Atmel SAM platform, I would first need a data source similar to CubeMX with machine-readable data. (See Introducing modm-devices blog post). Otherwise you'd go crazy trying to manually add all this data to a similar degree of completeness and correctness as with the existing AVR and STM32 platforms and it wouldn't really be maintainable for us either.

Do you know of some configuration GUI or similar data source for Atmel SAMs?

@salkinium
Copy link
Member

Bullseye: http://packs.download.atmel.com has SAM* data as well. We already use this for AVR, a quick glance over the .atdf files shows interrupt table, pins and pin alternate functions. It also includes the cmsis header files, which we would add as a separate repository (cmsis-header-sam?) analog to the cmsis-header-stm32 repo.

@CrustyAuklet
Copy link
Author

CrustyAuklet commented Apr 4, 2019

yes the packs link contains the .atdf files as well as the standard ARM .svd files.
There is also https://start.atmel.com/ which is a web gui that generates projects as well as a machine readable description of that project. I don't know the details but I know Adafruit does some automated generation and download using Atmel Start to maintain their copy of ASF4 ( https://github.com/adafruit/asf4/tree/master/tools ).

@salkinium
Copy link
Member

I think the .atdf files contain enough information to cover all the modm features. Do you want to try to add them into modm-devices?

@CrustyAuklet
Copy link
Author

I'll give it a shot. Looks like I need to do two things:

  • create a CMSIS repo with a script(s) to download the device packs, suck out the headers, and make sure they are formatted properly.
  • fork modm-devices and add the new processors by parsing the .atdf files through the existing tools.

I'll probably start with the D21 since the featherD21 is very easy to get and cheap compared to all my custom L21 hardware. If I hit a wall I will post here.

@asmfreak
Copy link
Contributor

asmfreak commented Apr 5, 2019

Does this also include  Atmel SAM3X8E ARM Cortex-M3 found in Due?

@salkinium
Copy link
Member

salkinium commented Apr 5, 2019

I don‘t see a reason why the modm-devices parser couldn‘t parse ALL pack files of ALL SAM* devices. The formats are pretty much all the same (but the devil is in the detail like with the STM32 Cube Data). What the extend of the HAL implementation will be, depends heavily on the fragmentation of the hardware. But modm is very modular, so we can build that up gradually. I‘d focus first on startup, then GPIO, then UART, then the rest.

@salkinium
Copy link
Member

So, yes, why not? Once we have the modm-devices data, everything becomes significantly easier to port.

Note that I recently separated the Cortex-M core from the STM32 core, in anticipation of additional Cortex-M based vendors: #176.

@salkinium
Copy link
Member

Please don't hesitate to ask for help if your stuck, since my code is not particularly Pythonic or well documented.

@CrustyAuklet
Copy link
Author

Header repo similar to modm-io/cmsis-header-stm
just samd51 and samd21 for now. Since Atmel keeps all the packs on one page I think a future feature could be to discover all available SAM devices from the html, instead of using a hard-coded list.

Also packs contain separate trees for each variant. For example SAMD21 has SAMD21A. SAMD21B, SAMD21C... etc. I did diffs on the folders and there are differences so I just made each variant a top level folder.

fork of modm-devices
got script to download and extract the .atdf files into the expected location (easy)
the dfg folder is a little more confusing, but I made the class for parsing the part number.

@salkinium
Copy link
Member

salkinium commented Apr 20, 2019

Ok, we now have data, lets format that into some code using lbuild.
Note that you can explore the available lbuild modules for your target using
lbuild -r repo.lb -D :target={identifier} discover --developer.

Here's a checklist to add a new Cortex-M platform to modm:

  • Find data source and format into device files in modm-devices and point ext/modm-devices submodule to that.

  • Extract CMSIS headers into own repository and add as submodule in ext/{vendor}/{platform}.

  • Add new platform devices to modm:target option in repo.lb.

  • Create a very simple GPIO example for your test device in examples/{board}/blink (like AVR/blink).
    This example will be used to test the startup, delay and GPIO port.
    Try out lbuild discover --developer and find what is missing in the tree (modm:platform:* mostly).
    lbuild build will probably fail.

  • Port core and CMSIS modules

modm:platform:core module in modm/src/modm/platform/core/{platform}:

The startup code is shared for ARM Cortex-M platforms in the modm:platform:cortex-m.
But you will have to port the linkerscript, and the __modm_initialize_platform() function.
Use the STM32 code module to port your own.

The Cortex-M module provides you with predefined sections to assemble the linkerscripts.
You need to arrange those in the right order and assign these sections to the right memory.
The most restrictive linkerscript is the one for just one continuous SRAM section.
Note the use of table sections, which tell the startup script what memory to copy/zero and what SRAM to use for the heap.
The heap memory is attributed using these traits.

modm:cmsis:device module in ext/{vendor}:

This module provides the CMSIS header files and CPP defines for the specific device.
Note that the STM32 module also does
additional work for aiding debugging and providing clock control definitions.
These are not necessary initially.

  • Port clock module: modm:platform:{clock-control} in modm/src/modm/platform/clock/{platform}

The spinning (blocking) delay functions modm::delay{Milli, Micro, Nano}seconds() require
the current CPU frequencies.
They must be defaulted to the startup frequency of the CPU,
so that these functions work correctly before configuring the system clock.

While it is not necessary to implement system clock abstractions right away, it is very useful
to provide the updateCoreFrequency<Core_Hz>() function.

  • Port GPIO module: modm:platform:gpio in modm/src/modm/platform/gpio/{platform}

Implement the very basic modm::GpioIO interface
and then extend it with platform-specific functions.
You can ignore the signal connections for now.
This basic GPIO implementation will already give you BitBangI2cMaster and BitBangSpiMaster.

Note that the existing implementations implement GpioSet,
which is an optimization to efficiently access an unordered set of GPIOs, which is useful for building
fast bit-bang drivers for SPI and I2C. Similarly, SoftwareGpioPort and GpioPort
are also optimizations that can be ignored for now.

  • Get blinky example running:

Get it to compile, then get it to program with OpenOCD using scons program.
Consider providing a simple Board Support Package,
that defined a custom OpenOCD configuration script if so required.

Once you can program, you can also scons gdb to debug from the reset handler onwards.

You should now be able to blink an LED. *slow clap*

  • Port minimum:

    • Signal connections -> to connect to pins to peripherals.
    • UART -> to get serial output.
    • Board Support Package -> gives you a SystemClock frequency tree and initialize functions
  • Nice to have:

    • Some system clock configuration API
    • Full GPIO implementation: GpioSet, SoftwareGpioPort, GpioPort
    • Hardware drivers for I2C, SPI, ADC, Timer, CAN, maybe more
    • Unit tests in hardware (modm/test/modm/platform)

PS: There is a lot of duplicate Python code in modm that should be moved to modm-devices.
I'm aware of this and working to not only share data with modm-devices but also code,
so you can also share common derived information directly from modm-device instead of
duplicating this code in the modm modules.

@salkinium
Copy link
Member

Btw, I ordered a different SAMD21 breakout board, so I can test your port and add another board.

@strongly-typed
Copy link
Collaborator

Btw, I ordered a different SAMD21 breakout board, so I can test your port and add another board.

Me too! Great to see some porting effort here! I just received an NXP board ...

BTW, I get a

scons: *** [__size] ZeroDivisionError : float division by zero
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/site-packages/scons/SCons/Action.py", line 1202, in execute
    result = self.execfunction(target=target, source=rsources, env=env)
  File "/Users/usr/Dev/modm/modm-the-slat/examples/feather_m0/blink/modm/ext/dlr/scons-build-tools/site_tools/utils_buildsize.py", line 123, in size_action
    "rom_p": totals["rom"] / float(flash) * 100.0,
ZeroDivisionError: float division by zero
scons: building terminated because of errors.

when I do a lbuild build && scons in modm-the-slat/examples/feather_m0/blink at feature/microchip-sam (254eb07) and modm-devices at ba51890

@tannewt
Copy link

tannewt commented Apr 23, 2020

I've done a bunch of work (CircuitPython) with the SAMD21 and SAMD51 and can help answer questions if folks have them.

@salkinium
Copy link
Member

Thanks for reminding me about this work, @tannewt! I think all the hard stuff for SAMD support is already done, including modm-devices data, so I will work on merging modm-devices and cleaning up the PR and merging it too in the current state. Then others can continue porting GPIO/UART/etc without having to deal with the foundations too.

@salkinium salkinium mentioned this issue May 6, 2020
28 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

Successfully merging a pull request may close this issue.

5 participants