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