Nice! Now just build it INSIDE of a calculatorThat's the next step. First I want to make sure it's flawless. I will also add the original midi out code to the chip. This project was based around the code of my midi interface.
Ninja'd you. I already made it :DYou should show it off then to give it a bit of spice...
Also: I have to come up with a cool name:
TIMID (TI+MIDI+SID)
Zound80
*insert more idea's here*
KSidM8zAlso: I have to come up with a cool name:How about Zid80?
TIMID (TI+MIDI+SID)
Zound80
*insert more idea's here*
Imho, you should also speed up the "pcb + enclosure" business to 'sell' it faster.What do you mean by that?
More: http://playground.arduino.cc/Main/SID-emulator
i simply mean, the project final stages are always the hardest part to accomplish. that's all. :DImho, you should also speed up the "pcb + enclosure" business to 'sell' it faster.What do you mean by that?
#include <SID.h>
// MACROs
#define PIN2H (PIND & 0B00000100)
#define PIN3L !(PIND & 0B00001000)
#define CLR(x,y) (x&=(~(1<<y)))
#define SET(x,y) (x|=(1<<y))
SID mySid;
void setup()
{
pinMode(2,INPUT);
pinMode(3,INPUT);
mySid.begin();
}
byte n=0;
int timer=0;
byte count=0;
byte get=B00000000;
int addrval[2] = {0};
void loop()
{
do{
do
{
if (PIN3L) // If the clock pin is LOW
{
if (PIN2H) // And the data pin is HIGH
{
CLR(get,count); // CLEAR BIT
}
else // otherwise
{
SET(get,count); // SET BIT
}
count++; // Increase the bit counter
while(PIN3L) // Wait until the clock pin goes HIGH again
{
timer++; // Increase the timeout timer
if (timer==500){// Timeout at 500 loops
n=count=0; // Reset counters
break; // Break free
}
}
timer=0; // Reset the timeout timer
}
}while(count!=8); // Loop again when the bit counter has not reached 8 bits yet
addrval[n]=get; // Otherwise store the received byte in an array in cell n
n++; // Increase the byte counter
count=0; // Reset the bit counter
}while(n!=2); // Loop again when the byte counter has not reached two bytes yet
// Otherwise write the value to the register.
mySid.set_register(addrval[0], addrval[1]);
n=0; // Reset the byte counter
}
Can someone tell me what to optimize?
I tried to optimize the arduino code, but it's not getting an awful lot faster since my first optimization.Well, i do not have the whole program picture, so it is not very easy to comment. However, i do see you are polling some bit (PIN3L), what is bound to be always slow. Can't you use interrupts instead, saving cpu cycles to do other things? http://www.cab.u-szeged.hu/linux/doc/khg/node19.html
....
I already use timer interrupts for the sid emulation library. Can I use these in parallel?Yes, as long as you take care of the relative synchronization. It can be a bit more awkward to program, though.
.. I watched the signal on the scope.If you have available spare output bits, you can also use the scope to 'debug' the program.
00 ff - write ff (0-255) to register 00 (Freq Lo)
01 ff - write ff (0-255) to register 01 (Freq Hi)
04 17 - write TRIANGLE|GATE_ON to register 04 (Conrol reg)
That's 6 bytes!1D nn - write nn(0-255) to register 29
That's only two bytes!
I am not that good at programming for the pc and....Hum, I bet that with your Axe knowledge, if you start up with a "c-language cheap tutorial", within a couple of hours you'll have your converter just about ready. But, i'm just guessing, of course.. Fine work, btw.
// MACROs
#define PIN2L !(PIND & 0B00000100)
#define PIN3L !(PIND & 0B00001000)
#define CLR(x,y) (x&=(~(1<<y)))
#define SET(x,y) (x|=(1<<y))
byte get;
byte bitCount = 8;
void bitTransceive()
{
get >>= 1;
if (PIN2L)
{
get |= 128;
}
bitCount--;
}
void setup()
{
CLR(DDRD,2); //pinMode 2 is input
CLR(DDRD,3); //pinMode 3 is input
Serial.begin(115200);
attachInterrupt(1,bitTransceive,FALLING);
}
void loop()
{
if (!bitCount){
// Pull down clock line to make sure the calculator does not send while the atmega
// is processing the incoming data.
SET(DDRD,3);
Serial.println(get);
get = 0;
bitCount = 8;
CLR(DDRD,3);
// Released the clockline.
}
}
My goal was to make the code compacter, faster, more readable and understandable. I don't think there is a lot of room for improvement here!#define _N 255
// MACROs
#define PIN2L !(PIND & 0B00000100)
#define PIN3L !(PIND & 0B00001000)
#define CLR(x,y) (x&=(~(1<<y)))
#define SET(x,y) (x|=(1<<y))
byte data;
byte bitCount = 8;
// State _N (255) : Do nothing and wait for incoming interrupt. Carry out other tasks in the mean time.
// State 0 : Slave receives (Receive bytes from master)
// State 1 : Slave sends (Send bytes to master)
void bitReceive()
{
if(bitCount){
data >>= 1;
if (PIN2L)
{
data |= 128;
}
bitCount--;
}
}
void bitSend()
{
if(bitCount)
{
//Set portD
DDRD |= 4;
if(data & 1)
PORTD &= 251;
else
PORTD |= 4;
data >>= 1;
bitCount--;
}
}
void setup()
{
CLR(DDRD,2); //pinMode 2 is input
CLR(DDRD,3); //pinMode 3 is input
attachInterrupt(1,bitReceive,FALLING);
}
void loop()
{
byte state = _N, address, cell[128];
while(1)
{
if (!bitCount){
// Pull down clock line to make sure the calculator does not send while the atmega
// is processing the incoming data.
DDRD |= 8;
switch (state)
{
case 255:
{
bitCount = 8;
address = data >> 1;
state = data & 1;
// When the mode is Slave Transmit the function bitSend() is attached to the interrupt.
if (state){
data = cell[address];
attachInterrupt(1,bitSend,FALLING);
}
break;
}
case 0:
{
cell[address] = data;
bitCount = 8;
// Return to mode _N.
state = _N;
break;
}
case 1:
{
bitCount = 8;
// Re-attach the bitReceive function to the external interrupt on pin 3 and
// return to mode _N.
attachInterrupt(1,bitReceive,FALLING);
state = _N;
break;
}
}
// Release the clockline and data line.
DDRD &= 243;
PORTD &= 251;
}
}
}
This code compiles to less than 1k and it uses only 16 bytes of RAM + 128 for the data cells (used in this example so you can read and write from these cells from the calculator. These will get replaced by the SID registers).