From: Michael McMaster Date: Fri, 11 Oct 2013 14:37:27 +0000 (+1000) Subject: Multi-sector writes, increased SPI clock to 24MHz, Added support for SDHC/SDXC. X-Git-Tag: v3.0~10 X-Git-Url: http://git.codesrc.com/gitweb.cgi?a=commitdiff_plain;h=27e482ea8c073555f459b81ddb5187fd531c8703;p=SCSI2SD.git Multi-sector writes, increased SPI clock to 24MHz, Added support for SDHC/SDXC. --- diff --git a/software/SCSI2SD/SCSI2SD.cydsn/Generated_Source/PSoC5/config.hex b/software/SCSI2SD/SCSI2SD.cydsn/Generated_Source/PSoC5/config.hex index c281d8f..c6c8b64 100644 --- a/software/SCSI2SD/SCSI2SD.cydsn/Generated_Source/PSoC5/config.hex +++ b/software/SCSI2SD/SCSI2SD.cydsn/Generated_Source/PSoC5/config.hex @@ -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 diff --git a/software/SCSI2SD/SCSI2SD.cydsn/Generated_Source/PSoC5/cyfitter.h b/software/SCSI2SD/SCSI2SD.cydsn/Generated_Source/PSoC5/cyfitter.h index 2dec2e0..610d0fc 100644 --- a/software/SCSI2SD/SCSI2SD.cydsn/Generated_Source/PSoC5/cyfitter.h +++ b/software/SCSI2SD/SCSI2SD.cydsn/Generated_Source/PSoC5/cyfitter.h @@ -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 diff --git a/software/SCSI2SD/SCSI2SD.cydsn/Generated_Source/PSoC5/cyfitter_cfg.c b/software/SCSI2SD/SCSI2SD.cydsn/Generated_Source/PSoC5/cyfitter_cfg.c index 200ebad..d674761 100644 --- a/software/SCSI2SD/SCSI2SD.cydsn/Generated_Source/PSoC5/cyfitter_cfg.c +++ b/software/SCSI2SD/SCSI2SD.cydsn/Generated_Source/PSoC5/cyfitter_cfg.c @@ -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; diff --git a/software/SCSI2SD/SCSI2SD.cydsn/Generated_Source/PSoC5/cyfittergnu.inc b/software/SCSI2SD/SCSI2SD.cydsn/Generated_Source/PSoC5/cyfittergnu.inc index 629bee4..88b1b13 100644 --- a/software/SCSI2SD/SCSI2SD.cydsn/Generated_Source/PSoC5/cyfittergnu.inc +++ b/software/SCSI2SD/SCSI2SD.cydsn/Generated_Source/PSoC5/cyfittergnu.inc @@ -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 diff --git a/software/SCSI2SD/SCSI2SD.cydsn/Generated_Source/PSoC5/cyfitterrv.inc b/software/SCSI2SD/SCSI2SD.cydsn/Generated_Source/PSoC5/cyfitterrv.inc index 3699982..49eb0dd 100644 --- a/software/SCSI2SD/SCSI2SD.cydsn/Generated_Source/PSoC5/cyfitterrv.inc +++ b/software/SCSI2SD/SCSI2SD.cydsn/Generated_Source/PSoC5/cyfitterrv.inc @@ -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 diff --git a/software/SCSI2SD/SCSI2SD.cydsn/SCSI2SD.cycdx b/software/SCSI2SD/SCSI2SD.cydsn/SCSI2SD.cycdx index 880f831..1748503 100644 --- a/software/SCSI2SD/SCSI2SD.cydsn/SCSI2SD.cycdx +++ b/software/SCSI2SD/SCSI2SD.cydsn/SCSI2SD.cycdx @@ -7,7 +7,7 @@ - + diff --git a/software/SCSI2SD/SCSI2SD.cydsn/SCSI2SD.cydwr b/software/SCSI2SD/SCSI2SD.cydsn/SCSI2SD.cydwr index 357f64c..ed4c6c4 100755 Binary files a/software/SCSI2SD/SCSI2SD.cydsn/SCSI2SD.cydwr and b/software/SCSI2SD/SCSI2SD.cydsn/SCSI2SD.cydwr differ diff --git a/software/SCSI2SD/SCSI2SD.cydsn/SCSI2SD.cyfit b/software/SCSI2SD/SCSI2SD.cydsn/SCSI2SD.cyfit index ddfbf10..ddd23b7 100644 Binary files a/software/SCSI2SD/SCSI2SD.cydsn/SCSI2SD.cyfit and b/software/SCSI2SD/SCSI2SD.cydsn/SCSI2SD.cyfit differ diff --git a/software/SCSI2SD/SCSI2SD.cydsn/SCSI2SD.cyprj b/software/SCSI2SD/SCSI2SD.cydsn/SCSI2SD.cyprj index 6dc1b1c..5fff193 100755 --- a/software/SCSI2SD/SCSI2SD.cydsn/SCSI2SD.cyprj +++ b/software/SCSI2SD/SCSI2SD.cydsn/SCSI2SD.cyprj @@ -95,6 +95,13 @@ + + + + + + + @@ -203,6 +210,13 @@ + + + + + + + diff --git a/software/SCSI2SD/SCSI2SD.cydsn/SCSI2SD.svd b/software/SCSI2SD/SCSI2SD.cydsn/SCSI2SD.svd index 28ee2d3..7719d7c 100644 --- a/software/SCSI2SD/SCSI2SD.cydsn/SCSI2SD.svd +++ b/software/SCSI2SD/SCSI2SD.cydsn/SCSI2SD.svd @@ -9,7 +9,7 @@ SD_Clk_Ctl No description available - 0x40006575 + 0x40006476 0 0x1 diff --git a/software/SCSI2SD/SCSI2SD.cydsn/TopDesign/TopDesign.cysch b/software/SCSI2SD/SCSI2SD.cydsn/TopDesign/TopDesign.cysch index 6eb4869..8c9586b 100755 Binary files a/software/SCSI2SD/SCSI2SD.cydsn/TopDesign/TopDesign.cysch and b/software/SCSI2SD/SCSI2SD.cydsn/TopDesign/TopDesign.cysch differ diff --git a/software/SCSI2SD/SCSI2SD.cydsn/disk.c b/software/SCSI2SD/SCSI2SD.cydsn/disk.c index ad0fac5..61e1101 100755 --- a/software/SCSI2SD/SCSI2SD.cydsn/disk.c +++ b/software/SCSI2SD/SCSI2SD.cydsn/disk.c @@ -18,6 +18,7 @@ #include "device.h" #include "scsi.h" #include "disk.h" +#include "sd.h" #include @@ -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); + } } } } diff --git a/software/SCSI2SD/SCSI2SD.cydsn/mode.c b/software/SCSI2SD/SCSI2SD.cydsn/mode.c index 89639cc..83b00c7 100755 --- a/software/SCSI2SD/SCSI2SD.cydsn/mode.c +++ b/software/SCSI2SD/SCSI2SD.cydsn/mode.c @@ -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 diff --git a/software/SCSI2SD/SCSI2SD.cydsn/sd.c b/software/SCSI2SD/SCSI2SD.cydsn/sd.c new file mode 100755 index 0000000..c76c72d --- /dev/null +++ b/software/SCSI2SD/SCSI2SD.cydsn/sd.c @@ -0,0 +1,451 @@ +// Copyright (C) 2013 Michael McMaster +// +// 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 . + +#include "device.h" +#include "scsi.h" +#include "disk.h" +#include "sd.h" + +#include + +// 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; + } +} + diff --git a/software/SCSI2SD/SCSI2SD.cydsn/sd.h b/software/SCSI2SD/SCSI2SD.cydsn/sd.h new file mode 100755 index 0000000..3473a7d --- /dev/null +++ b/software/SCSI2SD/SCSI2SD.cydsn/sd.h @@ -0,0 +1,63 @@ +// Copyright (C) 2013 Michael McMaster +// +// 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 . +#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