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

added atsam4s code and scope traces

parent 413a0632
No related branches found
No related tags found
No related merge requests found
Pipeline #
#include <asf.h>
int main (void)
{
PMC->PMC_PCER0 = 1 << ID_PIOA; //enable PIOA peripheral clock
//MAINCK OPTIONS: A) External, B) Internal
/*
//with 12 MHz external crystal for MAINCK
REG_CKGR_MOR |= CKGR_MOR_KEY_PASSWD | CKGR_MOR_MOSCXTEN;
//wait for crystal to become ready
while (!(REG_PMC_SR & PMC_SR_MOSCXTS));
//select crystal for main clock
REG_CKGR_MOR |= CKGR_MOR_KEY_PASSWD | CKGR_MOR_MOSCSEL;
//master clock source selection - choose main clock
REG_PMC_MCKR |= PMC_MCKR_CSS_MAIN_CLK;
//wait until main clock ready
while (!(REG_PMC_SR & PMC_SR_MCKRDY));
//select processer prescaler (0 - no divisor, 12 MHz)
REG_PMC_MCKR |= PMC_MCKR_PRES_CLK_1;
//select processer prescaler (div 4) 12mhz/4 = 3mhz
//REG_PMC_MCKR |= PMC_MCKR_PRES_CLK_4;
//wait until main clock ready
while (!(REG_PMC_SR & PMC_SR_MCKRDY));
//configure PLLB for 114MHz = (12 MHz / 4) * ( 37+1 )
//all faster speeds result in a slower ring oscillator
//REG_CKGR_PLLBR |= CKGR_PLLBR_MULB(37) | CKGR_PLLBR_DIVB(4);
//REG_CKGR_PLLBR |= CKGR_PLLBR_MULB(82) | CKGR_PLLBR_DIVB(2);
*/
//or use 4 MHz internal oscillator for MAINCK
// 106 MHz = ( 4 MHz / 2 ) * (52 + 1)
//strange that any faster produced a slower ring...
REG_CKGR_PLLBR |= CKGR_PLLBR_MULB(52) | CKGR_PLLBR_DIVB(2);
REG_PMC_MCKR |= PMC_MCKR_CSS_PLLB_CLK; //choose PLLB for master clock source
REG_PIOA_PER |= PIO_PER_P24 | PIO_PER_P25; //enable PIO controller on PA25 and PA26, PIO_PER_P25 = 1<<25, PIO_PER_P26 = 1<<26
REG_PIOA_OER = PIO_PER_P24; //set PA25 as output
REG_PIOA_ODR = PIO_PER_P25; //set PA26 as input
//v1 with asf
//ioport_set_pin_dir(EXT1_PIN_5, IOPORT_DIR_INPUT);
//ioport_set_pin_dir(EXT1_PIN_6, IOPORT_DIR_OUTPUT);
while (1) {
//v1 with asf
//ioport_set_pin_level(EXT1_PIN_6, !ioport_get_pin_level(EXT1_PIN_5)); //ring
if (REG_PIOA_PDSR & PIO_PDSR_P25){
REG_PIOA_CODR = PIO_PER_P24; //if pin26 is high, set pin 25 low
} else {
REG_PIOA_SODR = PIO_PER_P24; //if pin26 is low, set pin 25 high
}
}
}
......@@ -16,17 +16,78 @@ pre code {
<h1>ATSAM4S</h1>
<figure>
<img src='4s-pic.jpg' height=50%>
<img src='ring.png' height=50%>
<figcaption>Ring oscillator with ATSAM4S</figcaption>
</figure>
<p>This ring oscillator runs on the ATSAM4S MCU using the XPlained Pro Dev Kit. The ATSAM4S has an ARM Cortex-M4 running with a max speed of 120 MHz. C code for the oscillator is available <a href='atsam4s_main.c'>here</a>, or visible below.</p>
<pre>
<code>
code
#include <asf.h>
int main (void)
{
PMC->PMC_PCER0 = 1 << ID_PIOA; //enable PIOA peripheral clock
//MAINCK OPTIONS: A) External, B) Internal
/*
//with 12 MHz external crystal for MAINCK
REG_CKGR_MOR |= CKGR_MOR_KEY_PASSWD | CKGR_MOR_MOSCXTEN;
//wait for crystal to become ready
while (!(REG_PMC_SR & PMC_SR_MOSCXTS));
//select crystal for main clock
REG_CKGR_MOR |= CKGR_MOR_KEY_PASSWD | CKGR_MOR_MOSCSEL;
//master clock source selection - choose main clock
REG_PMC_MCKR |= PMC_MCKR_CSS_MAIN_CLK;
//wait until main clock ready
while (!(REG_PMC_SR & PMC_SR_MCKRDY));
//select processer prescaler (0 - no divisor, 12 MHz)
REG_PMC_MCKR |= PMC_MCKR_PRES_CLK_1;
//select processer prescaler (div 4) 12mhz/4 = 3mhz
//REG_PMC_MCKR |= PMC_MCKR_PRES_CLK_4;
//wait until main clock ready
while (!(REG_PMC_SR & PMC_SR_MCKRDY));
//configure PLLB for 114MHz = (12 MHz / 4) * ( 37+1 )
//all faster speeds result in a slower ring oscillator
//REG_CKGR_PLLBR |= CKGR_PLLBR_MULB(37) | CKGR_PLLBR_DIVB(4);
//REG_CKGR_PLLBR |= CKGR_PLLBR_MULB(82) | CKGR_PLLBR_DIVB(2);
*/
//or use 4 MHz internal oscillator for MAINCK
// 106 MHz = ( 4 MHz / 2 ) * (52 + 1)
//strange that any faster produced a slower ring...
REG_CKGR_PLLBR |= CKGR_PLLBR_MULB(52) | CKGR_PLLBR_DIVB(2);
REG_PMC_MCKR |= PMC_MCKR_CSS_PLLB_CLK; //choose PLLB for master clock source
REG_PIOA_PER |= PIO_PER_P24 | PIO_PER_P25; //enable PIO controller on PA25 and PA26, PIO_PER_P25 = 1<<25, PIO_PER_P26 = 1<<26
REG_PIOA_OER = PIO_PER_P24; //set PA25 as output
REG_PIOA_ODR = PIO_PER_P25; //set PA26 as input
//v1 with asf
//ioport_set_pin_dir(EXT1_PIN_5, IOPORT_DIR_INPUT);
//ioport_set_pin_dir(EXT1_PIN_6, IOPORT_DIR_OUTPUT);
while (1) {
//v1 with asf
//ioport_set_pin_level(EXT1_PIN_6, !ioport_get_pin_level(EXT1_PIN_5)); //ring
if (REG_PIOA_PDSR & PIO_PDSR_P25){
REG_PIOA_CODR = PIO_PER_P24; //if pin26 is high, set pin 25 low
} else {
REG_PIOA_SODR = PIO_PER_P24; //if pin26 is low, set pin 25 high
}
}
}
</code>
</pre>
<p>The system clock is sensitive near its maximum with the ring frequency decreasing dramatically if a threshold is exceeded for the system clock. Strangely enough, the fastest ring oscillators occured for system clocks of less than 120 MHz. The code above shows how to use both the internal oscillator to feed the PLL, as well as a 12 MHz external oscillator.</p>
<p>The code also shows how to use the Atmel software framework calls. This runs roughly half as fast as the direct port manipulation.</p>
<p><a href='../../index.html'>Back</a></p>
......
gpio/atsam4s/ring.png

6.33 KiB

0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment