//************************************************************* // EASY_MP3_AND_MIDI_PLAYER_ADD_I2C_LCD_24F // // MPEG Audio and MIDI Codec LSI: VS1053biEXT CLK:12.288MHz) // Used Microchip Memory Disk Drive File System:FAT16 // // Used I2C2 Module // // Condition: // 8MHz Internal RC oscillator, 4x PLL (8MHzx4= 32MHz) // Fcy=32MHz/2=16MHz, Tcy=62.5ns // // CPU: PIC24FJ64GA002 // // 2012/10/16: N.Ishii //************************************************************ /* Addition to Project File */ // Source Files Folder VS1011.c // FSIO.c // SD-SPI.c // easy_mp3_player_24f.c // Header Files Folder VS1011.h // GenericTypeDefs.h // FScohfig.h // FSDefs.h // FSIO.h // SD-SPI.h // // I2C_LCD Library lcd_i2c_lib.c // lcd_i2c_lib.h // // Linker Script Folder p24FJ64GA002.gld #include //#include "stdio.h" #include "VS1011.h" #include "GenericTypeDefs.h" #include "FSIO.h" //#include "uart.h" // Used Debug 110118 /// Set Configuration Word 1 _CONFIG1 ( JTAGEN_OFF & // JTAG Port: OFF GCP_OFF & // Code Protect:@OFF GWRP_OFF & // Write ProtectFOFF BKBUG_OFF & // Background Debug: OFF COE_OFF & // Clip On Emulation: OFF ICS_PGx1 & // Select ICD Pin: EMUC/EMUD-> PGC1/PGD1 For Common Use FWDTEN_OFF // WDT: OFF ) /// Set Configuration Word 2 _CONFIG2 ( IESO_OFF & // 2 Speed Start Up: OFF FNOSC_FRCPLL & // 8MHz Internal RC oscillator, 4x PLL-> 8MHzx4=32MHz // FNOSC_FRC & // Non PLL: 8MHz(Fcy=4MHz) FCKSM_CSDCMD & // Change Clock Control: OFF Clock Monitor: OFF OSCIOFNC_ON & // OSCO/RA3 function: Used RA3 IOL1WAY_OFF & // RP Register Protection: Unlimited Writes To RP Registers I2C1SEL_PRI & // I2C1 pins Select: Use Primary I2C1 pins POSCMOD_NONE // Oscillator Selection: Primary disabled ) /// Used debug: Function Prottypes 110129 void delay_us(int usec); void delay_ms(int msec); void PlaySkip(void); // 120913 void lcd_init(void); void lcd_data(unsigned char data); void lcd_cmd(unsigned char cmd); void lcd_str(char* ptr); void lcd_clear(void); /// message table (used debug) char msg1[] = "First Line"; char msg2[] = "Second Line"; //----------------------------------------------------------------------------------- /// SD Define #define SD_CS_ENABLE PORTBbits.RB4 = 0 // CS_pin = 0 #define SD_CS_DISABLE PORTBbits.RB4 = 1 // CS_pin = 1 //---------------------------------------------------------------- /// A Variable of VS1011 BYTE Volume, BASS, ChgFlag; //---------------------------------------------------------------- /// A Variable of FAT16 FSFILE *pfile; // Structure Pointer for FAT File size_t result; BYTE Buffer[256]; //BYTE Buffer[2048]; SearchRec Record; SearchRec *rptr = &Record; int i; //-------------------------------------------------------------------- /// I2C LCD void File_Name_TX_I2C_LCD(void) { unsigned char i; char *str_filename; str_filename = Record.filename; for (i = 0; i <12; ++i) { lcd_data(str_filename[i]); } lcd_cmd(0x80); // Cursor Home for( i= 0; i<12; ++i) str_filename[i] = 0; } //-------------------------------------------------------------------------------------- /// Switch Change Notification Interrupts void __attribute__((interrupt, no_auto_psv)) _CNInterrupt(void) { IFS1bits.CNIF = 0; // Add 110218:Clear CN Interrupt Flag /// Cheak SW ON: SW1(SKIP) or SW2(BOOST) delay_ms(1); // Add 110118: Prevention Chattering if (!PORTBbits.RB0) { // SW1 On Then NEXT File FSfclose(pfile); // Forced Close Current File // PlayEnd(); // Dispose of Play End PlaySkip(); /// Search NEXT File result = FindNext(rptr); // To NEXT File if ((result==0)&&(Record.attributes==ATTR_ARCHIVE)) pfile = FSfopen(Record.filename, "r"); else { // Mod.110220: File End Then Repeat from First result = FindFirst("*.*", ATTR_ARCHIVE, rptr); if (result == 0) { pfile = FSfopen(Record.filename, "r"); // File Open (Read Mode) } } // Disp. I2C LCD File_Name_TX_I2C_LCD(); } if (!PORTBbits.RB1) { // SW2 On Then Control BASS BOOST BASS ++; // Up BASS Boost if (BASS >15) BASS = 0; // 15max < BASS -> Return to 0 ChgFlag = 1; // Chenge Flag On } } //-------------------------------------------------------------------- // Main routine int main(void) { // CPU Clock Pre Scalere 1:1 CLKDIV = 0; // Set AD1PCFG: ANx Port is All Digital Pin AD1PCFG = 0xFFFF; /// Set LED & SW Port Direction TRISAbits.TRISA3 = 0; // RA3 is RED_LED output used debug TRISAbits.TRISA4 = 0; // RA4 is GREEN_LED output TRISBbits.TRISB0 = 1; // RB0 is SW1 input TRISBbits.TRISB1 = 1; // RB1 is SW2 input /// Set SD Port Direction TRISBbits.TRISB4 = 0; // RB4 is CS/ output TRISBbits.TRISB8 = 1; // RB8 is CD/ input TRISBbits.TRISB9 = 1; // RB9 is WE/ input /// Set I2C Port Direction TRISBbits.TRISB2 = 1; // RB2 is SDA2 (Hi) TRISBbits.TRISB3 = 1; // RB3 is SCL2 (Hi) // Set Pull Up CNPU1 = 0x1030; // Pull Up Port is RB0(SW1), RB1(SW2), RB14(DREQ) CNPU2 = 0x00E1; // Pull Up Port is RB10(SO_VS1101(SI_PIC Side)),RB7(SDI), RB8(CD/), RB9(WE/) /// Set Switch Change Notification Interrupts CNEN1 = 0x0030; // Valid SW1, SW2 IPC4bits.CNIP = 5; IEC1bits.CNIE = 1; //Enable SW INT /// SPI1 Pin Mapping: SD Side RPINR20bits.SDI1R = 7; // RP7 is SDI1 RPOR3bits.RP6R = 8; // RP6 is SCK1 RPOR2bits.RP5R = 7; // RP5 is SDO1 /// SPI2 Pin Mapping: VS1011e Side RPINR22bits.SDI2R = 10; // RP10 is SDI2 (VS_S0) RPOR6bits.RP12R = 11; // RP12 is SCK2 (VS_SCLK) RPOR5bits.RP11R = 10; // RP11 is SDO2 (VS_SI) /// Initialize I2C2 I2C2BRG = 0x9E; // 100kHz I2C2CON = 0x8000; // Enable I2C2 lcd_init(); // Initialize I2C_LCD // Initiale LCD Disp. lcd_str(msg1); // "First Line" lcd_cmd(0xC0); lcd_str(msg2); // "Second Line" // Initialize LED & SD LATAbits.LATA3 = 1; // RED_LED OFF LATAbits.LATA4 = 1; // GREEN_LED OFF SD_CS_DISABLE; // CS = 1 /// Initialize VS1011e VS1011_Init(); // Initialize VS1011 Port+ SPI2(CKP=4M)+ SDI_TestMode+ CLK Doubler Volume = 0x08; // Set Volume = -8[dB] SetVolume(Volume, Volume); BASS = 0; // Set Bass Boost = off SetBassBoost(BASS, 15); delay_ms(1000); lcd_clear(); // Start VS1011e Sine Test // VS1011_SineTest(); // Start Sin_5kHz //--------------------------------------------------------------------- /// Check Mount SD Card and Format SD_CS_ENABLE; // CS = 0 while(FSInit() != 1) // Check Mount SD Card and Format { LATAbits.LATA3 = 0; // Red LED ON delay_ms(1000); LATAbits.LATA3 = 1; // Red LED OFF delay_ms(1000); } // SD Mount LATAbits.LATA4 = 0; // Green LED ON delay_ms(1000); LATAbits.LATA4 = 1; // Green LED OFF delay_ms(1000); // First File Search (A Precondition: Loute Only Be MP3 File) result = FindFirst("*.*", ATTR_ARCHIVE, rptr); if (result == 0) { pfile = FSfopen(Record.filename, "r"); // File Open (Read Mode) } // Disp. I2C LCD File_Name_TX_I2C_LCD(); LATAbits.LATA4 = 0; // Green LED ON delay_ms(1000); LATAbits.LATA4 = 1; // Green LED OFF delay_ms(1000); //------------------------------------------------------------------------------------- /// main loop while(1) { /// Out of Music Data if (pfile != 0) { // Success File Open ? LATAbits.LATA4 = 0; // Green LED ON delay_ms(1000); LATAbits.LATA4 = 1; // Green LED OFF delay_ms(1000); // Out of Music Data As Far as EOF of File do{ /// Check BASS Boost SW2 & Control if (ChgFlag) { ChgFlag = 0; SetBassBoost(BASS, 15); // Set BASS Boost } /* Send of Music Data */ SRbits.IPL = 7; // Right in the middle of Processing SPI is CN Interrupt Disable MP3_XDCS_IO = 0; /// File Read (Unit 256Byte) // result = FSfread(Buffer, 1, 256, pfile); result = FSfread(Buffer, 1, 32, pfile); LATAbits.LATA3 = 0; // Red LED ON for( i= 0; i