| [292] | 1 | /** | 
|---|
 | 2 |  * \file sdcard.h | 
|---|
 | 3 |  * \date 30 August 2012 | 
|---|
 | 4 |  * \author Cesar fuguet <cesar.fuguet-tortolero@lip6.fr> | 
|---|
 | 5 |  * | 
|---|
 | 6 |  * This file defines the driver of a SD Card device using an SPI controller | 
|---|
 | 7 |  */ | 
|---|
 | 8 |  | 
|---|
 | 9 | #ifndef SDCARD_H | 
|---|
 | 10 | #define SDCARD_H | 
|---|
 | 11 |  | 
|---|
 | 12 | #include <spi.h> | 
|---|
 | 13 |  | 
|---|
 | 14 | /** | 
|---|
 | 15 |  * \brief SD Card type definition | 
|---|
 | 16 |  */ | 
|---|
 | 17 | struct sdcard_dev | 
|---|
 | 18 | {  | 
|---|
 | 19 |     /**  | 
|---|
 | 20 |      * SPI controller pointer  | 
|---|
 | 21 |      */ | 
|---|
 | 22 |     struct spi_dev * spi; | 
|---|
 | 23 |  | 
|---|
 | 24 |     /** | 
|---|
 | 25 |      * Block length of the SDCARD | 
|---|
 | 26 |      */ | 
|---|
 | 27 |     unsigned int block_length; | 
|---|
 | 28 |  | 
|---|
 | 29 |     /** | 
|---|
 | 30 |      * Access pointer representing the offset in bytes used | 
|---|
 | 31 |      * to read or write in the SDCARD. | 
|---|
 | 32 |      * | 
|---|
 | 33 |      * \note this driver is for cards SDSD, therefore this offset | 
|---|
 | 34 |      *       must be multiple of the block length | 
|---|
 | 35 |      */  | 
|---|
 | 36 |     unsigned int access_pointer; | 
|---|
 | 37 |  | 
|---|
 | 38 |     /** | 
|---|
 | 39 |      * Slave ID. This ID represents the number of the slave select signal | 
|---|
 | 40 |      * used in the hardware platform | 
|---|
 | 41 |      */ | 
|---|
 | 42 |     int    slave_id; | 
|---|
| [501] | 43 |  | 
|---|
 | 44 |     /* is the card high capacity ? */ | 
|---|
 | 45 |     int sdhc; | 
|---|
| [292] | 46 | }; | 
|---|
 | 47 |  | 
|---|
 | 48 | /** | 
|---|
 | 49 |  * \param   sdcard  : uninitialized pointer. This parameter will contain | 
|---|
 | 50 |  *                    a pointer to the initialized block device or NULL otherwise | 
|---|
 | 51 |  * \param   spi     : initialized pointer to the spi controller | 
|---|
 | 52 |  * \param   ss      : slave select signal number | 
|---|
 | 53 |  * | 
|---|
 | 54 |  * \return  0 when initialization succeeds or an error code value otherwise. | 
|---|
 | 55 |  *          The error codes are defined in this header file. | 
|---|
 | 56 |  * | 
|---|
 | 57 |  * \brief   Initialize the block device | 
|---|
 | 58 |  */ | 
|---|
 | 59 | int sdcard_dev_open(struct sdcard_dev * sdcard, struct spi_dev * spi, int ss); | 
|---|
 | 60 |  | 
|---|
 | 61 | /** | 
|---|
 | 62 |  * \param   sdcard  : Pointer to the initialized block device | 
|---|
 | 63 |  * \param   buf     : Pointer to a memory segment wherein store | 
|---|
 | 64 |  * \param   count   : number of bytes to read | 
|---|
 | 65 |  * | 
|---|
 | 66 |  * \return  0 when read succeeds or an error code value otherwise. | 
|---|
 | 67 |  *          The error codes are defined in this header file. | 
|---|
 | 68 |  * | 
|---|
 | 69 |  * \brief   Read in the block device | 
|---|
 | 70 |  * | 
|---|
 | 71 |  * The read is made in the current block device access pointer. | 
|---|
 | 72 |  * In the read succeeds, the block device access pointer is | 
|---|
 | 73 |  * relocated to the next block. | 
|---|
 | 74 |  */ | 
|---|
 | 75 | int sdcard_dev_read(struct sdcard_dev * sdcard, void * buf, unsigned int count); | 
|---|
 | 76 |  | 
|---|
 | 77 | /** | 
|---|
 | 78 |  * \param   sdcard  : Pointer to the initialized block device | 
|---|
 | 79 |  * \param   buf     : Pointer to a memory segment wherein the | 
|---|
 | 80 |  * \param   count   : number of blocks to write | 
|---|
 | 81 |  * | 
|---|
 | 82 |  * \return  0 when write succeeds or an error code value otherwise. | 
|---|
 | 83 |  *          The error codes are defined in this header file. | 
|---|
 | 84 |  * | 
|---|
 | 85 |  * \brief   Write in the block device | 
|---|
 | 86 |  * | 
|---|
 | 87 |  * The write is made in the current block device access pointer. | 
|---|
 | 88 |  * In the write succeeds, the block device access pointer is | 
|---|
 | 89 |  * relocated to the next block. | 
|---|
 | 90 |  */ | 
|---|
 | 91 | unsigned int sdcard_dev_write(struct sdcard_dev * sdcard, void * buf, unsigned int count); | 
|---|
 | 92 |  | 
