ClearCore Library
Macros | Enumerations | Functions
SysUtils.h File Reference

ClearCore common utility functions. More...

#include <stdint.h>
+ Include dependency graph for SysUtils.h:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define PMUX_SELECTION(GPIO_PORT, GPIO_PIN, PER_TYPE)
 
#define DATA_OUTPUT_STATE(GPIO_PORT, DATA_MASK, STATE)
 
#define PMUX_ENABLE(GPIO_PORT, GPIO_PIN)    PORT->Group[(GPIO_PORT)].PINCFG[(GPIO_PIN)].bit.PMUXEN = 1
 
#define PMUX_DISABLE(GPIO_PORT, GPIO_PIN)    PORT->Group[(GPIO_PORT)].PINCFG[(GPIO_PIN)].bit.PMUXEN = 0
 
#define PIN_CONFIGURATION(GPIO_PORT, GPIO_PIN, CONFIG)    PORT->Group[(GPIO_PORT)].PINCFG[(GPIO_PIN)].reg = (CONFIG)
 
#define DATA_DIRECTION_OUTPUT(GPIO_PORT, DATA_MASK)    PORT->Group[(GPIO_PORT)].DIRSET.reg = (DATA_MASK)
 
#define DATA_DIRECTION_INPUT(GPIO_PORT, DATA_MASK)    PORT->Group[(GPIO_PORT)].DIRCLR.reg = (DATA_MASK)
 
#define SYNCBUSY_WAIT(PER, BITMASK)
 
#define CLOCK_ENABLE(BUS, BIT)    MCLK->BUS.bit.BIT = 1
 
#define SET_CLOCK_SOURCE(PER_GCLK_ID, GCLK_INDEX)
 
#define max(a, b)   (((a) > (b)) ? (a) : (b))
 
#define min(a, b)   (((a) < (b)) ? (a) : (b))
 

Enumerations

enum  PerType {
  PER_EXTINT = 0, PER_ANALOG, PER_SERCOM, PER_SERCOM_ALT,
  PER_TIMER, PER_TIMER_ALT, PER_TIMER_PDEC, PER_USB,
  PER_SDHC, PER_I2S, PER_PCC, PER_GMAC,
  PER_GCLK_AC, PER_CCL
}
 

Functions

void GClkFreqUpdate (uint8_t gclkIndex, uint32_t freqReq)
 Update GCLK frequency. More...
 

Detailed Description

ClearCore common utility functions.

Macro Definition Documentation

#define CLOCK_ENABLE (   BUS,
  BIT 
)    MCLK->BUS.bit.BIT = 1

Enable the clock specified by the bit on the given Advanced Peripheral Bus.

Examples:
DigitalIOExamples/PeriodicInterrupt/PeriodicInterrupt.cpp.
#define DATA_DIRECTION_INPUT (   GPIO_PORT,
  DATA_MASK 
)    PORT->Group[(GPIO_PORT)].DIRCLR.reg = (DATA_MASK)

Configure the port data direction as input.

#define DATA_DIRECTION_OUTPUT (   GPIO_PORT,
  DATA_MASK 
)    PORT->Group[(GPIO_PORT)].DIRSET.reg = (DATA_MASK)

Configure the port data direction as output.

#define DATA_OUTPUT_STATE (   GPIO_PORT,
  DATA_MASK,
  STATE 
)
Value:
if ((STATE)) { \
PORT->Group[(GPIO_PORT)].OUTSET.reg = (DATA_MASK); \
} \
else { \
PORT->Group[(GPIO_PORT)].OUTCLR.reg = (DATA_MASK); \
}

Write the data mask to the Data Output Value register on the specified port.

#define max (   a,
 
)    (((a) > (b)) ? (a) : (b))

Return the maximum value of a and b.

Examples:
DigitalIOExamples/PeriodicInterrupt/PeriodicInterrupt.cpp.
#define min (   a,
 
)    (((a) < (b)) ? (a) : (b))

Return the minimum value of a and b.

#define PIN_CONFIGURATION (   GPIO_PORT,
  GPIO_PIN,
  CONFIG 
)    PORT->Group[(GPIO_PORT)].PINCFG[(GPIO_PIN)].reg = (CONFIG)

