SAMV71 Xplained Ultra Software Package 1.4

at45d.c

00001 /* ----------------------------------------------------------------------------
00002  *         SAM Software Package License
00003  * ----------------------------------------------------------------------------
00004  * Copyright (c) 2014, 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 //------------------------------------------------------------------------------
00031 //         Headers
00032 //------------------------------------------------------------------------------
00033 
00034 #include "at45.h"
00035 #include "at45d.h"
00036 #include "board.h"
00037 #include <assert.h>
00038 
00039 //------------------------------------------------------------------------------
00040 //         Local functions
00041 //------------------------------------------------------------------------------
00042 
00043 //------------------------------------------------------------------------------
00044 /// Wait for transfer to finish calling the SPI driver ISR (interrupts are
00045 /// disabled).
00046 /// \param pAt45  Pointer to an AT45 driver instance.
00047 //------------------------------------------------------------------------------
00048 static void AT45D_Wait(At45 *pAt45)
00049 {
00050     SANITY_CHECK(pAt45);
00051 
00052     // Wait for transfer to finish
00053     while (AT45_IsBusy(pAt45)) {
00054         SPID_Handler(pAt45->pSpid);
00055     }
00056 }
00057 
00058 
00059 //------------------------------------------------------------------------------
00060 //         Global functions
00061 //------------------------------------------------------------------------------
00062 
00063 //------------------------------------------------------------------------------
00064 /// Waits for the At45 to be ready to accept new commands.
00065 /// \param pAt45  Pointer to a At45 driver instance.
00066 //------------------------------------------------------------------------------
00067 void AT45D_WaitReady(At45 *pAt45) 
00068 {
00069     unsigned char ready = 0;
00070 
00071     SANITY_CHECK(pAt45);
00072 
00073     // Poll device until it is ready
00074     while (!ready) {
00075         ready = AT45_STATUS_READY(AT45D_GetStatus(pAt45));
00076     }
00077 }
00078 
00079 //------------------------------------------------------------------------------
00080 /// Retrieves and returns the At45 current status, or 0 if an error
00081 /// happened.
00082 /// \param pAt45  Pointer to a At45 driver instance.
00083 //------------------------------------------------------------------------------
00084 unsigned char AT45D_GetStatus(At45 *pAt45)
00085 {
00086     unsigned char error;
00087     unsigned char status;
00088 
00089     SANITY_CHECK(pAt45);
00090 
00091     // Issue a status register read command
00092     error = AT45_SendCommand(pAt45, AT45_STATUS_READ, 1, &status, 1, 0, 0, 0);
00093     ASSERT(!error, "-F- AT45_GetStatus: Failed to issue command.\n\r");
00094 
00095     // Wait for command to terminate
00096     while (AT45_IsBusy(pAt45)) {
00097     
00098         AT45D_Wait(pAt45);
00099     }
00100 
00101     return status;
00102 }
00103 
00104 //------------------------------------------------------------------------------
00105 /// Reads data from the At45 inside the provided buffer. Since a continuous
00106 /// read command is used, there is no restriction on the buffer size and read
00107 /// address.
00108 /// \param pAt45  Pointer to a At45 driver instance.
00109 /// \param pBuffer  Data buffer.
00110 /// \param size  Number of bytes to read.
00111 /// \param address  Address at which data shall be read.
00112 //------------------------------------------------------------------------------
00113 void AT45D_Read(
00114     At45 *pAt45,
00115     unsigned char *pBuffer,
00116     unsigned int size,
00117     unsigned int address) 
00118 {
00119     unsigned char error;
00120 
00121     SANITY_CHECK(pAt45);
00122     SANITY_CHECK(pBuffer);
00123 
00124     // Issue a continuous read array command
00125     error = AT45_SendCommand(
00126                 pAt45, AT45_CONTINUOUS_READ_LEG, 8, pBuffer, size, address, 0, 0);
00127     ASSERT(!error, "-F- AT45_Read: Failed to issue command\n\r");
00128 
00129     // Wait for the read command to execute
00130     while (AT45_IsBusy(pAt45)) {
00131     
00132         AT45D_Wait(pAt45);
00133     }
00134 }
00135 
00136 //------------------------------------------------------------------------------
00137 /// Writes data on the At45 at the specified address. Only one page of
00138 /// data is written that way; if the address is not at the beginning of the
00139 /// page, the data is written starting from this address and wraps around to
00140 /// the beginning of the page.
00141 /// \param pAt45  Pointer to a At45 driver instance.
00142 /// \param pBuffer  Buffer containing the data to write.
00143 /// \param size  Number of bytes to write.
00144 /// \param address  Destination address on the At45.
00145 //------------------------------------------------------------------------------
00146 void AT45D_Write(
00147     At45 *pAt45,
00148     unsigned char *pBuffer,
00149     unsigned int size,
00150     unsigned int address) 
00151 {
00152     unsigned char error;
00153 
00154     SANITY_CHECK(pAt45);
00155     SANITY_CHECK(pBuffer);
00156     SANITY_CHECK(size <= pAt45->pDesc->pageSize);
00157 
00158     // Issue a page write through buffer 1 command
00159     error = AT45_SendCommand(
00160                     pAt45, AT45_PAGE_WRITE_BUF1, 4, pBuffer, size, address, 0, 0);
00161     ASSERT(!error, "-F- AT45_Write: Could not issue command.\n\r");
00162 
00163     // Wait until the command is sent
00164     while (AT45_IsBusy(pAt45)) {
00165         AT45D_Wait(pAt45);
00166     }
00167 
00168     // Wait until the At45 becomes ready again
00169     AT45D_WaitReady(pAt45);
00170 }
00171 
00172 //------------------------------------------------------------------------------
00173 /// Erases a page of data at the given address in the At45.
00174 /// \param pAt45  Pointer to a At45 driver instance.
00175 /// \param address  Address of page to erase.
00176 //------------------------------------------------------------------------------
00177 void AT45D_Erase(At45 *pAt45, unsigned int address) 
00178 {
00179     unsigned char error;
00180 
00181     SANITY_CHECK(pAt45);
00182 
00183     // Issue a page erase command.
00184     error = AT45_SendCommand(pAt45, AT45_PAGE_ERASE, 4, 0, 0, address, 0, 0);
00185     ASSERT(!error, "-F- AT45_Erase: Could not issue command.\n\r");
00186 
00187     // Wait for end of transfer
00188     while (AT45_IsBusy(pAt45)) {
00189         AT45D_Wait(pAt45);
00190     }
00191 
00192     // Poll until the At45 has completed the erase operation
00193     AT45D_WaitReady(pAt45);
00194 }
00195 
00196 //------------------------------------------------------------------------------
00197 /// Configure power-of-2 binary page size in the At45.
00198 /// \param pAt45  Pointer to a At45 driver instance.
00199 //------------------------------------------------------------------------------
00200 
00201 void AT45D_BinaryPage(At45 *pAt45) 
00202 {
00203     unsigned char error;
00204     unsigned char opcode[3]= {AT45_BINARY_PAGE};
00205     SANITY_CHECK(pAt45);
00206 
00207     // Issue a binary page command.
00208 
00209     error = AT45_SendCommand(
00210                 pAt45, AT45_BINARY_PAGE_FIRST_OPCODE, 1, opcode, 3, 0, 0, 0);
00211    
00212     ASSERT(!error, "-F- AT45_Erase: Could not issue command.\n\r");
00213 
00214     // Wait for end of transfer
00215     while (AT45_IsBusy(pAt45)) {
00216     
00217         AT45D_Wait(pAt45);
00218     }
00219 
00220     // Wait until the At45 becomes ready again
00221     AT45D_WaitReady(pAt45);
00222 }
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines