/* ---------------------------------------------------------------------------- * ATMEL Microcontroller Software Support * ---------------------------------------------------------------------------- * Copyright (c) 2008, Atmel Corporation * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the disclaimer below. * * Atmel's name may not be used to endorse or promote products derived from * this software without specific prior written permission. * * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ---------------------------------------------------------------------------- */ //------------------------------------------------------------------------------ /// \unit /// !Purpose /// /// Generic Media type, which provides transparent access to all types of /// memories. /// /// \note The physical or HW related media operations (physical device /// connection & protection detecting, PIO configurations and interface /// driver initialization) are excluded. /// /// !Usage /// -# Do PIO initialization for peripheral interfaces. /// -# Initialize peripheral interface driver & device driver. /// -# Initialize specific media interface and link to this initialized driver. /// //------------------------------------------------------------------------------ #ifndef MEDIA_H #define MEDIA_H //------------------------------------------------------------------------------ // Definitions //------------------------------------------------------------------------------ //! \brief Operation result code returned by media methods #define MED_STATUS_SUCCESS 0x00 #define MED_STATUS_ERROR 0x01 #define MED_STATUS_BUSY 0x02 #define MED_STATUS_PROTECTED 0x04 //! \brief Media statuses #define MED_STATE_READY 0x00 /// Media is ready for access #define MED_STATE_BUSY 0x01 /// Media is busy //------------------------------------------------------------------------------ // Types //------------------------------------------------------------------------------ typedef struct _Media Media; typedef void (*MediaCallback)(void *argument, unsigned char status, unsigned int transferred, unsigned int remaining); typedef unsigned char (*Media_write)(Media *media, unsigned int address, void *data, unsigned int length, MediaCallback callback, void *argument); typedef unsigned char (*Media_read)(Media *media, unsigned int address, void *data, unsigned int length, MediaCallback callback, void *argument); typedef unsigned char (*Media_cancelIo)(Media *media); typedef unsigned char (*Media_lock)(Media *media, unsigned int start, unsigned int end, unsigned int *pActualStart, unsigned int *pActualEnd); typedef unsigned char (*Media_unlock)(Media *media, unsigned int start, unsigned int end, unsigned int *pActualStart, unsigned int *pActualEnd); typedef unsigned char (*Media_ioctl)(Media *media, unsigned char ctrl, void *buff); typedef unsigned char (*Media_flush)(Media *media); typedef void (*Media_handler)(Media *media); //! \brief Media transfer //! \see TransferCallback typedef struct { void *data; //!< Pointer to the data buffer unsigned int address; //!< Address where to read/write the data unsigned int length; //!< Size of the data to read/write MediaCallback callback; //!< Callback to invoke when the transfer done void *argument; //!< Callback argument } MEDTransfer; //! \brief Media object //! \see MEDTransfer struct _Media { Media_write write; //!< Write method Media_read read; //!< Read method Media_cancelIo cancelIo; //!< Cancel pending IO method Media_lock lock; //!< lock method if possible Media_unlock unlock; //!< unlock method if possible Media_flush flush; //!< Flush method Media_handler handler; //!< Interrupt handler unsigned int blockSize; //!< Block size in bytes (1, 512, 1K, 2K ...) unsigned int baseAddress; //!< Base address of media in number of blocks unsigned int size; //!< Size of media in number of blocks MEDTransfer transfer; //!< Current transfer operation void *interface; //!< Pointer to the physical interface used unsigned char bReserved:4, mappedRD:1, //!< Mapped to memory space to read mappedWR:1, //!< Mapped to memory space to write protected:1, //!< Protected media? removable:1; //!< Removable/Fixed media? unsigned char state; //!< Status of media unsigned short reserved; }; /// Available medias. extern Media medias[]; /// Number of medias which are effectively used. /// Defined by Media, shared usage by USB MSD & FS ... extern unsigned int numMedias; //------------------------------------------------------------------------------ // Inline Functions //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ //! \brief Writes data on a media //! \param media Pointer to a Media instance //! \param address Address at which to write //! \param data Pointer to the data to write //! \param length Size of the data buffer //! \param callback Optional pointer to a callback function to invoke when //! the write operation terminates //! \param argument Optional argument for the callback function //! \return Operation result code //! \see TransferCallback //------------------------------------------------------------------------------ static inline unsigned char MED_Write(Media *media, unsigned int address, void *data, unsigned int length, MediaCallback callback, void *argument) { return media->write(media, address, data, length, callback, argument); } //------------------------------------------------------------------------------ //! \brief Reads a specified amount of data from a media //! \param media Pointer to a Media instance //! \param address Address of the data to read //! \param data Pointer to the buffer in which to store the retrieved //! data //! \param length Length of the buffer //! \param callback Optional pointer to a callback function to invoke when //! the operation is finished //! \param argument Optional pointer to an argument for the callback //! \return Operation result code //! \see TransferCallback //------------------------------------------------------------------------------ static inline unsigned char MED_Read(Media *media, unsigned int address, void *data, unsigned int length, MediaCallback callback, void *argument) { return media->read(media, address, data, length, callback, argument); } //------------------------------------------------------------------------------ //! \brief Locks all the regions in the given address range. //! \param media Pointer to a Media instance /// \param start Start address of lock range. /// \param end End address of lock range. /// \param pActualStart Start address of the actual lock range (optional). /// \param pActualEnd End address of the actual lock range (optional). /// \return 0 if successful; otherwise returns an error code. //------------------------------------------------------------------------------ static inline unsigned char MED_Lock(Media *media, unsigned int start, unsigned int end, unsigned int *pActualStart, unsigned int *pActualEnd) { if( media->lock ) { return media->lock(media, start, end, pActualStart, pActualEnd); } else { return MED_STATUS_SUCCESS; } } //------------------------------------------------------------------------------ //! \brief Unlocks all the regions in the given address range //! \param media Pointer to a Media instance /// \param start Start address of unlock range. /// \param end End address of unlock range. /// \param pActualStart Start address of the actual unlock range (optional). /// \param pActualEnd End address of the actual unlock range (optional). /// \return 0 if successful; otherwise returns an error code. //------------------------------------------------------------------------------ static inline unsigned char MED_Unlock(Media *media, unsigned int start, unsigned int end, unsigned int *pActualStart, unsigned int *pActualEnd) { if( media->unlock ) { return media->unlock(media, start, end, pActualStart, pActualEnd); } else { return MED_STATUS_SUCCESS; } } //------------------------------------------------------------------------------ //! \brief //! \param media Pointer to the Media instance to use //------------------------------------------------------------------------------ static inline unsigned char MED_Flush(Media *media) { if (media->flush) { return media->flush(media); } else { return MED_STATUS_SUCCESS; } } //------------------------------------------------------------------------------ //! \brief Invokes the interrupt handler of the specified media //! \param media Pointer to the Media instance to use //------------------------------------------------------------------------------ static inline void MED_Handler(Media *media) { if (media->handler) { media->handler(media); } } //------------------------------------------------------------------------------ // Exported functions //------------------------------------------------------------------------------ extern void MED_HandleAll(Media *medias, unsigned char numMedias); #endif // _MEDIA_H