1 // Copyright (C) 2013 Michael McMaster <michael@codesrc.com>
3 // This file is part of SCSI2SD.
5 // SCSI2SD is free software: you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation, either version 3 of the License, or
8 // (at your option) any later version.
10 // SCSI2SD is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with SCSI2SD. If not, see <http://www.gnu.org/licenses/>.
19 #include "stm32f2xx.h"
23 #include "stm32f4xx.h"
27 #include "bsp_driver_sd.h"
44 static int sdCmdActive
= 0;
47 sdReadDMAPoll(uint32_t remainingSectors
)
49 // TODO DMA byte counting disabled for now as it's not
51 // We can ask the SDIO controller how many bytes have been
52 // processed (SDIO_GetDataCounter()) but I'm not sure if that
53 // means the data has been transfered via dma to memory yet.
54 // uint32_t dmaBytesRemaining = __HAL_DMA_GET_COUNTER(hsd.hdmarx) * 4;
56 if (HAL_SD_GetState(&hsd
) != HAL_SD_STATE_BUSY
)
58 // DMA transfer is complete
60 return remainingSectors
;
64 return remainingSectors - ((dmaBytesRemaining + (SD_SECTOR_SIZE - 1)) / SD_SECTOR_SIZE);
69 void sdReadDMA(uint32_t lba
, uint32_t sectors
, uint8_t* outputBuffer
)
71 if (HAL_SD_ReadBlocks_DMA(&hsd
, outputBuffer
, lba
* 512ll, sectors
) != HAL_OK
)
75 scsiDev
.status
= CHECK_CONDITION
;
76 scsiDev
.target
->sense
.code
= HARDWARE_ERROR
;
77 scsiDev
.target
->sense
.asc
= LOGICAL_UNIT_COMMUNICATION_FAILURE
;
78 scsiDev
.phase
= STATUS
;
86 void sdCompleteTransfer()
99 memset(sdDev
.csd
, 0, sizeof(sdDev
.csd
));
100 memset(sdDev
.cid
, 0, sizeof(sdDev
.cid
));
103 static int sdDoInit()
109 int8_t error
= BSP_SD_Init();
112 HAL_SD_CardInfoTypeDef cardInfo
;
113 HAL_SD_GetCardInfo(&hsd
, &cardInfo
);
114 memcpy(sdDev
.csd
, hsd
.CSD
, sizeof(sdDev
.csd
));
115 memcpy(sdDev
.cid
, hsd
.CID
, sizeof(sdDev
.cid
));
116 sdDev
.capacity
= cardInfo
.BlockNbr
;
117 blockDev
.state
|= DISK_PRESENT
| DISK_INITIALISED
;
124 blockDev
.state
&= ~(DISK_PRESENT
| DISK_INITIALISED
);
135 // Check if there's an SD card present.
138 static int firstInit
= 1;
142 blockDev
.state
&= ~(DISK_PRESENT
| DISK_INITIALISED
);
146 if (firstInit
|| (scsiDev
.phase
== BUS_FREE
))
148 uint8_t cs
= HAL_GPIO_ReadPin(nSD_CD_GPIO_Port
, nSD_CD_Pin
) ? 0 : 1;
149 uint8_t wp
= HAL_GPIO_ReadPin(nSD_WP_GPIO_Port
, nSD_WP_Pin
) ? 0 : 1;
151 if (cs
&& !(blockDev
.state
& DISK_PRESENT
))
163 blockDev
.state
|= DISK_PRESENT
| DISK_INITIALISED
;
167 blockDev
.state
|= DISK_WP
;
171 blockDev
.state
&= ~DISK_WP
;
174 // Always "start" the device. Many systems (eg. Apple System 7)
175 // won't respond properly to
176 // LOGICAL_UNIT_NOT_READY_INITIALIZING_COMMAND_REQUIRED sense
177 // code, even if they stopped it first with
178 // START STOP UNIT command.
179 blockDev
.state
|= DISK_STARTED
;
187 for (int i
= 0; i
< 10; ++i
)
189 // visual indicator of SD error
198 else if (!cs
&& (blockDev
.state
& DISK_PRESENT
))
201 blockDev
.state
&= ~DISK_PRESENT
;
202 blockDev
.state
&= ~DISK_INITIALISED
;
204 for (i
= 0; i
< S2S_MAX_TARGETS
; ++i
)
206 scsiDev
.targets
[i
].unitAttention
= PARAMETERS_CHANGED
;