# MIOS32_SDCARD

## Defines
#define | MIOS32_SDCARD_MUTEX_TAKE {}
#define | MIOS32_SDCARD_MUTEX_GIVE {}
#define | MIOS32_SDCARD_SPI_PRESCALER MIOS32_SPI_PRESCALER_8
#define | SDCMD_GO_IDLE_STATE (0x40+0)
#define | SDCMD_GO_IDLE_STATE_CRC 0x95
#define | SDCMD_SEND_OP_COND (0x40+1)
#define | SDCMD_SEND_OP_COND_CRC 0xf9
#define | SDCMD_SEND_OP_COND_SDC (0xC0+41)
#define | SDCMD_SEND_OP_COND_SDC_CRC 0xff
#define | SDCMD_READ_OCR (0x40+58)
#define | SDCMD_READ_OCR_CRC 0xff
#define | SDCMD_APP_CMD (0x40+55)
#define | SDCMD_APP_CMD_CRC 0xff
#define | SDCMD_SEND_IF_COND (0x40+8)
#define | SDCMD_SEND_IF_COND_CRC 0x87
#define | SDCMD_SEND_CSD (0x40+9)
#define | SDCMD_SEND_CSD_CRC 0xff
#define | SDCMD_SEND_CID (0x40+10)
#define | SDCMD_SEND_CID_CRC 0xff
#define | SDCMD_SEND_STATUS (0x40+13)
#define | SDCMD_SEND_STATUS_CRC 0xaf
#define | SDCMD_READ_SINGLE_BLOCK (0x40+17)
#define | SDCMD_READ_SINGLE_BLOCK_CRC 0xff
#define | SDCMD_SET_BLOCKLEN (0x40+16)
#define | SDCMD_SET_BLOCKLEN_CRC 0xff
#define | SDCMD_WRITE_SINGLE_BLOCK (0x40+24)
#define | SDCMD_WRITE_SINGLE_BLOCK_CRC 0xff
#define | CT_MMC 0x01
#define | CT_SD1 0x02
#define | CT_SD2 0x04
#define | CT_SDC (CT_SD1|CT_SD2)
#define | CT_BLOCK 0x08
## Functions
s32 | MIOS32_SDCARD_Init (u32 mode)
s32 | MIOS32_SDCARD_PowerOn (void)
s32 | MIOS32_SDCARD_PowerOff (void)
s32 | MIOS32_SDCARD_CheckAvailable (u8 was_available)
s32 | MIOS32_SDCARD_SendSDCCmd (u8 cmd, u32 addr, u8 crc)
s32 | MIOS32_SDCARD_SectorRead (u32 sector, u8 *buffer)
s32 | MIOS32_SDCARD_SectorWrite (u32 sector, u8 *buffer)
s32 | MIOS32_SDCARD_CIDRead (mios32_sdcard_cid_t *cid)
s32 | MIOS32_SDCARD_CSDRead (mios32_sdcard_csd_t *csd)

## Detailed Description

SD Card is accessed via SPI1 (J16) or alternatively via SPI2 (J8/9) A bitbanging solution (for using alternative ports) will be provided later.

The card has to be supplied with 3.3V!

The SDIO peripheral is not used to ensure compatibility with "mid density" devices of the STM32 family, and future derivatives != STM32

MIOS32_SDCARD_Init(0) has to be called only once to initialize the driver.

MIOS32_SDCARD_CheckAvailable() should be called to connect with the SD Card. If 0 is returned, it can be assumed that no SD Card is connected. The function can be called periodically from a low priority task to retry a connection, resp. for an auto-detection during runtime

MIOS32_SDCARD_SectorRead/SectorWrite allow to read/write a 512 byte sector.

If such an access returns an error, it can be assumed that the SD Card has been disconnected during the transfer.

Since DMA is used for serial transfers, Reading/Writing a sector typically takes ca. 500 uS, accordingly the achievable transfer rate is ca. 1 MByte/s (8 MBit/s)

08 Jan 2009: Modified by philetaylor to add MMC and HCSD support also added a first attempt at using a mutex to allow sharing of SPI0 between SD cards and ENC28J60 ethernet. If used in this way, SD card must be inserted at poweron and will not be recognised if inserted after. Hopefully a fix will be found for this!

## Define Documentation

#define CT_BLOCK 0x08

#define CT_MMC 0x01

#define CT_SD1 0x02

#define CT_SD2 0x04

#define CT_SDC (CT_SD1|CT_SD2)

#define MIOS32_SDCARD_MUTEX_GIVE {}

#define MIOS32_SDCARD_MUTEX_TAKE {}

#define MIOS32_SDCARD_SPI_PRESCALER MIOS32_SPI_PRESCALER_8

#define SDCMD_APP_CMD (0x40+55)

#define SDCMD_APP_CMD_CRC 0xff

#define SDCMD_GO_IDLE_STATE (0x40+0)

#define SDCMD_GO_IDLE_STATE_CRC 0x95

#define SDCMD_READ_OCR (0x40+58)

#define SDCMD_READ_OCR_CRC 0xff

#define SDCMD_READ_SINGLE_BLOCK (0x40+17)

#define SDCMD_READ_SINGLE_BLOCK_CRC 0xff

#define SDCMD_SEND_CID (0x40+10)

#define SDCMD_SEND_CID_CRC 0xff

#define SDCMD_SEND_CSD (0x40+9)

#define SDCMD_SEND_CSD_CRC 0xff

#define SDCMD_SEND_IF_COND (0x40+8)

#define SDCMD_SEND_IF_COND_CRC 0x87

#define SDCMD_SEND_OP_COND (0x40+1)

#define SDCMD_SEND_OP_COND_CRC 0xf9

