Firmware: optimize non-sector-aligned SD DMA reads
This commit is contained in:
parent
afc26397b1
commit
b272a6fc1c
@ -47,9 +47,15 @@
|
|||||||
s: Bit 2 = partial, Bit 1:0 = target
|
s: Bit 2 = partial, Bit 1:0 = target
|
||||||
target: see above
|
target: see above
|
||||||
|
|
||||||
60 sssseeee set SD DMA partial transfer start+end
|
60 xsssyeee set SD DMA partial transfer parameters
|
||||||
ssss = start offset (msb first)
|
x: 0 = read from sector start (skip until
|
||||||
eeee = end offset (msb first)
|
start offset reached)
|
||||||
|
8 = assume mid-sector position and read
|
||||||
|
immediately
|
||||||
|
sss = start offset (msb first)
|
||||||
|
y: 0 = skip rest of SD sector
|
||||||
|
8 = stop mid-sector if end offset reached
|
||||||
|
eee = end offset (msb first)
|
||||||
|
|
||||||
8p - read (RAM only)
|
8p - read (RAM only)
|
||||||
p: 0 = no increment after read
|
p: 0 = no increment after read
|
||||||
@ -98,7 +104,7 @@
|
|||||||
15 SD DMA busy (0=idle, 1=busy)
|
15 SD DMA busy (0=idle, 1=busy)
|
||||||
14 DAC read pointer MSB
|
14 DAC read pointer MSB
|
||||||
13 MSU read pointer MSB
|
13 MSU read pointer MSB
|
||||||
12 [TODO SD DMA CRC status (0=ok, 1=error); valid after bit 15 -> 0]
|
12 reserved (0)
|
||||||
11 reserved (0)
|
11 reserved (0)
|
||||||
10 reserved (0)
|
10 reserved (0)
|
||||||
9 reserved (0)
|
9 reserved (0)
|
||||||
@ -239,7 +245,7 @@ void fpga_sddma(uint8_t tgt, uint8_t partial) {
|
|||||||
}
|
}
|
||||||
DBG_SD printf("...complete\n");
|
DBG_SD printf("...complete\n");
|
||||||
FPGA_DESELECT();
|
FPGA_DESELECT();
|
||||||
if(test<5)printf("loopy: %ld %02x\n", test, status);
|
// if(test<5)printf("loopy: %ld %02x\n", test, status);
|
||||||
BITBAND(SD_CLKREG->FIODIR, SD_CLKPIN) = 1;
|
BITBAND(SD_CLKREG->FIODIR, SD_CLKPIN) = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -35,6 +35,8 @@ int i;
|
|||||||
|
|
||||||
int sd_offload = 0, ff_sd_offload = 0, sd_offload_tgt = 0;
|
int sd_offload = 0, ff_sd_offload = 0, sd_offload_tgt = 0;
|
||||||
int sd_offload_partial = 0;
|
int sd_offload_partial = 0;
|
||||||
|
int sd_offload_start_mid = 0;
|
||||||
|
int sd_offload_end_mid = 0;
|
||||||
uint16_t sd_offload_partial_start = 0;
|
uint16_t sd_offload_partial_start = 0;
|
||||||
uint16_t sd_offload_partial_end = 0;
|
uint16_t sd_offload_partial_end = 0;
|
||||||
|
|
||||||
|
|||||||
@ -115,11 +115,12 @@ uint8_t cid[17];
|
|||||||
uint8_t ccs=0;
|
uint8_t ccs=0;
|
||||||
uint32_t rca;
|
uint32_t rca;
|
||||||
|
|
||||||
enum trans_state { TRANS_NONE = 0, TRANS_READ, TRANS_WRITE };
|
enum trans_state { TRANS_NONE = 0, TRANS_READ, TRANS_WRITE, TRANS_MID };
|
||||||
enum cmd_state { CMD_RSP = 0, CMD_RSPDAT, CMD_DAT };
|
enum cmd_state { CMD_RSP = 0, CMD_RSPDAT, CMD_DAT };
|
||||||
|
|
||||||
int during_blocktrans = TRANS_NONE;
|
int during_blocktrans = TRANS_NONE;
|
||||||
uint32_t last_block = 0;
|
uint32_t last_block = 0;
|
||||||
|
uint16_t last_offset = 0;
|
||||||
|
|
||||||
volatile int sd_changed;
|
volatile int sd_changed;
|
||||||
|
|
||||||
@ -395,7 +396,6 @@ int send_command_fast(uint8_t* cmd, uint8_t* rsp, uint8_t* buf){
|
|||||||
printf("CMD%d timed out\n", cmdno);
|
printf("CMD%d timed out\n", cmdno);
|
||||||
return 0; /* no response within timeout */
|
return 0; /* no response within timeout */
|
||||||
}
|
}
|
||||||
|
|
||||||
i=rsplen;
|
i=rsplen;
|
||||||
uint8_t cmddata=0, datdata=0;
|
uint8_t cmddata=0, datdata=0;
|
||||||
while(i--) { /* process response */
|
while(i--) { /* process response */
|
||||||
@ -460,20 +460,31 @@ int send_command_fast(uint8_t* cmd, uint8_t* rsp, uint8_t* buf){
|
|||||||
state=CMD_DAT;
|
state=CMD_DAT;
|
||||||
j=datcnt;
|
j=datcnt;
|
||||||
datshift=8;
|
datshift=8;
|
||||||
|
timeout=2000000;
|
||||||
DBG_SD printf("response over, waiting for data...\n");
|
DBG_SD printf("response over, waiting for data...\n");
|
||||||
/* wait for data start bit on DAT0 */
|
/* wait for data start bit on DAT0 */
|
||||||
while((BITBAND(SD_DAT0REG->FIOPIN, SD_DAT0PIN)) && --timeout) {
|
while((BITBAND(SD_DAT0REG->FIOPIN, SD_DAT0PIN)) && --timeout) {
|
||||||
wiggle_fast_neg1();
|
wiggle_fast_neg1();
|
||||||
}
|
}
|
||||||
|
//printf("%ld\n", timeout);
|
||||||
DBG_SD if(!timeout) printf("timed out!\n");
|
DBG_SD if(!timeout) printf("timed out!\n");
|
||||||
wiggle_fast_neg1(); /* eat the start bit */
|
wiggle_fast_neg1(); /* eat the start bit */
|
||||||
if(sd_offload) {
|
if(sd_offload) {
|
||||||
if(sd_offload_partial) {
|
if(sd_offload_partial) {
|
||||||
|
if(sd_offload_partial_start != 0) {
|
||||||
|
if(during_blocktrans == TRANS_MID) sd_offload_partial_start |= 0x8000;
|
||||||
|
}
|
||||||
|
if(sd_offload_partial_end != 512) {
|
||||||
|
sd_offload_partial_end |= 0x8000;
|
||||||
|
}
|
||||||
|
DBG_SD printf("new partial %d - %d\n", sd_offload_partial_start, sd_offload_partial_end);
|
||||||
fpga_set_sddma_range(sd_offload_partial_start, sd_offload_partial_end);
|
fpga_set_sddma_range(sd_offload_partial_start, sd_offload_partial_end);
|
||||||
fpga_sddma(sd_offload_tgt, 1);
|
fpga_sddma(sd_offload_tgt, 1);
|
||||||
sd_offload_partial=0;
|
// sd_offload_partial=0;
|
||||||
|
last_offset=sd_offload_partial_end;
|
||||||
} else {
|
} else {
|
||||||
fpga_sddma(sd_offload_tgt, 0);
|
fpga_sddma(sd_offload_tgt, 0);
|
||||||
|
last_offset=0;
|
||||||
}
|
}
|
||||||
state=CMD_RSP;
|
state=CMD_RSP;
|
||||||
return rsplen;
|
return rsplen;
|
||||||
@ -597,17 +608,24 @@ int stream_datablock(uint8_t *buf) {
|
|||||||
uint32_t timeout=1000000;
|
uint32_t timeout=1000000;
|
||||||
|
|
||||||
DBG_SD printf("stream_datablock: wait for ready...\n");
|
DBG_SD printf("stream_datablock: wait for ready...\n");
|
||||||
while((BITBAND(SD_DAT0REG->FIOPIN, SD_DAT0PIN)) && --timeout) {
|
if(during_blocktrans != TRANS_MID) {
|
||||||
wiggle_fast_neg1();
|
while((BITBAND(SD_DAT0REG->FIOPIN, SD_DAT0PIN)) && --timeout) {
|
||||||
|
wiggle_fast_neg1();
|
||||||
|
}
|
||||||
|
DBG_SD if(!timeout) printf("timeout!\n");
|
||||||
|
wiggle_fast_neg1(); /* eat the start bit */
|
||||||
}
|
}
|
||||||
DBG_SD if(!timeout) printf("timeout!\n");
|
|
||||||
|
|
||||||
wiggle_fast_neg1(); /* eat the start bit */
|
|
||||||
if(sd_offload) {
|
if(sd_offload) {
|
||||||
if(sd_offload_partial) {
|
if(sd_offload_partial) {
|
||||||
|
if(sd_offload_partial_start != 0) {
|
||||||
|
if(during_blocktrans == TRANS_MID) sd_offload_partial_start |= 0x8000;
|
||||||
|
}
|
||||||
|
if(sd_offload_partial_end != 512) {
|
||||||
|
sd_offload_partial_end |= 0x8000;
|
||||||
|
}
|
||||||
|
DBG_SD printf("str partial %d - %d\n", sd_offload_partial_start, sd_offload_partial_end);
|
||||||
fpga_set_sddma_range(sd_offload_partial_start, sd_offload_partial_end);
|
fpga_set_sddma_range(sd_offload_partial_start, sd_offload_partial_end);
|
||||||
fpga_sddma(sd_offload_tgt, 1);
|
fpga_sddma(sd_offload_tgt, 1);
|
||||||
sd_offload_partial=0;
|
|
||||||
} else {
|
} else {
|
||||||
fpga_sddma(sd_offload_tgt, 0);
|
fpga_sddma(sd_offload_tgt, 0);
|
||||||
}
|
}
|
||||||
@ -772,7 +790,21 @@ void read_block(uint32_t address, uint8_t *buf) {
|
|||||||
#else
|
#else
|
||||||
stream_datablock(buf);
|
stream_datablock(buf);
|
||||||
#endif
|
#endif
|
||||||
last_block=address;
|
last_block = address;
|
||||||
|
last_offset = sd_offload_partial_end & 0x1ff;
|
||||||
|
if(sd_offload_partial && sd_offload_partial_end != 512) {
|
||||||
|
during_blocktrans = TRANS_MID;
|
||||||
|
}
|
||||||
|
sd_offload_partial = 0;
|
||||||
|
} else if (during_blocktrans == TRANS_MID
|
||||||
|
&& last_block == address
|
||||||
|
&& last_offset == sd_offload_partial_start
|
||||||
|
&& sd_offload_partial) {
|
||||||
|
stream_datablock(buf);
|
||||||
|
last_offset = sd_offload_partial_end & 0x1ff;
|
||||||
|
sd_offload_partial_start |= 0x8000;
|
||||||
|
during_blocktrans = TRANS_READ;
|
||||||
|
sd_offload_partial = 0;
|
||||||
} else {
|
} else {
|
||||||
if(during_blocktrans) {
|
if(during_blocktrans) {
|
||||||
// uart_putc('_');
|
// uart_putc('_');
|
||||||
@ -780,7 +812,7 @@ void read_block(uint32_t address, uint8_t *buf) {
|
|||||||
/* send STOP_TRANSMISSION to end an open READ/WRITE_MULTIPLE_BLOCK */
|
/* send STOP_TRANSMISSION to end an open READ/WRITE_MULTIPLE_BLOCK */
|
||||||
cmd_fast(STOP_TRANSMISSION, 0, 0x61, NULL, rsp);
|
cmd_fast(STOP_TRANSMISSION, 0, 0x61, NULL, rsp);
|
||||||
}
|
}
|
||||||
last_block=address;
|
last_block = address;
|
||||||
if(!ccs) {
|
if(!ccs) {
|
||||||
address <<= 9;
|
address <<= 9;
|
||||||
}
|
}
|
||||||
@ -792,8 +824,10 @@ void read_block(uint32_t address, uint8_t *buf) {
|
|||||||
#else
|
#else
|
||||||
cmd_fast(READ_MULTIPLE_BLOCK, address, 0, buf, rsp);
|
cmd_fast(READ_MULTIPLE_BLOCK, address, 0, buf, rsp);
|
||||||
#endif
|
#endif
|
||||||
|
sd_offload_partial = 0;
|
||||||
during_blocktrans = TRANS_READ;
|
during_blocktrans = TRANS_READ;
|
||||||
}
|
}
|
||||||
|
// printf("trans state = %d\n", during_blocktrans);
|
||||||
}
|
}
|
||||||
|
|
||||||
void write_block(uint32_t address, uint8_t* buf) {
|
void write_block(uint32_t address, uint8_t* buf) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user