unsigned char SPI(unsigned char byte) // 1 byte per spi-schnittstelle senden { SSPBUF=byte; // Byte uebergeben while(!BF); // warten bis senden beendet ist return(SSPBUF); // wert von spi empfangen } unsigned char SPI_READ(void) // 1 byte von spi-schnittstelle lesen { SSPBUF=0xFF; while(!BF); // warten bis senden beendet ist return(SSPBUF); // wert von spi empfangen } unsigned char mmc_response(unsigned char response) { mmc_count=0; do { mmc_count++; } while(SPI_READ() != response && mmc_count<200); if (mmc_count==200) mmc_erg=0; else mmc_erg=1; return(mmc_erg); } void command(unsigned char *CMD_com) // einen befehl ( 6 bytes ) zur mmc senden { unsigned char a; for (a=0;a<6;a++) {SPI(*CMD_com++);} } unsigned char cmd_befehl(unsigned char *CMD_bef,unsigned char cmd_wert) { mmi_count=0; do { mmi_count++; command(CMD_bef); } while((mmc_response(cmd_wert)!=1) && (mmi_count<200)); if (mmi_count==200) return(0); else return(1); } unsigned char go_idle_state(void) { unsigned char i; //SPI-Init: SMP=0; // Input is value in the middle of the cock CKE=0; // getting dates by rising edge CKP=1; // High is passive state SSPM3=0; SSPM2=0; SSPM1=1; // speed f/64(312kHz), Master SSPM0=0; // speed 1,25MHz), Master SSPEN=1; // SPI on //MMC-Init: mmc_disable; //by hardware, logic negative for (i=0;i<10;i++) SPI(0xFF); //80 clocks senden zum Synchronisieren. mmc_enable; CMD[0]=0x40;CMD[1]=0x00;CMD[2]=0x00;CMD[3]=0x00;CMD[4]=0x00;CMD[5]=0x95; cmd_befehl(CMD,1); return(mmc_control); } void app_send_op_cond(void) //ACMD41=CMD55 + CMD41 nur für SD-Karten { unsigned char mmc_temp; mms_count=0; do { mms_count++; CMD[0]=0x77;CMD[1]=0x00;CMD[2]=0x00;CMD[3]=0x00;CMD[4]=0x00;CMD[5]=0xFF; //CMD55 //140208 mmc_control=cmd_befehl_oder(CMD,0,1); mmc_temp=cmd_befehl(CMD,0); CMD[0]=0x69;//CMD[1]=0x00;CMD[2]=0x00;CMD[3]=0x00;CMD[4]=0x00;CMD[5]=0xFF; //CMD41 mmc_control=cmd_befehl(CMD,0); } while(!((mmc_control==1) || (mmc_temp==1) || (mms_count>=200))); if (mms_count>=mmi_max) mmc_control=0; //Timeout erreicht, d.h. nichts gefunden. else mmc_control=1; } void send_op_cond(void) { CMD[0]=0x41;CMD[1]=0x00;CMD[2]=0x00;CMD[3]=0x00;CMD[4]=0x00;CMD[5]=0xFF; cmd_befehl(CMD,0); mmc_disable; //extra clock to allow mmc to finish off what it is doing SPI(0xFF); mmc_enable; } void set_blocklen(unsigned int blocklaenge) //neu301007 { CMD[0]=0x50;CMD[1]=0x00;CMD[2]=0x00; CMD[3]=(char)((blocklaenge&0xFF00)>>8); //high-Teil CMD[4]=(char)((blocklaenge&0x00FF)); //low-Teil CMD[5]=0xFF; mmc_control=cmd_befehl(CMD,0); } void readblock(unsigned long rb_adr) { unsigned int j; CMD[0]=0x51;CMD[4]=0x00;CMD[5]=0xFF; rb_adr = rb_adr << 9; //rb_adr = rb_adr * 512 CMD[1] = (char)(((rb_adr & 0xFF000000) >>24 )); CMD[2] = (char)(((rb_adr & 0x00FF0000) >>16 )); CMD[3] = (char)(((rb_adr & 0x0000FF00) >> 8 )); cmd_befehl(CMD,0); mmc_response(0xFE); for (j=0;j<512;j++) //512 Bytes eines Blocks lesen. { sdbuffer[j]=SPI_READ(); } //am Ende einige Takte senden: SPI(0xFF); //CRC-Byte ignore. SPI(0xFF); //CRC-Byte ignore } void mmc_init(void) { mmc_control=0; mmc_control=go_idle_state(); //CMD0 if (mmc_control) { app_send_op_cond(); //ACMD41 if (mmc_control) { send_op_cond(); //CMD1 set_blocklen(512); //optinoal readblock(0x00000000); LCDText(sdbuffer[0]); //display on lcd-screen } } } }