Commit ed37f661 authored by Sam Calisch's avatar Sam Calisch

add atsamd51

parent 5dc47c4e
Pipeline #2677 passed with stage
in 2 seconds
<html>
<head>
<style>
pre code {
background-color: #eee;
border: 1px solid #999;
display: block;
padding: 20px;
}
</style>
</head>
<body>
<h1>ATSAMD51</h1>
<figure>
<img src='ring.jpg' height=50%>
<figcaption>Ring oscillator with ATSAMD51J19</figcaption>
</figure>
<p>This ring oscillator runs on the ATSAMD51J19 MCU using the Adafruit Feather dev board. The ATSAMD51J19 has an ARM Cortex-M4 running with a max speed of 120 MHz. Code for the oscillator is available <a href='ring.ino'>here</a>, or visible below.</p>
<pre>
<code>
#define portin PORT->Group[PORTA].IN.reg
#define outclr PORT->Group[PORTA].OUTCLR.reg
#define outset PORT->Group[PORTA].OUTSET.reg
#define out PORT->Group[PORTA].OUT.reg
#define outtgl PORT->Group[PORTA].OUTTGL.reg
const uint8_t in_pin = 21;
const uint32_t in_mask = 1ul&lt&ltin_pin;
const uint8_t out_pin = 22;
const uint32_t out_mask = 1ul&lt&ltout_pin;
void setup() {
// Set pin mode according to chapter '32.6.3 I/O Pin Configuration'
// enable input, to support reading back values, with pullups disabled
PORT->Group[PORTA].PINCFG[out_pin].reg = (uint8_t)(PORT_PINCFG_INEN) ;
// Set pin to output mode
PORT->Group[PORTA].DIRSET.reg = out_mask;
// Set in pin to input mode
PORT->Group[PORTA].PINCFG[in_pin].reg=(uint8_t)(PORT_PINCFG_INEN) ;
PORT->Group[PORTA].DIRCLR.reg = in_pin ;
//make sure port synchronizer always active, else we'll use extra clock cycles.
//I'm not sure I'm activating the synchronizer correctly, because I don't see a change when I add this...
PORT->Group[PORTA].CTRL.reg = in_mask;
//loop
while(1){
//ternary operator: assymetric 300ns (200-100)
//portin & in_mask ? outclr = out_mask : outset = out_mask;
//portin & in_mask ? outclr = out_mask : out = out_mask;
//full port inversion: symmetric 300ns
out = ~(portin);
//bitwise xor: 300ns
//out = ((portin ^ in_mask) << 1);
//if else, 300ns
/*if (portin & in_mask){
outclr = out_mask;
} else {
outset = out_mask;
}*/
}
}
void loop() {}
</code>
</pre>
<p>By default the port consumes extra clock cycles to save power and only sample the input pin when a read is requested (see description below). We can set the input synchronizer to always be active to avoid this delay. I've tried to do this above, but I need to confirm if this was successful.</p>
<img src='port-diagram.png' height=200px>
<img src='input-synchronization.png' height=200px>
<p><a href='../../index.html'>Back</a></p>
</body>
</html>
\ No newline at end of file
#define portin PORT->Group[PORTA].IN.reg
#define outclr PORT->Group[PORTA].OUTCLR.reg
#define outset PORT->Group[PORTA].OUTSET.reg
#define out PORT->Group[PORTA].OUT.reg
#define outtgl PORT->Group[PORTA].OUTTGL.reg
//11: { PORTA, 21, PIO_TCC_PDEC, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM0_CH1, TCC0_CH1, EXTERNAL_INT_5 },
const uint8_t in_pin = 21;
const uint32_t in_mask = 1ul<<in_pin;
//12: { PORTA, 22, PIO_TCC_PDEC, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM0_CH2, TCC0_CH2, EXTERNAL_INT_6 },
const uint8_t out_pin = 22;
const uint32_t out_mask = 1ul<<out_pin;
//led:{ PORTA, 23, PIO_TCC_PDEC, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM0_CH3, TCC0_CH3, EXTERNAL_INT_7 }, // TCC2/WO[1]
//const uint32_t out_mask = 1ul<<23;
void setup() {
//set clock port for digital io
//PM->APBBMASK.reg |= PM_APBBMASK_PORT ;
// Set pin mode according to chapter '32.6.3 I/O Pin Configuration'
// enable input, to support reading back values, with pullups disabled
PORT->Group[PORTA].PINCFG[out_pin].reg = (uint8_t)(PORT_PINCFG_INEN) ;
// Set pin to output mode
PORT->Group[PORTA].DIRSET.reg = out_mask;
// Set in pin to input mode
PORT->Group[PORTA].PINCFG[in_pin].reg=(uint8_t)(PORT_PINCFG_INEN) ;
PORT->Group[PORTA].DIRCLR.reg = in_pin ;
PORT->Group[PORTA].CTRL.reg = in_mask; //make sure port synchronizer always active
while(1){
/*PORT->Group[PORTA].OUTSET.reg = out_mask; // turn on led
delay(1000); // wait for a second
PORT->Group[PORTA].OUTCLR.reg = out_mask; // turn off led
delay(1000); // wait for a second
*/
//ternary operator: assymetric 300ns (200-100)
//portin & in_mask ? outclr = out_mask : outset = out_mask;
//portin & in_mask ? outclr = out_mask : out = out_mask;
out = ~(portin);
//bitwise xor: 300ns
//out = ((portin ^ in_mask) << 1);
//if else
/*if (portin & in_mask){
outclr = out_mask;
} else {
outset = out_mask;
}*/
//toggle, 10 mhz
//outtgl = out_mask;
//manual toggle, 20mhz
//outclr = out_mask;
//outset = out_mask;
}
}
void loop() {}
......@@ -7,6 +7,7 @@
"dev_board_sales_link":"link for dev board purchase",
"ic_price":"price for bare ic, dollars",
"ic_sales_link":"link for ic purchase",
"cpu_frequency":"clock speed in MHz",
"ring_period":"period of one full ring oscillator waveform, in microseconds"
},
......@@ -63,6 +64,17 @@
}
],
"gpio":[
{
"name":"ATSAMD51",
"serial_number":"",
"subdirectory_path":"gpio/atsamd51",
"dev_board_price":14.95,
"dev_board_sales link":"https://www.adafruit.com/product/3800",
"ic_price":4.31,
"ic_sales_link":"ATSAMD51J19A-AUTCT-ND",
"cpu_frequency":120,
"ring_period":0.27
},
{
"name":"ATSAMS70",
"serial_number":"",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment