ButterflyMP3
|
00001 00046 #include <avr/io.h> 00047 #include <avr/pgmspace.h> 00048 #include <avr/interrupt.h> 00049 00050 #define MMC_C 00051 #include "types.h" 00052 #include "mmc.h" 00053 #include "delay.h" 00054 #include "main.h" 00055 #include "uart.h" 00056 #include "vs1001.h" 00057 00058 uint8 mmc_sbuf[512]; 00059 uint8 mmc_scratch[32]; 00060 00061 00065 void SpiInit(void) 00066 { 00067 uint8 dummy; 00068 00069 SBI(SPI_DDR, SPI_SS); // SS must be output for Master mode to work 00070 SBI(SPI_DDR, SPI_MOSI); // set MOSI a output 00071 SBI(SPI_DDR, SPI_SCK); // set SCK as output 00072 CBI(SPI_DDR, SPI_MISO); // MISO is input 00073 //CBI(SPI_PORT, SPI_SCK); // set SCK low 00074 00075 SBI(MMC_PORT,MMC_CS); 00076 SBI(MMC_DDR,MMC_CS); 00077 00078 // hold dataflash in reset so it doesn't interfere with 00079 // MMC or VS1001. 00080 DDRF |= (1<<PE7); // PE7 is output. 00081 PORTF &= ~(1<<PE7); // hold PE7 low 00082 00083 /* enable SPI as master, set clk divider fosc/4 */ 00084 // Although the MMC card is capable of clock speeds up to 20Mhz 00085 // We are limited to 2Mhz for the VS1001k until we set the clock doubler 00086 // after which we are limited to 4Mhz by the butterfly. 00087 /* later we will enable 2X mode once vS1001 has been initialized.*/ 00088 SPCR = (0<<SPIE)|(1<<SPE)|(0<<DORD)|(1<<MSTR)|(0<<CPOL)|(0<<CPHA)|(0<<SPR1)|(0<<SPR0); 00089 SPSR = (0<<SPI2X); 00090 dummy = SPSR; // clear status 00091 dummy = SPDR; 00092 } 00093 00094 00105 uint8 SpiByte(unsigned char byte) 00106 { 00107 uint8 i,dummy; 00108 00109 SPDR = byte; // put byte to send in SPDR, which initiates xmit 00110 00111 loop_until_bit_is_set(SPSR, SPIF); //wait for completion 00112 00113 //delay(5); //wait 5 microseconds after sending data to control port 00114 for (i=0;i<8;i++) // 2 + 5i clock cycles -> 42 clocks at 8 Mhz -> 5.25uS 00115 asm volatile("nop"); 00116 00117 i = SPSR; // clear status 00118 dummy = SPDR; 00119 return dummy; // return with byte shifted in from slave 00120 00121 } 00122 00123 00130 uint8 MMCGet(void) 00131 { 00132 uint8 i,Byte; 00133 00134 for (i=0;i<8;i++){ 00135 Byte = SpiByte(0xff); 00136 if (Byte != 0xff) return Byte; 00137 } 00138 00139 return Byte; 00140 } 00141 00155 void MMCCommand(unsigned char command, uint8 px, uint8 py, uint8 pz) 00156 { 00157 CBI(MMC_PORT,MMC_CS); // Select card 00158 // CBI( BSYNC_PORT, BSYNC_PIN ); // byte sync lo 00159 00160 SpiByte(0xff); 00161 SpiByte(command | 0x40); 00162 SpiByte(px); 00163 SpiByte(py); 00164 SpiByte(pz); 00165 SpiByte(0x00); 00166 SpiByte(0x95); 00167 /* 00168 correct CRC for first command in SPI 00169 after that CRC is ignored, so no problem with 00170 always sending 0x95 00171 */ 00172 /* 00173 the reason I did not re set the MMC_CS line was because I didn't want to 00174 de-assert the line after the command while waiting for a response. 00175 The card is selected here as a backup to make sure it is selected. 00176 I might go through and remove places where it is redundant when 00177 i get a chance. 00178 00179 <<!! the following behaviour has been removed as redundent 00180 I may add it back in a new mode compatable form if needed. 00181 00182 The BSYNC line is held low to ensure that the spi data is sent as a command 00183 to the MMC and not as data to teh vs1001 as I have combinned both the 00184 interfaces on the vs1001 to save pins. 00185 00186 !!>> 00187 00188 Any data on the spi lines is read as data by the vs1001 when the 00189 BSYNC line is high. 00190 */ 00191 } 00192 00193 00200 uint8 MMC_Reset(void) 00201 { 00202 unsigned char Byte; 00203 unsigned int i; 00204 00205 SBI(MMC_PORT,MMC_CS); 00206 //CBI( BSYNC_PORT, BSYNC_PIN ); // byte sync lo 00207 00208 /* start off with 80 bits of high data with card deselected */ 00209 for(i=0;i<10;i++) 00210 Byte = SpiByte(0xff); 00211 00212 /* now send CMD0 - go to idle state, try up to 100 times */ 00213 MMCCommand(0,0,0,0); /* software reset command */ 00214 00215 if (MMCGet() != 1) 00216 { 00217 SBI(MMC_PORT ,MMC_CS); 00218 SpiByte(0xff); 00219 return -1; // MMC Not detected 00220 } 00221 00222 00223 /* send CMD1 until we get a 0 back, indicating card is done initializing */ 00224 i =0xffff; /* but only do it up to 1000 times */ 00225 Byte = 1; 00226 00227 while (Byte && i--){ 00228 MMCCommand(1,0,0,0); 00229 Byte = MMCGet(); 00230 } 00231 00232 SBI(MMC_PORT,MMC_CS); 00233 SpiByte(0xff); // Clear SPI 00234 00235 if (Byte){ 00236 return -2; // Init Fail 00237 } 00238 00239 00240 return 0; 00241 } 00242 00251 uint8 MMC_Detect(void) 00252 { 00253 uint8 i; 00254 #if (REV >='B') // MMC detect only available on rev_b boards. 00255 MMC_DDR &= ~(1<<MMC_CS); // set as input 00256 MMC_PORT &= ~(1<<MMC_CS); // disable pullup 00257 00258 //wait 18 microseconds after sending data to control port 00259 for (i=0;i<29;i++) // 2 + 5i clock cycles -> 147 clocks at 8 Mhz -> 18.375uS 00260 asm volatile("nop"); 00261 00262 if((MMC_PIN & (1<<MMC_CS)) == 0) 00263 { 00264 MMC_PORT |= (1<<MMC_CS); 00265 MMC_DDR |= (1<<MMC_CS); 00266 return FALSE; 00267 } 00268 MMC_PORT |= (1<<MMC_CS); 00269 MMC_DDR |= (1<<MMC_CS); 00270 #endif 00271 return TRUE; 00272 } 00273 00274 00281 uint16 MMC_Check(void) 00282 { 00283 uint16 word; 00284 00285 MMCCommand(MMC_SEND_STATUS,0,0,0); // check card ststus 00286 word = MMCGet(); 00287 word = (word<<8) + SpiByte(0xff); // NOTE spibyte and not MMCGET!!! 00288 00289 SBI(MMC_PORT,MMC_CS); // Deselect card 00290 SpiByte(0xff); // Clear SPI 00291 00292 return word; 00293 } 00294 00303 /* 00304 uint8 MMC_Identify(void) 00305 { 00306 uint8 byte,data,i; 00307 00308 00309 MMCCommand(MMC_SEND_CID,0,0,0); // send cmd 00310 byte = MMCGet(); // check reponse 00311 00312 if (byte==0){ // get the CID... 00313 for (i=0;i<32;i++){ 00314 data = SpiByte(0xff); 00315 mmc_scratch[i]=data; 00316 } 00317 } 00318 00319 SBI(MMC_PORT,MMC_CS); // Deselect card 00320 SpiByte(0xff); // Clear SPI 00321 00322 return byte; 00323 } 00324 */ 00325 00332 /* 00333 uint8 MMC_CardType(void) 00334 { 00335 uint8 byte,data,i; 00336 00337 MMCCommand(MMC_SEND_CSD,0,0,0); // send cmd 00338 byte = MMCGet(); // check reponse 00339 00340 if (byte==0){ // get the CID... 00341 for (i=0;i<32;i++){ 00342 data = SpiByte(0xff); 00343 mmc_scratch[i]=data; 00344 } 00345 } 00346 00347 SBI(MMC_PORT,MMC_CS); // Deselect card 00348 SpiByte(0xff); // Clear SPI 00349 00350 return byte; 00351 } 00352 */ 00358 // 00359 //uint32 MMC_Capacity(void) 00360 //{ 00361 // uint8 byte,data,multi,blk_len; 00362 // uint32 c_size; 00363 // uint32 capacity; 00364 // byte = MMC_CardType(); 00365 // if (byte==0) {// got info okay 00366 // blk_len = 0x0F & mmc_scratch[6]; // this should equal 9 -> 512 bytes 00367 // /* ; get size into reg 00368 // ; 7 8 9 00369 // ; xxxx xxxx xxxx xxxx xxxx xxxx 00370 // ; ^^ ^^^^ ^^^^ ^^ 00371 // */ 00372 // data =(mmc_scratch[7] & 0x03)<<6; 00373 // data |= (mmc_scratch[8] >> 2); 00374 // c_size = data << 4; 00375 // data =(mmc_scratch[8] << 2 ) | ((mmc_scratch[9] & 0xC0)>>6 ); 00376 // c_size |= data; 00377 // 00378 // /* ; get multiplier 00379 // ; 10 11 00380 // ; xxxx xxxx xxxx xxxx 00381 // ; ^^ ^ 00382 // */ 00383 // multi = ((mmc_scratch[10] & 0x03 ) << 1 ) ; 00384 // multi |= ((mmc_scratch[11] & 0x80) >> 7); 00385 // // sectors = (size+1)<<(multiplier+2) 00386 // capacity = (c_size + 1)<<(multi + blk_len + 2); 00387 // 00388 // return capacity; 00389 // } 00390 // return 0xFFFFFFFF; 00391 //} 00392 // 00393 00399 //uint8 MMC_Name(void) 00400 //{ 00401 // uint8 byte,i; 00402 // 00403 // byte = MMC_Identify(); // Grab CID into mmc_scratch 00404 // 00405 // if (byte==0){ 00406 // for (i=0;i<6;i++) 00407 // mmc_scratch[i]=mmc_scratch[i+4]; 00408 // mmc_scratch[6]=0; 00409 // } 00410 // 00411 // return byte; 00412 //} 00413 00414 00415 /*************************************************************************** 00416 * MMC_Read 00417 * Read one sector from the memory card into mmc_sbuf[] 00418 * Note this assumes block length of 512 Bytes 00419 * @Param <lba> the number of the sector to read 00420 * @Return Status from the read call. 00421 ***************************************************************************/ 00422 uint8 MMC_Read(uint32 lba) 00423 { 00424 uint8 byte,data,px,py,pz; 00425 uint16 sec,i; 00426 uint16 word; 00427 #ifdef USE_MMC_CACHE 00428 static uint32 last_read_lba=0xffffffff; // remember last sector for caching purposes 00429 00430 if (last_read_lba == lba){ // exit ASSUMING BUFFER HAS NOT BEEN ALTERED 00431 return 0x00; // OK 00432 } 00433 #endif 00434 00435 SpiByte(0xff); 00436 CBI(MMC_PORT,MMC_CS); // Select card 00437 MMCCommand(MMC_SEND_STATUS,0,0,0); // check card status 00438 word = MMCGet(); 00439 word = (word<<8) + SpiByte(0xff); 00440 00441 00442 lba <<=9; // * 512 00443 pz = (lba>>8 & 0xff); 00444 py =( lba>>16 & 0xff); 00445 px =( lba>>24 & 0xff); 00446 00447 SpiByte(0xff); 00448 CBI(MMC_PORT,MMC_CS); // Select card 00449 MMCCommand(MMC_READ_SINGLE_BLOCK, px , py, pz); 00450 byte = MMCGet(); // check reponse 00451 00452 //TODO: if i get a byte == 0x05 should I resend? 00453 00454 if (byte==0){ // then everything okay 00455 i=500; // wait up to 255 bytes for response 00456 data = SpiByte(0xff); 00457 00458 while ((data != MMC_STARTBLOCK_READ) && (i--)){ 00459 data = SpiByte(0xff); 00460 } 00461 00462 if (i!=0){ // read okay. start grabbing the data 00463 for(sec=0;sec<512;sec++) 00464 mmc_sbuf[sec] = SpiByte(0xff); 00465 SpiByte(0xff); // flush MMC CRC 00466 SpiByte(0xff); // 00467 SpiByte(0xff); //Clear SPI 00468 SpiByte(0xff); // 00469 }else{ 00470 byte = 0xff;// signal MMC Coms error 00471 } 00472 //}else{ 00473 // PRINT("MMC_READ_SINGLE_BLOCK\t"); 00474 // PRINT("\t");UART_Printfu32(lba<<9); 00475 // PRINT("\t");UART_Printfu16(word); 00476 // PRINT("\t");UART_Printfu08(byte); 00477 // PRINT("\t");UART_Printfu08(SpiByte(0xff)); 00478 // EOL(); 00479 00480 } 00481 00482 SBI(MMC_PORT,MMC_CS); // Deselect card 00483 SpiByte(0xff); // Clear SPI 00484 00485 #ifdef USE_MMC_CACHE 00486 if (byte == 0){ 00487 last_read_lba = lba;// save for next time. 00488 } 00489 #endif 00490 return byte; 00491 } 00492 00493 /************************************************************************* 00494 * uint8 MMCWriteSector(uint32lba) 00495 * 00496 * - writes a sector to the card (512 bytes) 00497 * - takes sector # as param 00498 * - data is in mmc_sbuf[] 00499 * - returns success/failure status of operation. 00500 **************************************************************************/ 00501 // ****** UNTESTED ****** 00502 //uint8 MMC_Write(uint32 lba) 00503 //{ 00504 // unsigned char px,py,pz; 00505 // unsigned int i; 00506 // lba <<=1; 00507 // pz = (lba & 0xff); 00508 // lba >>= 8; 00509 // py =( lba & 0xff); 00510 // lba >>= 8; 00511 // px =( lba & 0xff); 00512 // 00513 // CBI(MMC_PORT,MMC_CS); // Select card 00515 // if (MMCGet() == 0xff) return 0xff; 00516 // 00517 // SpiByte(0xfe); // Send Start Byte 00518 // 00519 // for (i=0;i<512;i++) // read the sector 00520 // { 00521 // SpiByte(mmc_sbuf[i]); 00522 // } 00523 // SpiByte(0xff); // checksum -> don't care about it for now 00524 // SpiByte(0xff); // checksum -> don't care about it for now 00525 // SpiByte(0xff); // Read "data response byte" 00526 // 00527 // if (MMCGet() == 0xff) return 0xff; 00528 // 00529 // SBI(MMC_PORT,MMC_CS); // Deselect card 00530 // SpiByte(0xff); // Clear SPI 00531 // 00532 // return 0; 00533 //} 00534 00535 //void MMC_Flush(void) 00536 //{ 00537 // uint8 i; 00538 // SBI(MMC_PORT,MMC_CS); 00539 // /* start off with 80 bits of high data with card deselected */ 00540 // for(i=0;i<10;i++) 00541 // SpiByte(0xff); 00542 // //CBI(MMC_PORT,MMC_CS); /* select card */ 00543 //} 00544 00545 00546 /*************************************************************************** 00547 * Name: MMC_WriteProtect 00548 * Description: Set or clear the MMC Writeprotect 00549 * Parameters: <set> determines weather to set or clear the write protection 00550 * Returns: error code. 00551 ***************************************************************************/ 00552 //uint8 MMC_WriteProtect(uint8 set){ 00553 // uint8 byte; 00554 // 00555 // if (set){ 00556 // MMCCommand(MMC_SET_WRITE_PROT,0,0,0); // send cmd 00557 // }else{ 00558 // MMCCommand(MMC_CLR_WRITE_PROT,0,0,0); // send cmd 00559 // } 00560 // byte = MMCGet(); // check reponse 00561 // 00562 // SBI(MMC_PORT,MMC_CS); // Deselect card 00563 // SpiByte(0xff); // Clear SPI 00564 // 00565 // return byte; 00566 //}