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 == 0) && (hz > PeripheralClock)) {
51         return E_BAD_PARAM;
52     }
53 
54     if ((spi_num == 1) && (hz > SystemCoreClock)) {
55         return E_BAD_PARAM;
56     }
57 
58 #ifndef MSDK_NO_GPIO_CLK_INIT
59     mxc_gpio_cfg_t gpio_cfg_spi;
60     gpio_cfg_spi.pad = MXC_GPIO_PAD_NONE;
61     gpio_cfg_spi.port = MXC_GPIO0;
62 
63     // Set VDDIO level
64     if (pins.vddioh) {
65         gpio_cfg_spi.vssel = MXC_GPIO_VSSEL_VDDIOH;
66     } else {
67         gpio_cfg_spi.vssel = MXC_GPIO_VSSEL_VDDIO;
68     }
69 
70     // Configure GPIO for spi
71     if (spi == MXC_SPI1) {
72         MXC_SYS_Reset_Periph(MXC_SYS_RESET0_SPI1);
73         MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_SPI1);
74 
75 #if (TARGET != MAX78000 || TARGET_NUM == 32655)
76 
77         //Define pins
78         if (pins.ss1) {
79             gpio_cfg_spi.mask = MXC_GPIO_PIN_26;
80             gpio_cfg_spi.func = MXC_GPIO_FUNC_ALT2;
81             MXC_GPIO_Config(&gpio_cfg_spi);
82         }
83 
84         if (pins.ss2) {
85             gpio_cfg_spi.func = MXC_GPIO_FUNC_ALT2;
86             gpio_cfg_spi.mask = MXC_GPIO_PIN_27;
87             MXC_GPIO_Config(&gpio_cfg_spi);
88         }
89 
90 #endif
91         //clear mask
92         gpio_cfg_spi.mask = 0;
93 
94         // check rest of the pins
95         if (pins.clock) {
96             gpio_cfg_spi.mask |= MXC_GPIO_PIN_23;
97         }
98 
99         if (pins.miso) {
100             gpio_cfg_spi.mask |= MXC_GPIO_PIN_22;
101         }
102 
103         if (pins.mosi) {
104             gpio_cfg_spi.mask |= MXC_GPIO_PIN_21;
105         }
106 
107         if (pins.sdio2) {
108             gpio_cfg_spi.mask |= MXC_GPIO_PIN_24;
109         }
110 
111         if (pins.sdio3) {
112             gpio_cfg_spi.mask |= MXC_GPIO_PIN_25;
113         }
114 
115         if (pins.ss0) {
116             gpio_cfg_spi.mask |= MXC_GPIO_PIN_20;
117         }
118 
119         gpio_cfg_spi.func = MXC_GPIO_FUNC_ALT1;
120 #ifdef MXC_SPI0
121     } else if (spi == MXC_SPI0) {
122         MXC_SYS_Reset_Periph(MXC_SYS_RESET1_SPI0);
123         MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_SPI0);
124 
125         //Define pins
126         if (pins.ss1) {
127             gpio_cfg_spi.mask = MXC_GPIO_PIN_11;
128             gpio_cfg_spi.func = MXC_GPIO_FUNC_ALT2;
129             MXC_GPIO_Config(&gpio_cfg_spi);
130         }
131 
132         if (pins.ss2) {
133             gpio_cfg_spi.func = MXC_GPIO_FUNC_ALT2;
134             gpio_cfg_spi.mask = MXC_GPIO_PIN_10;
135             MXC_GPIO_Config(&gpio_cfg_spi);
136         }
137 
138         //clear mask
139         gpio_cfg_spi.mask = 0;
140 
141         // check rest of the pins
142         if (pins.clock) {
143             gpio_cfg_spi.mask |= MXC_GPIO_PIN_7;
144         }
145 
146         if (pins.miso) {
147             gpio_cfg_spi.mask |= MXC_GPIO_PIN_6;
148         }
149 
150         if (pins.mosi) {
151             gpio_cfg_spi.mask |= MXC_GPIO_PIN_5;
152         }
153 
154         if (pins.sdio2) {
155             gpio_cfg_spi.mask |= MXC_GPIO_PIN_8;
156         }
157 
158         if (pins.sdio3) {
159             gpio_cfg_spi.mask |= MXC_GPIO_PIN_9;
160         }
161 
162         if (pins.ss0) {
163             gpio_cfg_spi.mask |= MXC_GPIO_PIN_4;
164         }
165 
166         gpio_cfg_spi.func = MXC_GPIO_FUNC_ALT1;
167 #endif
168     } else {
169         return E_NO_DEVICE;
170     }
171 
172     MXC_GPIO_Config(&gpio_cfg_spi);
173 #else
174     (void)pins;
175 #endif // MSDK_NO_GPIO_CLK_INIT
176 
177     return MXC_SPI_RevA1_Init((mxc_spi_reva_regs_t *)spi, masterMode, quadModeUsed, numSlaves,
178                               ssPolarity, hz);
179 }
180 
MXC_SPI_Shutdown(mxc_spi_regs_t * spi)181 int MXC_SPI_Shutdown(mxc_spi_regs_t *spi)
182 {
183     int spi_num;
184     spi_num = MXC_SPI_GET_IDX(spi);
185     MXC_ASSERT(spi_num >= 0);
186     (void)spi_num;
187 
188     MXC_SPI_RevA1_Shutdown((mxc_spi_reva_regs_t *)spi);
189 
190     if (spi == MXC_SPI1) {
191         MXC_SYS_ClockDisable(MXC_SYS_PERIPH_CLOCK_SPI1);
192 #ifdef MXC_SPI0
193     } else if (spi == MXC_SPI0) {
194         MXC_SYS_ClockDisable(MXC_SYS_PERIPH_CLOCK_SPI0);
195 #endif
196     } else {
197         return E_NO_DEVICE;
198     }
199 
200     return E_NO_ERROR;
201 }
202 
MXC_SPI_ReadyForSleep(mxc_spi_regs_t * spi)203 int MXC_SPI_ReadyForSleep(mxc_spi_regs_t *spi)
204 {
205     return MXC_SPI_RevA1_ReadyForSleep((mxc_spi_reva_regs_t *)spi);
206 }
207 
MXC_SPI_GetPeripheralClock(mxc_spi_regs_t * spi)208 int MXC_SPI_GetPeripheralClock(mxc_spi_regs_t *spi)
209 {
210     int retval;
211 
212     if (spi == MXC_SPI1) {
213         retval = PeripheralClock;
214 #ifdef MXC_SPI0 // SPI0 is not accessible from the RISC core.
215     } else if (spi == MXC_SPI0) {
216         int sys_clk = (MXC_GCR->clkctrl & MXC_F_GCR_CLKCTRL_SYSCLK_SEL) >>
217                       MXC_F_GCR_CLKCTRL_SYSCLK_SEL_POS;
218         switch (sys_clk) {
219         case MXC_SYS_CLOCK_IPO:
220             retval = IPO_FREQ;
221             break;
222         case MXC_SYS_CLOCK_IBRO:
223             retval = IBRO_FREQ;
224             break;
225         case MXC_SYS_CLOCK_ISO:
226             retval = ISO_FREQ;
227             break;
228         case MXC_SYS_CLOCK_INRO:
229             retval = INRO_FREQ;
230             break;
231         case MXC_SYS_CLOCK_ERTCO:
232             retval = ERTCO_FREQ;
233             break;
234         case MXC_SYS_CLOCK_EXTCLK:
235             retval = EXTCLK_FREQ;
236             break;
237 #if TARGET_NUM == 32655 || TARGET_NUM == 32680
238         case MXC_SYS_CLOCK_ERFO:
239             retval = ERFO_FREQ;
240             break;
241 #endif
242         default:
243             return E_BAD_STATE;
244         }
245 #endif // MXC_SPI0
246     } else {
247         return E_BAD_PARAM;
248     }
249 
250     retval /= 2;
251 
252     return retval;
253 }
254 
MXC_SPI_SetFrequency(mxc_spi_regs_t * spi,unsigned int hz)255 int MXC_SPI_SetFrequency(mxc_spi_regs_t *spi, unsigned int hz)
256 {
257     return MXC_SPI_RevA1_SetFrequency((mxc_spi_reva_regs_t *)spi, hz);
258 }
259 
MXC_SPI_GetFrequency(mxc_spi_regs_t * spi)260 unsigned int MXC_SPI_GetFrequency(mxc_spi_regs_t *spi)
261 {
262     return MXC_SPI_RevA1_GetFrequency((mxc_spi_reva_regs_t *)spi);
263 }
264 
MXC_SPI_SetDataSize(mxc_spi_regs_t * spi,int dataSize)265 int MXC_SPI_SetDataSize(mxc_spi_regs_t *spi, int dataSize)
266 {
267     return MXC_SPI_RevA1_SetDataSize((mxc_spi_reva_regs_t *)spi, dataSize);
268 }
269 
MXC_SPI_GetDataSize(mxc_spi_regs_t * spi)270 int MXC_SPI_GetDataSize(mxc_spi_regs_t *spi)
271 {
272     return MXC_SPI_RevA1_GetDataSize((mxc_spi_reva_regs_t *)spi);
273 }
274 
MXC_SPI_SetSlave(mxc_spi_regs_t * spi,int ssIdx)275 int MXC_SPI_SetSlave(mxc_spi_regs_t *spi, int ssIdx)
276 {
277     return MXC_SPI_RevA1_SetSlave((mxc_spi_reva_regs_t *)spi, ssIdx);
278 }
279 
MXC_SPI_GetSlave(mxc_spi_regs_t * spi)280 int MXC_SPI_GetSlave(mxc_spi_regs_t *spi)
281 {
282     return MXC_SPI_RevA1_GetSlave((mxc_spi_reva_regs_t *)spi);
283 }
284 
MXC_SPI_SetWidth(mxc_spi_regs_t * spi,mxc_spi_width_t spiWidth)285 int MXC_SPI_SetWidth(mxc_spi_regs_t *spi, mxc_spi_width_t spiWidth)
286 {
287     return MXC_SPI_RevA1_SetWidth((mxc_spi_reva_regs_t *)spi, spiWidth);
288 }
289 
MXC_SPI_GetWidth(mxc_spi_regs_t * spi)290 mxc_spi_width_t MXC_SPI_GetWidth(mxc_spi_regs_t *spi)
291 {
292     return MXC_SPI_RevA1_GetWidth((mxc_spi_reva_regs_t *)spi);
293 }
294 
MXC_SPI_SetMTMode(mxc_spi_regs_t * spi,int mtMode)295 int MXC_SPI_SetMTMode(mxc_spi_regs_t *spi, int mtMode)
296 {
297     return MXC_SPI_RevA1_SetMTMode((mxc_spi_reva_regs_t *)spi, mtMode);
298 }
299 
MXC_SPI_GetMTMode(mxc_spi_regs_t * spi)300 int MXC_SPI_GetMTMode(mxc_spi_regs_t *spi)
301 {
302     return MXC_SPI_RevA1_GetMTMode((mxc_spi_reva_regs_t *)spi);
303 }
304 
MXC_SPI_SetMode(mxc_spi_regs_t * spi,mxc_spi_mode_t spiMode)305 int MXC_SPI_SetMode(mxc_spi_regs_t *spi, mxc_spi_mode_t spiMode)
306 {
307     return MXC_SPI_RevA1_SetMode((mxc_spi_reva_regs_t *)spi, spiMode);
308 }
309 
MXC_SPI_GetMode(mxc_spi_regs_t * spi)310 mxc_spi_mode_t MXC_SPI_GetMode(mxc_spi_regs_t *spi)
311 {
312     return MXC_SPI_RevA1_GetMode((mxc_spi_reva_regs_t *)spi);
313 }
314 
MXC_SPI_StartTransmission(mxc_spi_regs_t * spi)315 int MXC_SPI_StartTransmission(mxc_spi_regs_t *spi)
316 {
317     return MXC_SPI_RevA1_StartTransmission((mxc_spi_reva_regs_t *)spi);
318 }
319 
MXC_SPI_GetActive(mxc_spi_regs_t * spi)320 int MXC_SPI_GetActive(mxc_spi_regs_t *spi)
321 {
322     return MXC_SPI_RevA1_GetActive((mxc_spi_reva_regs_t *)spi);
323 }
324 
MXC_SPI_AbortTransmission(mxc_spi_regs_t * spi)325 int MXC_SPI_AbortTransmission(mxc_spi_regs_t *spi)
326 {
327     return MXC_SPI_RevA1_AbortTransmission((mxc_spi_reva_regs_t *)spi);
328 }
329 
MXC_SPI_ReadRXFIFO(mxc_spi_regs_t * spi,unsigned char * bytes,unsigned int len)330 unsigned int MXC_SPI_ReadRXFIFO(mxc_spi_regs_t *spi, unsigned char *bytes, unsigned int len)
331 {
332     return MXC_SPI_RevA1_ReadRXFIFO((mxc_spi_reva_regs_t *)spi, bytes, len);
333 }
334 
MXC_SPI_GetRXFIFOAvailable(mxc_spi_regs_t * spi)335 unsigned int MXC_SPI_GetRXFIFOAvailable(mxc_spi_regs_t *spi)
336 {
337     return MXC_SPI_RevA1_GetRXFIFOAvailable((mxc_spi_reva_regs_t *)spi);
338 }
339 
MXC_SPI_WriteTXFIFO(mxc_spi_regs_t * spi,unsigned char * bytes,unsigned int len)340 unsigned int MXC_SPI_WriteTXFIFO(mxc_spi_regs_t *spi, unsigned char *bytes, unsigned int len)
341 {
342     return MXC_SPI_RevA1_WriteTXFIFO((mxc_spi_reva_regs_t *)spi, bytes, len);
343 }
344 
MXC_SPI_GetTXFIFOAvailable(mxc_spi_regs_t * spi)345 unsigned int MXC_SPI_GetTXFIFOAvailable(mxc_spi_regs_t *spi)
346 {
347     return MXC_SPI_RevA1_GetTXFIFOAvailable((mxc_spi_reva_regs_t *)spi);
348 }
349 
MXC_SPI_ClearRXFIFO(mxc_spi_regs_t * spi)350 void MXC_SPI_ClearRXFIFO(mxc_spi_regs_t *spi)
351 {
352     MXC_SPI_RevA1_ClearRXFIFO((mxc_spi_reva_regs_t *)spi);
353 }
354 
MXC_SPI_ClearTXFIFO(mxc_spi_regs_t * spi)355 void MXC_SPI_ClearTXFIFO(mxc_spi_regs_t *spi)
356 {
357     MXC_SPI_RevA1_ClearTXFIFO((mxc_spi_reva_regs_t *)spi);
358 }
359 
MXC_SPI_SetRXThreshold(mxc_spi_regs_t * spi,unsigned int numBytes)360 int MXC_SPI_SetRXThreshold(mxc_spi_regs_t *spi, unsigned int numBytes)
361 {
362     return MXC_SPI_RevA1_SetRXThreshold((mxc_spi_reva_regs_t *)spi, numBytes);
363 }
364 
MXC_SPI_GetRXThreshold(mxc_spi_regs_t * spi)365 unsigned int MXC_SPI_GetRXThreshold(mxc_spi_regs_t *spi)
366 {
367     return MXC_SPI_RevA1_GetRXThreshold((mxc_spi_reva_regs_t *)spi);
368 }
369 
MXC_SPI_SetTXThreshold(mxc_spi_regs_t * spi,unsigned int numBytes)370 int MXC_SPI_SetTXThreshold(mxc_spi_regs_t *spi, unsigned int numBytes)
371 {
372     return MXC_SPI_RevA1_SetTXThreshold((mxc_spi_reva_regs_t *)spi, numBytes);
373 }
374 
MXC_SPI_GetTXThreshold(mxc_spi_regs_t * spi)375 unsigned int MXC_SPI_GetTXThreshold(mxc_spi_regs_t *spi)
376 {
377     return MXC_SPI_RevA1_GetTXThreshold((mxc_spi_reva_regs_t *)spi);
378 }
379 
MXC_SPI_GetFlags(mxc_spi_regs_t * spi)380 unsigned int MXC_SPI_GetFlags(mxc_spi_regs_t *spi)
381 {
382     return MXC_SPI_RevA1_GetFlags((mxc_spi_reva_regs_t *)spi);
383 }
384 
MXC_SPI_ClearFlags(mxc_spi_regs_t * spi)385 void MXC_SPI_ClearFlags(mxc_spi_regs_t *spi)
386 {
387     MXC_SPI_RevA1_ClearFlags((mxc_spi_reva_regs_t *)spi);
388 }
389 
MXC_SPI_EnableInt(mxc_spi_regs_t * spi,unsigned int intEn)390 void MXC_SPI_EnableInt(mxc_spi_regs_t *spi, unsigned int intEn)
391 {
392     MXC_SPI_RevA1_EnableInt((mxc_spi_reva_regs_t *)spi, intEn);
393 }
394 
MXC_SPI_DisableInt(mxc_spi_regs_t * spi,unsigned int intDis)395 void MXC_SPI_DisableInt(mxc_spi_regs_t *spi, unsigned int intDis)
396 {
397     MXC_SPI_RevA1_DisableInt((mxc_spi_reva_regs_t *)spi, intDis);
398 }
399 
MXC_SPI_MasterTransaction(mxc_spi_req_t * req)400 int MXC_SPI_MasterTransaction(mxc_spi_req_t *req)
401 {
402     return MXC_SPI_RevA1_MasterTransaction((mxc_spi_reva_req_t *)req);
403 }
404 
MXC_SPI_MasterTransactionAsync(mxc_spi_req_t * req)405 int MXC_SPI_MasterTransactionAsync(mxc_spi_req_t *req)
406 {
407     return MXC_SPI_RevA1_MasterTransactionAsync((mxc_spi_reva_req_t *)req);
408 }
409 
MXC_SPI_MasterTransactionDMA(mxc_spi_req_t * req)410 int MXC_SPI_MasterTransactionDMA(mxc_spi_req_t *req)
411 {
412     int reqselTx = -1;
413     int reqselRx = -1;
414 
415     int spi_num;
416 
417     spi_num = MXC_SPI_GET_IDX(req->spi);
418     MXC_ASSERT(spi_num >= 0);
419 
420     if (req->txData != NULL) {
421         switch (spi_num) {
422         case 0:
423             reqselTx = MXC_DMA_REQUEST_SPI1TX;
424             break;
425 
426         case 1:
427             reqselTx = MXC_DMA_REQUEST_SPI0TX;
428             break;
429 
430         default:
431             return E_BAD_PARAM;
432         }
433     }
434 
435     if (req->rxData != NULL) {
436         switch (spi_num) {
437         case 0:
438             reqselRx = MXC_DMA_REQUEST_SPI1RX;
439             break;
440 
441         case 1:
442             reqselRx = MXC_DMA_REQUEST_SPI0RX;
443             break;
444 
445         default:
446             return E_BAD_PARAM;
447         }
448     }
449 
450     return MXC_SPI_RevA1_MasterTransactionDMA((mxc_spi_reva_req_t *)req, reqselTx, reqselRx,
451                                               MXC_DMA);
452 }
453 
MXC_SPI_SlaveTransaction(mxc_spi_req_t * req)454 int MXC_SPI_SlaveTransaction(mxc_spi_req_t *req)
455 {
456     return MXC_SPI_RevA1_SlaveTransaction((mxc_spi_reva_req_t *)req);
457 }
458 
MXC_SPI_SlaveTransactionAsync(mxc_spi_req_t * req)459 int MXC_SPI_SlaveTransactionAsync(mxc_spi_req_t *req)
460 {
461     return MXC_SPI_RevA1_SlaveTransactionAsync((mxc_spi_reva_req_t *)req);
462 }
463 
MXC_SPI_SlaveTransactionDMA(mxc_spi_req_t * req)464 int MXC_SPI_SlaveTransactionDMA(mxc_spi_req_t *req)
465 {
466     int reqselTx = -1;
467     int reqselRx = -1;
468 
469     int spi_num;
470 
471     spi_num = MXC_SPI_GET_IDX(req->spi);
472     MXC_ASSERT(spi_num >= 0);
473 
474     if (req->txData != NULL) {
475         switch (spi_num) {
476         case 0:
477             reqselTx = MXC_DMA_REQUEST_SPI1TX;
478             break;
479 
480         case 1:
481             reqselTx = MXC_DMA_REQUEST_SPI0TX;
482             break;
483 
484         default:
485             return E_BAD_PARAM;
486             break;
487         }
488     }
489 
490     if (req->rxData != NULL) {
491         switch (spi_num) {
492         case 0:
493             reqselRx = MXC_DMA_REQUEST_SPI1RX;
494             break;
495 
496         case 1:
497             reqselRx = MXC_DMA_REQUEST_SPI0RX;
498             break;
499 
500         default:
501             return E_BAD_PARAM;
502             break;
503         }
504     }
505 
506     return MXC_SPI_RevA1_SlaveTransactionDMA((mxc_spi_reva_req_t *)req, reqselTx, reqselRx,
507                                              MXC_DMA);
508 }
509 
MXC_SPI_SetDefaultTXData(mxc_spi_regs_t * spi,unsigned int defaultTXData)510 int MXC_SPI_SetDefaultTXData(mxc_spi_regs_t *spi, unsigned int defaultTXData)
511 {
512     return MXC_SPI_RevA1_SetDefaultTXData((mxc_spi_reva_regs_t *)spi, defaultTXData);
513 }
514 
MXC_SPI_AbortAsync(mxc_spi_regs_t * spi)515 void MXC_SPI_AbortAsync(mxc_spi_regs_t *spi)
516 {
517     MXC_SPI_RevA1_AbortAsync((mxc_spi_reva_regs_t *)spi);
518 }
519 
MXC_SPI_AsyncHandler(mxc_spi_regs_t * spi)520 void MXC_SPI_AsyncHandler(mxc_spi_regs_t *spi)
521 {
522     MXC_SPI_RevA1_AsyncHandler((mxc_spi_reva_regs_t *)spi);
523 }
524 
MXC_SPI_HWSSControl(mxc_spi_regs_t * spi,int state)525 void MXC_SPI_HWSSControl(mxc_spi_regs_t *spi, int state)
526 {
527     MXC_SPI_RevA1_HWSSControl((mxc_spi_reva_regs_t *)spi, state);
528 }
529