You are on page 1of 24

//ME1 ok input (final)

//ME1 latest ok all input! 15%

#include "xc.h"
_CONFIG1 (FWDTEN_OFF & JTAGEN_OFF)
_CONFIG2 (POSCMOD_NONE & OSCIOFNC_ON & FCKSM_CSDCMD &
FNOSC_FRCPLL & PLL96MHZ_OFF & PLLDIV_NODIV)
_CONFIG3 (SOSCSEL_IO)

// Delay Timers
#define DELAY15 4000 // Computed Value: 3750
#define DELAY4p1 2000 // Computed Value: 1025
#define DELAY1u 10 // Computed Value: 1
#define DEB_MAX 10000 // Debounce Delay
//LCD FUNCTIONS
// Writing Functions
void write(int rs, int db4, int db5, int db6, int db7); // Program LCD by bits
void write2(int hex); // Display a character in the LCD. May use hex or ''.
void enable(void); // Enables and Disables the Enable pin in LCD
void second_line(void); // Moves cursor to the second line
void first_line(void);
// Moving Functions
void moveright(void); // Move cursor one space to the right
void moveleft(void);
// Delay Functions
void delay15ms(void); // Delay by (at least) 15ms
void delay4p1ms(void); // Delay by (at least) 4.1ms
void delay1us(void); // Delay by (at least) 1us
void delay500ms(void);
void delay250ms(void);
// LCD Initialization Functions
void fset(void); // Function set
void set4bit(void); // Sets LCD to 4-bit mode
void setNF(void); // Sets number of lines and character format
void displayOFF(void); // Turn OFF LCD display
void clrDisplay(void); // Clear LCD display
void entryMode(void); // Set LCD's entry mode: increment and shift
void displayON(void); // Turn ON LCD display
void initLCD(void); // Culmination of all LCD initialization functions
// LCD Variables
int hex, un, ln; // Hex, Upper Nibble/Number, Lower Nibble/Number
int N = 1; // Flag: Number of lines = 2
int F = 0; // Flag: 5x7 Character
int I = 1; // Flag: Increment
int S = 0; // Flag: Shift OFF
int C = 1; // Flag: Cursor ON
int B = 1; // Flag: Blink ON
int delay, delay1;

//KEYPAD FUNCTIONS
void __attribute__((interrupt)) _CNInterrupt(void);

void reset_press(void);

void col1(void);
void col2(void);
void col3(void);

int row1_press;
int row2_press;
int row3_press;
int row4_press;

//composer
int flag; //distinguishes rest from note eg. no sharps and octaves in rest
int index = 0; //limit = 18, max number of notes allowed
int cursor = 0; //cursor counter for lcd display
int a[19]; //duration counter
int b[19]; //sharp flag 1 = # 0 = natural
int d[19]; //toggle for octave 1 = 1st octave, 0 = 2nd octave
int countcursor;
int aold; //comparison for cursor spacing
int movecount;
char c[19]; //store note
int temp;

void duration(void); //compare flag, outputs actual note value


void octave(void); //toggles between 1st and 2nd octave
void cursorcount(void); //counts current cursor position
void checkline(void); //check if max number of notes per line (3/line)
void sharpcheck(void); //toggles # and natural
void sharp(void); //writes # when flag = 1
void durationupdatedec(void); //for decreasing the duration
void durationupdateinc(void); //for increasing the duration
void backspace(void); //delete function
void movecursor(void); //delete function (travelling from 2nd to 1st line)
void backscreen(void); //shows previous screen

int adcvalue;

void __attribute__ ((interrupt, no_auto_psv)) _ADC1Interrupt(void);

void setpwm(void);
void setoc1rs(void);
void playback(void);

int oc1rs;
int oc1r;

/* ===== START OF MAIN FUNCTION ===== */


void main(void){
// Set pins
AD1PCFG = 0xFDFF; // Set RB15/AN9 as an analog pin
AD1CON1 = 0xA0E7; //1010 0000 1110 0111
AD1CON2 = 0x0000; //0000 0000 0000 0000
AD1CON3 = 0x0201; //0000 0010 0000 0001
AD1CHS = 0x0009; //0000 0000 0000 1001
AD1CSSL = 0x0000; //0000 0000 0000 0000
TRISA = 0xFFFF; // Set all RA as inputs
TRISB = 0x8028; // Set all RB as outputs, except RB15

IEC0bits.AD1IE = 1;//enable interrupt


IFS0bits.AD1IF = 0;//clear interrupt flag
AD1CON1bits.ADON = 1; //turn on ADC

__builtin_write_OSCCONL(OSCCON&(~(1<<6)));
RPOR3bits.RP7R = 0x12;
__builtin_write_OSCCONL(OSCCON|(1<<6));

initLCD();
/* Enable internal pullups
* RA0 - CN2 (CNPU1)
*/
CNPU1 = CNPU1 | 0x000C;
CNPU2 = CNPU2 | 0x6000;
/* Enable interrupts and clear IRQ flag
* RA0 - CN2 (CNEN1)
*/
CNEN1 = CNEN1 | 0x000C;
CNEN2 = CNEN2 | 0x6000;

IEC1bits.CNIE = 1;
IFS1bits.CNIF = 0;

/* Pull down col1 */

while(1){

if(PORTBbits.RB5 != 0){
delay500ms();
playback();
}

if(PORTBbits.RB3 != 0){
if(index > 0){
delay500ms();
backspace();
if(index % 3 == 1){
movecursor();
}
if(index % 6 == 1){
backscreen();
}
index = index - 1;
if(index == 0){
clrDisplay();
}
}
}

col1();
delay15ms();

if (row1_press){//1
reset_press();
delay500ms();
checkline();
flag = 0;
index = index + 1;
if(index<=18){
a[index] = 0;
b[index] = 0;
c[index] = 'c';
d[index] = 1;
duration();
write2(c[index]);
write2('1');
moveright();
countcursor = 4;
setpwm();
}
else{
index = 18;
}
row1_press = 0; //clear flag
}

if (row2_press){//4
reset_press();
delay500ms();
checkline();
flag = 0;
index = index + 1;
if(index<=18){
a[index] = 0;
b[index] = 0;
c[index] = 'f';
d[index] = 1;
duration();
write2(c[index]);
write2('1');
moveright();
countcursor = 4;
setpwm();
}
else{
index = 18;
}
row2_press = 0; //clear flag
}

if (row3_press){//7
reset_press();
delay500ms();
checkline();
flag = 0;
index = index + 1;
if(index<=18){
a[index] = 0;
b[index] = 0;
c[index] = 'b';
d[index] = 1;
duration();
write2(c[index]);
write2('1');
moveright();
countcursor = 4;
setpwm();
}
else{
index = 18;
}
row3_press = 0; //clear flag
}

if (row4_press){//10
reset_press();
if (index > 0){
if (flag == 0){
delay500ms();
moveleft();
moveleft();
d[index] = !d[index];
octave();
setpwm();
}
}
row4_press = 0; //clear flag
}

col2();
delay15ms();
if (row1_press){//2
reset_press();
delay500ms();
checkline();
flag = 0;
index = index + 1;
if(index<=18){
a[index] = 0;
b[index] = 0;
c[index] = 'd';
d[index] = 1;
duration();
write2(c[index]);
write2('1');
moveright();
countcursor = 4;
setpwm();
}
else{
index = 18;
}
row1_press = 0; //clear flag
}

if (row2_press){//5
reset_press();
delay500ms();
checkline();
flag = 0;
index = index + 1;
if(index<=18){
a[index] = 0;
b[index] = 0;
c[index] = 'g';
d[index] = 1;
duration();
write2(c[index]);
write2('1');
moveright();
countcursor = 4;
setpwm();
}
else{
index = 18;
}
row2_press = 0; //clear flag
}

if (row3_press){//8
reset_press();
if (index > 0){
delay500ms();
aold = a[index];
a[index] = a[index] - 1;
if(a[index] >= -2){
durationupdatedec();
}
else{
a[index] = aold;
}
}
setpwm();
row3_press = 0; //clear flag
}

if (row4_press){//0
reset_press();
delay500ms();
checkline();
flag = 1;
index = index + 1;
if(index<=18){
a[index] = 0;
b[index] = 0;
c[index] = '-';
d[index] = 1;
duration();
write2(c[index]);
moveright();
countcursor = 3;
}
else{
index = 18;
}
row4_press = 0; //clear flag
}

col3();
delay15ms();

if (row1_press){//3
reset_press();
delay500ms();
checkline();
flag = 0;
index = index + 1;
if(index<=18){
a[index] = 0;
b[index] = 0;
c[index] = 'e';
d[index] = 1;
duration();
write2(c[index]);
write2('1');
moveright();
countcursor = 4;
setpwm();
}
else{
index = 18;
}
row1_press = 0; //clear flag
}

if (row2_press){//6
reset_press();
delay500ms();
checkline();
flag = 0;
index = index + 1;
if(index<=18){
a[index] = 0;
b[index] = 0;
c[index] = 'a';
d[index] = 1;
duration();
write2(c[index]);
write2('1');
moveright();
countcursor = 4;
setpwm();
}
else{
index = 18;
}
row2_press = 0; //clear flag
}

if (row3_press){//8
reset_press();
if (index > 0){
delay500ms();
aold = a[index];
a[index] = a[index] + 1;
if(a[index] <= 3){
durationupdateinc();
}
else{
a[index] = aold;
}
}
setpwm();
row3_press = 0; //clear flag
}

if (row4_press){//11
reset_press();
if (index > 0){
if (flag == 0){
if(c[index] != 'e' && c[index] != 'b'){
delay500ms();
b[index] = !b[index];
sharpcheck();
}
}
}
setpwm();
row4_press = 0; //clear flag
}

}
return 0;
}
/* ===== END OF MAIN FUNCTION ===== */

