1 /**
2 * @file spi.c
3 * @brief This file contains the function implementations for the
4 * Serial Peripheral Interface peripheral module.
5 */
6
7 /******************************************************************************
8 *
9 * Copyright (C) 2022-2023 Maxim Integrated Products, Inc. (now owned by
10 * Analog Devices, Inc.),
11 * Copyright (C) 2023-2024 Analog Devices, Inc.
12 *
13 * Licensed under the Apache License, Version 2.0 (the "License");
14 * you may not use this file except in compliance with the License.
15 * You may obtain a copy of the License at
16 *
17 * http://www.apache.org/licenses/LICENSE-2.0
18 *
19 * Unless required by applicable law or agreed to in writing, software
20 * distributed under the License is distributed on an "AS IS" BASIS,
21 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 * See the License for the specific language governing permissions and
23 * limitations under the License.
24 *
25 ******************************************************************************/
26
27 /* **** Includes **** */
28 #include <string.h>
29 #include "spi.h"
30 #include "spi_reva1.h"
31 #include "mxc_sys.h"
32 #include "mxc_errors.h"
33
34 /**
35 * @ingroup spi
36 * @{
37 */
38
39 /* **** Definitions **** */
40
41 /* **** Functions **** */
42
MXC_SPI_Init(mxc_spi_regs_t * spi,int masterMode,int quadModeUsed,int numSlaves,unsigned ssPolarity,unsigned int hz)43 int MXC_SPI_Init(mxc_spi_regs_t *spi, int masterMode, int quadModeUsed, int numSlaves,
44 unsigned ssPolarity, unsigned int hz)
45 {
46 if (numSlaves > MXC_SPI_SS_INSTANCES) {
47 return E_BAD_PARAM;
48 }
49
50 // Check if frequency is too high
51 if (hz > PeripheralClock) {
52 return E_BAD_PARAM;
53 }
54
55 #ifndef MSDK_NO_GPIO_CLK_INIT
56 switch (MXC_SPI_GET_IDX(spi)) {
57 case 0:
58 MXC_SYS_Reset_Periph(MXC_SYS_RESET_SPI0);
59 MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_SPI0);
60 MXC_GPIO_Config(&gpio_cfg_spi0_0);
61 MXC_GPIO_Config(&gpio_cfg_spi0_1);
62 break;
63 case 1:
64 MXC_SYS_Reset_Periph(MXC_SYS_RESET_SPI1);
65 MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_SPI1);
66 MXC_GPIO_Config(&gpio_cfg_spi1);
67 break;
68 case 2:
69 MXC_SYS_Reset_Periph(MXC_SYS_RESET_SPI2);
70 MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_SPI2);
71 MXC_GPIO_Config(&gpio_cfg_spi2);
72 break;
73 case 3:
74 MXC_SYS_Reset_Periph(MXC_SYS_RESET_SPI3);
75 MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_SPI3);
76 MXC_GPIO_Config(&gpio_cfg_spi3);
77 break;
78 default:
79 return E_BAD_PARAM;
80 }
81 #endif // MSDK_NO_GPIO_CLK_INIT
82
83 return MXC_SPI_RevA1_Init((mxc_spi_reva_regs_t *)spi, masterMode, quadModeUsed, numSlaves,
84 ssPolarity, hz);
85 }
86
87 /* ************************************************************************ */
MXC_SPI_Shutdown(mxc_spi_regs_t * spi)88 int MXC_SPI_Shutdown(mxc_spi_regs_t *spi)
89 {
90 MXC_SPI_RevA1_Shutdown((mxc_spi_reva_regs_t *)spi);
91
92 switch (MXC_SPI_GET_IDX(spi)) {
93 case 0:
94 MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_SPI0);
95 break;
96 case 1:
97 MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_SPI1);
98 break;
99 case 2:
100 MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_SPI2);
101 break;
102 case 3:
103 MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_SPI3);
104 break;
105 default:
106 return E_BAD_PARAM;
107 }
108
109 return E_NO_ERROR;
110 }
111
112 /* ************************************************************************ */
MXC_SPI_ReadyForSleep(mxc_spi_regs_t * spi)113 int MXC_SPI_ReadyForSleep(mxc_spi_regs_t *spi)
114 {
115 return MXC_SPI_RevA1_ReadyForSleep((mxc_spi_reva_regs_t *)spi);
116 }
117
118 /* ************************************************************************ */
MXC_SPI_GetPeripheralClock(mxc_spi_regs_t * spi)119 int MXC_SPI_GetPeripheralClock(mxc_spi_regs_t *spi)
120 {
121 if (MXC_SPI_GET_IDX(spi) == 3) {
122 return PeripheralClock * 2;
123 } else if (MXC_SPI_GET_IDX(spi) != -1) {
124 return PeripheralClock;
125 } else {
126 return E_BAD_PARAM;
127 }
128 return E_NO_ERROR;
129 }
130
131 /* ************************************************************************ */
MXC_SPI_SetFrequency(mxc_spi_regs_t * spi,unsigned int hz)132 int MXC_SPI_SetFrequency(mxc_spi_regs_t *spi, unsigned int hz)
133 {
134 return MXC_SPI_RevA1_SetFrequency((mxc_spi_reva_regs_t *)spi, hz);
135 }
136
137 /* ************************************************************************ */
MXC_SPI_GetFrequency(mxc_spi_regs_t * spi)138 unsigned int MXC_SPI_GetFrequency(mxc_spi_regs_t *spi)
139 {
140 return MXC_SPI_RevA1_GetFrequency((mxc_spi_reva_regs_t *)spi);
141 }
142
143 /* ************************************************************************ */
MXC_SPI_SetDataSize(mxc_spi_regs_t * spi,int dataSize)144 int MXC_SPI_SetDataSize(mxc_spi_regs_t *spi, int dataSize)
145 {
146 return MXC_SPI_RevA1_SetDataSize((mxc_spi_reva_regs_t *)spi, dataSize);
147 }
148
149 /* ************************************************************************ */
MXC_SPI_GetDataSize(mxc_spi_regs_t * spi)150 int MXC_SPI_GetDataSize(mxc_spi_regs_t *spi)
151 {
152 return MXC_SPI_RevA1_GetDataSize((mxc_spi_reva_regs_t *)spi);
153 }
154
155 /* ************************************************************************* */
156 /* Low-level functions */
157 /* ************************************************************************* */
158
MXC_SPI_SetSlave(mxc_spi_regs_t * spi,int ssIdx)159 int MXC_SPI_SetSlave(mxc_spi_regs_t *spi, int ssIdx)
160 {
161 return MXC_SPI_RevA1_SetSlave((mxc_spi_reva_regs_t *)spi, ssIdx);
162 }
163
164 /* ************************************************************************ */
MXC_SPI_GetSlave(mxc_spi_regs_t * spi)165 int MXC_SPI_GetSlave(mxc_spi_regs_t *spi)
166 {
167 int spi_num = MXC_SPI_GET_IDX((mxc_spi_regs_t *)spi);
168 MXC_ASSERT(spi_num >= 0);
169
170 int slvSel = (spi->ctrl0 & MXC_F_SPI_CTRL0_SS_SEL) >> MXC_F_SPI_CTRL0_SS_SEL_POS;
171
172 if (slvSel &
173 (MXC_V_SPI_CTRL0_SS_SEL_SS0 | MXC_V_SPI_CTRL0_SS_SEL_SS1 | MXC_V_SPI_CTRL0_SS_SEL_SS2)) {
174 return slvSel >> 1;
175 } else {
176 return 3;
177 }
178 }
179
180 /* ************************************************************************ */
MXC_SPI_SetWidth(mxc_spi_regs_t * spi,mxc_spi_width_t spiWidth)181 int MXC_SPI_SetWidth(mxc_spi_regs_t *spi, mxc_spi_width_t spiWidth)
182 {
183 return MXC_SPI_RevA1_SetWidth((mxc_spi_reva_regs_t *)spi, spiWidth);
184 }
185
186 /* ************************************************************************ */
MXC_SPI_GetWidth(mxc_spi_regs_t * spi)187 mxc_spi_width_t MXC_SPI_GetWidth(mxc_spi_regs_t *spi)
188 {
189 return MXC_SPI_RevA1_GetWidth((mxc_spi_reva_regs_t *)spi);
190 }
191
192 /* ************************************************************************ */
MXC_SPI_SetMode(mxc_spi_regs_t * spi,mxc_spi_mode_t spiMode)193 int MXC_SPI_SetMode(mxc_spi_regs_t *spi, mxc_spi_mode_t spiMode)
194 {
195 return MXC_SPI_RevA1_SetMode((mxc_spi_reva_regs_t *)spi, (mxc_spi_reva_mode_t)spiMode);
196 }
197
198 /* ************************************************************************ */
MXC_SPI_GetMode(mxc_spi_regs_t * spi)199 mxc_spi_mode_t MXC_SPI_GetMode(mxc_spi_regs_t *spi)
200 {
201 return (mxc_spi_mode_t)MXC_SPI_RevA1_GetMode((mxc_spi_reva_regs_t *)spi);
202 }
203
204 /* ************************************************************************ */
MXC_SPI_StartTransmission(mxc_spi_regs_t * spi)205 int MXC_SPI_StartTransmission(mxc_spi_regs_t *spi)
206 {
207 return MXC_SPI_RevA1_StartTransmission((mxc_spi_reva_regs_t *)spi);
208 }
209
210 /* ************************************************************************ */
MXC_SPI_GetActive(mxc_spi_regs_t * spi)211 int MXC_SPI_GetActive(mxc_spi_regs_t *spi)
212 {
213 return MXC_SPI_RevA1_GetActive((mxc_spi_reva_regs_t *)spi);
214 }
215
216 /* ************************************************************************ */
MXC_SPI_AbortTransmission(mxc_spi_regs_t * spi)217 int MXC_SPI_AbortTransmission(mxc_spi_regs_t *spi)
218 {
219 return MXC_SPI_RevA1_AbortTransmission((mxc_spi_reva_regs_t *)spi);
220 }
221
222 /* ************************************************************************ */
MXC_SPI_ReadRXFIFO(mxc_spi_regs_t * spi,unsigned char * bytes,unsigned int len)223 unsigned int MXC_SPI_ReadRXFIFO(mxc_spi_regs_t *spi, unsigned char *bytes, unsigned int len)
224 {
225 return MXC_SPI_RevA1_ReadRXFIFO((mxc_spi_reva_regs_t *)spi, bytes, len);
226 }
227
228 /* ************************************************************************ */
MXC_SPI_GetRXFIFOAvailable(mxc_spi_regs_t * spi)229 unsigned int MXC_SPI_GetRXFIFOAvailable(mxc_spi_regs_t *spi)
230 {
231 return MXC_SPI_RevA1_GetRXFIFOAvailable((mxc_spi_reva_regs_t *)spi);
232 }
233
234 /* ************************************************************************ */
MXC_SPI_WriteTXFIFO(mxc_spi_regs_t * spi,unsigned char * bytes,unsigned int len)235 unsigned int MXC_SPI_WriteTXFIFO(mxc_spi_regs_t *spi, unsigned char *bytes, unsigned int len)
236 {
237 return MXC_SPI_RevA1_WriteTXFIFO((mxc_spi_reva_regs_t *)spi, bytes, len);
238 }
239
240 /* ************************************************************************ */
MXC_SPI_GetTXFIFOAvailable(mxc_spi_regs_t * spi)241 unsigned int MXC_SPI_GetTXFIFOAvailable(mxc_spi_regs_t *spi)
242 {
243 return MXC_SPI_RevA1_GetTXFIFOAvailable((mxc_spi_reva_regs_t *)spi);
244 }
245
246 /* ************************************************************************ */
MXC_SPI_ClearRXFIFO(mxc_spi_regs_t * spi)247 void MXC_SPI_ClearRXFIFO(mxc_spi_regs_t *spi)
248 {
249 MXC_SPI_RevA1_ClearRXFIFO((mxc_spi_reva_regs_t *)spi);
250 }
251
252 /* ************************************************************************ */
MXC_SPI_ClearTXFIFO(mxc_spi_regs_t * spi)253 void MXC_SPI_ClearTXFIFO(mxc_spi_regs_t *spi)
254 {
255 MXC_SPI_RevA1_ClearTXFIFO((mxc_spi_reva_regs_t *)spi);
256 }
257
258 /* ************************************************************************ */
MXC_SPI_SetRXThreshold(mxc_spi_regs_t * spi,unsigned int numBytes)259 int MXC_SPI_SetRXThreshold(mxc_spi_regs_t *spi, unsigned int numBytes)
260 {
261 return MXC_SPI_RevA1_SetRXThreshold((mxc_spi_reva_regs_t *)spi, numBytes);
262 }
263
264 /* ************************************************************************ */
MXC_SPI_GetRXThreshold(mxc_spi_regs_t * spi)265 unsigned int MXC_SPI_GetRXThreshold(mxc_spi_regs_t *spi)
266 {
267 return MXC_SPI_RevA1_GetRXThreshold((mxc_spi_reva_regs_t *)spi);
268 }
269
270 /* ************************************************************************ */
MXC_SPI_SetTXThreshold(mxc_spi_regs_t * spi,unsigned int numBytes)271 int MXC_SPI_SetTXThreshold(mxc_spi_regs_t *spi, unsigned int numBytes)
272 {
273 return MXC_SPI_RevA1_SetTXThreshold((mxc_spi_reva_regs_t *)spi, numBytes);
274 }
275
276 /* ************************************************************************ */
MXC_SPI_GetTXThreshold(mxc_spi_regs_t * spi)277 unsigned int MXC_SPI_GetTXThreshold(mxc_spi_regs_t *spi)
278 {
279 return MXC_SPI_RevA1_GetTXThreshold((mxc_spi_reva_regs_t *)spi);
280 }
281
282 /* ************************************************************************ */
MXC_SPI_GetFlags(mxc_spi_regs_t * spi)283 unsigned int MXC_SPI_GetFlags(mxc_spi_regs_t *spi)
284 {
285 return MXC_SPI_RevA1_GetFlags((mxc_spi_reva_regs_t *)spi);
286 }
287
288 /* ************************************************************************ */
MXC_SPI_ClearFlags(mxc_spi_regs_t * spi)289 void MXC_SPI_ClearFlags(mxc_spi_regs_t *spi)
290 {
291 MXC_SPI_RevA1_ClearFlags((mxc_spi_reva_regs_t *)spi);
292 }
293
294 /* ************************************************************************ */
MXC_SPI_EnableInt(mxc_spi_regs_t * spi,unsigned int mask)295 void MXC_SPI_EnableInt(mxc_spi_regs_t *spi, unsigned int mask)
296 {
297 MXC_SPI_RevA1_EnableInt((mxc_spi_reva_regs_t *)spi, mask);
298 }
299
300 /* ************************************************************************ */
MXC_SPI_DisableInt(mxc_spi_regs_t * spi,unsigned int mask)301 void MXC_SPI_DisableInt(mxc_spi_regs_t *spi, unsigned int mask)
302 {
303 MXC_SPI_RevA1_DisableInt((mxc_spi_reva_regs_t *)spi, mask);
304 }
305
306 /* ************************************************************************* */
307 /* Transaction level functions */
308 /* ************************************************************************* */
309
MXC_SPI_MasterTransaction(mxc_spi_req_t * req)310 int MXC_SPI_MasterTransaction(mxc_spi_req_t *req)
311 {
312 return MXC_SPI_RevA1_MasterTransaction((mxc_spi_reva_req_t *)req);
313 }
314
315 /* ************************************************************************ */
MXC_SPI_MasterTransactionAsync(mxc_spi_req_t * req)316 int MXC_SPI_MasterTransactionAsync(mxc_spi_req_t *req)
317 {
318 return MXC_SPI_RevA1_MasterTransactionAsync((mxc_spi_reva_req_t *)req);
319 }
320
321 /* ************************************************************************ */
MXC_SPI_MasterTransactionDMA(mxc_spi_req_t * req)322 int MXC_SPI_MasterTransactionDMA(mxc_spi_req_t *req)
323 {
324 int retVal = E_NO_ERROR;
325
326 switch (MXC_SPI_GET_IDX(req->spi)) {
327 case 0:
328 retVal = MXC_SPI_RevA1_MasterTransactionDMA(
329 (mxc_spi_reva_req_t *)req, MXC_DMA_REQUEST_SPI0TX, MXC_DMA_REQUEST_SPI0RX, MXC_DMA);
330 break;
331 case 1:
332 retVal = MXC_SPI_RevA1_MasterTransactionDMA(
333 (mxc_spi_reva_req_t *)req, MXC_DMA_REQUEST_SPI1TX, MXC_DMA_REQUEST_SPI1RX, MXC_DMA);
334 break;
335 case 2:
336 retVal = MXC_SPI_RevA1_MasterTransactionDMA(
337 (mxc_spi_reva_req_t *)req, MXC_DMA_REQUEST_SPI2TX, MXC_DMA_REQUEST_SPI2RX, MXC_DMA);
338 break;
339 case 3:
340 retVal = MXC_SPI_RevA1_MasterTransactionDMA(
341 (mxc_spi_reva_req_t *)req, MXC_DMA_REQUEST_SPI3TX, MXC_DMA_REQUEST_SPI3RX, MXC_DMA);
342 break;
343 default:
344 return E_BAD_PARAM;
345 }
346
347 return retVal;
348 }
349
350 /* ************************************************************************ */
MXC_SPI_SlaveTransaction(mxc_spi_req_t * req)351 int MXC_SPI_SlaveTransaction(mxc_spi_req_t *req)
352 {
353 return MXC_SPI_RevA1_SlaveTransaction((mxc_spi_reva_req_t *)req);
354 }
355
356 /* ************************************************************************ */
MXC_SPI_SlaveTransactionAsync(mxc_spi_req_t * req)357 int MXC_SPI_SlaveTransactionAsync(mxc_spi_req_t *req)
358 {
359 return MXC_SPI_RevA1_SlaveTransactionAsync((mxc_spi_reva_req_t *)req);
360 }
361
362 /* ************************************************************************ */
MXC_SPI_SlaveTransactionDMA(mxc_spi_req_t * req)363 int MXC_SPI_SlaveTransactionDMA(mxc_spi_req_t *req)
364 {
365 int retVal = E_NO_ERROR;
366
367 switch (MXC_SPI_GET_IDX(req->spi)) {
368 case 0:
369 retVal = MXC_SPI_RevA1_SlaveTransactionDMA(
370 (mxc_spi_reva_req_t *)req, MXC_DMA_REQUEST_SPI0TX, MXC_DMA_REQUEST_SPI0RX, MXC_DMA);
371 break;
372 case 1:
373 retVal = MXC_SPI_RevA1_SlaveTransactionDMA(
374 (mxc_spi_reva_req_t *)req, MXC_DMA_REQUEST_SPI1TX, MXC_DMA_REQUEST_SPI1RX, MXC_DMA);
375 break;
376 case 2:
377 retVal = MXC_SPI_RevA1_SlaveTransactionDMA(
378 (mxc_spi_reva_req_t *)req, MXC_DMA_REQUEST_SPI2TX, MXC_DMA_REQUEST_SPI2RX, MXC_DMA);
379 break;
380 case 3:
381 retVal = MXC_SPI_RevA1_SlaveTransactionDMA(
382 (mxc_spi_reva_req_t *)req, MXC_DMA_REQUEST_SPI3TX, MXC_DMA_REQUEST_SPI3RX, MXC_DMA);
383 break;
384 default:
385 return E_BAD_PARAM;
386 }
387
388 return retVal;
389 }
390
391 /* ************************************************************************ */
MXC_SPI_SetDefaultTXData(mxc_spi_regs_t * spi,unsigned int defaultTXData)392 int MXC_SPI_SetDefaultTXData(mxc_spi_regs_t *spi, unsigned int defaultTXData)
393 {
394 return MXC_SPI_RevA1_SetDefaultTXData((mxc_spi_reva_regs_t *)spi, defaultTXData);
395 }
396
397 /* ************************************************************************ */
MXC_SPI_AbortAsync(mxc_spi_regs_t * spi)398 void MXC_SPI_AbortAsync(mxc_spi_regs_t *spi)
399 {
400 MXC_SPI_RevA1_AbortAsync((mxc_spi_reva_regs_t *)spi);
401 }
402
403 /* ************************************************************************ */
MXC_SPI_AsyncHandler(mxc_spi_regs_t * spi)404 void MXC_SPI_AsyncHandler(mxc_spi_regs_t *spi)
405 {
406 MXC_SPI_RevA1_AsyncHandler((mxc_spi_reva_regs_t *)spi);
407 }
408
MXC_SPI_HWSSControl(mxc_spi_regs_t * spi,int state)409 void MXC_SPI_HWSSControl(mxc_spi_regs_t *spi, int state)
410 {
411 MXC_SPI_RevA1_HWSSControl((mxc_spi_reva_regs_t *)spi, state);
412 }
413
414 /**@} end of group spi */
415