Set the pin configuration for the specified pin on the specified port.

#define PMUX_DISABLE (   GPIO_PORT,
  GPIO_PIN 
)    PORT->Group[(GPIO_PORT)].PINCFG[(GPIO_PIN)].bit.PMUXEN = 0

Disable the peripheral multiplexer on the specified pin on the specified port.

#define PMUX_ENABLE (   GPIO_PORT,
  GPIO_PIN 
)    PORT->Group[(GPIO_PORT)].PINCFG[(GPIO_PIN)].bit.PMUXEN = 1

Enable the peripheral multiplexer on the specified pin on the specified port.

#define PMUX_SELECTION (   GPIO_PORT,
  GPIO_PIN,
  PER_TYPE 
)
Value:
if ((GPIO_PIN) & 1) { \
PORT->Group[(GPIO_PORT)].PMUX[(GPIO_PIN) >> 1].bit.PMUXO = (PER_TYPE); \
} \
else { \
PORT->Group[(GPIO_PORT)].PMUX[(GPIO_PIN) >> 1].bit.PMUXE = (PER_TYPE); \
}

Set the correct peripheral multiplexer for the specified pin in the specified port.

#define SET_CLOCK_SOURCE (   PER_GCLK_ID,
  GCLK_INDEX 
)
Value:
GCLK->PCHCTRL[(PER_GCLK_ID)].bit.CHEN = 0; \
while (GCLK->PCHCTRL[(PER_GCLK_ID)].bit.CHEN) { \
continue; \
} \
GCLK->PCHCTRL[(PER_GCLK_ID)].bit.GEN = GCLK_PCHCTRL_GEN((GCLK_INDEX)); \
GCLK->PCHCTRL[(PER_GCLK_ID)].bit.CHEN = 1; \
while (GCLK->SYNCBUSY.reg & GCLK_SYNCBUSY_GENCTRL((GCLK_INDEX))) { \
continue; \
}

Set the peripheral's clock source.

  • PER_GLCK_ID is the GCLK ID of a peripheral (e.g. DAC_GCLK_ID).
  • GCLK_INDEX is the numeric index of the GCLK source (i.e. 0-11).

This will work because GCLK_PCHCTRL_GEN_GCLKx_Val == x for x in 0, 11. Therefore GCLK_PCHCTRL_GEN(x) == GCLK_PCHCTRL_GEN(GCLK_PCHCTRL_GEN_GCLKx_Val) and so the correct value will be set in the GEN register of the GCLK.

The procedure for setting a peripheral's clock source follows from section 14.6.3.3 Selecting the Clock Source for a Peripheral (p. 155) of the SAMD5xE5x datasheet:

  1. Disable the Peripheral Channel by writing PCHCTRLm.CHEN=0
  2. Assert that PCHCTRLm.CHEN reads '0'
  3. Change the source of the Peripheral Channel by writing PCHCTRLm.GEN
  4. Re-enable the Peripheral Channel by writing PCHCTRLm.CHEN=1

...and from section 14.6.3.1 Enabling a Peripheral Clock (p. 155):

The PCHCTRLm.CHEN bit must be synchronized to the generic clock domain. PCHCTRLm.CHEN will continue to read as its previous state until the synchronization is complete.

This necessary synchronization is the reason for the final while-loop.

#define SYNCBUSY_WAIT (   PER,
  BITMASK 
)
Value:
while ((PER)->SYNCBUSY.reg & (BITMASK)) { \
continue; \
}

Wait for the synchronization bits (BITMASK) of the peripheral (PER).

Examples:
DigitalIOExamples/PeriodicInterrupt/PeriodicInterrupt.cpp.

Enumeration Type Documentation

enum PerType

Peripheral type

Function Documentation

void GClkFreqUpdate ( uint8_t  gclkIndex,
uint32_t  freqReq 
)

Update GCLK frequency.

Updates the divisor on the specified GCLK to generate the requested frequency.

Parameters
[in]gclkIndexThe GCLK index.
[in]freqReqThe requested frequency, in Hz.