488 lines
22 KiB
C
488 lines
22 KiB
C
// DOM-IGNORE-BEGIN
|
|
/*******************************************************************************
|
|
Copyright 2015 Microchip Technology Inc. (www.microchip.com)
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
|
|
To request to license the code under the MLA license (www.microchip.com/mla_license),
|
|
please contact mla_licensing@microchip.com
|
|
*******************************************************************************/
|
|
//DOM-IGNORE-END
|
|
|
|
#ifndef SDMMC_H
|
|
#define SDMMC_H
|
|
|
|
#include "FileSystem_config.h"
|
|
//#include "system.h"
|
|
#include <stdint.h>
|
|
#include <stdbool.h>
|
|
|
|
#include "fileio_media.h"
|
|
|
|
/*****************************************************************************/
|
|
/* Custom structures and definitions */
|
|
/*****************************************************************************/
|
|
//Definition for a structure used when calling either FILEIO_SD_AsyncReadTasks()
|
|
//function, or the FILEIO_SD_AsyncWriteTasks() function.
|
|
typedef struct
|
|
{
|
|
uint16_t wNumBytes; //Number of bytes to attempt to read or write in the next call to MDD_SDSPI_AsyncReadTasks() or MDD_SDSPI_AsyncWriteTasks. May be updated between calls to the handler.
|
|
uint32_t dwBytesRemaining; //Should be initialized to the total number of uint8_ts that you wish to read or write. This value is allowed to be greater than a single block size of the media.
|
|
uint8_t* pBuffer; //Pointer to where the read/written uint8_ts should be copied to/from. May be updated between calls to the handler function.
|
|
uint32_t dwAddress; //Starting block address to read or to write to on the media. Should only get initialized, do not modify after that.
|
|
uint8_t bStateVariable; //State machine variable. Should get initialized to ASYNC_READ_QUEUED or ASYNC_WRITE_QUEUED to start an operation. After that, do not modify until the read or write is complete.
|
|
}FILEIO_SD_ASYNC_IO;
|
|
|
|
//Response codes for the FILEIO_SD_AsyncReadTasks() function.
|
|
#define FILEIO_SD_ASYNC_READ_COMPLETE 0x00
|
|
#define FILEIO_SD_ASYNC_READ_BUSY 0x01
|
|
#define FILEIO_SD_ASYNC_READ_NEW_PACKET_READY 0x02
|
|
#define FILEIO_SD_ASYNC_READ_ERROR 0xFF
|
|
|
|
//FILEIO_SD_AsyncReadTasks() state machine variable values. These are used internally to sd_spi.c.
|
|
#define FILEIO_SD_ASYNC_READ_COMPLETE 0x00
|
|
#define FILEIO_SD_ASYNC_READ_QUEUED 0x01 //Initialize to this to start a read sequence
|
|
#define FILEIO_SD_ASYNC_READ_WAIT_START_TOKEN 0x03
|
|
#define FILEIO_SD_ASYNC_READ_NEW_PACKET_READY 0x02
|
|
#define FILEIO_SD_ASYNC_READ_ABORT 0xFE
|
|
#define FILEIO_SD_ASYNC_READ_ERROR 0xFF
|
|
|
|
//Possible return values when calling FILEIO_SD_AsyncWriteTasks()
|
|
#define FILEIO_SD_ASYNC_WRITE_COMPLETE 0x00
|
|
#define FILEIO_SD_ASYNC_WRITE_SEND_PACKET 0x02
|
|
#define FILEIO_SD_ASYNC_WRITE_BUSY 0x03
|
|
#define FILEIO_SD_ASYNC_WRITE_ERROR 0xFF
|
|
|
|
//FILEIO_SD_AsyncWriteTasks() state machine variable values. These are used internally to sd_spi.c.
|
|
#define FILEIO_SD_ASYNC_WRITE_COMPLETE 0x00
|
|
#define FILEIO_SD_ASYNC_WRITE_QUEUED 0x01 //Initialize to this to start a write sequence
|
|
#define FILEIO_SD_ASYNC_WRITE_TRANSMIT_PACKET 0x02
|
|
#define FILEIO_SD_ASYNC_WRITE_MEDIA_BUSY 0x03
|
|
#define FILEIO_SD_ASYNC_STOP_TOKEN_SENT_WAIT_BUSY 0x04
|
|
#define FILEIO_SD_ASYNC_WRITE_ABORT 0xFE
|
|
#define FILEIO_SD_ASYNC_WRITE_ERROR 0xFF
|
|
|
|
|
|
/*****************************************************************************/
|
|
/* Function pointer types */
|
|
/*****************************************************************************/
|
|
|
|
/*************************************************************************************
|
|
Function:
|
|
typedef void (*FILEIO_SD_CSSet)(uint8_t value)
|
|
|
|
Summary:
|
|
Prototype for a user-implemented function to set or
|
|
clear the SPI's chip select pin.
|
|
|
|
Input:
|
|
value - The value of the chip select pin (1 or 0)
|
|
|
|
Return Values:
|
|
None
|
|
|
|
Description:
|
|
Most functions in this driver require the user to implement the functions
|
|
that comprise a FILEIO_SD_DRIVE_CONFIG structure. This function pointer
|
|
definition describes a function in this structure that will set/clear the
|
|
chip select pin.
|
|
|
|
Remarks:
|
|
None
|
|
***********************************************************************************/
|
|
typedef void (*FILEIO_SD_CSSet)(uint8_t value);
|
|
|
|
/*************************************************************************************
|
|
Function:
|
|
typedef bool (*FILEIO_SD_CDGet)(void);
|
|
|
|
Summary:
|
|
Prototype for a user-implemented function to get the current state of the
|
|
Card Detect pin, if one exists.
|
|
|
|
Input:
|
|
None
|
|
|
|
Return Values:
|
|
true if the card detect pin indicates the card is inserted, false otherwise.
|
|
If the physical socket in use does not have a card detect pin, this
|
|
function should always return true.
|
|
|
|
Description:
|
|
Most functions in this driver require the user to implement the functions
|
|
that comprise a FILEIO_SD_DRIVE_CONFIG structure. This function pointer
|
|
definition describes a function in this structure that will return the value
|
|
of a card detect pin. These pins are a typical feature on the physical
|
|
sockets manufactured for SD card (not on the SD cards themselves). On
|
|
some types of SD card (i.e. micro SD) this pin will not be available.
|
|
|
|
Remarks:
|
|
None
|
|
***********************************************************************************/
|
|
typedef bool (*FILEIO_SD_CDGet)(void);
|
|
|
|
/*************************************************************************************
|
|
Function:
|
|
typedef bool (*FILEIO_SD_WPGet)(void);
|
|
|
|
Summary:
|
|
Prototype for a user-implemented function to get the current state of the
|
|
Write Protect pin, if one exists.
|
|
|
|
Input:
|
|
None
|
|
|
|
Return Values:
|
|
true if the write protect pin indicates the card is inserted, false otherwise.
|
|
If the physical socket in use does not have a write protect pin, this
|
|
function should always return false.
|
|
|
|
Description:
|
|
Most functions in this driver require the user to implement the functions
|
|
that comprise a FILEIO_SD_DRIVE_CONFIG structure. This function pointer
|
|
definition describes a function in this structure that will return the value
|
|
of a write protect pin. These pins are a typical feature on the physical
|
|
sockets manufactured for SD card (not on the SD cards themselves). On
|
|
some types of SD card (i.e. micro SD) this pin will not be available.
|
|
|
|
Remarks:
|
|
None
|
|
***********************************************************************************/
|
|
typedef bool (*FILEIO_SD_WPGet)(void);
|
|
|
|
/*************************************************************************************
|
|
Function:
|
|
typedef void (*FILEIO_SD_PinConfigure)(void);
|
|
|
|
Summary:
|
|
Prototype for a user-implemented function to configure the pins used by
|
|
the SD card.
|
|
|
|
Input:
|
|
None
|
|
|
|
Return Values:
|
|
None.
|
|
|
|
Description:
|
|
Most functions in this driver require the user to implement the functions
|
|
that comprise a FILEIO_SD_DRIVE_CONFIG structure. This function pointer
|
|
definition describes a function in this structure that will configure all of
|
|
the pins used by the SD Card. The configuration may involve setting/clearing
|
|
the TRIS bits, disabling the analog state of the pins, setting up peripheral
|
|
pin select, or other operations (depending on the device).
|
|
The user must configure the chip select, card detect, and write protect pins.
|
|
Optionally, configuration for the SPI pins (SDI, SDO, SCK) and SPI module
|
|
may be performed in this function, though it may make more sense to configure
|
|
those in another part of any given application.
|
|
|
|
Remarks:
|
|
None
|
|
***********************************************************************************/
|
|
typedef void (*FILEIO_SD_PinConfigure)(void);
|
|
|
|
// A configuration structure used by the SD-SPI driver functions to perform specific
|
|
// tasks.
|
|
typedef struct
|
|
{
|
|
uint8_t index; // The numeric index of the SPI module to use (i.e. 1 for SPI1/SSP1, 2 for SPI2, SSP2,...)
|
|
FILEIO_SD_CSSet csFunc; // Pointer to a user-implemented function to set/clear the chip select pins
|
|
FILEIO_SD_CDGet cdFunc; // Pointer to a user-implemented function to get the status of the card detect pin
|
|
FILEIO_SD_WPGet wpFunc; // Pointer to a user-implemented function to get the status of the write protect pin
|
|
FILEIO_SD_PinConfigure configurePins; // Pointer to a user-implemented function to configure the pins used by the SD Card
|
|
} FILEIO_SD_DRIVE_CONFIG;
|
|
|
|
|
|
/*****************************************************************************/
|
|
/* Public Prototypes */
|
|
/*****************************************************************************/
|
|
|
|
/*********************************************************
|
|
Function:
|
|
bool FILEIO_SD_MediaDetect (FILEIO_SD_DRIVE_CONFIG * config)
|
|
Summary:
|
|
Determines whether an SD card is present
|
|
Conditions:
|
|
The FILEIO_SD_MediaDetect function pointer must be configured
|
|
to point to this function in FSconfig.h
|
|
Input:
|
|
config - The given drive configuration
|
|
Return Values:
|
|
true - Card detected
|
|
false - No card detected
|
|
Side Effects:
|
|
None.
|
|
Description:
|
|
The FILEIO_SD_MediaDetect function determine if an SD card is connected to
|
|
the microcontroller.
|
|
If the MEDIA_SOFT_DETECT is not defined, the detection is done by polling
|
|
the SD card detect pin.
|
|
The MicroSD connector does not have a card detect pin, and therefore a
|
|
software mechanism must be used. To do this, the SEND_STATUS command is sent
|
|
to the card. If the card is not answering with 0x00, the card is either not
|
|
present, not configured, or in an error state. If this is the case, we try
|
|
to reconfigure the card. If the configuration fails, we consider the card not
|
|
present (it still may be present, but malfunctioning). In order to use the
|
|
software card detect mechanism, the MEDIA_SOFT_DETECT macro must be defined.
|
|
|
|
Remarks:
|
|
None
|
|
*********************************************************/
|
|
bool FILEIO_SD_MediaDetect(FILEIO_SD_DRIVE_CONFIG * config);
|
|
|
|
/*****************************************************************************
|
|
Function:
|
|
FILEIO_MEDIA_INFORMATION * FILEIO_SD_MediaInitialize (void)
|
|
Summary:
|
|
Initializes the SD card.
|
|
Conditions:
|
|
The FILEIO_SD_MediaInitialize function pointer must be pointing to this function.
|
|
Input:
|
|
config - An SD Drive configuration structure pointer
|
|
Return Values:
|
|
The function returns a pointer to the FILEIO_MEDIA_INFORMATION structure. The
|
|
errorCode member may contain the following values:
|
|
* MEDIA_NO_ERROR - The media initialized successfully
|
|
* MEDIA_CANNOT_INITIALIZE - Cannot initialize the media.
|
|
Side Effects:
|
|
None.
|
|
Description:
|
|
This function will send initialization commands to and SD card.
|
|
Remarks:
|
|
Psuedo code flow for the media initialization process is as follows:
|
|
|
|
-------------------------------------------------------------------------------------------
|
|
SD Card SPI Initialization Sequence (for physical layer v1.x or v2.0 device) is as follows:
|
|
-------------------------------------------------------------------------------------------
|
|
0. Power up tasks
|
|
a. Initialize microcontroller SPI module to no more than 400kbps rate so as to support MMC devices.
|
|
b. Add delay for SD card power up, prior to sending it any commands. It wants the
|
|
longer of: 1ms, the Vdd ramp time (time from 2.7V to Vdd stable), and 74+ clock pulses.
|
|
1. Send CMD0 (GO_IDLE_STATE) with CS = 0. This puts the media in SPI mode and software resets the SD/MMC card.
|
|
2. Send CMD8 (SEND_IF_COND). This requests what voltage the card wants to run at.
|
|
Note: Some cards will not support this command.
|
|
a. If illegal command response is received, this implies either a v1.x physical spec device, or not an SD card (ex: MMC).
|
|
b. If normal response is received, then it must be a v2.0 or later SD memory card.
|
|
|
|
If v1.x device:
|
|
-----------------
|
|
3. Send CMD1 repeatedly, until initialization complete (indicated by R1 response uint8_t/idle bit == 0)
|
|
4. Basic initialization is complete. May now switch to higher SPI frequencies.
|
|
5. Send CMD9 to read the CSD structure. This will tell us the total flash size and other info which will be useful later.
|
|
6. Parse CSD structure bits (based on v1.x structure format) and extract useful information about the media.
|
|
7. The card is now ready to perform application data transfers.
|
|
|
|
If v2.0+ device:
|
|
-----------------
|
|
3. Verify the voltage range is feasible. If not, unusable card, should notify user that the card is incompatible with this host.
|
|
4. Send CMD58 (Read OCR).
|
|
5. Send CMD55, then ACMD41 (SD_SEND_OP_COND, with HCS = 1).
|
|
a. Loop CMD55/ACMD41 until R1 response uint8_t == 0x00 (indicating the card is no longer busy/no longer in idle state).
|
|
6. Send CMD58 (Get CCS).
|
|
a. If CCS = 1 --> SDHC card.
|
|
b. If CCS = 0 --> Standard capacity SD card (which is v2.0+).
|
|
7. Basic initialization is complete. May now switch to higher SPI frequencies.
|
|
8. Send CMD9 to read the CSD structure. This will tell us the total flash size and other info which will be useful later.
|
|
9. Parse CSD structure bits (based on v2.0 structure format) and extract useful information about the media.
|
|
10. The card is now ready to perform application data transfers.
|
|
--------------------------------------------------------------------------------
|
|
********************************************************************************/
|
|
FILEIO_MEDIA_INFORMATION * FILEIO_SD_MediaInitialize(FILEIO_SD_DRIVE_CONFIG * config);
|
|
|
|
/*********************************************************
|
|
Function:
|
|
bool FILEIO_SD_MediaDeinitialize(
|
|
FILEIO_SD_DRIVE_CONFIG * config)
|
|
Summary:
|
|
Disables the SD card
|
|
Conditions:
|
|
The FILEIO_SD_MediaDeinitialize function pointer is pointing
|
|
towards this function.
|
|
Input:
|
|
config - An SD Drive configuration structure pointer
|
|
Return:
|
|
true if successful, false otherwise
|
|
Side Effects:
|
|
None.
|
|
Description:
|
|
This function will disable the SPI port and deselect
|
|
the SD card.
|
|
Remarks:
|
|
None
|
|
*********************************************************/
|
|
bool FILEIO_SD_MediaDeinitialize(FILEIO_SD_DRIVE_CONFIG * config);
|
|
|
|
/*********************************************************
|
|
Function:
|
|
uint32_t FILEIO_SD_CapacityRead(
|
|
FILEIO_SD_DRIVE_CONFIG * config)
|
|
Summary:
|
|
Determines the current capacity of the SD card
|
|
Conditions:
|
|
FILEIO_SD_MediaInitialize() is complete
|
|
Input:
|
|
config - An SD Drive configuration structure pointer
|
|
Return:
|
|
The capacity of the device
|
|
Side Effects:
|
|
None.
|
|
Description:
|
|
The FILEIO_SD_CapacityRead function is used by the
|
|
USB mass storage class to return the total number
|
|
of sectors on the card.
|
|
Remarks:
|
|
None
|
|
*********************************************************/
|
|
uint32_t FILEIO_SD_CapacityRead(FILEIO_SD_DRIVE_CONFIG * config);
|
|
|
|
/*********************************************************
|
|
Function:
|
|
uint16_t FILEIO_SD_SectorSizeRead(
|
|
FILEIO_SD_DRIVE_CONFIG * config)
|
|
Summary:
|
|
Determines the current sector size on the SD card
|
|
Conditions:
|
|
FILEIO_SD_MediaInitialize() is complete
|
|
Input:
|
|
config - An SD Drive configuration structure pointer
|
|
Return:
|
|
The size of the sectors for the physical media
|
|
Side Effects:
|
|
None.
|
|
Description:
|
|
The FILEIO_SD_SectorSizeRead function is used by the
|
|
USB mass storage class to return the card's sector
|
|
size to the PC on request.
|
|
Remarks:
|
|
None
|
|
*********************************************************/
|
|
uint16_t FILEIO_SD_SectorSizeRead(FILEIO_SD_DRIVE_CONFIG * config);
|
|
|
|
/*********************************************************
|
|
Function:
|
|
void FILEIO_SD_IOInitialize (
|
|
FILEIO_SD_DRIVE_CONFIG * config)
|
|
Summary:
|
|
Initializes the I/O lines connected to the card
|
|
Conditions:
|
|
FILEIO_SD_MediaInitialize() is complete. The MDD_InitIO
|
|
function pointer is pointing to this function.
|
|
Input:
|
|
config - An SD Drive configuration structure pointer
|
|
Return:
|
|
None
|
|
Side Effects:
|
|
None.
|
|
Description:
|
|
The FILEIO_SD_IOInitialize function initializes the I/O
|
|
pins connected to the SD card.
|
|
Remarks:
|
|
None
|
|
*********************************************************/
|
|
void FILEIO_SD_IOInitialize(FILEIO_SD_DRIVE_CONFIG * config);
|
|
//extern void FILEIO_Driver_IOInitialize(void);
|
|
|
|
/*****************************************************************************
|
|
Function:
|
|
uint8_t FILEIO_SD_SectorRead (uint32_t sector_addr, uint8_t * buffer)
|
|
Summary:
|
|
Reads a sector of data from an SD card.
|
|
Conditions:
|
|
The FILEIO_SD_SectorRead function pointer must be pointing towards this function.
|
|
Input:
|
|
config - An SD Drive configuration structure pointer
|
|
sectorAddress - The address of the sector on the card.
|
|
buffer - The buffer where the retrieved data will be stored. If
|
|
buffer is NULL, do not store the data anywhere.
|
|
Return Values:
|
|
true - The sector was read successfully
|
|
false - The sector could not be read
|
|
Side Effects:
|
|
None
|
|
Description:
|
|
The FILEIO_SD_SectorRead function reads a sector of data uint8_ts (512 uint8_ts)
|
|
of data from the SD card starting at the sector address and stores them in
|
|
the location pointed to by 'buffer.'
|
|
Remarks:
|
|
The card expects the address field in the command packet to be a uint8_t address.
|
|
The sector_addr value is converted to a uint8_t address by shifting it left nine
|
|
times (multiplying by 512).
|
|
|
|
This function performs a synchronous read operation. In other uint16_ts, this
|
|
function is a blocking function, and will not return until either the data
|
|
has fully been read, or, a timeout or other error occurred.
|
|
***************************************************************************************/
|
|
bool FILEIO_SD_SectorRead(FILEIO_SD_DRIVE_CONFIG * config, uint32_t sector_addr, uint8_t * buffer);
|
|
|
|
/*****************************************************************************
|
|
Function:
|
|
bool FILEIO_SD_SectorWrite (FILEIO_SD_DRIVE_CONFIG * config,
|
|
uint32_t sector_addr, uint8_t * buffer, uint8_t allowWriteToZero)
|
|
Summary:
|
|
Writes a sector of data to an SD card.
|
|
Conditions:
|
|
The FILEIO_SD_SectorWrite function pointer must be pointing to this function.
|
|
Input:
|
|
config - An SD Drive configuration structure pointer
|
|
sectorAddress - The address of the sector on the card.
|
|
buffer - The buffer with the data to write.
|
|
allowWriteToZero -
|
|
- true - Writes to the 0 sector (MBR) are allowed
|
|
- false - Any write to the 0 sector will fail.
|
|
Return Values:
|
|
true - The sector was written successfully.
|
|
false - The sector could not be written.
|
|
Side Effects:
|
|
None.
|
|
Description:
|
|
The FILEIO_SD_SectorWrite function writes one sector of data (512 uint8_ts)
|
|
of data from the location pointed to by 'buffer' to the specified sector of
|
|
the SD card.
|
|
Remarks:
|
|
The card expects the address field in the command packet to be a uint8_t address.
|
|
The sector_addr value is converted to a uint8_t address by shifting it left nine
|
|
times (multiplying by 512).
|
|
***************************************************************************************/
|
|
bool FILEIO_SD_SectorWrite(FILEIO_SD_DRIVE_CONFIG * config, uint32_t sector_addr, uint8_t * buffer, bool allowWriteToZero);
|
|
|
|
/*******************************************************************************
|
|
Function:
|
|
uint8_t FILEIO_SD_WriteProtectStateGet
|
|
Summary:
|
|
Indicates whether the card is write-protected.
|
|
Conditions:
|
|
The FILEIO_SD_WriteProtectStateGet function pointer must be pointing to this function.
|
|
Input:
|
|
config - An SD Drive configuration structure pointer
|
|
Return Values:
|
|
true - The card is write-protected
|
|
false - The card is not write-protected
|
|
Side Effects:
|
|
None.
|
|
Description:
|
|
The FILEIO_SD_WriteProtectStateGet function will determine if the SD card is
|
|
write protected by checking the electrical signal that corresponds to the
|
|
physical write-protect switch.
|
|
Remarks:
|
|
None
|
|
*******************************************************************************/
|
|
bool FILEIO_SD_WriteProtectStateGet(FILEIO_SD_DRIVE_CONFIG * config);
|
|
|
|
|
|
uint8_t FILEIO_SD_AsyncReadTasks(FILEIO_SD_DRIVE_CONFIG * config, FILEIO_SD_ASYNC_IO*);
|
|
uint8_t FILEIO_SD_AsyncWriteTasks(FILEIO_SD_DRIVE_CONFIG * config, FILEIO_SD_ASYNC_IO*);
|
|
|
|
|
|
|
|
#endif
|