/***************************************************************************** Microchip Memory Disk Drive File System ***************************************************************************** FileName: Demonstration1.c Dependencies: FSIO.h Processor: PIC32 Compiler: C32 Company: Microchip Technology, Inc. Software License Agreement The software supplied herewith by Microchip Technology Incorporated (the “Company”) for its PICmicro® Microcontroller is intended and supplied to you, the Company’s customer, for use solely and exclusively on Microchip PICmicro Microcontroller products. The software is owned by the Company and/or its supplier, and is protected under applicable copyright laws. All rights are reserved. Any use in violation of the foregoing restrictions may subject the user to criminal sanctions under applicable laws, as well as to civil liability for the breach of the terms and conditions of this license. THIS SOFTWARE IS PROVIDED IN AN “AS IS” CONDITION. NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. Note: This file is included to give you a basic demonstration of how the functions in this library work. Prototypes for these functions, along with more information about them, can be found in FSIO.h *****************************************************************************/ //DOM-IGNORE-BEGIN /******************************************************************** Change History: Rev Description ---- ----------------------- 1.3.0 Initial Revision 1.3.4 Cleaned up the unnecessary part of main() function. ********************************************************************/ //DOM-IGNORE-END /******************************************************************************* //NOTE : DISABLE MACRO "SUPPORT_LFN" IN "FSconfig.h" FILE TO WORK WITH THIS DEMO EFFECTIVELY. DISABLING "SUPPORT_LFN" WILL SAVE LOT OF MEMORY FOR THIS DEMO. ********************************************************************************/ #include "FSIO.h" #include #include #include #include #include unsigned char step =0; unsigned char ind = 0; unsigned char complete=0; unsigned char message[]; unsigned char ck_a=0; unsigned char ck_b=0; unsigned long mode; unsigned long test; unsigned char gps_file_created; unsigned char test_file_created; unsigned long numEg; //counter for engine rpm unsigned long numWh; //counter for wheel rpm int butpre1 = 0; //variable to be set to 1 when button is pressed, debouncing purposes int butpre2 = 0; //variable to be set to 1 when button is pressed, debouncing purposes unsigned char NOFIX[] = {'N','o',' ','F','i','x'}; unsigned char FIX[] = {' ',' ',' ','F','i','x'}; unsigned char RACE[] = {'R','a','c','e'}; unsigned char BUG[] = {'B','U','G'}; unsigned char TEST[] = {'T','e','s','t'}; #if defined (__PIC32MX__) #pragma config FPLLMUL = MUL_20 // PLL Multiplier #pragma config FPLLIDIV = DIV_2 // PLL Input Divider #pragma config FPLLODIV = DIV_1 // PLL Output Divider #pragma config FPBDIV = DIV_2 // Peripheral Clock divisor ****cahnged from DIV_2 #pragma config FWDTEN = OFF // Watchdog Timer #pragma config WDTPS = PS1 // Watchdog Timer Postscale #pragma config FCKSM = CSDCMD // Clock Switching & Fail Safe Clock Monitor #pragma config OSCIOFNC = OFF // CLKO Enable #pragma config POSCMOD = OFF // Primary Oscillator ****changed from HS #pragma config IESO = OFF // Internal/External Switch-over #pragma config FSOSCEN = OFF // Secondary Oscillator Enable (KLO was off) #pragma config FNOSC = FRCPLL // Oscillator Selection *****changed from PRIPLL #pragma config CP = OFF // Code Protect #pragma config BWP = OFF // Boot Flash Write Protect #pragma config PWP = OFF // Program Flash Write Protect #pragma config ICESEL = ICS_PGx1 // ICE/ICD Comm Channel Select ****changed from ICS_PGx2 #pragma config DEBUG = ON // Background Debugger Enable #endif void serial_init1(unsigned long value) { U3MODEbits.ON=1; U3MODEbits.BRGH=1; U3STAbits.UTXEN=1; U3STAbits.URXEN=1; unsigned long Fpb = 40000000; unsigned long num = Fpb/(4*value)-1; U3BRG = num; } void serial_init6(unsigned long value) { //U6MODEbits.ON=1; //U6MODEbits.BRGH=1; //U6STAbits.UTXEN=1; //U6STAbits.URXEN=1; //unsigned long Fpb = 10000000; //unsigned long num2 = 4*Fpb/(4*value)-1; //U6BRG = num2; } unsigned char getu1(void) { while(1) { if (U3STAbits.URXDA == 1) { char letter = U3RXREG; return letter; } } } unsigned char getu6(void) { //while(1) //{ // if (U6STAbits.URXDA == 1) // { // char letter3 = U6RXREG; // return letter3; // } //} } void putu1(unsigned char letter4) { while(1) { if (U3STAbits.UTXBF == 0) { U3TXREG = letter4; return; } } } void putu6(unsigned char letter2) { // while(1) // { // if (U6STAbits.UTXBF == 0) // { // U6TXREG = letter2; // return; // } // } } void enableInter(void) { INTCONbits.MVEC=1; IEC0bits.INT1IE=0; IEC0bits.INT2IE=0; IEC0bits.INT3IE=0; IEC0bits.INT4IE=0; IFS0bits.INT1IF=0; IFS0bits.INT2IF=0; IFS0bits.INT3IF=0; IFS0bits.INT4IF=0; IPC1bits.INT1IP = 7; IPC2bits.INT2IP = 6; IPC3bits.INT3IP = 4; IPC4bits.INT4IP = 3; INTCONbits.INT1EP=1; INTCONbits.INT2EP=1; INTCONbits.INT3EP=1; INTCONbits.INT4EP=1; IEC0bits.INT1IE=1; IEC0bits.INT2IE=1; IEC0bits.INT3IE=1; IEC0bits.INT4IE=1; IEC1bits.U3RXIE=1; IFS0bits.INT3IF=0; U3STAbits.URXISEL1=0; IPC7bits.U3IP=111; U3STAbits.URXISEL0=0; IFS1bits.U3RXIF=0; asm("ei"); //clear interrupt flag } void spiInit() { SPI4BRG = (40/(2*2))-1; TRISBbits.TRISB12=0; //CS output TRISBbits.TRISB14=0; //CLK output TRISFbits.TRISF4=1; //MISO input TRISFbits.TRISF5=0; //MOSI output LATBbits.LATB12=1; //CS high unsigned int left; left = SPI4BUF; SPI4STATCLR=0x40; SPI4CONbits.ON=1; SPI4CONbits.CKE=1; SPI4CONbits.CKP=0; SPI4CONbits.SMP=1; SPI4CONbits.MSTEN=1; SPI4CONbits.SRXISEL=00; } unsigned char swap(unsigned char info) { SPI4BUF=info; //while(!SPI4STATbits.SPIRBF); while(!SPILCD_INT); return SPI4BUF; SPILCD_INT=0; } void sndCMD (unsigned char comd[], unsigned char reply[]) { int n; int i; //send zero swap(0xFF); //send six command bytes for (n=0;n<6;n++) { swap(comd[n]); } //wait until reply is heard do { reply[0] = swap(0xFF); } while (reply[0]==0xFF); //read reply for (i=1;i<6;i++) { reply[i] = swap(0xFF); } return; } void sdInit () { spiInit(); int n; unsigned char comd[6]; comd[0]=0x40; comd[1]=0x00; comd[2]=0x00; comd[3]=0x00; comd[4]=0x00; comd[5]=0x95; unsigned char reply[6]; reply[0]=0x00; reply[1]=0x00; reply[2]=0x00; reply[3]=0x00; reply[4]=0x00; reply[5]=0x00; //wait for (n=0;n<25;n++) { swap(0xFF); } //set CS low LATBbits.LATB12=0; //wait for (n=0;n<25;n++) { swap(0xFF); } //send CMD0 sndCMD(comd,reply); //send CMD8 comd[0]=0x48; comd[1]=0x00; comd[2]=0x00; comd[3]=0x01; comd[4]=0xAA; comd[5]=0x87; sndCMD(comd,reply); do { //CMD55 inform SD of application specific command comd[0]=0x77; comd[1]=0x00; comd[2]=0x00; comd[3]=0x00; comd[4]=0x00; comd[5]=0x95; sndCMD(comd,reply); //ACMD41 to check if SD is out of idle state comd[0]=0x69; comd[1]=0x40; comd[2]=0x00; comd[3]=0x00; comd[4]=0x00; comd[5]=0x95; sndCMD(comd,reply); } while (reply[0]!=0x00); } void sdstuff () { FSFILE * pointer; char path[30]; char count = 30; char * pointer2; SearchRec rec; unsigned char attributes; unsigned char size = 0, i; // Turn on the interrupts //INTEnableSystemMultiVectoredInt(); //SYSTEMConfigPerformance(GetSystemClock()); //mOSCSetPBDIV(OSC_PB_DIV_2); //1) Initialize the RTCC //RtccInit(); //while(RtccGetClkStat()!=RTCC_CLK_ON); // wait for the SOSC to be actually running and RTCC to have its clock source //DelayMs(1000); // could wait here at most 32ms //RtccOpen(0x10073000, 0x07011602, 0); //2) Initialize SD Card sdInit(); SPI4BRG = 9; //TRISBbits.TRISB10=0; //WE //PORTBbits.RB10=1; //WE //TRISBbits.TRISB11=1; //CD //PORTBbits.RB11=1; //CD TRISBbits.TRISB12=0; //CS output TRISBbits.TRISB14=0; //CLK output TRISFbits.TRISF4=1; //MISO input TRISFbits.TRISF5=0; //MOSI output SD_CS=1; unsigned int empty_buff; empty_buff = SPI4BUF; SPI4CONbits.CKP = 0; SPI4CONbits.CKE = 1; SPI4CONbits.SMP=1; SPI4CONbits.MSTEN=1; SPI4CONbits.ON=1; /** int n; unsigned char comd[6]; comd[0]=0x40; comd[1]=0x00; comd[2]=0x00; comd[3]=0x00; comd[4]=0x00; comd[5]=0x95; unsigned char reply[6]; reply[0]=0x00; reply[1]=0x00; reply[2]=0x00; reply[3]=0x00; reply[4]=0x00; reply[5]=0x00; //wait for (n=0;n<25;n++) { swap(0xFF); } //set CS low SD_CS=0; //wait for (n=0;n<25;n++) { swap(0xFF); } //send CMD0 sndCMD(comd,reply); //send CMD8 comd[0]=0x48; comd[1]=0x00; comd[2]=0x00; comd[3]=0x01; comd[4]=0xAA; comd[5]=0x87; sndCMD(comd,reply); do { //CMD55 inform SD of application specific command comd[0]=0x77; comd[1]=0x00; comd[2]=0x00; comd[3]=0x00; comd[4]=0x00; comd[5]=0x95; sndCMD(comd,reply); //ACMD41 to check if SD is out of idle state comd[0]=0x69; comd[1]=0x40; comd[2]=0x00; comd[3]=0x00; comd[4]=0x00; comd[5]=0x95; sndCMD(comd,reply); } while (reply[0]!=0x00); //3) Media Detect //while(!MDD_SDSPI_MediaDetect()); // Initialize the library //4) FSInit //while (!FSInit()); */ SD_WE_TRIS=0; SD_WE=0x00; } void sd_ammend (char toSD[]) { #ifdef ALLOW_WRITES char newline[]="\r"; FSFILE * pointer; int length2 = strlen(toSD); pointer = FSfopen("GPSDATA.csv","a"); FSfwrite(toSD,1,length2,pointer); FSfclose(pointer); #endif } void sd_fammend (unsigned long tester) { #ifdef ALLOW_WRITES char newline[]="\r"; FSFILE * pointer; pointer = FSfopen("GPSDATA.csv","a"); FSfprintf(pointer,"%1d",tester); FSfclose(pointer); #endif } void lap_ammend (char toSD[]) { #ifdef ALLOW_WRITES char newline[]="\r"; FSFILE * pointer; int length2 = strlen(toSD); pointer = FSfopen("LAPTIMES.csv","a"); FSfwrite(toSD,1,length2,pointer); FSfclose(pointer); #endif } void lap_fammend (unsigned long tester) { #ifdef ALLOW_WRITES char newline[]="\r"; FSFILE * pointer; pointer = FSfopen("LAPTIMES.csv","a"); FSfprintf(pointer,"%1d",tester); FSfclose(pointer); #endif } void sd_try(float try) { #ifdef ALLOW_WRITES FSFILE * pointer; pointer = FSfopen("GPSDATA.csv","a"); FSfprintf(pointer,"%.3f",try); FSfclose(pointer); #endif } void sd_format (unsigned long UTCtime) { #ifdef ALLOW_WRITES char newline[]="\r"; char topline[]="Time (sec),Speed ((m/s)*10^2),Latitude ((deg)*10^6),Longitude ((deg)*10^6),Engine rpm,Wheel rpm"; char lapline[]="Lap,Lap Time (sec)\r"; FSFILE * pointer1; FSFILE * pointer2; int length1 = strlen(topline); int length2 = strlen(lapline); if (gps_file_created==0) { pointer1 = FSfopen("GPSDATA.csv","w"); FSfwrite(topline,1,length1,pointer1); FSfclose(pointer1); pointer2 = FSfopen("LAPTIMES.csv","w"); FSfwrite(lapline,1,length2,pointer2); FSfclose(pointer2); gps_file_created=1; } else { sd_ammend("New Data Set,UTC Time:,"); sd_fammend(UTCtime); sd_ammend("\r"); sd_ammend("New Data Set,UTC Time:,"); sd_fammend(UTCtime); sd_ammend("\r"); } #endif } void __ISR(_UART_3_VECTOR, IPL7AUTO) u1interrupt(void) { unsigned char disp1; disp1=getu1(); //get input from UART1 buffer //putu6(disp1); //send to UART6 for terminal IFS1bits.U3RXIF=0; //clear interrupt flag switch (step) { case 0: if (disp1==0xD0) { step=1; } else { step=0; } break; case 1: if (disp1==0xDD) { step=2; } else { step=0; } break; case 2: if (disp1==0x20) { ck_a=disp1; ck_b=ck_a; ind=0; step=3; } else { step=0; } break; case 3: message[ind]=disp1; ck_a=ck_a+disp1; ck_b=ck_b+ck_a; ind=ind+1; if (ind==32) { step=4; } break; case 4: if (ck_a==disp1) { step=5; } else { step=0; } break; case 5: if (ck_b==disp1) { complete=1; } step=0; break; default: step=0; } } void __ISR(_EXTERNAL_1_VECTOR, IPL7AUTO) INT1Interrupt(void) //LAP { //whatever the lap button does butpre1 = 1; IEC0bits.INT1IE=0; IFS0bits.INT1IF=0; } void __ISR(_EXTERNAL_2_VECTOR, IPL7AUTO) INT2Interrupt(void) //DONE { //whatever the stop button does butpre2 = 1; IEC0bits.INT2IE=0; IFS0bits.INT2IF=0; test=1; } void __ISR(_EXTERNAL_3_VECTOR, IPL7AUTO) INT3Interrupt(void) //ENGINE RPM { numEg=numEg+1; IFS0bits.INT3IF=0; } void __ISR(19, IPL7AUTO) INT4Interrupt(void) //WHEEL RPM { numWh=numWh+1; IFS0bits.INT4IF=0; } void excel_setup (unsigned long fix, unsigned long date, unsigned long UTCtime) { unsigned long yr; unsigned long day; unsigned long month; day = date/10000; date = date - day*10000; month = date/100; date = date - month*100; yr = date; sd_format(UTCtime); if (fix==3) { sd_ammend(","); sd_fammend(month); sd_ammend("/"); sd_fammend(day); sd_ammend("/"); sd_fammend(yr); sd_ammend(","); } else { sd_ammend(",DATE UNAVAILABLE"); } sd_ammend("\r"); } void gps_setting (unsigned char setting[]) { int n=0; while(setting[n]!='\0') { putu1(setting[n]); n=n+1; } } unsigned long value(unsigned int index) { unsigned long value1; value1 = message[index]; value1 = (value1<<8)+message[index-1]; value1 = (value1<<8)+message[index-2]; value1 = (value1<<8)+message[index-3]; return value1; } int main(int argc, char** argv) { numWh = 0; numEg = 0; //initialize UART for GPS and corresponding interrupts TRISGbits.TRISG6=1; TRISGbits.TRISG8=0; TRISGbits.TRISG7=1; TRISGbits.TRISG9=0; TRISDbits.TRISD8=1; TRISDbits.TRISD9=1; TRISDbits.TRISD10=1; TRISDbits.TRISD11=1 enableInter(); serial_init1(38400); gps_setting("$PGCMD,16,0,0,0,0,0*6A\r\n"); //initialize SD card and SPI LCD_init(); //sdstuff(); //Delayms(30); // int g=0; // // SD_CS =0; // while(g<15) // { // swap('V'); // g=g+1; // } // SD_CS =1; //initialize gps and set in binary mode //variable declarations unsigned long latit; unsigned long longit; unsigned long date; unsigned long speed; unsigned long fix; unsigned long t=0; unsigned long laptime=0; unsigned long laps=0; unsigned char formatted=0; unsigned long time_of_last_press; unsigned long butdec1 = 0; //counter to debounce button unsigned long butdec2 = 0; //counter to debounce button char PREVLAP[4]; char SPEED[3]; char testspd[3]; char DIG0[1]; char DIG1[1]; char DIG2[1]; char DIG3[1]; unsigned long UTCtime; mode=1; test=0; gps_file_created=0; unsigned long prevLAP=0; unsigned long speed2 = 2000; unsigned long dig0; unsigned long dig1; unsigned long dig2; unsigned long dig3; unsigned int fixset=0; unsigned int nofixset=0; unsigned int modeset=0; unsigned int velocityset=0; while(1) { //snd_cmd(0x51,0x00); //string_snd(tester,3); if (butpre1 == 1) //resets counter if button is pressed { butdec1 = 0; butpre1 = 0; test=2; } if (butpre2 == 1) //resets other counter if button is pressed { butdec2 = 0; butpre2 = 0; } if(butdec1 == 30000) //restarts the lap button interrupt { IFS0bits.INT1IF=0; IEC0bits.INT1IE=1; butdec1 = 0; } if(butdec2 == 30000) //restarts the stop button interrupt { IFS0bits.INT2IF=0; IEC0bits.INT2IE=1; butdec2 = 0; } ++butdec1; ++butdec2; //lap button activated if ((test==2)&&(mode==1)) { //snd_cmd(0x45,0x51); //string_snd(tester,3); prevLAP=t; t=0; sprintf(PREVLAP, "%ld", prevLAP); snd_cmd(0x45,0x5E); //Delayms(10); if(prevLAP < 10) { string_snd(PREVLAP,1); } else if(prevLAP < 100) { string_snd(PREVLAP,2); } else if(prevLAP<1000) { string_snd(PREVLAP,3); } else if(prevLAP>1000) { string_snd(PREVLAP,4); } else { string_snd(PREVLAP,0); } // laps++; // laptime=t-time_of_last_press; // time_of_last_press=t; // //// lap_fammend(laps); //// lap_ammend(","); //// lap_fammend(laptime); //// lap_ammend("\r"); //// //change screen display test=0; } //test mode activated if (test==1) { //formatted=0; //display speed on screen snd_cmd(0x45,0x46); string_snd(TEST,4); //when lap is pressed //create file if first time //delay 100ms //calculate rpm //output time and rpm to file } //race mode activated if (test==0) { if (modeset==0) { //Delayms(5); snd_cmd(0x45,0x46); //Delayms(10); string_snd(RACE,4); modeset=1; } if (complete==1) { //output rps char ERPS[3]; //Delayms(5); sprintf(ERPS, "%ld", numEg); snd_cmd(0x45,0x52); //Delayms(10); if(numEg < 10) { string_snd(ERPS,1); } else if((numEg < 100)&&(numEg>9)) { string_snd(ERPS,2); } else { string_snd(ERPS,3); } numEg=0; char RPS[3]; //Delayms(5); sprintf(RPS, "%ld", numWh); snd_cmd(0x45,0x12); // Delayms(10); if(numWh < 10) { string_snd(RPS,1); } else if((numWh < 100)&&(numWh>9)) { string_snd(RPS,2); } else { string_snd(RPS,3); } numWh=0; //output time t++; //sendValue(t,0x1D); char T[4]; //Delayms(5); sprintf(T, "%ld", t); snd_cmd(0x45,0x1D); //Delayms(20); if(t < 10) { string_snd(T,1); } else if(t < 100) { string_snd(T,2); } else if(t < 1000) { string_snd(T,3); } else { string_snd(T,4); } //extract values from message speed = value(15); latit = value(3); longit = value(7); date = value(25); UTCtime = value(29); fix = message[21]; if (fix!=3) { if (nofixset==0) { //Delayms(5); snd_cmd(0x45,0x22); //Delayms(10); string_snd(NOFIX,6); nofixset=1; fixset=0; } } else if (fix==3) { if (fixset==0) { //Delayms(5); snd_cmd(0x45,0x22); //Delayms(10); string_snd(FIX,6); fixset=1; nofixset=0; } } if (mode==0) { snd_cmd(0x45,0x06); //Delayms(10); string_snd(BUG,3); } if (mode==1) { //snd_cmd(0x45,0x46); //string_snd(RACE,6); //if this is the first message received, format the two excel sheets // if (formatted==0) // { //// excel_setup(fix,date,UTCtime); // formatted=1; // } //output data if gps fix exists if (fix==3) { //calc erpm and wrpm based on counters // sd_fammend(t); // sd_ammend(","); // sd_fammend(speed); // sd_ammend(","); // sd_fammend(latit); // sd_ammend(","); // sd_fammend(longit); // //sd_ammend(","); // //sd_fammend(erpm); // //sd_ammend(","); // //sd_fammend(wrpm); // sd_ammend("\r"); //screen displays speed and lap times // long speed3=speed; speed3=speed3*224; //sprintf(testspd,"%ld",speed3); //Delayms(5); snd_cmd(0x45,0x05); //Delayms(10); dig0=(speed3/100000)%10; dig1=(speed3/10000)%10; dig2=(speed3/1000)%10; dig3=speed3%1000; sprintf(DIG0,"%ld",dig0); sprintf(DIG1,"%ld",dig1); sprintf(DIG2,"%ld",dig2); sprintf(DIG3,"%ld",dig3); if (DIG0!=0) { string_snd(DIG0,1); } string_snd(DIG1,1); LCD_snd('.'); string_snd(DIG2,1); string_snd(DIG3,1); //snd_cmd(0x45,SPEED[0]); //snd_cmd(0x45,'.'); //snd_cmd(0x45,SPEED[1]); //snd_cmd(0x45,SPEED[2]) velocityset=0; } else { if (velocityset==0); { //Delayms(5); snd_cmd(0x45,0x05); //Delayms(10); dig0=0; dig1=0; dig2=0; dig3=0; sprintf(DIG0,"%ld",dig0); sprintf(DIG1,"%ld",dig1); sprintf(DIG2,"%ld",dig2); sprintf(DIG3,"%ld",dig3); string_snd(DIG0,1); string_snd(DIG1,1); LCD_snd('.'); string_snd(DIG2,1); string_snd(DIG3,1); // sd_fammend(t); // sd_ammend(","); // sd_ammend("NO GPS FIXXX0"); // sd_ammend("\r"); } velocityset=1; //screen displays zero for speed and normal lap time } complete=0; } } } } //return (EXIT_SUCCESS); }