SAMV71 Xplained Ultra Software Package 1.4

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 
00094     // Leave the Busy state
00095     media->state = MED_STATE_READY;
00096 
00097     // Invoke callback
00098     if (callback != 0) {
00099 
00100         callback(argument, error, 0, 0);
00101     }
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,NULL);
00146 
00147     // Leave the Busy state
00148     media->state = MED_STATE_READY;
00149 
00150     // Invoke the callback if it exists
00151     if (callback != 0) {
00152 
00153         callback(argument, error, 0, 0);
00154     }
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     // Check that the media is ready
00180     if (media->state != MED_STATE_READY) {
00181         //printf("MEDSdusb_Read: Busy\n\r");
00182         return MED_STATUS_BUSY;
00183     }
00184     // Check that the data to read is not too big
00185     if ((length + address) > media->size) {
00186         //printf("MEDSdusb_Read: Data too big: %d, %d\n\r", 
00187             //(int)length, (int)address);
00188         return MED_STATUS_ERROR;
00189     }
00190     // Enter Busy state
00191     media->state = MED_STATE_BUSY;
00192   #if 1
00193     error = SD_Read((sSdCard*)media->interface,
00194                      address,data,length,
00195                      (fSdmmcCallback)callback,NULL);
00196     error = (error ? MED_STATUS_ERROR : MED_STATUS_SUCCESS);
00197     media->state = MED_STATE_READY;
00198     if (callback) callback(argument, error, 0, 0);
00199     return error;
00200   #else
00201     MEDTransfer * pXfr;
00202     // Start media transfer
00203     pXfr = &media->transfer;
00204     pXfr->data     = data;
00205     pXfr->address  = address;
00206     pXfr->length   = length;
00207     pXfr->callback = callback;
00208     pXfr->argument = argument;
00209 
00210     error = SD_Read((sSdCard*)media->interface,
00211                      address,
00212                      data,
00213                      length,
00214                      (fSdmmcCallback)SdMmcCallback,
00215                      media);
00216     return (error ? MED_STATUS_ERROR : MED_STATUS_SUCCESS);
00217   #endif
00218 }
00219 
00220 /**
00221  * \brief  Writes data on a SDRAM media
00222  * \param  media    Pointer to a Media instance
00223  * \param  address  Address at which to write
00224  * \param  data     Pointer to the data to write
00225  * \param  length   Size of the data buffer
00226  * \param  callback Optional pointer to a callback function to invoke when
00227  *                   the write operation terminates
00228  * \param  argument Optional argument for the callback function
00229  * \return Operation result code
00230  * \see    Media
00231  * \see    MediaCallback
00232  */
00233 static uint8_t MEDSdusb_Write(sMedia         *media,
00234                               uint32_t       address,
00235                               void          *data,
00236                               uint32_t       length,
00237                               MediaCallback  callback,
00238                               void          *argument)
00239 {
00240     uint8_t error;
00241     if (media->state != MED_STATE_READY) {
00242         TRACE_INFO("MEDSdusb_Write: Busy\n\r");
00243         return MED_STATUS_BUSY;
00244     }
00245     // Check that the data to write is not too big
00246     if ((length + address) > media->size) {
00247         TRACE_WARNING("MEDSdcard_Write: Data too big\n\r");
00248         return MED_STATUS_ERROR;
00249     }
00250     // Put the media in Busy state
00251     media->state = MED_STATE_BUSY;
00252   #if 1
00253     error = SD_Write((sSdCard*)media->interface,address,data,length,
00254                 (fSdmmcCallback)callback,NULL);
00255     error = (error ? MED_STATUS_ERROR : MED_STATUS_SUCCESS);
00256     media->state = MED_STATE_READY;
00257     if (callback) callback(argument, error, 0, 0);
00258     return error;
00259   #else
00260     MEDTransfer * pXfr;
00261     // Start media transfer
00262     pXfr = &media->transfer;
00263     pXfr->data = data;
00264     pXfr->address = address;
00265     pXfr->length = length;
00266     pXfr->callback = callback;
00267     pXfr->argument = argument;
00268 
00269     error = SD_Write((sSdCard*)media->interface,
00270                       address,
00271                       data,
00272                       length,
00273                       (fSdmmcCallback)SdMmcCallback,
00274                       media);
00275     return (error ? MED_STATUS_ERROR : MED_STATUS_SUCCESS);
00276   #endif
00277 }
00278 
00279 /**
00280  * \brief  Initializes a Media instance 
00281  * \param  media Pointer to the Media instance to initialize
00282  * \return 1 if success.
00283  */
00284 uint8_t MEDSdcard_Initialize(sMedia *media, sSdCard *pSdDrv)
00285 {
00286     TRACE_INFO("MEDSdcard init\n\r");
00287     // Initialize media fields
00288     media->interface = pSdDrv;
00289     #if !defined(OP_BOOTSTRAP_MCI_on)
00290     media->write = MEDSdcard_Write;
00291     #else
00292     media->write = 0;
00293     #endif
00294     media->read = MEDSdcard_Read;
00295     media->lock = 0;
00296     media->unlock = 0;
00297     media->handler = 0;
00298     media->flush = 0;
00299 
00300     media->blockSize = SD_BLOCK_SIZE;
00301     media->baseAddress = 0;
00302     media->size = pSdDrv->dwNbBlocks;
00303 
00304     media->mappedRD  = 0;
00305     media->mappedWR  = 0;
00306     media->removable = 1;
00307 
00308     media->state = MED_STATE_READY;
00309 
00310     media->transfer.data = 0;
00311     media->transfer.address = 0;
00312     media->transfer.length = 0;
00313     media->transfer.callback = 0;
00314     media->transfer.argument = 0;
00315 
00316     return 1;
00317 }
00318 
00319 /**
00320  * \brief  Initializes a Media instance
00321  * \param  media Pointer to the Media instance to initialize
00322  * \return 1 if success.
00323  */
00324 uint8_t MEDSdusb_Initialize(sMedia *media, sSdCard *pSdDrv)
00325 {
00326     printf("MEDSdusb init\n\r");
00327 
00328     // Initialize media fields
00329     media->interface = pSdDrv;
00330     media->write = MEDSdusb_Write;
00331     media->read = MEDSdusb_Read;
00332     media->lock = 0;
00333     media->unlock = 0;
00334     media->handler = 0;
00335     media->flush = 0;
00336 
00337     media->blockSize = SD_BLOCK_SIZE;
00338     media->baseAddress = 0;
00339     media->size = pSdDrv->dwNbBlocks;
00340 
00341     media->mappedRD  = 0;
00342     media->mappedWR  = 0;
00343     media->protected = 0;
00344     media->removable = 1;
00345 
00346     media->state = MED_STATE_READY;
00347 
00348     media->transfer.data = 0;
00349     media->transfer.address = 0;
00350     media->transfer.length = 0;
00351     media->transfer.callback = 0;
00352     media->transfer.argument = 0;
00353 
00354     return 1;
00355 }
00356 
00357 /**
00358  * \brief  erase all the SDCARD
00359  * \param  media Pointer to the Media instance to initialize
00360  */
00361 
00362 void MEDSdcard_EraseAll(sMedia *media)
00363 {
00364     uint8_t buffer[SD_BLOCK_SIZE];
00365     uint32_t block;
00366     uint32_t multiBlock = 1; // change buffer size for multiblocks
00367     uint8_t error;
00368 
00369     printf("MEDSdcard Erase All ...\n\r");
00370 
00371     // Clear the block buffer
00372     memset(buffer, 0, media->blockSize * multiBlock);
00373 
00374     for (block=0;
00375          block < (media->size-multiBlock);
00376          block += multiBlock) {
00377         error = SD_WriteBlocks((sSdCard*)media->interface, block,buffer,multiBlock);
00378         if( error ) {
00379           printf("\n\r-F- Failed to erase block (%u) #%u\n\r", 
00380                 (unsigned int)error,  (unsigned int)block);
00381           /* Wait for watchdog reset or freeze the program */
00382           while (1);
00383         }
00384     }
00385 }
00386 
00387 /**
00388  * \brief  erase block
00389  * \param  media Pointer to the Media instance to initialize
00390  * \param  block to erase
00391  */
00392 void MEDSdcard_EraseBlock(sMedia *media, uint32_t block)
00393 {
00394     uint8_t buffer[SD_BLOCK_SIZE];
00395     uint8_t error;
00396 
00397     // Clear the block buffer
00398     memset(buffer, 0, media->blockSize);
00399     error = SD_WriteBlocks((sSdCard*)media->interface, block,buffer,1);
00400     if( error ) {
00401         TRACE_ERROR("\n\r-F- Failed to write block (%u) #%u\n\r",
00402             (unsigned int)error, (unsigned int)block);
00403         /* Wait for watchdog reset or freeze the program */
00404         while (1);
00405     }
00406 }
00407 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines