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 "mxc_device.h"
25 #include "mxc_assert.h"
26 #include "mxc_lock.h"
27 #include "mxc_sys.h"
28 #include "mxc_delay.h"
29 #include "spi_reva1.h"
30 #include "dma.h"
31 
32 /* **** Functions **** */
MXC_SPI_Init(mxc_spi_regs_t * spi,int masterMode,int quadModeUsed,int numSlaves,unsigned ssPolarity,unsigned int hz,sys_map_t map)33 int MXC_SPI_Init(mxc_spi_regs_t *spi, int masterMode, int quadModeUsed, int numSlaves,
34                  unsigned ssPolarity, unsigned int hz, sys_map_t map)
35 {
36     int spi_num;
37 
38     spi_num = MXC_SPI_GET_IDX(spi);
39     (void)spi_num;
40     MXC_ASSERT(spi_num >= 0);
41 
42     if (numSlaves > MXC_SPI_SS_INSTANCES) {
43         return E_BAD_PARAM;
44     }
45 
46     // Check if frequency is too high
47     if (hz > PeripheralClock) {
48         return E_BAD_PARAM;
49     }
50 
51 #ifndef MSDK_NO_GPIO_CLK_INIT
52     // Configure GPIO for spi
53     if (spi == MXC_SPI0) {
54         MXC_GCR->rstr1 |= MXC_F_GCR_RSTR1_SPI0;
55         while (MXC_GCR->rstr1 & MXC_F_GCR_RSTR1_SPI0) {}
56         MXC_GCR->perckcn1 &= ~(MXC_F_GCR_PERCKCN1_SPI0D);
57         if (map == MAP_A) {
58             MXC_GPIO_Config(&gpio_cfg_spi0a);
59 
60             // Configure Chip Select GPIOs
61             if (numSlaves == 1) {
62                 MXC_GPIO_Config(&gpio_cfg_spi0_ss0a);
63             }
64             if (numSlaves == 2) {
65                 MXC_GPIO_Config(&gpio_cfg_spi0_ss0a);
66                 MXC_GPIO_Config(&gpio_cfg_spi0_ss1);
67             }
68             if (numSlaves == 3) {
69                 MXC_GPIO_Config(&gpio_cfg_spi0_ss0a);
70                 MXC_GPIO_Config(&gpio_cfg_spi0_ss1);
71                 MXC_GPIO_Config(&gpio_cfg_spi0_ss2);
72             }
73         } else if (map == MAP_B) {
74             // Configure Chip Select GPIOs
75             if (numSlaves == 1) {
76                 MXC_GPIO_Config(&gpio_cfg_spi0_ss0b);
77             }
78             if (numSlaves == 2) {
79                 MXC_GPIO_Config(&gpio_cfg_spi0_ss0b);
80                 MXC_GPIO_Config(&gpio_cfg_spi0_ss1);
81             }
82             if (numSlaves == 3) {
83                 MXC_GPIO_Config(&gpio_cfg_spi0_ss0b);
84                 MXC_GPIO_Config(&gpio_cfg_spi0_ss1);
85                 MXC_GPIO_Config(&gpio_cfg_spi0_ss2);
86             }
87             MXC_GPIO_Config(&gpio_cfg_spi0b);
88         } else {
89             return E_BAD_PARAM;
90         }
91     } else if (spi == MXC_SPI1) {
92         MXC_GCR->rstr0 |= MXC_F_GCR_RSTR0_SPI1;
93         while (MXC_GCR->rstr0 & MXC_F_GCR_RSTR0_SPI1) {}
94         MXC_GCR->perckcn0 &= ~(MXC_F_GCR_PERCKCN0_SPI1D);
95         MXC_GPIO_Config(&gpio_cfg_spi1);
96         // Configure Chip Select GPIOs
97         if (numSlaves == 1) {
98             MXC_GPIO_Config(&gpio_cfg_spi1_ss0);
99         }
100         if (numSlaves == 2) {
101             MXC_GPIO_Config(&gpio_cfg_spi1_ss0);
102             MXC_GPIO_Config(&gpio_cfg_spi1_ss1);
103         }
104         if (numSlaves == 3) {
105             MXC_GPIO_Config(&gpio_cfg_spi1_ss0);
106             MXC_GPIO_Config(&gpio_cfg_spi1_ss1);
107             MXC_GPIO_Config(&gpio_cfg_spi1_ss2);
108         }
109     } else if (spi == MXC_SPI2) {
110         MXC_GCR->rstr0 |= MXC_F_GCR_RSTR0_SPI2;
111         while (MXC_GCR->rstr0 & MXC_F_GCR_RSTR0_SPI2) {}
112         MXC_GCR->perckcn0 &= ~(MXC_F_GCR_PERCKCN0_SPI2D);
113         MXC_GPIO_Config(&gpio_cfg_spi2);
114 
115         // Configure Chip Select GPIOs
116         if (numSlaves == 1) {
117             MXC_GPIO_Config(&gpio_cfg_spi2_ss0);
118         }
119         if (numSlaves == 2) {
120             MXC_GPIO_Config(&gpio_cfg_spi2_ss0);
121             MXC_GPIO_Config(&gpio_cfg_spi2_ss1);
122         }
123         if (numSlaves == 3) {
124             MXC_GPIO_Config(&gpio_cfg_spi2_ss0);
125             MXC_GPIO_Config(&gpio_cfg_spi2_ss1);
126             MXC_GPIO_Config(&gpio_cfg_spi2_ss2);
127         }
128     } else {
129         return E_NO_DEVICE;
130     }
131 #else
132     (void)map;
133 #endif // MSDK_NO_GPIO_CLK_INIT
134 
135     return MXC_SPI_RevA1_Init((mxc_spi_reva_regs_t *)spi, masterMode, quadModeUsed, numSlaves,
136                               ssPolarity, hz);
137 }
138 
MXC_SPI_Shutdown(mxc_spi_regs_t * spi)139 int MXC_SPI_Shutdown(mxc_spi_regs_t *spi)
140 {
141     int spi_num;
142     spi_num = MXC_SPI_GET_IDX(spi);
143     (void)spi_num;
144     MXC_ASSERT(spi_num >= 0);
145 
146     MXC_SPI_RevA1_Shutdown((mxc_spi_reva_regs_t *)spi);
147 
148     if (spi == MXC_SPI0) {
149         MXC_GCR->perckcn1 |= (MXC_F_GCR_PERCKCN1_SPI0D);
150     } else if (spi == MXC_SPI1) {
151         MXC_GCR->perckcn0 |= (MXC_F_GCR_PERCKCN0_SPI1D);
152     } else if (spi == MXC_SPI2) {
153         MXC_GCR->perckcn0 |= (MXC_F_GCR_PERCKCN0_SPI2D);
154     } else {
155         return E_INVALID;
156     }
157 
158     return E_NO_ERROR;
159 }
160 
MXC_SPI_ReadyForSleep(mxc_spi_regs_t * spi)161 int MXC_SPI_ReadyForSleep(mxc_spi_regs_t *spi)
162 {
163     return MXC_SPI_RevA1_ReadyForSleep((mxc_spi_reva_regs_t *)spi);
164 }
165 
MXC_SPI_GetPeripheralClock(mxc_spi_regs_t * spi)166 int MXC_SPI_GetPeripheralClock(mxc_spi_regs_t *spi)
167 {
168     if (spi == MXC_SPI0) {
169         uint32_t clk_src = (MXC_GCR->clkcn & MXC_F_GCR_CLKCN_CLKSEL) >> MXC_F_GCR_CLKCN_CLKSEL_POS;
170         switch (clk_src) {
171         case MXC_SYS_CLOCK_HIRC96:
172             return HIRC96_FREQ;
173         case MXC_SYS_CLOCK_HIRC8:
174             return HIRC8_FREQ;
175         case MXC_SYS_CLOCK_HIRC:
176             return HIRC_FREQ;
177         case MXC_SYS_CLOCK_XTAL32M:
178             return XTAL32M_FREQ;
179         case MXC_SYS_CLOCK_LIRC8K:
180             return LIRC8_FREQ;
181         case MXC_SYS_CLOCK_XTAL32K:
182             return XTAL32K_FREQ;
183         default:
184             return E_BAD_PARAM;
185         }
186     } else if (spi == MXC_SPI1 || spi == MXC_SPI2) {
187         return PeripheralClock;
188     }
189     return E_NO_ERROR;
190 }
191 
MXC_SPI_SetFrequency(mxc_spi_regs_t * spi,unsigned int hz)192 int MXC_SPI_SetFrequency(mxc_spi_regs_t *spi, unsigned int hz)
193 {
194     return MXC_SPI_RevA1_SetFrequency((mxc_spi_reva_regs_t *)spi, hz);
195 }
196 
MXC_SPI_GetFrequency(mxc_spi_regs_t * spi)197 unsigned int MXC_SPI_GetFrequency(mxc_spi_regs_t *spi)
198 {
199     return MXC_SPI_RevA1_GetFrequency((mxc_spi_reva_regs_t *)spi);
200 }
201 
MXC_SPI_SetDataSize(mxc_spi_regs_t * spi,int dataSize)202 int MXC_SPI_SetDataSize(mxc_spi_regs_t *spi, int dataSize)
203 {
204     return MXC_SPI_RevA1_SetDataSize((mxc_spi_reva_regs_t *)spi, dataSize);
205 }
206 
MXC_SPI_GetDataSize(mxc_spi_regs_t * spi)207 int MXC_SPI_GetDataSize(mxc_spi_regs_t *spi)
208 {
209     return MXC_SPI_RevA1_GetDataSize((mxc_spi_reva_regs_t *)spi);
210 }
211 
MXC_SPI_SetSlave(mxc_spi_regs_t * spi,int ssIdx)212 int MXC_SPI_SetSlave(mxc_spi_regs_t *spi, int ssIdx)
213 {
214     return MXC_SPI_RevA1_SetSlave((mxc_spi_reva_regs_t *)spi, ssIdx);
215 }
216 
MXC_SPI_GetSlave(mxc_spi_regs_t * spi)217 int MXC_SPI_GetSlave(mxc_spi_regs_t *spi)
218 {
219     return MXC_SPI_RevA1_GetSlave((mxc_spi_reva_regs_t *)spi);
220 }
221 
MXC_SPI_SetWidth(mxc_spi_regs_t * spi,mxc_spi_width_t spiWidth)222 int MXC_SPI_SetWidth(mxc_spi_regs_t *spi, mxc_spi_width_t spiWidth)
223 {
224     return MXC_SPI_RevA1_SetWidth((mxc_spi_reva_regs_t *)spi, spiWidth);
225 }
226 
MXC_SPI_GetWidth(mxc_spi_regs_t * spi)227 mxc_spi_width_t MXC_SPI_GetWidth(mxc_spi_regs_t *spi)
228 {
229     return (mxc_spi_width_t)MXC_SPI_RevA1_GetWidth((mxc_spi_reva_regs_t *)spi);
230 }
231 
MXC_SPI_SetMode(mxc_spi_regs_t * spi,mxc_spi_mode_t spiMode)232 int MXC_SPI_SetMode(mxc_spi_regs_t *spi, mxc_spi_mode_t spiMode)
233 {
234     return MXC_SPI_RevA1_SetMode((mxc_spi_reva_regs_t *)spi, spiMode);
235 }
236 
MXC_SPI_GetMode(mxc_spi_regs_t * spi)237 mxc_spi_mode_t MXC_SPI_GetMode(mxc_spi_regs_t *spi)
238 {
239     return MXC_SPI_RevA1_GetMode((mxc_spi_reva_regs_t *)spi);
240 }
241 
MXC_SPI_StartTransmission(mxc_spi_regs_t * spi)242 int MXC_SPI_StartTransmission(mxc_spi_regs_t *spi)
243 {
244     return MXC_SPI_RevA1_StartTransmission((mxc_spi_reva_regs_t *)spi);
245 }
246 
MXC_SPI_GetActive(mxc_spi_regs_t * spi)247 int MXC_SPI_GetActive(mxc_spi_regs_t *spi)
248 {
249     return MXC_SPI_RevA1_GetActive((mxc_spi_reva_regs_t *)spi);
250 }
251 
MXC_SPI_AbortTransmission(mxc_spi_regs_t * spi)252 int MXC_SPI_AbortTransmission(mxc_spi_regs_t *spi)
253 {
254     return MXC_SPI_RevA1_AbortTransmission((mxc_spi_reva_regs_t *)spi);
255 }
256 
MXC_SPI_ReadRXFIFO(mxc_spi_regs_t * spi,unsigned char * bytes,unsigned int len)257 unsigned int MXC_SPI_ReadRXFIFO(mxc_spi_regs_t *spi, unsigned char *bytes, unsigned int len)
258 {
259     return MXC_SPI_RevA1_ReadRXFIFO((mxc_spi_reva_regs_t *)spi, bytes, len);
260 }
261 
MXC_SPI_GetRXFIFOAvailable(mxc_spi_regs_t * spi)262 unsigned int MXC_SPI_GetRXFIFOAvailable(mxc_spi_regs_t *spi)
263 {
264     return MXC_SPI_RevA1_GetRXFIFOAvailable((mxc_spi_reva_regs_t *)spi);
265 }
266 
MXC_SPI_WriteTXFIFO(mxc_spi_regs_t * spi,unsigned char * bytes,unsigned int len)267 unsigned int MXC_SPI_WriteTXFIFO(mxc_spi_regs_t *spi, unsigned char *bytes, unsigned int len)
268 {
269     return MXC_SPI_RevA1_WriteTXFIFO((mxc_spi_reva_regs_t *)spi, bytes, len);
270 }
271 
MXC_SPI_GetTXFIFOAvailable(mxc_spi_regs_t * spi)272 unsigned int MXC_SPI_GetTXFIFOAvailable(mxc_spi_regs_t *spi)
273 {
274     return MXC_SPI_RevA1_GetTXFIFOAvailable((mxc_spi_reva_regs_t *)spi);
275 }
276 
MXC_SPI_ClearRXFIFO(mxc_spi_regs_t * spi)277 void MXC_SPI_ClearRXFIFO(mxc_spi_regs_t *spi)
278 {
279     MXC_SPI_RevA1_ClearRXFIFO((mxc_spi_reva_regs_t *)spi);
280 }
281 
MXC_SPI_ClearTXFIFO(mxc_spi_regs_t * spi)282 void MXC_SPI_ClearTXFIFO(mxc_spi_regs_t *spi)
283 {
284     MXC_SPI_RevA1_ClearTXFIFO((mxc_spi_reva_regs_t *)spi);
285 }
286 
MXC_SPI_SetRXThreshold(mxc_spi_regs_t * spi,unsigned int numBytes)287 int MXC_SPI_SetRXThreshold(mxc_spi_regs_t *spi, unsigned int numBytes)
288 {
289     return MXC_SPI_RevA1_SetRXThreshold((mxc_spi_reva_regs_t *)spi, numBytes);
290 }
291 
MXC_SPI_GetRXThreshold(mxc_spi_regs_t * spi)292 unsigned int MXC_SPI_GetRXThreshold(mxc_spi_regs_t *spi)
293 {
294     return MXC_SPI_RevA1_GetRXThreshold((mxc_spi_reva_regs_t *)spi);
295 }
296 
MXC_SPI_SetTXThreshold(mxc_spi_regs_t * spi,unsigned int numBytes)297 int MXC_SPI_SetTXThreshold(mxc_spi_regs_t *spi, unsigned int numBytes)
298 {
299     return MXC_SPI_RevA1_SetTXThreshold((mxc_spi_reva_regs_t *)spi, numBytes);
300 }
301 
MXC_SPI_GetTXThreshold(mxc_spi_regs_t * spi)302 unsigned int MXC_SPI_GetTXThreshold(mxc_spi_regs_t *spi)
303 {
304     return MXC_SPI_RevA1_GetTXThreshold((mxc_spi_reva_regs_t *)spi);
305 }
306 
MXC_SPI_GetFlags(mxc_spi_regs_t * spi)307 unsigned int MXC_SPI_GetFlags(mxc_spi_regs_t *spi)
308 {
309     return MXC_SPI_RevA1_GetFlags((mxc_spi_reva_regs_t *)spi);
310 }
311 
MXC_SPI_ClearFlags(mxc_spi_regs_t * spi)312 void MXC_SPI_ClearFlags(mxc_spi_regs_t *spi)
313 {
314     MXC_SPI_RevA1_ClearFlags((mxc_spi_reva_regs_t *)spi);
315 }
316 
MXC_SPI_EnableInt(mxc_spi_regs_t * spi,unsigned int mask)317 void MXC_SPI_EnableInt(mxc_spi_regs_t *spi, unsigned int mask)
318 {
319     MXC_SPI_RevA1_EnableInt((mxc_spi_reva_regs_t *)spi, mask);
320 }
321 
MXC_SPI_DisableInt(mxc_spi_regs_t * spi,unsigned int mask)322 void MXC_SPI_DisableInt(mxc_spi_regs_t *spi, unsigned int mask)
323 {
324     MXC_SPI_RevA1_DisableInt((mxc_spi_reva_regs_t *)spi, mask);
325 }
326 
MXC_SPI_MasterTransaction(mxc_spi_req_t * req)327 int MXC_SPI_MasterTransaction(mxc_spi_req_t *req)
328 {
329     return MXC_SPI_RevA1_MasterTransaction((mxc_spi_reva_req_t *)req);
330 }
331 
MXC_SPI_MasterTransactionAsync(mxc_spi_req_t * req)332 int MXC_SPI_MasterTransactionAsync(mxc_spi_req_t *req)
333 {
334     return MXC_SPI_RevA1_MasterTransactionAsync((mxc_spi_reva_req_t *)req);
335 }
336 
MXC_SPI_MasterTransactionDMA(mxc_spi_req_t * req,mxc_dma_regs_t * dma)337 int MXC_SPI_MasterTransactionDMA(mxc_spi_req_t *req, mxc_dma_regs_t *dma)
338 {
339     int reqselTx = -1;
340     int reqselRx = -1;
341 
342     int spi_num;
343 
344     if (MXC_DMA_GET_IDX(dma) == -1) {
345         return E_BAD_PARAM;
346     }
347 
348     spi_num = MXC_SPI_GET_IDX(req->spi);
349     MXC_ASSERT(spi_num >= 0);
350 
351     if (req->txData != NULL) {
352         switch (spi_num) {
353         case 0:
354             reqselTx = MXC_DMA_REQUEST_SPI0TX;
355             break;
356 
357         case 1:
358             reqselTx = MXC_DMA_REQUEST_SPI1TX;
359             break;
360 
361         case 2:
362             reqselTx = MXC_DMA_REQUEST_SPI2TX;
363             break;
364 
365         default:
366             return E_BAD_PARAM;
367         }
368     }
369 
370     if (req->rxData != NULL) {
371         switch (spi_num) {
372         case 0:
373             reqselRx = MXC_DMA_REQUEST_SPI0RX;
374             break;
375 
376         case 1:
377             reqselRx = MXC_DMA_REQUEST_SPI1RX;
378             break;
379 
380         case 2:
381             reqselRx = MXC_DMA_REQUEST_SPI2RX;
382             break;
383 
384         default:
385             return E_BAD_PARAM;
386         }
387     }
388 
389     return MXC_SPI_RevA1_MasterTransactionDMA((mxc_spi_reva_req_t *)req, reqselTx, reqselRx, dma);
390 }
391 
MXC_SPI_SlaveTransaction(mxc_spi_req_t * req)392 int MXC_SPI_SlaveTransaction(mxc_spi_req_t *req)
393 {
394     return MXC_SPI_RevA1_SlaveTransaction((mxc_spi_reva_req_t *)req);
395 }
396 
MXC_SPI_SlaveTransactionAsync(mxc_spi_req_t * req)397 int MXC_SPI_SlaveTransactionAsync(mxc_spi_req_t *req)
398 {
399     return MXC_SPI_RevA1_SlaveTransactionAsync((mxc_spi_reva_req_t *)req);
400 }
401 
MXC_SPI_SlaveTransactionDMA(mxc_spi_req_t * req,mxc_dma_regs_t * dma)402 int MXC_SPI_SlaveTransactionDMA(mxc_spi_req_t *req, mxc_dma_regs_t *dma)
403 {
404     int reqselTx = -1;
405     int reqselRx = -1;
406 
407     if (MXC_DMA_GET_IDX(dma) == -1) {
408         return E_BAD_PARAM;
409     }
410 
411     int spi_num;
412 
413     spi_num = MXC_SPI_GET_IDX(req->spi);
414     MXC_ASSERT(spi_num >= 0);
415 
416     if (req->txData != NULL) {
417         switch (spi_num) {
418         case 0:
419             reqselTx = MXC_DMA_REQUEST_SPI0TX;
420             break;
421 
422         case 1:
423             reqselTx = MXC_DMA_REQUEST_SPI1TX;
424             break;
425 
426         case 2:
427             reqselTx = MXC_DMA_REQUEST_SPI2TX;
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_SPI0RX;
439             break;
440 
441         case 1:
442             reqselRx = MXC_DMA_REQUEST_SPI1RX;
443             break;
444 
445         case 2:
446             reqselRx = MXC_DMA_REQUEST_SPI2RX;
447             break;
448 
449         default:
450             return E_BAD_PARAM;
451         }
452     }
453 
454     return MXC_SPI_RevA1_SlaveTransactionDMA((mxc_spi_reva_req_t *)req, reqselTx, reqselRx, dma);
455 }
456 
MXC_SPI_SetDefaultTXData(mxc_spi_regs_t * spi,unsigned int defaultTXData)457 int MXC_SPI_SetDefaultTXData(mxc_spi_regs_t *spi, unsigned int defaultTXData)
458 {
459     return MXC_SPI_RevA1_SetDefaultTXData((mxc_spi_reva_regs_t *)spi, defaultTXData);
460 }
461 
MXC_SPI_AbortAsync(mxc_spi_regs_t * spi)462 void MXC_SPI_AbortAsync(mxc_spi_regs_t *spi)
463 {
464     MXC_SPI_RevA1_AbortAsync((mxc_spi_reva_regs_t *)spi);
465 }
466 
MXC_SPI_AsyncHandler(mxc_spi_regs_t * spi)467 void MXC_SPI_AsyncHandler(mxc_spi_regs_t *spi)
468 {
469     MXC_SPI_RevA1_AsyncHandler((mxc_spi_reva_regs_t *)spi);
470 }
471 
MXC_SPI_HWSSControl(mxc_spi_regs_t * spi,int state)472 void MXC_SPI_HWSSControl(mxc_spi_regs_t *spi, int state)
473 {
474     MXC_SPI_RevA1_HWSSControl((mxc_spi_reva_regs_t *)spi, state);
475 }
476