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
c_state <= #1 spi_wr_b;
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
end
@ -595,7 +595,7 @@ module i2c_master_bit_ctrl(
begin
c_state <= #1 spi_wr_c;
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
end
@ -612,7 +612,7 @@ module i2c_master_bit_ctrl(
c_state <= #1 idle;
cmd_ack <= #1 1'b1;
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
end

View File

@ -11,7 +11,7 @@ module i2c_opencores
scl_pad_io, sda_pad_io, spi_miso_pad_i
);
parameter drive_scl_high = 0;
parameter always_drive_io = 0;
// Common bus signals
input wb_clk_i; // WISHBONE clock
@ -43,7 +43,7 @@ wire scl_padoen_o;
assign wb_cyc_i = wb_stb_i;
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_o;
@ -51,7 +51,7 @@ wire sda_pad_io;
wire sda_padoen_o;
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
// 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
#
add_parameter drive_scl_high INTEGER 1
set_parameter_property drive_scl_high DEFAULT_VALUE 0
set_parameter_property drive_scl_high DISPLAY_NAME "Drive SCL high instead of tristate"
set_parameter_property drive_scl_high DISPLAY_HINT boolean
set_parameter_property drive_scl_high TYPE INTEGER
set_parameter_property drive_scl_high UNITS None
set_parameter_property drive_scl_high HDL_PARAMETER true
add_parameter always_drive_io INTEGER 1
set_parameter_property always_drive_io DEFAULT_VALUE 0
set_parameter_property always_drive_io DISPLAY_NAME "Always drive IO lines (no tristate)"
set_parameter_property always_drive_io DISPLAY_HINT boolean
set_parameter_property always_drive_io TYPE INTEGER
set_parameter_property always_drive_io UNITS None
set_parameter_property always_drive_io HDL_PARAMETER true
#
# 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)))
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);
return 0;

View File

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

View File

