/************************************************************************ FILE: main.c DESC: Wav player built with MultiMedia Card,uC SAM7S256, display LCD BY: Szymon Dyja WEB: www.pro-qwerty.com ************************************************************************/ #include #include #include #include "LCD.h" #include "Board.h" #include "lib_AT91SAM7X256.h" #include "ff.h" #include "diskio.h" #define BUFF_SIZE 2000 //sound buffer size DIR dir; /* Directory object */ FIL file1; /* File object */ char *ptr; FILINFO finfo; volatile FIL plik; WORD bw; DWORD acc_size; /* Work register for fs command */ WORD acc_files, acc_dirs; volatile unsigned int ii=0, indeks=0, buf_1=1, play=1, read=1, time1; volatile unsigned char bufor1[BUFF_SIZE], bufor0[BUFF_SIZE]; //sound buffors __ramfunc void falszywe(void); __ramfunc void przerwanie(); static void device_init(void); void read_b(void); void next_song(void); void time(int t); //************************************************************************ int main(void) { char buf[10]; //bufor for intToStr() int res; FATFS fs; memset(&fs, 0, sizeof(FATFS)); /* Invalidate file system */ FatFs = &fs; LCD_Open(); //LCD open device_init(); LCD_XY(1,0);LCD("Device inited");pauza(1000);LCD_ClrScr(); res=f_mountdrv(); LCD("Mounted: ");intToStr(buf, res); LCD(buf);pauza(1000); LCD_ClrScr(); AT91C_BASE_AIC->AIC_IECR = (1 << AT91C_ID_SYS); f_opendir(&dir, ptr); next_song();LCD_XY(1,0);LCD("play"); while(1) { if(IsPressed(SW2)) //Stopped playing if pressed SW1 { while(IsPressed(SW2)){ read_b();} if(play==0) { play=1; LCD_XY(1, 0); LCD(" "); LCD_XY(1,0); LCD("play"); }else { play=0; //Clear global flag LCD_XY(1, 0); LCD(" "); LCD_XY(1,0); LCD("stop"); } } if(IsPressed(SW1)) //Stopped playing if pressed SW2 { play=1; //Set global flag LCD_ClrScr(); LCD_XY(1,0); LCD("I'm running"); } if(IsPressed(SW3)) //Stopped playing if pressed SW2 { while(IsPressed(SW3)){ read_b();} next_song(); } time(1); read_b(); } return 0; /* never reached */ } //************************************************************************ void time(int t) { char buf[10]; if(time1!=(ii/22500)) { LCD_XY(1, 8); LCD(" "); LCD_XY(1,8); intToStr(buf, ii/22500); LCD(buf); time1=ii/22500; } } //************************************************************************ void next_song() { int n, res; play=0; do { n=0; res = f_readdir(&dir, &finfo); if ((res != FR_OK) || !finfo.fname[0]) { f_opendir(&dir, ptr); res = f_readdir(&dir, &finfo); } if(!(finfo.fattrib & AM_DIR)) while(finfo.fname[n++]); }while((finfo.fattrib & AM_DIR) || (finfo.fname[n-2]!='V') || (finfo.fname[n-3]!='A') || (finfo.fname[n-4]!='W') ); f_close(&plik); f_open(&plik, &(finfo.fname[0]) , FA_READ|FA_OPEN_EXISTING); LCD_XY(0, 0); LCD(" "); LCD_XY(0, 0); LCD(&(finfo.fname[0])); buf_1=0; ii=0; indeks=0; read=1; play=1; } //************************************************************************ void read_b(void) { if(read==1) { if(buf_1) //load to first buffor { f_read(&plik, bufor0, BUFF_SIZE, &bw); }else //load to second buffor { GPIO_Toggle(LED1); f_read(&plik, bufor1, BUFF_SIZE, &bw); } read=0; } } //************************************************************************ __ramfunc void przerwanie() //interupt soun processing { int dummy1; dummy1=AT91C_BASE_PITC->PITC_PIVR; if(ii>=((plik.fsize/2)-2)) { next_song(); } if(play) //do if global flag play is set { ii++; if(buf_1) //play from first buffor { AT91C_BASE_PWMC->PWMC_CH[1].PWMC_CUPDR=(unsigned int)bufor1[indeks]; //set PWM VAlue AT91C_BASE_PWMC->PWMC_CH[2].PWMC_CUPDR=(unsigned int)bufor1[indeks+1]; if(indeks>=(BUFF_SIZE-2)) { buf_1=0; indeks=0; read=1; } }else //play from second buffor { AT91C_BASE_PWMC->PWMC_CH[1].PWMC_CUPDR=(unsigned int)bufor0[indeks]; //set PWM VAlue AT91C_BASE_PWMC->PWMC_CH[2].PWMC_CUPDR=(unsigned int)bufor0[indeks+1]; if(indeks>=(BUFF_SIZE-2)) { buf_1=1; indeks=0; read=1; GPIO_Toggle(LED1); } } indeks=indeks+2;; } AT91C_BASE_AIC->AIC_EOICR=0x0; } //************************************************************************ static void device_init(void) { AT91C_BASE_AIC->AIC_SPU = (int) falszywe ; int dummy; LCD_Open(); GPIO_CfgOutput(LED1|PA1|PA2); GPIO_CfgInput(SW1|SW2|SW3); PMC_OpenClock(1<<2); PMC_OpenClock(1<<10); GPIO_SetPin(1<<1|1<<2|LED1); AT91C_BASE_PWMC->PWMC_IDR=0x1<<1|0x1<<2; AT91C_BASE_PWMC->PWMC_DIS=0x1<<1|0x1<<2; AT91F_PWMC_CfgChannel(AT91C_BASE_PWMC, 1, 0x3, 256, 1); //configure I'st channel PWM, 8-bit resolution AT91F_PWMC_CfgChannel(AT91C_BASE_PWMC, 2, 0x3, 256, 1); PIO_OpenA(PA1|PA2); AT91C_BASE_PWMC->PWMC_ENA=0x1<<1|0x1<<2; // Enable User Reset and set its minimal assertion to 960 us AT91C_BASE_RSTC->RSTC_RMR = AT91C_RSTC_URSTEN | (0x4<<8) | (unsigned int)(0xA5<<24); PMC_OpenClock(1<<1); // Set-up the PIO // First, enable the clock of the PIO and set the LEDs in output AT91F_PMC_EnablePeriphClock ( AT91C_BASE_PMC, 1 << AT91C_ID_PIOA ) ; AT91C_BASE_AIC->AIC_SPU = (int) falszywe ; volatile AT91S_AIC * pAIC = AT91C_BASE_AIC; *AT91C_PITC_PIMR = AT91C_PITC_PITIEN | /* PIT Interrupt Enable */ AT91C_PITC_PITEN | /* PIT Enable */ (45 * 48 + 8) >> 4; /* Periodic Interval Value */ pAIC->AIC_SMR[AT91C_ID_SYS] = AT91C_AIC_SRCTYPE_INT_POSITIVE_EDGE | 7; pAIC->AIC_SVR[AT91C_ID_SYS] = (unsigned long) przerwanie; } //************************************************************************ __ramfunc void falszywe(void) { AT91C_BASE_AIC->AIC_EOICR=0x0; }