Rewrite readblock in assembly

This commit is contained in:
Byron Lathi
2023-08-08 19:28:10 -07:00
parent 446f4e7539
commit e73c4e1d08
7 changed files with 606 additions and 560 deletions

View File

@@ -276,56 +276,58 @@ void SD_sendStatus(uint8_t *res)
token = 0x0X - Data error
token = 0xFF - timeout
*******************************************************************************/
uint8_t SD_readSingleBlock(uint32_t addr, uint8_t *buf, uint8_t *token)
{
uint8_t res1, read;
uint16_t readAttempts;
uint16_t i;
// uint8_t SD_readSingleBlock(uint32_t addr, uint8_t *buf, uint8_t *token)
// {
// uint8_t res1, read;
// uint16_t readAttempts;
// uint16_t i;
// set token to none
*token = 0xFF;
// // set token to none
// *token = 0xFF;
// assert chip select
spi_exchange(0xFF);
spi_select(0);
spi_exchange(0xFF);
// // assert chip select
// spi_exchange(0xFF);
// spi_select(0);
// spi_exchange(0xFF);
// send CMD17
SD_command(CMD17, addr, CMD17_CRC);
// // send CMD17
// SD_command(CMD17, addr, CMD17_CRC);
// read R1
res1 = SD_readRes1();
// // read R1
// res1 = SD_readRes1();
// if response received from card
if(res1 != 0xFF)
{
// wait for a response token (timeout = 100ms)
readAttempts = 0;
while(++readAttempts != SD_MAX_READ_ATTEMPTS)
if((read = spi_exchange(0xFF)) != 0xFF) break;
// // if response received from card
// if(res1 != 0xFF)
// {
// // wait for a response token (timeout = 100ms)
// readAttempts = 0;
// while(++readAttempts != SD_MAX_READ_ATTEMPTS)
// if((read = spi_exchange(0xFF)) != 0xFF) break;
// if response token is 0xFE
if(read == SD_START_TOKEN)
{
// read 512 byte block
for(i = 0; i < SD_BLOCK_LEN; i++) *buf++ = spi_exchange(0xFF);
// cprintf("read attempts: %d\r\n", readAttempts);
// read 16-bit CRC
spi_exchange(0xFF);
spi_exchange(0xFF);
}
// // if response token is 0xFE
// if(read == SD_START_TOKEN)
// {
// // read 512 byte block
// for(i = 0; i < SD_BLOCK_LEN; i++) *buf++ = spi_exchange(0xFF);
// set token to card response
*token = read;
}
// // read 16-bit CRC
// spi_exchange(0xFF);
// spi_exchange(0xFF);
// }
// deassert chip select
spi_exchange(0xFF);
spi_deselect(0);
spi_exchange(0xFF);
// // set token to card response
// *token = read;
// }
return res1;
}
// // deassert chip select
// spi_exchange(0xFF);
// spi_deselect(0);
// spi_exchange(0xFF);
// return res1;
// }
#define SD_MAX_WRITE_ATTEMPTS 3907

View File

