This ring oscillator runs on the ATSAMS70 MCU using a homebrew dev-board documented here. The ATSAMS70 has an ARM Cortex-M7 running with a max speed of 300 MHz. C code for the oscillator is available here, or visible below.
#include
int main (void)
{
/* Insert system clock initialization code here (sysclk_init()). */
board_init();
sysclk_init();
/* Insert application code here, after the board has been initialized. */
// startup the PIOA peripheral clock - only necessary for Inputs and Interrupts
PMC->PMC_PCER0 = 1 << ID_PIOA;
// Peripheral Enable Register
// Set PER to 1 at the pin to enable the PIO peripheral,
// set PDR (peripheral disable register) to 1 to clear that, opening the pin up for other peripherals (uart, etc)
PIOA->PIO_PER |= PIO_PER_P28 | PIO_PER_P15;
// Output Enable Register
PIOA->PIO_OER = PIO_PER_P28;
// Output Disable Register
PIOA->PIO_ODR = PIO_PER_P15;
// B1 pulls PA15 to GND
while (1) {
// Clear Output Data Register (open drain)
if(PIOA->PIO_PDSR & PIO_PER_P15){
PIOA->PIO_CODR = PIO_PER_P28;
} else {
PIOA->PIO_SODR = PIO_PER_P28;
}
}
}
Oddly, the ring would bounce between 5.7MHz and 3.7MHz - I'm guessing that this is due to the GPIO peripheral occasionally sampling on a 'close' edge of it's 150MHz peripheral clock or on 'the next edge' ... if that makes any sense.