Skip to content
Snippets Groups Projects
Commit 9c5a36af authored by Sam Calisch's avatar Sam Calisch
Browse files

Merge branch 'jake' into 'master'

add M0

See merge request !1
parents 19a2e9f4 3f6b701f
No related branches found
No related tags found
1 merge request!1add M0
Pipeline #
<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'>
<figcaption>Ring oscillator with M0.</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
#define LED_OUTSET PORT->Group[PIN_LED_PORT].OUTSET.reg
#define LED_OUTCLR PORT->Group[PIN_LED_PORT].OUTCLR.reg
#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 a pin to in
PORT->Group[PIN_LED_PORT].PINCFG[PIN_LED_PIN].reg = (uint8_t)(PORT_PINCFG_INEN);
// setting same pin to out (arduino configures an output as both, so it can read its own state. handy
PORT->Group[PIN_LED_PORT].DIRSET.reg = (uint32_t)(1 << PIN_LED_PIN);
// 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>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=25%>
<figcaption>Adafruit Feather dev board used in this test.</figcaption>
</figure>
<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
also samd/1.0.19/variants/variant.h and variant.cpp and pins_arduino.h
*/
#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'>
<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>
\ No newline at end of file
gpio/m0/m0-feather.jpg

112 KiB

gpio/m0/m0-scope-arduino.jpg

186 KiB

gpio/m0/m0-scope.jpg

167 KiB

void setup() {
// put your setup code here, to run once:
pinMode(10, OUTPUT);
pinMode(11, INPUT);
}
void loop() {
while (1) {
digitalWrite(10, 1 - digitalRead(11));
}
}
/*
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);
}
/*
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
also samd/1.0.19/variants/variant.h and variant.cpp and pins_arduino.h
*/
#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() {
}
......@@ -63,6 +63,26 @@
}
],
"gpio":[
{
"name":"M0, arduino",
"serial_number":"",
"subdirectory_path":"gpio/m0",
"dev_board_price":19.00,
"dev_board_sales link":"",
"ic_price":2.1,
"ic_sales_link":"",
"ring_period":6.14
},
{
"name":"M0, port",
"serial_number":"",
"subdirectory_path":"gpio/m0",
"dev_board_price":5.00,
"dev_board_sales link":"",
"ic_price":2.1,
"ic_sales_link":"",
"ring_period":0.687
},
{
"name":"nucleo, mbed",
"serial_number":"",
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment