Hi!
Longtime lurker here. I have recently been able to get a MOS6581 SID to run as a network player using ACID64 and a program I wrote in LabView to actually work. It works about 95% at the moment. By that, I can play every SID I've tried. I can even play the heavily digitized ones at pretty much regular speed. The other 5% is in the stuff that feels like a hack in my program. I currently use a PWM channel (FTM0) for the ~1MHz SID clock and the IntervalTimer for the delays between writes. The problem is that these two timers don't really synchronize together with the settings I have used. I can see on my oscilloscope that the CLK walks away from the chip select and I have to reset the FTM0 counter right before I write the data so I can place the ~400ns write pulse around the falling edge of the CLK.
So, my question is... Is there a better way to generate a synchronized interval timer and a clock? The CLK doesn't have to be exactly 1MHz since the actual PAL clock is a little slower and the NTSC clock is a little faster. Here is my program...
Teensy 3.2 @ 96MHz
Thanks in advance for any advice on how tor make it better.
David
Longtime lurker here. I have recently been able to get a MOS6581 SID to run as a network player using ACID64 and a program I wrote in LabView to actually work. It works about 95% at the moment. By that, I can play every SID I've tried. I can even play the heavily digitized ones at pretty much regular speed. The other 5% is in the stuff that feels like a hack in my program. I currently use a PWM channel (FTM0) for the ~1MHz SID clock and the IntervalTimer for the delays between writes. The problem is that these two timers don't really synchronize together with the settings I have used. I can see on my oscilloscope that the CLK walks away from the chip select and I have to reset the FTM0 counter right before I write the data so I can place the ~400ns write pulse around the falling edge of the CLK.
So, my question is... Is there a better way to generate a synchronized interval timer and a clock? The CLK doesn't have to be exactly 1MHz since the actual PAL clock is a little slower and the NTSC clock is a little faster. Here is my program...
Teensy 3.2 @ 96MHz
Code:
#define RESET 17
#define RW 16
#define CLK 4
#define CS1 3
#define NOP __asm__("nop\n\t")
volatile unsigned int nexttime;
volatile unsigned int timetonext;
volatile byte address;
volatile byte data;
volatile byte dataavailable;
volatile byte serdatlow;
volatile byte serdathigh;
volatile byte serdataddress;
volatile byte serdatdata;
volatile byte testdata;
volatile int cycles_per_us;
byte x = 1;
IntervalTimer myTimer;
void setup() {
Serial.begin(115200);
pinMode(RESET, OUTPUT);
digitalWrite(RESET, HIGH);
pinMode(RW, OUTPUT);
digitalWrite(RW, HIGH);
pinMode(CLK, OUTPUT);
digitalWrite(CLK, LOW);
pinMode(CS1, OUTPUT);
digitalWrite(CS1, HIGH);
pinMode(2, OUTPUT); //DATA0
pinMode(14, OUTPUT); //DATA1
pinMode(7, OUTPUT); //DATA2
pinMode(8, OUTPUT); //DATA3
pinMode(6, OUTPUT); //DATA4
pinMode(20, OUTPUT); //DATA5
pinMode(21, OUTPUT); //DATA6
pinMode(5, OUTPUT); //DATA7
pinMode(15, OUTPUT); //ADDRESS0
pinMode(22, OUTPUT); //ADDRESS1
pinMode(23, OUTPUT); //ADDRESS2
pinMode(9, OUTPUT); //ADDRESS3
pinMode(10, OUTPUT); //ADDRESS4
analogWriteFrequency(CLK, 1000000); // set SID clock frequency to 1MHz
analogWriteResolution(5); // PWM resolution
analogWrite(CLK, 15); // PWM dutycycle
myTimer.begin(DATA, 5);
myTimer.priority(8);
cycles_per_us = F_BUS / 1000000;
}
FASTRUN void loop() { // get serial data and pass to device
digitalWriteFast(RESET, LOW);
delayMicroseconds(20);
digitalWriteFast(RESET, HIGH);
while (x == 1) {
if (Serial.available() >= 4) {
serdathigh = Serial.read();
serdatlow = Serial.read();
timetonext = serdathigh * 256 + serdatlow;
PIT_LDVAL0 = timetonext * cycles_per_us; // reset the PIT timer in myTimer to the delay until the next write
serdataddress = Serial.read();
serdatdata = Serial.read();
dataavailable = 1;
while (dataavailable == 1) {} // wait for myTimer to fire interrupt
}
}
}
FASTRUN void DATA(void)
{
if (dataavailable >= 1) {
for (int i = 0; i <= 4; i++) {
NOP;
}
FTM1_CNT = 0; // reset PWM FTM counter so that I can align the data with the falling edge of the CLK
GPIOC_PDOR = serdataddress;
digitalWriteFast(RW, LOW);
digitalWriteFast(CS1, LOW);
for (int i = 0; i <= 3; i++) {
NOP;
}
GPIOD_PDOR = serdatdata;
for (int i = 0; i <= 3; i++) {
NOP;
}
dataavailable = 0;
digitalWriteFast(RW, HIGH);
digitalWriteFast(CS1, HIGH);
}
}
Thanks in advance for any advice on how tor make it better.
David
Last edited: