1 /******************************************************************************
2 * Copyright (C) 2023 Maxim Integrated Products, Inc., All Rights Reserved.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17 * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
18 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Except as contained in this notice, the name of Maxim Integrated
23 * Products, Inc. shall not be used except as stated in the Maxim Integrated
24 * Products, Inc. Branding Policy.
25 *
26 * The mere transfer of this software does not imply any licenses
27 * of trade secrets, proprietary technology, copyrights, patents,
28 * trademarks, maskwork rights, or any other form of intellectual
29 * property whatsoever. Maxim Integrated Products, Inc. retains all
30 * ownership rights.
31 *
32 ******************************************************************************/
33
34 #include <stdio.h>
35 #include <stddef.h>
36 #include <stdint.h>
37 #include <stdbool.h>
38
39 #include "mxc_device.h"
40 #include "mxc_assert.h"
41 #include "mxc_errors.h"
42 #include "mxc_lock.h"
43 #include "mxc_sys.h"
44 #include "mxc_delay.h"
45 #include "spi_reva2.h"
46 #include "spi.h"
47 #include "dma.h"
48 #include "gpio.h"
49
50 /* **** Definitions **** */
51
52 /* ************************************************************************** */
53
54 // Max 4 Possible Target Select Options per SPI instance
55 #define MXC_SPI_TS0_MASK_POS (0)
56 #define MXC_SPI_TS1_MASK_POS (1)
57 #define MXC_SPI_TS2_MASK_POS (2)
58 #define MXC_SPI_TS3_MASK_POS (3)
59
MXC_SPI_Init(mxc_spi_regs_t * spi,mxc_spi_type_t controller_target,mxc_spi_interface_t if_mode,int numTargets,uint8_t ts_active_pol_mask,uint32_t freq,mxc_spi_pins_t pins)60 int MXC_SPI_Init(mxc_spi_regs_t *spi, mxc_spi_type_t controller_target, mxc_spi_interface_t if_mode,
61 int numTargets, uint8_t ts_active_pol_mask, uint32_t freq, mxc_spi_pins_t pins)
62 {
63 int error;
64 int8_t spi_num;
65 mxc_spi_tscontrol_t ts_control;
66 mxc_gpio_cfg_t temp_cfg; // main SPI pins.
67 mxc_gpio_cfg_t temp_ts_cfg; // TS pins.
68 mxc_gpio_vssel_t vssel;
69
70 spi_num = MXC_SPI_GET_IDX(spi);
71 if (spi_num < 0 || spi_num >= MXC_SPI_INSTANCES) {
72 return E_BAD_PARAM;
73 }
74
75 // Check if frequency is too high
76 if ((spi_num == 0) && (freq > MXC_SPI_GetPeripheralClock(spi))) {
77 return E_BAD_PARAM;
78 }
79
80 if ((spi_num == 1) && (freq > SystemCoreClock)) {
81 return E_BAD_PARAM;
82 }
83
84 if (pins.vddioh) {
85 vssel = MXC_GPIO_VSSEL_VDDIOH;
86 } else {
87 vssel = MXC_GPIO_VSSEL_VDDIO;
88 }
89
90 // SPI Target mode only supports HW_AUTO.
91 if (pins.ss0 || pins.ss1 || pins.ss2 || (controller_target == MXC_SPI_TYPE_TARGET)) {
92 ts_control = MXC_SPI_TSCONTROL_HW_AUTO;
93 } else {
94 ts_control = MXC_SPI_TSCONTROL_SW_APP;
95 }
96
97 error = MXC_SPI_RevA2_SetTSControl((mxc_spi_reva_regs_t *)spi, ts_control);
98 if (error != E_NO_ERROR) {
99 return error;
100 }
101
102 // Configure SPI peripheral and pins.
103 if (spi == MXC_SPI0) {
104 MXC_SYS_Reset_Periph(MXC_SYS_RESET0_SPI0);
105 MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_SPI0);
106
107 switch (if_mode) {
108 case MXC_SPI_INTERFACE_STANDARD:
109 temp_cfg = gpio_cfg_spi0_standard;
110 break;
111
112 case MXC_SPI_INTERFACE_QUAD:
113 return E_NOT_SUPPORTED;
114
115 case MXC_SPI_INTERFACE_3WIRE:
116 temp_cfg = gpio_cfg_spi0_3wire;
117 break;
118
119 case MXC_SPI_INTERFACE_DUAL:
120 temp_cfg = gpio_cfg_spi0_dual;
121 break;
122
123 default:
124 return E_BAD_PARAM;
125 }
126
127 // Set up HW TS pins (if HW_AUTO TS control scheme was selected).
128 // Voltage and drive strength settings will match the SPI pins.
129 if (ts_control == MXC_SPI_TSCONTROL_HW_AUTO) {
130 // Target Select 0 - TS0 (L. SS0 pin)
131 if (pins.ss0 == true) {
132 temp_ts_cfg = gpio_cfg_spi0_ts0;
133 temp_ts_cfg.vssel = vssel;
134 temp_ts_cfg.drvstr = pins.drvstr;
135
136 error = MXC_GPIO_Config(&temp_ts_cfg);
137 if (error != E_NO_ERROR) {
138 return error;
139 }
140 }
141 }
142 } else if (spi == MXC_SPI1) {
143 MXC_SYS_Reset_Periph(MXC_SYS_RESET0_SPI1);
144 MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_SPI1);
145
146 switch (if_mode) {
147 case MXC_SPI_INTERFACE_STANDARD:
148 temp_cfg = gpio_cfg_spi1_standard;
149 break;
150
151 case MXC_SPI_INTERFACE_QUAD:
152 return E_NOT_SUPPORTED;
153
154 case MXC_SPI_INTERFACE_3WIRE:
155 temp_cfg = gpio_cfg_spi1_3wire;
156 break;
157
158 case MXC_SPI_INTERFACE_DUAL:
159 temp_cfg = gpio_cfg_spi1_dual;
160 break;
161
162 default:
163 return E_BAD_PARAM;
164 }
165
166 // Set up HW TS pins (if HW_AUTO TS control scheme was selected).
167 // Voltage and drive strength settings will match the SPI pins.
168 if (ts_control == MXC_SPI_TSCONTROL_HW_AUTO) {
169 // Target Select 0 - TS0 (L. SS0 pin)
170 if (pins.ss0 == true) {
171 temp_ts_cfg = gpio_cfg_spi1_ts0;
172 temp_ts_cfg.vssel = vssel;
173 temp_ts_cfg.drvstr = pins.drvstr;
174
175 error = MXC_GPIO_Config(&temp_ts_cfg);
176 if (error != E_NO_ERROR) {
177 return error;
178 }
179 }
180
181 // Target Select 1 - TS1 (L. SS1 pin)
182 if (pins.ss1 == true) {
183 temp_ts_cfg = gpio_cfg_spi1_ts1;
184 temp_ts_cfg.vssel = vssel;
185 temp_ts_cfg.drvstr = pins.drvstr;
186
187 error = MXC_GPIO_Config(&temp_ts_cfg);
188 if (error != E_NO_ERROR) {
189 return error;
190 }
191 }
192
193 // Target Select 2 - TS2 (L. SS2 pin)
194 if (pins.ss2 == true) {
195 temp_ts_cfg = gpio_cfg_spi1_ts2;
196 temp_ts_cfg.vssel = vssel;
197 temp_ts_cfg.drvstr = pins.drvstr;
198
199 error = MXC_GPIO_Config(&temp_ts_cfg);
200 if (error != E_NO_ERROR) {
201 return error;
202 }
203 }
204
205 // Target Select 3 - TS2 (L. SS3 pin)
206 if (pins.ss3 == true) {
207 temp_ts_cfg = gpio_cfg_spi1_ts3;
208 temp_ts_cfg.vssel = vssel;
209 temp_ts_cfg.drvstr = pins.drvstr;
210
211 error = MXC_GPIO_Config(&temp_ts_cfg);
212 if (error != E_NO_ERROR) {
213 return error;
214 }
215 }
216 }
217 // SPI2 does not exist in the MAX32572 (to match instance addressing with MAX32570B)
218 } else if (spi == MXC_SPI3) {
219 MXC_SYS_Reset_Periph(MXC_SYS_RESET1_SPI3);
220 MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_SPI3);
221
222 switch (if_mode) {
223 case MXC_SPI_INTERFACE_STANDARD:
224 temp_cfg = gpio_cfg_spi3_standard;
225 break;
226
227 case MXC_SPI_INTERFACE_QUAD:
228 temp_cfg = gpio_cfg_spi3_quad;
229 break;
230
231 case MXC_SPI_INTERFACE_3WIRE:
232 temp_cfg = gpio_cfg_spi3_3wire;
233 break;
234
235 case MXC_SPI_INTERFACE_DUAL:
236 temp_cfg = gpio_cfg_spi3_dual;
237 break;
238
239 default:
240 return E_BAD_PARAM;
241 }
242
243 // Set up HW TS pins (if HW_AUTO TS control scheme was selected).
244 // Voltage and drive strength settings will match the SPI pins.
245 if (ts_control == MXC_SPI_TSCONTROL_HW_AUTO) {
246 // Target Select 0 - TS0 (L. SS0 pin)
247 if (pins.ss0 == true) {
248 temp_ts_cfg = gpio_cfg_spi3_ts0;
249 temp_ts_cfg.vssel = vssel;
250 temp_ts_cfg.drvstr = pins.drvstr;
251
252 error = MXC_GPIO_Config(&temp_ts_cfg);
253 if (error != E_NO_ERROR) {
254 return error;
255 }
256 }
257
258 // Target Select 1 - TS1 (L. SS1 pin)
259 if (pins.ss1 == true) {
260 temp_ts_cfg = gpio_cfg_spi3_ts1;
261 temp_ts_cfg.vssel = vssel;
262 temp_ts_cfg.drvstr = pins.drvstr;
263
264 error = MXC_GPIO_Config(&temp_ts_cfg);
265 if (error != E_NO_ERROR) {
266 return error;
267 }
268 }
269
270 // Target Select 2 - TS2 (L. SS2 pin)
271 if (pins.ss2 == true) {
272 temp_ts_cfg = gpio_cfg_spi3_ts2;
273 temp_ts_cfg.vssel = vssel;
274 temp_ts_cfg.drvstr = pins.drvstr;
275
276 error = MXC_GPIO_Config(&temp_ts_cfg);
277 if (error != E_NO_ERROR) {
278 return error;
279 }
280 }
281
282 // Target Select 3 - TS2 (L. SS3 pin)
283 if (pins.ss3 == true) {
284 temp_ts_cfg = gpio_cfg_spi3_ts3;
285 temp_ts_cfg.vssel = vssel;
286 temp_ts_cfg.drvstr = pins.drvstr;
287
288 error = MXC_GPIO_Config(&temp_ts_cfg);
289 if (error != E_NO_ERROR) {
290 return error;
291 }
292 }
293 }
294
295 } else {
296 return E_NO_DEVICE;
297 }
298
299 temp_cfg.vssel = vssel;
300 temp_cfg.drvstr = pins.drvstr;
301
302 // Configure main SPI pins.
303 error = MXC_GPIO_Config(&temp_cfg);
304 if (error != E_NO_ERROR) {
305 return error;
306 }
307
308 return MXC_SPI_RevA2_Init((mxc_spi_reva_regs_t *)spi, controller_target, if_mode, freq,
309 ts_active_pol_mask);
310 }
311
MXC_SPI_Config(mxc_spi_cfg_t * cfg)312 int MXC_SPI_Config(mxc_spi_cfg_t *cfg)
313 {
314 return MXC_SPI_RevA2_Config(cfg);
315 }
316
MXC_SPI_ConfigStruct(mxc_spi_cfg_t * cfg,bool use_dma_tx,bool use_dma_rx)317 int MXC_SPI_ConfigStruct(mxc_spi_cfg_t *cfg, bool use_dma_tx, bool use_dma_rx)
318 {
319 if (cfg == NULL) {
320 return E_BAD_PARAM;
321 }
322
323 cfg->spi = MXC_SPI1; // SPI1 is available on both the ARM and RISCV core.
324 cfg->clk_mode = MXC_SPI_CLKMODE_0; // 0 - CPOL :: 0 - CPHA
325
326 if (use_dma_tx || use_dma_rx) {
327 cfg->use_dma_tx = use_dma_tx;
328 cfg->use_dma_rx = use_dma_rx;
329 cfg->dma = MXC_DMA;
330 } else {
331 cfg->use_dma_tx = false;
332 cfg->use_dma_rx = false;
333 cfg->dma = NULL;
334 }
335
336 return E_SUCCESS;
337 }
338
MXC_SPI_Shutdown(mxc_spi_regs_t * spi)339 int MXC_SPI_Shutdown(mxc_spi_regs_t *spi)
340 {
341 int8_t spi_num;
342
343 spi_num = MXC_SPI_GET_IDX(spi);
344 if (spi_num < 0 || spi_num >= MXC_SPI_INSTANCES) {
345 return E_BAD_PARAM;
346 }
347
348 MXC_SPI_RevA2_Shutdown((mxc_spi_reva_regs_t *)spi);
349
350 if (spi == MXC_SPI0) {
351 MXC_SYS_ClockDisable(MXC_SYS_PERIPH_CLOCK_SPI0);
352 } else if (spi == MXC_SPI1) {
353 MXC_SYS_ClockDisable(MXC_SYS_PERIPH_CLOCK_SPI1);
354 // SPI2 does not exist in the MAX32572 (to match instance addressing with MAX32570B)
355 } else if (spi == MXC_SPI3) {
356 MXC_SYS_ClockDisable(MXC_SYS_PERIPH_CLOCK_SPI3);
357 } else {
358 return E_NO_DEVICE;
359 }
360
361 return E_NO_ERROR;
362 }
363
MXC_SPI_GetFlags(mxc_spi_regs_t * spi)364 unsigned int MXC_SPI_GetFlags(mxc_spi_regs_t *spi)
365 {
366 return (unsigned int)MXC_SPI_RevA2_GetFlags((mxc_spi_reva_regs_t *)spi);
367 }
368
MXC_SPI_ClearFlags(mxc_spi_regs_t * spi)369 void MXC_SPI_ClearFlags(mxc_spi_regs_t *spi)
370 {
371 MXC_SPI_RevA2_ClearFlags((mxc_spi_reva_regs_t *)spi);
372 }
373
MXC_SPI_EnableInt(mxc_spi_regs_t * spi,unsigned int intEn)374 void MXC_SPI_EnableInt(mxc_spi_regs_t *spi, unsigned int intEn)
375 {
376 MXC_SPI_RevA2_EnableInt((mxc_spi_reva_regs_t *)spi, (uint32_t)intEn);
377 }
378
MXC_SPI_DisableInt(mxc_spi_regs_t * spi,unsigned int intDis)379 void MXC_SPI_DisableInt(mxc_spi_regs_t *spi, unsigned int intDis)
380 {
381 MXC_SPI_RevA2_DisableInt((mxc_spi_reva_regs_t *)spi, (uint32_t)intDis);
382 }
383
MXC_SPI_GetPeripheralClock(mxc_spi_regs_t * spi)384 int MXC_SPI_GetPeripheralClock(mxc_spi_regs_t *spi)
385 {
386 int retval;
387
388 retval = PeripheralClock;
389 retval /= 2;
390
391 return retval;
392 }
393
MXC_SPI_SetTSControl(mxc_spi_regs_t * spi,mxc_spi_tscontrol_t ts_control)394 int MXC_SPI_SetTSControl(mxc_spi_regs_t *spi, mxc_spi_tscontrol_t ts_control)
395 {
396 return MXC_SPI_RevA2_SetTSControl((mxc_spi_reva_regs_t *)spi, ts_control);
397 }
398
MXC_SPI_GetTSControl(mxc_spi_regs_t * spi)399 mxc_spi_tscontrol_t MXC_SPI_GetTSControl(mxc_spi_regs_t *spi)
400 {
401 return MXC_SPI_RevA2_GetTSControl((mxc_spi_reva_regs_t *)spi);
402 }
403
MXC_SPI_SetFrequency(mxc_spi_regs_t * spi,unsigned int hz)404 int MXC_SPI_SetFrequency(mxc_spi_regs_t *spi, unsigned int hz)
405 {
406 return MXC_SPI_RevA2_SetFrequency((mxc_spi_reva_regs_t *)spi, hz);
407 }
408
MXC_SPI_GetFrequency(mxc_spi_regs_t * spi)409 unsigned int MXC_SPI_GetFrequency(mxc_spi_regs_t *spi)
410 {
411 return MXC_SPI_RevA2_GetFrequency((mxc_spi_reva_regs_t *)spi);
412 }
413
MXC_SPI_SetFrameSize(mxc_spi_regs_t * spi,int frame_size)414 int MXC_SPI_SetFrameSize(mxc_spi_regs_t *spi, int frame_size)
415 {
416 return MXC_SPI_RevA2_SetFrameSize((mxc_spi_reva_regs_t *)spi, frame_size);
417 }
418
MXC_SPI_GetFrameSize(mxc_spi_regs_t * spi)419 int MXC_SPI_GetFrameSize(mxc_spi_regs_t *spi)
420 {
421 return MXC_SPI_RevA2_GetFrameSize((mxc_spi_reva_regs_t *)spi);
422 }
423
MXC_SPI_SetInterface(mxc_spi_regs_t * spi,mxc_spi_interface_t mode)424 int MXC_SPI_SetInterface(mxc_spi_regs_t *spi, mxc_spi_interface_t mode)
425 {
426 return MXC_SPI_RevA2_SetInterface((mxc_spi_reva_regs_t *)spi, mode);
427 }
428
MXC_SPI_GetInterface(mxc_spi_regs_t * spi)429 mxc_spi_interface_t MXC_SPI_GetInterface(mxc_spi_regs_t *spi)
430 {
431 return MXC_SPI_RevA2_GetInterface((mxc_spi_reva_regs_t *)spi);
432 }
433
MXC_SPI_SetClkMode(mxc_spi_regs_t * spi,mxc_spi_clkmode_t clk_mode)434 int MXC_SPI_SetClkMode(mxc_spi_regs_t *spi, mxc_spi_clkmode_t clk_mode)
435 {
436 return MXC_SPI_RevA2_SetClkMode((mxc_spi_reva_regs_t *)spi, clk_mode);
437 }
438
MXC_SPI_GetClkMode(mxc_spi_regs_t * spi)439 mxc_spi_clkmode_t MXC_SPI_GetClkMode(mxc_spi_regs_t *spi)
440 {
441 return MXC_SPI_RevA2_GetClkMode((mxc_spi_reva_regs_t *)spi);
442 }
443
MXC_SPI_SetCallback(mxc_spi_regs_t * spi,mxc_spi_callback_t completeCB,void * data)444 int MXC_SPI_SetCallback(mxc_spi_regs_t *spi, mxc_spi_callback_t completeCB, void *data)
445 {
446 return MXC_SPI_RevA2_SetCallback((mxc_spi_reva_regs_t *)spi, completeCB, data);
447 }
448
MXC_SPI_GetActive(mxc_spi_regs_t * spi)449 int MXC_SPI_GetActive(mxc_spi_regs_t *spi)
450 {
451 return MXC_SPI_RevA2_GetActive((mxc_spi_reva_regs_t *)spi);
452 }
453
MXC_SPI_ReadyForSleep(mxc_spi_regs_t * spi)454 int MXC_SPI_ReadyForSleep(mxc_spi_regs_t *spi)
455 {
456 return MXC_SPI_RevA2_ReadyForSleep((mxc_spi_reva_regs_t *)spi);
457 }
458
MXC_SPI_SetDummyTX(mxc_spi_regs_t * spi,uint16_t tx_value)459 int MXC_SPI_SetDummyTX(mxc_spi_regs_t *spi, uint16_t tx_value)
460 {
461 return MXC_SPI_RevA2_SetDummyTX((mxc_spi_reva_regs_t *)spi, tx_value);
462 }
463
MXC_SPI_StartTransmission(mxc_spi_regs_t * spi)464 int MXC_SPI_StartTransmission(mxc_spi_regs_t *spi)
465 {
466 return MXC_SPI_RevA2_StartTransmission((mxc_spi_reva_regs_t *)spi);
467 }
468
MXC_SPI_AbortTransmission(mxc_spi_regs_t * spi)469 int MXC_SPI_AbortTransmission(mxc_spi_regs_t *spi)
470 {
471 return MXC_SPI_RevA2_AbortTransmission((mxc_spi_reva_regs_t *)spi);
472 }
473
MXC_SPI_GetTXFIFOAvailable(mxc_spi_regs_t * spi)474 unsigned int MXC_SPI_GetTXFIFOAvailable(mxc_spi_regs_t *spi)
475 {
476 return MXC_SPI_RevA2_GetTXFIFOAvailable((mxc_spi_reva_regs_t *)spi);
477 }
478
MXC_SPI_GetRXFIFOAvailable(mxc_spi_regs_t * spi)479 unsigned int MXC_SPI_GetRXFIFOAvailable(mxc_spi_regs_t *spi)
480 {
481 return MXC_SPI_RevA2_GetRXFIFOAvailable((mxc_spi_reva_regs_t *)spi);
482 }
483
MXC_SPI_ClearTXFIFO(mxc_spi_regs_t * spi)484 void MXC_SPI_ClearTXFIFO(mxc_spi_regs_t *spi)
485 {
486 MXC_SPI_RevA2_ClearTXFIFO((mxc_spi_reva_regs_t *)spi);
487 }
488
MXC_SPI_ClearRXFIFO(mxc_spi_regs_t * spi)489 void MXC_SPI_ClearRXFIFO(mxc_spi_regs_t *spi)
490 {
491 MXC_SPI_RevA2_ClearRXFIFO((mxc_spi_reva_regs_t *)spi);
492 }
493
MXC_SPI_SetTXThreshold(mxc_spi_regs_t * spi,unsigned int numBytes)494 int MXC_SPI_SetTXThreshold(mxc_spi_regs_t *spi, unsigned int numBytes)
495 {
496 return (int)MXC_SPI_RevA2_SetTXThreshold((mxc_spi_reva_regs_t *)spi, numBytes);
497 }
498
MXC_SPI_SetRXThreshold(mxc_spi_regs_t * spi,unsigned int numBytes)499 int MXC_SPI_SetRXThreshold(mxc_spi_regs_t *spi, unsigned int numBytes)
500 {
501 return (int)MXC_SPI_RevA2_SetRXThreshold((mxc_spi_reva_regs_t *)spi, numBytes);
502 }
503
MXC_SPI_GetTXThreshold(mxc_spi_regs_t * spi)504 unsigned int MXC_SPI_GetTXThreshold(mxc_spi_regs_t *spi)
505 {
506 return (unsigned int)MXC_SPI_RevA2_GetTXThreshold((mxc_spi_reva_regs_t *)spi);
507 }
508
MXC_SPI_GetRXThreshold(mxc_spi_regs_t * spi)509 unsigned int MXC_SPI_GetRXThreshold(mxc_spi_regs_t *spi)
510 {
511 return (unsigned int)MXC_SPI_RevA2_GetRXThreshold((mxc_spi_reva_regs_t *)spi);
512 }
513
514 /* ** DMA-Specific Functions ** */
515
MXC_SPI_DMA_Init(mxc_spi_regs_t * spi,mxc_dma_regs_t * dma,bool use_dma_tx,bool use_dma_rx)516 int MXC_SPI_DMA_Init(mxc_spi_regs_t *spi, mxc_dma_regs_t *dma, bool use_dma_tx, bool use_dma_rx)
517 {
518 return MXC_SPI_RevA2_DMA_Init((mxc_spi_reva_regs_t *)spi, (mxc_dma_reva_regs_t *)dma,
519 use_dma_tx, use_dma_rx);
520 }
521
MXC_SPI_DMA_GetInitialized(mxc_spi_regs_t * spi)522 bool MXC_SPI_DMA_GetInitialized(mxc_spi_regs_t *spi)
523 {
524 return MXC_SPI_RevA2_DMA_GetInitialized((mxc_spi_reva_regs_t *)spi);
525 }
526
MXC_SPI_DMA_GetTXChannel(mxc_spi_regs_t * spi)527 int MXC_SPI_DMA_GetTXChannel(mxc_spi_regs_t *spi)
528 {
529 return MXC_SPI_RevA2_DMA_GetTXChannel((mxc_spi_reva_regs_t *)spi);
530 }
531
MXC_SPI_DMA_GetRXChannel(mxc_spi_regs_t * spi)532 int MXC_SPI_DMA_GetRXChannel(mxc_spi_regs_t *spi)
533 {
534 return MXC_SPI_RevA2_DMA_GetRXChannel((mxc_spi_reva_regs_t *)spi);
535 }
536
MXC_SPI_DMA_SetRequestSelect(mxc_spi_regs_t * spi,bool use_dma_tx,bool use_dma_rx)537 int MXC_SPI_DMA_SetRequestSelect(mxc_spi_regs_t *spi, bool use_dma_tx, bool use_dma_rx)
538 {
539 int8_t spi_num;
540 int tx_reqsel = -1;
541 int rx_reqsel = -1;
542
543 spi_num = MXC_SPI_GET_IDX(spi);
544 if (spi_num < 0 || spi_num >= MXC_SPI_INSTANCES) {
545 return E_INVALID;
546 }
547
548 if (use_dma_tx) {
549 switch (spi_num) {
550 case 0:
551 tx_reqsel = MXC_DMA_REQUEST_SPI0TX;
552 break;
553
554 case 1:
555 tx_reqsel = MXC_DMA_REQUEST_SPI1TX;
556 break;
557
558 // SPI2 does not exist in the MAX32572 (to match instance addressing with MAX32570B)
559
560 case 3:
561 tx_reqsel = MXC_DMA_REQUEST_SPI3TX;
562 break;
563
564 default:
565 return E_BAD_PARAM;
566 }
567 }
568
569 if (use_dma_rx) {
570 switch (spi_num) {
571 case 0:
572 rx_reqsel = MXC_DMA_REQUEST_SPI0RX;
573 break;
574
575 case 1:
576 rx_reqsel = MXC_DMA_REQUEST_SPI1RX;
577 break;
578
579 // SPI2 does not exist in the MAX32572 (to match instance addressing with MAX32570B)
580
581 case 3:
582 rx_reqsel = MXC_DMA_REQUEST_SPI3RX;
583 break;
584
585 default:
586 return E_BAD_PARAM;
587 }
588 }
589
590 return MXC_SPI_RevA2_DMA_SetRequestSelect((mxc_spi_reva_regs_t *)spi, tx_reqsel, rx_reqsel);
591 }
592
593 /* ** Transaction Functions ** */
594
MXC_SPI_MasterTransaction(mxc_spi_req_t * req)595 int MXC_SPI_MasterTransaction(mxc_spi_req_t *req)
596 {
597 return MXC_SPI_RevA2_ControllerTransaction((mxc_spi_reva_regs_t *)(req->spi), req->txData,
598 req->txLen, req->rxData, req->rxLen, req->ssDeassert,
599 req->ssIdx);
600 }
601
MXC_SPI_MasterTransactionAsync(mxc_spi_req_t * req)602 int MXC_SPI_MasterTransactionAsync(mxc_spi_req_t *req)
603 {
604 int error;
605
606 // Users can set their own callback and pass in their own data if they choose to.
607 if (req->completeCB != NULL) {
608 error = MXC_SPI_RevA2_SetCallback((mxc_spi_reva_regs_t *)(req->spi), req->completeCB, req);
609 if (error != E_NO_ERROR) {
610 return error;
611 }
612 }
613
614 return MXC_SPI_RevA2_ControllerTransactionAsync((mxc_spi_reva_regs_t *)(req->spi), req->txData,
615 req->txLen, req->rxData, req->rxLen,
616 req->ssDeassert, req->ssIdx);
617 }
618
MXC_SPI_MasterTransactionDMA(mxc_spi_req_t * req)619 int MXC_SPI_MasterTransactionDMA(mxc_spi_req_t *req)
620 {
621 int error;
622
623 // Users can set their own callback and pass in their own data if they choose to.
624 if (req->completeCB != NULL) {
625 error = MXC_SPI_RevA2_SetCallback((mxc_spi_reva_regs_t *)(req->spi), req->completeCB, req);
626 if (error != E_NO_ERROR) {
627 return error;
628 }
629 }
630
631 return MXC_SPI_RevA2_ControllerTransactionDMA((mxc_spi_reva_regs_t *)(req->spi), req->txData,
632 req->txLen, req->rxData, req->rxLen,
633 req->ssDeassert, req->ssIdx,
634 (mxc_dma_reva_regs_t *)MXC_DMA);
635 }
636
MXC_SPI_ControllerTransaction(mxc_spi_req_t * req)637 int MXC_SPI_ControllerTransaction(mxc_spi_req_t *req)
638 {
639 return MXC_SPI_RevA2_ControllerTransaction((mxc_spi_reva_regs_t *)(req->spi), req->txData,
640 req->txLen, req->rxData, req->rxLen, req->ssDeassert,
641 req->ssIdx);
642 }
643
MXC_SPI_ControllerTransactionAsync(mxc_spi_req_t * req)644 int MXC_SPI_ControllerTransactionAsync(mxc_spi_req_t *req)
645 {
646 int error;
647
648 // Users can set their own callback and pass in their own data if they choose to.
649 if (req->completeCB != NULL) {
650 error = MXC_SPI_RevA2_SetCallback((mxc_spi_reva_regs_t *)(req->spi), req->completeCB, req);
651 if (error != E_NO_ERROR) {
652 return error;
653 }
654 }
655
656 return MXC_SPI_RevA2_ControllerTransactionAsync((mxc_spi_reva_regs_t *)(req->spi), req->txData,
657 req->txLen, req->rxData, req->rxLen,
658 req->ssDeassert, req->ssIdx);
659 }
660
MXC_SPI_ControllerTransactionDMA(mxc_spi_req_t * req)661 int MXC_SPI_ControllerTransactionDMA(mxc_spi_req_t *req)
662 {
663 int error;
664
665 // Users can set their own callback and pass in their own data if they choose to.
666 if (req->completeCB != NULL) {
667 error = MXC_SPI_RevA2_SetCallback((mxc_spi_reva_regs_t *)(req->spi), req->completeCB, req);
668 if (error != E_NO_ERROR) {
669 return error;
670 }
671 }
672
673 return MXC_SPI_RevA2_ControllerTransactionDMA((mxc_spi_reva_regs_t *)(req->spi), req->txData,
674 req->txLen, req->rxData, req->rxLen,
675 req->ssDeassert, req->ssIdx,
676 (mxc_dma_reva_regs_t *)MXC_DMA);
677 }
678
MXC_SPI_SlaveTransaction(mxc_spi_req_t * req)679 int MXC_SPI_SlaveTransaction(mxc_spi_req_t *req)
680 {
681 return MXC_SPI_RevA2_TargetTransaction((mxc_spi_reva_regs_t *)(req->spi), req->txData,
682 req->txLen, req->rxData, req->rxLen);
683 }
684
MXC_SPI_SlaveTransactionAsync(mxc_spi_req_t * req)685 int MXC_SPI_SlaveTransactionAsync(mxc_spi_req_t *req)
686 {
687 int error;
688
689 // Users can set their own callback and pass in their own data if they choose to.
690 if (req->completeCB != NULL) {
691 error = MXC_SPI_RevA2_SetCallback((mxc_spi_reva_regs_t *)(req->spi), req->completeCB, req);
692 if (error != E_NO_ERROR) {
693 return error;
694 }
695 }
696
697 return MXC_SPI_RevA2_TargetTransactionAsync((mxc_spi_reva_regs_t *)(req->spi), req->txData,
698 req->txLen, req->rxData, req->rxLen);
699 }
700
MXC_SPI_SlaveTransactionDMA(mxc_spi_req_t * req)701 int MXC_SPI_SlaveTransactionDMA(mxc_spi_req_t *req)
702 {
703 int error;
704
705 // Users can set their own callback and pass in their own data if they choose to.
706 if (req->completeCB != NULL) {
707 error = MXC_SPI_RevA2_SetCallback((mxc_spi_reva_regs_t *)(req->spi), req->completeCB, req);
708 if (error != E_NO_ERROR) {
709 return error;
710 }
711 }
712
713 return MXC_SPI_RevA2_TargetTransactionDMA((mxc_spi_reva_regs_t *)(req->spi), req->txData,
714 req->txLen, req->rxData, req->rxLen,
715 (mxc_dma_reva_regs_t *)MXC_DMA);
716 }
717
MXC_SPI_TargetTransaction(mxc_spi_req_t * req)718 int MXC_SPI_TargetTransaction(mxc_spi_req_t *req)
719 {
720 return MXC_SPI_RevA2_TargetTransaction((mxc_spi_reva_regs_t *)(req->spi), req->txData,
721 req->txLen, req->rxData, req->rxLen);
722 }
723
MXC_SPI_TargetTransactionAsync(mxc_spi_req_t * req)724 int MXC_SPI_TargetTransactionAsync(mxc_spi_req_t *req)
725 {
726 int error;
727
728 error = MXC_SPI_RevA2_SetCallback((mxc_spi_reva_regs_t *)(req->spi), req->completeCB, req);
729 if (error != E_NO_ERROR) {
730 return error;
731 }
732
733 return MXC_SPI_RevA2_TargetTransactionAsync((mxc_spi_reva_regs_t *)(req->spi), req->txData,
734 req->txLen, req->rxData, req->rxLen);
735 }
736
MXC_SPI_TargetTransactionDMA(mxc_spi_req_t * req)737 int MXC_SPI_TargetTransactionDMA(mxc_spi_req_t *req)
738 {
739 int error;
740
741 error = MXC_SPI_RevA2_SetCallback((mxc_spi_reva_regs_t *)(req->spi), req->completeCB, req);
742 if (error != E_NO_ERROR) {
743 return error;
744 }
745
746 return MXC_SPI_RevA2_TargetTransactionDMA((mxc_spi_reva_regs_t *)(req->spi), req->txData,
747 req->txLen, req->rxData, req->rxLen,
748 (mxc_dma_reva_regs_t *)MXC_DMA);
749 }
750
751 /* ** Handler Functions ** */
752
MXC_SPI_AsyncHandler(mxc_spi_regs_t * spi)753 void MXC_SPI_AsyncHandler(mxc_spi_regs_t *spi)
754 {
755 MXC_SPI_RevA2_Handler((mxc_spi_reva_regs_t *)spi);
756 }
757
MXC_SPI_Handler(mxc_spi_regs_t * spi)758 void MXC_SPI_Handler(mxc_spi_regs_t *spi)
759 {
760 MXC_SPI_RevA2_Handler((mxc_spi_reva_regs_t *)spi);
761 }
762
MXC_SPI_DMA_TX_Handler(mxc_spi_regs_t * spi)763 void MXC_SPI_DMA_TX_Handler(mxc_spi_regs_t *spi)
764 {
765 MXC_SPI_RevA2_DMA_TX_Handler((mxc_spi_reva_regs_t *)spi);
766 }
767
MXC_SPI_DMA_RX_Handler(mxc_spi_regs_t * spi)768 void MXC_SPI_DMA_RX_Handler(mxc_spi_regs_t *spi)
769 {
770 MXC_SPI_RevA2_DMA_RX_Handler((mxc_spi_reva_regs_t *)spi);
771 }
772
773 /* ** Unsupported-Legacy Functions from Previous Implementation ** */
774
MXC_SPI_SetDataSize(mxc_spi_regs_t * spi,int dataSize)775 int MXC_SPI_SetDataSize(mxc_spi_regs_t *spi, int dataSize)
776 {
777 return MXC_SPI_RevA2_SetFrameSize((mxc_spi_reva_regs_t *)spi, dataSize);
778 }
779
MXC_SPI_GetDataSize(mxc_spi_regs_t * spi)780 int MXC_SPI_GetDataSize(mxc_spi_regs_t *spi)
781 {
782 return MXC_SPI_RevA2_GetFrameSize((mxc_spi_reva_regs_t *)spi);
783 }
784
MXC_SPI_SetWidth(mxc_spi_regs_t * spi,mxc_spi_width_t spiWidth)785 int MXC_SPI_SetWidth(mxc_spi_regs_t *spi, mxc_spi_width_t spiWidth)
786 {
787 switch (spiWidth) {
788 case SPI_WIDTH_3WIRE:
789 return MXC_SPI_SetInterface(spi, MXC_SPI_INTERFACE_3WIRE);
790
791 case SPI_WIDTH_STANDARD:
792 return MXC_SPI_SetInterface(spi, MXC_SPI_INTERFACE_STANDARD);
793
794 case SPI_WIDTH_DUAL:
795 return MXC_SPI_SetInterface(spi, MXC_SPI_INTERFACE_DUAL);
796 break;
797
798 case SPI_WIDTH_QUAD:
799 return MXC_SPI_SetInterface(spi, MXC_SPI_INTERFACE_QUAD);
800
801 default:
802 return E_BAD_PARAM;
803 }
804 }
805
MXC_SPI_GetWidth(mxc_spi_regs_t * spi)806 mxc_spi_width_t MXC_SPI_GetWidth(mxc_spi_regs_t *spi)
807 {
808 mxc_spi_interface_t if_mode;
809
810 if_mode = MXC_SPI_GetInterface(spi);
811
812 switch (if_mode) {
813 case MXC_SPI_INTERFACE_STANDARD:
814 return SPI_WIDTH_STANDARD;
815
816 case MXC_SPI_INTERFACE_QUAD:
817 return SPI_WIDTH_QUAD;
818
819 case MXC_SPI_INTERFACE_DUAL:
820 return SPI_WIDTH_DUAL;
821
822 case MXC_SPI_INTERFACE_3WIRE:
823 return SPI_WIDTH_3WIRE;
824
825 default:
826 return SPI_WIDTH_STANDARD;
827 }
828 }
829
MXC_SPI_AbortAsync(mxc_spi_regs_t * spi)830 void MXC_SPI_AbortAsync(mxc_spi_regs_t *spi)
831 {
832 MXC_SPI_AbortTransmission(spi);
833 }
834
MXC_SPI_SetSlave(mxc_spi_regs_t * spi,int ssIdx)835 int MXC_SPI_SetSlave(mxc_spi_regs_t *spi, int ssIdx)
836 {
837 return E_NOT_SUPPORTED;
838 }
839
MXC_SPI_GetSlave(mxc_spi_regs_t * spi)840 int MXC_SPI_GetSlave(mxc_spi_regs_t *spi)
841 {
842 return E_NOT_SUPPORTED;
843 }
844
MXC_SPI_SetMode(mxc_spi_regs_t * spi,mxc_spi_mode_t spiMode)845 int MXC_SPI_SetMode(mxc_spi_regs_t *spi, mxc_spi_mode_t spiMode)
846 {
847 switch (spiMode) {
848 case SPI_MODE_0:
849 return MXC_SPI_SetClkMode(spi, MXC_SPI_CLKMODE_0);
850
851 case SPI_MODE_1:
852 return MXC_SPI_SetClkMode(spi, MXC_SPI_CLKMODE_1);
853
854 case SPI_MODE_2:
855 return MXC_SPI_SetClkMode(spi, MXC_SPI_CLKMODE_2);
856
857 case SPI_MODE_3:
858 return MXC_SPI_SetClkMode(spi, MXC_SPI_CLKMODE_3);
859
860 default:
861 return E_BAD_PARAM;
862 }
863 }
864
MXC_SPI_GetMode(mxc_spi_regs_t * spi)865 mxc_spi_mode_t MXC_SPI_GetMode(mxc_spi_regs_t *spi)
866 {
867 mxc_spi_clkmode_t clk_mode;
868
869 clk_mode = MXC_SPI_GetClkMode(spi);
870
871 switch (clk_mode) {
872 case MXC_SPI_CLKMODE_0:
873 return SPI_MODE_0;
874
875 case MXC_SPI_CLKMODE_1:
876 return SPI_MODE_1;
877
878 case MXC_SPI_CLKMODE_2:
879 return SPI_MODE_2;
880
881 case MXC_SPI_CLKMODE_3:
882 return SPI_MODE_3;
883
884 default:
885 return SPI_MODE_0;
886 }
887 }
888
MXC_SPI_SetDefaultTXData(mxc_spi_regs_t * spi,unsigned int defaultTXData)889 int MXC_SPI_SetDefaultTXData(mxc_spi_regs_t *spi, unsigned int defaultTXData)
890 {
891 return MXC_SPI_RevA2_SetDummyTX((mxc_spi_reva_regs_t *)spi, defaultTXData);
892 }
893