|---|
 | 93 | /** | 
|---|
 | 94 |  * \param   sdcard  : Pointer to the initialized block device | 
|---|
 | 95 |  * \param   pos     : Position where the block device access | 
|---|
 | 96 |  *                    pointer must be move | 
|---|
 | 97 |  * | 
|---|
 | 98 |  * \return  void | 
|---|
 | 99 |  * | 
|---|
 | 100 |  * \brief   Change block device access pointer position | 
|---|
 | 101 |  *   | 
|---|
 | 102 |  * The block device access pointer is relocated in terms of blocks | 
|---|
 | 103 |  */ | 
|---|
 | 104 | void sdcard_dev_lseek(struct sdcard_dev * sdcard, unsigned int pos); | 
|---|
 | 105 |  | 
|---|
 | 106 | /** | 
|---|
 | 107 |  * \param   sdcard  : Pointer to the initialized block device | 
|---|
 | 108 |  * \param   len     : Block device length to set | 
|---|
 | 109 |  * | 
|---|
 | 110 |  * \return  0 when succeed or error code value otherwise | 
|---|
 | 111 |  * | 
|---|
 | 112 |  * \brief   Set the block length of the device | 
|---|
 | 113 |  */ | 
|---|
 | 114 | int sdcard_dev_set_blocklen(struct sdcard_dev * sdcard, unsigned int len); | 
|---|
 | 115 |  | 
|---|
 | 116 | /** | 
|---|
 | 117 |  * SD Card constants | 
|---|
 | 118 |  */ | 
|---|
 | 119 |  | 
|---|
 | 120 | /** Number of retries after an unacknowledge command */ | 
|---|
 | 121 | #define SDCARD_COMMAND_TIMEOUT      100 | 
|---|
 | 122 |  | 
|---|
 | 123 | /** This command is a simple SD commmand */ | 
|---|
 | 124 | #define SDCARD_CMD                  0 | 
|---|
 | 125 |  | 
|---|
 | 126 | /** This is an application specific command */ | 
|---|
 | 127 | #define SDCARD_ACMD                 1 | 
|---|
 | 128 |  | 
|---|
 | 129 | /** The transmition is done in the negative edge of the clock */ | 
|---|
 | 130 | #define SDCARD_TX_NEGEDGE           0 | 
|---|
 | 131 |  | 
|---|
 | 132 | /** The transmition is done in the positive edge of the clock */ | 
|---|
 | 133 | #define SDCARD_TX_POSEDGE           1 | 
|---|
 | 134 |  | 
|---|
 | 135 | /** The reception is done in the negative edge of the clock */ | 
|---|
 | 136 | #define SDCARD_RX_NEGEDGE           0 | 
|---|
 | 137 |  | 
|---|
 | 138 | /** The reception is done in the positive edge of the clock */ | 
|---|
 | 139 | #define SDCARD_RX_POSEDGE           1 | 
|---|
 | 140 |  | 
|---|
 | 141 | /** | 
|---|
 | 142 |  * SD Card macros | 
|---|
 | 143 |  */ | 
|---|
 | 144 |  | 
|---|
 | 145 | /** Check if the response is valid */ | 
|---|
 | 146 | #define SDCARD_CHECK_R1_VALID(x)    (~x & SDCARD_R1_RSP_VALID) ? 1 : 0 | 
|---|
 | 147 |  | 
|---|
 | 148 | /** | 
|---|
 | 149 |  * Check if there is an error in the response | 
|---|
 | 150 |  * | 
|---|
 | 151 |  * \note this macro must be used after verify that the response is | 
|---|
 | 152 |  *       valid | 
|---|
 | 153 |  */ | 
|---|
 | 154 | #define SDCARD_CHECK_R1_ERROR(x)    ( x & 0x7E)                ? 1 : 0 | 
|---|
 | 155 |  | 
|---|
 | 156 | /** | 
|---|
 | 157 |  * SD Card Response 1 (R1) format constants | 
|---|
 | 158 |  */ | 
|---|
 | 159 | #define SDCARD_R1_IN_IDLE_STATE     ( 1 << 0 ) /**< \brief R1 bit 0 */ | 
|---|
 | 160 | #define SDCARD_R1_ERASE_RESET       ( 1 << 1 ) /**< \brief R1 bit 1 */ | 
|---|
 | 161 | #define SDCARD_R1_ILLEGAL_CMD       ( 1 << 2 ) /**< \brief R1 bit 2 */ | 
|---|
 | 162 | #define SDCARD_R1_COM_CRC_ERR       ( 1 << 3 ) /**< \brief R1 bit 3 */ | 
|---|
 | 163 | #define SDCARD_R1_ERASE_SEQ_ERR     ( 1 << 4 ) /**< \brief R1 bit 4 */ | 
|---|
 | 164 | #define SDCARD_R1_ADDRESS_ERR       ( 1 << 5 ) /**< \brief R1 bit 5 */ | 
|---|
 | 165 | #define SDCARD_R1_PARAMETER_ERR     ( 1 << 6 ) /**< \brief R1 bit 6 */ | 
|---|
 | 166 | #define SDCARD_R1_RSP_VALID         ( 1 << 7 ) /**< \brief R1 bit 7 */ | 
|---|
 | 167 |  | 
|---|
 | 168 | #endif | 
|---|
 | 169 |  | 
|---|
 | 170 | /* | 
|---|
 | 171 |  * vim: tabstop=4 : shiftwidth=4 : expandtab : softtabstop=4 | 
|---|
 | 172 |  */ | 
|---|