86ef90294e618d596360b2e83f995c4131d56ba9
1 /*\r
2 * Copyright (C) 2020 Texas Instruments Incorporated - http://www.ti.com/\r
3 *\r
4 * Redistribution and use in source and binary forms, with or without\r
5 * modification, are permitted provided that the following conditions\r
6 * are met:\r
7 *\r
8 * Redistributions of source code must retain the above copyright\r
9 * notice, this list of conditions and the following disclaimer.\r
10 *\r
11 * Redistributions in binary form must reproduce the above copyright\r
12 * notice, this list of conditions and the following disclaimer in the\r
13 * documentation and/or other materials provided with the\r
14 * distribution.\r
15 *\r
16 * Neither the name of Texas Instruments Incorporated nor the names of\r
17 * its contributors may be used to endorse or promote products derived\r
18 * from this software without specific prior written permission.\r
19 *\r
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\r
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
31 *\r
32 */\r
33 \r
34 /**\r
35 * \file spi_eeprom.c\r
36 *\r
37 * \brief This file contains spi eeprom data transfer functions.\r
38 * \r
39 */\r
40 \r
41 #include <stdio.h>\r
42 #include <stdlib.h>\r
43 #include <string.h>\r
44 \r
45 #include <ti/drv/spi/SPI.h>\r
46 #include <ti/drv/spi/soc/SPI_soc.h>\r
47 #include <ti/drv/uart/UART_stdio.h>\r
48 \r
49 #include "board.h"\r
50 #include "board_cfg.h"\r
51 #include "spi_eeprom.h"\r
52 \r
53 /*\r
54 * \brief Activate SPI transfer\r
55 *\r
56 * Command code used with SPI_control(). arg is a pointer to an uint32_t\r
57 * that contains the enable/disable value to be placed into the SPI register.\r
58 *\r
59 * Command argument 0: (1: enable, 0: disable)\r
60 */\r
61 #define SPI_V0_CMD_XFER_ACTIVATE (SPI_CMD_RESERVED + 0U)\r
62 \r
63 extern void BOARD_delay(uint32_t usecs);\r
64 \r
65 /**\r
66 * \brief This function is used to perform spi command\r
67 * read\r
68 *\r
69 * \param handle spi handle specific to spi instance\r
70 * *cmd spi command to be read\r
71 * cmdLen length of the spi command\r
72 * *rxbuf pionter to the receive buffer\r
73 * rxlen length of the receive buffer\r
74 *\r
75 * \return bool\r
76 * \n true - command read successfully\r
77 * \n false - command read failed\r
78 * \r
79 */\r
80 static bool spieeprom_cmd_read(SPI_Handle handle,\r
81 uint8_t *cmd,\r
82 uint32_t cmdLen,\r
83 uint8_t *rxbuf,\r
84 uint32_t rxlen)\r
85 {\r
86 SPI_Transaction transaction; /* SPI transaction structure */\r
87 uint32_t xferEnable;\r
88 uint32_t terminateXfer = 0;\r
89 bool retVal = false;\r
90 \r
91 /* Enable transfer */\r
92 xferEnable = 1;\r
93 SPI_control(handle, SPI_V0_CMD_XFER_ACTIVATE, (void *)&xferEnable);\r
94 \r
95 /* If no read data, release CS at the end of write */\r
96 if (rxlen == 0)\r
97 terminateXfer = 1;\r
98 \r
99 /* Write Command */\r
100 transaction.txBuf = cmd;\r
101 transaction.rxBuf = NULL;\r
102 transaction.count = cmdLen;\r
103 transaction.arg = (void *)&terminateXfer;\r
104 \r
105 retVal = SPI_transfer(handle, &transaction);\r
106 if (retVal == false)\r
107 return retVal;\r
108 \r
109 /* Receive the data */\r
110 if (rxlen)\r
111 {\r
112 /* Read Device ID */\r
113 transaction.txBuf = NULL;\r
114 transaction.rxBuf = rxbuf;\r
115 transaction.count = rxlen;\r
116 terminateXfer = 1;\r
117 transaction.arg = (void *)&terminateXfer;\r
118 \r
119 retVal = SPI_transfer(handle, &transaction);\r
120 }\r
121 \r
122 /* Disable transfer */\r
123 xferEnable = 0;\r
124 SPI_control(handle, SPI_V0_CMD_XFER_ACTIVATE, (void *)&xferEnable);\r
125 return retVal;\r
126 }\r
127 \r
128 /**\r
129 * \brief This function is used to perform spi command\r
130 * write\r
131 *\r
132 * \param handle spi handle specific to spi instance\r
133 * *cmd spi command to write\r
134 * cmdLen length of the spi command\r
135 * *txbuf pionter to the transfer buffer\r
136 * txlen length of the transfer buffer\r
137 *\r
138 * \return bool\r
139 * \n true - command written successfully\r
140 * \n false - command write failed\r
141 * \r
142 */\r
143 static bool spieeprom_cmd_write(SPI_Handle handle,\r
144 uint8_t *cmd,\r
145 uint32_t cmdLen,\r
146 uint8_t *txbuf,\r
147 uint32_t txlen)\r
148 {\r
149 SPI_Transaction transaction; /* SPI transaction structure */\r
150 uint32_t xferEnable;\r
151 uint32_t terminateXfer = 0;\r
152 bool retVal = false;\r
153 \r
154 /* Enable transfer */\r
155 xferEnable = 1;\r
156 SPI_control(handle, SPI_V0_CMD_XFER_ACTIVATE, (void *)&xferEnable);\r
157 \r
158 /* If no read data, release CS at the end of write */\r
159 if (txlen == 0)\r
160 terminateXfer = 1;\r
161 \r
162 /* Write Command */\r
163 transaction.txBuf = cmd;\r
164 transaction.rxBuf = NULL;\r
165 transaction.count = cmdLen;\r
166 transaction.arg = (void *)&terminateXfer;\r
167 \r
168 retVal = SPI_transfer(handle, &transaction);\r
169 if (retVal == false)\r
170 return retVal;\r
171 \r
172 /* write data */\r
173 if (txlen)\r
174 {\r
175 /* Write data */\r
176 transaction.txBuf = txbuf;\r
177 transaction.rxBuf = NULL;\r
178 transaction.count = txlen;\r
179 terminateXfer = 1;\r
180 transaction.arg = (void *)&terminateXfer;\r
181 \r
182 retVal = SPI_transfer(handle, &transaction);\r
183 }\r
184 \r
185 /* Disable transfer */\r
186 xferEnable = 0;\r
187 SPI_control(handle, SPI_V0_CMD_XFER_ACTIVATE, (void *)&xferEnable);\r
188 return retVal;\r
189 }\r
190 \r
191 /**\r
192 * \brief This function is used to perform spi write enable\r
193 *\r
194 * \param handle spi handle specific to spi instance\r
195 * \r
196 * \return bool\r
197 * \n true - write enabled successfully\r
198 * \n false - write enable failed\r
199 * \r
200 */\r
201 static bool spieeprom_write_enable(SPI_Handle handle)\r
202 {\r
203 uint8_t cmd = SPI_EEPROM_CMD_WREN;\r
204 bool retVal;\r
205 \r
206 retVal = spieeprom_cmd_read(handle, &cmd, 1, NULL, 0);\r
207 \r
208 return retVal;\r
209 }\r
210 \r
211 /**\r
212 * \brief This function is used to write data to eeprom\r
213 *\r
214 * \param handle spi handle specific to spi instance\r
215 * spiTransaction pointer to spi transaction struct access\r
216 * length length of data buffer\r
217 * addr address to be written\r
218 * \r
219 * \return int8_t\r
220 * \n TEST_PASS - eeprom write passed\r
221 * \n TEST_FAIL - eeprom write failed\r
222 * \r
223 */\r
224 int8_t spiEepromWrite(SPI_Handle handle,\r
225 SPI_Transaction* spiTransaction,\r
226 int8_t length,\r
227 uint32_t addr)\r
228 {\r
229 uint8_t cmd[3];\r
230 bool retVal;\r
231 \r
232 /* Send Write Enable command */\r
233 retVal = spieeprom_write_enable(handle);\r
234 if (retVal == false)\r
235 return TEST_FAIL;\r
236 \r
237 cmd[0] = SPI_EEPROM_CMD_WRITE;\r
238 cmd[1] = (uint8_t)(addr >> 8);\r
239 cmd[2] = (uint8_t)addr;\r
240 \r
241 retVal = spieeprom_cmd_write(handle, cmd, 3, spiTransaction->txBuf, length);\r
242 if (retVal == false)\r
243 {\r
244 return TEST_FAIL;\r
245 }\r
246 else\r
247 {\r
248 return TEST_PASS;\r
249 }\r
250 }\r
251 \r
252 /**\r
253 * \brief This function is used to read data from eeprom\r
254 *\r
255 * \param handle spi handle specific to spi instance\r
256 * spiTransaction pointer to spi transaction struct access\r
257 * length length of data buffer\r
258 * addr address to be read\r
259 * \r
260 * \return int8_t\r
261 * \n TEST_PASS - eeprom write passed\r
262 * \n TEST_FAIL - eeprom write failed\r
263 * \r
264 */\r
265 int8_t spiEepromRead(SPI_Handle handle,\r
266 SPI_Transaction* spiTransaction,\r
267 int8_t length,\r
268 uint32_t addr)\r
269 {\r
270 uint8_t cmd[3];\r
271 bool retVal;\r
272 \r
273 /* Initialize the command to be sent serially */\r
274 cmd[0] = SPI_EEPROM_CMD_READ;\r
275 cmd[1] = (uint8_t)(addr >> 8);\r
276 cmd[2] = (uint8_t)addr;\r
277 \r
278 retVal = spieeprom_cmd_read(handle, cmd, 3, spiTransaction->rxBuf, length);\r
279 if (retVal == false)\r
280 {\r
281 return TEST_FAIL;\r
282 }\r
283 else\r
284 {\r
285 return TEST_PASS;\r
286 }\r
287 }\r