#include #include #include #include #include # define YCOE PA7 //pin 2 JP3 ATmega16 pin 33 connect thru 1K resistor # define YRST PA5 //pin 3 JP3 ATmega16 pin 35 connect thru 1K resistor # define SDIN PD3 //pin 4 JP3 ATmega16 pin 17 connect thru 1K resistor # define SYNC PD6 //pin 5 JP3 ATmega16 pin 20 connect thru 1K resistor # define SCLK PD4 //pin 7 JP3 ATmega16 pin 18 connect thru 1K resistor # define IRQ PD2 //pin 8 JP3 ATmega16 pin 16 connect directly # define MPWM PD5 //pin 9 JP3 ATmega16 pin 19 connect thru 1K resistor volatile uint8_t Yflag, x, y; // function actually writes data to an address in the Yamaha sound chip. // sends 8-bits to the Yamaha sound chip by controlling the SCLK, SDIN wires void send_fm8 (uint8_t shift) { return; } // function that writes data to an address in the Yamaha sound chip. // processes the addr/data and should call send_fm8(uint8_t shift) // to send bits, _must_ configure SYNC, SCLK, SDIN wires appropriately // for beginning and end of transmission void send_fm (uint8_t addr, uint16_t data) { return; } void init_fm (void) { // setup I/O DDRD = 0x78; DDRA = 0xA0; PORTD = 0; // SDIN, SYNC, and SCLK = 0 // reset both chips // we use delays to ensure proper timing for Yamaha operations PORTA = 0x00; // both reset (low) //wait (100 x 4) cycles = wait 400 cycles = >100 YCLK cycles, ~55 usec. _delay_loop_2(100); // start oscillator PORTA = 0x80; //wait (100 x 4) cycles = wait 400 cycles = >100 YCLK cycles, ~55 usec. _delay_loop_2(100); // reset fm chip PORTA = 0xA0; _delay_loop_2(100); // set the clock divider CLKSEL ( $33 = 0; default reset) $39 = 64; send_fm(0x33,0); send_fm(0x39,0x40); _delay_loop_2(30000); // set power management AP1 = 0 $38 = $1C send_fm(0x38,0x1C); _delay_loop_2(30000); _delay_loop_2(30000); _delay_loop_2(30000); // set power management AP1,AP2 = 0$38 = $18 send_fm(0x38,0x18); _delay_loop_2(1000); // set power management all on $38 = $00 send_fm(0x38,0x00); _delay_loop_2(30000); // set timbre data $10-2F send_fm(0x10,0xc223); // modulator 1 send_fm(0x11,0x0bf0); send_fm(0x12,0xC223); // carrier 1 send_fm(0x13,0x0800); // set timbre allotment data $30 = 0 all voices modulator 1 carrier 1 send_fm(0x30,0); // set tempo data $31 = 72 (120 beats/min) send_fm(0x31,31); // set volumes $35, $36 send_fm(0x35,0x15); send_fm(0x36,0x15); //------------------end of initialization-------------------------- } // function loads up a sample birdsong into the Yamaha sound // chips FIFO and begins playing void send_birdcall(void) { // write notes and a rest to FIFO // bbwa send_fm(0,0xc847); //1100 1000 0100 0111 bbwa send_fm(0,0xbc60); //1011 1100 0110 0000 send_fm(0,0xb42b); //1011 0100 0010 1011 send_fm(0,0xdc33); //1101 0100 0010 1011 send_fm(0,0xcc33); //1100 1100 0011 0011 send_fm(0,0xc874); //1100 1000 0111 0100 send_fm(0,0xc411); //1100 0100 0001 0001 send_fm(0,0xbc12); //1011 1100 0001 0010 send_fm(0,0xac11); //1010 1100 0001 0001 send_fm(0,0xc412); //1100 0100 0001 0010 send_fm(0,0xd411); //1101 0100 0001 0001 send_fm(0,0xdc12); //1101 1100 0001 0010 send_fm(0,0xd811); //1101 1000 0001 0001 send_fm(0,0xdc12); //1101 1100 0001 0010 send_fm(0,0xd823); //1101 1000 0010 1011 send_fm(0,0xd43c); //1101 0100 0011 1100 send_fm(0,0xcc47); //1100 1100 0100 0111 send_fm(0,0xbc11); //1011 1100 0001 0001 send_fm(0,0xf411); //1111 0100 0001 0001 send_fm(0,0xe812); //1110 1000 0001 0010 send_fm(0,0xf412); //1111 0100 0001 0010 send_fm(0,0xe433); //1110 0100 0011 0011 send_fm(0,0xdc12); //1101 1100 0001 0010 send_fm(0,0xe469); //1110 0100 0110 1001 send_fm(0,0xe812); //1110 1000 0001 0010 send_fm(0,0xe423); //1110 0100 0010 1011 send_fm(0,0xe811); //1110 1000 0001 0001 send_fm(0,0xe411); //1110 0100 0001 0001 send_fm(0,0xe812); //1110 1000 0001 0010 send_fm(0,0xe411); //1110 0100 0001 0001 // $00 = $3000 a rest send_fm(0,0x3000); // set up interrupt send_fm(0x34,0x0021); // start FM $32 = 1 send_fm(0x32,1); } int main (void) { // initialize interrupts init_fm(); // initialize Yamaha sei(); // send an initial birdcall to get things started send_birdcall(); /* loop forever, the interrupts are doing the rest */ for (;;){ // send another birdcall only if we've been interrupted by the Yamaha chip if( /* TODO */ ){ // clear interrupt send_fm(0x34,0x0); send_birdcall(); } } // never reached return (0); }