
Originally Posted by
JBeale
Is there some reference that tells me what T4 hardware modules are already being used in the background even without loading any libraries? I assume delay(), delayMicroseconds() as well as analogWrite() etc. all have hardware support.
I also wondered what peripherals might be already in use. I don't have any knowledge - perhaps one of the experts will point you in the right direction.
Attached is some commented code on using GPT2. I chose GPT2 because the outputs/inputs were convenient (seem to remember some pin restriction on GPT1 - was it the capture not being available?). This example uses the 32bit counter to count 75,000 ticks of the 150 MHz clock, giving a HALF PERIOD of 500uS or 1 KHz frequency, but the limit would be H.P. of 28 seconds (2^32 times 6.667 nS). With the ppm error, you would need some tweaking of the compare value to get the precision. Note there is only one counter, even though there are three compare registers.
Notice in the RM diagram on page 3074 (Fig 51-1) that it is ONLY Compare1 that can reset the counter on a comparison match, which is why I also set this in my code, even though I use Compare3 as the toggle output signal. It took me a while to understand how these Compare's work for this GPT style timer (as you may read in my RED ALERT concern in the Beta Tests).
My ISR fires every 500 uS, so I count 2000 ISRTicks to get a one second flash of the LED.
Code:
//TESTT4004 - GPT TEST PROGRAM for T4
//===================================
//Author: TelephoneBill
//Date: 19 AUG 2019
//Version: 001
//NOTES: Using GPT2 as the timer. GPT2 Output Compare3 (1 KHz) is on pin 16. CompareValue = 0x000124F7 = (75,000 - 1)
//Compare1 is the counter reset mechanism. Compare2 is not used here. Compare3 is the toggle output on pin 16.
//definitions
uint32_t Save1, Save2;
byte Byte1;
volatile uint32_t ISRTicks = 0;
//SETUP
//=====
void setup() {
//initialise general hardware
Serial.begin(115200); //setup serial port
pinMode(13, OUTPUT); //pin 13 as digital output
FlashLED(4); //confidence boost
//set clock gating registers to inhibit GPT and PIT clocks (while changing to 150 MHz)
Save1 = CCM_CCGR0; //save current state 0
Save2 = CCM_CCGR1; //save current state 1
CCM_CCGR0 &= 0xF0FFFFFF; //inhibit GPT2 (CG12,CG13)
CCM_CCGR1 &= 0xFF0FCFFF; //inhibit GPT1 and PIT (CG6,CG10,CG11)
//change the mux setting for IPG_CLK_ROOT (set bit6 = 0). This enables the 150 MHz.
CCM_CSCMR1 &= 0xFFFFFFBF;
//restore GPT and PIT gated clocks to former values
CCM_CCGR0 = Save1;
CCM_CCGR1 = Save2;
//configure clocks for GPT2 module
CCM_CCGR0 |= 0x0F000000; //enable clocks to GPT2 (CG12,CG13)
//configure GPT2 for test
GPT2_CR = 0; //clear the control register, FRR = 0 means restart after Compare
GPT2_SR = 0x3F; //clear all prior status
GPT2_PR = 0; //prescale register set divide by 1
GPT2_CR |= GPT_CR_CLKSRC(1); //clock selection #1 (peripheral clock = 150 MHz)
GPT2_CR |= GPT_CR_ENMOD; //reset count to zero before enabling
GPT2_CR |= 0x04800000; //Compare3 = toggle mode, Compare2 = toggle mode
GPT2_OCR1 = 0x000124F7; //Compare1 value (74,999 decimal)
GPT2_OCR2 = 0x000124F7; //Compare2 value (74,999 decimal)
GPT2_OCR3 = 0x000124F7; //Compare3 value (74,999 decimal)
GPT2_IR = 0x00000004; //enable interrupt for Compare flag
GPT2_CR |= GPT_CR_EN; //enable GPT1 counting at 150 MHz
//configure Teensy pin 16 as Compare3 output
IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_07 = 8; // GPT2 Compare3 is now output on pin 16
//enable GPT1 interrupt within NVIC table
attachInterruptVector(IRQ_GPT2, GPT2_isr); //declare which routine performs the ISR function
NVIC_ENABLE_IRQ(IRQ_GPT2);
}
//ISR ROUTINE FOR GPT1
//====================
//FASTRUN puts this code into RAM to run twice as fast
FASTRUN void GPT2_isr(void) {
GPT2_SR = 0x00000004; //reset the interrupt flags in status register
ISRTicks++;
if (ISRTicks>=2000) {
ISRTicks = 0;
digitalWriteFast(13, 1);
}
if (ISRTicks==100) {
digitalWriteFast(13, 0);
}
asm volatile("dsb");
}
//MAIN LOOP
//=========
void loop() {
//call KeyInput() routine
KeyInput(); //no key currently used, but could be employed to change timer period dynamically
}
//SUBROUTINES
//===========
//Flash LED routine
void FlashLED(int m) {
for (int n=0;n<m;n++) {
digitalWriteFast(13, 1); //set pin 13 high
delay(100);
digitalWriteFast(13, 0); //set pin 13 low
delay(100);
}
}
void KeyInput() {
//process any keystrokes available
if (Serial.available()>0) {
//read the incoming byte
Byte1 = Serial.read();
if (Byte1>0x20) {
switch (Byte1) {
case 'A': //
//task goes here...
break;
}
}
}
}