diff --git a/gpio/m0/index.html b/gpio/m0/index.html new file mode 100644 index 0000000000000000000000000000000000000000..5c644ac3baf5194494a61abd581d6a47af59e4ce --- /dev/null +++ b/gpio/m0/index.html @@ -0,0 +1,153 @@ +<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 diff --git a/gpio/m0/m0-feather.jpg b/gpio/m0/m0-feather.jpg new file mode 100644 index 0000000000000000000000000000000000000000..080beaeeea9704ce7c97bc48b3c0b3969d7ec5dc Binary files /dev/null and b/gpio/m0/m0-feather.jpg differ diff --git a/gpio/m0/m0-scope-arduino.jpg b/gpio/m0/m0-scope-arduino.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d2578e9e88cd5033ccf934e1999e18d8562fda77 Binary files /dev/null and b/gpio/m0/m0-scope-arduino.jpg differ diff --git a/gpio/m0/m0-scope.jpg b/gpio/m0/m0-scope.jpg new file mode 100644 index 0000000000000000000000000000000000000000..8d38ab7b48e4e3de411b8b2a836d642321fbe0d3 Binary files /dev/null and b/gpio/m0/m0-scope.jpg differ diff --git a/gpio/m0/m0_arduino/m0_arduino.ino b/gpio/m0/m0_arduino/m0_arduino.ino new file mode 100644 index 0000000000000000000000000000000000000000..e82f9d7e4214de1f27ebad2722c3f9ee142545c8 --- /dev/null +++ b/gpio/m0/m0_arduino/m0_arduino.ino @@ -0,0 +1,12 @@ +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)); + } +} diff --git a/gpio/m0/m0_port/m0_port.ino b/gpio/m0/m0_port/m0_port.ino new file mode 100644 index 0000000000000000000000000000000000000000..32643ad39078ed6e305f691b39639762370752ff --- /dev/null +++ b/gpio/m0/m0_port/m0_port.ino @@ -0,0 +1,41 @@ +/* + 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); +} diff --git a/gpio/m0/m0_portSearch/m0_portSearch.ino b/gpio/m0/m0_portSearch/m0_portSearch.ino new file mode 100644 index 0000000000000000000000000000000000000000..d33aecf5830cd19d265ea1bed23c9cdc108ca56e --- /dev/null +++ b/gpio/m0/m0_portSearch/m0_portSearch.ino @@ -0,0 +1,35 @@ +/* + 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() { + +} diff --git a/ring.json b/ring.json index a6a5778f43802d6f9293789e53bcfdabf17e5d66..6a83b0a7f9d056f040de5c5af0db9267957011d9 100644 --- a/ring.json +++ b/ring.json @@ -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":"",