modm-io / modm

modm: a C++23 library generator for AVR and ARM Cortex-M devices
https://modm.io
Mozilla Public License 2.0
749 stars 132 forks source link

Support for ATSAM arm processors #189

Closed CrustyAuklet closed 4 years ago

CrustyAuklet commented 5 years ago

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 commented 5 years ago

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 commented 5 years ago

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 commented 5 years ago

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 commented 5 years ago

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 commented 5 years ago

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

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 commented 5 years ago

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

salkinium commented 5 years ago

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 commented 5 years ago

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 commented 5 years ago

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

CrustyAuklet commented 5 years ago

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 commented 5 years ago

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:

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.

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.

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

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 commented 5 years ago

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

strongly-typed commented 5 years ago

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 commented 4 years ago

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

salkinium commented 4 years ago

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.