VLSI Solution Oy VS1103 VLSI Solution Karaoke, MIDI and ADPCM Player Source Code Documentation

Main Page | Class List | File List | Class Members | File Members | Related Pages

storage.c

Go to the documentation of this file.
00001 
00019 #include "storage.h"
00020 #include "board.h"
00021 #include "console.h"
00022 #include "mmc.h"
00023 #include "buffer.h"
00024 #include "vs10xx.h"
00025 
00026 
00027 
00028 //#define MMCDEBUG
00029 
00030 
00036 Public unsigned char InitStorage(){
00037 
00038   unsigned char result;
00039 
00040   MOSI_TO_MMC = YES;
00041   ConsoleWrite ("Init: Storage: MMC/SD in SPI mode.\r");
00042 
00043   result=InitMMC();
00044   if (result==0x0e){ //ok, no support for seek-before-read
00045     return 0;
00046   }
00047 
00048   if (result){ //error resulted in MMC startup
00049     ConsoleWrite("Can't start MMC: ");
00050     ConsolePutHex8(result);
00051     ConsolePutChar(13);
00052     return 1; //MMC Init Error
00053   }
00054 
00055   ConsoleWrite("InitStorage ok.\r");
00056   return 0;
00057 
00058 }
00059 
00060 
00064 Public unsigned char ReadDiskSector(unsigned long sectorN){
00065   MOSI_TO_MMC = YES;
00066   //ConsolePutChar('s');
00067   if (SeekSector(sectorN)) return 0x0f; //seek error
00068   //ConsolePutChar('S');
00069   if (ReadPhysicalSector()){
00070     ConsoleWrite(" Read Error ");
00071     return 0x10; //read error
00072   }
00073   return 0; /* All OK return */
00074 }
00075 
00076 
00077 
00078 unsigned char TransferSectorSDI(unsigned long sectorN){  
00079 
00080 
00081   MOSI_TO_MMC = YES;
00082   Mp3DeselectControl(); //Just in case
00083   Mp3DeselectData(); //Just in case
00084   
00085   if (SeekSector(sectorN)) return 0x0f; //seek error
00086   // code from mmc.c: unsigned char ReadPhysicalSector(){
00087   MMCSelect();
00088   MmcWaitForData();
00089 
00090 
00091 #if 0
00092   PerformBlockRead();  
00093 
00094   SPI8Clocks(4); //Send 8*4=32 clocks (4 ff's) to MMC to be nice.
00095   MMCDeselect();
00096   SPI8Clocks(4); //Again, give the poor MMC some clocks, it likes them.
00097   
00098   Mp3SelectData();
00099   // BlockTransmit in C
00100   dataBufPtr = diskSect.raw.buf;
00101   // Use global pointer and unrolled loop for speed
00102   while (dataBufPtr < diskSect.raw.buf+512){
00103     SPIPutCharWithoutWaiting(*dataBufPtr++); 
00104     SPIPutCharWithoutWaiting(*dataBufPtr++); 
00105     SPIPutCharWithoutWaiting(*dataBufPtr++); 
00106     SPIPutCharWithoutWaiting(*dataBufPtr++); 
00107     SPIPutCharWithoutWaiting(*dataBufPtr++); 
00108     SPIPutCharWithoutWaiting(*dataBufPtr++); 
00109     SPIPutCharWithoutWaiting(*dataBufPtr++); 
00110     SPIPutCharWithoutWaiting(*dataBufPtr++); 
00111     SPIPutCharWithoutWaiting(*dataBufPtr++); 
00112     SPIPutCharWithoutWaiting(*dataBufPtr++); 
00113     SPIPutCharWithoutWaiting(*dataBufPtr++); 
00114     SPIPutCharWithoutWaiting(*dataBufPtr++); 
00115     SPIPutCharWithoutWaiting(*dataBufPtr++); 
00116     SPIPutCharWithoutWaiting(*dataBufPtr++); 
00117     SPIPutCharWithoutWaiting(*dataBufPtr++); 
00118     SPIPutCharWithoutWaiting(*dataBufPtr++); 
00119   }
00120   Mp3DeselectData();
00121 #else
00122   // FAST DIRECT TRANSFER VERSION
00123   
00124   MOSI_TO_MMC = NO; //force MMC data in to be "1"
00125   SPIPutCharWithoutWaiting(0xff);
00126   SPIWait();
00127   Mp3SelectData();
00128 
00129 #if 0
00130   // C version
00131   {
00132     unsigned int i;
00133     unsigned char c = SPI_RESULT_BYTE;
00134     for (i=0; i<512; i++){
00135       SPIPutCharWithoutWaiting(c);
00136       SPIWait();
00137       c = SPI_RESULT_BYTE;
00138     }
00139   }
00140 #else
00141   // ASM version
00142 
00143 
00144 
00145 
00146 
00147    // BlockRead in Assembler
00148 
00149    _asm
00150         //asm prologue start
00151         push    psw
00152         push    acc
00153         mov     a,r2
00154         push    acc
00155         mov     a,r1
00156         push    acc
00157         //prologue end
00158      
00159      mov r2, #0 // put 256 to r2
00160 3106$:
00161 
00162 3122$:
00163      
00164      mov R1, _SPDAT
00165      mov _SPDAT, R1
00166      nop
00167      mov A, _SPSTA
00168      mov A, _SPSTA
00169      mov A, _SPSTA
00170      
00171 
00172 
00173      mov R1, _SPDAT
00174      mov _SPDAT, R1
00175      nop
00176      mov A, _SPSTA
00177      djnz R2, 3122$
00178 
00179 3108$:        
00180         //asm epilogue start
00181         pop     acc
00182         mov     r1,a
00183         pop     acc
00184         mov     r2,a
00185         pop     acc
00186         pop     psw     
00187         //epilogue end
00188    _endasm;
00189 
00190 
00191 
00192 
00193 
00194 
00195 
00196 
00197 #endif
00198 
00199   Mp3DeselectData();
00200   MOSI_TO_MMC = YES;
00201   SPI8Clocks(4); //Send 8*4=32 clocks (4 ff's) to MMC to be nice.
00202   MMCDeselect();
00203   SPI8Clocks(4); //Again, give the poor MMC some clocks, it likes them.
00204   
00205 #endif
00206 
00207 
00208 
00209   
00210   //RED_LED = LED_OFF;
00211   
00212   return 0; //ok return
00213 }
00214 
00215 
00216 #include "midimap.c"
00217 // Apply midi map translation to diskSect
00218 void ApplyMidiMap(){
00219   static bit midiProgramChange = 0;
00220   static xdata unsigned char channel;
00221   unsigned int i;
00222   i=0;
00223   while(i<512){
00224     if (midiProgramChange){
00225       unsigned char instrument = diskSect.raw.buf[i];
00226       unsigned char oldInstrument = instrument;
00227       instrument = midiMap[instrument];
00228 
00229 #if 0
00230       ConsoleWrite("Channel ");
00231       ConsolePutUInt(channel+1);
00232       ConsoleWrite("has instrument ");
00233       ConsolePutUInt(oldInstrument+1);
00234       if (instrument != oldInstrument){
00235         ConsoleWrite("-> ");
00236         ConsolePutUInt(instrument+1);
00237       }
00238       ConsolePutChar(13);
00239 #endif
00240       diskSect.raw.buf[i] = instrument;      
00241     }
00242     midiProgramChange = 0;
00243     if ((diskSect.raw.buf[i] & 0x80)
00244         && ((diskSect.raw.buf[i] & 0xf0) == 0xc0)){      
00245       midiProgramChange = 1;
00246       channel = diskSect.raw.buf[i] & 0x0f;
00247     }
00248     i++;
00249   }
00250 }
00251 
00252 
00253 // Transfer a MIDI sector
00254 unsigned char TransferSectorSCI(unsigned long sectorN){  
00255 
00256 
00257   MOSI_TO_MMC = YES;
00258   Mp3DeselectControl(); //Just in case
00259   Mp3DeselectData(); //Just in case
00260   
00261   if (SeekSector(sectorN)) return 0x0f; //seek error
00262   
00263   
00264   // code from mmc.c: unsigned char ReadPhysicalSector(){
00265   MMCSelect();
00266   MmcWaitForData();
00267   
00268   //GREEN_LED = LED_ON;
00269   PerformBlockRead();  
00270   //GREEN_LED = LED_OFF;
00271   
00272   SPI8Clocks(4); //Send 8*4=32 clocks (4 ff's) to MMC to be nice.
00273   MMCDeselect();
00274   SPI8Clocks(4); //Again, give the poor MMC some clocks, it likes them.
00275   
00276   ApplyMidiMap();
00277   
00278   //GREEN_LED = LED_ON;
00279   Mp3DeselectData(); //Just In Case
00280   // BlockTransmit in C
00281   dataBufPtr = diskSect.raw.buf;
00282   // Use global pointer and unrolled loop for speed
00283   while (dataBufPtr < diskSect.raw.buf+512){
00284     Mp3SelectControl();
00285     SPIPutCharWithoutWaiting(VS_WRITE_COMMAND);SPIWait();
00286     SPIPutCharWithoutWaiting(SCI_IN0);SPIWait();
00287     SPIPutCharWithoutWaiting(*dataBufPtr++);SPIWait();
00288     SPIPutCharWithoutWaiting(*dataBufPtr++);SPIWait(); 
00289     SPIPutCharWithoutWaiting(*dataBufPtr++);SPIWait(); //SciMultiWrite
00290     SPIPutCharWithoutWaiting(*dataBufPtr++);SPIWait(); 
00291     SPIPutCharWithoutWaiting(*dataBufPtr++);SPIWait(); //SciMultiWrite
00292     SPIPutCharWithoutWaiting(*dataBufPtr++);SPIWait(); 
00293     SPIPutCharWithoutWaiting(*dataBufPtr++);SPIWait(); //SciMultiWrite
00294     SPIPutCharWithoutWaiting(*dataBufPtr++);SPIWait(); 
00295     Mp3DeselectControl();
00296   }
00297   //GREEN_LED = LED_OFF;
00298   
00299   return 0; //ok return
00300 }
00301 
00302 
00303 
00304 
00305 
00306 
00308 Public void DumpDiskSector(){
00309   unsigned int ha,la;
00310   
00311   ConsoleWrite("\rDiskBlock ");
00312   ConsolePutUInt(sectorAddress.l);
00313   ConsoleWrite(":\r");
00314   for (ha=0; ha<32; ha++){
00315     ConsolePutHex16 ((ha<<4));
00316     ConsoleWrite(": ");
00317     for (la=0; la<16; la++){
00318       ConsolePutHex8(diskSect.raw.buf[(ha<<4)+la]);
00319       ConsolePutChar(' ');
00320       if (la==7){ 
00321         ConsolePutChar(' ');
00322       }
00323     }
00324     ConsolePutChar(' ');
00325     for (la=0; la<16; la++){
00326       if ((diskSect.raw.buf[(ha<<4)+la]) > 30){
00327         ConsolePutChar(diskSect.raw.buf[(ha<<4)+la]);
00328       }else{
00329         ConsolePutChar('.');
00330       }
00331     }
00332     ConsolePutChar('\r');
00333   } 
00334 }
00335 
00336 
00337 
00338 
00339 
00340 
00341 
00342 
00343 
00350 Public void WriteDiskSector(unsigned long sectorN){
00351   MOSI_TO_MMC = YES;
00352   sectorAddress.l = sectorN;
00353   dataBufPtr = diskSect.raw.buf;
00354   WritePhysicalSector();
00355 }
00356 

All software copyright 2000-2004 VLSI Solution OY. Redistribution of these software modules is limited to VLSI Solution Oy chip promotional use only. Free or commercial use of these software modules in MP3 players is ok if the product includes chip(s) from VLSI. You can request the complete (compilable) package from mp3@vlsi.fi. This exampe code is provided with good faith to assist You in code development, but under no circumstances will VLSI offer any guarantees on the usability or functionality of any example software or its fitness for any purpose.