STM32 Bootloader
Customizable Bootloader for STM32 microcontrollers
sd_diskio.c
Go to the documentation of this file.
1 
23 /* Includes ------------------------------------------------------------------*/
24 #include "sd_diskio.h"
25 
26 #include "board.h"
27 #include "log.h"
28 #include "sdmmc.h"
29 
30 #include <stdbool.h>
31 
32 /* Private function prototypes -----------------------------------------------*/
36 static void SdReadCompleteCallback(void);
37 
41 static void SdWriteCompleteCallback(void);
42 
49 static DSTATUS SdDiskIoInit(BYTE pdrv);
50 
57 static DSTATUS SdDiskIoStatus(BYTE pdrv);
58 
68 static DRESULT SdDiskIoRead(BYTE pdrv, BYTE* buff, DWORD sector, UINT count);
69 
79 static DRESULT SdDiskIoWrite(BYTE pdrv,
80  const BYTE* buff,
81  DWORD sector,
82  UINT count);
83 
93 static DRESULT SdDiskIoIoctl(BYTE pdrv, BYTE cmd, void* buff);
94 
95 /* Private variables ---------------------------------------------------------*/
97 static volatile bool isReadComplete = false;
98 
100 static volatile bool isWriteComplete = false;
101 
102 /* Functions -----------------------------------------------------------------*/
103 const Diskio_drvTypeDef* SdDiskIoGetDriver(void)
104 {
105  static const Diskio_drvTypeDef SD_DISK_IO_DRIVER = {
108  };
109 
110  return &SD_DISK_IO_DRIVER;
111 }
112 
113 static DSTATUS SdDiskIoInit(BYTE pdrv)
114 {
117 
118  isReadComplete = false;
119  isWriteComplete = false;
120 
121  return SdDiskIoStatus(pdrv);
122 }
123 
124 static DSTATUS SdDiskIoStatus(BYTE pdrv)
125 {
126  UNUSED(pdrv);
127  DSTATUS result = STA_NOINIT;
128 
130  {
131  result &= ~STA_NOINIT;
132  }
133 
134  return result;
135 }
136 
137 static DRESULT SdDiskIoRead(BYTE pdrv, BYTE* buff, DWORD sector, UINT count)
138 {
139  UNUSED(pdrv);
140  DRESULT result = RES_ERROR;
141 
142 #if defined(USE_SDMMC_DMA)
143  /* Use SD Driver in DMA mode */
144  isReadComplete = false;
145  if (SdmmcReadBlocksDma(buff, sector, count))
146  {
147  /* Wait for DMA Complete */
148  uint32_t timeout = HAL_GetTick();
149  while (!isReadComplete &&
150  ((HAL_GetTick() - timeout) < SDMMC_TRANSFER_TIMEOUT))
151  {
152  }
153 
154  /* In case of a timeout return error */
155  if (!isReadComplete)
156  {
157  result = RES_ERROR;
158  }
159  else
160  {
162  {
163  result = RES_OK;
164  }
165  else
166  {
167  LogPrint("ERROR: SD card is not in transfer state.\n");
168  }
169  }
170  }
171 #else
172  /* Use SD Driver in blocking mode */
173  if (SdmmcReadBlocks(buff, sector, count, SDMMC_TRANSFER_TIMEOUT))
174  {
176  {
177  result = RES_OK;
178  }
179  }
180 #endif /* USE_SDMMC_DMA */
181 
182  return result;
183 }
184 
185 static DRESULT SdDiskIoWrite(BYTE pdrv,
186  const BYTE* buff,
187  DWORD sector,
188  UINT count)
189 {
190  UNUSED(pdrv);
191  DRESULT result = RES_ERROR;
192 
193 #if defined(USE_SDMMC_DMA)
194  /* Use SD Driver in DMA mode */
195  isWriteComplete = false;
196  if (SdmmcWriteBlocksDma(buff, sector, count))
197  {
198  /* Wait for DMA complete */
199  uint32_t timeout = HAL_GetTick();
200  while (!isWriteComplete &&
201  ((HAL_GetTick() - timeout) < SDMMC_TRANSFER_TIMEOUT))
202  {
203  }
204 
205  /* In case of a timeout return error */
206  if (!isWriteComplete)
207  {
208  result = RES_ERROR;
209  }
210  else
211  {
213  {
214  result = RES_OK;
215  }
216  else
217  {
218  LogPrint("ERROR: SD card is not in transfer state.\n");
219  }
220  }
221  }
222 #else
223  /* Use SD Driver in blocking mode */
224  result = RES_ERROR;
225  if (SdmmcWriteBlocks(buff, sector, count, SDMMC_TRANSFER_TIMEOUT))
226  {
228  {
229  result = RES_OK;
230  }
231  }
232 #endif /* USE_SDMMC_DMA */
233 
234  return result;
235 }
236 
237 static DRESULT SdDiskIoIoctl(BYTE pdrv, BYTE cmd, void* buff)
238 {
239  UNUSED(pdrv);
240  DRESULT result = RES_NOTRDY;
241 
243  {
244  SdCardInfo sdCardInfo = {0};
245  switch (cmd)
246  {
247  /* Make sure that no pending write process */
248  case CTRL_SYNC:
249  result = RES_OK;
250  break;
251 
252  /* Get number of sectors on the disk (DWORD) */
253  case GET_SECTOR_COUNT:
254  if (SdmmcGetCardInfo(&sdCardInfo))
255  {
256  // Message: A conversion should not be performed from
257  // pointer to void into pointer to object
258  // [misra-c2012-11.5]
259  // Reason: The pointer to the buffer needs to be
260  // converted to a pointer to DWORD in order to
261  // fill the buffer with the requested value.
262  // Risk: Conversion of a pointer to void into a
263  // pointer to object may result in a pointer
264  // that is not correctly aligned, resulting in
265  // undefined behavior.
266  // Prevention: Code reviews.
267  // cppcheck-suppress [misra-c2012-11.5]
268  *(DWORD*)buff = sdCardInfo.LogBlockNbr;
269  result = RES_OK;
270  }
271  break;
272 
273  /* Get R/W sector size (WORD) */
274  case GET_SECTOR_SIZE:
275  if (SdmmcGetCardInfo(&sdCardInfo))
276  {
277  // Message: A conversion should not be performed from
278  // pointer to void into pointer to object
279  // [misra-c2012-11.5]
280  // Reason: The pointer to the buffer needs to be
281  // converted to a pointer to WORD in order to
282  // fill the buffer with the requested value.
283  // Risk: Conversion of a pointer to void into a
284  // pointer to object may result in a pointer
285  // that is not correctly aligned, resulting in
286  // undefined behavior.
287  // Prevention: Code reviews.
288  // cppcheck-suppress [misra-c2012-11.5]
289  *(WORD*)buff = (WORD)sdCardInfo.LogBlockSize;
290  result = RES_OK;
291  }
292  break;
293 
294  /* Get erase block size in unit of sector (DWORD) */
295  case GET_BLOCK_SIZE:
296  if (SdmmcGetCardInfo(&sdCardInfo))
297  {
298  // Message: A conversion should not be performed from
299  // pointer to void into pointer to object
300  // [misra-c2012-11.5]
301  // Reason: The pointer to the buffer needs to be
302  // converted to a pointer to DWORD in order to
303  // fill the buffer with the requested value.
304  // Risk: Conversion of a pointer to void into a
305  // pointer to object may result in a pointer
306  // that is not correctly aligned, resulting in
307  // undefined behavior.
308  // Prevention: Code reviews.
309  // cppcheck-suppress [misra-c2012-11.5]
310  *(DWORD*)buff = sdCardInfo.LogBlockSize;
311  result = RES_OK;
312  }
313  break;
314 
315  default:
316  result = RES_PARERR;
317  break;
318  }
319  }
320 
321  return result;
322 }
323 
324 static void SdReadCompleteCallback(void)
325 {
326  isReadComplete = true;
327 }
328 
329 static void SdWriteCompleteCallback(void)
330 {
331  isWriteComplete = true;
332 }
333 
This file contains the board-specific GPIO pin definitions, peripheral configurations,...
static volatile bool isWriteComplete
Definition: sd_diskio.c:100
static DRESULT SdDiskIoRead(BYTE pdrv, BYTE *buff, DWORD sector, UINT count)
Read one or more sectors from the SD card.
Definition: sd_diskio.c:137
static DRESULT SdDiskIoWrite(BYTE pdrv, const BYTE *buff, DWORD sector, UINT count)
Write one or more sectors to the SD card.
Definition: sd_diskio.c:185
static DSTATUS SdDiskIoStatus(BYTE pdrv)
Return the current status of the SD card.
Definition: sd_diskio.c:124
static volatile bool isReadComplete
Definition: sd_diskio.c:97
static DRESULT SdDiskIoIoctl(BYTE pdrv, BYTE cmd, void *buff)
Perform miscellaneous disk I/O control operations on the SD card.
Definition: sd_diskio.c:237
static void SdReadCompleteCallback(void)
Callback for the SD DMA read transfer complete.
Definition: sd_diskio.c:324
const Diskio_drvTypeDef * SdDiskIoGetDriver(void)
Get a pointer to the SD card disk I/O driver structure containing the initialize, status,...
Definition: sd_diskio.c:103
static void SdWriteCompleteCallback(void)
Callback for the SD DMA write transfer complete.
Definition: sd_diskio.c:329
static DSTATUS SdDiskIoInit(BYTE pdrv)
Initialize the SD card disk I/O driver and register DMA callbacks.
Definition: sd_diskio.c:113
#define SDMMC_TRANSFER_TIMEOUT
Definition: board.h:92
void LogPrint(const char *format,...)
Print a formatted log message over the UART interface.
Definition: log.c:40
bool SdmmcGetCardInfo(SdCardInfo *const cardInfo)
Get the SD card information (capacity, block size, etc.).
Definition: sdmmc.c:127
void SdmmcRegisterRxCompleteCallback(Callback callback)
Register a callback for the DMA receive complete event.
Definition: sdmmc.c:314
bool SdmmcWriteBlocks(const uint8_t *const data, const uint32_t blockAddress, const uint32_t numOfBlocks, const uint32_t timeout)
Write blocks to the SD card in blocking mode.
Definition: sdmmc.c:146
bool SdmmcReadBlocks(uint8_t *const data, const uint32_t blockAddress, const uint32_t numOfBlocks, const uint32_t timeout)
Read blocks from the SD card in blocking mode.
Definition: sdmmc.c:137
bool SdmmcReadBlocksDma(uint8_t *const data, const uint32_t blockAddress, const uint32_t numOfBlocks)
Read blocks from the SD card using DMA.
Definition: sdmmc.c:172
void SdmmcRegisterTxCompleteCallback(Callback callback)
Register a callback for the DMA transmit complete event.
Definition: sdmmc.c:319
bool SdmmcWriteBlocksDma(const uint8_t *const data, const uint32_t blockAddress, const uint32_t numOfBlocks)
Write blocks to the SD card using DMA.
Definition: sdmmc.c:191
HAL_SD_CardInfoTypeDef SdCardInfo
Definition: sdmmc.h:41
bool SdmmcIsCardInTransferState(void)
Check if the SD card is in the transfer state.
Definition: sdmmc.c:132
This file contains the UART-based logging function prototypes for the debug output.
This file contains the SD card disk I/O driver interface for the FatFs middleware.
This file contains the SDMMC peripheral driver function prototypes for SD card initialization,...