SAMV71 Xplained Ultra Software Package 1.3

MEDSdcard.c

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