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.vssel) {
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         //clear mask
76         gpio_cfg_spi.mask = 0;
77 
78         if (pins.map_a) {
79             // check rest of the pins
80             if (pins.clock) {
81                 gpio_cfg_spi.mask |= MXC_GPIO_PIN_17;
82             }
83             if (pins.miso) {
84                 gpio_cfg_spi.mask |= MXC_GPIO_PIN_7;
85             }
86             if (pins.mosi) {
87                 gpio_cfg_spi.mask |= MXC_GPIO_PIN_8;
88             }
89             if (pins.ss0) {
90                 gpio_cfg_spi.mask |= MXC_GPIO_PIN_18;
91             }
92 
93             gpio_cfg_spi.func = MXC_GPIO_FUNC_ALT1;
94         } else {
95             // check rest of the pins
96             if (pins.clock) {
97                 gpio_cfg_spi.mask |= MXC_GPIO_PIN_11;
98             }
99             if (pins.miso) {
100                 gpio_cfg_spi.mask |= MXC_GPIO_PIN_13;
101             }
102             if (pins.mosi) {
103                 gpio_cfg_spi.mask |= MXC_GPIO_PIN_12;
104             }
105             if (pins.ss0) {
106                 gpio_cfg_spi.mask |= MXC_GPIO_PIN_10;
107             }
108 
109             gpio_cfg_spi.func = MXC_GPIO_FUNC_ALT2;
110         }
111 #ifdef MXC_SPI0
112     } else if (spi == MXC_SPI0) {
113         MXC_SYS_Reset_Periph(MXC_SYS_RESET0_SPI0);
114         MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_SPI0);
115 
116         //clear mask
117         gpio_cfg_spi.mask = 0;
118 
119         // check rest of the pins
120         if (pins.clock) {
121             gpio_cfg_spi.mask |= MXC_GPIO_PIN_4;
122         }
123 
124         if (pins.miso) {
125             gpio_cfg_spi.mask |= MXC_GPIO_PIN_2;
126         }
127 
128         if (pins.mosi) {
129             gpio_cfg_spi.mask |= MXC_GPIO_PIN_3;
130         }
131 
132         if (pins.ss0) {
133             gpio_cfg_spi.mask |= MXC_GPIO_PIN_5;
134         }
135 
136         gpio_cfg_spi.func = MXC_GPIO_FUNC_ALT1;
137 #endif
138     } else {
139         return E_NO_DEVICE;
140     }
141 
142     MXC_GPIO_Config(&gpio_cfg_spi);
143 #else
144     (void)pins;
145 #endif // MSDK_NO_GPIO_CLK_INIT
146 
147     return MXC_SPI_RevA1_Init((mxc_spi_reva_regs_t *)spi, masterMode, quadModeUsed, numSlaves,
148                               ssPolarity, hz);
149 }
150 
MXC_SPI_Shutdown(mxc_spi_regs_t * spi)151 int MXC_SPI_Shutdown(mxc_spi_regs_t *spi)
152 {
153     int spi_num;
154     spi_num = MXC_SPI_GET_IDX(spi);
155     MXC_ASSERT(spi_num >= 0);
156     (void)spi_num;
157 
158     MXC_SPI_RevA1_Shutdown((mxc_spi_reva_regs_t *)spi);
159 
160     if (spi == MXC_SPI1) {
161         MXC_SYS_ClockDisable(MXC_SYS_PERIPH_CLOCK_SPI1);
162 #ifdef MXC_SPI0
163     } else if (spi == MXC_SPI0) {
164         MXC_SYS_ClockDisable(MXC_SYS_PERIPH_CLOCK_SPI0);
165 #endif
166     } else {
167         return E_NO_DEVICE;
168     }
169 
170     return E_NO_ERROR;
171 }
172 
MXC_SPI_ReadyForSleep(mxc_spi_regs_t * spi)173 int MXC_SPI_ReadyForSleep(mxc_spi_regs_t *spi)
174 {
175     return MXC_SPI_RevA1_ReadyForSleep((mxc_spi_reva_regs_t *)spi);
176 }
177 
MXC_SPI_GetPeripheralClock(mxc_spi_regs_t * spi)178 int MXC_SPI_GetPeripheralClock(mxc_spi_regs_t *spi)
179 {
180     if (MXC_SPI_GET_IDX(spi) > -1 && MXC_SPI_GET_IDX(spi) < 3) {
181         return PeripheralClock;
182     } else if (MXC_SPI_GET_IDX(spi) > 2) {
183         uint32_t clk_src = (MXC_GCR->clkctrl & MXC_F_GCR_CLKCTRL_SYSCLK_SEL) >>
184                            MXC_F_GCR_CLKCTRL_SYSCLK_SEL_POS;
185         switch (clk_src) {
186         case MXC_SYS_CLOCK_IPO:
187             return IPO_FREQ;
188         case MXC_SYS_CLOCK_ERFO:
189             return ERFO_FREQ;
190         case MXC_SYS_CLOCK_IBRO:
191             return IBRO_FREQ;
192         case MXC_SYS_CLOCK_INRO:
193             return INRO_FREQ;
194         case MXC_SYS_CLOCK_ERTCO:
195             return ERTCO_FREQ;
196         case MXC_SYS_CLOCK_EXTCLK:
197             return HF_EXTCLK_FREQ;
198         default:
199             return E_BAD_PARAM;
200         }
201     } else {
202         return E_BAD_PARAM;
203     }
204     return E_NO_ERROR;
205 }
206 
MXC_SPI_SetFrequency(mxc_spi_regs_t * spi,unsigned int hz)207 int MXC_SPI_SetFrequency(mxc_spi_regs_t *spi, unsigned int hz)
208 {
209     return MXC_SPI_RevA1_SetFrequency((mxc_spi_reva_regs_t *)spi, hz);
210 }
211 
MXC_SPI_GetFrequency(mxc_spi_regs_t * spi)212 unsigned int MXC_SPI_GetFrequency(mxc_spi_regs_t *spi)
213 {
214     return MXC_SPI_RevA1_GetFrequency((mxc_spi_reva_regs_t *)spi);
215 }
216 
MXC_SPI_SetDataSize(mxc_spi_regs_t * spi,int dataSize)217 int MXC_SPI_SetDataSize(mxc_spi_regs_t *spi, int dataSize)
218 {
219     return MXC_SPI_RevA1_SetDataSize((mxc_spi_reva_regs_t *)spi, dataSize);
220 }
221 
MXC_SPI_GetDataSize(mxc_spi_regs_t * spi)222 int MXC_SPI_GetDataSize(mxc_spi_regs_t *spi)
223 {
224     return MXC_SPI_RevA1_GetDataSize((mxc_spi_reva_regs_t *)spi);
225 }
226 
MXC_SPI_SetSlave(mxc_spi_regs_t * spi,int ssIdx)227 int MXC_SPI_SetSlave(mxc_spi_regs_t *spi, int ssIdx)
228 {
229     return MXC_SPI_RevA1_SetSlave((mxc_spi_reva_regs_t *)spi, ssIdx);
230 }
231 
MXC_SPI_GetSlave(mxc_spi_regs_t * spi)232 int MXC_SPI_GetSlave(mxc_spi_regs_t *spi)
233 {
234     return MXC_SPI_RevA1_GetSlave((mxc_spi_reva_regs_t *)spi);
235 }
236 
MXC_SPI_SetWidth(mxc_spi_regs_t * spi,mxc_spi_width_t spiWidth)237 int MXC_SPI_SetWidth(mxc_spi_regs_t *spi, mxc_spi_width_t spiWidth)
238 {
239     return MXC_SPI_RevA1_SetWidth((mxc_spi_reva_regs_t *)spi, spiWidth);
240 }
241 
MXC_SPI_GetWidth(mxc_spi_regs_t * spi)242 mxc_spi_width_t MXC_SPI_GetWidth(mxc_spi_regs_t *spi)
243 {
244     return MXC_SPI_RevA1_GetWidth((mxc_spi_reva_regs_t *)spi);
245 }
246 
MXC_SPI_SetMode(mxc_spi_regs_t * spi,mxc_spi_mode_t spiMode)247 int MXC_SPI_SetMode(mxc_spi_regs_t *spi, mxc_spi_mode_t spiMode)
248 {
249     return MXC_SPI_RevA1_SetMode((mxc_spi_reva_regs_t *)spi, spiMode);
250 }
251 
MXC_SPI_GetMode(mxc_spi_regs_t * spi)252 mxc_spi_mode_t MXC_SPI_GetMode(mxc_spi_regs_t *spi)
253 {
254     return MXC_SPI_RevA1_GetMode((mxc_spi_reva_regs_t *)spi);
255 }
256 
MXC_SPI_StartTransmission(mxc_spi_regs_t * spi)257 int MXC_SPI_StartTransmission(mxc_spi_regs_t *spi)
258 {
259     return MXC_SPI_RevA1_StartTransmission((mxc_spi_reva_regs_t *)spi);
260 }
261 
MXC_SPI_GetActive(mxc_spi_regs_t * spi)262 int MXC_SPI_GetActive(mxc_spi_regs_t *spi)
263 {
264     return MXC_SPI_RevA1_GetActive((mxc_spi_reva_regs_t *)spi);
265 }
266 
MXC_SPI_AbortTransmission(mxc_spi_regs_t * spi)267 int MXC_SPI_AbortTransmission(mxc_spi_regs_t *spi)
268 {
269     return MXC_SPI_RevA1_AbortTransmission((mxc_spi_reva_regs_t *)spi);
270 }
271 
MXC_SPI_ReadRXFIFO(mxc_spi_regs_t * spi,unsigned char * bytes,unsigned int len)272 unsigned int MXC_SPI_ReadRXFIFO(mxc_spi_regs_t *spi, unsigned char *bytes, unsigned int len)
273 {
274     return MXC_SPI_RevA1_ReadRXFIFO((mxc_spi_reva_regs_t *)spi, bytes, len);
275 }
276 
MXC_SPI_GetRXFIFOAvailable(mxc_spi_regs_t * spi)277 unsigned int MXC_SPI_GetRXFIFOAvailable(mxc_spi_regs_t *spi)
278 {
279     return MXC_SPI_RevA1_GetRXFIFOAvailable((mxc_spi_reva_regs_t *)spi);
280 }
281 
MXC_SPI_WriteTXFIFO(mxc_spi_regs_t * spi,unsigned char * bytes,unsigned int len)282 unsigned int MXC_SPI_WriteTXFIFO(mxc_spi_regs_t *spi, unsigned char *bytes, unsigned int len)
283 {
284     return MXC_SPI_RevA1_WriteTXFIFO((mxc_spi_reva_regs_t *)spi, bytes, len);
285 }
286 
MXC_SPI_GetTXFIFOAvailable(mxc_spi_regs_t * spi)287 unsigned int MXC_SPI_GetTXFIFOAvailable(mxc_spi_regs_t *spi)
288 {
289     return MXC_SPI_RevA1_GetTXFIFOAvailable((mxc_spi_reva_regs_t *)spi);
290 }
291 
MXC_SPI_ClearRXFIFO(mxc_spi_regs_t * spi)292 void MXC_SPI_ClearRXFIFO(mxc_spi_regs_t *spi)
293 {
294     MXC_SPI_RevA1_ClearRXFIFO((mxc_spi_reva_regs_t *)spi);
295 }
296 
MXC_SPI_ClearTXFIFO(mxc_spi_regs_t * spi)297 void MXC_SPI_ClearTXFIFO(mxc_spi_regs_t *spi)
298 {
299     MXC_SPI_RevA1_ClearTXFIFO((mxc_spi_reva_regs_t *)spi);
300 }
301 
MXC_SPI_SetRXThreshold(mxc_spi_regs_t * spi,unsigned int numBytes)302 int MXC_SPI_SetRXThreshold(mxc_spi_regs_t *spi, unsigned int numBytes)
303 {
304     return MXC_SPI_RevA1_SetRXThreshold((mxc_spi_reva_regs_t *)spi, numBytes);
305 }
306 
MXC_SPI_GetRXThreshold(mxc_spi_regs_t * spi)307 unsigned int MXC_SPI_GetRXThreshold(mxc_spi_regs_t *spi)
308 {
309     return MXC_SPI_RevA1_GetRXThreshold((mxc_spi_reva_regs_t *)spi);
310 }
311 
MXC_SPI_SetTXThreshold(mxc_spi_regs_t * spi,unsigned int numBytes)312 int MXC_SPI_SetTXThreshold(mxc_spi_regs_t *spi, unsigned int numBytes)
313 {
314     return MXC_SPI_RevA1_SetTXThreshold((mxc_spi_reva_regs_t *)spi, numBytes);
315 }
316 
MXC_SPI_GetTXThreshold(mxc_spi_regs_t * spi)317 unsigned int MXC_SPI_GetTXThreshold(mxc_spi_regs_t *spi)
318 {
319     return MXC_SPI_RevA1_GetTXThreshold((mxc_spi_reva_regs_t *)spi);
320 }
321 
MXC_SPI_GetFlags(mxc_spi_regs_t * spi)322 unsigned int MXC_SPI_GetFlags(mxc_spi_regs_t *spi)
323 {
324     return MXC_SPI_RevA1_GetFlags((mxc_spi_reva_regs_t *)spi);
325 }
326 
MXC_SPI_ClearFlags(mxc_spi_regs_t * spi)327 void MXC_SPI_ClearFlags(mxc_spi_regs_t *spi)
328 {
329     MXC_SPI_RevA1_ClearFlags((mxc_spi_reva_regs_t *)spi);
330 }
331 
MXC_SPI_EnableInt(mxc_spi_regs_t * spi,unsigned int intEn)332 void MXC_SPI_EnableInt(mxc_spi_regs_t *spi, unsigned int intEn)
333 {
334     MXC_SPI_RevA1_EnableInt((mxc_spi_reva_regs_t *)spi, intEn);
335 }
336 
MXC_SPI_DisableInt(mxc_spi_regs_t * spi,unsigned int intDis)337 void MXC_SPI_DisableInt(mxc_spi_regs_t *spi, unsigned int intDis)
338 {
339     MXC_SPI_RevA1_DisableInt((mxc_spi_reva_regs_t *)spi, intDis);
340 }
341 
MXC_SPI_MasterTransaction(mxc_spi_req_t * req)342 int MXC_SPI_MasterTransaction(mxc_spi_req_t *req)
343 {
344     return MXC_SPI_RevA1_MasterTransaction((mxc_spi_reva_req_t *)req);
345 }
346 
MXC_SPI_MasterTransactionAsync(mxc_spi_req_t * req)347 int MXC_SPI_MasterTransactionAsync(mxc_spi_req_t *req)
348 {
349     return MXC_SPI_RevA1_MasterTransactionAsync((mxc_spi_reva_req_t *)req);
350 }
351 
MXC_SPI_MasterTransactionDMA(mxc_spi_req_t * req)352 int MXC_SPI_MasterTransactionDMA(mxc_spi_req_t *req)
353 {
354     int reqselTx = -1;
355     int reqselRx = -1;
356 
357     int spi_num;
358 
359     spi_num = MXC_SPI_GET_IDX(req->spi);
360     MXC_ASSERT(spi_num >= 0);
361 
362     if (req->txData != NULL) {
363         switch (spi_num) {
364         case 0:
365             reqselTx = MXC_DMA_REQUEST_SPI0TX;
366             break;
367 
368         case 1:
369             reqselTx = MXC_DMA_REQUEST_SPI1TX;
370             break;
371 
372         default:
373             return E_BAD_PARAM;
374         }
375     }
376 
377     if (req->rxData != NULL) {
378         switch (spi_num) {
379         case 0:
380             reqselRx = MXC_DMA_REQUEST_SPI0RX;
381             break;
382 
383         case 1:
384             reqselRx = MXC_DMA_REQUEST_SPI1RX;
385             break;
386 
387         default:
388             return E_BAD_PARAM;
389         }
390     }
391 
392     return MXC_SPI_RevA1_MasterTransactionDMA((mxc_spi_reva_req_t *)req, reqselTx, reqselRx,
393                                               MXC_DMA);
394 }
395 
MXC_SPI_SlaveTransaction(mxc_spi_req_t * req)396 int MXC_SPI_SlaveTransaction(mxc_spi_req_t *req)
397 {
398     return MXC_SPI_RevA1_SlaveTransaction((mxc_spi_reva_req_t *)req);
399 }
400 
MXC_SPI_SlaveTransactionAsync(mxc_spi_req_t * req)401 int MXC_SPI_SlaveTransactionAsync(mxc_spi_req_t *req)
402 {
403     return MXC_SPI_RevA1_SlaveTransactionAsync((mxc_spi_reva_req_t *)req);
404 }
405 
MXC_SPI_SlaveTransactionDMA(mxc_spi_req_t * req)406 int MXC_SPI_SlaveTransactionDMA(mxc_spi_req_t *req)
407 {
408     int reqselTx = -1;
409     int reqselRx = -1;
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_SPI1TX;
420             break;
421 
422         case 1:
423             reqselTx = MXC_DMA_REQUEST_SPI0TX;
424             break;
425 
426         default:
427             return E_BAD_PARAM;
428             break;
429         }
430     }
431 
432     if (req->rxData != NULL) {
433         switch (spi_num) {
434         case 0:
435             reqselRx = MXC_DMA_REQUEST_SPI1RX;
436             break;
437 
438         case 1:
439             reqselRx = MXC_DMA_REQUEST_SPI0RX;
440             break;
441 
442         default:
443             return E_BAD_PARAM;
444             break;
445         }
446     }
447 
448     return MXC_SPI_RevA1_SlaveTransactionDMA((mxc_spi_reva_req_t *)req, reqselTx, reqselRx,
449                                              MXC_DMA);
450 }
451 
MXC_SPI_SetDefaultTXData(mxc_spi_regs_t * spi,unsigned int defaultTXData)452 int MXC_SPI_SetDefaultTXData(mxc_spi_regs_t *spi, unsigned int defaultTXData)
453 {
454     return MXC_SPI_RevA1_SetDefaultTXData((mxc_spi_reva_regs_t *)spi, defaultTXData);
455 }
456 
MXC_SPI_AbortAsync(mxc_spi_regs_t * spi)457 void MXC_SPI_AbortAsync(mxc_spi_regs_t *spi)
458 {
459     MXC_SPI_RevA1_AbortAsync((mxc_spi_reva_regs_t *)spi);
460 }
461 
MXC_SPI_AsyncHandler(mxc_spi_regs_t * spi)462 void MXC_SPI_AsyncHandler(mxc_spi_regs_t *spi)
463 {
464     MXC_SPI_RevA1_AsyncHandler((mxc_spi_reva_regs_t *)spi);
465 }
466 
MXC_SPI_HWSSControl(mxc_spi_regs_t * spi,int state)467 void MXC_SPI_HWSSControl(mxc_spi_regs_t *spi, int state)
468 {
469     MXC_SPI_RevA1_HWSSControl((mxc_spi_reva_regs_t *)spi, state);
470 }
471