diff options
Diffstat (limited to 'firmwares/wifishield/wifiHD/src/SOFTWARE_FRAMEWORK/COMPONENTS/MEMORY')
4 files changed, 1321 insertions, 0 deletions
| diff --git a/firmwares/wifishield/wifiHD/src/SOFTWARE_FRAMEWORK/COMPONENTS/MEMORY/DATA_FLASH/AT45DBX/at45dbx.c b/firmwares/wifishield/wifiHD/src/SOFTWARE_FRAMEWORK/COMPONENTS/MEMORY/DATA_FLASH/AT45DBX/at45dbx.c new file mode 100644 index 0000000..93d3dd9 --- /dev/null +++ b/firmwares/wifishield/wifiHD/src/SOFTWARE_FRAMEWORK/COMPONENTS/MEMORY/DATA_FLASH/AT45DBX/at45dbx.c @@ -0,0 +1,653 @@ +/* This source file is part of the ATMEL AVR-UC3-SoftwareFramework-1.7.0 Release */ + +/*This file is prepared for Doxygen automatic documentation generation.*/ +/*! \file ********************************************************************* + * + * \brief Management of the AT45DBX data flash controller through SPI. + * + * This file manages the accesses to the AT45DBX data flash components. + * + * - Compiler:           IAR EWAVR32 and GNU GCC for AVR32 + * - Supported devices:  All AVR32 devices with an SPI module can be used. + * - AppNote: + * + * \author               Atmel Corporation: http://www.atmel.com \n + *                       Support and FAQ: http://support.atmel.no/ + * + ******************************************************************************/ + +/* Copyright (c) 2009 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: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an Atmel + * AVR product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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 + * + */ + +//_____  I N C L U D E S ___________________________________________________ + +#include "conf_access.h" + + +#if AT45DBX_MEM == ENABLE + +#include "compiler.h" +#include "board.h" +#include "gpio.h" +#include "spi.h" +#include "conf_at45dbx.h" +#include "at45dbx.h" + + +#if AT45DBX_MEM_CNT > 4 +  #error AT45DBX_MEM_CNT must not exceed 4 +#endif + + +//_____ D E F I N I T I O N S ______________________________________________ + +/*! \name AT45DBX Group A Commands + */ +//! @{ +#define AT45DBX_CMDA_RD_PAGE              0xD2        //!< Main Memory Page Read (Serial/8-bit Mode). +#define AT45DBX_CMDA_RD_ARRAY_LEG         0xE8        //!< Continuous Array Read, Legacy Command (Serial/8-bit Mode). +#define AT45DBX_CMDA_RD_ARRAY_LF_SM       0x03        //!< Continuous Array Read, Low-Frequency Mode (Serial Mode). +#define AT45DBX_CMDA_RD_ARRAY_AF_SM       0x0B        //!< Continuous Array Read, Any-Frequency Mode (Serial Mode). +#define AT45DBX_CMDA_RD_SECTOR_PROT_REG   0x32        //!< Read Sector Protection Register (Serial/8-bit Mode). +#define AT45DBX_CMDA_RD_SECTOR_LKDN_REG   0x35        //!< Read Sector Lockdown Register (Serial/8-bit Mode). +#define AT45DBX_CMDA_RD_SECURITY_REG      0x77        //!< Read Security Register (Serial/8-bit Mode). +//! @} + +/*! \name AT45DBX Group B Commands + */ +//! @{ +#define AT45DBX_CMDB_ER_PAGE              0x81        //!< Page Erase (Serial/8-bit Mode). +#define AT45DBX_CMDB_ER_BLOCK             0x50        //!< Block Erase (Serial/8-bit Mode). +#define AT45DBX_CMDB_ER_SECTOR            0x7C        //!< Sector Erase (Serial/8-bit Mode). +#define AT45DBX_CMDB_ER_CHIP              0xC794809A  //!< Chip Erase (Serial/8-bit Mode). +#define AT45DBX_CMDB_XFR_PAGE_TO_BUF1     0x53        //!< Main Memory Page to Buffer 1 Transfer (Serial/8-bit Mode). +#define AT45DBX_CMDB_XFR_PAGE_TO_BUF2     0x55        //!< Main Memory Page to Buffer 2 Transfer (Serial/8-bit Mode). +#define AT45DBX_CMDB_CMP_PAGE_TO_BUF1     0x60        //!< Main Memory Page to Buffer 1 Compare (Serial/8-bit Mode). +#define AT45DBX_CMDB_CMP_PAGE_TO_BUF2     0x61        //!< Main Memory Page to Buffer 2 Compare (Serial/8-bit Mode). +#define AT45DBX_CMDB_PR_BUF1_TO_PAGE_ER   0x83        //!< Buffer 1 to Main Memory Page Program with Built-in Erase (Serial/8-bit Mode). +#define AT45DBX_CMDB_PR_BUF2_TO_PAGE_ER   0x86        //!< Buffer 2 to Main Memory Page Program with Built-in Erase (Serial/8-bit Mode). +#define AT45DBX_CMDB_PR_BUF1_TO_PAGE      0x88        //!< Buffer 1 to Main Memory Page Program without Built-in Erase (Serial/8-bit Mode). +#define AT45DBX_CMDB_PR_BUF2_TO_PAGE      0x89        //!< Buffer 2 to Main Memory Page Program without Built-in Erase (Serial/8-bit Mode). +#define AT45DBX_CMDB_PR_PAGE_TH_BUF1      0x82        //!< Main Memory Page Program through Buffer 1 (Serial/8-bit Mode). +#define AT45DBX_CMDB_PR_PAGE_TH_BUF2      0x85        //!< Main Memory Page Program through Buffer 2 (Serial/8-bit Mode). +#define AT45DBX_CMDB_RWR_PAGE_TH_BUF1     0x58        //!< Auto Page Rewrite through Buffer 1 (Serial/8-bit Mode). +#define AT45DBX_CMDB_RWR_PAGE_TH_BUF2     0x59        //!< Auto Page Rewrite through Buffer 2 (Serial/8-bit Mode). +//! @} + +/*! \name AT45DBX Group C Commands + */ +//! @{ +#define AT45DBX_CMDC_RD_BUF1_LF_SM        0xD1        //!< Buffer 1 Read, Low-Frequency Mode (Serial Mode). +#define AT45DBX_CMDC_RD_BUF2_LF_SM        0xD3        //!< Buffer 2 Read, Low-Frequency Mode (Serial Mode). +#define AT45DBX_CMDC_RD_BUF1_AF_SM        0xD4        //!< Buffer 1 Read, Any-Frequency Mode (Serial Mode). +#define AT45DBX_CMDC_RD_BUF2_AF_SM        0xD6        //!< Buffer 2 Read, Any-Frequency Mode (Serial Mode). +#define AT45DBX_CMDC_RD_BUF1_AF_8M        0x54        //!< Buffer 1 Read, Any-Frequency Mode (8-bit Mode). +#define AT45DBX_CMDC_RD_BUF2_AF_8M        0x56        //!< Buffer 2 Read, Any-Frequency Mode (8-bit Mode). +#define AT45DBX_CMDC_WR_BUF1              0x84        //!< Buffer 1 Write (Serial/8-bit Mode). +#define AT45DBX_CMDC_WR_BUF2              0x87        //!< Buffer 2 Write (Serial/8-bit Mode). +#define AT45DBX_CMDC_RD_STATUS_REG        0xD7        //!< Status Register Read (Serial/8-bit Mode). +#define AT45DBX_CMDC_RD_MNFCT_DEV_ID_SM   0x9F        //!< Manufacturer and Device ID Read (Serial Mode). +//! @} + +/*! \name AT45DBX Group D Commands + */ +//! @{ +#define AT45DBX_CMDD_EN_SECTOR_PROT       0x3D2A7FA9  //!< Enable Sector Protection (Serial/8-bit Mode). +#define AT45DBX_CMDD_DIS_SECTOR_PROT      0x3D2A7F9A  //!< Disable Sector Protection (Serial/8-bit Mode). +#define AT45DBX_CMDD_ER_SECTOR_PROT_REG   0x3D2A7FCF  //!< Erase Sector Protection Register (Serial/8-bit Mode). +#define AT45DBX_CMDD_PR_SECTOR_PROT_REG   0x3D2A7FFC  //!< Program Sector Protection Register (Serial/8-bit Mode). +#define AT45DBX_CMDD_LKDN_SECTOR          0x3D2A7F30  //!< Sector Lockdown (Serial/8-bit Mode). +#define AT45DBX_CMDD_PR_SECURITY_REG      0x9B000000  //!< Program Security Register (Serial/8-bit Mode). +#define AT45DBX_CMDD_PR_CONF_REG          0x3D2A80A6  //!< Program Configuration Register (Serial/8-bit Mode). +#define AT45DBX_CMDD_DEEP_PWR_DN          0xB9        //!< Deep Power-down (Serial/8-bit Mode). +#define AT45DBX_CMDD_RSM_DEEP_PWR_DN      0xAB        //!< Resume from Deep Power-down (Serial/8-bit Mode). +//! @} + + +/*! \name Bit-Masks and Values for the Status Register + */ +//! @{ +#define AT45DBX_MSK_BUSY                  0x80        //!< Busy status bit-mask. +#define AT45DBX_BUSY                      0x00        //!< Busy status value (0x00 when busy, 0x80 when ready). +#define AT45DBX_MSK_DENSITY               0x3C        //!< Device density bit-mask. +//! @} +#if AT45DBX_MEM_SIZE == AT45DBX_1MB + +/*! \name AT45DB081 Memories + */ +//! @{ +#define AT45DBX_DENSITY                   0x24        //!< Device density value. +#define AT45DBX_BYTE_ADDR_BITS             9          //!< Address bits for byte position within buffer. + +//! @} +#elif AT45DBX_MEM_SIZE == AT45DBX_2MB + +/*! \name AT45DB161 Memories + */ +//! @{ +#define AT45DBX_DENSITY                   0x2C        //!< Device density value. +#define AT45DBX_BYTE_ADDR_BITS            10          //!< Address bits for byte position within buffer. +//! @} + +#elif AT45DBX_MEM_SIZE == AT45DBX_4MB + +/*! \name AT45DB321 Memories + */ +//! @{ +#define AT45DBX_DENSITY                   0x34        //!< Device density value. +#define AT45DBX_BYTE_ADDR_BITS            10          //!< Address bits for byte position within buffer. +//! @} + +#elif AT45DBX_MEM_SIZE == AT45DBX_8MB + +/*! \name AT45DB642 Memories + */ +//! @{ +#define AT45DBX_DENSITY                   0x3C        //!< Device density value. +#define AT45DBX_BYTE_ADDR_BITS            11          //!< Address bits for byte position within buffer. +//! @} + +#else +  #error AT45DBX_MEM_SIZE is not defined to a supported value +#endif + +//! Address bits for page selection. +#define AT45DBX_PAGE_ADDR_BITS            (AT45DBX_MEM_SIZE - AT45DBX_PAGE_BITS) + +//! Number of bits for addresses within pages. +#define AT45DBX_PAGE_BITS                 (AT45DBX_BYTE_ADDR_BITS - 1) + +//! Page size in bytes. +#define AT45DBX_PAGE_SIZE                 (1 << AT45DBX_PAGE_BITS) + +//! Bit-mask for byte position within buffer in \ref gl_ptr_mem. +#define AT45DBX_MSK_PTR_BYTE              ((1 << AT45DBX_PAGE_BITS) - 1) + +//! Bit-mask for page selection in \ref gl_ptr_mem. +#define AT45DBX_MSK_PTR_PAGE              (((1 << AT45DBX_PAGE_ADDR_BITS) - 1) << AT45DBX_PAGE_BITS) + +//! Bit-mask for byte position within sector in \ref gl_ptr_mem. +#define AT45DBX_MSK_PTR_SECTOR            ((1 << AT45DBX_SECTOR_BITS) - 1) + + +/*! \brief Sends a dummy byte through SPI. + */ +#define spi_write_dummy()                 spi_write(AT45DBX_SPI, 0xFF) + + +//! Boolean indicating whether memory is in busy state. +static Bool at45dbx_busy; + +//! Memory data pointer. +static U32 gl_ptr_mem; + +//! Sector buffer. +static U8 sector_buf[AT45DBX_SECTOR_SIZE]; + + +/*! \name Control Functions + */ +//! @{ + + +Bool at45dbx_init(spi_options_t spiOptions, unsigned int pba_hz) +{ +  // Setup SPI registers according to spiOptions. +  for (spiOptions.reg = AT45DBX_SPI_FIRST_NPCS; +       spiOptions.reg < AT45DBX_SPI_FIRST_NPCS + AT45DBX_MEM_CNT; +       spiOptions.reg++) +  { +    if (spi_setupChipReg(AT45DBX_SPI, &spiOptions, pba_hz) != SPI_OK) return KO; +  } + +  // Memory ready. +  at45dbx_busy = FALSE; + +  return OK; +} + + +/*! \brief Selects or unselects a DF memory. + * + * \param memidx  Memory ID of DF to select or unselect. + * \param bSelect Boolean indicating whether the DF memory has to be selected. + */ +static void at45dbx_chipselect_df(U8 memidx, Bool bSelect) +{ +  if (bSelect) +  { +    // Select SPI chip. +    spi_selectChip(AT45DBX_SPI, AT45DBX_SPI_FIRST_NPCS + memidx); +  } +  else +  { +    // Unselect SPI chip. +    spi_unselectChip(AT45DBX_SPI, AT45DBX_SPI_FIRST_NPCS + memidx); +  } +} + + +Bool at45dbx_mem_check(void) +{ +  U8 df; +  U16 status = 0; + +  // DF memory check. +  for (df = 0; df < AT45DBX_MEM_CNT; df++) +  { +    // Select the DF memory to check. +    at45dbx_chipselect_df(df, TRUE); + +    // Send the Status Register Read command. +    spi_write(AT45DBX_SPI, AT45DBX_CMDC_RD_STATUS_REG); + +    // Send a dummy byte to read the status register. +    spi_write_dummy(); +    spi_read(AT45DBX_SPI, &status); + +    // Unselect the checked DF memory. +    at45dbx_chipselect_df(df, FALSE); + +    // Unexpected device density value. +    if ((status & AT45DBX_MSK_DENSITY) < AT45DBX_DENSITY) return KO; +  } + +  return OK; +} + + +/*! \brief Waits until the DF is ready. + */ +static void at45dbx_wait_ready(void) +{ +  U16 status; + +  // Select the DF memory gl_ptr_mem points to. +  at45dbx_chipselect_df(gl_ptr_mem >> AT45DBX_MEM_SIZE, TRUE); + +  // Send the Status Register Read command. +  spi_write(AT45DBX_SPI, AT45DBX_CMDC_RD_STATUS_REG); + +  // Read the status register until the DF is ready. +  do +  { +    // Send a dummy byte to read the status register. +    spi_write_dummy(); +    spi_read(AT45DBX_SPI, &status); +  } while ((status & AT45DBX_MSK_BUSY) == AT45DBX_BUSY); + +  // Unselect the DF memory gl_ptr_mem points to. +  at45dbx_chipselect_df(gl_ptr_mem >> AT45DBX_MEM_SIZE, FALSE); +} + + +Bool at45dbx_read_open(U32 sector) +{ +  U32 addr; + +  // Set the global memory pointer to a byte address. +  gl_ptr_mem = sector << AT45DBX_SECTOR_BITS; // gl_ptr_mem = sector * AT45DBX_SECTOR_SIZE. + +  // If the DF memory is busy, wait until it's ready. +  if (at45dbx_busy) at45dbx_wait_ready(); +  at45dbx_busy = FALSE; + +  // Select the DF memory gl_ptr_mem points to. +  at45dbx_chipselect_df(gl_ptr_mem >> AT45DBX_MEM_SIZE, TRUE); + +  // Initiate a page read at a given sector. + +  // Send the Main Memory Page Read command. +  spi_write(AT45DBX_SPI, AT45DBX_CMDA_RD_PAGE); + +  // Send the three address bytes, which comprise: +  //  - (24 - (AT45DBX_PAGE_ADDR_BITS + AT45DBX_BYTE_ADDR_BITS)) reserved bits; +  //  - then AT45DBX_PAGE_ADDR_BITS bits specifying the page in main memory to be read; +  //  - then AT45DBX_BYTE_ADDR_BITS bits specifying the starting byte address within that page. +  // NOTE: The bits of gl_ptr_mem above the AT45DBX_MEM_SIZE bits are useless for the local +  // DF addressing. They are used for DF discrimination when there are several DFs. +  addr = (Rd_bitfield(gl_ptr_mem, AT45DBX_MSK_PTR_PAGE) << AT45DBX_BYTE_ADDR_BITS) | +         Rd_bitfield(gl_ptr_mem, AT45DBX_MSK_PTR_BYTE); +  spi_write(AT45DBX_SPI, LSB2W(addr)); +  spi_write(AT45DBX_SPI, LSB1W(addr)); +  spi_write(AT45DBX_SPI, LSB0W(addr)); + +  // Send 32 don't care clock cycles to initialize the read operation. +  spi_write_dummy(); +  spi_write_dummy(); +  spi_write_dummy(); +  spi_write_dummy(); + +  return OK; +} + + +void at45dbx_read_close(void) +{ +  // Unselect the DF memory gl_ptr_mem points to. +  at45dbx_chipselect_df(gl_ptr_mem >> AT45DBX_MEM_SIZE, FALSE); + +  // Memory ready. +  at45dbx_busy = FALSE; +} + + +Bool at45dbx_write_open(U32 sector) +{ +  U32 addr; + +  // Set the global memory pointer to a byte address. +  gl_ptr_mem = sector << AT45DBX_SECTOR_BITS; // gl_ptr_mem = sector * AT45DBX_SECTOR_SIZE. + +  // If the DF memory is busy, wait until it's ready. +  if (at45dbx_busy) at45dbx_wait_ready(); +  at45dbx_busy = FALSE; + +#if AT45DBX_PAGE_SIZE > AT45DBX_SECTOR_SIZE +  // Select the DF memory gl_ptr_mem points to. +  at45dbx_chipselect_df(gl_ptr_mem >> AT45DBX_MEM_SIZE, TRUE); + +  // Transfer the content of the current page to buffer 1. + +  // Send the Main Memory Page to Buffer 1 Transfer command. +  spi_write(AT45DBX_SPI, AT45DBX_CMDB_XFR_PAGE_TO_BUF1); + +  // Send the three address bytes, which comprise: +  //  - (24 - (AT45DBX_PAGE_ADDR_BITS + AT45DBX_BYTE_ADDR_BITS)) reserved bits; +  //  - then AT45DBX_PAGE_ADDR_BITS bits specifying the page in main memory to be read; +  //  - then AT45DBX_BYTE_ADDR_BITS don't care bits. +  // NOTE: The bits of gl_ptr_mem above the AT45DBX_MEM_SIZE bits are useless for the local +  // DF addressing. They are used for DF discrimination when there are several DFs. +  addr = Rd_bitfield(gl_ptr_mem, AT45DBX_MSK_PTR_PAGE) << AT45DBX_BYTE_ADDR_BITS; +  spi_write(AT45DBX_SPI, LSB2W(addr)); +  spi_write(AT45DBX_SPI, LSB1W(addr)); +  spi_write(AT45DBX_SPI, LSB0W(addr)); + +  // Unselect the DF memory gl_ptr_mem points to. +  at45dbx_chipselect_df(gl_ptr_mem >> AT45DBX_MEM_SIZE, FALSE); + +  // Wait for end of page transfer. +  at45dbx_wait_ready(); +#endif + +  // Select the DF memory gl_ptr_mem points to. +  at45dbx_chipselect_df(gl_ptr_mem >> AT45DBX_MEM_SIZE, TRUE); + +  // Initiate a page write at a given sector. + +  // Send the Main Memory Page Program through Buffer 1 command. +  spi_write(AT45DBX_SPI, AT45DBX_CMDB_PR_PAGE_TH_BUF1); + +  // Send the three address bytes, which comprise: +  //  - (24 - (AT45DBX_PAGE_ADDR_BITS + AT45DBX_BYTE_ADDR_BITS)) reserved bits; +  //  - then AT45DBX_PAGE_ADDR_BITS bits specifying the page in main memory to be written; +  //  - then AT45DBX_BYTE_ADDR_BITS bits specifying the starting byte address within that page. +  // NOTE: The bits of gl_ptr_mem above the AT45DBX_MEM_SIZE bits are useless for the local +  // DF addressing. They are used for DF discrimination when there are several DFs. +  addr = (Rd_bitfield(gl_ptr_mem, AT45DBX_MSK_PTR_PAGE) << AT45DBX_BYTE_ADDR_BITS) | +         Rd_bitfield(gl_ptr_mem, AT45DBX_MSK_PTR_BYTE); +  spi_write(AT45DBX_SPI, LSB2W(addr)); +  spi_write(AT45DBX_SPI, LSB1W(addr)); +  spi_write(AT45DBX_SPI, LSB0W(addr)); + +  return OK; +} + + +void at45dbx_write_close(void) +{ +  // While end of logical sector not reached, zero-fill remaining memory bytes. +  while (Rd_bitfield(gl_ptr_mem, AT45DBX_MSK_PTR_SECTOR)) +  { +    spi_write(AT45DBX_SPI, 0x00); +    gl_ptr_mem++; +  } + +  // Unselect the DF memory gl_ptr_mem points to. +  at45dbx_chipselect_df(gl_ptr_mem >> AT45DBX_MEM_SIZE, FALSE); + +  // Memory busy. +  at45dbx_busy = TRUE; +} + + +//! @} + + +/*! \name Single-Byte Access Functions + */ +//! @{ + + +U8 at45dbx_read_byte(void) +{ +  U16 data; + +  // Memory busy. +  if (at45dbx_busy) +  { +    // Being here, we know that we previously finished a page read. +    // => We have to access the next page. + +    // Memory ready. +    at45dbx_busy = FALSE; + +    // Eventually select the next DF and open the next page. +    // NOTE: at45dbx_read_open input parameter is a sector. +    at45dbx_read_open(gl_ptr_mem >> AT45DBX_SECTOR_BITS); // gl_ptr_mem / AT45DBX_SECTOR_SIZE. +  } + +  // Send a dummy byte to read the next data byte. +  spi_write_dummy(); +  spi_read(AT45DBX_SPI, &data); +  gl_ptr_mem++; + +  // If end of page reached, +  if (!Rd_bitfield(gl_ptr_mem, AT45DBX_MSK_PTR_BYTE)) +  { +    // unselect the DF memory gl_ptr_mem points to. +    at45dbx_chipselect_df(gl_ptr_mem >> AT45DBX_MEM_SIZE, FALSE); + +    // Memory busy. +    at45dbx_busy = TRUE; +  } + +  return data; +} + + +Bool at45dbx_write_byte(U8 b) +{ +  // Memory busy. +  if (at45dbx_busy) +  { +    // Being here, we know that we previously launched a page programming. +    // => We have to access the next page. + +    // Eventually select the next DF and open the next page. +    // NOTE: at45dbx_write_open input parameter is a sector. +    at45dbx_write_open(gl_ptr_mem >> AT45DBX_SECTOR_BITS); // gl_ptr_mem / AT45DBX_SECTOR_SIZE. +  } + +  // Write the next data byte. +  spi_write(AT45DBX_SPI, b); +  gl_ptr_mem++; + +  // If end of page reached, +  if (!Rd_bitfield(gl_ptr_mem, AT45DBX_MSK_PTR_BYTE)) +  { +    // unselect the DF memory gl_ptr_mem points to in order to program the page. +    at45dbx_chipselect_df(gl_ptr_mem >> AT45DBX_MEM_SIZE, FALSE); + +    // Memory busy. +    at45dbx_busy = TRUE; +  } + +  return OK; +} + + +//! @} + + +/*! \name Multiple-Sector Access Functions + */ +//! @{ + + +Bool at45dbx_read_multiple_sector(U16 nb_sector) +{ +  while (nb_sector--) +  { +    // Read the next sector. +    at45dbx_read_sector_2_ram(sector_buf); +    at45dbx_read_multiple_sector_callback(sector_buf); +  } + +  return OK; +} + + +Bool at45dbx_write_multiple_sector(U16 nb_sector) +{ +  while (nb_sector--) +  { +    // Write the next sector. +    at45dbx_write_multiple_sector_callback(sector_buf); +    at45dbx_write_sector_from_ram(sector_buf); +  } + +  return OK; +} + + +//! @} + + +/*! \name Single-Sector Access Functions + */ +//! @{ + + +Bool at45dbx_read_sector_2_ram(void *ram) +{ +  U8 *_ram = ram; +  U16 i; +  U16 data; + +  // Memory busy. +  if (at45dbx_busy) +  { +    // Being here, we know that we previously finished a page read. +    // => We have to access the next page. + +    // Memory ready. +    at45dbx_busy = FALSE; + +    // Eventually select the next DF and open the next page. +    // NOTE: at45dbx_read_open input parameter is a sector. +    at45dbx_read_open(gl_ptr_mem >> AT45DBX_SECTOR_BITS); // gl_ptr_mem / AT45DBX_SECTOR_SIZE. +  } + +  // Read the next sector. +  for (i = AT45DBX_SECTOR_SIZE; i; i--) +  { +    // Send a dummy byte to read the next data byte. +    spi_write_dummy(); +    spi_read(AT45DBX_SPI, &data); +    *_ram++ = data; +  } + +  // Update the memory pointer. +  gl_ptr_mem += AT45DBX_SECTOR_SIZE; + +#if AT45DBX_PAGE_SIZE > AT45DBX_SECTOR_SIZE +  // If end of page reached, +  if (!Rd_bitfield(gl_ptr_mem, AT45DBX_MSK_PTR_BYTE)) +#endif +  { +    // unselect the DF memory gl_ptr_mem points to. +    at45dbx_chipselect_df(gl_ptr_mem >> AT45DBX_MEM_SIZE, FALSE); + +    // Memory busy. +    at45dbx_busy = TRUE; +  } + +  return OK; +} + + +Bool at45dbx_write_sector_from_ram(const void *ram) +{ +  const U8 *_ram = ram; +  U16 i; + +  // Memory busy. +  if (at45dbx_busy) +  { +    // Being here, we know that we previously launched a page programming. +    // => We have to access the next page. + +    // Eventually select the next DF and open the next page. +    // NOTE: at45dbx_write_open input parameter is a sector. +    at45dbx_write_open(gl_ptr_mem >> AT45DBX_SECTOR_BITS); // gl_ptr_mem / AT45DBX_SECTOR_SIZE. +  } + +  // Write the next sector. +  for (i = AT45DBX_SECTOR_SIZE; i; i--) +  { +    // Write the next data byte. +    spi_write(AT45DBX_SPI, *_ram++); +  } + +  // Update the memory pointer. +  gl_ptr_mem += AT45DBX_SECTOR_SIZE; + +#if AT45DBX_PAGE_SIZE > AT45DBX_SECTOR_SIZE +  // If end of page reached, +  if (!Rd_bitfield(gl_ptr_mem, AT45DBX_MSK_PTR_BYTE)) +#endif +  { +    // unselect the DF memory gl_ptr_mem points to in order to program the page. +    at45dbx_chipselect_df(gl_ptr_mem >> AT45DBX_MEM_SIZE, FALSE); + +    // Memory busy. +    at45dbx_busy = TRUE; +  } + +  return OK; +} + + +//! @} + + +#endif  // AT45DBX_MEM == ENABLE diff --git a/firmwares/wifishield/wifiHD/src/SOFTWARE_FRAMEWORK/COMPONENTS/MEMORY/DATA_FLASH/AT45DBX/at45dbx.h b/firmwares/wifishield/wifiHD/src/SOFTWARE_FRAMEWORK/COMPONENTS/MEMORY/DATA_FLASH/AT45DBX/at45dbx.h new file mode 100644 index 0000000..e5263b2 --- /dev/null +++ b/firmwares/wifishield/wifiHD/src/SOFTWARE_FRAMEWORK/COMPONENTS/MEMORY/DATA_FLASH/AT45DBX/at45dbx.h @@ -0,0 +1,270 @@ +/* This header file is part of the ATMEL AVR-UC3-SoftwareFramework-1.7.0 Release */ + +/*This file is prepared for Doxygen automatic documentation generation.*/ +/*! \file ********************************************************************* + * + * \brief Management of the AT45DBX data flash controller through SPI. + * + * This file manages the accesses to the AT45DBX data flash components. + * + * - Compiler:           IAR EWAVR32 and GNU GCC for AVR32 + * - Supported devices:  All AVR32 devices with an SPI module can be used. + * - AppNote: + * + * \author               Atmel Corporation: http://www.atmel.com \n + *                       Support and FAQ: http://support.atmel.no/ + * + ******************************************************************************/ + +/* Copyright (c) 2009 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: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an Atmel + * AVR product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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 + * + */ + +#ifndef _AT45DBX_H_ +#define _AT45DBX_H_ + + +#include "conf_access.h" + +#if AT45DBX_MEM == DISABLE +  #error at45dbx.h is #included although AT45DBX_MEM is disabled +#endif + + +#include "spi.h" + + +//_____ D E F I N I T I O N S ______________________________________________ + +/*! \name Available AT45DBX Sizes + * + * Number of address bits of available AT45DBX data flash memories. + * + * \note Only memories with page sizes of at least 512 bytes (sector size) are + *       supported. + */ +//! @{ +#define AT45DBX_1MB             20 +#define AT45DBX_2MB             21 +#define AT45DBX_4MB             22 +#define AT45DBX_8MB             23 +//! @} + +// AT45DBX_1MB +#define AT45DBX_SECTOR_BITS     			8		  //! Number of bits for addresses within sectors. +// AT45DBX_2MB AT45DBX_4MB AT45DBX_8MB +//#define AT45DBX_SECTOR_BITS     			9		  //! Number of bits for addresses within sectors. + +//! Sector size in bytes. +#define AT45DBX_SECTOR_SIZE     (1 << AT45DBX_SECTOR_BITS) + + +//_____ D E C L A R A T I O N S ____________________________________________ + +/*! \name Control Functions + */ +//! @{ + +/*! \brief Initializes the data flash controller and the SPI channel by which + *         the DF is controlled. + * + * \param spiOptions  Initialization options of the DF SPI channel. + * \param pba_hz      SPI module input clock frequency (PBA clock, Hz). + * + * \retval OK Success. + * \retval KO Failure. + */ +extern Bool at45dbx_init(spi_options_t spiOptions, unsigned int pba_hz); + +/*! \brief Performs a memory check on all DFs. + * + * \retval OK Success. + * \retval KO Failure. + */ +extern Bool at45dbx_mem_check(void); + +/*! \brief Opens a DF memory in read mode at a given sector. + * + * \param sector  Start sector. + * + * \retval OK Success. + * \retval KO Failure. + * + * \note Sector may be page-unaligned (depending on the DF page size). + */ +extern Bool at45dbx_read_open(U32 sector); + +/*! \brief Unselects the current DF memory. + */ +extern void at45dbx_read_close(void); + +/*! \brief This function opens a DF memory in write mode at a given sector. + * + * \param sector  Start sector. + * + * \retval OK Success. + * \retval KO Failure. + * + * \note Sector may be page-unaligned (depending on the DF page size). + * + * \note If \ref AT45DBX_PAGE_SIZE > \ref AT45DBX_SECTOR_SIZE, page content is + *       first loaded in buffer to then be partially updated by write byte or + *       write sector functions. + */ +extern Bool at45dbx_write_open(U32 sector); + +/*! \brief Fills the end of the current logical sector and launches page programming. + */ +extern void at45dbx_write_close(void); + +//! @} + + +/*! \name Single-Byte Access Functions + */ +//! @{ + +/*! \brief Performs a single byte read from DF memory. + * + * \return The read byte. + * + * \note First call must be preceded by a call to the \ref at45dbx_read_open + *       function. + */ +extern U8 at45dbx_read_byte(void); + +/*! \brief Performs a single byte write to DF memory. + * + * \param b The byte to write. + * + * \retval OK Success. + * \retval KO Failure. + * + * \note First call must be preceded by a call to the \ref at45dbx_write_open + *       function. + */ +extern Bool at45dbx_write_byte(U8 b); + +//! @} + + +/*! \name Multiple-Sector Access Functions + */ +//! @{ + +/*! \brief Reads \a nb_sector sectors from DF memory. + * + * Data flow is: DF -> callback. + * + * \param nb_sector Number of contiguous sectors to read. + * + * \retval OK Success. + * \retval KO Failure. + * + * \note First call must be preceded by a call to the \ref at45dbx_read_open + *       function. + * + * \note As \ref AT45DBX_PAGE_SIZE is always a multiple of + *       \ref AT45DBX_SECTOR_SIZE, there is no need to check page end for each + *       byte. + */ +extern Bool at45dbx_read_multiple_sector(U16 nb_sector); + +/*! \brief Callback function invoked after each sector read during + *         \ref at45dbx_read_multiple_sector. + * + * \param psector Pointer to read sector. + */ +extern void at45dbx_read_multiple_sector_callback(const void *psector); + +/*! \brief Writes \a nb_sector sectors to DF memory. + * + * Data flow is: callback -> DF. + * + * \param nb_sector Number of contiguous sectors to write. + * + * \retval OK Success. + * \retval KO Failure. + * + * \note First call must be preceded by a call to the \ref at45dbx_write_open + *       function. + * + * \note As \ref AT45DBX_PAGE_SIZE is always a multiple of + *       \ref AT45DBX_SECTOR_SIZE, there is no need to check page end for each + *       byte. + */ +extern Bool at45dbx_write_multiple_sector(U16 nb_sector); + +/*! \brief Callback function invoked before each sector write during + *         \ref at45dbx_write_multiple_sector. + * + * \param psector Pointer to sector to write. + */ +extern void at45dbx_write_multiple_sector_callback(void *psector); + +//! @} + + +/*! \name Single-Sector Access Functions + */ +//! @{ + +/*! \brief Reads 1 DF sector to a RAM buffer. + * + * Data flow is: DF -> RAM. + * + * \param ram Pointer to RAM buffer. + * + * \retval OK Success. + * \retval KO Failure. + * + * \note First call must be preceded by a call to the \ref at45dbx_read_open + *       function. + */ +extern Bool at45dbx_read_sector_2_ram(void *ram); + +/*! \brief Writes 1 DF sector from a RAM buffer. + * + * Data flow is: RAM -> DF. + * + * \param ram Pointer to RAM buffer. + * + * \retval OK Success. + * \retval KO Failure. + * + * \note First call must be preceded by a call to the \ref at45dbx_write_open + *       function. + */ +extern Bool at45dbx_write_sector_from_ram(const void *ram); + +//! @} + + +#endif  // _AT45DBX_H_ diff --git a/firmwares/wifishield/wifiHD/src/SOFTWARE_FRAMEWORK/COMPONENTS/MEMORY/DATA_FLASH/AT45DBX/at45dbx_mem.c b/firmwares/wifishield/wifiHD/src/SOFTWARE_FRAMEWORK/COMPONENTS/MEMORY/DATA_FLASH/AT45DBX/at45dbx_mem.c new file mode 100644 index 0000000..4c0ace2 --- /dev/null +++ b/firmwares/wifishield/wifiHD/src/SOFTWARE_FRAMEWORK/COMPONENTS/MEMORY/DATA_FLASH/AT45DBX/at45dbx_mem.c @@ -0,0 +1,234 @@ +/* This source file is part of the ATMEL AVR-UC3-SoftwareFramework-1.7.0 Release */ + +/*This file is prepared for Doxygen automatic documentation generation.*/ +/*! \file ********************************************************************* + * + * \brief CTRL_ACCESS interface for the AT45DBX data flash controller. + * + * - Compiler:           IAR EWAVR32 and GNU GCC for AVR32 + * - Supported devices:  All AVR32 devices with an SPI module can be used. + * - AppNote: + * + * \author               Atmel Corporation: http://www.atmel.com \n + *                       Support and FAQ: http://support.atmel.no/ + * + ******************************************************************************/ + +/* Copyright (c) 2009 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: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an Atmel + * AVR product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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 + * + */ + +//_____  I N C L U D E S ___________________________________________________ + +#include "conf_access.h" + + +#if AT45DBX_MEM == ENABLE + +#include "conf_at45dbx.h" +#include "at45dbx.h" +#include "at45dbx_mem.h" + + +//_____ D E F I N I T I O N S ______________________________________________ + +//! Whether to detect write accesses to the memory. +#define AT45DBX_MEM_TEST_CHANGE_STATE     ENABLED + + +#if (ACCESS_USB == ENABLED || ACCESS_MEM_TO_RAM == ENABLED) && AT45DBX_MEM_TEST_CHANGE_STATE == ENABLED + +//! Memory data modified flag. +static volatile Bool s_b_data_modify = FALSE; + +#endif + + +/*! \name Control Interface + */ +//! @{ + + +Ctrl_status at45dbx_test_unit_ready(void) +{ +  return (at45dbx_mem_check() == OK) ? CTRL_GOOD : CTRL_NO_PRESENT; +} + + +Ctrl_status at45dbx_read_capacity(U32 *u32_nb_sector) +{ +  *u32_nb_sector = (AT45DBX_MEM_CNT << (AT45DBX_MEM_SIZE - AT45DBX_SECTOR_BITS)) - 1; + +  return CTRL_GOOD; +} + + +Bool at45dbx_wr_protect(void) +{ +  return FALSE; +} + + +Bool at45dbx_removal(void) +{ +  return FALSE; +} + + +//! @} + + +#if ACCESS_USB == ENABLED + +#include "usb_drv.h" +#include "scsi_decoder.h" + + +/*! \name MEM <-> USB Interface + */ +//! @{ + + +Ctrl_status at45dbx_usb_read_10(U32 addr, U16 nb_sector) +{ +  if (addr + nb_sector > AT45DBX_MEM_CNT << (AT45DBX_MEM_SIZE - AT45DBX_SECTOR_BITS)) return CTRL_FAIL; + +  at45dbx_read_open(addr); +  at45dbx_read_multiple_sector(nb_sector); +  at45dbx_read_close(); + +  return CTRL_GOOD; +} + + +void at45dbx_read_multiple_sector_callback(const void *psector) +{ +  U16 data_to_transfer = AT45DBX_SECTOR_SIZE; + +  // Transfer read sector to the USB interface. +  while (data_to_transfer) +  { +    while (!Is_usb_in_ready(g_scsi_ep_ms_in)) +    { +      if(!Is_usb_endpoint_enabled(g_scsi_ep_ms_in)) +         return; // USB Reset +    }          + +    Usb_reset_endpoint_fifo_access(g_scsi_ep_ms_in); +    data_to_transfer = usb_write_ep_txpacket(g_scsi_ep_ms_in, psector, +                                             data_to_transfer, &psector); +    Usb_ack_in_ready_send(g_scsi_ep_ms_in); +  } +} + + +Ctrl_status at45dbx_usb_write_10(U32 addr, U16 nb_sector) +{ +  if (addr + nb_sector > AT45DBX_MEM_CNT << (AT45DBX_MEM_SIZE - AT45DBX_SECTOR_BITS)) return CTRL_FAIL; + +#if AT45DBX_MEM_TEST_CHANGE_STATE == ENABLED +  if (nb_sector) s_b_data_modify = TRUE; +#endif + +  at45dbx_write_open(addr); +  at45dbx_write_multiple_sector(nb_sector); +  at45dbx_write_close(); + +  return CTRL_GOOD; +} + + +void at45dbx_write_multiple_sector_callback(void *psector) +{ +  U16 data_to_transfer = AT45DBX_SECTOR_SIZE; + +  // Transfer sector to write from the USB interface. +  while (data_to_transfer) +  { +    while (!Is_usb_out_received(g_scsi_ep_ms_out)) +    { +      if(!Is_usb_endpoint_enabled(g_scsi_ep_ms_out)) +         return; // USB Reset +    }          + +    Usb_reset_endpoint_fifo_access(g_scsi_ep_ms_out); +    data_to_transfer = usb_read_ep_rxpacket(g_scsi_ep_ms_out, psector, +                                            data_to_transfer, &psector); +    Usb_ack_out_received_free(g_scsi_ep_ms_out); +  } +} + + +//! @} + +#endif  // ACCESS_USB == ENABLED + + +#if ACCESS_MEM_TO_RAM == ENABLED + +/*! \name MEM <-> RAM Interface + */ +//! @{ + + +Ctrl_status at45dbx_df_2_ram(U32 addr, void *ram) +{ +  if (addr + 1 > AT45DBX_MEM_CNT << (AT45DBX_MEM_SIZE - AT45DBX_SECTOR_BITS)) return CTRL_FAIL; + +  at45dbx_read_open(addr); +  at45dbx_read_sector_2_ram(ram); +  at45dbx_read_close(); + +  return CTRL_GOOD; +} + + +Ctrl_status at45dbx_ram_2_df(U32 addr, const void *ram) +{ +  if (addr + 1 > AT45DBX_MEM_CNT << (AT45DBX_MEM_SIZE - AT45DBX_SECTOR_BITS)) return CTRL_FAIL; + +#if AT45DBX_MEM_TEST_CHANGE_STATE == ENABLED +  s_b_data_modify = TRUE; +#endif + +  at45dbx_write_open(addr); +  at45dbx_write_sector_from_ram(ram); +  at45dbx_write_close(); + +  return CTRL_GOOD; +} + + +//! @} + +#endif  // ACCESS_MEM_TO_RAM == ENABLED + + +#endif  // AT45DBX_MEM == ENABLE diff --git a/firmwares/wifishield/wifiHD/src/SOFTWARE_FRAMEWORK/COMPONENTS/MEMORY/DATA_FLASH/AT45DBX/at45dbx_mem.h b/firmwares/wifishield/wifiHD/src/SOFTWARE_FRAMEWORK/COMPONENTS/MEMORY/DATA_FLASH/AT45DBX/at45dbx_mem.h new file mode 100644 index 0000000..de24fa3 --- /dev/null +++ b/firmwares/wifishield/wifiHD/src/SOFTWARE_FRAMEWORK/COMPONENTS/MEMORY/DATA_FLASH/AT45DBX/at45dbx_mem.h @@ -0,0 +1,164 @@ +/* This header file is part of the ATMEL AVR-UC3-SoftwareFramework-1.7.0 Release */ + +/*This file is prepared for Doxygen automatic documentation generation.*/ +/*! \file ********************************************************************* + * + * \brief CTRL_ACCESS interface for the AT45DBX data flash controller. + * + * - Compiler:           IAR EWAVR32 and GNU GCC for AVR32 + * - Supported devices:  All AVR32 devices with an SPI module can be used. + * - AppNote: + * + * \author               Atmel Corporation: http://www.atmel.com \n + *                       Support and FAQ: http://support.atmel.no/ + * + ******************************************************************************/ + +/* Copyright (c) 2009 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: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an Atmel + * AVR product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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 + * + */ + +#ifndef _AT45DBX_MEM_H_ +#define _AT45DBX_MEM_H_ + + +#include "conf_access.h" + +#if AT45DBX_MEM == DISABLE +  #error at45dbx_mem.h is #included although AT45DBX_MEM is disabled +#endif + + +#include "ctrl_access.h" + + +//_____ D E C L A R A T I O N S ____________________________________________ + +/*! \name Control Interface + */ +//! @{ + +/*! \brief Tests the memory state and initializes the memory if required. + * + * The TEST UNIT READY SCSI primary command allows an application client to poll + * a LUN until it is ready without having to allocate memory for returned data. + * + * This command may be used to check the media status of LUNs with removable + * media. + * + * \return Status. + */ +extern Ctrl_status at45dbx_test_unit_ready(void); + +/*! \brief Returns the address of the last valid sector in the memory. + * + * \param u32_nb_sector Pointer to the address of the last valid sector. + * + * \return Status. + */ +extern Ctrl_status at45dbx_read_capacity(U32 *u32_nb_sector); + +/*! \brief Returns the write-protection state of the memory. + * + * \return \c TRUE if the memory is write-protected, else \c FALSE. + * + * \note Only used by removable memories with hardware-specific write + *       protection. + */ +extern Bool at45dbx_wr_protect(void); + +/*! \brief Tells whether the memory is removable. + * + * \return \c TRUE if the memory is removable, else \c FALSE. + */ +extern Bool at45dbx_removal(void); + +//! @} + + +#if ACCESS_USB == ENABLED + +/*! \name MEM <-> USB Interface + */ +//! @{ + +/*! \brief Tranfers data from the memory to USB. + * + * \param addr      Address of first memory sector to read. + * \param nb_sector Number of sectors to transfer. + * + * \return Status. + */ +extern Ctrl_status at45dbx_usb_read_10(U32 addr, U16 nb_sector); + +/*! \brief Tranfers data from USB to the memory. + * + * \param addr      Address of first memory sector to write. + * \param nb_sector Number of sectors to transfer. + * + * \return Status. + */ +extern Ctrl_status at45dbx_usb_write_10(U32 addr, U16 nb_sector); + +//! @} + +#endif + + +#if ACCESS_MEM_TO_RAM == ENABLED + +/*! \name MEM <-> RAM Interface + */ +//! @{ + +/*! \brief Copies 1 data sector from the memory to RAM. + * + * \param addr  Address of first memory sector to read. + * \param ram   Pointer to RAM buffer to write. + * + * \return Status. + */ +extern Ctrl_status at45dbx_df_2_ram(U32 addr, void *ram); + +/*! \brief Copies 1 data sector from RAM to the memory. + * + * \param addr  Address of first memory sector to write. + * \param ram   Pointer to RAM buffer to read. + * + * \return Status. + */ +extern Ctrl_status at45dbx_ram_2_df(U32 addr, const void *ram); + +//! @} + +#endif + + +#endif  // _AT45DBX_MEM_H_ | 
