1 /******************************************************************************
2  *
3  * Copyright (C) 2022-2023 Maxim Integrated Products, Inc. (now owned by
4  * Analog Devices, Inc.),
5  * Copyright (C) 2023-2024 Analog Devices, Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  ******************************************************************************/
20 
21 #include <stdio.h>
22 #include <stddef.h>
23 #include <stdint.h>
24 #include <stdbool.h>
25 
26 #include "mxc_device.h"
27 #include "mxc_assert.h"
28 #include "mxc_lock.h"
29 #include "mxc_sys.h"
30 #include "mxc_delay.h"
31 #include "spi_reva1.h"
32 #include "dma.h"
33 
34 /* **** Definitions **** */
35 
36 /* ************************************************************************** */
MXC_SPI_Init(mxc_spi_regs_t * spi,int masterMode,int quadModeUsed,int numSlaves,unsigned ssPolarity,unsigned int hz,mxc_spi_pins_t pins)37 int MXC_SPI_Init(mxc_spi_regs_t *spi, int masterMode, int quadModeUsed, int numSlaves,
38                  unsigned ssPolarity, unsigned int hz, mxc_spi_pins_t pins)
39 {
40     int spi_num;
41 
42     spi_num = MXC_SPI_GET_IDX(spi);
43     MXC_ASSERT(spi_num >= 0);
44 
45     if (numSlaves > MXC_SPI_SS_INSTANCES) {
46         return E_BAD_PARAM;
47     }
48 
49     // Check if frequency is too high
50     if ((spi_num < 3) && (hz > PeripheralClock)) {
51         return E_BAD_PARAM;
52     }
53 
54     if ((spi_num > 2) && (hz > SystemCoreClock)) {
55         return E_BAD_PARAM;
56     }
57 
58 #ifndef MSDK_NO_GPIO_CLK_INIT
59     // Configure GPIO for spi
60     if (spi == MXC_SPI0) {
61         MXC_SYS_Reset_Periph(MXC_SYS_RESET0_SPI0);
62         MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_SPI0);
63         MXC_GPIO_Config(&gpio_cfg_spi0);
64 
65         // Enable slave select pins
66         if (pins.ss0) {
67             MXC_GPIO_Config(&gpio_cfg_spi0_ss0);
68         }
69 
70         if (pins.ss1) {
71             MXC_GPIO_Config(&gpio_cfg_spi0_ss1);
72         }
73 
74         if (pins.ss2) {
75             return E_BAD_PARAM;
76         }
77     } else if (spi == MXC_SPI1) {
78         MXC_SYS_Reset_Periph(MXC_SYS_RESET0_SPI1);
79         MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_SPI1);
80         MXC_GPIO_Config(&gpio_cfg_spi1);
81 
82         // Enable slave select pins
83         if (pins.ss0) {
84             MXC_GPIO_Config(&gpio_cfg_spi1_ss0);
85         }
86 
87         if (pins.ss1) {
88             MXC_GPIO_Config(&gpio_cfg_spi1_ss1);
89         }
90 
91         if (pins.ss2) {
92             MXC_GPIO_Config(&gpio_cfg_spi1_ss2);
93         }
94     } else if (spi == MXC_SPI2) {
95         MXC_SYS_Reset_Periph(MXC_SYS_RESET0_SPI2);
96         MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_SPI2);
97         MXC_GPIO_Config(&gpio_cfg_spi2);
98 
99         // Enable slave select pins
100         if (pins.ss0) {
101             MXC_GPIO_Config(&gpio_cfg_spi2_ss0);
102         }
103 
104         if (pins.ss1) {
105             MXC_GPIO_Config(&gpio_cfg_spi2_ss1);
106         }
107 
108         if (pins.ss2) {
109             MXC_GPIO_Config(&gpio_cfg_spi2_ss2);
110         }
111 #ifndef __riscv
112     } else if (spi == MXC_SPI3) {
113         MXC_SYS_Reset_Periph(MXC_SYS_RESET1_SPI3);
114         MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_SPI3);
115         MXC_GPIO_Config(&gpio_cfg_spi3);
116 
117         // Enable slave select pins
118         if (pins.ss0) {
119             MXC_GPIO_Config(&gpio_cfg_spi3_ss0);
120         }
121 
122         if (pins.ss1) {
123             MXC_GPIO_Config(&gpio_cfg_spi3_ss1);
124         }
125 
126         if (pins.ss2) {
127             MXC_GPIO_Config(&gpio_cfg_spi3_ss2);
128         }
129     } else if (spi == MXC_SPI4) {
130         MXC_SYS_Reset_Periph(MXC_SYS_RESET1_SPI4);
131         MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_SPI4);
132         MXC_GPIO_Config(&gpio_cfg_spi4);
133 
134         // Enable slave select pins
135         if (pins.ss0) {
136             MXC_GPIO_Config(&gpio_cfg_spi4_ss0);
137         }
138 
139         if (pins.ss1) {
140             MXC_GPIO_Config(&gpio_cfg_spi4_ss1);
141         }
142 
143         if (pins.ss2) {
144             MXC_GPIO_Config(&gpio_cfg_spi4_ss2);
145         }
146 #endif // __riscv
147     } else {
148         return E_NO_DEVICE;
149     }
150 #else
151     (void)pins;
152 #endif // MSDK_NO_GPIO_CLK_INIT
153 
154     return MXC_SPI_RevA1_Init((mxc_spi_reva_regs_t *)spi, masterMode, quadModeUsed, numSlaves,
155                               ssPolarity, hz);
156 }
157 
MXC_SPI_Shutdown(mxc_spi_regs_t * spi)158 int MXC_SPI_Shutdown(mxc_spi_regs_t *spi)
159 {
160     int spi_num;
161     spi_num = MXC_SPI_GET_IDX(spi);
162     MXC_ASSERT(spi_num >= 0);
163     (void)spi_num;
164 
165     MXC_SPI_RevA1_Shutdown((mxc_spi_reva_regs_t *)spi);
166 
167     if (spi == MXC_SPI0) {
168         MXC_SYS_ClockDisable(MXC_SYS_PERIPH_CLOCK_SPI0);
169     } else if (spi == MXC_SPI1) {
170         MXC_SYS_ClockDisable(MXC_SYS_PERIPH_CLOCK_SPI1);
171     } else if (spi == MXC_SPI2) {
172         MXC_SYS_ClockDisable(MXC_SYS_PERIPH_CLOCK_SPI2);
173 #ifndef __riscv
174     } else if (spi == MXC_SPI3) {
175         MXC_SYS_ClockDisable(MXC_SYS_PERIPH_CLOCK_SPI3);
176     } else if (spi == MXC_SPI4) {
177         MXC_SYS_ClockDisable(MXC_SYS_PERIPH_CLOCK_SPI4);
178 #endif //__riscv
179     } else {
180         return E_NO_DEVICE;
181     }
182 
183     return E_NO_ERROR;
184 }
185 
MXC_SPI_ReadyForSleep(mxc_spi_regs_t * spi)186 int MXC_SPI_ReadyForSleep(mxc_spi_regs_t *spi)
187 {
188     return MXC_SPI_RevA1_ReadyForSleep((mxc_spi_reva_regs_t *)spi);
189 }
190 
MXC_SPI_GetPeripheralClock(mxc_spi_regs_t * spi)191 int MXC_SPI_GetPeripheralClock(mxc_spi_regs_t *spi)
192 {
193     int clk_freq = 0;
194 
195     if (MXC_SPI_GET_IDX(spi) > -1 && MXC_SPI_GET_IDX(spi) < 3) {
196         clk_freq = PeripheralClock;
197     } else if (MXC_SPI_GET_IDX(spi) > 2) {
198         uint32_t clk_src = (MXC_GCR->clkctrl & MXC_F_GCR_CLKCTRL_SYSCLK_SEL) >>
199                            MXC_F_GCR_CLKCTRL_SYSCLK_SEL_POS;
200         switch (clk_src) {
201         case MXC_SYS_CLOCK_IPO:
202             clk_freq = IPO_FREQ;
203             break;
204         case MXC_SYS_CLOCK_ERFO:
205             clk_freq = ERFO_FREQ;
206             break;
207         case MXC_SYS_CLOCK_IBRO:
208             clk_freq = IBRO_FREQ;
209             break;
210         case MXC_SYS_CLOCK_ISO:
211             clk_freq = ISO_FREQ;
212             break;
213         case MXC_SYS_CLOCK_INRO:
214             clk_freq = INRO_FREQ;
215             break;
216         case MXC_SYS_CLOCK_ERTCO:
217             clk_freq = ERTCO_FREQ;
218             break;
219         case MXC_SYS_CLOCK_EXTCLK:
220             clk_freq = EXTCLK_FREQ;
221             break;
222         default:
223             return E_BAD_PARAM;
224         }
225     } else {
226         return E_BAD_PARAM;
227     }
228     return (clk_freq / 2);
229 }
230 
MXC_SPI_SetFrequency(mxc_spi_regs_t * spi,unsigned int hz)231 int MXC_SPI_SetFrequency(mxc_spi_regs_t *spi, unsigned int hz)
232 {
233     return MXC_SPI_RevA1_SetFrequency((mxc_spi_reva_regs_t *)spi, hz);
234 }
235 
MXC_SPI_GetFrequency(mxc_spi_regs_t * spi)236 unsigned int MXC_SPI_GetFrequency(mxc_spi_regs_t *spi)
237 {
238     return MXC_SPI_RevA1_GetFrequency((mxc_spi_reva_regs_t *)spi);
239 }
240 
MXC_SPI_SetDataSize(mxc_spi_regs_t * spi,int dataSize)241 int MXC_SPI_SetDataSize(mxc_spi_regs_t *spi, int dataSize)
242 {
243     return MXC_SPI_RevA1_SetDataSize((mxc_spi_reva_regs_t *)spi, dataSize);
244 }
245 
MXC_SPI_GetDataSize(mxc_spi_regs_t * spi)246 int MXC_SPI_GetDataSize(mxc_spi_regs_t *spi)
247 {
248     return MXC_SPI_RevA1_GetDataSize((mxc_spi_reva_regs_t *)spi);
249 }
250 
MXC_SPI_SetSlave(mxc_spi_regs_t * spi,int ssIdx)251 int MXC_SPI_SetSlave(mxc_spi_regs_t *spi, int ssIdx)
252 {
253     return MXC_SPI_RevA1_SetSlave((mxc_spi_reva_regs_t *)spi, ssIdx);
254 }
255 
MXC_SPI_GetSlave(mxc_spi_regs_t * spi)256 int MXC_SPI_GetSlave(mxc_spi_regs_t *spi)
257 {
258     return MXC_SPI_RevA1_GetSlave((mxc_spi_reva_regs_t *)spi);
259 }
260 
MXC_SPI_SetWidth(mxc_spi_regs_t * spi,mxc_spi_width_t spiWidth)261 int MXC_SPI_SetWidth(mxc_spi_regs_t *spi, mxc_spi_width_t spiWidth)
262 {
263     return MXC_SPI_RevA1_SetWidth((mxc_spi_reva_regs_t *)spi, (mxc_spi_reva_width_t)spiWidth);
264 }
265 
MXC_SPI_GetWidth(mxc_spi_regs_t * spi)266 mxc_spi_width_t MXC_SPI_GetWidth(mxc_spi_regs_t *spi)
267 {
268     return (mxc_spi_width_t)MXC_SPI_RevA1_GetWidth((mxc_spi_reva_regs_t *)spi);
269 }
270 
MXC_SPI_SetMode(mxc_spi_regs_t * spi,mxc_spi_mode_t spiMode)271 int MXC_SPI_SetMode(mxc_spi_regs_t *spi, mxc_spi_mode_t spiMode)
272 {
273     return MXC_SPI_RevA1_SetMode((mxc_spi_reva_regs_t *)spi, (mxc_spi_reva_mode_t)spiMode);
274 }
275 
MXC_SPI_GetMode(mxc_spi_regs_t * spi)276 mxc_spi_mode_t MXC_SPI_GetMode(mxc_spi_regs_t *spi)
277 {
278     return (mxc_spi_mode_t)MXC_SPI_RevA1_GetMode((mxc_spi_reva_regs_t *)spi);
279 }
280 
MXC_SPI_StartTransmission(mxc_spi_regs_t * spi)281 int MXC_SPI_StartTransmission(mxc_spi_regs_t *spi)
282 {
283     return MXC_SPI_RevA1_StartTransmission((mxc_spi_reva_regs_t *)spi);
284 }
285 
MXC_SPI_GetActive(mxc_spi_regs_t * spi)286 int MXC_SPI_GetActive(mxc_spi_regs_t *spi)
287 {
288     return MXC_SPI_RevA1_GetActive((mxc_spi_reva_regs_t *)spi);
289 }
290 
MXC_SPI_AbortTransmission(mxc_spi_regs_t * spi)291 int MXC_SPI_AbortTransmission(mxc_spi_regs_t *spi)
292 {
293     return MXC_SPI_RevA1_AbortTransmission((mxc_spi_reva_regs_t *)spi);
294 }
295 
MXC_SPI_ReadRXFIFO(mxc_spi_regs_t * spi,unsigned char * bytes,unsigned int len)296 unsigned int MXC_SPI_ReadRXFIFO(mxc_spi_regs_t *spi, unsigned char *bytes, unsigned int len)
297 {
298     return MXC_SPI_RevA1_ReadRXFIFO((mxc_spi_reva_regs_t *)spi, bytes, len);
299 }
300 
MXC_SPI_GetRXFIFOAvailable(mxc_spi_regs_t * spi)301 unsigned int MXC_SPI_GetRXFIFOAvailable(mxc_spi_regs_t *spi)
302 {
303     return MXC_SPI_RevA1_GetRXFIFOAvailable((mxc_spi_reva_regs_t *)spi);
304 }
305 
MXC_SPI_WriteTXFIFO(mxc_spi_regs_t * spi,unsigned char * bytes,unsigned int len)306 unsigned int MXC_SPI_WriteTXFIFO(mxc_spi_regs_t *spi, unsigned char *bytes, unsigned int len)
307 {
308     return MXC_SPI_RevA1_WriteTXFIFO((mxc_spi_reva_regs_t *)spi, bytes, len);
309 }
310 
MXC_SPI_GetTXFIFOAvailable(mxc_spi_regs_t * spi)311 unsigned int MXC_SPI_GetTXFIFOAvailable(mxc_spi_regs_t *spi)
312 {
313     return MXC_SPI_RevA1_GetTXFIFOAvailable((mxc_spi_reva_regs_t *)spi);
314 }
315 
MXC_SPI_ClearRXFIFO(mxc_spi_regs_t * spi)316 void MXC_SPI_ClearRXFIFO(mxc_spi_regs_t *spi)
317 {
318     MXC_SPI_RevA1_ClearRXFIFO((mxc_spi_reva_regs_t *)spi);
319 }
320 
MXC_SPI_ClearTXFIFO(mxc_spi_regs_t * spi)321 void MXC_SPI_ClearTXFIFO(mxc_spi_regs_t *spi)
322 {
323     MXC_SPI_RevA1_ClearTXFIFO((mxc_spi_reva_regs_t *)spi);
324 }
325 
MXC_SPI_SetRXThreshold(mxc_spi_regs_t * spi,unsigned int numBytes)326 int MXC_SPI_SetRXThreshold(mxc_spi_regs_t *spi, unsigned int numBytes)
327 {
328     return MXC_SPI_RevA1_SetRXThreshold((mxc_spi_reva_regs_t *)spi, numBytes);
329 }
330 
MXC_SPI_GetRXThreshold(mxc_spi_regs_t * spi)331 unsigned int MXC_SPI_GetRXThreshold(mxc_spi_regs_t *spi)
332 {
333     return MXC_SPI_RevA1_GetRXThreshold((mxc_spi_reva_regs_t *)spi);
334 }
335 
MXC_SPI_SetTXThreshold(mxc_spi_regs_t * spi,unsigned int numBytes)336 int MXC_SPI_SetTXThreshold(mxc_spi_regs_t *spi, unsigned int numBytes)
337 {
338     return MXC_SPI_RevA1_SetTXThreshold((mxc_spi_reva_regs_t *)spi, numBytes);
339 }
340 
MXC_SPI_GetTXThreshold(mxc_spi_regs_t * spi)341 unsigned int MXC_SPI_GetTXThreshold(mxc_spi_regs_t *spi)
342 {
343     return MXC_SPI_RevA1_GetTXThreshold((mxc_spi_reva_regs_t *)spi);
344 }
345 
MXC_SPI_GetFlags(mxc_spi_regs_t * spi)346 unsigned int MXC_SPI_GetFlags(mxc_spi_regs_t *spi)
347 {
348     return MXC_SPI_RevA1_GetFlags((mxc_spi_reva_regs_t *)spi);
349 }
350 
MXC_SPI_ClearFlags(mxc_spi_regs_t * spi)351 void MXC_SPI_ClearFlags(mxc_spi_regs_t *spi)
352 {
353     MXC_SPI_RevA1_ClearFlags((mxc_spi_reva_regs_t *)spi);
354 }
355 
MXC_SPI_EnableInt(mxc_spi_regs_t * spi,unsigned int intEn)356 void MXC_SPI_EnableInt(mxc_spi_regs_t *spi, unsigned int intEn)
357 {
358     MXC_SPI_RevA1_EnableInt((mxc_spi_reva_regs_t *)spi, intEn);
359 }
360 
MXC_SPI_DisableInt(mxc_spi_regs_t * spi,unsigned int intDis)361 void MXC_SPI_DisableInt(mxc_spi_regs_t *spi, unsigned int intDis)
362 {
363     MXC_SPI_RevA1_DisableInt((mxc_spi_reva_regs_t *)spi, intDis);
364 }
365 
MXC_SPI_MasterTransaction(mxc_spi_req_t * req)366 int MXC_SPI_MasterTransaction(mxc_spi_req_t *req)
367 {
368     return MXC_SPI_RevA1_MasterTransaction((mxc_spi_reva_req_t *)req);
369 }
370 
MXC_SPI_MasterTransactionAsync(mxc_spi_req_t * req)371 int MXC_SPI_MasterTransactionAsync(mxc_spi_req_t *req)
372 {
373     return MXC_SPI_RevA1_MasterTransactionAsync((mxc_spi_reva_req_t *)req);
374 }
375 
MXC_SPI_MasterTransactionDMA(mxc_spi_req_t * req)376 int MXC_SPI_MasterTransactionDMA(mxc_spi_req_t *req)
377 {
378     int reqselTx = -1;
379     int reqselRx = -1;
380 
381     int spi_num;
382 
383     spi_num = MXC_SPI_GET_IDX(req->spi);
384     MXC_ASSERT(spi_num >= 0);
385 
386     if (req->txData != NULL) {
387         switch (spi_num) {
388         case 0:
389             reqselTx = MXC_DMA_REQUEST_SPI0TX;
390             break;
391         case 1:
392             reqselTx = MXC_DMA_REQUEST_SPI1TX;
393             break;
394         case 2:
395             reqselTx = MXC_DMA_REQUEST_SPI2TX;
396             break;
397         case 3:
398             reqselTx = MXC_DMA_REQUEST_SPI3TX;
399             break;
400         case 4:
401             reqselTx = MXC_DMA_REQUEST_SPI4TX;
402             break;
403         default:
404             return E_BAD_PARAM;
405         }
406     }
407 
408     if (req->rxData != NULL) {
409         switch (spi_num) {
410         case 0:
411             reqselRx = MXC_DMA_REQUEST_SPI0RX;
412             break;
413         case 1:
414             reqselRx = MXC_DMA_REQUEST_SPI1RX;
415             break;
416         case 2:
417             reqselRx = MXC_DMA_REQUEST_SPI2RX;
418             break;
419         case 3:
420             reqselRx = MXC_DMA_REQUEST_SPI3RX;
421             break;
422         case 4:
423             reqselRx = MXC_DMA_REQUEST_SPI4RX;
424             break;
425         default:
426             return E_BAD_PARAM;
427         }
428     }
429 
430     return MXC_SPI_RevA1_MasterTransactionDMA((mxc_spi_reva_req_t *)req, reqselTx, reqselRx,
431                                               MXC_DMA);
432 }
433 
MXC_SPI_SlaveTransaction(mxc_spi_req_t * req)434 int MXC_SPI_SlaveTransaction(mxc_spi_req_t *req)
435 {
436     return MXC_SPI_RevA1_SlaveTransaction((mxc_spi_reva_req_t *)req);
437 }
438 
MXC_SPI_SlaveTransactionAsync(mxc_spi_req_t * req)439 int MXC_SPI_SlaveTransactionAsync(mxc_spi_req_t *req)
440 {
441     return MXC_SPI_RevA1_SlaveTransactionAsync((mxc_spi_reva_req_t *)req);
442 }
443 
MXC_SPI_SlaveTransactionDMA(mxc_spi_req_t * req)444 int MXC_SPI_SlaveTransactionDMA(mxc_spi_req_t *req)
445 {
446     int reqselTx = -1;
447     int reqselRx = -1;
448 
449     int spi_num;
450 
451     spi_num = MXC_SPI_GET_IDX(req->spi);
452     MXC_ASSERT(spi_num >= 0);
453 
454     if (req->txData != NULL) {
455         switch (spi_num) {
456         case 0:
457             reqselRx = MXC_DMA_REQUEST_SPI0TX;
458             break;
459         case 1:
460             reqselRx = MXC_DMA_REQUEST_SPI1TX;
461             break;
462         case 2:
463             reqselTx = MXC_DMA_REQUEST_SPI2TX;
464             break;
465         case 3:
466             reqselTx = MXC_DMA_REQUEST_SPI3TX;
467             break;
468         case 4:
469             reqselTx = MXC_DMA_REQUEST_SPI4TX;
470             break;
471         default:
472             return E_BAD_PARAM;
473             break;
474         }
475     }
476 
477     if (req->rxData != NULL) {
478         switch (spi_num) {
479         case 0:
480             reqselRx = MXC_DMA_REQUEST_SPI0RX;
481             break;
482         case 1:
483             reqselRx = MXC_DMA_REQUEST_SPI1RX;
484             break;
485         case 2:
486             reqselTx = MXC_DMA_REQUEST_SPI2RX;
487             break;
488         case 3:
489             reqselTx = MXC_DMA_REQUEST_SPI3RX;
490             break;
491         case 4:
492             reqselTx = MXC_DMA_REQUEST_SPI4RX;
493             break;
494         default:
495             return E_BAD_PARAM;
496             break;
497         }
498     }
499 
500     return MXC_SPI_RevA1_SlaveTransactionDMA((mxc_spi_reva_req_t *)req, reqselTx, reqselRx,
501                                              MXC_DMA);
502 }
503 
MXC_SPI_SetDefaultTXData(mxc_spi_regs_t * spi,unsigned int defaultTXData)504 int MXC_SPI_SetDefaultTXData(mxc_spi_regs_t *spi, unsigned int defaultTXData)
505 {
506     return MXC_SPI_RevA1_SetDefaultTXData((mxc_spi_reva_regs_t *)spi, defaultTXData);
507 }
508 
MXC_SPI_AbortAsync(mxc_spi_regs_t * spi)509 void MXC_SPI_AbortAsync(mxc_spi_regs_t *spi)
510 {
511     MXC_SPI_RevA1_AbortAsync((mxc_spi_reva_regs_t *)spi);
512 }
513 
MXC_SPI_AsyncHandler(mxc_spi_regs_t * spi)514 void MXC_SPI_AsyncHandler(mxc_spi_regs_t *spi)
515 {
516     MXC_SPI_RevA1_AsyncHandler((mxc_spi_reva_regs_t *)spi);
517 }
518 
MXC_SPI_HWSSControl(mxc_spi_regs_t * spi,int state)519 void MXC_SPI_HWSSControl(mxc_spi_regs_t *spi, int state)
520 {
521     MXC_SPI_RevA1_HWSSControl((mxc_spi_reva_regs_t *)spi, state);
522 }
523