]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/CORTEX_M7_SAMV71_Xplained_IAR_Keil/libboard_samv7-ek/source/s25fl1_qspi.c
Final V8.2.1 release ready for tagging:
[freertos] / FreeRTOS / Demo / CORTEX_M7_SAMV71_Xplained_IAR_Keil / libboard_samv7-ek / source / s25fl1_qspi.c
1 /* ----------------------------------------------------------------------------\r
2  *         SAM Software Package License \r
3  * ----------------------------------------------------------------------------\r
4  * Copyright (c) 2013, Atmel Corporation\r
5  *\r
6  * All rights reserved.\r
7  *\r
8  * Redistribution and use in source and binary forms, with or without\r
9  * modification, are permitted provided that the following conditions are met:\r
10  *\r
11  * - Redistributions of source code must retain the above copyright notice,\r
12  * this list of conditions and the disclaimer below.\r
13  *\r
14  * Atmel's name may not be used to endorse or promote products derived from\r
15  * this software without specific prior written permission.\r
16  *\r
17  * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR\r
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE\r
20  * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,\r
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r
22  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\r
23  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\r
24  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\r
25  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\r
26  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
27  * ----------------------------------------------------------------------------\r
28  */\r
29 \r
30 \r
31 /** \r
32  * \addtogroup at25_spi_module S25FL1 SPI driver\r
33  * \ingroup lib_spiflash\r
34  *\r
35  * The S25FL1 serial firmware dataflash driver is based on top of the\r
36  * corresponding Spi driver. A Dataflash structure instance has to be\r
37  * initialized using the S25FL1_Configure() function. Then a command can be send \r
38  * to the serial flash using the SPI_SendCommand() function. \r
39  *\r
40  * \section Usage\r
41  * <ul>\r
42  * <li>Initializes an S25FL1 instance and configures SPI chip select pin\r
43  *    using S25FL1_Configure(). </li>\r
44  * <li>Detect DF and returns DF description corresponding to the device\r
45  *    connected using S25FL1D_ReadJedecId() and S25FL1_FindDevice().\r
46  *    This function shall be called by the application before S25FL1_SendCommand().</li>\r
47  * <li> Sends a command to the DF through the SPI using S25FL1_SendCommand().\r
48  *    The command is identified by its command code and the number of\r
49  *    bytes to transfer.</li>\r
50  *    <li> Example code for sending command to write a page to DF.</li>\r
51  *    \code\r
52  *        // Program page\r
53  *        error = S25FL1_SendCommand(pS25fl1, S25FL1_BYTE_PAGE_PROGRAM, 4,\r
54  *                pData, writeSize, address, 0, 0);\r
55  *    \endcode\r
56  *    <li> Example code for sending command to read a page from DF.\r
57  *       If data needs to be received, then a data buffer must be\r
58  *       provided.</li>\r
59  *    \code\r
60  *        // Start a read operation\r
61  *        error = S25FL1_SendCommand(pS25fl1, S25FL1_READ_ARRAY_LF,\r
62  *                4, pData, size, address, 0, 0);\r
63  *    \endcode\r
64  *    <li> This function does not block; its optional callback will\r
65  *       be invoked when the transfer completes.</li>\r
66  * <li> Check the S25FL1 driver is ready or not by polling S25FL1_IsBusy().</li>\r
67  * </ul>\r
68  *\r
69  * Related files :\n\r
70  * \ref at25_spi.c\n\r
71  * \ref at25_spi.h.\n\r
72  */\r
73 \r
74 /**\r
75  * \file\r
76  *\r
77  * Implementation for the S25FL1 SPI driver.\r
78  *\r
79  */\r
80 \r
81 /*----------------------------------------------------------------------------\r
82  *        Headers\r
83  *----------------------------------------------------------------------------*/\r
84 #include <board.h>\r
85 //#include <libspiflash.h>\r
86 #include <assert.h>\r
87 \r
88 /*----------------------------------------------------------------------------\r
89  *        Local definitions\r
90  *----------------------------------------------------------------------------*/\r
91 \r
92 \r
93 \r
94 /*----------------------------------------------------------------------------\r
95  *        Exported functions\r
96  *----------------------------------------------------------------------------*/\r
97 \r
98 /**\r
99  * \brief Initializes an S25FL1 driver instance with the given SPI driver and chip\r
100  * select value.\r
101  *\r
102  * \param pS25fl1  Pointer to an S25FL1 driver instance.\r
103  * \param pSpid  Pointer to an SPI driver instance.\r
104  * \param cs  Chip select value to communicate with the serial flash.\r
105  * \param polling Uses polling mode instead of IRQ trigger.\r
106  */\r
107 void S25FL1_Configure(S25fl1 *pS25fl1, Qspid *pQspid, uint8_t polling)\r
108 {\r
109     SpidCmd *pCommand;\r
110 \r
111     assert(pS25fl1);\r
112     assert(pQSpid);\r
113 \r
114 \r
115     /* Initialize the S25FL1 fields */\r
116     pS25fl1->pQspid = pSpid;\r
117     pS25fl1->pDesc = 0;\r
118     pS25fl1->pollingMode = polling;\r
119 \r
120     /* Initialize the command structure */\r
121     pCommand = &(pS25fl1->command);\r
122     pCommand->pCmd = (uint8_t *) pS25fl1->CmdBuffer;\r
123     pCommand->callback = 0;\r
124     pCommand->pArgument = 0;\r
125 }\r
126 \r
127 /**\r
128  * \brief Is serial flash driver busy.\r
129  *\r
130  * \param pS25fl1  Pointer to an S25fl1 driver instance.\r
131  *\r
132  * \return 1 if the serial flash driver is currently busy executing a command;\r
133  * otherwise returns 0.\r
134  */\r
135 uint8_t S25FL1_IsBusy(S25fl1 *pS25fl1)\r
136 {\r
137     if (pS25fl1->pollingMode)\r
138     {\r
139         SPID_Handler(pS25fl1->pSpid);\r
140         SPID_DmaHandler(pS25fl1->pSpid);\r
141     }\r
142     return SPID_IsBusy(pS25fl1->pSpid);\r
143 }\r
144 \r
145 /**\r
146  * \brief Sends a command to the serial flash through the SPI. The command is made up\r
147  * of two parts: the first is used to transmit the command byte and optionally,\r
148  * address and dummy bytes. The second part is the data to send or receive.\r
149  * This function does not block: it returns as soon as the transfer has been\r
150  * started. An optional callback can be invoked to notify the end of transfer.\r
151  *\r
152  * \param pS25fl1  Pointer to an S25fl1 driver instance.\r
153  * \param cmd  Command byte.\r
154  * \param cmdSize  Size of command (command byte + address bytes + dummy bytes).\r
155  * \param pData Data buffer.\r
156  * \param dataSize  Number of bytes to send/receive.\r
157  * \param address  Address to transmit.\r
158  * \param callback  Optional user-provided callback to invoke at end of transfer.\r
159  * \param pArgument  Optional argument to the callback function.\r
160  *\r
161  * \return 0 if successful; otherwise, returns S25FL1_ERROR_BUSY if the S25FL1\r
162  * driver is currently executing a command, or S25FL1_ERROR_SPI if the command\r
163  * cannot be sent because of a SPI error.\r
164  */\r
165 uint8_t S25FL1_SendCommand(uint8_t Instr, uint8_t ReadWrite)\r
166 \r
167 {  \r
168     pDev->Instruction = Instr; \r
169     QSPI_SendFrame(QSPI, pDev, ReadWrite);\r
170 }\r
171 \r
172 /**\r
173  * \brief Tries to detect a serial firmware flash device given its JEDEC identifier.\r
174  * The JEDEC id can be retrieved by sending the correct command to the device.\r
175  *\r
176  * \param pS25fl1  Pointer to an S25FL1 driver instance.\r
177  * \param jedecId  JEDEC identifier of device.\r
178  *\r
179  * \return the corresponding S25FL1 descriptor if found; otherwise returns 0.\r
180  */\r
181 const S25fl1Desc * S25FL1_FindDevice(S25fl1 *pS25fl1, uint32_t jedecId)\r
182 {\r
183     uint32_t i = 0;\r
184 \r
185     assert(pS25fl1);\r
186 \r
187     /* Search if device is recognized */\r
188     pS25fl1->pDesc = 0;\r
189     while ((i < NUMDATAFLASH) && !(pS25fl1->pDesc)) {\r
190 \r
191         if ((jedecId & 0xFF00FFFF) == (at25Devices[i].jedecId & 0xFF00FFFF)) {\r
192 \r
193             pS25fl1->pDesc = &(at25Devices[i]);\r
194         }\r
195 \r
196         i++;\r
197     }\r
198 \r
199     return pS25fl1->pDesc;\r
200 }\r