ClearCore Library
Loading...
Searching...
No Matches
PeriodicInterrupt.cpp

Return to SDK Examples for Microchip Studio

1/*
2 * PeriodicInterrupt
3 * Configure a user-defined periodic interrupt.
4 */
5 /*
6 * Title: PeriodicInterrupt
7 *
8 * Objective:
9 * This example demonstrates how to generate a user defined periodic
10 * interrupt.
11 *
12 * Description:
13 * This example configures a periodic interrupt handler that turns the
14 * user LED on and off during each call to the interrupt. Once configured,
15 * The interrupt will execute at the requested frequency without having to
16 * be called from the main program.
17 *
18 * Requirements:
19 * ** None
20 *
21 * Links:
22 * ** ClearCore Documentation: https://teknic-inc.github.io/ClearCore-library/
23 * ** ClearCore Manual: https://www.teknic.com/files/downloads/clearcore_user_manual.pdf
24 *
25 * Last Modified: 6/11/2020
26 * Copyright (c) 2020 Teknic Inc. This work is free to use, copy and distribute under the terms of
27 * the standard MIT permissive software license which can be found at https://opensource.org/licenses/MIT
28 */
29
30#include "ClearCore.h"
31
42void ConfigurePeriodicInterrupt(uint32_t frequencyHz);
43
46extern "C" void TCC2_0_Handler(void) __attribute__((
47 alias("PeriodicInterrupt")));
48
49// Periodic interrupt priority
50// 0 is highest priority, 7 is lowest priority
51// Recommended priority is >= 4 to not interfere with other processing
52#define PERIODIC_INTERRUPT_PRIORITY 4
53#define ACK_PERIODIC_INTERRUPT TCC2->INTFLAG.reg = TCC_INTFLAG_MASK
54
55// State currently written to LED_BUILTIN
56bool ledState = false;
57uint32_t interruptFreqHz = 4;
58
66extern "C" void PeriodicInterrupt(void) {
67 // Perform periodic processing here.
68 ledState = !ledState;
69 ConnectorLed.State(ledState);
70
71 // Acknowledge the interrupt to clear the flag and wait for the next interrupt.
72 ACK_PERIODIC_INTERRUPT;
73}
74
75int main() {
76 ConfigurePeriodicInterrupt(interruptFreqHz);
77}
78
79void ConfigurePeriodicInterrupt(uint32_t frequencyHz) {
80 // Enable the TCC2 peripheral.
81 // TCC2 and TCC3 share their clock configuration and they
82 // are already configured to be clocked at 120 MHz from GCLK0.
83 CLOCK_ENABLE(APBCMASK, TCC2_);
84
85 // Disable TCC2.
86 TCC2->CTRLA.bit.ENABLE = 0;
87 SYNCBUSY_WAIT(TCC2, TCC_SYNCBUSY_ENABLE);
88
89 // Reset the TCC module so we know we are starting from a clean state.
90 TCC2->CTRLA.bit.SWRST = 1;
91 while (TCC2->CTRLA.bit.SWRST) {
92 continue;
93 }
94
95 // If the frequency requested is zero, disable the interrupt and bail out.
96 if (!frequencyHz) {
97 NVIC_DisableIRQ(TCC2_0_IRQn);
98 return;
99 }
100
101 // Determine the clock prescaler and period value needed to achieve the
102 // requested frequency.
103 uint32_t period = (CPU_CLK + frequencyHz / 2) / frequencyHz;
104 uint8_t prescale;
105 // Make sure period is >= 1.
106 period = max(period, 1U);
107
108 // Prescale values 0-4 map to prescale divisors of 1-16,
109 // dividing by 2 each increment.
110 for (prescale = TCC_CTRLA_PRESCALER_DIV1_Val;
111 prescale < TCC_CTRLA_PRESCALER_DIV16_Val && (period - 1) > UINT16_MAX;
112 prescale++) {
113 period = period >> 1;
114 }
115 // Prescale values 5-7 map to prescale divisors of 64-1024,
116 // dividing by 4 each increment.
117 for (; prescale < TCC_CTRLA_PRESCALER_DIV1024_Val && (period - 1) > UINT16_MAX;
118 prescale++) {
119 period = period >> 2;
120 }
121 // If we have maxed out the prescaler and the period is still too big,
122 // use the maximum period. This results in a ~1.788 Hz interrupt.
123 if (period > UINT16_MAX) {
124 TCC2->PER.reg = UINT16_MAX;
125 }
126 else {
127 TCC2->PER.reg = period - 1;
128 }
129 TCC2->CTRLA.bit.PRESCALER = prescale;
130
131 // Interrupt every period on counter overflow.
132 TCC2->INTENSET.bit.OVF = 1;
133 // Enable TCC2.
134 TCC2->CTRLA.bit.ENABLE = 1;
135
136 // Set the interrupt priority and enable it.
137 NVIC_SetPriority(TCC2_0_IRQn, PERIODIC_INTERRUPT_PRIORITY);
138 NVIC_EnableIRQ(TCC2_0_IRQn);
139}
#define CPU_CLK
Definition SysTiming.h:36
#define CLOCK_ENABLE(BUS, BIT)
Definition SysUtils.h:135
#define SYNCBUSY_WAIT(PER, BITMASK)
Definition SysUtils.h:127
#define max(a, b)
Definition SysUtils.h:180
int16_t State() override
Get LED's last sampled state.