For some reason, when I set up the interval timer, I am only getting it to fire once. The code I am trying to update for use with the T4 already works on T3.2, T3.5, and T3.6 with minor timing tweaks between them, but not yet on the T4. The new program is an update my Commodore 6581 (SID) player.
https://forum.pjrc.com/threads/42587-David-s-MOS6581-SID-network-player-(Teensy-3-2)?highlight=SID
I need a 1MHz clock and a timed chip select that lines up with the clock's rising edge and doesn't "walk" away from the clock between SID writes. That looks like the following:
The code needed to do this on previous Teensys is this:
The variable "timetonext" is the number of microseconds to wait before firing the interrupt and can be any number between 0 and 65535. I used PIT_LDVAL0 to change the start of the timer on the fly and it worked very well. Also, don't worry if the chip select doesn't line up with the clock in the example since that can be fixed with different amounts of delayCycles either in the interrupt routine or the main routine.
Any ideas?
David
https://forum.pjrc.com/threads/42587-David-s-MOS6581-SID-network-player-(Teensy-3-2)?highlight=SID
I need a 1MHz clock and a timed chip select that lines up with the clock's rising edge and doesn't "walk" away from the clock between SID writes. That looks like the following:
The code needed to do this on previous Teensys is this:
Code:
#define CLK 4
#define CS1 3
#define NOP __asm__("nop\n\t")
volatile long timetonext;
volatile byte dataavailable;
volatile unsigned long cycles_per_us;
static inline void delayCycles(uint32_t cycles)
{ // MIN return in 7 cycles NEAR 20 cycles it gives wait +/- 2 cycles - with sketch timing overhead
uint32_t begin = ARM_DWT_CYCCNT - 12; // Overhead Factor for execution
while (ARM_DWT_CYCCNT - begin < cycles) ; // wait
}
IntervalTimer myTimer;
void setup() {
Serial.begin(115200);
pinMode(CLK, OUTPUT);
digitalWrite(CLK, HIGH);
pinMode(CS1, OUTPUT);
digitalWrite(CS1, HIGH);
analogWriteFrequency(CLK, 1000000); // set clock frequency to 1MHz
analogWriteResolution(5); // PWM resolution
analogWrite(CLK, 15); // PWM dutycycle
myTimer.begin(DATA, 10);
//myTimer.priority(64);
cycles_per_us = F_BUS_ACTUAL / 1000000;
}
FASTRUN void loop() {
while (1) {
timetonext = 3; //Change this to vary the number of CLK pulses between CS1 pulses
dataavailable = 1;
PIT_LDVAL0 = timetonext * cycles_per_us - 1; // reset the PIT timer in myTimer to the delay until the next write
while (dataavailable == 1) {} // wait for myTimer to fire interrupt
}
}
FASTRUN void DATA(void)
{
if (dataavailable >= 1) {
digitalWriteFast(CS1, LOW);
// 200ns Pulse on Teensy 4 @ 600MHz
delayCycles(45);
dataavailable = 0;
digitalWriteFast(CS1, HIGH);
}
}
The variable "timetonext" is the number of microseconds to wait before firing the interrupt and can be any number between 0 and 65535. I used PIT_LDVAL0 to change the start of the timer on the fly and it worked very well. Also, don't worry if the chip select doesn't line up with the clock in the example since that can be fixed with different amounts of delayCycles either in the interrupt routine or the main routine.
Any ideas?
David