<html> <head> <style> pre code { background-color: #eee; border: 1px solid #999; display: block; padding: 20px; } </style> </head> <body> <h1>M0 - ATSAMD21</h1> <figure> <img src='m0-feather.jpg' height=50%> <figcaption>Ring oscillator with M0 Feather.</figcaption> </figure> <p>This ring oscillator runs on the 'M0' ATSAMD21, which is a fairly popular microcontroller with an Arm Cortex M0 at it's heart. It has native USB functionality, and is supported with an Adafruit bootloader, making writing and running code fairly straightforward. I used Adafruit's Feather dev board for this test.</p> <p>I dug through the arduino cores and printed out their lookup tables so that I could write the registers down... This was a great (albeit tangential) exercise.</p> <pre> <code> /* I found most of these definitions in the arduino cores in AppData/Local/Arduino15/packages/adafruit/hardware/samd/1.0.19/cores/arduino/wiring_digital.c & wiring_digital.h */ #define PIN_LED_PORT 0 #define PIN_LED_PIN 17 #define PIN_10_PORT 0 #define PIN_10_PIN 18 #define PIN_11_PORT 0 #define PIN_11_PIN 16 uint32_t ulPin = 11; void setup() { // set a pin to in / out ... starting PORT->Group[g_APinDescription[ulPin].ulPort].PINCFG[g_APinDescription[ulPin].ulPin].reg = (uint8_t)(PORT_PINCFG_INEN) ; PORT->Group[g_APinDescription[ulPin].ulPort].DIRSET.reg = (uint32_t)(1 << g_APinDescription[ulPin].ulPin) ; //pinMode(10, OUTPUT); //pinMode(11, INPUT); } void loop() { EPortType port = g_APinDescription[ulPin].ulPort; uint32_t pin = g_APinDescription[ulPin].ulPin; uint32_t pinMask = (1ul << pin); Serial.print("11, port: "); Serial.print(port); Serial.print(" pin: "); Serial.print(pin); Serial.println(""); PORT->Group[port].OUTSET.reg = pinMask; delay(100); PORT->Group[port].OUTCLR.reg = pinMask; delay(100); } </code> </pre> <p>This enabled me to write the code that I ran during the test, where the M0 clocked at 1.45MHz. Scope traces and code below.</p> <figure> <img src="m0-scope.jpg" height=50%> <figcaption>Adafruit Feather dev board used in this test.</figcaption> </figure> <pre> <code> #define PIN_10_PORT 0 #define PIN_10_PIN 18 #define PIN_11_PORT 0 #define PIN_11_PIN 16 #define RING_PORT_OUTSET PORT->Group[PIN_10_PORT].OUTSET.reg #define RING_PORT_OUTCLR PORT->Group[PIN_10_PORT].OUTCLR.reg #define RING_PORT_OUT_MASK (1UL << PIN_10_PIN) #define RING_PORT_IN PORT->Group[PIN_11_PORT].IN.reg #define RING_PORT_IN_MASK (1UL << PIN_11_PIN) void setup() { // set 10 to output PORT->Group[PIN_10_PORT].DIRSET.reg = (uint32_t)(1 << PIN_10_PIN); // set 11 to input PORT->Group[PIN_11_PORT].PINCFG[PIN_11_PIN].reg = (uint8_t)(PORT_PINCFG_INEN); // do loop while (1) { // no loop just c RING_PORT_IN & RING_PORT_IN_MASK ? RING_PORT_OUTCLR = RING_PORT_OUT_MASK : RING_PORT_OUTSET = RING_PORT_OUT_MASK; } } void loop() { } </code> </pre> <p>With the Arduino digitalWrite and digitalRead calls, the ring is ~162khz</p> <figure> <img src='m0-scope-arduino.jpg' height=50%> <figcaption>Ring oscillator with M0 using Arduino library calls.</figcaption> </figure> <p>The code for this is below. About 1us of this latency is 'loop' call overhead.</p> <pre> <code> void setup() { // put your setup code here, to run once: pinMode(10, OUTPUT); pinMode(11, INPUT); } void loop() { // put your main code here, to run repeatedly: digitalWrite(10, 1-digitalRead(11)); } </code> </pre> <p><a href='../../index.html'>Back</a></p> </body> </html>