5 * th9x - http://code.google.com/p/th9x
6 * er9x - http://code.google.com/p/er9x
7 * gruvin9x - http://code.google.com/p/gruvin9x
9 * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
22 #include "FatFs/diskio.h"
25 /* Definitions for MMC/SDC command */
26 #define CMD0 (0x40+0) /* GO_IDLE_STATE */
27 #define CMD1 (0x40+1) /* SEND_OP_COND (MMC) */
28 #define ACMD41 (0xC0+41) /* SEND_OP_COND (SDC) */
29 #define CMD8 (0x40+8) /* SEND_IF_COND */
30 #define CMD9 (0x40+9) /* SEND_CSD */
31 #define CMD10 (0x40+10) /* SEND_CID */
32 #define CMD12 (0x40+12) /* STOP_TRANSMISSION */
33 #define ACMD13 (0xC0+13) /* SD_STATUS (SDC) */
34 #define CMD16 (0x40+16) /* SET_BLOCKLEN */
35 #define CMD17 (0x40+17) /* READ_SINGLE_BLOCK */
36 #define CMD18 (0x40+18) /* READ_MULTIPLE_BLOCK */
37 #define CMD23 (0x40+23) /* SET_BLOCK_COUNT (MMC) */
38 #define ACMD23 (0xC0+23) /* SET_WR_BLK_ERASE_COUNT (SDC) */
39 #define CMD24 (0x40+24) /* WRITE_BLOCK */
40 #define CMD25 (0x40+25) /* WRITE_MULTIPLE_BLOCK */
41 #define CMD55 (0x40+55) /* APP_CMD */
42 #define CMD58 (0x40+58) /* READ_OCR */
44 /* Card-Select Controls (Platform dependent) */
45 #define SD_SELECT() GPIO_ResetBits(SD_GPIO, SD_GPIO_PIN_CS) /* MMC CS = L */
46 #define SD_DESELECT() GPIO_SetBits(SD_GPIO, SD_GPIO_PIN_CS) /* MMC CS = H */
52 /* Card type flags (CardType) */
56 #define CT_SDC (CT_SD1|CT_SD2)
59 /*-----------------------------------------------------------------------*/
60 /* Lock / unlock functions */
61 /*-----------------------------------------------------------------------*/
63 static RTOS_MUTEX_HANDLE ioMutex
;
65 int ff_cre_syncobj (BYTE vol
, _SYNC_t
*mutex
)
71 int ff_req_grant (_SYNC_t mutex
)
73 RTOS_LOCK_MUTEX(mutex
);
77 void ff_rel_grant (_SYNC_t mutex
)
79 RTOS_UNLOCK_MUTEX(mutex
);
82 int ff_del_syncobj (_SYNC_t mutex
)
88 static const DWORD socket_state_mask_cp
= (1 << 0);
89 static const DWORD socket_state_mask_wp
= (1 << 1);
92 DSTATUS Stat
= STA_NOINIT
; /* Disk status */
95 DWORD Timer1
, Timer2
; /* 100Hz decrement timers */
97 BYTE CardType
; /* Card type flags */
99 enum speed_setting
{ INTERFACE_SLOW
, INTERFACE_FAST
};
101 static void interface_speed( enum speed_setting speed
)
106 if ( speed
== INTERFACE_SLOW
) {
107 /* Set slow clock (100k-400k) */
108 tmp
= ( tmp
| SPI_BaudRatePrescaler_128
);
110 /* Set fast clock (depends on the CSD) */
111 tmp
= ( tmp
& ~SPI_BaudRatePrescaler_128
) | SD_SPI_BaudRatePrescaler
;
116 static inline DWORD
socket_is_write_protected(void)
118 return 0; /* fake not protected */
121 static inline DWORD
socket_is_empty(void)
123 return !SD_CARD_PRESENT(); /* fake inserted */
126 static void card_power(BYTE on
)
131 static int chk_power(void)
133 return 1; /* fake powered */
136 /*-----------------------------------------------------------------------*/
137 /* Transmit/Receive a byte to MMC via SPI (Platform dependent) */
138 /*-----------------------------------------------------------------------*/
139 static BYTE
stm32_spi_rw( BYTE out
)
141 /* Loop while DR register in not empty */
142 /// not needed: while (SPI_I2S_GetFlagStatus(SD_SPI, SPI_I2S_FLAG_TXE) == RESET) { ; }
144 /* Send byte through the SPI peripheral */
145 SPI_I2S_SendData(SD_SPI
, out
);
147 /* Wait to receive a byte */
148 while (SPI_I2S_GetFlagStatus(SD_SPI
, SPI_I2S_FLAG_RXNE
) == RESET
) { ; }
150 /* Return the byte read from the SPI bus */
151 return SPI_I2S_ReceiveData(SD_SPI
);
156 /*-----------------------------------------------------------------------*/
157 /* Transmit a byte to MMC via SPI (Platform dependent) */
158 /*-----------------------------------------------------------------------*/
160 #define xmit_spi(dat) stm32_spi_rw(dat)
162 /*-----------------------------------------------------------------------*/
163 /* Receive a byte from MMC via SPI (Platform dependent) */
164 /*-----------------------------------------------------------------------*/
169 return stm32_spi_rw(0xff);
172 /* Alternative macro to receive data fast */
173 #define rcvr_spi_m(dst) *(dst)=stm32_spi_rw(0xff)
177 /*-----------------------------------------------------------------------*/
178 /* Wait for card ready */
179 /*-----------------------------------------------------------------------*/
180 static BYTE
wait_ready (void)
184 Timer2
= 50; /* Wait for ready in timeout of 500ms */
188 } while ((res
!= 0xFF) && Timer2
);
193 static void spi_reset()
195 for (int n
=0; n
<520; ++n
) {
198 TRACE_SD_CARD_EVENT(1, sd_spi_reset
, 0);
201 /*-----------------------------------------------------------------------*/
202 /* Deselect the card and release SPI bus */
203 /*-----------------------------------------------------------------------*/
206 void release_spi (void)
214 #if defined(STM32F4) && !defined(BOOT)
215 WORD rw_workbyte
[1] __DMA
;
218 /*-----------------------------------------------------------------------*/
219 /* Transmit/Receive Block using DMA (Platform dependent. STM32 here) */
220 /*-----------------------------------------------------------------------*/
222 void stm32_dma_transfer(
223 BOOL receive
, /* FALSE for buff->SPI, TRUE for SPI->buff */
224 const BYTE
*buff
, /* receive TRUE : 512 byte data block to be transmitted
225 receive FALSE : Data buffer to store received data */
226 UINT btr
/* receive TRUE : Byte count (must be multiple of 2)
227 receive FALSE : Byte count (must be 512) */
230 DMA_InitTypeDef DMA_InitStructure
;
231 #if defined(STM32F4) && !defined(BOOT)
232 rw_workbyte
[0] = 0xffff;
234 WORD rw_workbyte
[] = { 0xffff };
237 DMA_DeInit(SD_DMA_Stream_SPI_RX
);
238 DMA_DeInit(SD_DMA_Stream_SPI_TX
);
240 /* shared DMA configuration values between SPI2 RX & TX*/
241 DMA_InitStructure
.DMA_Channel
= SD_DMA_Channel_SPI
;//the same channel
242 DMA_InitStructure
.DMA_PeripheralBaseAddr
= (DWORD
)(&(SD_SPI
->DR
));
243 DMA_InitStructure
.DMA_PeripheralDataSize
= DMA_PeripheralDataSize_Byte
;
244 DMA_InitStructure
.DMA_MemoryDataSize
= DMA_MemoryDataSize_Byte
;
245 DMA_InitStructure
.DMA_PeripheralInc
= DMA_PeripheralInc_Disable
;
246 DMA_InitStructure
.DMA_BufferSize
= btr
;
247 DMA_InitStructure
.DMA_Mode
= DMA_Mode_Normal
;
248 DMA_InitStructure
.DMA_Priority
= DMA_Priority_VeryHigh
;
250 DMA_InitStructure
.DMA_FIFOMode
= DMA_FIFOMode_Enable
;
251 DMA_InitStructure
.DMA_FIFOThreshold
= DMA_FIFOThreshold_Full
;
252 DMA_InitStructure
.DMA_MemoryBurst
= DMA_MemoryBurst_Single
;
253 DMA_InitStructure
.DMA_PeripheralBurst
= DMA_PeripheralBurst_Single
;
257 DMA_InitStructure
.DMA_Memory0BaseAddr
= (DWORD
)buff
;
258 DMA_InitStructure
.DMA_DIR
= DMA_DIR_PeripheralToMemory
;
259 DMA_InitStructure
.DMA_MemoryInc
= DMA_MemoryInc_Enable
;
260 DMA_Init(SD_DMA_Stream_SPI_RX
, &DMA_InitStructure
);
261 DMA_InitStructure
.DMA_Memory0BaseAddr
= (DWORD
)rw_workbyte
;
262 DMA_InitStructure
.DMA_DIR
= DMA_DIR_MemoryToPeripheral
;
263 DMA_InitStructure
.DMA_MemoryInc
= DMA_MemoryInc_Disable
;
264 DMA_Init(SD_DMA_Stream_SPI_TX
, &DMA_InitStructure
);
267 #if _FS_READONLY == 0
268 DMA_InitStructure
.DMA_Memory0BaseAddr
= (DWORD
)rw_workbyte
;
269 DMA_InitStructure
.DMA_DIR
= DMA_DIR_PeripheralToMemory
;
270 DMA_InitStructure
.DMA_MemoryInc
= DMA_MemoryInc_Disable
;
271 DMA_Init(SD_DMA_Stream_SPI_RX
, &DMA_InitStructure
);
272 DMA_InitStructure
.DMA_Memory0BaseAddr
= (DWORD
)buff
;
273 DMA_InitStructure
.DMA_DIR
= DMA_DIR_MemoryToPeripheral
;
274 DMA_InitStructure
.DMA_MemoryInc
= DMA_MemoryInc_Enable
;
275 DMA_Init(SD_DMA_Stream_SPI_TX
, &DMA_InitStructure
);
279 /* Enable DMA Channels */
280 DMA_Cmd(SD_DMA_Stream_SPI_RX
, ENABLE
);
281 DMA_Cmd(SD_DMA_Stream_SPI_TX
, ENABLE
);
283 /* Enable SPI TX/RX request */
284 SPI_I2S_DMACmd(SD_SPI
, SPI_I2S_DMAReq_Rx
| SPI_I2S_DMAReq_Tx
, ENABLE
);
286 while (DMA_GetFlagStatus(SD_DMA_Stream_SPI_TX
, SD_DMA_FLAG_SPI_TC_TX
) == RESET
) { ; }
287 while (DMA_GetFlagStatus(SD_DMA_Stream_SPI_RX
, SD_DMA_FLAG_SPI_TC_RX
) == RESET
) { ; }
289 /* Disable DMA Channels */
290 DMA_Cmd(SD_DMA_Stream_SPI_RX
, DISABLE
);
291 DMA_Cmd(SD_DMA_Stream_SPI_TX
, DISABLE
);
293 /* Disable SPI RX/TX request */
294 SPI_I2S_DMACmd(SD_SPI
, SPI_I2S_DMAReq_Rx
| SPI_I2S_DMAReq_Tx
, DISABLE
);
296 #endif /* SD_USE_DMA */
299 /*-----------------------------------------------------------------------*/
300 /* Power Control and interface-initialization (Platform dependent) */
301 /*-----------------------------------------------------------------------*/
306 SPI_InitTypeDef SPI_InitStructure
;
307 GPIO_InitTypeDef GPIO_InitStructure
;
308 volatile BYTE dummyread
;
312 GPIO_InitStructure
.GPIO_Pin
= SD_GPIO_PRESENT_GPIO_PIN
;
313 GPIO_InitStructure
.GPIO_Mode
= GPIO_Mode_IN
;
314 GPIO_InitStructure
.GPIO_Speed
= GPIO_Speed_50MHz
;
315 GPIO_InitStructure
.GPIO_OType
= GPIO_OType_OD
;
316 GPIO_InitStructure
.GPIO_PuPd
= GPIO_PuPd_UP
;
317 GPIO_Init(SD_GPIO_PRESENT_GPIO
, &GPIO_InitStructure
);
319 for (uint32_t Timer
= 25000; Timer
>0;Timer
--); /* Wait for 250ms */
321 /* Configure I/O for Flash Chip select */
322 GPIO_InitStructure
.GPIO_Pin
= SD_GPIO_PIN_CS
;
323 GPIO_InitStructure
.GPIO_Mode
= GPIO_Mode_OUT
;
324 GPIO_InitStructure
.GPIO_OType
= GPIO_OType_PP
;
325 GPIO_InitStructure
.GPIO_PuPd
= GPIO_PuPd_NOPULL
;
326 GPIO_Init(SD_GPIO
, &GPIO_InitStructure
);
328 /* De-select the Card: Chip Select high */
331 /* Configure SPI pins: SCK MISO and MOSI with alternate function push-down */
332 GPIO_InitStructure
.GPIO_Pin
= SD_GPIO_PIN_SCK
| SD_GPIO_PIN_MOSI
|SD_GPIO_PIN_MISO
;
333 GPIO_InitStructure
.GPIO_Mode
= GPIO_Mode_AF
;
334 GPIO_InitStructure
.GPIO_PuPd
= GPIO_PuPd_UP
;
335 GPIO_Init(SD_GPIO
, &GPIO_InitStructure
);
336 GPIO_PinAFConfig(SD_GPIO
,SD_GPIO_PinSource_SCK
,SD_GPIO_AF
);
337 GPIO_PinAFConfig(SD_GPIO
,SD_GPIO_PinSource_MISO
,SD_GPIO_AF
);
338 GPIO_PinAFConfig(SD_GPIO
,SD_GPIO_PinSource_MOSI
,SD_GPIO_AF
);
340 /* SPI configuration */
341 SPI_InitStructure
.SPI_Direction
= SPI_Direction_2Lines_FullDuplex
;
342 SPI_InitStructure
.SPI_Mode
= SPI_Mode_Master
;
343 SPI_InitStructure
.SPI_DataSize
= SPI_DataSize_8b
;
344 SPI_InitStructure
.SPI_CPOL
= SPI_CPOL_Low
;
345 SPI_InitStructure
.SPI_CPHA
= SPI_CPHA_1Edge
;
346 SPI_InitStructure
.SPI_NSS
= SPI_NSS_Soft
;
347 SPI_InitStructure
.SPI_BaudRatePrescaler
= SD_SPI_BaudRatePrescaler
;
348 SPI_InitStructure
.SPI_FirstBit
= SPI_FirstBit_MSB
;
349 SPI_InitStructure
.SPI_CRCPolynomial
= 7;
350 SPI_Init(SD_SPI
, &SPI_InitStructure
);
351 SPI_CalculateCRC(SD_SPI
, DISABLE
);
352 SPI_Cmd(SD_SPI
, ENABLE
);
355 while (SPI_I2S_GetFlagStatus(SD_SPI
, SPI_I2S_FLAG_TXE
) == RESET
) { ; }
356 dummyread
= SPI_I2S_ReceiveData(SD_SPI
);
358 (void) dummyread
; // Discard value - prevents compiler warning
362 void power_off (void)
364 GPIO_InitTypeDef GPIO_InitStructure
;
366 if (!(Stat
& STA_NOINIT
)) {
372 SPI_I2S_DeInit(SD_SPI
);
373 SPI_Cmd(SD_SPI
, DISABLE
);
375 //All SPI-Pins to input with weak internal pull-downs
376 GPIO_InitStructure
.GPIO_Pin
= SD_GPIO_PIN_SCK
| SD_GPIO_PIN_MISO
| SD_GPIO_PIN_MOSI
;
377 GPIO_InitStructure
.GPIO_Mode
= GPIO_Mode_IN
;
378 GPIO_InitStructure
.GPIO_OType
= GPIO_OType_PP
;
379 GPIO_InitStructure
.GPIO_PuPd
= GPIO_PuPd_DOWN
;
380 GPIO_Init(SD_GPIO
, &GPIO_InitStructure
);
384 Stat
|= STA_NOINIT
; /* Set STA_NOINIT */
387 /*-----------------------------------------------------------------------*/
388 /* Receive a data packet from MMC */
389 /*-----------------------------------------------------------------------*/
391 #if defined(SD_USE_DMA) && defined(STM32F4) && !defined(BOOT)
392 uint8_t sd_buff
[512] __DMA
;
396 BOOL
rcvr_datablock (
397 BYTE
*buff
, /* Data buffer to store received data */
398 UINT btr
/* Byte count (must be multiple of 4) */
405 do { /* Wait for data packet in timeout of 100ms */
407 } while ((token
== 0xFF) && Timer1
);
409 TRACE_SD_CARD_EVENT(1, sd_rcvr_datablock
, ((uint32_t)(Timer1
) << 24) + ((uint32_t)(btr
) << 8) + token
);
411 return FALSE
; /* If not valid data token, return with error */
414 #if defined(SD_USE_DMA) && defined(STM32F4) && !defined(BOOT)
415 stm32_dma_transfer(TRUE
, sd_buff
, btr
);
416 memcpy(buff
, sd_buff
, btr
);
417 #elif defined(SD_USE_DMA)
418 stm32_dma_transfer(TRUE
, buff
, btr
);
420 do { /* Receive the data block into buffer */
426 #endif /* SD_USE_DMA */
428 rcvr_spi(); /* Discard CRC */
431 return TRUE
; /* Return with success */
436 /*-----------------------------------------------------------------------*/
437 /* Send a data packet to MMC */
438 /*-----------------------------------------------------------------------*/
440 #define DATA_RESPONSE_TIMEOUT 10
443 BOOL
xmit_datablock (
444 const BYTE
*buff
, /* 512 byte data block to be transmitted */
445 BYTE token
/* Data/Stop token */
453 if (wait_ready() != 0xFF) {
454 TRACE_SD_CARD_EVENT(1, sd_xmit_datablock_wait_ready
, token
);
459 xmit_spi(token
); /* transmit data token */
460 if (token
!= 0xFD) { /* Is data token */
462 #if defined(SD_USE_DMA) && defined(STM32F4) && !defined(BOOT)
463 memcpy(sd_buff
, buff
, 512);
464 stm32_dma_transfer(FALSE
, sd_buff
, 512);
465 #elif defined(SD_USE_DMA)
466 stm32_dma_transfer(FALSE
, buff
, 512);
469 do { /* transmit the 512 byte data block to MMC */
473 #endif /* SD_USE_DMA */
475 xmit_spi(0xFF); /* CRC (Dummy) */
479 Despite what the SD card standard says, the reality is that (at least for some SD cards)
480 the Data Response byte does not come immediately after the last byte of data.
482 This delay only happens very rarely, but it does happen. Typical response delay is some 10ms
484 Timer2
= DATA_RESPONSE_TIMEOUT
;
486 resp
= rcvr_spi(); /* Receive data response */
487 if ((resp
& 0x1F) == 0x05) {
488 TRACE_SD_CARD_EVENT((Timer2
!= DATA_RESPONSE_TIMEOUT
), sd_xmit_datablock_rcvr_spi
, ((uint32_t)(Timer2
) << 16) + ((uint32_t)(resp
) << 8) + token
);
492 TRACE_SD_CARD_EVENT(1, sd_xmit_datablock_rcvr_spi
, ((uint32_t)(Timer2
) << 16) + ((uint32_t)(resp
) << 8) + token
);
497 TRACE_SD_CARD_EVENT(1, sd_xmit_datablock_rcvr_spi
, ((uint32_t)(Timer2
) << 16) + ((uint32_t)(resp
) << 8) + token
);
504 /*-----------------------------------------------------------------------*/
505 /* Send a command packet to MMC */
506 /*-----------------------------------------------------------------------*/
510 BYTE cmd
, /* Command byte */
511 DWORD arg
/* Argument */
517 if (cmd
& 0x80) { /* ACMD<n> is the command sequence of CMD55-CMD<n> */
519 res
= send_cmd(CMD55
, 0);
520 if (res
> 1) return res
;
523 /* Select the card and wait for ready */
525 if (wait_ready() != 0xFF) {
526 TRACE_SD_CARD_EVENT(1, sd_send_cmd_wait_ready
, cmd
);
531 /* Send command packet */
532 xmit_spi(cmd
); /* Start + Command index */
533 xmit_spi((BYTE
)(arg
>> 24)); /* Argument[31..24] */
534 xmit_spi((BYTE
)(arg
>> 16)); /* Argument[23..16] */
535 xmit_spi((BYTE
)(arg
>> 8)); /* Argument[15..8] */
536 xmit_spi((BYTE
)arg
); /* Argument[7..0] */
537 n
= 0x01; /* Dummy CRC + Stop */
538 if (cmd
== CMD0
) n
= 0x95; /* Valid CRC for CMD0(0) */
539 if (cmd
== CMD8
) n
= 0x87; /* Valid CRC for CMD8(0x1AA) */
542 /* Receive command response */
543 if (cmd
== CMD12
) rcvr_spi(); /* Skip a stuff byte when stop reading */
545 n
= 10; /* Wait for a valid response in timeout of 10 attempts */
548 } while ((res
& 0x80) && --n
);
550 TRACE_SD_CARD_EVENT((res
> 1), sd_send_cmd_rcvr_spi
, ((uint32_t)(n
) << 16) + ((uint32_t)(res
) << 8) + cmd
);
552 return res
; /* Return with the response value */
557 /*--------------------------------------------------------------------------
561 ---------------------------------------------------------------------------*/
564 /*-----------------------------------------------------------------------*/
565 /* Initialize Disk Drive */
566 /*-----------------------------------------------------------------------*/
568 DSTATUS
disk_initialize (
569 BYTE drv
/* Physical drive number (0) */
572 BYTE n
, cmd
, ty
, ocr
[4];
574 if (drv
) return STA_NOINIT
; /* Supports only single drive */
575 if (Stat
& STA_NODISK
) return Stat
; /* No card in the socket */
577 power_on(); /* Force socket power on and initialize interface */
578 interface_speed(INTERFACE_SLOW
);
579 for (n
= 10; n
; n
--) rcvr_spi(); /* 80 dummy clocks */
582 if (send_cmd(CMD0
, 0) == 1) { /* Enter Idle state */
583 Timer1
= 100; /* Initialization timeout of 1000 milliseconds */
584 if (send_cmd(CMD8
, 0x1AA) == 1) { /* SDHC */
585 for (n
= 0; n
< 4; n
++) ocr
[n
] = rcvr_spi(); /* Get trailing return value of R7 response */
586 if (ocr
[2] == 0x01 && ocr
[3] == 0xAA) { /* The card can work at VDD range of 2.7-3.6V */
587 while (Timer1
&& send_cmd(ACMD41
, 1UL << 30)); /* Wait for leaving idle state (ACMD41 with HCS bit) */
588 if (Timer1
&& send_cmd(CMD58
, 0) == 0) { /* Check CCS bit in the OCR */
589 for (n
= 0; n
< 4; n
++) ocr
[n
] = rcvr_spi();
590 ty
= (ocr
[0] & 0x40) ? CT_SD2
| CT_BLOCK
: CT_SD2
;
593 } else { /* SDSC or MMC */
594 if (send_cmd(ACMD41
, 0) <= 1) {
595 ty
= CT_SD1
; cmd
= ACMD41
; /* SDSC */
597 ty
= CT_MMC
; cmd
= CMD1
; /* MMC */
599 while (Timer1
&& send_cmd(cmd
, 0)); /* Wait for leaving idle state */
600 if (!Timer1
|| send_cmd(CMD16
, 512) != 0) /* Set R/W block length to 512 */
607 if (ty
) { /* Initialization succeeded */
608 Stat
&= ~STA_NOINIT
; /* Clear STA_NOINIT */
609 interface_speed(INTERFACE_FAST
);
611 else { /* Initialization failed */
620 /*-----------------------------------------------------------------------*/
621 /* Get Disk Status */
622 /*-----------------------------------------------------------------------*/
623 DSTATUS
disk_status (
624 BYTE drv
/* Physical drive number (0) */
627 if (drv
) return STA_NOINIT
; /* Supports only single drive */
632 #if defined(STM32F4) && !defined(BOOT)
633 DWORD scratch
[BLOCK_SIZE
/ 4] __DMA
;
636 /*-----------------------------------------------------------------------*/
638 /*-----------------------------------------------------------------------*/
640 int8_t SD_ReadSectors(uint8_t * buff
, uint32_t sector
, uint32_t count
)
642 #if defined(STM32F4) && !defined(BOOT)
643 if ((DWORD
)buff
< 0x20000000 || ((DWORD
)buff
& 3)) {
644 TRACE("disk_read bad alignment (%p)", buff
);
646 int8_t res
= SD_ReadSectors((BYTE
*)scratch
, sector
++, 1);
652 memcpy(buff
, scratch
, BLOCK_SIZE
);
661 if (!(CardType
& CT_BLOCK
)) sector
*= 512; /* Convert to byte address if needed */
663 if (count
== 1) { /* Single block read */
664 if (send_cmd(CMD17
, sector
) == 0) { /* READ_SINGLE_BLOCK */
665 if (rcvr_datablock(buff
, 512)) {
673 else { /* Multiple block read */
674 if (send_cmd(CMD18
, sector
) == 0) { /* READ_MULTIPLE_BLOCK */
676 if (!rcvr_datablock(buff
, 512)) {
681 send_cmd(CMD12
, 0); /* STOP_TRANSMISSION */
688 TRACE_SD_CARD_EVENT((count
!= 0), sd_SD_ReadSectors
, (count
<< 24) + ((sector
/((CardType
& CT_BLOCK
) ? 1 : 512)) & 0x00FFFFFF));
690 return count
? -1 : 0;
694 BYTE drv
, /* Physical drive number (0) */
695 BYTE
*buff
, /* Pointer to the data buffer to store read data */
696 DWORD sector
, /* Start sector number (LBA) */
697 UINT count
/* Sector count (1..255) */
700 if (drv
|| !count
) return RES_PARERR
;
701 if (Stat
& STA_NOINIT
) return RES_NOTRDY
;
702 int8_t res
= SD_ReadSectors(buff
, sector
, count
);
703 TRACE_SD_CARD_EVENT((res
!= 0), sd_disk_read
, (count
<< 24) + (sector
& 0x00FFFFFF));
704 return (res
!= 0) ? RES_ERROR
: RES_OK
;
709 /*-----------------------------------------------------------------------*/
710 /* Write Sector(s) */
711 /*-----------------------------------------------------------------------*/
713 int8_t SD_WriteSectors(const uint8_t * buff
, uint32_t sector
, uint32_t count
)
715 #if defined(STM32F4) && !defined(BOOT)
716 if ((DWORD
)buff
< 0x20000000 || ((DWORD
)buff
& 3)) {
717 TRACE("disk_write bad alignment (%p)", buff
);
719 memcpy(scratch
, buff
, BLOCK_SIZE
);
721 int8_t res
= SD_WriteSectors((const uint8_t *)scratch
, sector
++, 1);
734 if (!(CardType
& CT_BLOCK
)) sector
*= 512; /* Convert to byte address if needed */
736 if (count
== 1) { /* Single block write */
737 if (send_cmd(CMD24
, sector
) == 0) { /* WRITE_BLOCK */
738 if (xmit_datablock(buff
, 0xFE)) {
746 else { /* Multiple block write */
747 if (CardType
& CT_SDC
) send_cmd(ACMD23
, count
);
748 if (send_cmd(CMD25
, sector
) == 0) { /* WRITE_MULTIPLE_BLOCK */
750 if (!xmit_datablock(buff
, 0xFC)) break;
753 if (!xmit_datablock(0, 0xFD)) /* STOP_TRAN token */
761 TRACE_SD_CARD_EVENT((count
!= 0), sd_SD_WriteSectors
, (count
<< 24) + ((sector
/((CardType
& CT_BLOCK
) ? 1 : 512)) & 0x00FFFFFF));
763 return count
? -1 : 0;
767 BYTE drv
, /* Physical drive number (0) */
768 const BYTE
*buff
, /* Pointer to the data to be written */
769 DWORD sector
, /* Start sector number (LBA) */
770 UINT count
/* Sector count (1..255) */
773 if (drv
|| !count
) return RES_PARERR
;
774 if (Stat
& STA_NOINIT
) return RES_NOTRDY
;
775 if (Stat
& STA_PROTECT
) return RES_WRPRT
;
776 int8_t res
= SD_WriteSectors(buff
, sector
, count
);
777 TRACE_SD_CARD_EVENT((res
!= 0), sd_disk_write
, (count
<< 24) + (sector
& 0x00FFFFFF));
778 return (res
!= 0) ? RES_ERROR
: RES_OK
;
782 /*-----------------------------------------------------------------------*/
783 /* Miscellaneous Functions */
784 /*-----------------------------------------------------------------------*/
787 BYTE drv
, /* Physical drive number (0) */
788 BYTE ctrl
, /* Control code */
789 void *buff
/* Buffer to send/receive control data */
793 BYTE n
, csd
[16], *ptr
= (BYTE
*)buff
;
796 if (drv
) return RES_PARERR
;
800 if (ctrl
== CTRL_POWER
) {
802 case 0: /* Sub control code == 0 (POWER_OFF) */
804 power_off(); /* Power off */
807 case 1: /* Sub control code == 1 (POWER_ON) */
808 power_on(); /* Power on */
811 case 2: /* Sub control code == 2 (POWER_GET) */
812 *(ptr
+1) = (BYTE
)chk_power();
820 if (Stat
& STA_NOINIT
) {
825 case CTRL_SYNC
: /* Make sure that no pending write process */
827 if (wait_ready() == 0xFF) {
831 TRACE_SD_CARD_EVENT(1, sd_disk_ioctl_CTRL_SYNC
, 0);
835 case GET_SECTOR_COUNT
: /* Get number of sectors on the disk (DWORD) */
836 if ((send_cmd(CMD9
, 0) == 0) && rcvr_datablock(csd
, 16)) {
837 if ((csd
[0] >> 6) == 1) { /* SDC version 2.00 */
838 csize
= csd
[9] + ((WORD
)csd
[8] << 8) + 1;
839 *(DWORD
*)buff
= (DWORD
)csize
<< 10;
841 else { /* SDC version 1.XX or MMC*/
842 n
= (csd
[5] & 15) + ((csd
[10] & 128) >> 7) + ((csd
[9] & 3) << 1) + 2;
843 csize
= (csd
[8] >> 6) + ((WORD
)csd
[7] << 2) + ((WORD
)(csd
[6] & 3) << 10) + 1;
844 *(DWORD
*)buff
= (DWORD
)csize
<< (n
- 9);
849 TRACE_SD_CARD_EVENT(1, sd_disk_ioctl_GET_SECTOR_COUNT
, 0);
853 case GET_SECTOR_SIZE
: /* Get R/W sector size (WORD) */
858 case GET_BLOCK_SIZE
: /* Get erase block size in unit of sector (DWORD) */
859 if (CardType
& CT_SD2
) { /* SDC version 2.00 */
860 if (send_cmd(ACMD13
, 0) == 0) { /* Read SD status */
862 if (rcvr_datablock(csd
, 16)) { /* Read partial block */
863 for (n
= 64 - 16; n
; n
--) rcvr_spi(); /* Purge trailing data */
864 *(DWORD
*)buff
= 16UL << (csd
[10] >> 4);
868 } else { /* SDC version 1.XX or MMC */
869 if ((send_cmd(CMD9
, 0) == 0) && rcvr_datablock(csd
, 16)) { /* Read CSD */
870 if (CardType
& CT_SD1
) { /* SDC version 1.XX */
871 *(DWORD
*)buff
= (((csd
[10] & 63) << 1) + ((WORD
)(csd
[11] & 128) >> 7) + 1) << ((csd
[13] >> 6) - 1);
873 *(DWORD
*)buff
= ((WORD
)((csd
[10] & 124) >> 2) + 1) * (((csd
[11] & 3) << 3) + ((csd
[11] & 224) >> 5) + 1);
880 case MMC_GET_TYPE
: /* Get card type flags (1 byte) */
885 case MMC_GET_CSD
: /* Receive CSD as a data block (16 bytes) */
886 if (send_cmd(CMD9
, 0) == 0 /* READ_CSD */
887 && rcvr_datablock(ptr
, 16)) {
891 TRACE_SD_CARD_EVENT(1, sd_disk_ioctl_MMC_GET_CSD
, 0);
895 case MMC_GET_CID
: /* Receive CID as a data block (16 bytes) */
896 if (send_cmd(CMD10
, 0) == 0 /* READ_CID */
897 && rcvr_datablock(ptr
, 16)) {
901 TRACE_SD_CARD_EVENT(1, sd_disk_ioctl_MMC_GET_CID
, 0);
905 case MMC_GET_OCR
: /* Receive OCR as an R3 resp (4 bytes) */
906 if (send_cmd(CMD58
, 0) == 0) { /* READ_OCR */
907 for (n
= 4; n
; n
--) *ptr
++ = rcvr_spi();
911 TRACE_SD_CARD_EVENT(1, sd_disk_ioctl_MMC_GET_OCR
, 0);
915 case MMC_GET_SDSTAT
: /* Receive SD status as a data block (64 bytes) */
916 if (send_cmd(ACMD13
, 0) == 0) { /* SD_STATUS */
918 if (rcvr_datablock(ptr
, 64)) {
922 TRACE_SD_CARD_EVENT(1, sd_disk_ioctl_MMC_GET_SDSTAT_1
, 0);
926 TRACE_SD_CARD_EVENT(1, sd_disk_ioctl_MMC_GET_SDSTAT_2
, 0);
941 /*-----------------------------------------------------------------------*/
942 /* Device Timer Interrupt Procedure (Platform dependent) */
943 /*-----------------------------------------------------------------------*/
944 /* This function must be called in period of 10ms */
953 n
= Timer1
; /* 100Hz decrement timers */
959 pv
= socket_is_empty() | socket_is_write_protected(); /* Sample socket switch */
961 if (ns
== pv
) { /* Have contacts stabled? */
964 if (pv
& socket_state_mask_wp
) /* WP is H (write protected) */
966 else /* WP is L (write enabled) */
969 if (pv
& socket_state_mask_cp
) /* INS = H (Socket empty) */
970 s
|= (STA_NODISK
| STA_NOINIT
);
971 else /* INS = L (Card inserted) */
978 // TODO everything here should not be in the driver layer ...
981 #if defined(LOG_TELEMETRY)
982 FIL g_telemetryFile
= {};
988 if (f_mount(&g_FATFS_Obj
, "", 1) == FR_OK
) {
993 // TODO shouldn't be there!
998 ioMutex
= CoCreateMutex();
999 if (ioMutex
>= CFG_MAX_MUTEX
) {
1009 if (f_mount(&g_FATFS_Obj
, "", 1) == FR_OK
) {
1010 // call sdGetFreeSectors() now because f_getfree() takes a long time first time it's called
1013 #if defined(LOG_TELEMETRY)
1014 f_open(&g_telemetryFile
, LOGS_PATH
"/telemetry.log", FA_OPEN_ALWAYS
| FA_WRITE
);
1015 if (f_size(&g_telemetryFile
) > 0) {
1016 f_lseek(&g_telemetryFile
, f_size(&g_telemetryFile
)); // append
1025 audioQueue
.stopSD();
1026 #if defined(LOG_TELEMETRY)
1027 f_close(&g_telemetryFile
);
1029 f_mount(nullptr, "", 0); // unmount SD
1034 uint32_t sdMounted()
1036 return g_FATFS_Obj
.fs_type
!= 0;
1041 return (CardType
& CT_BLOCK
);
1044 uint32_t sdGetSpeed()