mirror of
https://github.com/fhgwright/SCSI2SD.git
synced 2025-02-06 15:29:56 +00:00
Multi-sector writes, increased SPI clock to 24MHz, Added support for SDHC/SDXC.
This commit is contained in:
parent
aa5e83b9db
commit
27e482ea8c
@ -1,30 +1,30 @@
|
||||
:20000000065200400165004034060140220701404314014043150140031601403F1701409B
|
||||
:2000200003400140024101400242014002430140064801400D49014004500140015101405F
|
||||
:2000400014FF18081CE12CFF34F06430870F81A1830E844785618698878288818A408BCF3F
|
||||
:200060008C048D4C9001914C924094889661974C98E299449A089B089C419D10A041A11029
|
||||
:20008000A441A508A720A840A944AC10AD4CB110B361B4C0B50FB63FB780B880B902BA2077
|
||||
:2000A000BB0CBE40BF40D409D604D80BD90BDB0BDC99DD90DF01008401200A6A102A1302EE
|
||||
:2000C00019201B80209421042244281029602A042B40302832013380381439425810590AE3
|
||||
:2000E0005A80628063407801C007C20FC40FCA0FCC0FCE0FD60FD809DE0102010404050176
|
||||
:20010000060807060A040E30120314101504160C1703182019031A0C1B041C0320032403E8
|
||||
:20012000280329052B022E483002324033073401363C3B083E1154405604580B590B5B0B91
|
||||
:200140005C995D905F0180E084208501860387028A088EE0900892109486950197049A01A1
|
||||
:200160009D06A210A645A902AB01B018B107B2E0B407B902BE05D808D908DB04DC99DF01A8
|
||||
:2001800000040180024003080404058007840A6A0C060D040E081028120113021501170833
|
||||
:2001A000184019821B181D041E882108278028042C0431083210378838043C0460806250DE
|
||||
:2001C00063206C0278017F01848089018B408D048E0490049108926A9302944097409801B7
|
||||
:2001E0009A519B0E9D02A028A508A640B704C0FFC27FC43FCA24CC56CE42D80FDE11E020BD
|
||||
:20020000E250E480EC1056085B045D90008401210A68102A13021B402018210122902308A9
|
||||
:20022000280229202A043028314032013814394240444104480449084B40500252555E8092
|
||||
:20024000610864016702682869416A427140730278019004910892089542966298029920F9
|
||||
:200260009C019D4A9E049F02A040A42AA680A740A812AF40C00FC20EC40FCA0ECC0FCE0F51
|
||||
:20028000D007D20CD610D812DE0130103640CC309C10A6409C10A6409C10A6402320270820
|
||||
:2002A0009C10AE40C860EE400B205004578084108B188C048F809B089C10B720C210D460F6
|
||||
:2002C000E64001010B0111011B01000FC02902461F172028802000D000D6600090D64000B2
|
||||
:2002E00000D0FF067FD2800400D60000C0000100C0040400C002080000219F8E000F00F0DE
|
||||
:20030000000FFF01002200080000404063024000050EFDBC3DFFFFFF2200F008040000005B
|
||||
:2003200000000228040B0B0B909900010000C00040011011C00100114001400100000000CE
|
||||
:2003400000000000000000000000000000FFFF00000000000800300008000000000000005F
|
||||
:200360000000000010000000FF000000000000010200F10E0E000C000000000000FCFC005A
|
||||
:2003800000000000F0000FF00000000000010000F00F0F000000000100000000000000005E
|
||||
:2000000006520040016500403706014023070140431401403F15014003160140401701409A
|
||||
:2000200003400140024101400242014002430140064801401049014004500140015101405C
|
||||
:2000400014FF18081CE12CFF34F06430870F5B045F018010818684418582870488818901B7
|
||||
:200060008A408BAE8C888D698E618F0690019186924094479698978698E299E79A089B0810
|
||||
:200080009C419D86A110A404A504A740A840A982AC41AD10B10FB3E0B4C0B510B63FB7087A
|
||||
:2000A000B880B922BA20BB0CBE40BF40D409D604D80BD90BDB0BDC99DD90DF010040012602
|
||||
:2000C0000A6910081220138019A02054226C2310281029A12A04300831403210330138500B
|
||||
:2000E0003905581059085A82628063406D407801C00FC20FC407CA0FCC0FCE0FD60FD809B0
|
||||
:20010000DE01023006040820095C0A0C0B200C100D380E0C0F421203140415401608173043
|
||||
:2001200019191A481B601C031D0722012307240328032C03303C3240337034013507360275
|
||||
:2001400037083B083E503F5054405604580B590B5B0B5C995D905F01820885018610870274
|
||||
:2001600089028B018D018E058F0494069A019D06AA03AC08AE10B018B107B407B902BE0108
|
||||
:20018000D808D908DC99DF010040010A02080448068008200A610E080F101028124013803D
|
||||
:2001A0001560190A1A021B901E88210822A027402902310832103340374038403B103C4019
|
||||
:2001C0003F1460806250632078017F018004848086808A028E2490409160926193169602FD
|
||||
:2001E00098219A509B80A028A208A508A6C2A780A821C0BFC26FC4CFCA01CC1ECE7CD80FA1
|
||||
:20020000DE11E250E42056085B045D90004401210A69102A190120102110221023042840C0
|
||||
:2002200029602A0430083210334138503904404041104380490A4A0A500352545E806108D9
|
||||
:2002400064016702682869056A406BC1714072017801904491409208931095059663984012
|
||||
:2002600099209C019D4B9E049F81A208A408A680AC40AE04AF40C00FC20FC407CA0FCC0F56
|
||||
:20028000CE0ED00DD20CD610D812DE0130103640CC309C10A6409C10A6409C10A640210887
|
||||
:2002A00025809C10AE40C860EE4009025004578081808410850889028C048F809C10A18852
|
||||
:2002C000C210D460E040E480E64001010B0111011B01000FC000020000D46008802000D0B5
|
||||
:2002E0000021FF4E90DC40001FD0200C7F118022C0DC01000020008FC0080400C0040800B3
|
||||
:2003000000DC9F00FF0000F0000F000000000008000001004602100005BEFDBC3FFFFFFF4B
|
||||
:200320002200F0080400000000000228040B0B0B909900010000C00040011011C001001132
|
||||
:20034000400140010000000000000000000000000000000000FFFF000000000008003000E5
|
||||
:2003600008000000000000000000000010000000FF000000000000010200F10E0E000C004A
|
||||
:200380000000000000FCFC0000000000F0000FF00000000000010000F00F0F000000000166
|
||||
:00000001FF
|
||||
|
@ -307,24 +307,24 @@
|
||||
/* SD_Clk_Ctl */
|
||||
#define SD_Clk_Ctl_Sync_ctrl_reg__0__MASK 0x01u
|
||||
#define SD_Clk_Ctl_Sync_ctrl_reg__0__POS 0
|
||||
#define SD_Clk_Ctl_Sync_ctrl_reg__16BIT_CONTROL_AUX_CTL_REG CYREG_B1_UDB05_06_ACTL
|
||||
#define SD_Clk_Ctl_Sync_ctrl_reg__16BIT_CONTROL_CONTROL_REG CYREG_B1_UDB05_06_CTL
|
||||
#define SD_Clk_Ctl_Sync_ctrl_reg__16BIT_CONTROL_COUNT_REG CYREG_B1_UDB05_06_CTL
|
||||
#define SD_Clk_Ctl_Sync_ctrl_reg__16BIT_COUNT_CONTROL_REG CYREG_B1_UDB05_06_CTL
|
||||
#define SD_Clk_Ctl_Sync_ctrl_reg__16BIT_COUNT_COUNT_REG CYREG_B1_UDB05_06_CTL
|
||||
#define SD_Clk_Ctl_Sync_ctrl_reg__16BIT_MASK_MASK_REG CYREG_B1_UDB05_06_MSK
|
||||
#define SD_Clk_Ctl_Sync_ctrl_reg__16BIT_MASK_PERIOD_REG CYREG_B1_UDB05_06_MSK
|
||||
#define SD_Clk_Ctl_Sync_ctrl_reg__16BIT_PERIOD_MASK_REG CYREG_B1_UDB05_06_MSK
|
||||
#define SD_Clk_Ctl_Sync_ctrl_reg__16BIT_PERIOD_PERIOD_REG CYREG_B1_UDB05_06_MSK
|
||||
#define SD_Clk_Ctl_Sync_ctrl_reg__CONTROL_AUX_CTL_REG CYREG_B1_UDB05_ACTL
|
||||
#define SD_Clk_Ctl_Sync_ctrl_reg__CONTROL_REG CYREG_B1_UDB05_CTL
|
||||
#define SD_Clk_Ctl_Sync_ctrl_reg__CONTROL_ST_REG CYREG_B1_UDB05_ST_CTL
|
||||
#define SD_Clk_Ctl_Sync_ctrl_reg__COUNT_REG CYREG_B1_UDB05_CTL
|
||||
#define SD_Clk_Ctl_Sync_ctrl_reg__COUNT_ST_REG CYREG_B1_UDB05_ST_CTL
|
||||
#define SD_Clk_Ctl_Sync_ctrl_reg__16BIT_CONTROL_AUX_CTL_REG CYREG_B0_UDB06_07_ACTL
|
||||
#define SD_Clk_Ctl_Sync_ctrl_reg__16BIT_CONTROL_CONTROL_REG CYREG_B0_UDB06_07_CTL
|
||||
#define SD_Clk_Ctl_Sync_ctrl_reg__16BIT_CONTROL_COUNT_REG CYREG_B0_UDB06_07_CTL
|
||||
#define SD_Clk_Ctl_Sync_ctrl_reg__16BIT_COUNT_CONTROL_REG CYREG_B0_UDB06_07_CTL
|
||||
#define SD_Clk_Ctl_Sync_ctrl_reg__16BIT_COUNT_COUNT_REG CYREG_B0_UDB06_07_CTL
|
||||
#define SD_Clk_Ctl_Sync_ctrl_reg__16BIT_MASK_MASK_REG CYREG_B0_UDB06_07_MSK
|
||||
#define SD_Clk_Ctl_Sync_ctrl_reg__16BIT_MASK_PERIOD_REG CYREG_B0_UDB06_07_MSK
|
||||
#define SD_Clk_Ctl_Sync_ctrl_reg__16BIT_PERIOD_MASK_REG CYREG_B0_UDB06_07_MSK
|
||||
#define SD_Clk_Ctl_Sync_ctrl_reg__16BIT_PERIOD_PERIOD_REG CYREG_B0_UDB06_07_MSK
|
||||
#define SD_Clk_Ctl_Sync_ctrl_reg__CONTROL_AUX_CTL_REG CYREG_B0_UDB06_ACTL
|
||||
#define SD_Clk_Ctl_Sync_ctrl_reg__CONTROL_REG CYREG_B0_UDB06_CTL
|
||||
#define SD_Clk_Ctl_Sync_ctrl_reg__CONTROL_ST_REG CYREG_B0_UDB06_ST_CTL
|
||||
#define SD_Clk_Ctl_Sync_ctrl_reg__COUNT_REG CYREG_B0_UDB06_CTL
|
||||
#define SD_Clk_Ctl_Sync_ctrl_reg__COUNT_ST_REG CYREG_B0_UDB06_ST_CTL
|
||||
#define SD_Clk_Ctl_Sync_ctrl_reg__MASK 0x01u
|
||||
#define SD_Clk_Ctl_Sync_ctrl_reg__MASK_CTL_AUX_CTL_REG CYREG_B1_UDB05_MSK_ACTL
|
||||
#define SD_Clk_Ctl_Sync_ctrl_reg__PERIOD_REG CYREG_B1_UDB05_MSK
|
||||
#define SD_Clk_Ctl_Sync_ctrl_reg__PER_CTL_AUX_CTL_REG CYREG_B1_UDB05_MSK_ACTL
|
||||
#define SD_Clk_Ctl_Sync_ctrl_reg__MASK_CTL_AUX_CTL_REG CYREG_B0_UDB06_MSK_ACTL
|
||||
#define SD_Clk_Ctl_Sync_ctrl_reg__PERIOD_REG CYREG_B0_UDB06_MSK
|
||||
#define SD_Clk_Ctl_Sync_ctrl_reg__PER_CTL_AUX_CTL_REG CYREG_B0_UDB06_MSK_ACTL
|
||||
|
||||
/* PARITY_EN */
|
||||
#define PARITY_EN__0__MASK 0x10u
|
||||
@ -1775,9 +1775,9 @@
|
||||
#define CYDEV_CHIP_FAMILY_PSOC5 3u
|
||||
#define CYDEV_CHIP_DIE_PSOC5LP 4u
|
||||
#define CYDEV_CHIP_DIE_EXPECT CYDEV_CHIP_DIE_PSOC5LP
|
||||
#define BCLK__BUS_CLK__HZ 64000000U
|
||||
#define BCLK__BUS_CLK__KHZ 64000U
|
||||
#define BCLK__BUS_CLK__MHZ 64U
|
||||
#define BCLK__BUS_CLK__HZ 63000000U
|
||||
#define BCLK__BUS_CLK__KHZ 63000U
|
||||
#define BCLK__BUS_CLK__MHZ 63U
|
||||
#define CYDEV_CHIP_DIE_ACTUAL CYDEV_CHIP_DIE_EXPECT
|
||||
#define CYDEV_CHIP_DIE_LEOPARD 1u
|
||||
#define CYDEV_CHIP_DIE_PANTHER 3u
|
||||
|
@ -117,31 +117,31 @@ typedef struct
|
||||
#define cy_cfg_data_table ((const cy_cfg_addrvalue_t CYFAR *)0x48000040u)
|
||||
|
||||
/* UDB_1_1_0_CONFIG Address: CYDEV_UCFG_B1_P3_U1_BASE Size (bytes): 128 */
|
||||
#define BS_UDB_1_1_0_CONFIG_VAL ((const uint8 CYFAR *)0x480002CCu)
|
||||
#define BS_UDB_1_1_0_CONFIG_VAL ((const uint8 CYFAR *)0x480002D4u)
|
||||
|
||||
/* IOPINS0_0 Address: CYREG_PRT0_DM0 Size (bytes): 8 */
|
||||
#define BS_IOPINS0_0_VAL ((const uint8 CYFAR *)0x4800034Cu)
|
||||
#define BS_IOPINS0_0_VAL ((const uint8 CYFAR *)0x48000354u)
|
||||
|
||||
/* IOPINS0_7 Address: CYREG_PRT12_DR Size (bytes): 10 */
|
||||
#define BS_IOPINS0_7_VAL ((const uint8 CYFAR *)0x48000354u)
|
||||
#define BS_IOPINS0_7_VAL ((const uint8 CYFAR *)0x4800035Cu)
|
||||
|
||||
/* IOPINS1_7 Address: CYREG_PRT12_DR + 0x0000000Bu Size (bytes): 5 */
|
||||
#define BS_IOPINS1_7_VAL ((const uint8 CYFAR *)0x48000360u)
|
||||
#define BS_IOPINS1_7_VAL ((const uint8 CYFAR *)0x48000368u)
|
||||
|
||||
/* IOPINS0_2 Address: CYREG_PRT2_DM0 Size (bytes): 8 */
|
||||
#define BS_IOPINS0_2_VAL ((const uint8 CYFAR *)0x48000368u)
|
||||
#define BS_IOPINS0_2_VAL ((const uint8 CYFAR *)0x48000370u)
|
||||
|
||||
/* IOPINS0_3 Address: CYREG_PRT3_DR Size (bytes): 10 */
|
||||
#define BS_IOPINS0_3_VAL ((const uint8 CYFAR *)0x48000370u)
|
||||
#define BS_IOPINS0_3_VAL ((const uint8 CYFAR *)0x48000378u)
|
||||
|
||||
/* IOPINS0_4 Address: CYREG_PRT4_DM0 Size (bytes): 8 */
|
||||
#define BS_IOPINS0_4_VAL ((const uint8 CYFAR *)0x4800037Cu)
|
||||
#define BS_IOPINS0_4_VAL ((const uint8 CYFAR *)0x48000384u)
|
||||
|
||||
/* IOPINS0_5 Address: CYREG_PRT5_DR Size (bytes): 10 */
|
||||
#define BS_IOPINS0_5_VAL ((const uint8 CYFAR *)0x48000384u)
|
||||
#define BS_IOPINS0_5_VAL ((const uint8 CYFAR *)0x4800038Cu)
|
||||
|
||||
/* IOPINS0_6 Address: CYREG_PRT6_DM0 Size (bytes): 8 */
|
||||
#define BS_IOPINS0_6_VAL ((const uint8 CYFAR *)0x48000390u)
|
||||
#define BS_IOPINS0_6_VAL ((const uint8 CYFAR *)0x48000398u)
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
@ -201,9 +201,9 @@ static void ClockSetup(void)
|
||||
|
||||
|
||||
/* Configure Digital Clocks based on settings from Clock DWR */
|
||||
CY_SET_XTND_REG16((void CYFAR *)(CYREG_CLKDIST_DCFG0_CFG0), 0x0001u);
|
||||
CY_SET_XTND_REG8((void CYFAR *)(CYREG_CLKDIST_DCFG0_CFG0 + 0x2u), 0x18u);
|
||||
CY_SET_XTND_REG16((void CYFAR *)(CYREG_CLKDIST_DCFG1_CFG0), 0x001Du);
|
||||
CY_SET_XTND_REG16((void CYFAR *)(CYREG_CLKDIST_DCFG0_CFG0), 0x0000u);
|
||||
CY_SET_XTND_REG8((void CYFAR *)(CYREG_CLKDIST_DCFG0_CFG0 + 0x2u), 0x11u);
|
||||
CY_SET_XTND_REG16((void CYFAR *)(CYREG_CLKDIST_DCFG1_CFG0), 0x003Bu);
|
||||
CY_SET_XTND_REG8((void CYFAR *)(CYREG_CLKDIST_DCFG1_CFG0 + 0x2u), 0x19u);
|
||||
|
||||
/* Configure ILO based on settings from Clock DWR */
|
||||
@ -211,11 +211,11 @@ static void ClockSetup(void)
|
||||
CY_SET_XTND_REG8((void CYFAR *)(CYREG_CLKDIST_CR), 0x08u);
|
||||
|
||||
/* Configure IMO based on settings from Clock DWR */
|
||||
CY_SET_XTND_REG8((void CYFAR *)(CYREG_FASTCLK_IMO_CR), 0x02u);
|
||||
CY_SET_XTND_REG8((void CYFAR *)(CYREG_IMO_TR1), (CY_GET_XTND_REG8((void CYFAR *)CYREG_FLSHID_CUST_TABLES_IMO_24MHZ)));
|
||||
CY_SET_XTND_REG8((void CYFAR *)(CYREG_FASTCLK_IMO_CR), 0x04u);
|
||||
CY_SET_XTND_REG8((void CYFAR *)(CYREG_IMO_TR1), (CY_GET_XTND_REG8((void CYFAR *)(CYREG_FLSHID_MFG_CFG_IMO_TR1 + 1u))));
|
||||
|
||||
/* Configure PLL based on settings from Clock DWR */
|
||||
CY_SET_XTND_REG16((void CYFAR *)(CYREG_FASTCLK_PLL_P), 0x0818u);
|
||||
CY_SET_XTND_REG16((void CYFAR *)(CYREG_FASTCLK_PLL_P), 0x0F15u);
|
||||
CY_SET_XTND_REG16((void CYFAR *)(CYREG_FASTCLK_PLL_CFG0), 0x1051u);
|
||||
/* Wait up to 250us for the PLL to lock */
|
||||
pllLock = 0u;
|
||||
|
@ -307,24 +307,24 @@
|
||||
/* SD_Clk_Ctl */
|
||||
.set SD_Clk_Ctl_Sync_ctrl_reg__0__MASK, 0x01
|
||||
.set SD_Clk_Ctl_Sync_ctrl_reg__0__POS, 0
|
||||
.set SD_Clk_Ctl_Sync_ctrl_reg__16BIT_CONTROL_AUX_CTL_REG, CYREG_B1_UDB05_06_ACTL
|
||||
.set SD_Clk_Ctl_Sync_ctrl_reg__16BIT_CONTROL_CONTROL_REG, CYREG_B1_UDB05_06_CTL
|
||||
.set SD_Clk_Ctl_Sync_ctrl_reg__16BIT_CONTROL_COUNT_REG, CYREG_B1_UDB05_06_CTL
|
||||
.set SD_Clk_Ctl_Sync_ctrl_reg__16BIT_COUNT_CONTROL_REG, CYREG_B1_UDB05_06_CTL
|
||||
.set SD_Clk_Ctl_Sync_ctrl_reg__16BIT_COUNT_COUNT_REG, CYREG_B1_UDB05_06_CTL
|
||||
.set SD_Clk_Ctl_Sync_ctrl_reg__16BIT_MASK_MASK_REG, CYREG_B1_UDB05_06_MSK
|
||||
.set SD_Clk_Ctl_Sync_ctrl_reg__16BIT_MASK_PERIOD_REG, CYREG_B1_UDB05_06_MSK
|
||||
.set SD_Clk_Ctl_Sync_ctrl_reg__16BIT_PERIOD_MASK_REG, CYREG_B1_UDB05_06_MSK
|
||||
.set SD_Clk_Ctl_Sync_ctrl_reg__16BIT_PERIOD_PERIOD_REG, CYREG_B1_UDB05_06_MSK
|
||||
.set SD_Clk_Ctl_Sync_ctrl_reg__CONTROL_AUX_CTL_REG, CYREG_B1_UDB05_ACTL
|
||||
.set SD_Clk_Ctl_Sync_ctrl_reg__CONTROL_REG, CYREG_B1_UDB05_CTL
|
||||
.set SD_Clk_Ctl_Sync_ctrl_reg__CONTROL_ST_REG, CYREG_B1_UDB05_ST_CTL
|
||||
.set SD_Clk_Ctl_Sync_ctrl_reg__COUNT_REG, CYREG_B1_UDB05_CTL
|
||||
.set SD_Clk_Ctl_Sync_ctrl_reg__COUNT_ST_REG, CYREG_B1_UDB05_ST_CTL
|
||||
.set SD_Clk_Ctl_Sync_ctrl_reg__16BIT_CONTROL_AUX_CTL_REG, CYREG_B0_UDB06_07_ACTL
|
||||
.set SD_Clk_Ctl_Sync_ctrl_reg__16BIT_CONTROL_CONTROL_REG, CYREG_B0_UDB06_07_CTL
|
||||
.set SD_Clk_Ctl_Sync_ctrl_reg__16BIT_CONTROL_COUNT_REG, CYREG_B0_UDB06_07_CTL
|
||||
.set SD_Clk_Ctl_Sync_ctrl_reg__16BIT_COUNT_CONTROL_REG, CYREG_B0_UDB06_07_CTL
|
||||
.set SD_Clk_Ctl_Sync_ctrl_reg__16BIT_COUNT_COUNT_REG, CYREG_B0_UDB06_07_CTL
|
||||
.set SD_Clk_Ctl_Sync_ctrl_reg__16BIT_MASK_MASK_REG, CYREG_B0_UDB06_07_MSK
|
||||
.set SD_Clk_Ctl_Sync_ctrl_reg__16BIT_MASK_PERIOD_REG, CYREG_B0_UDB06_07_MSK
|
||||
.set SD_Clk_Ctl_Sync_ctrl_reg__16BIT_PERIOD_MASK_REG, CYREG_B0_UDB06_07_MSK
|
||||
.set SD_Clk_Ctl_Sync_ctrl_reg__16BIT_PERIOD_PERIOD_REG, CYREG_B0_UDB06_07_MSK
|
||||
.set SD_Clk_Ctl_Sync_ctrl_reg__CONTROL_AUX_CTL_REG, CYREG_B0_UDB06_ACTL
|
||||
.set SD_Clk_Ctl_Sync_ctrl_reg__CONTROL_REG, CYREG_B0_UDB06_CTL
|
||||
.set SD_Clk_Ctl_Sync_ctrl_reg__CONTROL_ST_REG, CYREG_B0_UDB06_ST_CTL
|
||||
.set SD_Clk_Ctl_Sync_ctrl_reg__COUNT_REG, CYREG_B0_UDB06_CTL
|
||||
.set SD_Clk_Ctl_Sync_ctrl_reg__COUNT_ST_REG, CYREG_B0_UDB06_ST_CTL
|
||||
.set SD_Clk_Ctl_Sync_ctrl_reg__MASK, 0x01
|
||||
.set SD_Clk_Ctl_Sync_ctrl_reg__MASK_CTL_AUX_CTL_REG, CYREG_B1_UDB05_MSK_ACTL
|
||||
.set SD_Clk_Ctl_Sync_ctrl_reg__PERIOD_REG, CYREG_B1_UDB05_MSK
|
||||
.set SD_Clk_Ctl_Sync_ctrl_reg__PER_CTL_AUX_CTL_REG, CYREG_B1_UDB05_MSK_ACTL
|
||||
.set SD_Clk_Ctl_Sync_ctrl_reg__MASK_CTL_AUX_CTL_REG, CYREG_B0_UDB06_MSK_ACTL
|
||||
.set SD_Clk_Ctl_Sync_ctrl_reg__PERIOD_REG, CYREG_B0_UDB06_MSK
|
||||
.set SD_Clk_Ctl_Sync_ctrl_reg__PER_CTL_AUX_CTL_REG, CYREG_B0_UDB06_MSK_ACTL
|
||||
|
||||
/* PARITY_EN */
|
||||
.set PARITY_EN__0__MASK, 0x10
|
||||
@ -1775,9 +1775,9 @@
|
||||
.set CYDEV_CHIP_FAMILY_PSOC5, 3
|
||||
.set CYDEV_CHIP_DIE_PSOC5LP, 4
|
||||
.set CYDEV_CHIP_DIE_EXPECT, CYDEV_CHIP_DIE_PSOC5LP
|
||||
.set BCLK__BUS_CLK__HZ, 64000000
|
||||
.set BCLK__BUS_CLK__KHZ, 64000
|
||||
.set BCLK__BUS_CLK__MHZ, 64
|
||||
.set BCLK__BUS_CLK__HZ, 63000000
|
||||
.set BCLK__BUS_CLK__KHZ, 63000
|
||||
.set BCLK__BUS_CLK__MHZ, 63
|
||||
.set CYDEV_CHIP_DIE_ACTUAL, CYDEV_CHIP_DIE_EXPECT
|
||||
.set CYDEV_CHIP_DIE_LEOPARD, 1
|
||||
.set CYDEV_CHIP_DIE_PANTHER, 3
|
||||
|
@ -307,24 +307,24 @@ SD_Init_Clk__PM_STBY_MSK EQU 0x02
|
||||
; SD_Clk_Ctl
|
||||
SD_Clk_Ctl_Sync_ctrl_reg__0__MASK EQU 0x01
|
||||
SD_Clk_Ctl_Sync_ctrl_reg__0__POS EQU 0
|
||||
SD_Clk_Ctl_Sync_ctrl_reg__16BIT_CONTROL_AUX_CTL_REG EQU CYREG_B1_UDB05_06_ACTL
|
||||
SD_Clk_Ctl_Sync_ctrl_reg__16BIT_CONTROL_CONTROL_REG EQU CYREG_B1_UDB05_06_CTL
|
||||
SD_Clk_Ctl_Sync_ctrl_reg__16BIT_CONTROL_COUNT_REG EQU CYREG_B1_UDB05_06_CTL
|
||||
SD_Clk_Ctl_Sync_ctrl_reg__16BIT_COUNT_CONTROL_REG EQU CYREG_B1_UDB05_06_CTL
|
||||
SD_Clk_Ctl_Sync_ctrl_reg__16BIT_COUNT_COUNT_REG EQU CYREG_B1_UDB05_06_CTL
|
||||
SD_Clk_Ctl_Sync_ctrl_reg__16BIT_MASK_MASK_REG EQU CYREG_B1_UDB05_06_MSK
|
||||
SD_Clk_Ctl_Sync_ctrl_reg__16BIT_MASK_PERIOD_REG EQU CYREG_B1_UDB05_06_MSK
|
||||
SD_Clk_Ctl_Sync_ctrl_reg__16BIT_PERIOD_MASK_REG EQU CYREG_B1_UDB05_06_MSK
|
||||
SD_Clk_Ctl_Sync_ctrl_reg__16BIT_PERIOD_PERIOD_REG EQU CYREG_B1_UDB05_06_MSK
|
||||
SD_Clk_Ctl_Sync_ctrl_reg__CONTROL_AUX_CTL_REG EQU CYREG_B1_UDB05_ACTL
|
||||
SD_Clk_Ctl_Sync_ctrl_reg__CONTROL_REG EQU CYREG_B1_UDB05_CTL
|
||||
SD_Clk_Ctl_Sync_ctrl_reg__CONTROL_ST_REG EQU CYREG_B1_UDB05_ST_CTL
|
||||
SD_Clk_Ctl_Sync_ctrl_reg__COUNT_REG EQU CYREG_B1_UDB05_CTL
|
||||
SD_Clk_Ctl_Sync_ctrl_reg__COUNT_ST_REG EQU CYREG_B1_UDB05_ST_CTL
|
||||
SD_Clk_Ctl_Sync_ctrl_reg__16BIT_CONTROL_AUX_CTL_REG EQU CYREG_B0_UDB06_07_ACTL
|
||||
SD_Clk_Ctl_Sync_ctrl_reg__16BIT_CONTROL_CONTROL_REG EQU CYREG_B0_UDB06_07_CTL
|
||||
SD_Clk_Ctl_Sync_ctrl_reg__16BIT_CONTROL_COUNT_REG EQU CYREG_B0_UDB06_07_CTL
|
||||
SD_Clk_Ctl_Sync_ctrl_reg__16BIT_COUNT_CONTROL_REG EQU CYREG_B0_UDB06_07_CTL
|
||||
SD_Clk_Ctl_Sync_ctrl_reg__16BIT_COUNT_COUNT_REG EQU CYREG_B0_UDB06_07_CTL
|
||||
SD_Clk_Ctl_Sync_ctrl_reg__16BIT_MASK_MASK_REG EQU CYREG_B0_UDB06_07_MSK
|
||||
SD_Clk_Ctl_Sync_ctrl_reg__16BIT_MASK_PERIOD_REG EQU CYREG_B0_UDB06_07_MSK
|
||||
SD_Clk_Ctl_Sync_ctrl_reg__16BIT_PERIOD_MASK_REG EQU CYREG_B0_UDB06_07_MSK
|
||||
SD_Clk_Ctl_Sync_ctrl_reg__16BIT_PERIOD_PERIOD_REG EQU CYREG_B0_UDB06_07_MSK
|
||||
SD_Clk_Ctl_Sync_ctrl_reg__CONTROL_AUX_CTL_REG EQU CYREG_B0_UDB06_ACTL
|
||||
SD_Clk_Ctl_Sync_ctrl_reg__CONTROL_REG EQU CYREG_B0_UDB06_CTL
|
||||
SD_Clk_Ctl_Sync_ctrl_reg__CONTROL_ST_REG EQU CYREG_B0_UDB06_ST_CTL
|
||||
SD_Clk_Ctl_Sync_ctrl_reg__COUNT_REG EQU CYREG_B0_UDB06_CTL
|
||||
SD_Clk_Ctl_Sync_ctrl_reg__COUNT_ST_REG EQU CYREG_B0_UDB06_ST_CTL
|
||||
SD_Clk_Ctl_Sync_ctrl_reg__MASK EQU 0x01
|
||||
SD_Clk_Ctl_Sync_ctrl_reg__MASK_CTL_AUX_CTL_REG EQU CYREG_B1_UDB05_MSK_ACTL
|
||||
SD_Clk_Ctl_Sync_ctrl_reg__PERIOD_REG EQU CYREG_B1_UDB05_MSK
|
||||
SD_Clk_Ctl_Sync_ctrl_reg__PER_CTL_AUX_CTL_REG EQU CYREG_B1_UDB05_MSK_ACTL
|
||||
SD_Clk_Ctl_Sync_ctrl_reg__MASK_CTL_AUX_CTL_REG EQU CYREG_B0_UDB06_MSK_ACTL
|
||||
SD_Clk_Ctl_Sync_ctrl_reg__PERIOD_REG EQU CYREG_B0_UDB06_MSK
|
||||
SD_Clk_Ctl_Sync_ctrl_reg__PER_CTL_AUX_CTL_REG EQU CYREG_B0_UDB06_MSK_ACTL
|
||||
|
||||
; PARITY_EN
|
||||
PARITY_EN__0__MASK EQU 0x10
|
||||
@ -1775,9 +1775,9 @@ CYDEV_CHIP_MEMBER_5B EQU 4
|
||||
CYDEV_CHIP_FAMILY_PSOC5 EQU 3
|
||||
CYDEV_CHIP_DIE_PSOC5LP EQU 4
|
||||
CYDEV_CHIP_DIE_EXPECT EQU CYDEV_CHIP_DIE_PSOC5LP
|
||||
BCLK__BUS_CLK__HZ EQU 64000000
|
||||
BCLK__BUS_CLK__KHZ EQU 64000
|
||||
BCLK__BUS_CLK__MHZ EQU 64
|
||||
BCLK__BUS_CLK__HZ EQU 63000000
|
||||
BCLK__BUS_CLK__KHZ EQU 63000
|
||||
BCLK__BUS_CLK__MHZ EQU 63
|
||||
CYDEV_CHIP_DIE_ACTUAL EQU CYDEV_CHIP_DIE_EXPECT
|
||||
CYDEV_CHIP_DIE_LEOPARD EQU 1
|
||||
CYDEV_CHIP_DIE_PANTHER EQU 3
|
||||
|
@ -7,7 +7,7 @@
|
||||
<block name="SCSI_ID" BASE="0x0" SIZE="0x0" desc="" visible="true" />
|
||||
<block name="SD_Clk_mux" BASE="0x0" SIZE="0x0" desc="" visible="true" />
|
||||
<block name="SD_Clk_Ctl" BASE="0x0" SIZE="0x0" desc="" visible="true">
|
||||
<register name="SD_Clk_Ctl_CONTROL_REG" address="0x40006575" bitWidth="8" desc="" />
|
||||
<register name="SD_Clk_Ctl_CONTROL_REG" address="0x40006476" bitWidth="8" desc="" />
|
||||
</block>
|
||||
<block name="SD_Data_Clk" BASE="0x0" SIZE="0x0" desc="" visible="true" />
|
||||
<block name="LED1" BASE="0x0" SIZE="0x0" desc="" visible="true" />
|
||||
|
Binary file not shown.
Binary file not shown.
@ -95,6 +95,13 @@
|
||||
<build_action v="C_FILE" />
|
||||
<PropertyDeltas />
|
||||
</CyGuid_8b8ab257-35d3-4473-b57b-36315200b38b>
|
||||
<CyGuid_8b8ab257-35d3-4473-b57b-36315200b38b type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtFile" version="3" xml_contents_version="1">
|
||||
<CyGuid_31768f72-0253-412b-af77-e7dba74d1330 type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtItem" version="2" name="sd.c" persistent="\\xengarden\michael\projects\SCSI2SD\git\software\SCSI2SD\SCSI2SD.cydsn\sd.c">
|
||||
<Hidden v="False" />
|
||||
</CyGuid_31768f72-0253-412b-af77-e7dba74d1330>
|
||||
<build_action v="C_FILE" />
|
||||
<PropertyDeltas />
|
||||
</CyGuid_8b8ab257-35d3-4473-b57b-36315200b38b>
|
||||
</dependencies>
|
||||
</CyGuid_0820c2e7-528d-4137-9a08-97257b946089>
|
||||
</CyGuid_2f73275c-45bf-46ba-b3b1-00a2fe0c8dd8>
|
||||
@ -203,6 +210,13 @@
|
||||
<build_action v="NONE" />
|
||||
<PropertyDeltas />
|
||||
</CyGuid_8b8ab257-35d3-4473-b57b-36315200b38b>
|
||||
<CyGuid_8b8ab257-35d3-4473-b57b-36315200b38b type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtFile" version="3" xml_contents_version="1">
|
||||
<CyGuid_31768f72-0253-412b-af77-e7dba74d1330 type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtItem" version="2" name="sd.h" persistent="\\xengarden\michael\projects\SCSI2SD\git\software\SCSI2SD\SCSI2SD.cydsn\sd.h">
|
||||
<Hidden v="False" />
|
||||
</CyGuid_31768f72-0253-412b-af77-e7dba74d1330>
|
||||
<build_action v="NONE" />
|
||||
<PropertyDeltas />
|
||||
</CyGuid_8b8ab257-35d3-4473-b57b-36315200b38b>
|
||||
</dependencies>
|
||||
</CyGuid_0820c2e7-528d-4137-9a08-97257b946089>
|
||||
</CyGuid_2f73275c-45bf-46ba-b3b1-00a2fe0c8dd8>
|
||||
|
@ -9,7 +9,7 @@
|
||||
<peripheral>
|
||||
<name>SD_Clk_Ctl</name>
|
||||
<description>No description available</description>
|
||||
<baseAddress>0x40006575</baseAddress>
|
||||
<baseAddress>0x40006476</baseAddress>
|
||||
<addressBlock>
|
||||
<offset>0</offset>
|
||||
<size>0x1</size>
|
||||
|
Binary file not shown.
@ -18,6 +18,7 @@
|
||||
#include "device.h"
|
||||
#include "scsi.h"
|
||||
#include "disk.h"
|
||||
#include "sd.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
@ -25,8 +26,19 @@
|
||||
BlockDevice blockDev;
|
||||
Transfer transfer;
|
||||
|
||||
static void startRead(int nextBlock);
|
||||
static int sdInit();
|
||||
static int doSdInit()
|
||||
{
|
||||
int result = sdInit();
|
||||
if (result)
|
||||
{
|
||||
blockDev.state = blockDev.state | DISK_INITIALISED;
|
||||
|
||||
// TODO artificially limit this value according to EEPROM config.
|
||||
blockDev.capacity = sdDev.capacity;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static void doFormatUnit()
|
||||
{
|
||||
@ -85,7 +97,7 @@ static void doWrite(uint32 lba, uint32 blocks)
|
||||
scsiDev.status = CHECK_CONDITION;
|
||||
scsiDev.sense.code = ILLEGAL_REQUEST;
|
||||
scsiDev.sense.asc = WRITE_PROTECTED;
|
||||
scsiDev.phase = STATUS;
|
||||
scsiDev.phase = STATUS;
|
||||
}
|
||||
else if (((uint64) lba) + blocks > blockDev.capacity)
|
||||
{
|
||||
@ -102,6 +114,8 @@ static void doWrite(uint32 lba, uint32 blocks)
|
||||
transfer.currentBlock = 0;
|
||||
scsiDev.phase = DATA_OUT;
|
||||
scsiDev.dataLen = SCSI_BLOCK_SIZE;
|
||||
|
||||
sdPrepareWrite();
|
||||
}
|
||||
}
|
||||
|
||||
@ -123,7 +137,7 @@ static void doRead(uint32 lba, uint32 blocks)
|
||||
transfer.currentBlock = 0;
|
||||
scsiDev.phase = DATA_IN;
|
||||
scsiDev.dataLen = 0; // No data yet
|
||||
startRead(0);
|
||||
sdPrepareRead(0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -187,15 +201,12 @@ int scsiDiskCommand()
|
||||
blockDev.state = blockDev.state | DISK_STARTED;
|
||||
if (!(blockDev.state & DISK_INITIALISED))
|
||||
{
|
||||
if (sdInit())
|
||||
{
|
||||
blockDev.state = blockDev.state | DISK_INITIALISED;
|
||||
}
|
||||
doSdInit();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
blockDev.state = blockDev.state & (-1 ^ DISK_STARTED);
|
||||
blockDev.state &= ~DISK_STARTED;
|
||||
}
|
||||
}
|
||||
else if (command == 0x00)
|
||||
@ -331,285 +342,6 @@ int scsiDiskCommand()
|
||||
return commandHandled;
|
||||
}
|
||||
|
||||
|
||||
static uint8 sdCrc7(uint8* chr, uint8 cnt, uint8 crc)
|
||||
{
|
||||
uint8 a;
|
||||
for(a = 0; a < cnt; a++)
|
||||
{
|
||||
uint8 Data = chr[a];
|
||||
uint8 i;
|
||||
for(i = 0; i < 8; i++)
|
||||
{
|
||||
crc <<= 1;
|
||||
if( (Data & 0x80) ^ (crc & 0x80) ) {crc ^= 0x09;}
|
||||
Data <<= 1;
|
||||
}
|
||||
}
|
||||
return crc & 0x7F;
|
||||
}
|
||||
|
||||
// Read and write 1 byte.
|
||||
static uint8 sdSpiByte(uint8 value)
|
||||
{
|
||||
SDCard_WriteTxData(value);
|
||||
while(!(SDCard_ReadTxStatus() & SDCard_STS_SPI_DONE))
|
||||
{}
|
||||
while (!SDCard_GetRxBufferSize()) {}
|
||||
return SDCard_ReadRxData();
|
||||
}
|
||||
|
||||
static void sdSendCommand(uint8 cmd, uint32 param)
|
||||
{
|
||||
uint8 send[6];
|
||||
|
||||
send[0] = cmd | 0x40;
|
||||
send[1] = param >> 24;
|
||||
send[2] = param >> 16;
|
||||
send[3] = param >> 8;
|
||||
send[4] = param;
|
||||
send[5] = (sdCrc7(send, 5, 0) << 1) | 1;
|
||||
|
||||
for(cmd = 0; cmd < sizeof(send); cmd++)
|
||||
{
|
||||
sdSpiByte(send[cmd]);
|
||||
}
|
||||
}
|
||||
|
||||
static uint8 sdReadResp()
|
||||
{
|
||||
uint8 v;
|
||||
uint8 i = 128;
|
||||
do
|
||||
{
|
||||
v = sdSpiByte(0xFF);
|
||||
} while(i-- && (v == 0xFF));
|
||||
return v;
|
||||
}
|
||||
|
||||
static uint8 sdWaitResp()
|
||||
{
|
||||
uint8 v;
|
||||
uint8 i = 255;
|
||||
do
|
||||
{
|
||||
v = sdSpiByte(0xFF);
|
||||
} while(i-- && (v != 0xFE));
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
static uint8 sdCommandAndResponse(uint8 cmd, uint32 param)
|
||||
{
|
||||
SDCard_ClearRxBuffer();
|
||||
sdSpiByte(0xFF);
|
||||
sdSendCommand(cmd, param);
|
||||
return sdReadResp();
|
||||
}
|
||||
|
||||
|
||||
static int sdInit()
|
||||
{
|
||||
int result = 0;
|
||||
SD_CS_Write(1); // Set CS inactive (active low)
|
||||
SD_Init_Clk_Start(); // Turn on the slow 400KHz clock
|
||||
SD_Clk_Ctl_Write(0); // Select the 400KHz clock source.
|
||||
SDCard_Start(); // Enable SPI hardware
|
||||
|
||||
// Power on sequence. 74 clock cycles of a "1" while CS unasserted.
|
||||
int i;
|
||||
for (i = 0; i < 10; ++i)
|
||||
{
|
||||
sdSpiByte(0xFF);
|
||||
}
|
||||
|
||||
SD_CS_Write(0); // Set CS active (active low)
|
||||
CyDelayUs(1);
|
||||
|
||||
uint8 v = sdCommandAndResponse(0, 0);
|
||||
if(v != 1){goto bad;}
|
||||
|
||||
// TODO CMD8 + valid CC for ver2 + cards. arg 0x00..01AA
|
||||
|
||||
|
||||
// TODO SDv2 support: ACMD41, fallback to CMD1
|
||||
|
||||
v = sdCommandAndResponse(1, 0);
|
||||
for(i=0;v != 0 && i<50;++i){
|
||||
CyDelay(50);
|
||||
v = sdCommandAndResponse(1, 0);
|
||||
}
|
||||
if(v){goto bad;}
|
||||
|
||||
v = sdCommandAndResponse(16, SCSI_BLOCK_SIZE); //Force sector size
|
||||
if(v){goto bad;}
|
||||
v = sdCommandAndResponse(59, 0); //crc off
|
||||
if(v){goto bad;}
|
||||
|
||||
// now set the sd card up for full speed
|
||||
SD_Data_Clk_Start(); // Turn on the fast clock
|
||||
SD_Clk_Ctl_Write(1); // Select the fast clock source.
|
||||
SD_Init_Clk_Stop(); // Stop the slow clock.
|
||||
|
||||
v = sdCommandAndResponse(0x9, 0);
|
||||
if(v){goto bad;}
|
||||
v = sdWaitResp();
|
||||
if (v != 0xFE) { goto bad; }
|
||||
uint8 buf[16];
|
||||
for (i = 0; i < 16; ++i)
|
||||
{
|
||||
buf[i] = sdSpiByte(0xFF);
|
||||
}
|
||||
sdSpiByte(0xFF); // CRC
|
||||
sdSpiByte(0xFF); // CRC
|
||||
uint32 c_size = (((((uint32)buf[6]) & 0x3) << 16) | (((uint32)buf[7]) << 8) | buf[8]) >> 6;
|
||||
uint32 c_mult = (((((uint32)buf[9]) & 0x3) << 8) | ((uint32)buf[0xa])) >> 7;
|
||||
uint32 sectorSize = buf[5] & 0x0F;
|
||||
blockDev.capacity = ((c_size+1) * ((uint64)1 << (c_mult+2)) * ((uint64)1 << sectorSize)) / SCSI_BLOCK_SIZE;
|
||||
result = 1;
|
||||
goto out;
|
||||
|
||||
bad:
|
||||
blockDev.capacity = 0;
|
||||
|
||||
out:
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
static void startRead(int nextBlock)
|
||||
{
|
||||
// TODO 4Gb limit
|
||||
// NOTE: CMD17 is NOT in hex. decimal 17.
|
||||
uint8 v = sdCommandAndResponse(17, ((uint32)SCSI_BLOCK_SIZE) * (transfer.lba + transfer.currentBlock + nextBlock));
|
||||
if (v)
|
||||
{
|
||||
scsiDiskReset();
|
||||
|
||||
scsiDev.status = CHECK_CONDITION;
|
||||
scsiDev.sense.code = HARDWARE_ERROR;
|
||||
scsiDev.sense.asc = LOGICAL_UNIT_COMMUNICATION_FAILURE;
|
||||
scsiDev.phase = STATUS;
|
||||
}
|
||||
}
|
||||
|
||||
static int readReady()
|
||||
{
|
||||
uint8 v = sdWaitResp();
|
||||
if (v == 0xFF)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else if (v == 0xFE)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
scsiDiskReset();
|
||||
scsiDev.status = CHECK_CONDITION;
|
||||
scsiDev.sense.code = HARDWARE_ERROR;
|
||||
scsiDev.sense.asc = LOGICAL_UNIT_COMMUNICATION_FAILURE;
|
||||
scsiDev.phase = STATUS;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
static void readSector()
|
||||
{
|
||||
// TODO this is slow. Really slow.
|
||||
// Even if we don't use DMA, we still want to read/write multiple bytes
|
||||
// at a time.
|
||||
/*
|
||||
int i;
|
||||
for (i = 0; i < SCSI_BLOCK_SIZE; ++i)
|
||||
{
|
||||
scsiDev.data[i] = sdSpiByte(0xFF);
|
||||
}
|
||||
*/
|
||||
|
||||
// We have a spi FIFO of 4 bytes. use it.
|
||||
// This is much better, byut after 4 bytes we're still
|
||||
// blocking a bit.
|
||||
int i;
|
||||
for (i = 0; i < SCSI_BLOCK_SIZE; i+=4)
|
||||
{
|
||||
SDCard_WriteTxData(0xFF);
|
||||
SDCard_WriteTxData(0xFF);
|
||||
SDCard_WriteTxData(0xFF);
|
||||
SDCard_WriteTxData(0xFF);
|
||||
|
||||
while(!(SDCard_ReadTxStatus() & SDCard_STS_SPI_DONE))
|
||||
{}
|
||||
scsiDev.data[i] = SDCard_ReadRxData();
|
||||
scsiDev.data[i+1] = SDCard_ReadRxData();
|
||||
scsiDev.data[i+2] = SDCard_ReadRxData();
|
||||
scsiDev.data[i+3] = SDCard_ReadRxData();
|
||||
|
||||
}
|
||||
|
||||
|
||||
sdSpiByte(0xFF); // CRC
|
||||
sdSpiByte(0xFF); // CRC
|
||||
scsiDev.dataLen = SCSI_BLOCK_SIZE;
|
||||
scsiDev.dataPtr = 0;
|
||||
}
|
||||
|
||||
static void writeSector()
|
||||
{
|
||||
uint8 v = sdCommandAndResponse(24, ((uint32)SCSI_BLOCK_SIZE) * (transfer.lba + transfer.currentBlock));
|
||||
if (v)
|
||||
{
|
||||
scsiDiskReset();
|
||||
|
||||
scsiDev.status = CHECK_CONDITION;
|
||||
scsiDev.sense.code = HARDWARE_ERROR;
|
||||
scsiDev.sense.asc = LOGICAL_UNIT_COMMUNICATION_FAILURE;
|
||||
scsiDev.phase = STATUS;
|
||||
}
|
||||
else
|
||||
{
|
||||
SDCard_WriteTxData(0xFE);
|
||||
int i;
|
||||
for (i = 0; i < SCSI_BLOCK_SIZE; ++i)
|
||||
{
|
||||
SDCard_WriteTxData(scsiDev.data[i]);
|
||||
}
|
||||
while(!(SDCard_ReadTxStatus() & SDCard_STS_SPI_DONE))
|
||||
{}
|
||||
sdSpiByte(0x00); // CRC
|
||||
sdSpiByte(0x00); // CRC
|
||||
SDCard_ClearRxBuffer();
|
||||
v = sdSpiByte(0x00); // Response
|
||||
if (((v & 0x1F) >> 1) != 0x2) // Accepted.
|
||||
{
|
||||
scsiDiskReset();
|
||||
|
||||
scsiDev.status = CHECK_CONDITION;
|
||||
scsiDev.sense.code = HARDWARE_ERROR;
|
||||
scsiDev.sense.asc = LOGICAL_UNIT_COMMUNICATION_FAILURE;
|
||||
scsiDev.phase = STATUS;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Wait for the card to come out of busy.
|
||||
v = sdSpiByte(0xFF);
|
||||
while (v == 0)
|
||||
{
|
||||
v = sdSpiByte(0xFF);
|
||||
}
|
||||
uint8 r1 = sdCommandAndResponse(13, 0); // send status
|
||||
uint8 r2 = sdSpiByte(0xFF);
|
||||
if (r1 || r2)
|
||||
{
|
||||
scsiDev.status = CHECK_CONDITION;
|
||||
scsiDev.sense.code = HARDWARE_ERROR;
|
||||
scsiDev.sense.asc = WRITE_ERROR_AUTO_REALLOCATION_FAILED;
|
||||
scsiDev.phase = STATUS;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void scsiDiskPoll()
|
||||
{
|
||||
if (scsiDev.phase == DATA_IN &&
|
||||
@ -617,12 +349,12 @@ void scsiDiskPoll()
|
||||
{
|
||||
if (scsiDev.dataLen == 0)
|
||||
{
|
||||
if (readReady())
|
||||
if (sdIsReadReady())
|
||||
{
|
||||
readSector();
|
||||
sdReadSector();
|
||||
if ((transfer.currentBlock + 1) < transfer.blocks)
|
||||
{
|
||||
startRead(1); // Tell SD card to grab data while we send
|
||||
sdPrepareRead(1); // Tell SD card to grab data while we send
|
||||
// buffer to SCSI.
|
||||
}
|
||||
}
|
||||
@ -644,17 +376,23 @@ void scsiDiskPoll()
|
||||
{
|
||||
if (scsiDev.dataPtr == SCSI_BLOCK_SIZE)
|
||||
{
|
||||
writeSector();
|
||||
int writeOk = sdWriteSector();
|
||||
scsiDev.dataPtr = 0;
|
||||
transfer.currentBlock++;
|
||||
if (transfer.currentBlock >= transfer.blocks)
|
||||
|
||||
{
|
||||
scsiDev.dataLen = 0;
|
||||
scsiDev.phase = STATUS;
|
||||
scsiDiskReset();
|
||||
|
||||
if (writeOk)
|
||||
{
|
||||
sdCompleteWrite();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void scsiDiskReset()
|
||||
@ -685,12 +423,18 @@ void scsiDiskInit()
|
||||
{
|
||||
blockDev.state = blockDev.state | DISK_PRESENT;
|
||||
|
||||
// todo IF FAILS, TRY AGAIN LATER.
|
||||
// 5000 works well with the Mac.
|
||||
CyDelay(5000); // allow the card to wake up.
|
||||
if (sdInit())
|
||||
// Wait up to 5 seconds for the SD card to wake up.
|
||||
int retry;
|
||||
for (retry = 0; retry < 5; ++retry)
|
||||
{
|
||||
blockDev.state = blockDev.state | DISK_INITIALISED;
|
||||
if (doSdInit())
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
CyDelay(1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ static const uint8 DisconnectReconnectPage[] =
|
||||
|
||||
static const uint8 FormatDevicePage[] =
|
||||
{
|
||||
x03, // Page code
|
||||
0x03, // Page code
|
||||
0x16, // Page length
|
||||
0x00, 0x00, // Single zone
|
||||
0x00, 0x00, // No alternate sectors
|
||||
|
451
software/SCSI2SD/SCSI2SD.cydsn/sd.c
Executable file
451
software/SCSI2SD/SCSI2SD.cydsn/sd.c
Executable file
@ -0,0 +1,451 @@
|
||||
// Copyright (C) 2013 Michael McMaster <michael@codesrc.com>
|
||||
//
|
||||
// This file is part of SCSI2SD.
|
||||
//
|
||||
// SCSI2SD is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// SCSI2SD is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with SCSI2SD. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include "device.h"
|
||||
#include "scsi.h"
|
||||
#include "disk.h"
|
||||
#include "sd.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
// Global
|
||||
SdDevice sdDev;
|
||||
|
||||
static uint8 sdCrc7(uint8* chr, uint8 cnt, uint8 crc)
|
||||
{
|
||||
uint8 a;
|
||||
for(a = 0; a < cnt; a++)
|
||||
{
|
||||
uint8 Data = chr[a];
|
||||
uint8 i;
|
||||
for(i = 0; i < 8; i++)
|
||||
{
|
||||
crc <<= 1;
|
||||
if( (Data & 0x80) ^ (crc & 0x80) ) {crc ^= 0x09;}
|
||||
Data <<= 1;
|
||||
}
|
||||
}
|
||||
return crc & 0x7F;
|
||||
}
|
||||
|
||||
// Read and write 1 byte.
|
||||
static uint8 sdSpiByte(uint8 value)
|
||||
{
|
||||
SDCard_WriteTxData(value);
|
||||
while(!(SDCard_ReadTxStatus() & SDCard_STS_SPI_DONE))
|
||||
{}
|
||||
while (!SDCard_GetRxBufferSize()) {}
|
||||
return SDCard_ReadRxData();
|
||||
}
|
||||
|
||||
static void sdSendCommand(uint8 cmd, uint32 param)
|
||||
{
|
||||
uint8 send[6];
|
||||
|
||||
send[0] = cmd | 0x40;
|
||||
send[1] = param >> 24;
|
||||
send[2] = param >> 16;
|
||||
send[3] = param >> 8;
|
||||
send[4] = param;
|
||||
send[5] = (sdCrc7(send, 5, 0) << 1) | 1;
|
||||
|
||||
for(cmd = 0; cmd < sizeof(send); cmd++)
|
||||
{
|
||||
sdSpiByte(send[cmd]);
|
||||
}
|
||||
}
|
||||
|
||||
static uint8 sdReadResp()
|
||||
{
|
||||
uint8 v;
|
||||
uint8 i = 128;
|
||||
do
|
||||
{
|
||||
v = sdSpiByte(0xFF);
|
||||
} while(i-- && (v == 0xFF));
|
||||
return v;
|
||||
}
|
||||
|
||||
static uint8 sdWaitResp()
|
||||
{
|
||||
uint8 v;
|
||||
uint8 i = 255;
|
||||
do
|
||||
{
|
||||
v = sdSpiByte(0xFF);
|
||||
} while(i-- && (v != 0xFE));
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
static uint8 sdCommandAndResponse(uint8 cmd, uint32 param)
|
||||
{
|
||||
SDCard_ClearRxBuffer();
|
||||
sdSpiByte(0xFF);
|
||||
sdSendCommand(cmd, param);
|
||||
return sdReadResp();
|
||||
}
|
||||
|
||||
|
||||
void sdPrepareRead(int nextBlockOffset)
|
||||
{
|
||||
uint32 len = (transfer.lba + transfer.currentBlock + nextBlockOffset);
|
||||
if (!sdDev.ccs)
|
||||
{
|
||||
len = len * SCSI_BLOCK_SIZE;
|
||||
}
|
||||
uint8 v = sdCommandAndResponse(17, len);
|
||||
if (v)
|
||||
{
|
||||
scsiDiskReset();
|
||||
|
||||
scsiDev.status = CHECK_CONDITION;
|
||||
scsiDev.sense.code = HARDWARE_ERROR;
|
||||
scsiDev.sense.asc = LOGICAL_UNIT_COMMUNICATION_FAILURE;
|
||||
scsiDev.phase = STATUS;
|
||||
}
|
||||
}
|
||||
|
||||
int sdIsReadReady()
|
||||
{
|
||||
uint8 v = sdWaitResp();
|
||||
if (v == 0xFF)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else if (v == 0xFE)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
scsiDiskReset();
|
||||
scsiDev.status = CHECK_CONDITION;
|
||||
scsiDev.sense.code = HARDWARE_ERROR;
|
||||
scsiDev.sense.asc = LOGICAL_UNIT_COMMUNICATION_FAILURE;
|
||||
scsiDev.phase = STATUS;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void sdReadSector()
|
||||
{
|
||||
// We have a spi FIFO of 4 bytes. use it.
|
||||
// This is much better, byut after 4 bytes we're still
|
||||
// blocking a bit.
|
||||
int i;
|
||||
for (i = 0; i < SCSI_BLOCK_SIZE; i+=4)
|
||||
{
|
||||
SDCard_WriteTxData(0xFF);
|
||||
SDCard_WriteTxData(0xFF);
|
||||
SDCard_WriteTxData(0xFF);
|
||||
SDCard_WriteTxData(0xFF);
|
||||
|
||||
while(!(SDCard_ReadTxStatus() & SDCard_STS_SPI_DONE))
|
||||
{}
|
||||
scsiDev.data[i] = SDCard_ReadRxData();
|
||||
scsiDev.data[i+1] = SDCard_ReadRxData();
|
||||
scsiDev.data[i+2] = SDCard_ReadRxData();
|
||||
scsiDev.data[i+3] = SDCard_ReadRxData();
|
||||
|
||||
}
|
||||
|
||||
|
||||
sdSpiByte(0xFF); // CRC
|
||||
sdSpiByte(0xFF); // CRC
|
||||
scsiDev.dataLen = SCSI_BLOCK_SIZE;
|
||||
scsiDev.dataPtr = 0;
|
||||
}
|
||||
|
||||
static void sdWaitWriteBusy()
|
||||
{
|
||||
uint8 val;
|
||||
do
|
||||
{
|
||||
val = sdSpiByte(0xFF);
|
||||
} while (val != 0xFF);
|
||||
}
|
||||
|
||||
int sdWriteSector()
|
||||
{
|
||||
int result;
|
||||
// Wait for a previously-written sector to complete.
|
||||
sdWaitWriteBusy();
|
||||
|
||||
sdSpiByte(0xFC); // MULTIPLE byte start token
|
||||
int i;
|
||||
for (i = 0; i < SCSI_BLOCK_SIZE; i+=4)
|
||||
{
|
||||
SDCard_WriteTxData(scsiDev.data[i]);
|
||||
SDCard_WriteTxData(scsiDev.data[i+1]);
|
||||
SDCard_WriteTxData(scsiDev.data[i+2]);
|
||||
SDCard_WriteTxData(scsiDev.data[i+3]);
|
||||
|
||||
while(!(SDCard_ReadTxStatus() & SDCard_STS_SPI_DONE))
|
||||
{}
|
||||
|
||||
SDCard_ReadRxData();
|
||||
SDCard_ReadRxData();
|
||||
SDCard_ReadRxData();
|
||||
SDCard_ReadRxData();
|
||||
}
|
||||
|
||||
sdSpiByte(0x00); // CRC
|
||||
sdSpiByte(0x00); // CRC
|
||||
uint8 dataToken = sdSpiByte(0xFF); // Response
|
||||
if (((dataToken & 0x1F) >> 1) != 0x2) // Accepted.
|
||||
{
|
||||
sdWaitWriteBusy();
|
||||
sdSpiByte(0xFD); // STOP TOKEN
|
||||
// Wait for the card to come out of busy.
|
||||
sdWaitWriteBusy();
|
||||
|
||||
scsiDiskReset();
|
||||
|
||||
scsiDev.status = CHECK_CONDITION;
|
||||
scsiDev.sense.code = HARDWARE_ERROR;
|
||||
scsiDev.sense.asc = LOGICAL_UNIT_COMMUNICATION_FAILURE;
|
||||
scsiDev.phase = STATUS;
|
||||
result = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// The card is probably in the busy state.
|
||||
// Don't wait, as we could read the SCSI interface instead.
|
||||
result = 1;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void sdCompleteWrite()
|
||||
{
|
||||
// Wait for a previously-written sector to complete.
|
||||
sdWaitWriteBusy();
|
||||
|
||||
sdSpiByte(0xFD); // STOP TOKEN
|
||||
// Wait for the card to come out of busy.
|
||||
sdWaitWriteBusy();
|
||||
|
||||
uint8 r1 = sdCommandAndResponse(13, 0); // send status
|
||||
uint8 r2 = sdSpiByte(0xFF);
|
||||
if (r1 || r2)
|
||||
{
|
||||
scsiDev.status = CHECK_CONDITION;
|
||||
scsiDev.sense.code = HARDWARE_ERROR;
|
||||
scsiDev.sense.asc = WRITE_ERROR_AUTO_REALLOCATION_FAILED;
|
||||
scsiDev.phase = STATUS;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// SD Version 2 (SDHC) support
|
||||
static int sendIfCond()
|
||||
{
|
||||
int retries = 50;
|
||||
|
||||
do
|
||||
{
|
||||
uint8 status = sdCommandAndResponse(SD_SEND_IF_COND, 0x000001AA);
|
||||
|
||||
if (status == SD_R1_IDLE)
|
||||
{
|
||||
// Version 2 card.
|
||||
sdDev.version = 2;
|
||||
// Read 32bit response. Should contain the same bytes that
|
||||
// we sent in the command parameter.
|
||||
sdSpiByte(0xFF);
|
||||
sdSpiByte(0xFF);
|
||||
sdSpiByte(0xFF);
|
||||
sdSpiByte(0xFF);
|
||||
break;
|
||||
}
|
||||
else if (status & SD_R1_ILLEGAL)
|
||||
{
|
||||
// Version 1 card.
|
||||
sdDev.version = 1;
|
||||
break;
|
||||
}
|
||||
} while (--retries > 0);
|
||||
|
||||
return retries > 0;
|
||||
}
|
||||
|
||||
static int sdOpCond()
|
||||
{
|
||||
int retries = 50;
|
||||
|
||||
uint8 status;
|
||||
do
|
||||
{
|
||||
CyDelay(33); // Spec says to retry for 1 second.
|
||||
|
||||
sdCommandAndResponse(SD_APP_CMD, 0);
|
||||
// Host Capacity Support = 1 (SDHC/SDXC supported)
|
||||
status = sdCommandAndResponse(SD_APP_SEND_OP_COND, 0x40000000);
|
||||
} while ((status != 0) && (--retries > 0));
|
||||
|
||||
return retries > 0;
|
||||
}
|
||||
|
||||
static int sdReadOCR()
|
||||
{
|
||||
uint8 status = sdCommandAndResponse(SD_READ_OCR, 0);
|
||||
if(status){goto bad;}
|
||||
|
||||
uint8 buf[4];
|
||||
int i;
|
||||
for (i = 0; i < 4; ++i)
|
||||
{
|
||||
buf[i] = sdSpiByte(0xFF);
|
||||
}
|
||||
|
||||
sdDev.ccs = (buf[0] & 0x40) ? 1 : 0;
|
||||
|
||||
return 1;
|
||||
bad:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sdReadCSD()
|
||||
{
|
||||
uint8 status = sdCommandAndResponse(SD_SEND_CSD, 0);
|
||||
if(status){goto bad;}
|
||||
status = sdWaitResp();
|
||||
if (status != 0xFE) { goto bad; }
|
||||
|
||||
uint8 buf[16];
|
||||
int i;
|
||||
for (i = 0; i < 16; ++i)
|
||||
{
|
||||
buf[i] = sdSpiByte(0xFF);
|
||||
}
|
||||
sdSpiByte(0xFF); // CRC
|
||||
sdSpiByte(0xFF); // CRC
|
||||
|
||||
if ((buf[0] >> 6) == 0x00)
|
||||
{
|
||||
// CSD version 1
|
||||
// C_SIZE in bits [73:62]
|
||||
uint32 c_size = (((((uint32)buf[6]) & 0x3) << 16) | (((uint32)buf[7]) << 8) | buf[8]) >> 6;
|
||||
uint32 c_mult = (((((uint32)buf[9]) & 0x3) << 8) | ((uint32)buf[0xa])) >> 7;
|
||||
uint32 sectorSize = buf[5] & 0x0F;
|
||||
sdDev.capacity = ((c_size+1) * ((uint64)1 << (c_mult+2)) * ((uint64)1 << sectorSize)) / SCSI_BLOCK_SIZE;
|
||||
}
|
||||
else if ((buf[0] >> 6) == 0x01)
|
||||
{
|
||||
// CSD version 2
|
||||
// C_SIZE in bits [69:48]
|
||||
|
||||
uint32 c_size =
|
||||
((((uint32)buf[7]) & 0x3F) << 16) |
|
||||
(((uint32)buf[8]) << 8) |
|
||||
((uint32)buf[7]);
|
||||
sdDev.capacity = (c_size + 1) * 1024;
|
||||
}
|
||||
else
|
||||
{
|
||||
goto bad;
|
||||
}
|
||||
|
||||
return 1;
|
||||
bad:
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sdInit()
|
||||
{
|
||||
sdDev.version = 0;
|
||||
sdDev.ccs = 0;
|
||||
sdDev.capacity = 0;
|
||||
|
||||
int result = 0;
|
||||
SD_CS_Write(1); // Set CS inactive (active low)
|
||||
SD_Init_Clk_Start(); // Turn on the slow 400KHz clock
|
||||
SD_Clk_Ctl_Write(0); // Select the 400KHz clock source.
|
||||
SDCard_Start(); // Enable SPI hardware
|
||||
|
||||
// Power on sequence. 74 clock cycles of a "1" while CS unasserted.
|
||||
int i;
|
||||
for (i = 0; i < 10; ++i)
|
||||
{
|
||||
sdSpiByte(0xFF);
|
||||
}
|
||||
|
||||
SD_CS_Write(0); // Set CS active (active low)
|
||||
CyDelayUs(1);
|
||||
|
||||
uint8 v = sdCommandAndResponse(SD_GO_IDLE_STATE, 0);
|
||||
if(v != 1){goto bad;}
|
||||
|
||||
if (!sendIfCond()) goto bad; // Sets V1 or V2 flag
|
||||
if (!sdOpCond()) goto bad;
|
||||
if (!sdReadOCR()) goto bad;
|
||||
|
||||
// This command will be ignored if sdDev.ccs is set.
|
||||
// SDHC and SDXC are always 512bytes.
|
||||
v = sdCommandAndResponse(SD_SET_BLOCKLEN, SCSI_BLOCK_SIZE); //Force sector size
|
||||
if(v){goto bad;}
|
||||
v = sdCommandAndResponse(SD_CRC_ON_OFF, 0); //crc off
|
||||
if(v){goto bad;}
|
||||
|
||||
// now set the sd card up for full speed
|
||||
SD_Data_Clk_Start(); // Turn on the fast clock
|
||||
SD_Clk_Ctl_Write(1); // Select the fast clock source.
|
||||
SD_Init_Clk_Stop(); // Stop the slow clock.
|
||||
|
||||
if (!sdReadCSD()) goto bad;
|
||||
|
||||
result = 1;
|
||||
goto out;
|
||||
|
||||
bad:
|
||||
sdDev.capacity = 0;
|
||||
|
||||
out:
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void sdPrepareWrite()
|
||||
{
|
||||
// Set the number of blocks to pre-erase by the multiple block write command
|
||||
// We don't care about the response - if the command is not accepted, writes
|
||||
// will just be a bit slower.
|
||||
// Max 22bit parameter.
|
||||
uint32 blocks = transfer.blocks > 0x7FFFFF ? 0x7FFFFF : transfer.blocks;
|
||||
sdCommandAndResponse(SD_APP_CMD, 0);
|
||||
sdCommandAndResponse(SD_APP_SET_WR_BLK_ERASE_COUNT, blocks);
|
||||
|
||||
uint32 len = (transfer.lba + transfer.currentBlock);
|
||||
if (!sdDev.ccs)
|
||||
{
|
||||
len = len * SCSI_BLOCK_SIZE;
|
||||
}
|
||||
uint8 v = sdCommandAndResponse(25, len);
|
||||
if (v)
|
||||
{
|
||||
scsiDiskReset();
|
||||
|
||||
scsiDev.status = CHECK_CONDITION;
|
||||
scsiDev.sense.code = HARDWARE_ERROR;
|
||||
scsiDev.sense.asc = LOGICAL_UNIT_COMMUNICATION_FAILURE;
|
||||
scsiDev.phase = STATUS;
|
||||
}
|
||||
}
|
||||
|
63
software/SCSI2SD/SCSI2SD.cydsn/sd.h
Executable file
63
software/SCSI2SD/SCSI2SD.cydsn/sd.h
Executable file
@ -0,0 +1,63 @@
|
||||
// Copyright (C) 2013 Michael McMaster <michael@codesrc.com>
|
||||
//
|
||||
// This file is part of SCSI2SD.
|
||||
//
|
||||
// SCSI2SD is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// SCSI2SD is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with SCSI2SD. If not, see <http://www.gnu.org/licenses/>.
|
||||
#ifndef SD_H
|
||||
#define SD_H
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SD_GO_IDLE_STATE = 0,
|
||||
SD_SEND_OP_COND = 1,
|
||||
SD_SEND_IF_COND = 8, // SD V2
|
||||
SD_SEND_CSD = 9,
|
||||
SD_SET_BLOCKLEN = 16,
|
||||
SD_APP_SET_WR_BLK_ERASE_COUNT = 23,
|
||||
SD_APP_SEND_OP_COND = 41,
|
||||
SD_APP_CMD = 55,
|
||||
SD_READ_OCR = 58,
|
||||
SD_CRC_ON_OFF = 59
|
||||
} SD_CMD;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SD_R1_IDLE = 1,
|
||||
SD_R1_ERASE_RESET = 2,
|
||||
SD_R1_ILLEGAL = 4,
|
||||
SD_R1_CRC = 8,
|
||||
SD_R1_ERASE_SEQ = 0x10,
|
||||
SD_R1_ADDRESS = 0x20,
|
||||
SD_R1_PARAMETER = 0x40
|
||||
} SD_R1;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int version; // SDHC = version 2.
|
||||
int ccs; // Card Capacity Status. 1 = SDHC or SDXC
|
||||
int capacity; // in 512 byte blocks
|
||||
} SdDevice;
|
||||
|
||||
extern SdDevice sdDev;
|
||||
|
||||
int sdInit();
|
||||
void sdPrepareWrite();
|
||||
int sdWriteSector();
|
||||
void sdCompleteWrite();
|
||||
|
||||
void sdPrepareRead(int nextBlockOffset);
|
||||
int sdIsReadReady();
|
||||
void sdReadSector();
|
||||
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user