// Delay Functions
void delay500ms(void){
delay1 = 0;
while(delay1 < 40){
delay1++;
delay = 0;
while(delay < DELAY15){
delay++;
}
}
}
void delay250ms(void){
delay1 = 0;
while(delay1 < 20){
delay1++;
delay = 0;
while(delay < DELAY15){
delay++;
}
}
}
void delay15ms(void){
delay = 0;
while(delay < DELAY15){
delay++;
}
}
void delay4p1ms(void){
delay = 0;
while(delay < DELAY4p1){
delay++;
}
}
void delay1us(void){
delay = 0;
while(delay < DELAY1u){
delay++;
}
}

// Writing Functions
void enable(void){
LATBbits.LATB14 = 0b1;
LATBbits.LATB14 = 0b0;
delay1us();
}
void write(int rs, int db7, int db6, int db5, int db4){
LATBbits.LATB8 = db4;
LATBbits.LATB9 = db5;
LATBbits.LATB10 = db6;
LATBbits.LATB11 = db7;
LATBbits.LATB13 = rs;
enable();
delay1us();
}
void write2(int hex){
LATBbits.LATB13 = 1;
ln = hex%16;
un = (hex-ln)/16;
LATBbits.LATB8 = un%2;
LATBbits.LATB9 = (un/2)%2;
LATBbits.LATB10 = (un/4)%2;
LATBbits.LATB11 = (un/8)%2;
enable();
delay1us();
LATBbits.LATB8 = ln%2;
LATBbits.LATB9 = (ln/2)%2;
LATBbits.LATB10 = (ln/4)%2;
LATBbits.LATB11 = (ln/8)%2;
enable();
delay1us();
}
void second_line(void){
write(0,1,1,0,0);
write(0,0,0,0,0);
delay1us();
}
void first_line(void){
write(0,1,0,0,0);
write(0,0,0,0,0);
delay1us();
}

// LCD Initialization Functions