#define SDCMD_SEND_OP_COND_SDC (0xC0+41)

#define SDCMD_SEND_OP_COND_SDC_CRC 0xff

#define SDCMD_SEND_STATUS (0x40+13)

#define SDCMD_SEND_STATUS_CRC 0xaf

#define SDCMD_SET_BLOCKLEN (0x40+16)

#define SDCMD_SET_BLOCKLEN_CRC 0xff

#define SDCMD_WRITE_SINGLE_BLOCK (0x40+24)

#define SDCMD_WRITE_SINGLE_BLOCK_CRC 0xff

## Function Documentation

s32 MIOS32_SDCARD_CheckAvailable | ( | u8 | was_available | ) |

If SD card was previously available: Checks if the SD Card is still available by sending the STATUS command.
This takes ca. 10 uS

If SD card was previously not available: Checks if the SD Card is available by sending the IDLE command at low speed.
This takes ca. 500 uS!
Once we got a positive response, MIOS32_SDCARD_PowerOn() will be called by this function to initialize the card completely.

Example for Connection/Disconnection detection:

     // this function is called each second from a low-priority task
     // If multiple tasks are accessing the SD card, add a semaphore/mutex
     //  to avoid IO access collisions with other tasks!
     u8 sdcard_available;
     s32 SEQ_FILE_CheckSDCard(void)
     {
       // check if SD card is available
       // High speed access if the card was previously available
       u8 prev_sdcard_available = sdcard_available;
       sdcard_available = MIOS32_SDCARD_CheckAvailable(prev_sdcard_available);

       if( sdcard_available && !prev_sdcard_available ) {
         // SD Card has been connected

         // now it's possible to read/write sectors

       } else if( !sdcard_available && prev_sdcard_available ) {
         // SD Card has been disconnected

         // here you can notify your application about this state
       }

       return 0; // no error
     }

Parameters:

  `[in]` | was_available | should only be set if the SD card was previously available

Returns:
  0 if no response from SD Card
  1 if SD card is accessible

Here is the call graph for this function:

s32 MIOS32_SDCARD_CIDRead | ( | mios32_sdcard_cid_t * | cid | ) |

Reads the CID informations from SD Card

Parameters:

  `[in]` | *cid | pointer to buffer which holds the CID informations

Returns:
  0 if the informations haven been successfully read
  -error if error occured during read operation
  -256 if timeout during command has been sent
  -257 if timeout while waiting for start token

Here is the call graph for this function:

s32 MIOS32_SDCARD_CSDRead | ( | mios32_sdcard_csd_t * | csd | ) |

Reads the CSD informations from SD Card

Parameters:

  `[in]` | *csd | pointer to buffer which holds the CSD informations

Returns:
  0 if the informations haven been successfully read
  -error if error occured during read operation
  -256 if timeout during command has been sent
  -257 if timeout while waiting for start token

Here is the call graph for this function:

s32 MIOS32_SDCARD_Init | ( | u32 | mode | ) |

Initializes SPI pins and peripheral to access MMC/SD Card

Parameters:

  `[in]` | mode | currently only mode 0 supported

Returns:
  < 0 if initialisation failed

Here is the call graph for this function:

s32 MIOS32_SDCARD_PowerOff | ( | void |  | ) |

Disconnects from SD Card

Returns:
  < 0 on errors

Todo:
  not implemented yet

s32 MIOS32_SDCARD_PowerOn | ( | void |  | ) |

Connects to SD Card

Returns:
  < 0 if initialisation sequence failed

Here is the call graph for this function:

s32 MIOS32_SDCARD_SectorRead | ( | u32 | sector,
|  | u8 * | buffer |
| ) |  |  |

Reads 512 bytes from selected sector

Parameters:

  `[in]` | sector | 32bit sector
  `[in]` | *buffer | pointer to 512 byte buffer

Returns:
  0 if whole sector has been successfully read
  -error if error occured during read operation:
  - Bit 0 - In idle state if 1
  - Bit 1 - Erase Reset if 1
  - Bit 2 - Illgal Command if 1
  - Bit 3 - Com CRC Error if 1
  - Bit 4 - Erase Sequence Error if 1
  - Bit 5 - Address Error if 1
  - Bit 6 - Parameter Error if 1
  - Bit 7 - Not used, always '0'
  -256 if timeout during command has been sent
  -257 if timeout while waiting for start token

Here is the call graph for this function:

s32 MIOS32_SDCARD_SectorWrite | ( | u32 | sector,
|  | u8 * | buffer |
| ) |  |  |

Writes 512 bytes into selected sector

Parameters:

  `[in]` | sector | 32bit sector
  `[in]` | *buffer | pointer to 512 byte buffer

Returns:
  0 if whole sector has been successfully read
  -error if error occured during read operation:
  - Bit 0 - In idle state if 1
  - Bit 1 - Erase Reset if 1
  - Bit 2 - Illgal Command if 1
  - Bit 3 - Com CRC Error if 1
  - Bit 4 - Erase Sequence Error if 1
  - Bit 5 - Address Error if 1
  - Bit 6 - Parameter Error if 1
  - Bit 7 - Not used, always '0'
  -256 if timeout during command has been sent
  -257 if write operation not accepted
  -258 if timeout during write operation

Here is the call graph for this function:

s32 MIOS32_SDCARD_SendSDCCmd | ( | u8 | cmd,
|  | u32 | addr,
|  | u8 | crc |
| ) |  |  |

Sends command to SD card

Parameters:

  `[in]` | cmd | SD card command
  `[in]` | addr | 32bit address
  `[in]` | crc | precalculated CRC

Returns:
  >= 0x00 if command has been sent successfully (contains received byte)
  -1 if no response from SD Card (timeout)

Here is the call graph for this function: