Go Down

Topic: Output a 1MHz clock for SID chip (Read 2177 times) previous topic - next topic

golgobot

I'm trying to build an 8 bit synthesizer based on the SID 6581 chip found in the Commodore64. It requires a 1MHz clock input. Right now I'm using the timer2 interrupt, but I'm not sure it's working. Is there a more standard way to provide a reliable clock-out at a specific frequency than interrupts. Maybe a built-in function perhaps?

Thanks for any reply.

The code is based on the interrupt tutorial

[font=Courier]void setupTimer2()
{

 int result=(257 - 16); //the 0.5 is for rounding;

 TCCR2A = 0;
 TCCR2B = 0<<CS22 | 0<<CS21 | 1<<CS20;

 //Timer2 Overflow Interrupt Enable  
 TIMSK2 = 1<<TOIE2;

 //load the timer for its first cycle
 TCNT2=result;
}
int counter = 0;
//Timer2 overflow interrupt vector handler
ISR(TIMER2_OVF_vect) {
 
 samples++;

 if(samples == 16)
 {
   if(writeHigh)
   {
     digitalWrite(CLOCK, HIGH);
   }
   else
   {
     digitalWrite(CLOCK, LOW);
   }
   samples = 0;
   writeHigh = !writeHigh;
 }
 
 //Capture the current timer value. This is how much error we have
 //due to interrupt latency and the work in this function
 latency=TCNT2;

 //Reload the timer and correct for latency.  //Reload the timer and correct for latency.  //Reload the timer and correct for latency.
 TCNT2=latency + 257 - 16;
}[/font]

#1
Jun 22, 2008, 10:34 am Last Edit: Jun 22, 2008, 10:40 am by bens Reason: 1
I think your method will not work for one main reason:  you are trying to interrupting every microsecond, and your interrupt takes much longer to execute that a microsecond.  This frequent of an interrupt will pretty much take up all of your processing time, and you will have to write an incredibly efficient ISR just to make sure you get out before the next interrupt.  You will need to do direct register manipulation (e.g. no calls to digitalWrite() as this takes several microseconds to execute) and you should probably write the ISR in assembly just to maximize speed efficiency.

Instead of interrupts, you could set it up so one of the timers outputs a 50% duty-cycle PWM at 1 MHz, or you could modify your mega168 to run off of a 1 MHz clock (internal 8 MHz RC oscillator with CKDIV8 fuse bit programmed) and output that clock signal on the CKOUT pin (though I'm not sure you want your entire Arduino running at 1 MHz, and I'm not sure how happy the bootloader would be with this).

I'd recommend using a hardware PWM.  This would be a case of set it up and forget it, with no need for interrupts or any other processor interaction.  You will have to configure the PWM yourself, however, as the analogWrite() function will not produce the proper frequency.  I suggest you use a fast PWM with Timer2 running with a prescaler of 1 (so it's counting at the full speed of 16 MHz), and a TOP of 15 and a compare match on 8.   I've posted some sample code that shows how to do something like this in other threads.

- Ben

MikMo

Does the 1MhZ clock have to come from Arduino ?

If not then there are other rather easy solutions for making it, like a crystal or ceramic resonator or a 555 based oscillator.

Megaionstorm

Use a 1mhz crystal for the mos6581.
Mein Arduino Projekte Blog:
http://ardu-megatank.blogspot.de/

James C4S

Quote
Is there a more standard way to provide a reliable clock-out at a specific frequency than interrupts.

Yes, use a stable clock source like a crystal or oscillator.  Interrupts and timers from a micro-controller seems like the LAST thing you would want to use.
Capacitor Expert By Day, Enginerd by night.  ||  Personal Blog: www.baldengineer.com  || Electronics Tutorials for Beginners:  www.addohms.com

cr0sh

I tend to wonder if, in the future, say - 20 years from now - we'll find all kinds of Commodore 64 machines without any capability for sound...?

BTW, golgobot, do you know the SID has been emulated with the Arduino?:

http://www.arduino.cc/playground/Main/SID-emulator

:)
I will not respond to Arduino help PM's from random forum users; if you have such a question, start a new topic thread.

Megaionstorm

#6
Dec 05, 2010, 12:10 pm Last Edit: Dec 05, 2010, 12:11 pm by Megaionstorm Reason: 1
I think it could be a good idea not only to use the MOS6581 for a SID Emulator. Use the MOS6526CIA too ! It has two timers included.

C 64 Parts:
http://www.htu.tugraz.at/~herwig/c64/bauteile.php

Commodore SID 6581 Datasheet:
http://www.waitingforfriday.com/index.php/Commodore_SID_6581_Datasheet
Mein Arduino Projekte Blog:
http://ardu-megatank.blogspot.de/

CrossRoads

Don't think you can get there writing in arduino code anyway.
This yields 87 KHz on a score, 11.5uS period.

Code: [Select]

byte toggle =0; // used to select output hi/lo
byte outputPin5 = 5; // could be any

void setup (){
pinMode (outputPin5, OUTPUT);
}
void loop(){
toggle = 1-toggle;  // results in 0 1 0 1 ...
digitalWrite (outputPin5, toggle);
}

Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

CrossRoads

Don't think you can get there with an output pin using arduino code.
This  yields ~87KHz, 11.5uS, measured on a scope.

byte toggle =0; // used to select output hi/lo
byte outputPin5 = 5; // could be any

void setup (){
pinMode (outputPin5, OUTPUT);
}
void loop(){
toggle = 1-toggle;  // results in 0 1 0 1 ...
digitalWrite (outputPin5, toggle);
}
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

SeanJ

This might be helpful:
http://www.robotsimple.com/DS1077_Programmable_Oscillator_Breakout_16_2_kHz_to_133MHz

Coding Badly

#10
Dec 06, 2010, 06:42 am Last Edit: Dec 06, 2010, 06:42 am by bcook Reason: 1

Gentlefolk, the original post is from 2008 (21.06.2008 at 17:40:40) and the original poster never replied.  By now he's either figured out a solution, given up, or passed away.

CrossRoads

Well, it was fun seeing just how fast an output could be made to toggle anyway ...
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

Coding Badly


:)

In that case...
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1230286016

For the record, the "best" way to output a clock signal is to configure timer 1 or timer 2 to toggle a pin.

Go Up