//******************************************** unsigned int SD_CMD_Write(unsigned int CMDIndex,unsigned long CMDArg,unsigned int ResType,unsigned int CSLowRSV)//ResType:Response Type, send 1 for R1; send 2 for R1b; send 3 for R2. { //There are 7 steps need to do.(marked by [1]-[7]) unsigned int temp,Response,Response2,CRC,MaximumTimes; Response2=0; MaximumTimes=10; CRC=0x0095;//0x0095 is only valid for CMD0 if (CMDIndex!=0) CRC=0x00ff; sd_cse=0;//[1] CS Low SD_2Byte_Write(((CMDIndex|0x0040)<<8)+(CMDArg>>24));//[2] Transmit Command_Index & 1st Byte of Command_Argument. SD_2Byte_Write((CMDArg&0x00ffff00)>>8); //[2] 2nd & 3rd Byte of Command_Argument SD_2Byte_Write(((CMDArg&0x000000ff)<<8)+CRC); //[2] 4th Byte of Command_Argument & CRC only for CMD0 sd_dao=1;//[3] Do High //[3] Restore Do to High Level for (temp=0;temp<8;temp++)//[4] Provide 8 extra clock after CMD { sd_clk=0;//CLK Low Delay5us(); sd_clk=1;//CLK High Delay5us(); } switch (ResType)//[5] wait response { case 1://R1 { do Response=SD_Read(); while (Response==0xffff); break; } case 2://R1b { do Response=SD_Read(); while (Response==0xffff);//Read R1 firstly do Response2=SD_Read()-0xff00; while (Response2!=0);//Wait until the Busy_Signal_Token is non-zero break; } case 3: Response=SD_2Byte_Read();break;//R2 } if (CSLowRSV==0) sd_cse=1;//[6] CS High (if the CMD has data block response CS should be kept low) for (temp=0;temp<8;temp++)//[7] Provide 8 extra clock after card response { sd_clk=0;//CLK Low Delay5us(); sd_clk=1;//CLK High Delay5us(); } return Response; }
//}}} //{{{ int8_t SD_ReadCached (uint8_t* buf, uint32_t blk_addr, uint16_t blocks) { if (SD_present()) { if ((blk_addr >= mReadCacheBlock) && (blk_addr + blocks <= mReadCacheBlock + mReadCacheSize)) { mReadHits++; memcpy (buf, mReadCache + ((blk_addr - mReadCacheBlock) * 512), blocks * 512); } else { mReads++; SD_Read (mReadCache, blk_addr, mReadCacheSize); memcpy (buf, mReadCache, blocks * 512); mReadCacheBlock = blk_addr; } if (blk_addr != mReadBlock + mReadMultipleLen) { if (mReadMultipleLen) { // flush pending multiple //cLcd::debug ("rm:" + dec (mReadBlock) + "::" + dec (mReadMultipleLen)); mReadMultipleLen = 0; } mReadBlock = blk_addr; } mReadMultipleLen += blocks; return 0; } return -1; }
//******************************************** unsigned int Write_Single_Block(unsigned long int BlockAddress) { unsigned int temp,Response,MaximumTimes; MaximumTimes=10; if (BlockAddress>BlockNR) return 0xff20;//whether BlockAddress out of range? for(temp=0;temp<MaximumTimes;temp++) { Response=SD_CMD_Write(24,BlockAddress,1,1);//Send CMD24 if (Response==0xff00) temp=MaximumTimes; } for (temp=0;temp<8;temp++)//Provide 8 extra clock after CMD response { sd_clk=0;//CLK Low Delay5us(); sd_clk=1;//CLK High Delay5us(); } SD_Write(0x00fe);//Send Start Block Token //这里为了使只有512byte的单片机能够读写SD卡,特意节省了RAM的使用量,每次读写只有两个重复的128byte //如果您使用的单片机拥有1K以上的RAM请将"%128"去掉 for (temp=0;temp<256;temp++) SD_2Byte_Write(WriteBuffer[temp%128]);//Data Block SD_2Byte_Write(0xffff);//Send 2 Bytes CRC Response=SD_Read(); while (SD_Read()!=0xffff) {;} sd_cse=1;//CS_High() for (temp=0;temp<8;temp++)//Provide 8 extra clock after data response { sd_clk=0;//CLK Low Delay5us(); sd_clk=1;//CLK High Delay5us(); } return Response; }
DRESULT disk_read ( BYTE pdrv, /* Physical drive number (0..) */ BYTE *buff, /* Data buffer to store read data */ DWORD sector, /* Sector address (LBA) */ UINT count /* Number of sectors to read (1..128) */ ) { DRESULT ret; outpw(REG_SDH_GCTL, SDH_GCTL_SDEN_Msk); //sysprintf("disk_read - drv:%d, sec:%d, cnt:%d, buff:0x%x\n", pdrv, sector, count, (UINT32)buff); if (!((UINT32)buff & 0x80000000)) { /* Disk read buffer is not non-cachable buffer. Use my non-cachable to do disk read. */ if (count * 512 > _MAX_SS) return RES_ERROR; fatfs_win_buff = (BYTE *)((unsigned int)fatfs_win_buff_pool | 0x80000000); if (pdrv == DRV_SD0) ret = (DRESULT) SD_Read(SD_PORT0, fatfs_win_buff, sector, count); else if (pdrv == DRV_SD1) ret = (DRESULT) SD_Read(SD_PORT1, fatfs_win_buff, sector, count); else return RES_ERROR; memcpy(buff, fatfs_win_buff, count * 512); } else { if (pdrv == DRV_SD0) ret = (DRESULT) SD_Read(SD_PORT0, buff, sector, count); else if (pdrv == DRV_SD1) ret = (DRESULT) SD_Read(SD_PORT1, buff, sector, count); else return RES_ERROR; } return ret; }
//------------------------------------------------------------------------------ //! \brief Reads a specified amount of data from a SDCARD memory //! \param media Pointer to a Media instance //! \param address Address of the data to read //! \param data Pointer to the buffer in which to store the retrieved //! data //! \param length Length of the buffer //! \param callback Optional pointer to a callback function to invoke when //! the operation is finished //! \param argument Optional pointer to an argument for the callback //! \return Operation result code //------------------------------------------------------------------------------ static unsigned char MEDSdusb_Read(Media *media, unsigned int address, void *data, unsigned int length, MediaCallback callback, void *argument) { MEDTransfer * pXfr; unsigned char error; TRACE_INFO_WP("SDuRd(%d,%d) ", (int)address, (int)length); // Check that the media is ready if (media->state != MED_STATE_READY) { TRACE_INFO("MEDSdusb_Read: Busy\n\r"); return MED_STATUS_BUSY; } // Check that the data to read is not too big if ((length + address) > media->size) { TRACE_WARNING("MEDSdusb_Read: Data too big: %d, %d\n\r", (int)length, (int)address); return MED_STATUS_ERROR; } // Enter Busy state media->state = MED_STATE_BUSY; // Start media transfer pXfr = &media->transfer; pXfr->data = data; pXfr->address = address; pXfr->length = length; pXfr->callback = callback; pXfr->argument = argument; error = SD_Read((SdCard*)media->interface, address, data, length, SdMmcCallback, media); return (error ? MED_STATUS_ERROR : MED_STATUS_SUCCESS); }
static uint32_t handle_cmd_read_pages(uint32_t cmd, uint32_t *mailbox) { union read_pages_mailbox *mbx = (union read_pages_mailbox*)mailbox; uint32_t offset = mbx->in.offset; uint32_t length = mbx->in.length; assert(cmd == APPLET_CMD_READ_PAGES); if (!initialized) { trace_error_wp("Applet not initialized\r\n"); return APPLET_FAIL; } /* check that requested size does not overflow buffer */ if ((length * BLOCK_SIZE) > buffer_size) { trace_error_wp("Buffer overflow\r\n"); return APPLET_FAIL; } /* check that requested offset/size does not overflow memory */ if (offset + length > mem_size) { trace_error_wp("Memory overflow\r\n"); return APPLET_FAIL; } if (SD_Read(&lib, offset, buffer, length, NULL, NULL) != SDMMC_OK) { trace_info_wp("Error while reading %u bytes at offset 0x%08x\r\n", (unsigned)(mbx->in.length * BLOCK_SIZE), (unsigned)(mbx->in.offset * BLOCK_SIZE)); mbx->out.pages_read = 0; return APPLET_READ_FAIL; } trace_info_wp("Read %u bytes at offset 0x%08x\r\n", (unsigned)(mbx->in.length * BLOCK_SIZE), (unsigned)(mbx->in.offset * BLOCK_SIZE)); mbx->out.pages_read = mbx->in.length; return APPLET_SUCCESS; }
//******************************************** unsigned int Read_Single_Block(unsigned long int BlockAddress) { unsigned int temp,Response,MaximumTimes; MaximumTimes=10; if (BlockAddress>BlockNR) return 0xff20;//whether BlockAddress out of range? for(temp=0;temp<MaximumTimes;temp++) { Response=SD_CMD_Write(17,BlockAddress,1,1);//Send CMD17 if (Response==0xff00) temp=MaximumTimes; } while (SD_Read()!=0xfffe) {;} //这里为了使只有512byte的单片机能够读写SD卡,特意节省了RAM的使用量,每次读写只有两个重复的128byte //如果您使用的单片机拥有1K以上的RAM请将"%128"去掉 for (temp=0;temp<256;temp++) ReadBuffer[temp%128]=SD_2Byte_Read();//Get the readed data for (temp=0;temp<16;temp++)//Provide 16 clock to remove the last 2 bytes of data response (CRC) { sd_clk=0;//CLK Low Delay5us(); sd_clk=1;//CLK High Delay5us(); } sd_cse=1;//CS_High() for (temp=0;temp<8;temp++)//Provide 8 extra clock after data response { sd_clk=0;//CLK Low Delay5us(); sd_clk=1;//CLK High Delay5us(); } return Response; }
void set_env_funcptrs(void) { #ifdef CONFIG_SOC_HAYDN env_init = serialflash_env_init ; saveenv = serialflash_saveenv ; env_get_char_spec = serialflash_env_get_char_spec ; env_relocate_spec = serialflash_env_relocate_spec ; #elif (defined(CONFIG_SOC_MOZART) || defined(CONFIG_SOC_BEETHOVEN)) unsigned long val = inl(BOOTING_DEVICE_INFO); int sdbootSucess = 0 ; #ifdef CONFIG_CMD_MMC if(val == SYSCTRL_DATA_IN_SD && SD_Card_Detect(0)) { printf( " Boot Storage : SD Card\n" ) ; gd->env_valid = 0 ;//We always use default envs when booting from SD. env_init = sd_env_init ; saveenv = sd_saveenv ; env_get_char_spec = sd_env_get_char_spec ; env_relocate_spec = sd_env_relocate_spec ; //check if real sd boot if(SD_Read(MAGIC_SD_ADDR, MAGIC_DATA_SIZE, MAGIC_DRAM_ADDR) != 0) { printf("[ERR] SD-Read fails!\n") ; sdbootSucess = 0 ; goto SDBOOT_FAIL; } if((v_inl(MAGIC_DRAM_ADDR) != MAGIC_NUM0) || (v_inl(MAGIC_DRAM_ADDR+4) != MAGIC_NUM1)) { printf(" !! MAGIC# of SD Card is wrong\n") ; printf(" !! Find other Boot Storage..\n\n") ; sdbootSucess = 0 ; goto SDBOOT_FAIL ; } printf(" SD Card has correct Magic#.\n") ; printf(" SD Boot Sucessfully.\n\n") ; update_default_envs_ifsdboot() ; sdbootSucess = 1 ; #ifdef SDAUTOBURN_FLOW_FROMSD printf(" ****** Auto Burn Flow ******\n") ; printf(" Step 1. Copy data(size 0x%08x) from 0x%08x of SD to 0x%08x of DRAM\n", AUTOBURN_DATASIZE, AUTOBURN_SDADDR, AUTOBURN_DRAMADDR) ; SD_Read(AUTOBURN_SDADDR, AUTOBURN_DATASIZE, AUTOBURN_DRAMADDR) ; if(AUTOBURN_FLASHTYPE == AUTOBURN_SPIFLASH) { printf(" Step 2. Write data from 0x%08x of DRAM to 0x%08x of SPI FLASH\n", AUTOBURN_DRAMADDR, AUTOBURN_FLASHADDR) ; autoburn_sf = spi_flash_probe(0, 0, CONFIG_SF_DEFAULT_SPEED, CONFIG_DEFAULT_SPI_MODE); spi_flash_erase(autoburn_sf, AUTOBURN_FLASHADDR, AUTOBURN_DATASIZE, 0) ; spi_flash_write(autoburn_sf, AUTOBURN_FLASHADDR, AUTOBURN_DATASIZE, AUTOBURN_DRAMADDR, 0) ; printf(" Done\n") ; outl(0xFFF, 0x49000004); } else if(AUTOBURN_FLASHTYPE == AUTOBURN_NANDFLASH) { printf(" Step 3. Write data from 0x%08x of DRAM to 0x%08x of NAND FLASH\n", AUTOBURN_DRAMADDR, AUTOBURN_FLASHADDR) ; nand_info_t *mtd ; mtd = &nand_info[0] ; nand_erase_options_t opts; memset(&opts, 0, sizeof(opts)); opts.offset = AUTOBURN_FLASHADDR; opts.length = AUTOBURN_DATASIZE; //opts.jffs2 = clean; opts.jffs2 = 0;//[patch] we do not allow jffs2 in our u-boot opts.quiet = 0; opts.all = 1 ; unsigned long datasize = AUTOBURN_DATASIZE ; nand_erase_opts(mtd, &opts) ; //printf("chipsize=%d, blocksize=%d, block#=%d\n", mtd->totalsize, mtd->erasesize, (mtd->totalsize / mtd->erasesize)) ; nand_write_skip_bad(mtd, AUTOBURN_FLASHADDR, &datasize, AUTOBURN_DRAMADDR) ;//100 temporary } #endif //SDAUTOBURN_FLOW_FROMSD } if(sdbootSucess) return ; #endif //CONFIG_CMD_SD SDBOOT_FAIL: if ( val == SYSCTRL_DATA_IN_SERIALFLASH) { printf( " Boot Storage : Serial Flash\n" ) ; env_init = serialflash_env_init ; saveenv = serialflash_saveenv ; env_get_char_spec = serialflash_env_get_char_spec ; env_relocate_spec = serialflash_env_relocate_spec ; } #if defined(CONFIG_CMD_NAND) else if ( val == SYSCTRL_DATA_IN_NANDFLASH) { update_default_envs_ifnfboot() ; printf( " Boot Storage : Nand Flash\n" ) ; env_init = nand_env_init ; saveenv = nand_saveenv ; env_get_char_spec = nand_env_get_char_spec ; env_relocate_spec = nand_env_relocate_spec ; } #endif #endif //CONFIG_SOC_MOZART }
/******************************************************************************* * Function Name : main * Description : Main program * Input : None * Output : None * Return : None *******************************************************************************/ int main(void) { /* NVIC configuration */ NVIC_Configuration(); initialisation(); /* Initialisation of SD Card and creation of File */ SD_Init(); /* Blinkmuster laden */ if( SD_Start("muster.txt", FA_OPEN_EXISTING | FA_READ) ) { SD_Read(&muster,1); } SD_Close(); /* LCD Initialisieren */ GLCD_Init(); GLCD_Clear(White); GLCD_SetTextColor(Red); GLCD_DisplayString(1, 1, 1, "Write to SD-Card"); GLCD_DisplayString(8, 1, 1, "Press User to stop"); GLCD_DisplayString(4, 1, 1, "Fit Card into Slot"); /* Wait until SD Card is in Slot */ while(!(SD_Start("time.txt", FA_CREATE_ALWAYS | FA_WRITE))) { } length=sprintf (buffer, "runtime: %d:%d:%d ", hour, min, sek); GLCD_DisplayString(4, 1, 1, buffer); /***************************** * ENDE INITIALISIERUNG * ******************************/ GPIO_ResetBits(GPIOE,GPIO_Pin_All); // LED off all pins while(1) { // BFH_GLCD_UDP(); /* Alle 10ms wird das tickFlag gesetzt */ if(tickFlag) { tickFlag=0; // reset tickFlag if(write > 1) { /* Jede Sekunde einen Stamp ins File schreiben */ if((write%1000) == 0) { /* Zeit hochzählen */ sek++; if(sek==60) { sek=0; min++; } if(min==60) { min=0; hour++; } if(hour==24) { hour=0; } /* write time to Diaplay */ length=sprintf (buffer, "runtime: %d:%d:%d ", hour, min, sek); GLCD_DisplayString(4, 1, 1, buffer); /* write time to card */ length=sprintf (buffer, "runtime: %d:%d:%d\ttext\r\n", hour, min, sek); SD_Write(buffer,length); /* switch LED */ GPIOE->ODR ^= muster << 8; } write += 10; } /* Close SD Card */ else if (write == 1) { SD_Close(); write--; } /* Schreiben beendet -> LED löschen */ else { GPIOE->ODR |= muster << 8; GLCD_DisplayString(8, 1, 1, "Application stopped"); } } /* Wenn Taste gedrückt wird, schreiben beenden */ if((GPIOB->IDR&0x0080) == 0) { write = 1; } } }