1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
24
25
26
27
28
29
30
36
37
38
39
40
41
46
47
48
49
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
91
92
97
98
99
100
104
105
106
107
113
114
115
116
117
120
121
126
127
128
129
130
131
136
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
221
222
223
224
225
226
227
234
235
236
237
238
239
240
241
242
243
244
245
250
257
264
270
272
273
274
275
276
277
278
279
280
285
293
294
299
/* ... */
#include "ff_gen_drv.h"
#include "sd_diskio_dma_rtos.h"
Includes
#define QUEUE_SIZE (uint32_t) 10
#define READ_CPLT_MSG (uint32_t) 1
#define WRITE_CPLT_MSG (uint32_t) 2
/* ... */
#define SD_TIMEOUT 30 * 1000
#define SD_DEFAULT_BLOCK_SIZE 512
5 defines
/* ... */
Private define
static volatile DSTATUS Stat = STA_NOINIT;
static osMessageQId SDQueueID;Private variables
static DSTATUS SD_CheckStatus(BYTE lun);
DSTATUS SD_initialize (BYTE);
DSTATUS SD_status (BYTE);
DRESULT SD_read (BYTE, BYTE*, DWORD, UINT);
#if _USE_WRITE == 1
DRESULT SD_write (BYTE, const BYTE*, DWORD, UINT);
#endif
#if _USE_IOCTL == 1
DRESULT SD_ioctl (BYTE, BYTE, void*);
#endif
const Diskio_drvTypeDef SD_Driver =
{
SD_initialize,
SD_status,
SD_read,
#if _USE_WRITE == 1
SD_write,
#endif
#if _USE_IOCTL == 1
SD_ioctl,
#endif
...};
Private function prototypes
static DSTATUS SD_CheckStatus(BYTE lun)
{
Stat = STA_NOINIT;
if(BSP_SD_GetCardState() == MSD_OK)
{
Stat &= ~STA_NOINIT;
}if (BSP_SD_GetCardState() == MSD_OK) { ... }
return Stat;
}{ ... }
/* ... */
DSTATUS SD_initialize(BYTE lun)
{
Stat = STA_NOINIT;
/* ... */
if(osKernelRunning())
{
#if !defined(DISABLE_SD_INIT)
if(BSP_SD_Init() == MSD_OK)
{
Stat = SD_CheckStatus(lun);
}if (BSP_SD_Init() == MSD_OK) { ... }
/* ... */
#else
Stat = SD_CheckStatus(lun);
#endif
/* ... */
if (Stat != STA_NOINIT)
{
osMessageQDef(SD_Queue, QUEUE_SIZE, uint16_t);
SDQueueID = osMessageCreate (osMessageQ(SD_Queue), NULL);
}if (Stat != STA_NOINIT) { ... }
}if (osKernelRunning()) { ... }
return Stat;
}{ ... }
/* ... */
DSTATUS SD_status(BYTE lun)
{
return SD_CheckStatus(lun);
}{ ... }
/* ... */
DRESULT SD_read(BYTE lun, BYTE *buff, DWORD sector, UINT count)
{
DRESULT res = RES_ERROR;
osEvent event;
uint32_t timer;
if(BSP_SD_ReadBlocks_DMA((uint32_t*)buff,
(uint32_t) (sector),
count) == MSD_OK)
{
event = osMessageGet(SDQueueID, SD_TIMEOUT);
if (event.status == osEventMessage)
{
if (event.value.v == READ_CPLT_MSG)
{
timer = osKernelSysTick() + SD_TIMEOUT;
while(timer > osKernelSysTick())
{
if (BSP_SD_GetCardState() == SD_TRANSFER_OK)
{
res = RES_OK;
break;
}if (BSP_SD_GetCardState() == SD_TRANSFER_OK) { ... }
}while (timer > osKernelSysTick()) { ... }
}if (event.value.v == READ_CPLT_MSG) { ... }
}if (event.status == osEventMessage) { ... }
}if (BSP_SD_ReadBlocks_DMA((uint32_t*)buff, (uint32_t) (sector), count) == MSD_OK) { ... }
return res;
}{ ... }
/* ... */
#if _USE_WRITE == 1
DRESULT SD_write(BYTE lun, const BYTE *buff, DWORD sector, UINT count)
{
osEvent event;
DRESULT res = RES_ERROR;
uint32_t timer;
if(BSP_SD_WriteBlocks_DMA((uint32_t*)buff,
(uint32_t) (sector),
count) == MSD_OK)
{
event = osMessageGet(SDQueueID, SD_TIMEOUT);
if (event.status == osEventMessage)
{
if (event.value.v == WRITE_CPLT_MSG)
{
timer = osKernelSysTick() + SD_TIMEOUT;
while(timer > osKernelSysTick())
{
if (BSP_SD_GetCardState() == SD_TRANSFER_OK)
{
res = RES_OK;
break;
}if (BSP_SD_GetCardState() == SD_TRANSFER_OK) { ... }
}while (timer > osKernelSysTick()) { ... }
}if (event.value.v == WRITE_CPLT_MSG) { ... }
}if (event.status == osEventMessage) { ... }
}if (BSP_SD_WriteBlocks_DMA((uint32_t*)buff, (uint32_t) (sector), count) == MSD_OK) { ... }
return res;
}{ ... }
/* ... */#endif
/* ... */
#if _USE_IOCTL == 1
DRESULT SD_ioctl(BYTE lun, BYTE cmd, void *buff)
{
DRESULT res = RES_ERROR;
BSP_SD_CardInfo CardInfo;
if (Stat & STA_NOINIT) return RES_NOTRDY;
switch (cmd)
{
case CTRL_SYNC :
res = RES_OK;
break;
case CTRL_SYNC :
case GET_SECTOR_COUNT :
BSP_SD_GetCardInfo(&CardInfo);
*(DWORD*)buff = CardInfo.LogBlockNbr;
res = RES_OK;
break;
case GET_SECTOR_COUNT :
case GET_SECTOR_SIZE :
BSP_SD_GetCardInfo(&CardInfo);
*(WORD*)buff = CardInfo.LogBlockSize;
res = RES_OK;
break;
case GET_SECTOR_SIZE :
case GET_BLOCK_SIZE :
BSP_SD_GetCardInfo(&CardInfo);
*(DWORD*)buff = CardInfo.LogBlockSize / SD_DEFAULT_BLOCK_SIZE;
res = RES_OK;
break;
case GET_BLOCK_SIZE :
default:
res = RES_PARERR;default
}switch (cmd) { ... }
return res;
}{ ... }
/* ... */#endif
/* ... */
void BSP_SD_WriteCpltCallback(void)
{
/* ... */
osMessagePut(SDQueueID, WRITE_CPLT_MSG, osWaitForever);
}{ ... }
/* ... */
void BSP_SD_ReadCpltCallback(void)
{
/* ... */
osMessagePut(SDQueueID, READ_CPLT_MSG, osWaitForever);
}{ ... }