I've got a SAM D21 microcontroller. I want to use 3 output pins to output 3 clock signals:
high clock = 8 MHz
mid clock = 32.768 kHz
low clock = 8.192 kHz
In the datasheet under the section Multiplexed Signals, under the heading PORT Function Multiplexing, it says that Peripheral H can be used to send a clock signal to an output pin.
If I only use pins on Port B, then according to Table 7-1, I can do:
Clock No. 4 sent to Pin PB10
Clock No. 5 sent to Pin PB11
Clock No. 6 sent to Pin PB12
I've written some code to try make this happen.
My high clock is the 8 MHz oscillator divided by 1.
My mid clock is the 32.768 kHz oscillator divided by 1.
My low clock is the 32.768 kHz oscillator divided by 4 (giving 8.192 kHz).
Is it possible for my mid clock and my low clock to both come from the same clock source, but with a different divider?
Am I doing this properly in the following code?
#include <Arduino.h>
// All three clocks pins must be on Port B
#define PIN_CLOCK_HI 10 // linked to Clock No. 4
#define PIN_CLOCK_MID 11 // linked to Clock No. 5
#define PIN_CLOCK_LO 12 // linked to Clock No. 6
// These are the generic clock settings you don't need to know about
#define CLOCK_SETUP (GCLK_GENCTRL_OE|GCLK_GENCTRL_IDC|GCLK_GENCTRL_GENEN)
void setup(void)
{
// Set Clock No. 4 = 8 MHz oscillator divided by 1
GCLK->GENDIV.reg = GCLK_GENCTRL_ID(4) | GCLK_GENDIV_DIV(1); // divide by 1
while ( GCLK->STATUS.bit.SYNCBUSY ); // Wait for synchronization
GCLK->GENCTRL.reg = GCLK_GENCTRL_ID(4) | CLOCK_SETUP | GCLK_GENCTRL_SRC_OSC8M;
while ( GCLK->STATUS.bit.SYNCBUSY ); // Wait for synchronization
// Set Clock No. 5 = 32.768 kHz oscillator divided by 1
GCLK->GENDIV.reg = GCLK_GENCTRL_ID(5) | GCLK_GENDIV_DIV(1); // divide by 1
while ( GCLK->STATUS.bit.SYNCBUSY ); // Wait for synchronization
GCLK->GENCTRL.reg = GCLK_GENCTRL_ID(5) | CLOCK_SETUP | GCLK_GENCTRL_SRC_OSC32K;
while ( GCLK->STATUS.bit.SYNCBUSY ); // Wait for synchronization
// Set Clock No. 6 = 32.768 kHz oscillator divided by 4 = 8.192 kHz
GCLK->GENDIV.reg = GCLK_GENCTRL_ID(6) | GCLK_GENDIV_DIV(4); // divide by 4
while ( GCLK->STATUS.bit.SYNCBUSY ); // Wait for synchronization
GCLK->GENCTRL.reg = GCLK_GENCTRL_ID(6) | CLOCK_SETUP | GCLK_GENCTRL_SRC_OSC32K;
while ( GCLK->STATUS.bit.SYNCBUSY ); // Wait for synchronization
// Enable the port multiplexers on each clock pin
PORT->Group[PORTB].PINCFG[PIN_CLOCK_HI ].bit.PMUXEN = 1;
PORT->Group[PORTB].PINCFG[PIN_CLOCK_MID].bit.PMUXEN = 1;
PORT->Group[PORTB].PINCFG[PIN_CLOCK_LO ].bit.PMUXEN = 1;
// Set the port multiplexer to the clocks (i.e. Peripheral H)
PORT->Group[PORTB].PMUX[PIN_CLOCK_HI >> 1].reg |= PORT_PMUX_PMUXE_H;
PORT->Group[PORTB].PMUX[PIN_CLOCK_MID >> 1].reg |= PORT_PMUX_PMUXE_H;
PORT->Group[PORTB].PMUX[PIN_CLOCK_LO >> 1].reg |= PORT_PMUX_PMUXE_H;
}
void loop(void)
{
// Nothing to do in here
}