mirror of
https://github.com/mist-devel/mist-firmware.git
synced 2026-04-29 13:33:04 +00:00
Implement MMC_WriteMultiple, use it in IDE and ACSI
This commit is contained in:
@@ -149,15 +149,14 @@ DRESULT disk_write (
|
||||
switch (pdrv) {
|
||||
case DEV_MMC :
|
||||
// translate the arguments here
|
||||
while (count) {
|
||||
result = MMC_Write(sector++, buff);
|
||||
if (!result) return RES_ERROR;
|
||||
count--;
|
||||
buff += 512;
|
||||
}
|
||||
// translate the reslut code here
|
||||
if (count == 1)
|
||||
result = MMC_Write(sector, buff);
|
||||
else
|
||||
result = MMC_WriteMultiple(sector, buff, count);
|
||||
|
||||
return RES_OK;
|
||||
// translate the reslut code here
|
||||
res = result ? RES_OK : RES_ERROR;
|
||||
return res;
|
||||
/*
|
||||
case DEV_USB :
|
||||
// translate the arguments here
|
||||
|
||||
67
hdd.c
67
hdd.c
@@ -481,7 +481,8 @@ static inline void ATA_ReadSectors(unsigned char* tfr, unsigned short sector, un
|
||||
static inline void ATA_WriteSectors(unsigned char* tfr, unsigned short sector, unsigned short cylinder, unsigned char head, unsigned char unit, unsigned short sector_count, char multiple, char lbamode)
|
||||
{
|
||||
unsigned short i;
|
||||
unsigned short block_count;
|
||||
unsigned short block_count, block_size, sectors;
|
||||
unsigned char *buf;
|
||||
long lba=chs2lba(cylinder, head, sector, unit, lbamode);
|
||||
|
||||
// write sectors
|
||||
@@ -498,52 +499,64 @@ static inline void ATA_WriteSectors(unsigned char* tfr, unsigned short sector, u
|
||||
if (multiple && block_count > hdf[unit].sectors_per_block)
|
||||
block_count = hdf[unit].sectors_per_block;
|
||||
|
||||
while(block_count--)
|
||||
{
|
||||
while (!(GetFPGAStatus() & CMD_IDEDAT)); // wait for full write buffer
|
||||
EnableFpga();
|
||||
SPI(CMD_IDE_DATA_RD); // read data command
|
||||
SPI(0x00);
|
||||
SPI(0x00);
|
||||
SPI(0x00);
|
||||
SPI(0x00);
|
||||
SPI(0x00);
|
||||
spi_block_read(sector_buffer);
|
||||
DisableFpga();
|
||||
UINT bw;
|
||||
|
||||
while(block_count)
|
||||
{
|
||||
block_size = (block_count > SECTOR_BUFFER_SIZE/512) ? (SECTOR_BUFFER_SIZE/512) : block_count;
|
||||
sectors = block_size;
|
||||
buf = sector_buffer;
|
||||
while(sectors--) {
|
||||
while (!(GetFPGAStatus() & CMD_IDEDAT)); // wait for full write buffer
|
||||
EnableFpga();
|
||||
SPI(CMD_IDE_DATA_RD); // read data command
|
||||
SPI(0x00);
|
||||
SPI(0x00);
|
||||
SPI(0x00);
|
||||
SPI(0x00);
|
||||
SPI(0x00);
|
||||
spi_block_read(buf);
|
||||
DisableFpga();
|
||||
buf += 512;
|
||||
}
|
||||
switch(hdf[unit].type) {
|
||||
case HDF_FILE | HDF_SYNTHRDB:
|
||||
case HDF_FILE:
|
||||
if (f_size(&hdf[unit].idxfile->file) && (lba>-1)) {
|
||||
// Don't attempt to write to fake RDB
|
||||
FileWriteBlock(&hdf[unit].idxfile->file, sector_buffer);
|
||||
f_write(&hdf[unit].idxfile->file, sector_buffer, 512*block_size, &bw);
|
||||
}
|
||||
lba++;
|
||||
lba+=block_size;
|
||||
break;
|
||||
case HDF_CARD:
|
||||
case HDF_CARDPART0:
|
||||
case HDF_CARDPART1:
|
||||
case HDF_CARDPART2:
|
||||
case HDF_CARDPART3:
|
||||
MMC_Write(lba,sector_buffer);
|
||||
lba++;
|
||||
MMC_WriteMultiple(lba, sector_buffer, block_size);
|
||||
lba+=block_size;
|
||||
break;
|
||||
}
|
||||
|
||||
// decrease sector count
|
||||
if (sector_count!=1) {
|
||||
if (sector == hdf[unit].sectors) {
|
||||
sector = 1;
|
||||
head++;
|
||||
if (head == hdf[unit].heads) {
|
||||
head = 0;
|
||||
cylinder++;
|
||||
sectors = block_size;
|
||||
while(sectors--) {
|
||||
if (sector_count!=1) {
|
||||
if (sector == hdf[unit].sectors) {
|
||||
sector = 1;
|
||||
head++;
|
||||
if (head == hdf[unit].heads) {
|
||||
head = 0;
|
||||
cylinder++;
|
||||
}
|
||||
} else {
|
||||
sector++;
|
||||
}
|
||||
} else {
|
||||
sector++;
|
||||
}
|
||||
sector_count--; // decrease sector count
|
||||
}
|
||||
sector_count--; // decrease sector count
|
||||
|
||||
block_count-=block_size;
|
||||
}
|
||||
|
||||
if (hdf[unit].type & HDF_FILE)
|
||||
|
||||
101
hw/AT91SAM/mmc.c
101
hw/AT91SAM/mmc.c
@@ -396,29 +396,8 @@ unsigned char MMC_ReadMultiple(unsigned long lba, unsigned char *pReadBuffer, un
|
||||
return(1);
|
||||
}
|
||||
|
||||
// write 512-byte block
|
||||
unsigned char MMC_Write(unsigned long lba, const unsigned char *pWriteBuffer)
|
||||
static char MMC_SendDataBlock(const unsigned char *pWriteBuffer)
|
||||
{
|
||||
unsigned long i;
|
||||
|
||||
// check of card has been removed and try to re-initialize it
|
||||
if(!check_card()) return 0;
|
||||
|
||||
if (CardType != CARDTYPE_SDHC) // SDHC cards are addressed in sectors not bytes
|
||||
lba = lba << 9; // otherwise convert sector adddress to byte address
|
||||
|
||||
EnableCard();
|
||||
|
||||
if (MMC_Command(CMD24, lba))
|
||||
{
|
||||
iprintf("CMD24 (WRITE_BLOCK): invalid response 0x%02X (lba=%lu)\r", response, lba);
|
||||
DisableCard();
|
||||
return(0);
|
||||
}
|
||||
|
||||
SPI(0xFF); // one byte gap
|
||||
SPI(0xFE); // send Data Token
|
||||
|
||||
// send sector bytes
|
||||
spi_block_write(pWriteBuffer);
|
||||
spi_wait4xfer_end();
|
||||
@@ -435,32 +414,94 @@ unsigned char MMC_Write(unsigned long lba, const unsigned char *pWriteBuffer)
|
||||
response &= 0x1F;
|
||||
if (response != 0x05)
|
||||
{
|
||||
iprintf("CMD24 (WRITE_BLOCK): invalid status 0x%02X (lba=%lu)\r", response, lba);
|
||||
iprintf("MMC: SendDataBlock: invalid status 0x%02X\r", response);
|
||||
return(0);
|
||||
}
|
||||
|
||||
timeout = 0;
|
||||
while (SPI(0xFF) != 0xFF) // wait until the card is not busy
|
||||
{
|
||||
if (timeout++ >= 1000000)
|
||||
{
|
||||
iprintf("MMC: SendDataBlock: busy wait timeout!\r");
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// write 512-byte block
|
||||
unsigned char MMC_Write(unsigned long lba, const unsigned char *pWriteBuffer)
|
||||
{
|
||||
// check of card has been removed and try to re-initialize it
|
||||
if(!check_card()) return 0;
|
||||
|
||||
if (CardType != CARDTYPE_SDHC) // SDHC cards are addressed in sectors not bytes
|
||||
lba = lba << 9; // otherwise convert sector address to byte address
|
||||
|
||||
EnableCard();
|
||||
|
||||
if (MMC_Command(CMD24, lba))
|
||||
{
|
||||
iprintf("CMD24 (WRITE_BLOCK): invalid response 0x%02X (lba=%lu)\r", response, lba);
|
||||
DisableCard();
|
||||
return(0);
|
||||
}
|
||||
|
||||
// TODO: Move this to the beginning of MMC_Command to interleave Core and SD card better
|
||||
SPI(0xFF); // one byte gap
|
||||
SPI(0xFE); // send Data Token
|
||||
if(!MMC_SendDataBlock(pWriteBuffer)) {
|
||||
DisableCard();
|
||||
return(0);
|
||||
}
|
||||
DisableCard();
|
||||
return(1);
|
||||
}
|
||||
|
||||
// write 512-byte block
|
||||
unsigned char MMC_WriteMultiple(unsigned long lba, const unsigned char *pWriteBuffer, unsigned long nBlockCount)
|
||||
{
|
||||
//iprintf("MMC_WriteMultiple (lba=%d, count=%d)\n", lba, nBlockCount);
|
||||
// check of card has been removed and try to re-initialize it
|
||||
if(!check_card()) return 0;
|
||||
|
||||
if (CardType != CARDTYPE_SDHC) // SDHC cards are addressed in sectors not bytes
|
||||
lba = lba << 9; // otherwise convert sector address to byte address
|
||||
|
||||
EnableCard();
|
||||
|
||||
if (MMC_Command(CMD25, lba))
|
||||
{
|
||||
iprintf("CMD25 (WRITE_MULTIPLE_BLOCK): invalid response 0x%02X (lba=%lu)\r", response, lba);
|
||||
DisableCard();
|
||||
return(0);
|
||||
}
|
||||
|
||||
do {
|
||||
SPI(0xFC); // send Data Token
|
||||
if(!MMC_SendDataBlock(pWriteBuffer)) {
|
||||
DisableCard();
|
||||
return(0);
|
||||
}
|
||||
pWriteBuffer += 512;
|
||||
} while (--nBlockCount);
|
||||
|
||||
SPI(0xFD); // stop Token
|
||||
|
||||
timeout = 0;
|
||||
while (spi_in() == 0x00) // wait until the card is not busy
|
||||
while (SPI(0xFF) != 0xFF) // wait until the card is not busy
|
||||
{
|
||||
if (timeout++ >= 1000000)
|
||||
{
|
||||
iprintf("CMD24 (WRITE_BLOCK): busy wait timeout! (lba=%lu)\r", lba);
|
||||
iprintf("CMD25 (WRITE_MULTIPLE_BLOCK): busy wait timeout! (lba=%lu)\r", lba);
|
||||
DisableCard();
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
|
||||
// real life values here are ~500 until card becomes not busy again
|
||||
// iprintf("W:%d\n", timeout);
|
||||
|
||||
DisableCard();
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
// MMC command
|
||||
static RAMFUNC unsigned char MMC_Command(unsigned char cmd, unsigned long arg)
|
||||
{
|
||||
|
||||
@@ -79,6 +79,7 @@ unsigned char MMC_Init(void);
|
||||
unsigned char MMC_Read(unsigned long lba, unsigned char *pReadBuffer) RAMFUNC;
|
||||
unsigned char MMC_Write(unsigned long lba, const unsigned char *pWriteBuffer);
|
||||
unsigned char MMC_ReadMultiple(unsigned long lba, unsigned char *pReadBuffer, unsigned long nBlockCount);
|
||||
unsigned char MMC_WriteMultiple(unsigned long lba, const unsigned char *pWriteBuffer, unsigned long nBlockCount);
|
||||
unsigned char MMC_GetCSD(unsigned char *);
|
||||
unsigned char MMC_GetCID(unsigned char *);
|
||||
unsigned long MMC_GetCapacity(); // Returns the capacity in 512 byte blocks
|
||||
|
||||
27
tos.c
27
tos.c
@@ -239,6 +239,7 @@ static void dma_nak(void) {
|
||||
}
|
||||
|
||||
static void handle_acsi(unsigned char *buffer) {
|
||||
|
||||
static unsigned char asc[2] = { 0,0 };
|
||||
unsigned char target = buffer[10] >> 5;
|
||||
unsigned char device = buffer[1] >> 5;
|
||||
@@ -246,6 +247,11 @@ static void handle_acsi(unsigned char *buffer) {
|
||||
unsigned long lba = 256 * 256 * (buffer[1] & 0x1f) +
|
||||
256 * buffer[2] + buffer[3];
|
||||
unsigned short length = buffer[4];
|
||||
|
||||
unsigned short blocklen;
|
||||
unsigned char *buf;
|
||||
unsigned short blocks;
|
||||
|
||||
if(length == 0) length = 256;
|
||||
|
||||
if(user_io_dip_switch1()) {
|
||||
@@ -389,17 +395,28 @@ static void handle_acsi(unsigned char *buffer) {
|
||||
if(lba+length <= blocks) {
|
||||
DISKLED_ON;
|
||||
while(length) {
|
||||
mist_memory_read_block(sector_buffer);
|
||||
UINT bw;
|
||||
|
||||
blocklen = (length > SECTOR_BUFFER_SIZE/512) ? SECTOR_BUFFER_SIZE/512 : length;
|
||||
buf = sector_buffer;
|
||||
blocks = blocklen;
|
||||
while (blocks--) {
|
||||
mist_memory_read_block(buf);
|
||||
buf+=512;
|
||||
}
|
||||
if(hdd_direct && target == 0) {
|
||||
if(user_io_dip_switch1())
|
||||
tos_debugf("ACSI: direct write %ld", lba);
|
||||
MMC_Write(lba++, sector_buffer);
|
||||
if (blocklen == 1)
|
||||
MMC_Write(lba++, sector_buffer);
|
||||
else
|
||||
MMC_WriteMultiple(lba++, sector_buffer, blocklen);
|
||||
} else {
|
||||
IDXSeek(&sd_image[target+2], lba);
|
||||
FileWriteBlock(&sd_image[target+2].file, sector_buffer);
|
||||
lba++;
|
||||
f_write(&sd_image[target+2].file, sector_buffer, blocklen*512, &bw);
|
||||
}
|
||||
length--;
|
||||
lba+=blocklen;
|
||||
length-=blocklen;
|
||||
}
|
||||
DISKLED_OFF;
|
||||
dma_ack(0x00);
|
||||
|
||||
Reference in New Issue
Block a user