@@ -6,8 +6,9 @@
.export _SD_readBytes
.export _SD_powerUpSeq
.export _res1_cmd
.export _SD_readSingleBlock
.importzp sp, ptr1
.importzp sp, ptr1, ptr2, ptr3, ptr4, tmp1, tmp2, tmp3
.autoimport on
@@ -27,7 +28,7 @@
dey
arg_loop: ; send ARG
lda (sp),y
lda (sp),y ; is this sending only 3?
jsr _spi_exchange
dey
bpl arg_loop
@@ -187,4 +188,116 @@ read:
dex ; 2
bne @L1 ; 3
rts
.endproc
; ;uint8_t SD_readSingleBlock(uint32_t addr, uint8_t *buf, uint8_t *token)
.proc _SD_readSingleBlock: near
; token address in a/x
; buf address next on stack
; sd address above that
; ptr2 = *token
sta ptr2
stx ptr2 + 1
lda #$ff
sta (ptr2)
; ptr1 = *buf
jsr popptr1
; 4 bytes on stack are addr
; Move addr down on the stack
lda sp
sta ptr3
lda sp + 1
sta ptr3 + 1
; find a way to do this in a loop?
jsr decsp1
ldy #$0
lda (ptr3),y
sta (sp),y
iny
lda (ptr3),y
sta (sp),y
iny
lda (ptr3),y
sta (sp),y
iny
lda (ptr3),y
sta (sp),y
lda #$ff
jsr _spi_exchange
lda #$00 ; this gets ignored anyway
jsr _spi_select
lda #$ff
jsr _spi_exchange
; push cmd17
lda #$11
ldy #$4
sta (sp),y
; crc, 0
lda #$00
jsr _SD_command ; rely on command to teardown stack
jsr _SD_readRes1
cmp #$ff ; if 0xFF then you failed
beq end
sta tmp3 ; tmp3 = read
; y = read_attempts
ldy #$0
resp_loop:
lda #$ff
jsr _spi_exchange
sta tmp2 ; tmp2 = read
lda tmp2
cmp #$ff
bne got_resp
iny
bne resp_loop
bra after_read
got_resp:
ldx #$2
ldy #$00
load_loop:
lda #$ff
jsr _spi_exchange
sta (ptr1)
inc ptr1
bne @2
inc ptr1 + 1
@2: dey
bne load_loop
ldy #$00
dex
bne load_loop
lda #$ff
jsr _spi_exchange
lda #$ff
jsr _spi_exchange
after_read:
lda tmp2
sta (ptr2)
lda tmp3
end:
pha
lda #$ff
jsr _spi_exchange
lda #$00 ; this gets ignored anyway
jsr _spi_deselect
lda #$ff
jsr _spi_exchange
pla
rts
.endproc

View File

