SAMV71 Xplained Ultra Software Package 1.5

MEDSdcard.c

Go to the documentation of this file.
00001 /* ---------------------------------------------------------------------------- */
00002 /*                  Atmel Microcontroller Software Support                      */
00003 /*                       SAM Software Package License                           */
00004 /* ---------------------------------------------------------------------------- */
00005 /* Copyright (c) 2015, Atmel Corporation                                        */
00006 /*                                                                              */
00007 /* All rights reserved.                                                         */
00008 /*                                                                              */
00009 /* Redistribution and use in source and binary forms, with or without           */
00010 /* modification, are permitted provided that the following condition is met:    */
00011 /*                                                                              */
00012 /* - Redistributions of source code must retain the above copyright notice,     */
00013 /* this list of conditions and the disclaimer below.                            */
00014 /*                                                                              */
00015 /* Atmel's name may not be used to endorse or promote products derived from     */
00016 /* this software without specific prior written permission.                     */
00017 /*                                                                              */
00018 /* DISCLAIMER:  THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR   */
00019 /* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF */
00020 /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE   */
00021 /* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,      */
00022 /* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */
00023 /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,  */
00024 /* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF    */
00025 /* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING         */
00026 /* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, */
00027 /* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                           */
00028 /* ---------------------------------------------------------------------------- */
00029 
00030 /**
00031  * \file
00032  *
00033  * Implementation of media layer for the SdCard.
00034  *
00035  */
00036 
00037 /*------------------------------------------------------------------------------
00038  *         Headers
00039  *------------------------------------------------------------------------------*/
00040 #include "board.h"
00041 #include "Media.h"
00042 #include "MEDSdcard.h"
00043 #include "libsdmmc.h"
00044 #include <assert.h>
00045 #include <string.h>
00046 /*------------------------------------------------------------------------------
00047  *         Constants
00048  *------------------------------------------------------------------------------*/
00049 
00050 /** Number of SD Slots */
00051 #define NUM_SD_SLOTS            1
00052 /** Default block size for SD/MMC card access */
00053 #define SD_BLOCK_SIZE       512
00054 /**
00055  * \brief  Reads a specified amount of data from a SDCARD memory
00056  * \param  media    Pointer to a Media instance
00057  * \param  address  Address of the data to read
00058  * \param  data     Pointer to the buffer in which to store the retrieved
00059  *                   data
00060  * \param  length   Length of the buffer
00061  * \param  callback Optional pointer to a callback function to invoke when
00062  *                   the operation is finished
00063  * \param  argument Optional pointer to an argument for the callback
00064  * \return Operation result code
00065  */
00066 static uint8_t MEDSdcard_Read(sMedia *media,
00067                               uint32_t  address,
00068                               void          *data,
00069                               uint32_t  length,
00070                               MediaCallback callback,
00071                               void          *argument)
00072 {
00073     uint8_t error;
00074 
00075     // Check that the media is ready
00076     if (media->state != MED_STATE_READY) {
00077 
00078         TRACE_INFO("Media busy\n\r");
00079         return MED_STATUS_BUSY;
00080     }
00081 
00082     // Check that the data to read is not too big
00083     if ((length + address) > media->size) {
00084 
00085         TRACE_WARNING("MEDSdcard_Read: Data too big: %d, %d\n\r",
00086                       (int)length, (int)address);
00087         return MED_STATUS_ERROR;
00088     }
00089 
00090     // Enter Busy state
00091     media->state = MED_STATE_BUSY;
00092 
00093     error = SD_Read((sSdCard *)media->interface, address, data, length, NULL, NULL);
00094 
00095     // Leave the Busy state
00096     media->state = MED_STATE_READY;
00097 
00098     // Invoke callback
00099     if (callback != 0)
00100 
00101         callback(argument, error, 0, 0);
00102 
00103     return error;
00104 }
00105 
00106 /**
00107  * \brief  Writes data on a SDRAM media
00108  * \param  media    Pointer to a Media instance
00109  * \param  address  Address at which to write
00110  * \param  data     Pointer to the data to write
00111  * \param  length   Size of the data buffer
00112  * \param  callback Optional pointer to a callback function to invoke when
00113  *                   the write operation terminates
00114  * \param  argument Optional argument for the callback function
00115  * \return Operation result code
00116  * \see    Media
00117  * \see    MediaCallback
00118  */
00119 static uint8_t MEDSdcard_Write(sMedia         *media,
00120                                uint32_t  address,
00121                                void          *data,
00122                                uint32_t  length,
00123                                MediaCallback callback,
00124                                void          *argument)
00125 {
00126     uint8_t error;
00127 
00128     // Check that the media if ready
00129     if (media->state != MED_STATE_READY) {
00130 
00131         TRACE_WARNING("MEDSdcard_Write: Media is busy\n\r");
00132         return MED_STATUS_BUSY;
00133     }
00134 
00135     // Check that the data to write is not too big
00136     if ((length + address) > media->size) {
00137 
00138         TRACE_WARNING("MEDSdcard_Write: Data too big\n\r");
00139         return MED_STATUS_ERROR;
00140     }
00141 
00142     // Put the media in Busy state
00143     media->state = MED_STATE_BUSY;
00144 
00145     error = SD_Write((sSdCard *)media->interface, address, data, length, NULL,
00146                      NULL);
00147 
00148     // Leave the Busy state
00149     media->state = MED_STATE_READY;
00150 
00151     // Invoke the callback if it exists
00152     if (callback != 0)
00153 
00154         callback(argument, error, 0, 0);
00155 
00156     return error;
00157 }
00158 
00159 /**
00160  * \brief  Reads a specified amount of data from a SDCARD memory
00161  * \param  media    Pointer to a Media instance
00162  * \param  address  Address of the data to read
00163  * \param  data     Pointer to the buffer in which to store the retrieved
00164  *                   data
00165  * \param  length   Length of the buffer
00166  * \param  callback Optional pointer to a callback function to invoke when
00167  *                   the operation is finished
00168  * \param  argument Optional pointer to an argument for the callback
00169  * \return Operation result code
00170  */
00171 static uint8_t MEDSdusb_Read(sMedia         *media,
00172                              uint32_t       address,
00173                              void          *data,
00174                              uint32_t       length,
00175                              MediaCallback  callback,
00176                              void          *argument)
00177 {
00178     uint8_t error;
00179 
00180     // Check that the media is ready
00181     if (media->state != MED_STATE_READY) {
00182         //printf("MEDSdusb_Read: Busy\n\r");
00183         return MED_STATUS_BUSY;
00184     }
00185 
00186     // Check that the data to read is not too big
00187     if ((length + address) > media->size) {
00188         //printf("MEDSdusb_Read: Data too big: %d, %d\n\r",
00189         //(int)length, (int)address);
00190         return MED_STATUS_ERROR;
00191     }
00192 
00193     // Enter Busy state
00194     media->state = MED_STATE_BUSY;
00195 #if 1
00196     error = SD_Read((sSdCard *)media->interface,
00197                     address, data, length,
00198                     (fSdmmcCallback)callback, NULL);
00199     error = (error ? MED_STATUS_ERROR : MED_STATUS_SUCCESS);
00200     media->state = MED_STATE_READY;
00201 
00202     if (callback) callback(argument, error, 0, 0);
00203 
00204     return error;
00205 #else
00206     MEDTransfer *pXfr;
00207     // Start media transfer
00208     pXfr = &media->transfer;
00209     pXfr->data     = data;
00210     pXfr->address  = address;
00211     pXfr->length   = length;
00212     pXfr->callback = callback;
00213     pXfr->argument = argument;
00214 
00215     error = SD_Read((sSdCard *)media->interface,
00216                     address,
00217                     data,
00218                     length,
00219                     (fSdmmcCallback)SdMmcCallback,
00220                     media);
00221     return (error ? MED_STATUS_ERROR : MED_STATUS_SUCCESS);
00222 #endif
00223 }
00224 
00225 /**
00226  * \brief  Writes data on a SDRAM media
00227  * \param  media    Pointer to a Media instance
00228  * \param  address  Address at which to write
00229  * \param  data     Pointer to the data to write
00230  * \param  length   Size of the data buffer
00231  * \param  callback Optional pointer to a callback function to invoke when
00232  *                   the write operation terminates
00233  * \param  argument Optional argument for the callback function
00234  * \return Operation result code
00235  * \see    Media
00236  * \see    MediaCallback
00237  */
00238 static uint8_t MEDSdusb_Write(sMedia         *media,
00239                               uint32_t       address,
00240                               void          *data,
00241                               uint32_t       length,
00242                               MediaCallback  callback,
00243                               void          *argument)
00244 {
00245     uint8_t error;
00246 
00247     if (media->state != MED_STATE_READY) {
00248         TRACE_INFO("MEDSdusb_Write: Busy\n\r");
00249         return MED_STATUS_BUSY;
00250     }
00251 
00252     // Check that the data to write is not too big
00253     if ((length + address) > media->size) {
00254         TRACE_WARNING("MEDSdcard_Write: Data too big\n\r");
00255         return MED_STATUS_ERROR;
00256     }
00257 
00258     // Put the media in Busy state
00259     media->state = MED_STATE_BUSY;
00260 #if 1
00261     error = SD_Write((sSdCard *)media->interface, address, data, length,
00262                      (fSdmmcCallback)callback, NULL);
00263     error = (error ? MED_STATUS_ERROR : MED_STATUS_SUCCESS);
00264     media->state = MED_STATE_READY;
00265 
00266     if (callback) callback(argument, error, 0, 0);
00267 
00268     return error;
00269 #else
00270     MEDTransfer *pXfr;
00271     // Start media transfer
00272     pXfr = &media->transfer;
00273     pXfr->data = data;
00274     pXfr->address = address;
00275     pXfr->length = length;
00276     pXfr->callback = callback;
00277     pXfr->argument = argument;
00278 
00279     error = SD_Write((sSdCard *)media->interface,
00280                      address,
00281                      data,
00282                      length,
00283                      (fSdmmcCallback)SdMmcCallback,
00284                      media);
00285     return (error ? MED_STATUS_ERROR : MED_STATUS_SUCCESS);
00286 #endif
00287 }
00288 
00289 /**
00290  * \brief  Initializes a Media instance
00291  * \param  media Pointer to the Media instance to initialize
00292  * \return 1 if success.
00293  */
00294 uint8_t MEDSdcard_Initialize(sMedia *media, sSdCard *pSdDrv)
00295 {
00296     TRACE_INFO("MEDSdcard init\n\r");
00297     // Initialize media fields
00298     media->interface = pSdDrv;
00299 #if !defined(OP_BOOTSTRAP_MCI_on)
00300     media->write = MEDSdcard_Write;
00301 #else
00302     media->write = 0;
00303 #endif
00304     media->read = MEDSdcard_Read;
00305     media->lock = 0;
00306     media->unlock = 0;
00307     media->handler = 0;
00308     media->flush = 0;
00309 
00310     media->blockSize = SD_BLOCK_SIZE;
00311     media->baseAddress = 0;
00312     media->size = pSdDrv->dwNbBlocks;
00313 
00314     media->mappedRD  = 0;
00315     media->mappedWR  = 0;
00316     media->removable = 1;
00317 
00318     media->state = MED_STATE_READY;
00319 
00320     media->transfer.data = 0;
00321     media->transfer.address = 0;
00322     media->transfer.length = 0;
00323     media->transfer.callback = 0;
00324     media->transfer.argument = 0;
00325 
00326     return 1;
00327 }
00328 
00329 /**
00330  * \brief  Initializes a Media instance
00331  * \param  media Pointer to the Media instance to initialize
00332  * \return 1 if success.
00333  */
00334 uint8_t MEDSdusb_Initialize(sMedia *media, sSdCard *pSdDrv)
00335 {
00336     printf("MEDSdusb init\n\r");
00337 
00338     // Initialize media fields
00339     media->interface = pSdDrv;
00340     media->write = MEDSdusb_Write;
00341     media->read = MEDSdusb_Read;
00342     media->lock = 0;
00343     media->unlock = 0;
00344     media->handler = 0;
00345     media->flush = 0;
00346 
00347     media->blockSize = SD_BLOCK_SIZE;
00348     media->baseAddress = 0;
00349     media->size = pSdDrv->dwNbBlocks;
00350 
00351     media->mappedRD  = 0;
00352     media->mappedWR  = 0;
00353     media->protected = 0;
00354     media->removable = 1;
00355 
00356     media->state = MED_STATE_READY;
00357 
00358     media->transfer.data = 0;
00359     media->transfer.address = 0;
00360     media->transfer.length = 0;
00361     media->transfer.callback = 0;
00362     media->transfer.argument = 0;
00363 
00364     return 1;
00365 }
00366 
00367 /**
00368  * \brief  erase all the SDCARD
00369  * \param  media Pointer to the Media instance to initialize
00370  */
00371 
00372 void MEDSdcard_EraseAll(sMedia *media)
00373 {
00374     uint8_t buffer[SD_BLOCK_SIZE];
00375     uint32_t block;
00376     uint32_t multiBlock = 1; // change buffer size for multiblocks
00377     uint8_t error;
00378 
00379     printf("MEDSdcard Erase All ...\n\r");
00380 
00381     // Clear the block buffer
00382     memset(buffer, 0, media->blockSize * multiBlock);
00383 
00384     for (block = 0;
00385          block < (media->size - multiBlock);
00386          block += multiBlock) {
00387         error = SD_WriteBlocks((sSdCard *)media->interface, block, buffer, multiBlock);
00388 
00389         if (error) {
00390             printf("\n\r-F- Failed to erase block (%u) #%u\n\r",
00391                    (unsigned int)error,  (unsigned int)block);
00392 
00393             /* Wait for watchdog reset or freeze the program */
00394             while (1);
00395         }
00396     }
00397 }
00398 
00399 /**
00400  * \brief  erase block
00401  * \param  media Pointer to the Media instance to initialize
00402  * \param  block to erase
00403  */
00404 void MEDSdcard_EraseBlock(sMedia *media, uint32_t block)
00405 {
00406     uint8_t buffer[SD_BLOCK_SIZE];
00407     uint8_t error;
00408 
00409     // Clear the block buffer
00410     memset(buffer, 0, media->blockSize);
00411     error = SD_WriteBlocks((sSdCard *)media->interface, block, buffer, 1);
00412 
00413     if (error) {
00414         TRACE_ERROR("\n\r-F- Failed to write block (%u) #%u\n\r",
00415                     (unsigned int)error, (unsigned int)block);
00416 
00417         /* Wait for watchdog reset or freeze the program */
00418         while (1);
00419     }
00420 }
00421 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines