1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
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
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
|
//*****************************************************************************
//
// usbdsdcard.c - Routines supplied for use by the mass storage class device
// class.
//
// Copyright (c) 2012-2014 Texas Instruments Incorporated. All rights reserved.
// Software License Agreement
//
// Texas Instruments (TI) is supplying this software for use solely and
// exclusively on TI's microcontroller products. The software is owned by
// TI and/or its suppliers, and is protected under applicable copyright
// laws. You may not combine this software with "viral" open-source
// software in order to form a larger program.
//
// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
// DAMAGES, FOR ANY REASON WHATSOEVER.
//
// This is part of revision 2.1.0.12573 of the DK-TM4C123G Firmware Package.
//
//*****************************************************************************
#include <stdint.h>
#include <stdbool.h>
#include "inc/hw_ints.h"
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "driverlib/debug.h"
#include "driverlib/sysctl.h"
#include "driverlib/gpio.h"
#include "driverlib/interrupt.h"
#include "driverlib/rom.h"
#include "driverlib/systick.h"
#include "grlib/grlib.h"
#include "usblib/usblib.h"
#include "usblib/usb-ids.h"
#include "usblib/device/usbdevice.h"
#include "usblib/device/usbdmsc.h"
#include "usb_msc_structs.h"
#include "third_party/fatfs/src/diskio.h"
#include "drivers/cfal96x64x16.h"
#define SDCARD_PRESENT 0x00000001
#define SDCARD_IN_USE 0x00000002
struct
{
uint32_t ui32Flags;
}
g_sDriveInformation;
//*****************************************************************************
//
// This function opens the drive number and prepares it for use by the Mass
// storage class device.
//
// /param ui32Drive is the driver number to open.
//
// This function is used to initialize and open the physical drive number
// associated with the parameter /e ui32Drive. The function will return zero if
// the drive could not be opened for some reason. In the case of removable
// device like an SD card this function should return zero if the SD card is
// not present.
//
// /return Returns a pointer to data that should be passed to other APIs or it
// will return 0 if no drive was found.
//
//*****************************************************************************
void *
USBDMSCStorageOpen(uint_fast32_t ui32Drive)
{
uint_fast32_t ui32Temp;
ASSERT(ui32Drive == 0);
//
// Return if already in use.
//
if(g_sDriveInformation.ui32Flags & SDCARD_IN_USE)
{
return(0);
}
//
// Initialize the drive if it is present.
//
ui32Temp = disk_initialize(0);
if(ui32Temp == RES_OK)
{
//
// Card is present and in use.
//
g_sDriveInformation.ui32Flags = SDCARD_PRESENT | SDCARD_IN_USE;
}
else if(ui32Temp == STA_NODISK)
{
//
// Allocate the card but it is not present.
//
g_sDriveInformation.ui32Flags = SDCARD_IN_USE;
}
else
{
return(0);
}
return((void *)&g_sDriveInformation);
}
//*****************************************************************************
//
// This function close the drive number in use by the mass storage class device.
//
// /param pvDrive is the pointer that was returned from a call to
// USBDMSCStorageOpen().
//
// This function is used to close the physical drive number associated with the
// parameter /e pvDrive. This function will return 0 if the drive was closed
// successfully and any other value will indicate a failure.
//
// /return Returns 0 if the drive was successfully closed or non-zero for a
// failure.
//
//*****************************************************************************
void
USBDMSCStorageClose(void * pvDrive)
{
uint_fast8_t ui8Power;
ASSERT(pvDrive != 0);
//
// Clear all flags.
//
g_sDriveInformation.ui32Flags = 0;
//
// Power up the card.
//
ui8Power = 0;
//
// Turn off the power to the card.
//
disk_ioctl(0, CTRL_POWER, &ui8Power);
}
//*****************************************************************************
//
// This function will read a block from a device opened by the
// USBDMSCStorageOpen() call.
//
// /param pvDrive is the pointer that was returned from a call to
// USBDMSCStorageOpen().
// /param pui8Data is the buffer that data will be written into.
// /param ui32NumBlocks is the number of blocks to read.
//
// This function is use to read blocks from a physical device and return them
// in the /e pui8Data buffer. The data area pointed to by /e pui8Data should be
// at least /e ui32NumBlocks * Block Size bytes to prevent overwriting data.
//
// /return Returns the number of bytes that were read from the device.
//
//*****************************************************************************
uint32_t USBDMSCStorageRead(void * pvDrive,
uint8_t *pui8Data,
uint_fast32_t ui32Sector,
uint_fast32_t ui32NumBlocks)
{
ASSERT(pvDrive != 0);
if(disk_read (0, pui8Data, ui32Sector, ui32NumBlocks) == RES_OK)
{
// TODO remove fixed 512
return(ui32NumBlocks * 512);
}
return(0);
}
//*****************************************************************************
//
// This function will write a block to a device opened by the
// USBDMSCStorageOpen() call.
//
// /param pvDrive is the pointer that was returned from a call to
// USBDMSCStorageOpen().
// /param pui8Data is the buffer that data will be used for writing.
// /param ui32NumBlocks is the number of blocks to write.
//
// This function is use to write blocks to a physical device from the buffer
// pointed to by the /e pui8Data buffer. If the number of blocks is greater than
// one then the block address will increment and write to the next block until
// /e ui32NumBlocks * Block Size bytes have been written.
//
// /return Returns the number of bytes that were written to the device.
//
//*****************************************************************************
uint32_t USBDMSCStorageWrite(void * pvDrive,
uint8_t *pui8Data,
uint_fast32_t ui32Sector,
uint_fast32_t ui32NumBlocks)
{
ASSERT(pvDrive != 0);
if(disk_write(0, pui8Data, ui32Sector, ui32NumBlocks) == RES_OK)
{
return(ui32NumBlocks * 512);
}
return(0);
}
//*****************************************************************************
//
// This function will return the number of blocks present on a device.
//
// /param pvDrive is the pointer that was returned from a call to
// USBDMSCStorageOpen().
//
// This function is used to return the total number of blocks on a physical
// device based on the /e pvDrive parameter.
//
// /return Returns the number of blocks that are present in a device.
//
//*****************************************************************************
uint32_t
USBDMSCStorageNumBlocks(void * pvDrive)
{
uint_fast32_t ui32SectorCount;
//
// Read the number of sectors.
//
disk_ioctl(0, GET_SECTOR_COUNT, &ui32SectorCount);
return(ui32SectorCount);
}
//*****************************************************************************
//
// This function will return the current status of a device.
//
// /param pvDrive is the pointer that was returned from a call to
// USBDMSCStorageOpen().
//
// This function is used to return the current status of the device indicated by
// the /e pvDrive parameter. This can be used to see if the device is busy,
// or if it is present.
//
// /return Returns the size in bytes of blocks that in a device.
//
//*****************************************************************************
#define USBDMSC_IDLE 0x00000000
#define USBDMSC_NOT_PRESENT 0x00000001
uint32_t USBDMSCStorageStatus(void * pvDrive);
|