/* * File: PIC24_ButtonsWithI2C * Author: Zach * * Created on May 1, 2013, 02:29 AM */ #include #include #include #include #include #include #include "MiscLabels.h" #include "EffectsButtons.h" #include "SixteenSegmentLED.h" #include "ChordButtons.h" #include "PianoButtons.h" #include "TRIS_Initialization.c" /* * */ #define numPins 45 // number of pins that are used as inputs uint8_t output[numPins] = {0}; // initialize all output values to 0 static uint8_t oldvalue[numPins] = {0}; // initialize all oldvalues to 0 static uint8_t flag[numPins] = {0}; // initialize all flag variables to 0 static uint8_t flag2[8] = {0}; // initialize all flag2 variables to 0 static uint8_t LEDon[8] = {0}; // initialize all LEDon variables to 0 static uint8_t oldA = 0; uint8_t key = 1; uint8_t temp; // initialize a temporary variable for calculations #define A 8 #define B 9 #define buttonPress 1 // pressing the button grounds the pin #define t2intflag IFS0bits.T2IF // interupt flag bit for timer 2 #define i2cflag IFS1bits. //I2C #define receive_reg I2C1RCV //I2C long long playThis = 0x0000000000000000; _CONFIG1( JTAGEN_OFF); //Turn off JTAG so A0 and A1 are Digital I/O pins unsigned char sendByte1 = 0; unsigned char sendByte2 = 0; unsigned char sendByte3 = 0; unsigned char sendByte4 = 0; unsigned char sendByte5 = 0; void initiateClock(void){ OSCCONbits.COSC = 0b001; // sets system clock to Fosc and PLL CLKDIVbits.RCDIV = 0b000; // divides clk by 1 = 8 MHz /* Clock appears to operate at 16 MHz*/ } void initiateTimer() { T2CON = 0x0; // clear control register & stop timer // T2CON<15> enables timer (0=off, 1=on) // T2CON<1> = 0 selects PBCLK source (TCS) // T2CON<7> = 0 selectrs PBCLK source (TGATE) // set prescale value to 256 T2CONbits.TCKPS1 = 1; T2CONbits.TCKPS0 = 1; PR2 = 16; // set PR2 register to 31 - creates interrupt every ~2 ms /* formula is Fosc/2 (4MHz) / (prescaler (256) * PR2 (16) * 2) = timer frequency 1/timer frequency = timer period */ T2CONbits.TSIDL = 0; // continue in idle mode T2CONbits.T32 = 0; // act as 16 bit timer T2CONbits.TCS = 0; // use internal clock (Fosc/2) T2CONbits.TGATE = 0; // disable gated time accumulation t2intflag = 0; // clear the interrupt flag status TMR2 = 0; // clear timer register T2CONbits.TON = 1; // start timer } void initializeInterrupts(){ INTCON1bits.NSTDIS = 1; // nested interrupts are not desired IEC0bits.T2IE = 1; // enable interrupt for Timer 2 IPC1bits.T2IP = 0b111; // set priority to highest (7) t2intflag = 0; // clear the interrupt flag status IEC1bits.SI2C1IE = 1; // enable interrupt } void sendBytes(unsigned long long playThis){ sendByte1 = playThis>>56 & 0xFF; sendByte2 = (0xFF & (playThis>>48)); sendByte3 = (0xFF & (playThis>>40)); sendByte4 = (0xFF & (playThis>>32)); sendByte5 = (0xFF & (playThis>>24)); } void updateEffectsButtons(uint8_t output[]){ unsigned long long temp = 1; if(output[0]==1 && flag2[0]==0 && LEDon[0] == 0){EF1_L=0; flag2[0]=1; LEDon[0] = 1; LEDon[1] = 0; EF2_L=1; LEDon[2] = 0; EF3_L=1; LEDon[3] = 0; EF4_L=1; LEDon[4] = 0; EF5_L=1; LEDon[5] = 0; EF6_L=1; playThis = (playThis | (temp<<27));} // turn LED on and the mode else if (output[0]==1 && flag2[0]==0 && LEDon[0] == 1){EF1_L=0; flag2[0]=1; // turn LED off LEDon[0] = 1; playThis = (playThis | (temp<<27)); // turn on 1st LED and go back to standard mode } else {flag2[0]=output[0];} if(output[1]==1 && flag2[1]==0 && LEDon[1] == 0){EF2_L=0; flag2[1]=1; LEDon[1] = 1; LEDon[0] = 0; EF1_L=1; LEDon[2] = 0; EF3_L=1; LEDon[3] = 0; EF4_L=1; LEDon[4] = 0; EF5_L=1; LEDon[5] = 0; EF6_L=1; playThis = (playThis | (temp<<26));} // turn LED on else if (output[1]==1 && flag2[1]==0 && LEDon[1] == 1){EF2_L=1; flag2[1]=1; LEDon[1] = 0;// turn LED off LEDon[0] = 1; EF1_L=0; playThis = (playThis | (temp<<27)); // turn on 1st LED and go back to standard mode } else {flag2[1]=output[1];} if(output[2]==1 && flag2[2]==0 && LEDon[2] == 0){EF3_L=0; flag2[2]=1; LEDon[2] = 1; LEDon[0] = 0; EF1_L=1; LEDon[1] = 0; EF2_L=1; LEDon[3] = 0; EF4_L=1; LEDon[4] = 0; EF5_L=1; LEDon[5] = 0; EF6_L=1; playThis = (playThis | (temp<<25));} // turn LED on else if (output[2]==1 && flag2[2]==0 && LEDon[2] == 1){EF3_L=1; flag2[2]=1; LEDon[2] = 0; // turn LED off LEDon[0] = 1; EF1_L=0; playThis = (playThis | (temp<<27)); // turn on 1st LED and go back to standard mode } else {flag2[2]=output[2];} if(output[3]==1 && flag2[3]==0 && LEDon[3] == 0){EF4_L=0; flag2[3]=1; LEDon[3] = 1; LEDon[0] = 0; EF1_L=1; LEDon[1] = 0; EF2_L=1; LEDon[2] = 0; EF3_L=1; LEDon[4] = 0; EF5_L=1; LEDon[5] = 0; EF6_L=1; playThis = (playThis | (temp<<27));} // turn LED on else if (output[3]==1 && flag2[3]==0 && LEDon[3] == 1){EF4_L=1; flag2[3]=1; LEDon[3] = 0; // turn LED off LEDon[0] = 1; EF1_L=0; playThis = (playThis | (temp<<27)); // turn on 1st LED and go back to standard mode } // turn LED off else {flag2[3]=output[3];} if(output[4]==1 && flag2[4]==0 && LEDon[4] == 0){EF5_L=0; flag2[4]=1; LEDon[4] = 1; LEDon[0] = 0; EF1_L=1; LEDon[1] = 0; EF2_L=1; LEDon[2] = 0; EF3_L=1; LEDon[3] = 0; EF4_L=1; LEDon[5] = 0; EF6_L=1; playThis = (playThis | (temp<<27));} // turn LED on else if (output[4]==1 && flag2[4]==0 && LEDon[4] == 1){EF5_L=1; flag2[4]=1; LEDon[4] = 0; // turn LED off LEDon[0] = 1; EF1_L=0; playThis = (playThis | (temp<<27)); // turn on 1st LED and go back to standard mode } else {flag2[4]=output[4];} if(output[5]==1 && flag2[5]==0 && LEDon[5] == 0){EF6_L=0; flag2[5]=1; LEDon[5] = 1; LEDon[0] = 0; EF1_L=1; LEDon[1] = 0; EF2_L=1; LEDon[2] = 0; EF3_L=1; LEDon[3] = 0; EF4_L=1; LEDon[4] = 0; EF5_L=1; playThis = (playThis | (temp<<27));} // turn LED on else if (output[5]==1 && flag2[5]==0 && LEDon[5] == 1){EF6_L=1; flag2[5]=1; LEDon[5] = 0; // turn LED off LEDon[0] = 1; EF1_L=0; playThis = (playThis | (temp<<27)); // turn on 1st LED and go back to standard mode } else {flag2[5]=output[5];} if(output[6]==1 && flag2[6]==0 && LEDon[6] == 0){EF7_L=0; flag2[6]=1; LEDon[6] = 1;} // turn LED on else if (output[6]==1 && flag2[6]==0 && LEDon[6] == 1){EF7_L=1; flag2[6]=1; LEDon[6] = 0;} // turn LED off else {flag2[6]=output[6];} if(output[7]==1 && flag2[7]==0 && LEDon[7] == 0){EF8_L=0; flag2[7]=1; LEDon[7] = 1;} // turn LED on else if (output[7]==1 && flag2[7]==0 && LEDon[7] == 1){EF8_L=1; flag2[7]=1; LEDon[7] = 0;} // turn LED off else {flag2[7]=output[7];} if(LEDon[0]==1){playThis = (playThis | (temp<<27));} else if(LEDon[1]==1){playThis = (playThis | (temp<<26));} else if(LEDon[2]==1){playThis = (playThis | (temp<<25));} else if(LEDon[3]==1){playThis = (playThis | (temp<<27));} else if(LEDon[4]==1){playThis = (playThis | (temp<<27));} else if(LEDon[5]==1){playThis = (playThis | (temp<<27));} } void updateQuadEncoder(uint8_t output[]){ if(output[A]==1 && oldA==0 && output[B]==0){ if(key==11){key=0;} else key++; } else if(output[A]==1 && oldA==0 && output[B]==1){ if(key==0){key=11;} else key--; } else {} oldA=output[A]; switch (key){ case 0: Display_C(); break; case 1: Display_C_Sharp(); break; case 2: Display_D(); break; case 3: Display_D_Sharp(); break; case 4: Display_E(); break; case 5: Display_F(); break; case 6: Display_F_Sharp(); break; case 7: Display_G(); break; case 8: Display_G_Sharp(); break; case 9: Display_A(); break; case 10: Display_A_Sharp(); break; case 11: Display_B(); break; default: Display_All(); break; } } void updateStates(uint8_t output[]){ updateQuadEncoder(output); updateChordButtons(output); updatePianoKeys(output); updateEffectsButtons(output); /* if(output[1]==1){EF2_L=0;} // turn LED on else EF2_L=1; // turn LED off if(output[2]==1){EF3_L=0;} // turn LED on else EF3_L=1; // turn LED off if(output[3]==1){EF4_L=0;} // turn LED on else EF4_L=1; // turn LED off if(output[4]==1){EF5_L=0;} // turn LED on else EF5_L=1; // turn LED off if(output[5]==1){EF6_L=0;} // turn LED on else EF6_L=1; // turn LED off if(output[6]==1){EF7_L=0;} // turn LED on else EF7_L=1; // turn LED off if(output[7]==1){EF8_L=0;} // turn LED on else EF8_L=1; // turn LED off //if(output[8]==1){DOon} //else DOoff; */ } uint8_t number; void debounce_switches(void){ for (number=0; number> 2); // divide oldvalue by 4 oldvalue[number] = oldvalue[number] - temp; // create 0.75*oldvalue by subtraction /* Check respective pin, add .25 of newvalue to oldvalue */ switch (number){ case 0: if(EF1_B==buttonPress){oldvalue[number] = oldvalue[number]+0x3F;} // 0x3F is about 0.25 of a uint8 break; case 1: if(EF2_B==buttonPress){oldvalue[number] = oldvalue[number]+0x3F;} break; case 2: if(EF3_B==buttonPress){oldvalue[number] = oldvalue[number]+0x3F;} break; case 3: if(EF4_B==buttonPress){oldvalue[number] = oldvalue[number]+0x3F;} break; case 4: if(EF5_B==buttonPress){oldvalue[number] = oldvalue[number]+0x3F;} break; case 5: if(EF6_B==buttonPress){oldvalue[number] = oldvalue[number]+0x3F;} break; case 6: if(EF7_B==buttonPress){oldvalue[number] = oldvalue[number]+0x3F;} break; case 7: if(EF8_B==buttonPress){oldvalue[number] = oldvalue[number]+0x3F;} break; case 8: if(QUAD_SIG_A==buttonPress){oldvalue[number] = oldvalue[number]+0x3F;} break; case 9: if(QUAD_SIG_B==buttonPress){oldvalue[number] = oldvalue[number]+0x3F;} break; case 10: if(PIANO1==buttonPress){oldvalue[number] = oldvalue[number]+0x3F;} break; case 11: if(PIANO2==buttonPress){oldvalue[number] = oldvalue[number]+0x3F;} break; case 12: if(PIANO3==buttonPress){oldvalue[number] = oldvalue[number]+0x3F;} break; case 13: if(PIANO4==buttonPress){oldvalue[number] = oldvalue[number]+0x3F;} break; case 14: if(PIANO5==buttonPress){oldvalue[number] = oldvalue[number]+0x3F;} break; case 15: if(PIANO6==buttonPress){oldvalue[number] = oldvalue[number]+0x3F;} break; case 16: if(PIANO7==buttonPress){oldvalue[number] = oldvalue[number]+0x3F;} break; case 17: if(PIANO8==buttonPress){oldvalue[number] = oldvalue[number]+0x3F;} break; case 18: if(PIANO9==buttonPress){oldvalue[number] = oldvalue[number]+0x3F;} break; case 19: if(PIANO10==buttonPress){oldvalue[number] = oldvalue[number]+0x3F;} break; case 20: if(PIANO11==buttonPress){oldvalue[number] = oldvalue[number]+0x3F;} break; case 21: if(PIANO12==buttonPress){oldvalue[number] = oldvalue[number]+0x3F;} break; case 22: if(PIANO13==buttonPress){oldvalue[number] = oldvalue[number]+0x3F;} break; case 23: if(PIANO14==buttonPress){oldvalue[number] = oldvalue[number]+0x3F;} break; case 24: if(PIANO15==buttonPress){oldvalue[number] = oldvalue[number]+0x3F;} break; case 25: if(PIANO16==buttonPress){oldvalue[number] = oldvalue[number]+0x3F;} break; case 26: if(PIANO17==buttonPress){oldvalue[number] = oldvalue[number]+0x3F;} break; case 27: if(PIANO18==buttonPress){oldvalue[number] = oldvalue[number]+0x3F;} break; case 28: if(PIANO19==buttonPress){oldvalue[number] = oldvalue[number]+0x3F;} break; case 29: if(PIANO20==buttonPress){oldvalue[number] = oldvalue[number]+0x3F;} break; case 30: if(PIANO21==buttonPress){oldvalue[number] = oldvalue[number]+0x3F;} break; case 31: if(PIANO22==buttonPress){oldvalue[number] = oldvalue[number]+0x3F;} break; case 32: if(PIANO23==buttonPress){oldvalue[number] = oldvalue[number]+0x3F;} break; case 33: if(PIANO24==buttonPress){oldvalue[number] = oldvalue[number]+0x3F;} break; case 34: if(PIANO25==buttonPress){oldvalue[number] = oldvalue[number]+0x3F;} break; case 35: if(CHORD1==buttonPress){oldvalue[number] = oldvalue[number]+0x3F;} break; case 36: if(CHORD2==buttonPress){oldvalue[number] = oldvalue[number]+0x3F;} break; case 37: if(CHORD3==buttonPress){oldvalue[number] = oldvalue[number]+0x3F;} break; case 38: if(CHORD4==buttonPress){oldvalue[number] = oldvalue[number]+0x3F;} break; case 39: if(CHORD5==buttonPress){oldvalue[number] = oldvalue[number]+0x3F;} break; case 40: if(CHORD6==buttonPress){oldvalue[number] = oldvalue[number]+0x3F;} break; case 41: if(CHORD7==buttonPress){oldvalue[number] = oldvalue[number]+0x3F;} break; case 42: if(MODE_1==buttonPress){oldvalue[number] = oldvalue[number]+0x3F;} break; case 43: if(MODE_2==buttonPress){oldvalue[number] = oldvalue[number]+0x3F;} break; default: break; } /* Schmidt trigger - if 0.25*newvalue + 0.75*oldvalue is above or below 0.5*/ if((oldvalue[number] > 0xF0)&&(flag[number]==0)){flag[number]=1; output[number]=1;} if((oldvalue[number] < 0x0F)&&(flag[number]==1)){flag[number]=0; output[number]=0;} } updateStates(output); // change outputs according to whether the button is pushed or not } #define CHORDI 0x8900000000000000 #define CHORDII 0x2440000000000000 #define CHORDIII 0x0910000000000000 #define CHORDIV 0x0448000000000000 #define CHORDV 0x0112000000000000 #define CHORDVI 0x0048800000000000 #define CHORDVII 0x0012400000000000 void updateChordButtons(uint8_t output[]){ unsigned long long chord = 0; playThis = 0x0000000000000000; // initialize it if(output[35]==1) // if the chord button I is pressed {chord = CHORDI;} else if(output[36]==1) // if the chord button II is pressed {chord = CHORDII;} else if(output[37]==1){ // if the chord button III is pressed chord = CHORDIII;} else if(output[38]==1){ // if the chord button III is pressed chord = CHORDIV;} else if(output[39]==1){ // if the chord button III is pressed chord = CHORDV;} else if(output[40]==1){ // if the chord button III is pressed chord = CHORDVI;} else if(output[41]==1){ // if the chord button III is pressed chord = CHORDVII;} playThis = (playThis | (chord>>key)); // add chord frequencies } #define CdontPlay 0xAD5AD5FFFFFFFFFF void updatePianoKeys(uint8_t output[]){ uint8_t counter; long long temp; long long dontPlay = CdontPlay; if(output[42]==1) // if STANDARD MODE (play keyboard as normal) (MODE_1 == 1) { for (counter=0; counter<25; counter++) { temp = output[10+counter]; // need a long long variable if we're going to shift it playThis = (playThis | (temp<<(63-counter))); // put button info into a long long variable "playThis" } } else{ // ASSIST MODE (move the data around so that the keys being played correspond to the right key for (counter=0; counter<25; counter++) { temp = output[10+counter]; // go through the piano buttons on the board playThis = (playThis | (temp<<(63-key-counter))); } // get rid of notes that shouldn't be played (0 = don't play, 1 = don't care) dontPlay = dontPlay>>key; // shift the keyboard over to make "key" be C playThis = (playThis & dontPlay); } } void __attribute__((__interrupt__, __shadow__)) _T2Interrupt(void) { debounce_switches(); t2intflag = 0; //Reset Timer2 interrupt flag and Return from ISR } void initializeI2C(void){ I2C1BRG = 156; //132 // I21BRG = (1/I2C_CLK - 130ns)*SYS_CLK-2 // made clock 400 kHz // 156 makes it 100 kHz I2C1CONbits.I2CSIDL = 0; // operate in idle mode I2C1CONbits.IPMIEN = 0; // ????? I2C1CONbits.A10M = 0; // 7 bit slave address I2C1CONbits.DISSLW = 1; // disable slew rate control I2C1CONbits.SMEN = 1; // enable pin thresholds I2C1CONbits.STREN = 0; // disable clock stretching I2C1CONbits.ACKDT = 1; // send NACK during Acknowledge I2C1CONbits.I2CEN = 1; // enable I2C module } unsigned char buttonsToByte(char B1, char B2, char B3, char B4, char B5, char B6, char B7, char B8){ unsigned char buttonByte=0x00; buttonByte = B1<<7; buttonByte = (buttonByte | (B2<<6)); buttonByte = (buttonByte | (B3<<5)); buttonByte = (buttonByte | (B4<<4)); buttonByte = (buttonByte | (B5<<3)); buttonByte = (buttonByte | (B6<<2)); buttonByte = (buttonByte | (B7<<1)); buttonByte = (buttonByte | (B8)); return buttonByte; } int main(int argc, char** argv) { initiateClock(); initiateTimer(); initializeInterrupts(); initialize_tris(); initializeI2C(); LEDon[0]=1; EF1_L=0; //Initialize Tris TRISAbits.TRISA15 = 1; TRISAbits.TRISA5 = 1; TRISAbits.TRISA4 = 1; TRISAbits.TRISA14 = 1; // PORT C TRISCbits.TRISC13 = 1; TRISCbits.TRISC15 = 1; TRISCbits.TRISC12 = 1; // TRISCbits.TRISC14 = 1; // PORT D TRISDbits.TRISD1 = 1; TRISDbits.TRISD3 = 1; TRISDbits.TRISD9 = 1; TRISDbits.TRISD11 = 1; TRISDbits.TRISD0 = 1; TRISDbits.TRISD2 = 1; TRISDbits.TRISD8 = 1; TRISDbits.TRISD10 = 1; /*Listen Button*/ TRISDbits.TRISD7 = 1; TRISDbits.TRISD6 = 1; /*Quadrature Encoder*/ TRISDbits.TRISD4 = 1; TRISDbits.TRISD5 = 1; /*Mode Switch*/ TRISDbits.TRISD13 = 1; TRISDbits.TRISD12 = 1; /*Piano Buttons*/ AD1PCFG = 0xFFFF; //Set B Register to Digital TRISAbits.TRISA0 = 1; TRISEbits.TRISE8 = 1; TRISEbits.TRISE9 = 1; TRISBbits.TRISB5 = 1; TRISBbits.TRISB4 = 1; TRISBbits.TRISB3 = 1; TRISAbits.TRISA9 = 1; TRISAbits.TRISA10 = 1; TRISBbits.TRISB8 = 1; TRISBbits.TRISB9 = 1; TRISBbits.TRISB10 = 1; TRISBbits.TRISB11 = 1; TRISAbits.TRISA1 = 1; TRISFbits.TRISF13 = 1; TRISFbits.TRISF12 = 1; TRISBbits.TRISB12 = 1; TRISBbits.TRISB13 = 1; TRISBbits.TRISB14 = 1; TRISBbits.TRISB15 = 1; TRISDbits.TRISD14 = 1; TRISDbits.TRISD15 = 1; TRISFbits.TRISF4 = 1; TRISFbits.TRISF5 = 1; TRISFbits.TRISF3 = 1; TRISFbits.TRISF2 = 1; /*Chord Buttons*/ TRISCbits.TRISC1 = 1; TRISCbits.TRISC2 = 1; TRISCbits.TRISC3 = 1; TRISCbits.TRISC4 = 1; TRISGbits.TRISG6 = 1; TRISGbits.TRISG7 = 1; TRISGbits.TRISG8 = 1; /* 16 Segment LED*/ // PORT A TRISAbits.TRISA6 = 1; TRISAbits.TRISA7 = 1; // PORT E TRISEbits.TRISE0 = 1; TRISEbits.TRISE1 = 1; TRISEbits.TRISE2 = 1; TRISEbits.TRISE3 = 1; TRISEbits.TRISE4 = 1; TRISEbits.TRISE5 = 1; TRISEbits.TRISE6 = 1; TRISEbits.TRISE7 = 1; // PORT F TRISFbits.TRISF1 = 1; // PORT G TRISGbits.TRISG0 = 1; TRISGbits.TRISG1 = 1; TRISGbits.TRISG12 = 1; TRISGbits.TRISG13 = 1; TRISGbits.TRISG14 = 1; TRISGbits.TRISG15 = 1; char t; while(1){ sendBytes(playThis); //sendByte2=0b00010000; StartI2C1(); IdleI2C1(); t = MasterputcI2C1(0b10101010); //Address Byte IdleI2C1(); t = MasterputcI2C1(sendByte1); //Send First Byte (C1:G1) IdleI2C1(); t = MasterputcI2C1(sendByte2); //Send Second Byte (G#1:D#2) IdleI2C1(); t = MasterputcI2C1(sendByte3); //Send Third Byte (E2:B3) IdleI2C1(); t = MasterputcI2C1(sendByte4); //Send Fourth Byte (C3:G3) IdleI2C1(); t = MasterputcI2C1(sendByte5); //Send FIfth Byte (G#3:B4 and EF1:EF4) IdleI2C1(); StopI2C1(); IdleI2C1(); } return (EXIT_SUCCESS); }