void fset(void){
write(0,0,0,1,1);
delay4p1ms();
}
void set4bit(void){
write(0,0,0,1,0);
delay4p1ms();
}
void setNF(void){
write(0,0,0,1,0);
write(0,N,F,0,0);
delay4p1ms();
}
void displayOFF(void){
write(0,0,0,0,0);
write(0,1,0,0,0);
delay4p1ms();
}
void clrDisplay(void){
write(0,0,0,0,0);
write(0,0,0,0,1);
delay4p1ms();
}
void entryMode(void){
write(0,0,0,0,0);
write(0,0,1,I,S);
delay4p1ms();
}
void displayON(void){
write(0,0,0,0,0);
write(0,1,1,C,B);
delay4p1ms();
}
void initLCD(void){
delay15ms();
fset();
delay4p1ms();
fset();
delay1us();
fset();
set4bit();
setNF();
displayOFF();
clrDisplay();
entryMode();
displayON();

// Moving Functions
void moveright(void){
write(0,0,0,0,1);
write(0,0,1,0,0);
delay1us();
}

void moveleft(void){
write(0,0,0,0,1);
write(0,0,0,0,0);
delay1us();
}

//keypad
void __attribute__((interrupt)) _CNInterrupt(void){
int deb_ctr = 0; //debounce counter

if (!PORTAbits.RA0){
/* Software debounce */
while ((!PORTAbits.RA0) && (deb_ctr < DEB_MAX)){
deb_ctr++;
}
if (deb_ctr == DEB_MAX)
row1_press = 1; //set flag
else
row1_press = 0;
}

if (!PORTAbits.RA1){
/* Software debounce */
while ((!PORTAbits.RA1) && (deb_ctr < DEB_MAX)){
deb_ctr++;
}
if (deb_ctr == DEB_MAX)
row2_press = 1; //set flag
else
row2_press = 0;
}

if (!PORTAbits.RA2){
/* Software debounce */
while ((!PORTAbits.RA2) && (deb_ctr < DEB_MAX)){
deb_ctr++;
}
if (deb_ctr == DEB_MAX)
row3_press = 1; //set flag
else
row3_press = 0;
}

if (!PORTAbits.RA3){
/* Software debounce */
while ((!PORTAbits.RA3) && (deb_ctr < DEB_MAX)){
deb_ctr++;
}
if (deb_ctr == DEB_MAX)
row4_press = 1; //set flag
else
row4_press = 0;
}

/* Clear IRQ flag */


IFS1bits.CNIF = 0;
}

void reset_press(void){
LATBbits.LATB4 = 1;
LATBbits.LATB5 = 1;
LATBbits.LATB7 = 1;
LATBbits.LATB8 = 1;
}

/* Pull down col1 */

void col1(void){
LATBbits.LATB0 = 0;
LATBbits.LATB1 = 1;
LATBbits.LATB2 = 1;
}

/* Pull down col2 */

void col2(void){
LATBbits.LATB0 = 1;
LATBbits.LATB1 = 0;
LATBbits.LATB2 = 1;
}

/* Pull down col3 */

void col3(void){
LATBbits.LATB0 = 1;
LATBbits.LATB1 = 1;
LATBbits.LATB2 = 0;
}

//composer
void duration(void){
if (a[index] == -2)
{write2('1');}
if (a[index] == -1)
{write2('2');}
if (a[index] == 0)
{write2('4');}
if (a[index] == 1)
{write2('8');}
if (a[index] == 2)
{write2('1');
write2('6');}
if (a[index] == 3)
{write2('3');
write2('2');}
}

void octave(void){
if (d[index] == 1){
write2('1');
}
else
{ write2('2');}
write2(' ');
}

void checkline(void){
if (index != 18){
if (index%3 == 0){
if (index%6 ==0){
clrDisplay();
}
else{
second_line();
}
}
}
}

void sharpcheck(void){
if (b[index] == 1){
moveleft();
moveleft();
moveleft();
write2('#');
write2(c[index]);
octave();
}
else{
moveleft();
moveleft();
moveleft();
moveleft();
write2(c[index]);
octave();
}
}

void cursorcount(void){
if (c[index] != '-'){
if (b[index] == 1){
if (a[index] > 1){
countcursor = 6;
}
else{
countcursor = 5;
}
}
else{
if (a[index] > 1){
countcursor = 5;
}
else{
countcursor = 4;
}
}
}
else{
if (a[index] > 1){
countcursor = 4;
}
else{
countcursor = 3;
}
}
}

void durationupdatedec(void){
if (aold == 2){
cursorcount();
countcursor = countcursor + 1;
}
else{
cursorcount();
}
movecount = countcursor;
while(movecount > 0){
moveleft();
movecount = movecount - 1;
}
duration();
if (b[index] == 1){
write2('#');
}
write2(c[index]);
if (c[index] != '-'){
octave();
}
else{
write2(' ');
}
}

void durationupdateinc(void){
cursorcount();
if (a[index] == 2){
countcursor = countcursor - 1;
}
movecount = countcursor;
while(movecount > 0){
moveleft();
movecount = movecount - 1;
}
duration();
if (b[index] == 1){
write2('#');
}
write2(c[index]);
if (c[index] != '-'){
octave();
}
else{
write2(' ');
}
}
void backspace(void){
cursorcount();
movecount = countcursor;
while(movecount > 0){
moveleft();
movecount = movecount - 1;
}
movecount = countcursor;
while(movecount > 0){
write2(' ');
movecount = movecount - 1;
}
movecount = countcursor;
while(movecount > 0){
moveleft();
movecount = movecount - 1;
}
}

void movecursor(void){
temp = index;
index = index - 3;
movecount = 0;
while (index != (temp-1)){
cursorcount();
movecount = movecount + countcursor;
index = index + 1;
}
movecount = movecount + 3;
first_line();
while(movecount >= 0){
moveright();
movecount = movecount - 1;
}
index = temp;
}

void backscreen(void){
clrDisplay();
first_line();
temp = index;
index = index - 6;
while (index != temp){
if(index == temp - 3){
second_line();
}
duration();
sharp();
write2(c[index]);
octave();
index = index + 1;
}
index = temp;
}

void sharp(void){
if (b[index] ==1){
write2('#');
}
}

//adc interrupt

void __attribute__ ((interrupt, no_auto_psv)) _ADC1Interrupt(void){


IEC0bits.AD1IE = 0;//Disable interrupt
IFS0bits.AD1IF = 0;//Clear flag
adcvalue = ADC1BUF0;
IEC0bits.AD1IE = 1;//Enable interrupt
IFS0bits.AD1IF = 0;//Clear flag
}

//pwm functions
void setpwm(void){
OC1CON1 = 0;
setoc1rs();
oc1r = oc1rs * 0.5;
OC1R = oc1r; //50%
OC1RS = oc1rs;
OC1CON2 = 0x021F;
OC1CON1 = 0x2008;
OC1CON1bits.OCM = 0b110;
//set value of PR2
T2CONbits.TON = 0b1;

delay250ms();

T2CONbits.TON = 0b0; //Initiate Timer 2


OC1CON1bits.OCM = 0b000; //Edge-Aligned
}

void setoc1rs(void){
if (c[index] == 'c'){ //C
if (b[index] == 1){ //C#
if (d[index] == 1){ //C#1
oc1rs = 14439;
}
else{ //C#2
oc1rs = 7219;
}
}
else{ //C
if (d[index] == 1){ //C1
oc1rs = 15266;
}
else{ //C2
oc1rs = 7647;
}
}
}
else if (c[index] == 'd'){ //D
if (b[index] == 1){ //D#
if (d[index] == 1){ //D#1
oc1rs = 12860;
}
else{ //D#2
oc1rs = 6429;
}
}
else{ //D
if (d[index] == 1){ //D1
oc1rs = 13650;
}
else{ //D2
oc1rs = 6813;
}
}
}
else if (c[index] == 'e'){ //E

if (d[index] == 1){ //E1


oc1rs = 12120;
}
else{ //E2
oc1rs = 6068;
}

}
else if (c[index] == 'f'){ //F
if (b[index] == 1){ //F#
if (d[index] == 1){ //F#1
oc1rs = 10809;
}
else{ //F#2
oc1rs = 5404;
}
}
else{ //F
if (d[index] == 1){ //F1
oc1rs = 11460;
}
else{ //F2
oc1rs = 5729;
}
}
}
else if (c[index] == 'g'){ //G
if (b[index] == 1){ //G#
if (d[index] == 1){ //G#1
oc1rs = 9637;
}
else{ //G#2
oc1rs = 4812;
}
}
else{ //G
if (d[index] == 1){ //G1
oc1rs = 10203;
}
else{ //G2
oc1rs = 5107;
}
}
}
else if (c[index] == 'a'){ //A
if (b[index] == 1){ //A#
if (d[index] == 1){ //A#1
oc1rs = 8582;
}
else{ //A#2
oc1rs = 4290;
}
}
else{ //A
if (d[index] == 1){ //A1
oc1rs = 9089;
}
else{ //A2
oc1rs = 4544;
}
}
}
else if (c[index] == 'b'){ //B
if (d[index] == 1){ //B1
oc1rs = 8096;
}
else{ //B2
oc1rs = 4047;
}
}
}

void playback(void){
temp = index;
index = 1;
while(index != (temp + 1)){
setpwm();
index = index + 1;
}
index = temp;
}

You might also like