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