@ -111,6 +111,10 @@ BYTE __SD_Send_Cmd(BYTE cmd, DWORD arg)
{
BYTE wiredata[10];
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»
if(cmd & 0x80) {
cmd &= 0x7F;
@ -119,9 +123,10 @@ BYTE __SD_Send_Cmd(BYTE cmd, DWORD arg)
}
// Select the card
__SD_Deassert();
SPI_R(NULL, 4);
__SD_Assert();
// Send complete command set
wiredata[0] = cmd; // Start and command index
wiredata[1] = (arg >> 24); // Arg[31-24]
@ -139,12 +144,14 @@ BYTE __SD_Send_Cmd(BYTE cmd, DWORD arg)
// Receive command response
// Wait for a valid response in timeout of 5 milliseconds
SPI_Timer_On(5);
timer_set = SPI_Timer_On(5);
do {
SPI_R(&res, 1);
} while((res & 0x80)&&(SPI_Timer_Status()==TRUE));
SPI_Timer_Off();
if (timer_set == 0)
SPI_Timer_Off();
// Return with the response value
//printf("CMD_res: %u\n", res);
return(res);
}
@ -192,14 +199,17 @@ DWORD __SD_Sectors (SD_DEV *dev)
WORD C_SIZE = 0;
BYTE C_SIZE_MULT = 0;
BYTE READ_BL_LEN = 0;
int timer_set;
if(__SD_Send_Cmd(CMD9, 0)==0)
{
// 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 {
SPI_R(&tkn, 1);
} while((tkn==0xFF)&&(SPI_Timer_Status()==TRUE));
SPI_Timer_Off();
if (timer_set == 0)
SPI_Timer_Off();
if(tkn!=0xFE)
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 *= 1 << (C_SIZE_MULT + 2 + READ_BL_LEN - 9);
//ss /= SD_BLK_SIZE;
printf("ss: %u\n", ss);
return (ss);
} else return (0); // Error
}
@ -283,9 +292,9 @@ SDRESULTS SD_Init(SD_DEV *dev)
//for(idx = 0; idx != 10; idx++) SPI_RW(0xFF);
SPI_W(initdata, sizeof(initdata));
/*SPI_Timer_On(500);
SPI_Timer_On(500);
while(SPI_Timer_Status()==TRUE);
SPI_Timer_Off();*/
SPI_Timer_Off();
dev->mount = FALSE;
SPI_Timer_On(500);
@ -303,7 +312,6 @@ SDRESULTS SD_Init(SD_DEV *dev)
// Wait for leaving idle state (ACMD41 with HCS bit)...
SPI_Timer_On(1000);
while ((SPI_Timer_Status()==TRUE)&&(__SD_Send_Cmd(ACMD41, 1UL << 30)));
SPI_Timer_Off();
// CCS in the OCR?
if ((SPI_Timer_Status()==TRUE)&&(__SD_Send_Cmd(CMD58, 0) == 0))
{
@ -311,6 +319,7 @@ SDRESULTS SD_Init(SD_DEV *dev)
// SD version 2?
ct = (ocr[0] & 0x40) ? SDCT_SD2 | SDCT_BLOCK : SDCT_SD2;
}
SPI_Timer_Off();
}
} else {
// SD version 1 or MMC?
@ -327,8 +336,9 @@ SDRESULTS SD_Init(SD_DEV *dev)
// Wait for leaving idle state
SPI_Timer_On(250);
while((SPI_Timer_Status()==TRUE)&&(__SD_Send_Cmd(cmd, 0)));
SPI_Timer_Off();
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(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->mount = TRUE;
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
dev->debug.read = 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);
}
void SPI_Timer_On (WORD ms) {
sd_timer_ts = ms*(ALT_CPU_FREQ/1000);
alt_timestamp_start();
int SPI_Timer_On (WORD ms) {
if (!sd_timer_ts) {
sd_timer_ts = ms*(ALT_CPU_FREQ/1000);
alt_timestamp_start();
return 0;
}
return 1;
}
inline BOOL SPI_Timer_Status (void) {
@ -64,5 +68,6 @@ inline BOOL SPI_Timer_Status (void) {
}
inline void SPI_Timer_Off (void) {
sd_timer_ts = 0;
return;
}

View File

@ -71,7 +71,7 @@ void SPI_Freq_Low (void);
\brief Start a non-blocking timer.
\param ms Milliseconds.
*/
void SPI_Timer_On (WORD ms);
int SPI_Timer_On (WORD ms);
/**
\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">
<BspType>hal</BspType>
<BspVersion>default</BspVersion>
<BspGeneratedTimeStamp>Oct 21, 2016 1:18:01 AM</BspGeneratedTimeStamp>
<BspGeneratedUnixTimeStamp>1477001881487</BspGeneratedUnixTimeStamp>
<BspGeneratedLocation>./</BspGeneratedLocation>
<BspGeneratedTimeStamp>Oct 27, 2016 1:02:30 AM</BspGeneratedTimeStamp>
<BspGeneratedUnixTimeStamp>1477519350374</BspGeneratedUnixTimeStamp>
<BspGeneratedLocation>/home/markus/Code/ossc/software/sys_controller_bsp</BspGeneratedLocation>
<BspSettingsFile>settings.bsp</BspSettingsFile>
<SopcDesignFile>../../sys.sopcinfo</SopcDesignFile>
<JdiFile>default</JdiFile>

View File

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

View File

@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<EnsembleReport name="sys" kind="sys" version="1.0" fabric="QSYS">
<!-- 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 -->
<parameter name="AUTO_GENERATION_ID">
<type>java.lang.Integer</type>
<value>1477001042</value>
<value>1477519081</value>
<derived>false</derived>
<enabled>true</enabled>
<visible>false</visible>
@ -1613,7 +1613,7 @@ parameters are a RESULT of the module parameters. -->
path="i2c_opencores_0">
<!-- Describes a single module. Module parameters are
the requested settings for a module instance. -->
<parameter name="drive_scl_high">
<parameter name="always_drive_io">
<type>int</type>
<value>0</value>
<derived>false</derived>
@ -2240,7 +2240,7 @@ parameters are a RESULT of the module parameters. -->
path="i2c_opencores_1">
<!-- Describes a single module. Module parameters are
the requested settings for a module instance. -->
<parameter name="drive_scl_high">
<parameter name="always_drive_io">
<type>int</type>
<value>1</value>
<derived>false</derived>