@@ -3,152 +3,6 @@
#include "sd_print.h"
#include "sd_card.h"
/*
void SD_printR1(uint8_t res)
{
if(res == 0xFF)
{ cputs("\tNo response\r\n"); return; }
if(res & 0x80)
{ cputs("\tError: MSB = 1\r\n"); return; }
if(res == 0)
{ cputs("\tCard Ready\r\n"); return; }
if(PARAM_ERROR(res))
cputs("\tParameter Error\r\n");
if(ADDR_ERROR(res))
cputs("\tAddress Error\r\n");
if(ERASE_SEQ_ERROR(res))
cputs("\tErase Sequence Error\r\n");
if(CRC_ERROR(res))
cputs("\tCRC Error\r\n");
if(ILLEGAL_CMD(res))
cputs("\tIllegal Command\r\n");
if(ERASE_RESET(res))
cputs("\tErase Reset Error\r\n");
if(IN_IDLE(res))
cputs("\tIn Idle State\r\n");
}
*/
/*
void SD_printR2(uint8_t *res)
{
SD_printR1(res[0]);
if(res[0] == 0xFF) return;
if(res[1] == 0x00)
cputs("\tNo R2 Error\r\n");
if(OUT_OF_RANGE(res[1]))
cputs("\tOut of Range\r\n");
if(ERASE_PARAM(res[1]))
cputs("\tErase Parameter\r\n");
if(WP_VIOLATION(res[1]))
cputs("\tWP Violation\r\n");
if(CARD_ECC_FAILED(res[1]))
cputs("\tECC Failed\r\n");
if(CC_ERROR(res[1]))
cputs("\tCC Error\r\n");
if(ERROR(res[1]))
cputs("\tError\r\n");
if(WP_ERASE_SKIP(res[1]))
cputs("\tWP Erase Skip\r\n");
if(CARD_LOCKED(res[1]))
cputs("\tCard Locked\r\n");
}
*/
/*
void SD_printR3(uint8_t *res)
{
SD_printR1(res[0]);
if(res[0] > 1) return;
cputs("\tCard Power Up Status: ");
if(POWER_UP_STATUS(res[1]))
{
cputs("READY\r\n");
cputs("\tCCS Status: ");
if(CCS_VAL(res[1])){ cputs("1\r\n"); }
else cputs("0\r\n");
}
else
{
cputs("BUSY\r\n");
}
cputs("\tVDD Window: ");
if(VDD_2728(res[3])) cputs("2.7-2.8, ");
if(VDD_2829(res[2])) cputs("2.8-2.9, ");
if(VDD_2930(res[2])) cputs("2.9-3.0, ");
if(VDD_3031(res[2])) cputs("3.0-3.1, ");
if(VDD_3132(res[2])) cputs("3.1-3.2, ");
if(VDD_3233(res[2])) cputs("3.2-3.3, ");
if(VDD_3334(res[2])) cputs("3.3-3.4, ");
if(VDD_3435(res[2])) cputs("3.4-3.5, ");
if(VDD_3536(res[2])) cputs("3.5-3.6");
cputs("\r\n");
}
*/
/*
void SD_printR7(uint8_t *res)
{
SD_printR1(res[0]);
if(res[0] > 1) return;
cputs("\tCommand Version: ");
cprintf("%x", CMD_VER(res[1]));
cputs("\r\n");
cputs("\tVoltage Accepted: ");
if(VOL_ACC(res[3]) == VOLTAGE_ACC_27_33) {
cputs("2.7-3.6V\r\n");
} else if(VOL_ACC(res[3]) == VOLTAGE_ACC_LOW) {
cputs("LOW VOLTAGE\r\n");
} else if(VOL_ACC(res[3]) == VOLTAGE_ACC_RES1) {
cputs("RESERVED\r\n");
} else if(VOL_ACC(res[3]) == VOLTAGE_ACC_RES2) {
cputs("RESERVED\r\n");
} else {
cputs("NOT DEFINED\r\n");
}
cputs("\tEcho: ");
cprintf("%x", res[4]);
cputs("\r\n");
}
*/
/*
void SD_printCSD(uint8_t *buf)
{
cputs("CSD:\r\n");
cputs("\tCSD Structure: ");
cprintf("%x", (buf[0] & 0b11000000) >> 6);
cputs("\r\n");
cputs("\tTAAC: ");
cprintf("%x", buf[1]);
cputs("\r\n");
cputs("\tNSAC: ");
cprintf("%x", buf[2]);
cputs("\r\n");
cputs("\tTRAN_SPEED: ");
cprintf("%x", buf[3]);
cputs("\r\n");
cputs("\tDevice Size: ");
cprintf("%x", buf[7] & 0b00111111);
cprintf("%x", buf[8]);
cprintf("%x", buf[9]);
cputs("\r\n");
}
*/
void SD_printBuf(uint8_t *buf)
{
@@ -170,19 +24,3 @@ void SD_printBuf(uint8_t *buf)
}
cputs("\r\n");
}
/*
void SD_printDataErrToken(uint8_t token)
{
if(token & 0xF0)
cputs("\tNot Error token\r\n");
if(SD_TOKEN_OOR(token))
cputs("\tData out of range\r\n");
if(SD_TOKEN_CECC(token))
cputs("\tCard ECC failed\r\n");
if(SD_TOKEN_CC(token))
cputs("\tCC Error\r\n");
if(SD_TOKEN_ERROR(token))
cputs("\tError\r\n");
}
*/

View File

@@ -31,24 +31,17 @@ int main() {
{
cputs("Success\r\n");
// read sector 0
cputs("\r\nReading sector: 0x");
// ((uint8_t)(addr >> 24));
// cprintf("%x", (uint8_t)(addr >> 16));
// cprintf("%x", (uint8_t)(addr >> 8));
// cprintf("%x", (uint8_t)addr);
res[0] = SD_readSingleBlock(addr, buf, &token);
cputs("\r\nResponse:\r\n");
//SD_printR1(res[0]);
res[0] = SD_readSingleBlock(addr, buf, &token);
// if no error, print buffer
if((res[0] == 0x00) && (token == SD_START_TOKEN))
SD_printBuf(buf);
//else if error token received, print
else if(!(token & 0xF0))
{
cputs("Error token:\r\n");
//SD_printDataErrToken(token);
cputs("Error\r\n");
} else {
cprintf("bad token: %x\r\n", token);
}
__asm__ ("jmp (%v)", buf);