software/liblitesdcard: review/simplify (code is over-complicated, revert part of the old code and write a minimal test for now).
This commit is contained in:
parent
ee4056cfec
commit
ab447df922
|
@ -56,6 +56,66 @@ define_command(sdclk, sdclk, "Set SDCard clk freq (Mhz)", LITESDCARD_CMDS);
|
||||||
define_command(sdinit, sdcard_init, "Initialize SDCard", LITESDCARD_CMDS);
|
define_command(sdinit, sdcard_init, "Initialize SDCard", LITESDCARD_CMDS);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Command "sdread"
|
||||||
|
*
|
||||||
|
* Perform SDcard block read
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifdef CSR_SDCORE_BASE
|
||||||
|
static void sdread(int nb_params, char **params)
|
||||||
|
{
|
||||||
|
unsigned int block;
|
||||||
|
char *c;
|
||||||
|
|
||||||
|
if (nb_params < 1) {
|
||||||
|
printf("sdread <block>");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
block = strtoul(params[0], &c, 0);
|
||||||
|
if (*c != 0) {
|
||||||
|
printf("Incorrect block number");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sdcard_read(block, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
define_command(sdread, sdread, "Read SDCard block", LITESDCARD_CMDS);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Command "sdwrite"
|
||||||
|
*
|
||||||
|
* Perform SDcard block write
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifdef CSR_SDCORE_BASE
|
||||||
|
static void sdwrite(int nb_params, char **params)
|
||||||
|
{
|
||||||
|
unsigned int block;
|
||||||
|
char *c;
|
||||||
|
|
||||||
|
if (nb_params < 2) {
|
||||||
|
printf("sdwrite <block> <str>");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
block = strtoul(params[0], &c, 0);
|
||||||
|
if (*c != 0) {
|
||||||
|
printf("Incorrect block number");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sdcard_write(block, params[1], 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
define_command(sdwrite, sdwrite, "Write SDCard block", LITESDCARD_CMDS);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Command "sdtest"
|
* Command "sdtest"
|
||||||
*
|
*
|
||||||
|
@ -84,61 +144,3 @@ static void sdtest(int nb_params, char **params)
|
||||||
|
|
||||||
define_command(sdtest, sdtest, "Test SDCard Write & Read on N blocks", LITESDCARD_CMDS);
|
define_command(sdtest, sdtest, "Test SDCard Write & Read on N blocks", LITESDCARD_CMDS);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
|
||||||
* Command "sdtestread"
|
|
||||||
*
|
|
||||||
* Perform SDcard read test
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#ifdef CSR_SDCORE_BASE
|
|
||||||
static void sdtestread(int nb_params, char **params)
|
|
||||||
{
|
|
||||||
unsigned int block;
|
|
||||||
char *c;
|
|
||||||
|
|
||||||
if (nb_params < 1) {
|
|
||||||
printf("sdread <block>");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
block = strtoul(params[0], &c, 0);
|
|
||||||
if (*c != 0) {
|
|
||||||
printf("Incorrect block number");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
sdcard_test_read(block);
|
|
||||||
}
|
|
||||||
|
|
||||||
define_command(sdtestread, sdtestread, "Test SDCard Read on block N", LITESDCARD_CMDS);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Command "sdtestwrite"
|
|
||||||
*
|
|
||||||
* Perform SDcard write test
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#ifdef CSR_SDCORE_BASE
|
|
||||||
static void sdtestwrite(int nb_params, char **params)
|
|
||||||
{
|
|
||||||
unsigned int block;
|
|
||||||
char *c;
|
|
||||||
|
|
||||||
if (nb_params < 2) {
|
|
||||||
printf("sdtestwrite <block> <str>");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
block = strtoul(params[0], &c, 0);
|
|
||||||
if (*c != 0) {
|
|
||||||
printf("Incorrect block number");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
sdcard_test_write(block, params[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
define_command(sdtestwrite, sdtestwrite, "Test SDCard Write on block N", LITESDCARD_CMDS);
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// This file is Copyright (c) 2017 Florent Kermarrec <florent@enjoy-digital.fr>
|
// This file is Copyright (c) 2017-2020 Florent Kermarrec <florent@enjoy-digital.fr>
|
||||||
// This file is Copyright (c) 2019 Kees Jongenburger <kees.jongenburger@gmail.com>
|
// This file is Copyright (c) 2019 Kees Jongenburger <kees.jongenburger@gmail.com>
|
||||||
// This file is Copyright (c) 2018 bunnie <bunnie@kosagi.com>
|
// This file is Copyright (c) 2018 bunnie <bunnie@kosagi.com>
|
||||||
// This file is Copyright (c) 2020 Antmicro <www.antmicro.com>
|
// This file is Copyright (c) 2020 Antmicro <www.antmicro.com>
|
||||||
|
@ -14,34 +14,19 @@
|
||||||
|
|
||||||
#include "sdcard.h"
|
#include "sdcard.h"
|
||||||
|
|
||||||
|
//#define SDCARD_DEBUG
|
||||||
|
|
||||||
#ifdef CSR_SDCORE_BASE
|
#ifdef CSR_SDCORE_BASE
|
||||||
|
|
||||||
#define SDCARD_DEBUG
|
unsigned int sdcard_response[SD_RESPONSE_SIZE/4];
|
||||||
|
|
||||||
#define CHECK_LOOPS_PRINT_THRESHOLD 1000000
|
volatile char *sdread_buf = (char*)(SDREAD_BASE);
|
||||||
|
volatile char *sdwrite_buf = (char*)(SDWRITE_BASE);
|
||||||
|
|
||||||
#define REPEATED_MSG(cnt, thr, fmt, ...) do { \
|
/* clocking */
|
||||||
const int _cnt = (cnt); \
|
|
||||||
if((_cnt) >= (thr)) { \
|
|
||||||
if((_cnt) > (thr)) { \
|
|
||||||
printf("\033[1A\033[1G"); \
|
|
||||||
} \
|
|
||||||
printf(fmt "\033[0m\033[K\n", ## __VA_ARGS__); \
|
|
||||||
} \
|
|
||||||
} while(0);
|
|
||||||
|
|
||||||
#define BLOCK_SIZE 512
|
|
||||||
#define NO_RESPONSE 0xFF
|
|
||||||
|
|
||||||
#define SDCARD_RESPONSE_SIZE 4
|
|
||||||
unsigned int sdcard_response[SDCARD_RESPONSE_SIZE];
|
|
||||||
|
|
||||||
volatile char *SDREAD = (char*)(SDREAD_BASE);
|
|
||||||
volatile char *SDWRITE = (char*)(SDWRITE_BASE);
|
|
||||||
|
|
||||||
#ifdef CSR_SDCLK_CMD_DATA_ADDR
|
#ifdef CSR_SDCLK_CMD_DATA_ADDR
|
||||||
|
|
||||||
/* clocking */
|
|
||||||
static void sdclk_dcm_write(int cmd, int data)
|
static void sdclk_dcm_write(int cmd, int data)
|
||||||
{
|
{
|
||||||
int word;
|
int word;
|
||||||
|
@ -82,6 +67,7 @@ static void sdclk_get_config(unsigned int freq, unsigned int *best_m, unsigned i
|
||||||
void sdclk_set_clk(unsigned int freq) {
|
void sdclk_set_clk(unsigned int freq) {
|
||||||
unsigned int clk_m, clk_d;
|
unsigned int clk_m, clk_d;
|
||||||
|
|
||||||
|
printf("Setting SDCard clk freq to %dMHz\n", freq);
|
||||||
sdclk_get_config(100*freq, &clk_m, &clk_d);
|
sdclk_get_config(100*freq, &clk_m, &clk_d);
|
||||||
sdclk_dcm_write(0x1, clk_d-1);
|
sdclk_dcm_write(0x1, clk_d-1);
|
||||||
sdclk_dcm_write(0x3, clk_m-1);
|
sdclk_dcm_write(0x3, clk_m-1);
|
||||||
|
@ -149,6 +135,7 @@ static void sdclk_get_config(unsigned int freq, unsigned int *best_m, unsigned i
|
||||||
void sdclk_set_clk(unsigned int freq) {
|
void sdclk_set_clk(unsigned int freq) {
|
||||||
unsigned int clk_m, clk_d;
|
unsigned int clk_m, clk_d;
|
||||||
|
|
||||||
|
printf("Setting SDCard clk freq to %dMHz\n", freq);
|
||||||
sdclk_get_config(1000*freq, &clk_m, &clk_d);
|
sdclk_get_config(1000*freq, &clk_m, &clk_d);
|
||||||
sdclk_set_config(clk_m, clk_d);
|
sdclk_set_config(clk_m, clk_d);
|
||||||
}
|
}
|
||||||
|
@ -156,7 +143,7 @@ void sdclk_set_clk(unsigned int freq) {
|
||||||
#else
|
#else
|
||||||
|
|
||||||
void sdclk_set_clk(unsigned int freq) {
|
void sdclk_set_clk(unsigned int freq) {
|
||||||
printf("Unimplemented!\n");
|
printf("No SDClocker, returning.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -164,39 +151,39 @@ void sdclk_set_clk(unsigned int freq) {
|
||||||
/* command utils */
|
/* command utils */
|
||||||
|
|
||||||
int sdcard_wait_cmd_done(void) {
|
int sdcard_wait_cmd_done(void) {
|
||||||
unsigned check_counter = 0;
|
|
||||||
unsigned int cmdevt;
|
unsigned int cmdevt;
|
||||||
while (1) {
|
while (1) {
|
||||||
cmdevt = sdcore_cmdevt_read();
|
cmdevt = sdcore_cmdevt_read();
|
||||||
REPEATED_MSG(++check_counter, CHECK_LOOPS_PRINT_THRESHOLD,
|
busy_wait(1); /* FIXME */
|
||||||
"\033[36m cmdevt: %08x (check #%d)",
|
#ifdef SDCARD_DEBUG
|
||||||
cmdevt, check_counter);
|
printf("cmdevt: %08x\n", cmdevt);
|
||||||
if(check_counter > CHECK_LOOPS_PRINT_THRESHOLD) {
|
#endif
|
||||||
putchar('\n');
|
|
||||||
return NO_RESPONSE; //If we reach threshold, and cmdevt didn't return valid status, return NO_RESPONSE
|
|
||||||
}
|
|
||||||
if (cmdevt & 0x1) {
|
if (cmdevt & 0x1) {
|
||||||
if (cmdevt & 0x4)
|
if (cmdevt & 0x4) {
|
||||||
|
#ifdef SDCARD_DEBUG
|
||||||
|
printf("cmdevt: SD_TIMEOUT\n");
|
||||||
|
#endif
|
||||||
return SD_TIMEOUT;
|
return SD_TIMEOUT;
|
||||||
else if (cmdevt & 0x8)
|
}
|
||||||
|
else if (cmdevt & 0x8) {
|
||||||
|
#ifdef SDCARD_DEBUG
|
||||||
|
printf("cmdevt: SD_CRCERROR\n");
|
||||||
return SD_CRCERROR;
|
return SD_CRCERROR;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
return SD_OK;
|
return SD_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int sdcard_wait_data_done(void) {
|
int sdcard_wait_data_done(void) {
|
||||||
unsigned check_counter = 0;
|
|
||||||
unsigned int dataevt;
|
unsigned int dataevt;
|
||||||
while (1) {
|
while (1) {
|
||||||
dataevt = sdcore_dataevt_read();
|
dataevt = sdcore_dataevt_read();
|
||||||
REPEATED_MSG(++check_counter, CHECK_LOOPS_PRINT_THRESHOLD,
|
busy_wait(1); /* FIXME */
|
||||||
"\033[36m dataevt: %08x (check #%d)",
|
#ifdef SDCARD_DEBUG
|
||||||
dataevt, check_counter);
|
printf("dataevt: %08x\n", dataevt);
|
||||||
if(check_counter > CHECK_LOOPS_PRINT_THRESHOLD) {
|
#endif
|
||||||
putchar('\n');
|
|
||||||
return NO_RESPONSE; //If we reach threshold, and cmdevt didn't return valid status, return NO_RESPONSE
|
|
||||||
}
|
|
||||||
if (dataevt & 0x1) {
|
if (dataevt & 0x1) {
|
||||||
if (dataevt & 0x4)
|
if (dataevt & 0x4)
|
||||||
return SD_TIMEOUT;
|
return SD_TIMEOUT;
|
||||||
|
@ -208,15 +195,18 @@ int sdcard_wait_data_done(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int sdcard_wait_response(void) {
|
int sdcard_wait_response(void) {
|
||||||
int i, status;
|
#ifdef SDCARD_DEBUG
|
||||||
|
int i;
|
||||||
|
#endif
|
||||||
|
int status;
|
||||||
|
|
||||||
status = sdcard_wait_cmd_done();
|
status = sdcard_wait_cmd_done();
|
||||||
|
|
||||||
csr_rd_buf_uint32(CSR_SDCORE_RESPONSE_ADDR,
|
csr_rd_buf_uint32(CSR_SDCORE_RESPONSE_ADDR,
|
||||||
sdcard_response, SDCARD_RESPONSE_SIZE);
|
sdcard_response, SD_RESPONSE_SIZE/4);
|
||||||
|
|
||||||
#ifdef SDCARD_DEBUG
|
#ifdef SDCARD_DEBUG
|
||||||
for(i = 0; i < SDCARD_RESPONSE_SIZE; i++) {
|
for(i = 0; i < SD_RESPONSE_SIZE/4; i++) {
|
||||||
printf("%08x ", sdcard_response[i]);
|
printf("%08x ", sdcard_response[i]);
|
||||||
}
|
}
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
@ -386,7 +376,7 @@ int sdcard_write_single_block(unsigned int blockaddr) {
|
||||||
int cmd_response = -1;
|
int cmd_response = -1;
|
||||||
while (cmd_response != SD_OK) {
|
while (cmd_response != SD_OK) {
|
||||||
sdcore_argument_write(blockaddr);
|
sdcore_argument_write(blockaddr);
|
||||||
sdcore_blocksize_write(BLOCK_SIZE);
|
sdcore_blocksize_write(SD_BLOCK_SIZE);
|
||||||
sdcore_blockcount_write(1);
|
sdcore_blockcount_write(1);
|
||||||
sdcore_command_write((24 << 8) | SDCARD_CTRL_RESPONSE_SHORT |
|
sdcore_command_write((24 << 8) | SDCARD_CTRL_RESPONSE_SHORT |
|
||||||
(SDCARD_CTRL_DATA_TRANSFER_WRITE << 5));
|
(SDCARD_CTRL_DATA_TRANSFER_WRITE << 5));
|
||||||
|
@ -403,7 +393,7 @@ int sdcard_write_multiple_block(unsigned int blockaddr, unsigned int blockcnt) {
|
||||||
int cmd_response = -1;
|
int cmd_response = -1;
|
||||||
while (cmd_response != SD_OK) {
|
while (cmd_response != SD_OK) {
|
||||||
sdcore_argument_write(blockaddr);
|
sdcore_argument_write(blockaddr);
|
||||||
sdcore_blocksize_write(BLOCK_SIZE);
|
sdcore_blocksize_write(SD_BLOCK_SIZE);
|
||||||
sdcore_blockcount_write(blockcnt);
|
sdcore_blockcount_write(blockcnt);
|
||||||
sdcore_command_write((25 << 8) | SDCARD_CTRL_RESPONSE_SHORT |
|
sdcore_command_write((25 << 8) | SDCARD_CTRL_RESPONSE_SHORT |
|
||||||
(SDCARD_CTRL_DATA_TRANSFER_WRITE << 5));
|
(SDCARD_CTRL_DATA_TRANSFER_WRITE << 5));
|
||||||
|
@ -420,7 +410,7 @@ int sdcard_read_single_block(unsigned int blockaddr) {
|
||||||
int cmd_response = -1;
|
int cmd_response = -1;
|
||||||
while (cmd_response != SD_OK) {
|
while (cmd_response != SD_OK) {
|
||||||
sdcore_argument_write(blockaddr);
|
sdcore_argument_write(blockaddr);
|
||||||
sdcore_blocksize_write(BLOCK_SIZE);
|
sdcore_blocksize_write(SD_BLOCK_SIZE);
|
||||||
sdcore_blockcount_write(1);
|
sdcore_blockcount_write(1);
|
||||||
sdcore_command_write((17 << 8) | SDCARD_CTRL_RESPONSE_SHORT |
|
sdcore_command_write((17 << 8) | SDCARD_CTRL_RESPONSE_SHORT |
|
||||||
(SDCARD_CTRL_DATA_TRANSFER_READ << 5));
|
(SDCARD_CTRL_DATA_TRANSFER_READ << 5));
|
||||||
|
@ -437,7 +427,7 @@ int sdcard_read_multiple_block(unsigned int blockaddr, unsigned int blockcnt) {
|
||||||
int cmd_response = -1;
|
int cmd_response = -1;
|
||||||
while (cmd_response != SD_OK) {
|
while (cmd_response != SD_OK) {
|
||||||
sdcore_argument_write(blockaddr);
|
sdcore_argument_write(blockaddr);
|
||||||
sdcore_blocksize_write(BLOCK_SIZE);
|
sdcore_blocksize_write(SD_BLOCK_SIZE);
|
||||||
sdcore_blockcount_write(blockcnt);
|
sdcore_blockcount_write(blockcnt);
|
||||||
sdcore_command_write((18 << 8) | SDCARD_CTRL_RESPONSE_SHORT |
|
sdcore_command_write((18 << 8) | SDCARD_CTRL_RESPONSE_SHORT |
|
||||||
(SDCARD_CTRL_DATA_TRANSFER_READ << 5));
|
(SDCARD_CTRL_DATA_TRANSFER_READ << 5));
|
||||||
|
@ -526,30 +516,23 @@ void sdcard_decode_csd(void) {
|
||||||
|
|
||||||
(1 << ((sdcard_response[1] >> 16) & 0xf)),
|
(1 << ((sdcard_response[1] >> 16) & 0xf)),
|
||||||
|
|
||||||
size * BLOCK_SIZE / (1024 * 1024)
|
size * SD_BLOCK_SIZE / (1024 * 1024)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* bist */
|
/* writer / reader */
|
||||||
|
|
||||||
#ifdef CSR_SDDATAWRITER_BASE
|
#ifdef CSR_SDDATAWRITER_BASE
|
||||||
|
|
||||||
void sdcard_sddatawriter_start(void) {
|
void sdcard_sddatawriter_start(void) {
|
||||||
sddatawriter_reset_write(1);
|
sddatawriter_reset_write(1);
|
||||||
sddatawriter_start_write(1);
|
sddatawriter_start_write(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
int sdcard_sddatawriter_wait(void) {
|
int sdcard_sddatawriter_wait(void) {
|
||||||
unsigned check_counter = 0;
|
|
||||||
unsigned done = 0;
|
unsigned done = 0;
|
||||||
while(!done) {
|
while(!done) {
|
||||||
done = sddatawriter_done_read();
|
done = sddatawriter_done_read();
|
||||||
REPEATED_MSG(++check_counter, CHECK_LOOPS_PRINT_THRESHOLD,
|
|
||||||
"\033[36m sddatawriter_done_read: %08x (check #%d)",
|
|
||||||
done, ++check_counter);
|
|
||||||
if(check_counter > CHECK_LOOPS_PRINT_THRESHOLD) {
|
|
||||||
putchar('\n');
|
|
||||||
return NO_RESPONSE; //If we reach threshold, and cmdevt didn't return valid status, return NO_RESPONSE
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -562,17 +545,9 @@ void sdcard_sddatareader_start(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int sdcard_sddatareader_wait(void) {
|
int sdcard_sddatareader_wait(void) {
|
||||||
unsigned check_counter = 0;
|
|
||||||
unsigned done = 0;
|
unsigned done = 0;
|
||||||
while((done & 1) == 0) {
|
while((done & 1) == 0) {
|
||||||
done = sddatareader_done_read();
|
done = sddatareader_done_read();
|
||||||
REPEATED_MSG(++check_counter, CHECK_LOOPS_PRINT_THRESHOLD,
|
|
||||||
"\033[36m sddatareader_done_read: %08x (check #%d)",
|
|
||||||
done, check_counter);
|
|
||||||
if(check_counter > CHECK_LOOPS_PRINT_THRESHOLD) {
|
|
||||||
putchar('\n');
|
|
||||||
return NO_RESPONSE; //If we reach threshold, and cmdevt didn't return valid status, return NO_RESPONSE
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -591,20 +566,6 @@ int sdcard_init(void) {
|
||||||
sdcard_go_idle();
|
sdcard_go_idle();
|
||||||
busy_wait(1);
|
busy_wait(1);
|
||||||
sdcard_send_ext_csd();
|
sdcard_send_ext_csd();
|
||||||
#ifdef SDCARD_DEBUG
|
|
||||||
printf("Accepted voltage: ");
|
|
||||||
if(sdcard_response[3] & 0x0)
|
|
||||||
printf("Not defined\n");
|
|
||||||
else if(sdcard_response[3] >> 8 & 0x1)
|
|
||||||
printf("2.7-3.6V\n");
|
|
||||||
else if(sdcard_response[3] >> 12 & 0x1)
|
|
||||||
printf("Reserved\n");
|
|
||||||
else if(sdcard_response[3] >> 16 & 0x1)
|
|
||||||
printf("Reserved\n");
|
|
||||||
else
|
|
||||||
printf("Invalid response\n");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* wait for card to be ready */
|
/* wait for card to be ready */
|
||||||
/* FIXME: 1.8v support */
|
/* FIXME: 1.8v support */
|
||||||
for(;;) {
|
for(;;) {
|
||||||
|
@ -618,9 +579,7 @@ int sdcard_init(void) {
|
||||||
|
|
||||||
/* send identification */
|
/* send identification */
|
||||||
sdcard_all_send_cid();
|
sdcard_all_send_cid();
|
||||||
#ifdef SDCARD_DEBUG
|
|
||||||
sdcard_decode_cid();
|
sdcard_decode_cid();
|
||||||
#endif
|
|
||||||
|
|
||||||
/* set relative card address */
|
/* set relative card address */
|
||||||
sdcard_set_relative_address();
|
sdcard_set_relative_address();
|
||||||
|
@ -657,154 +616,95 @@ int sdcard_init(void) {
|
||||||
sdcard_app_send_scr();
|
sdcard_app_send_scr();
|
||||||
|
|
||||||
/* set block length */
|
/* set block length */
|
||||||
sdcard_app_set_blocklen(BLOCK_SIZE);
|
sdcard_app_set_blocklen(SD_BLOCK_SIZE);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern void dump_bytes(unsigned int *ptr, int count, unsigned long addr);
|
extern void dump_bytes(unsigned int *ptr, int count, unsigned long addr);
|
||||||
|
|
||||||
void sdcard_test_write(unsigned block, const char *data)
|
void sdcard_write(unsigned block, const char *data, char silent)
|
||||||
{
|
{
|
||||||
#ifdef CSR_SDDATAWRITER_BASE
|
#ifdef CSR_SDDATAWRITER_BASE
|
||||||
const char *c = data;
|
const char *c = data;
|
||||||
int i;
|
int i;
|
||||||
for(i = 0; i < BLOCK_SIZE; i++) {
|
|
||||||
SDWRITE[i] = *c;
|
if (data != NULL) {
|
||||||
|
for(i=0; i<SD_BLOCK_SIZE; i++) {
|
||||||
|
sdwrite_buf[i] = *c;
|
||||||
if(*(++c) == 0) {
|
if(*(++c) == 0) {
|
||||||
c = data;
|
c = data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (silent == 0) {
|
||||||
|
printf("Writing SD block %d from mem:\n", block);
|
||||||
|
dump_bytes((unsigned int *)SDWRITE_BASE, SD_BLOCK_SIZE, (unsigned long) SDWRITE_BASE);
|
||||||
|
}
|
||||||
|
|
||||||
printf("SDWRITE:\n");
|
sdcore_datawcrcclear_write(1);
|
||||||
dump_bytes((unsigned int *)SDWRITE_BASE, BLOCK_SIZE, (unsigned long) SDWRITE_BASE);
|
|
||||||
|
|
||||||
sdcard_set_block_count(1);
|
sdcard_set_block_count(1);
|
||||||
sdcard_sddatawriter_start();
|
sdcard_sddatawriter_start();
|
||||||
sdcard_write_single_block(block * BLOCK_SIZE);
|
sdcard_write_single_block(block * SD_BLOCK_SIZE);
|
||||||
sdcard_sddatawriter_wait();
|
sdcard_sddatawriter_wait();
|
||||||
sdcard_stop_transmission();
|
sdcard_stop_transmission();
|
||||||
#else
|
#else
|
||||||
printf("Writer core not present\n");
|
printf("No SDWriter, returning.\n");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void sdcard_test_read(unsigned block)
|
void sdcard_read(unsigned block, char silent)
|
||||||
{
|
{
|
||||||
#ifdef CSR_SDDATAREADER_BASE
|
#ifdef CSR_SDDATAREADER_BASE
|
||||||
int i;
|
int i;
|
||||||
for(i = 0; i < sizeof(SDREAD); ++i) {
|
for(i = 0; i < sizeof(sdread_buf); ++i) {
|
||||||
SDREAD[i] = 0;
|
sdread_buf[i] = 0;
|
||||||
}
|
}
|
||||||
printf("SDREAD (0x%08x) before read:\n", SDREAD);
|
if (silent == 0)
|
||||||
dump_bytes((unsigned int *)SDREAD_BASE, BLOCK_SIZE, (unsigned long) SDREAD_BASE);
|
printf("Reading SD block %d from mem:\n", block);
|
||||||
|
|
||||||
sdcard_set_block_count(1);
|
sdcard_set_block_count(1);
|
||||||
sdcard_sddatareader_start();
|
sdcard_sddatareader_start();
|
||||||
sdcard_read_single_block(block * BLOCK_SIZE);
|
sdcard_read_single_block(block * SD_BLOCK_SIZE);
|
||||||
sdcard_sddatareader_wait();
|
sdcard_sddatareader_wait();
|
||||||
|
|
||||||
printf("SDREAD (0x%08x) after read:\n", SDREAD);
|
if (silent == 0)
|
||||||
dump_bytes((unsigned int *)SDREAD_BASE, BLOCK_SIZE, (unsigned long) SDREAD_BASE);
|
dump_bytes((unsigned int *)SDREAD_BASE, SD_BLOCK_SIZE, (unsigned long) SDREAD_BASE);
|
||||||
#else
|
#else
|
||||||
printf("Reader core not present\n");
|
printf("No SDReader, returning.\n");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int sdcard_test(unsigned int count)
|
int sdcard_test(unsigned int blocks)
|
||||||
{
|
{
|
||||||
#if defined(CSR_SDDATAREADER_BASE) && defined(CSR_SDDATAWRITER_BASE)
|
#if defined(CSR_SDDATAREADER_BASE) && defined(CSR_SDDATAWRITER_BASE)
|
||||||
|
int i, j;
|
||||||
|
int errors;
|
||||||
|
|
||||||
|
printf("Test SDCard on %d blocks...\n", blocks);
|
||||||
|
errors = 0;
|
||||||
|
for(i=0; i<blocks; i=i+1) {
|
||||||
|
/* fill write mem */
|
||||||
srand(0);
|
srand(0);
|
||||||
int i, j, status;
|
for(j=0; j<SD_BLOCK_SIZE; j++)
|
||||||
int crcerrors = 0;
|
sdwrite_buf[j] = (rand() + i) & 0xff;
|
||||||
int timeouterrors = 0;
|
/* write block from write mem */
|
||||||
int repeat = 0;
|
sdcard_write(i, NULL, 0);
|
||||||
|
|
||||||
sdcore_datawcrcclear_write(1);
|
busy_wait(100); /* FIXME */
|
||||||
|
|
||||||
for(i = 0; i < count; i = repeat ? i : i + 1) {
|
|
||||||
REPEATED_MSG(i, 0, "\033[96mWriting block %d (%d/%d); crc errors: %d; timeouts: %d; datawcrc: %u",
|
|
||||||
i, i + 1, count, crcerrors, timeouterrors, sdcore_datawcrcerrors_read());
|
|
||||||
if(!repeat) {
|
|
||||||
for(j = 0; j < BLOCK_SIZE; ++j) {
|
|
||||||
unsigned number = rand();
|
|
||||||
SDWRITE[j] = number & 0xFF;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
busy_wait(1);
|
|
||||||
}
|
|
||||||
repeat = 0;
|
|
||||||
|
|
||||||
sdcard_set_block_count(1);
|
|
||||||
sdcard_sddatawriter_start();
|
|
||||||
status = sdcard_write_single_block(i * BLOCK_SIZE);
|
|
||||||
if (status == SD_CRCERROR) {
|
|
||||||
++crcerrors;
|
|
||||||
} else if (status == SD_TIMEOUT) {
|
|
||||||
++timeouterrors;
|
|
||||||
}
|
|
||||||
if (status != SD_OK) {
|
|
||||||
REPEATED_MSG(1, 0, "\033[31m Repeating\n");
|
|
||||||
repeat = 1;
|
|
||||||
}
|
|
||||||
status = sdcard_sddatawriter_wait();
|
|
||||||
if (status != 0) {
|
|
||||||
REPEATED_MSG(1, 0, "\033[31m Repeating\n");
|
|
||||||
repeat = 1;
|
|
||||||
}
|
|
||||||
sdcard_stop_transmission();
|
|
||||||
}
|
|
||||||
REPEATED_MSG(i, 0, "\033[39;1mWriting crc errors: %d; timeouts: %d; datawcrc: %u",
|
|
||||||
crcerrors, timeouterrors, sdcore_datawcrcerrors_read());
|
|
||||||
|
|
||||||
|
/* read block to read mem */
|
||||||
|
sdcard_read(i, 0);
|
||||||
|
/* check read mem */
|
||||||
srand(0);
|
srand(0);
|
||||||
int errors = 0;
|
for(j=0; j<SD_BLOCK_SIZE; j++)
|
||||||
int errorsblk = 0;
|
if (sdread_buf[j] != ((rand() + i) & 0xff))
|
||||||
crcerrors = 0;
|
errors++;
|
||||||
timeouterrors = 0;
|
|
||||||
for(i = 0; i < count; i = repeat ? i : i + 1) {
|
|
||||||
REPEATED_MSG(i, 0, "\033[96mReading and checking block %d (%d/%d); errors: %d in %d blocks; crc errors: %d; timeouts: %d",
|
|
||||||
i, i + 1, count, errors, errorsblk, crcerrors, timeouterrors);
|
|
||||||
|
|
||||||
repeat = 0;
|
|
||||||
sdcard_set_block_count(1);
|
|
||||||
sdcard_sddatareader_start();
|
|
||||||
status = sdcard_read_single_block(i * BLOCK_SIZE);
|
|
||||||
if (status == SD_CRCERROR) {
|
|
||||||
++crcerrors;
|
|
||||||
} else if (status == SD_TIMEOUT) {
|
|
||||||
++timeouterrors;
|
|
||||||
}
|
}
|
||||||
if (status != SD_OK) {
|
printf("Errors: %d\n", errors);
|
||||||
REPEATED_MSG(1, 0, "\033[31m Repeating\n");
|
return errors;
|
||||||
repeat = 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
status = sdcard_sddatareader_wait();
|
|
||||||
if (status != 0) {
|
|
||||||
REPEATED_MSG(1, 0, "\033[31m Repeating\n");
|
|
||||||
repeat = 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
int ok = 1;
|
|
||||||
for(j = 0; j < BLOCK_SIZE; ++j) {
|
|
||||||
unsigned number = rand();
|
|
||||||
|
|
||||||
if(SDREAD[j] != (number & 0xFF)) {
|
|
||||||
++errors;
|
|
||||||
ok = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(!ok) {
|
|
||||||
REPEATED_MSG(0, 0, "\033[31m Block check failed\n");
|
|
||||||
++errorsblk;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
REPEATED_MSG(i, 0, "\033[39;1mReading errors: %d in %d blocks; crc errors: %d; timeouts: %d",
|
|
||||||
errors, errorsblk, crcerrors, timeouterrors);
|
|
||||||
#else
|
#else
|
||||||
printf("Reader and/or writer core not present\n");
|
printf("No SDWriter or SDReader, returning.\n");
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,9 @@
|
||||||
|
|
||||||
#ifdef CSR_SDCORE_BASE
|
#ifdef CSR_SDCORE_BASE
|
||||||
|
|
||||||
|
#define SD_BLOCK_SIZE 512
|
||||||
|
#define SD_RESPONSE_SIZE 128
|
||||||
|
|
||||||
#define SD_OK 0
|
#define SD_OK 0
|
||||||
#define SD_CRCERROR 1
|
#define SD_CRCERROR 1
|
||||||
#define SD_TIMEOUT 2
|
#define SD_TIMEOUT 2
|
||||||
|
@ -97,13 +100,13 @@ void sdcard_bist_checker_wait(void);
|
||||||
void hexdump(volatile const char *buf, size_t len);
|
void hexdump(volatile const char *buf, size_t len);
|
||||||
|
|
||||||
int sdcard_init(void);
|
int sdcard_init(void);
|
||||||
void sdcard_test_write(unsigned block, const char *data);
|
void sdcard_write(unsigned block, const char *data, char silent);
|
||||||
void sdcard_test_read(unsigned block);
|
void sdcard_read(unsigned block, char silent);
|
||||||
void sdcard_sddatawriter_start(void);
|
void sdcard_sddatawriter_start(void);
|
||||||
void sdcard_sddatareader_start(void);
|
void sdcard_sddatareader_start(void);
|
||||||
int sdcard_sddatawriter_wait(void);
|
int sdcard_sddatawriter_wait(void);
|
||||||
int sdcard_sddatareader_wait(void);
|
int sdcard_sddatareader_wait(void);
|
||||||
int sdcard_test(unsigned int loops);
|
int sdcard_test(unsigned int blocks);
|
||||||
|
|
||||||
#endif /* CSR_SDCORE_BASE */
|
#endif /* CSR_SDCORE_BASE */
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue