Improve SD card IO.

This commit is contained in:
marqs 2016-10-27 01:08:23 +03:00
parent f55e9a877e
commit 611c8763c2
12 changed files with 719 additions and 704 deletions

View File

@ -587,7 +587,7 @@ module i2c_master_bit_ctrl(
begin begin
c_state <= #1 spi_wr_b; c_state <= #1 spi_wr_b;
scl_oen <= #1 1'b0; // set SCL low scl_oen <= #1 1'b0; // set SCL low
sda_oen <= #1 1'b1; // keep SDA sda_oen <= #1 din; // set SDA
sda_chk <= #1 1'b0; // don't check SDA output sda_chk <= #1 1'b0; // don't check SDA output
end end
@ -595,7 +595,7 @@ module i2c_master_bit_ctrl(
begin begin
c_state <= #1 spi_wr_c; c_state <= #1 spi_wr_c;
scl_oen <= #1 1'b0; // keep SCL low scl_oen <= #1 1'b0; // keep SCL low
sda_oen <= #1 din; // set SDA sda_oen <= #1 din; // keep SDA
sda_chk <= #1 1'b0; // don't check SDA output sda_chk <= #1 1'b0; // don't check SDA output
end end
@ -612,7 +612,7 @@ module i2c_master_bit_ctrl(
c_state <= #1 idle; c_state <= #1 idle;
cmd_ack <= #1 1'b1; cmd_ack <= #1 1'b1;
scl_oen <= #1 1'b1; // tri-state SCL scl_oen <= #1 1'b1; // tri-state SCL
sda_oen <= #1 1'b1; // tri-state SDA sda_oen <= #1 din; // keep SDA
sda_chk <= #1 1'b0; // don't check SDA output sda_chk <= #1 1'b0; // don't check SDA output
end end

View File

@ -11,7 +11,7 @@ module i2c_opencores
scl_pad_io, sda_pad_io, spi_miso_pad_i scl_pad_io, sda_pad_io, spi_miso_pad_i
); );
parameter drive_scl_high = 0; parameter always_drive_io = 0;
// Common bus signals // Common bus signals
input wb_clk_i; // WISHBONE clock input wb_clk_i; // WISHBONE clock
@ -43,7 +43,7 @@ wire scl_padoen_o;
assign wb_cyc_i = wb_stb_i; assign wb_cyc_i = wb_stb_i;
assign scl_pad_i = scl_pad_io; assign scl_pad_i = scl_pad_io;
assign scl_pad_io = scl_padoen_o ? (drive_scl_high ? 1'b1 : 1'bZ) : scl_pad_o; assign scl_pad_io = scl_padoen_o ? (always_drive_io ? 1'b1 : 1'bZ) : scl_pad_o;
wire sda_pad_i; wire sda_pad_i;
wire sda_pad_o; wire sda_pad_o;
@ -51,7 +51,7 @@ wire sda_pad_io;
wire sda_padoen_o; wire sda_padoen_o;
assign sda_pad_i = sda_pad_io; assign sda_pad_i = sda_pad_io;
assign sda_pad_io = sda_padoen_o ? 1'bZ : sda_pad_o; assign sda_pad_io = sda_padoen_o ? (always_drive_io ? 1'b1 : 1'bZ) : sda_pad_o;
// Avalon doesn't have an asynchronous reset // Avalon doesn't have an asynchronous reset
// set it to be inactive and just use synchronous reset // set it to be inactive and just use synchronous reset

View File

@ -59,13 +59,13 @@ add_fileset_file timescale.v VERILOG PATH timescale.v
# #
# parameters # parameters
# #
add_parameter drive_scl_high INTEGER 1 add_parameter always_drive_io INTEGER 1
set_parameter_property drive_scl_high DEFAULT_VALUE 0 set_parameter_property always_drive_io DEFAULT_VALUE 0
set_parameter_property drive_scl_high DISPLAY_NAME "Drive SCL high instead of tristate" set_parameter_property always_drive_io DISPLAY_NAME "Always drive IO lines (no tristate)"
set_parameter_property drive_scl_high DISPLAY_HINT boolean set_parameter_property always_drive_io DISPLAY_HINT boolean
set_parameter_property drive_scl_high TYPE INTEGER set_parameter_property always_drive_io TYPE INTEGER
set_parameter_property drive_scl_high UNITS None set_parameter_property always_drive_io UNITS None
set_parameter_property drive_scl_high HDL_PARAMETER true set_parameter_property always_drive_io HDL_PARAMETER true
# #
# display items # display items

File diff suppressed because it is too large Load Diff

View File

@ -36,7 +36,7 @@ int check_flash()
if ((epcq_controller_dev == NULL) || !(epcq_controller_dev->is_epcs && (epcq_controller_dev->page_size == PAGESIZE))) if ((epcq_controller_dev == NULL) || !(epcq_controller_dev->is_epcs && (epcq_controller_dev->page_size == PAGESIZE)))
return -1; return -1;
printf("Flash size in bytes: %d\nSector size: %d (%d pages)\nPage size: %d\n", printf("Flash size in bytes: %lu\nSector size: %lu (%lu pages)\nPage size: %lu\n",
epcq_controller_dev->size_in_bytes, epcq_controller_dev->sector_size, epcq_controller_dev->sector_size/epcq_controller_dev->page_size, epcq_controller_dev->page_size); epcq_controller_dev->size_in_bytes, epcq_controller_dev->sector_size, epcq_controller_dev->sector_size/epcq_controller_dev->page_size, epcq_controller_dev->page_size);
return 0; return 0;

View File

@ -61,8 +61,8 @@ typedef struct {
typedef struct { typedef struct {
func_call f; func_call f;
char *text_success; const char *text_success;
char *text_failure; const char *text_failure;
} opt_func_call; } opt_func_call;
typedef struct menustruct menu_t; typedef struct menustruct menu_t;
@ -73,7 +73,7 @@ typedef struct {
} opt_submenu; } opt_submenu;
typedef struct { typedef struct {
char *name; const char *name;
menuitem_type type; menuitem_type type;
union { union {
opt_avconfig_selection sel; opt_avconfig_selection sel;

View File

@ -111,6 +111,10 @@ BYTE __SD_Send_Cmd(BYTE cmd, DWORD arg)
{ {
BYTE wiredata[10]; BYTE wiredata[10];
BYTE crc, res; BYTE crc, res;
int timer_set;
//printf("Sending SD CMD 0x%x with arg 0x%x\n", cmd, arg);
// ACMD«n» is the command sequense of CMD55-CMD«n» // ACMD«n» is the command sequense of CMD55-CMD«n»
if(cmd & 0x80) { if(cmd & 0x80) {
cmd &= 0x7F; cmd &= 0x7F;
@ -119,9 +123,10 @@ BYTE __SD_Send_Cmd(BYTE cmd, DWORD arg)
} }
// Select the card // Select the card
__SD_Deassert();
SPI_R(NULL, 4);
__SD_Assert(); __SD_Assert();
// Send complete command set // Send complete command set
wiredata[0] = cmd; // Start and command index wiredata[0] = cmd; // Start and command index
wiredata[1] = (arg >> 24); // Arg[31-24] wiredata[1] = (arg >> 24); // Arg[31-24]
@ -139,12 +144,14 @@ BYTE __SD_Send_Cmd(BYTE cmd, DWORD arg)
// Receive command response // Receive command response
// Wait for a valid response in timeout of 5 milliseconds // Wait for a valid response in timeout of 5 milliseconds
SPI_Timer_On(5); timer_set = SPI_Timer_On(5);
do { do {
SPI_R(&res, 1); SPI_R(&res, 1);
} while((res & 0x80)&&(SPI_Timer_Status()==TRUE)); } while((res & 0x80)&&(SPI_Timer_Status()==TRUE));
SPI_Timer_Off(); if (timer_set == 0)
SPI_Timer_Off();
// Return with the response value // Return with the response value
//printf("CMD_res: %u\n", res);
return(res); return(res);
} }
@ -192,14 +199,17 @@ DWORD __SD_Sectors (SD_DEV *dev)
WORD C_SIZE = 0; WORD C_SIZE = 0;
BYTE C_SIZE_MULT = 0; BYTE C_SIZE_MULT = 0;
BYTE READ_BL_LEN = 0; BYTE READ_BL_LEN = 0;
int timer_set;
if(__SD_Send_Cmd(CMD9, 0)==0) if(__SD_Send_Cmd(CMD9, 0)==0)
{ {
// Wait for response // Wait for response
SPI_Timer_On(5); // Wait for data packet (timeout of 5ms) timer_set = SPI_Timer_On(5); // Wait for data packet (timeout of 5ms)
do { do {
SPI_R(&tkn, 1); SPI_R(&tkn, 1);
} while((tkn==0xFF)&&(SPI_Timer_Status()==TRUE)); } while((tkn==0xFF)&&(SPI_Timer_Status()==TRUE));
SPI_Timer_Off(); if (timer_set == 0)
SPI_Timer_Off();
if(tkn!=0xFE) if(tkn!=0xFE)
return 0; return 0;
@ -240,7 +250,6 @@ DWORD __SD_Sectors (SD_DEV *dev)
//ss *= __SD_Power_Of_Two(C_SIZE_MULT + 2 + READ_BL_LEN - 9); //ss *= __SD_Power_Of_Two(C_SIZE_MULT + 2 + READ_BL_LEN - 9);
ss *= 1 << (C_SIZE_MULT + 2 + READ_BL_LEN - 9); ss *= 1 << (C_SIZE_MULT + 2 + READ_BL_LEN - 9);
//ss /= SD_BLK_SIZE; //ss /= SD_BLK_SIZE;
printf("ss: %u\n", ss);
return (ss); return (ss);
} else return (0); // Error } else return (0); // Error
} }
@ -283,9 +292,9 @@ SDRESULTS SD_Init(SD_DEV *dev)
//for(idx = 0; idx != 10; idx++) SPI_RW(0xFF); //for(idx = 0; idx != 10; idx++) SPI_RW(0xFF);
SPI_W(initdata, sizeof(initdata)); SPI_W(initdata, sizeof(initdata));
/*SPI_Timer_On(500); SPI_Timer_On(500);
while(SPI_Timer_Status()==TRUE); while(SPI_Timer_Status()==TRUE);
SPI_Timer_Off();*/ SPI_Timer_Off();
dev->mount = FALSE; dev->mount = FALSE;
SPI_Timer_On(500); SPI_Timer_On(500);
@ -303,7 +312,6 @@ SDRESULTS SD_Init(SD_DEV *dev)
// Wait for leaving idle state (ACMD41 with HCS bit)... // Wait for leaving idle state (ACMD41 with HCS bit)...
SPI_Timer_On(1000); SPI_Timer_On(1000);
while ((SPI_Timer_Status()==TRUE)&&(__SD_Send_Cmd(ACMD41, 1UL << 30))); while ((SPI_Timer_Status()==TRUE)&&(__SD_Send_Cmd(ACMD41, 1UL << 30)));
SPI_Timer_Off();
// CCS in the OCR? // CCS in the OCR?
if ((SPI_Timer_Status()==TRUE)&&(__SD_Send_Cmd(CMD58, 0) == 0)) if ((SPI_Timer_Status()==TRUE)&&(__SD_Send_Cmd(CMD58, 0) == 0))
{ {
@ -311,6 +319,7 @@ SDRESULTS SD_Init(SD_DEV *dev)
// SD version 2? // SD version 2?
ct = (ocr[0] & 0x40) ? SDCT_SD2 | SDCT_BLOCK : SDCT_SD2; ct = (ocr[0] & 0x40) ? SDCT_SD2 | SDCT_BLOCK : SDCT_SD2;
} }
SPI_Timer_Off();
} }
} else { } else {
// SD version 1 or MMC? // SD version 1 or MMC?
@ -327,8 +336,9 @@ SDRESULTS SD_Init(SD_DEV *dev)
// Wait for leaving idle state // Wait for leaving idle state
SPI_Timer_On(250); SPI_Timer_On(250);
while((SPI_Timer_Status()==TRUE)&&(__SD_Send_Cmd(cmd, 0))); while((SPI_Timer_Status()==TRUE)&&(__SD_Send_Cmd(cmd, 0)));
SPI_Timer_Off();
if(SPI_Timer_Status()==FALSE) ct = 0; if(SPI_Timer_Status()==FALSE) ct = 0;
SPI_Timer_Off();
if(__SD_Send_Cmd(CMD59, 0)) ct = 0; // Deactivate CRC check (default) if(__SD_Send_Cmd(CMD59, 0)) ct = 0; // Deactivate CRC check (default)
if(__SD_Send_Cmd(CMD16, 512)) ct = 0; // Set R/W block length to 512 bytes if(__SD_Send_Cmd(CMD16, 512)) ct = 0; // Set R/W block length to 512 bytes
} }
@ -337,7 +347,7 @@ SDRESULTS SD_Init(SD_DEV *dev)
dev->cardtype = ct; dev->cardtype = ct;
dev->mount = TRUE; dev->mount = TRUE;
dev->last_sector = __SD_Sectors(dev) - 1; dev->last_sector = __SD_Sectors(dev) - 1;
printf("lastsec %u\n", dev->last_sector); printf("lastsec %lu\n", dev->last_sector);
#ifdef SD_IO_DBG_COUNT #ifdef SD_IO_DBG_COUNT
dev->debug.read = 0; dev->debug.read = 0;
dev->debug.write = 0; dev->debug.write = 0;

View File

@ -54,9 +54,13 @@ inline void SPI_Freq_Low (void) {
I2C_init(SD_SPI_BASE,ALT_CPU_FREQ,400000); I2C_init(SD_SPI_BASE,ALT_CPU_FREQ,400000);
} }
void SPI_Timer_On (WORD ms) { int SPI_Timer_On (WORD ms) {
sd_timer_ts = ms*(ALT_CPU_FREQ/1000); if (!sd_timer_ts) {
alt_timestamp_start(); sd_timer_ts = ms*(ALT_CPU_FREQ/1000);
alt_timestamp_start();
return 0;
}
return 1;
} }
inline BOOL SPI_Timer_Status (void) { inline BOOL SPI_Timer_Status (void) {
@ -64,5 +68,6 @@ inline BOOL SPI_Timer_Status (void) {
} }
inline void SPI_Timer_Off (void) { inline void SPI_Timer_Off (void) {
sd_timer_ts = 0;
return; return;
} }

View File

@ -71,7 +71,7 @@ void SPI_Freq_Low (void);
\brief Start a non-blocking timer. \brief Start a non-blocking timer.
\param ms Milliseconds. \param ms Milliseconds.
*/ */
void SPI_Timer_On (WORD ms); int SPI_Timer_On (WORD ms);
/** /**
\brief Check the status of non-blocking timer. \brief Check the status of non-blocking timer.

View File

@ -2,9 +2,9 @@
<sch:Settings xmlns:sch="http://www.altera.com/embeddedsw/bsp/schema"> <sch:Settings xmlns:sch="http://www.altera.com/embeddedsw/bsp/schema">
<BspType>hal</BspType> <BspType>hal</BspType>
<BspVersion>default</BspVersion> <BspVersion>default</BspVersion>
<BspGeneratedTimeStamp>Oct 21, 2016 1:18:01 AM</BspGeneratedTimeStamp> <BspGeneratedTimeStamp>Oct 27, 2016 1:02:30 AM</BspGeneratedTimeStamp>
<BspGeneratedUnixTimeStamp>1477001881487</BspGeneratedUnixTimeStamp> <BspGeneratedUnixTimeStamp>1477519350374</BspGeneratedUnixTimeStamp>
<BspGeneratedLocation>./</BspGeneratedLocation> <BspGeneratedLocation>/home/markus/Code/ossc/software/sys_controller_bsp</BspGeneratedLocation>
<BspSettingsFile>settings.bsp</BspSettingsFile> <BspSettingsFile>settings.bsp</BspSettingsFile>
<SopcDesignFile>../../sys.sopcinfo</SopcDesignFile> <SopcDesignFile>../../sys.sopcinfo</SopcDesignFile>
<JdiFile>default</JdiFile> <JdiFile>default</JdiFile>

View File

@ -323,14 +323,14 @@
kind="i2c_opencores" kind="i2c_opencores"
version="13.0" version="13.0"
enabled="1"> enabled="1">
<parameter name="drive_scl_high" value="0" /> <parameter name="always_drive_io" value="0" />
</module> </module>
<module <module
name="i2c_opencores_1" name="i2c_opencores_1"
kind="i2c_opencores" kind="i2c_opencores"
version="13.0" version="13.0"
enabled="1"> enabled="1">
<parameter name="drive_scl_high" value="1" /> <parameter name="always_drive_io" value="1" />
</module> </module>
<module <module
name="jtag_uart_0" name="jtag_uart_0"

View File

@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<EnsembleReport name="sys" kind="sys" version="1.0" fabric="QSYS"> <EnsembleReport name="sys" kind="sys" version="1.0" fabric="QSYS">
<!-- Format version 15.1 185 (Future versions may contain additional information.) --> <!-- Format version 15.1 185 (Future versions may contain additional information.) -->
<!-- 2016.10.21.01:04:02 --> <!-- 2016.10.27.00:58:01 -->
<!-- A collection of modules and connections --> <!-- A collection of modules and connections -->
<parameter name="AUTO_GENERATION_ID"> <parameter name="AUTO_GENERATION_ID">
<type>java.lang.Integer</type> <type>java.lang.Integer</type>
<value>1477001042</value> <value>1477519081</value>
<derived>false</derived> <derived>false</derived>
<enabled>true</enabled> <enabled>true</enabled>
<visible>false</visible> <visible>false</visible>
@ -1613,7 +1613,7 @@ parameters are a RESULT of the module parameters. -->
path="i2c_opencores_0"> path="i2c_opencores_0">
<!-- Describes a single module. Module parameters are <!-- Describes a single module. Module parameters are
the requested settings for a module instance. --> the requested settings for a module instance. -->
<parameter name="drive_scl_high"> <parameter name="always_drive_io">
<type>int</type> <type>int</type>
<value>0</value> <value>0</value>
<derived>false</derived> <derived>false</derived>
@ -2240,7 +2240,7 @@ parameters are a RESULT of the module parameters. -->
path="i2c_opencores_1"> path="i2c_opencores_1">
<!-- Describes a single module. Module parameters are <!-- Describes a single module. Module parameters are
the requested settings for a module instance. --> the requested settings for a module instance. -->
<parameter name="drive_scl_high"> <parameter name="always_drive_io">
<type>int</type> <type>int</type>
<value>1</value> <value>1</value>
<derived>false</derived> <derived>false</derived>