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_errors.h"
29 #include "mxc_lock.h"
30 #include "mxc_sys.h"
31 #include "mxc_delay.h"
32 #include "spi_reva2.h"
33 #include "spi.h"
34 #include "dma.h"
35 #include "gpio.h"
36 
37 /* **** Definitions **** */
38 
39 /* ************************************************************************** */
40 
41 // Max 3 Possible Target Select Options per SPI instance
42 #define MXC_SPI_TS0_MASK_POS (0)
43 #define MXC_SPI_TS1_MASK_POS (1)
44 #define MXC_SPI_TS2_MASK_POS (2)
45 
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)46 int MXC_SPI_Init(mxc_spi_regs_t *spi, mxc_spi_type_t controller_target, mxc_spi_interface_t if_mode,
47                  int numTargets, uint8_t ts_active_pol_mask, uint32_t freq, mxc_spi_pins_t pins)
48 {
49     int error;
50     int8_t spi_num;
51     mxc_spi_tscontrol_t ts_control;
52     mxc_gpio_cfg_t temp_cfg; // main SPI pins.
53     mxc_gpio_cfg_t temp_ts_cfg; // TS pins.
54     mxc_gpio_vssel_t vssel;
55 
56     spi_num = MXC_SPI_GET_IDX(spi);
57     if (spi_num < 0 || spi_num >= MXC_SPI_INSTANCES) {
58         return E_BAD_PARAM;
59     }
60 
61     // Check if frequency is too high
62     if ((spi_num == 0) && (freq > MXC_SPI_GetPeripheralClock(spi))) {
63         return E_BAD_PARAM;
64     }
65 
66     if ((spi_num == 1) && (freq > SystemCoreClock)) {
67         return E_BAD_PARAM;
68     }
69 
70     if (pins.vddioh) {
71         vssel = MXC_GPIO_VSSEL_VDDIOH;
72     } else {
73         vssel = MXC_GPIO_VSSEL_VDDIO;
74     }
75 
76     // SPI Target mode only supports HW_AUTO.
77     if (pins.ss0 || pins.ss1 || pins.ss2 || (controller_target == MXC_SPI_TYPE_TARGET)) {
78         ts_control = MXC_SPI_TSCONTROL_HW_AUTO;
79     } else {
80         ts_control = MXC_SPI_TSCONTROL_SW_APP;
81     }
82 
83     error = MXC_SPI_RevA2_SetTSControl((mxc_spi_reva_regs_t *)spi, ts_control);
84     if (error != E_NO_ERROR) {
85         return error;
86     }
87 
88     // Configure SPI peripheral and pins.
89     if (spi == MXC_SPI1) {
90         MXC_SYS_Reset_Periph(MXC_SYS_RESET0_SPI1);
91         MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_SPI1);
92 
93         switch (if_mode) {
94         case MXC_SPI_INTERFACE_STANDARD:
95             temp_cfg = gpio_cfg_spi1_standard;
96             break;
97 
98         case MXC_SPI_INTERFACE_QUAD:
99             temp_cfg = gpio_cfg_spi1_quad;
100             break;
101 
102         case MXC_SPI_INTERFACE_3WIRE:
103             temp_cfg = gpio_cfg_spi1_3wire;
104             break;
105 
106         case MXC_SPI_INTERFACE_DUAL:
107             temp_cfg = gpio_cfg_spi1_dual;
108             break;
109 
110         default:
111             return E_BAD_PARAM;
112         }
113 
114         // Set up HW TS pins (if HW_AUTO TS control scheme was selected).
115         // Voltage and drive strength settings will match the SPI pins.
116         if (ts_control == MXC_SPI_TSCONTROL_HW_AUTO) {
117             // Target Select 0 - TS0 (L. SS0 pin)
118             if (pins.ss0 == true) {
119                 temp_ts_cfg = gpio_cfg_spi1_ts0;
120                 temp_ts_cfg.vssel = vssel;
121                 temp_ts_cfg.drvstr = pins.drvstr;
122 
123                 error = MXC_GPIO_Config(&temp_ts_cfg);
124                 if (error != E_NO_ERROR) {
125                     return error;
126                 }
127             }
128         }
129 
130 // Handle RISCV SPI instance numbering.
131 #ifdef MXC_SPI0
132     } else if (spi == MXC_SPI0) {
133         MXC_SYS_Reset_Periph(MXC_SYS_RESET1_SPI0);
134         MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_SPI0);
135 
136         switch (if_mode) {
137         case MXC_SPI_INTERFACE_STANDARD:
138             temp_cfg = gpio_cfg_spi0_standard;
139             break;
140 
141         case MXC_SPI_INTERFACE_QUAD:
142             temp_cfg = gpio_cfg_spi0_quad;
143             break;
144 
145         case MXC_SPI_INTERFACE_3WIRE:
146             temp_cfg = gpio_cfg_spi0_3wire;
147             break;
148 
149         case MXC_SPI_INTERFACE_DUAL:
150             temp_cfg = gpio_cfg_spi0_dual;
151             break;
152 
153         default:
154             return E_BAD_PARAM;
155         }
156 
157         // Set up HW TS pins (if HW_AUTO TS control scheme was selected).
158         // Voltage and drive strength settings will match the SPI pins.
159         if (ts_control == MXC_SPI_TSCONTROL_HW_AUTO) {
160             // Target Select 0 - TS0 (L. SS0 pin)
161             if (pins.ss0 == true) {
162                 temp_ts_cfg = gpio_cfg_spi0_ts0;
163                 temp_ts_cfg.vssel = vssel;
164                 temp_ts_cfg.drvstr = pins.drvstr;
165 
166                 error = MXC_GPIO_Config(&temp_ts_cfg);
167                 if (error != E_NO_ERROR) {
168                     return error;
169                 }
170             }
171 
172             // Target Select 1 - TS1 (L. SS1 pin)
173             if (pins.ss1 == true) {
174                 temp_ts_cfg = gpio_cfg_spi0_ts1;
175                 temp_ts_cfg.vssel = vssel;
176                 temp_ts_cfg.drvstr = pins.drvstr;
177 
178                 error = MXC_GPIO_Config(&temp_ts_cfg);
179                 if (error != E_NO_ERROR) {
180                     return error;
181                 }
182             }
183 
184             // Target Select 2 - TS2 (L. SS2 pin)
185             if (pins.ss2 == true) {
186                 temp_ts_cfg = gpio_cfg_spi0_ts2;
187                 temp_ts_cfg.vssel = vssel;
188                 temp_ts_cfg.drvstr = pins.drvstr;
189 
190                 error = MXC_GPIO_Config(&temp_ts_cfg);
191                 if (error != E_NO_ERROR) {
192                     return error;
193                 }
194             }
195         }
196 #endif
197 
198     } else {
199         return E_NO_DEVICE;
200     }
201 
202     temp_cfg.vssel = vssel;
203     temp_cfg.drvstr = pins.drvstr;
204 
205     // Configure main SPI pins.
206     error = MXC_GPIO_Config(&temp_cfg);
207     if (error != E_NO_ERROR) {
208         return error;
209     }
210 
211     return MXC_SPI_RevA2_Init((mxc_spi_reva_regs_t *)spi, controller_target, if_mode, freq,
212                               ts_active_pol_mask);
213 }
214 
MXC_SPI_Config(mxc_spi_cfg_t * cfg)215 int MXC_SPI_Config(mxc_spi_cfg_t *cfg)
216 {
217     return MXC_SPI_RevA2_Config(cfg);
218 }
219 
MXC_SPI_ConfigStruct(mxc_spi_cfg_t * cfg,bool use_dma_tx,bool use_dma_rx)220 int MXC_SPI_ConfigStruct(mxc_spi_cfg_t *cfg, bool use_dma_tx, bool use_dma_rx)
221 {
222     if (cfg == NULL) {
223         return E_BAD_PARAM;
224     }
225 
226     cfg->spi = MXC_SPI1; // SPI1 is available on both the ARM and RISCV core.
227     cfg->clk_mode = MXC_SPI_CLKMODE_0; // 0 - CPOL :: 0 - CPHA
228 
229     if (use_dma_tx || use_dma_rx) {
230         cfg->use_dma_tx = use_dma_tx;
231         cfg->use_dma_rx = use_dma_rx;
232         cfg->dma = MXC_DMA;
233     } else {
234         cfg->use_dma_tx = false;
235         cfg->use_dma_rx = false;
236         cfg->dma = NULL;
237     }
238 
239     return E_SUCCESS;
240 }
241 
MXC_SPI_Shutdown(mxc_spi_regs_t * spi)242 int MXC_SPI_Shutdown(mxc_spi_regs_t *spi)
243 {
244     int8_t spi_num;
245 
246     spi_num = MXC_SPI_GET_IDX(spi);
247     if (spi_num < 0 || spi_num >= MXC_SPI_INSTANCES) {
248         return E_BAD_PARAM;
249     }
250 
251     MXC_SPI_RevA2_Shutdown((mxc_spi_reva_regs_t *)spi);
252 
253     if (spi == MXC_SPI1) {
254         MXC_SYS_ClockDisable(MXC_SYS_PERIPH_CLOCK_SPI1);
255 #ifdef MXC_SPI0
256     } else if (spi == MXC_SPI0) {
257         MXC_SYS_ClockDisable(MXC_SYS_PERIPH_CLOCK_SPI0);
258 #endif
259     } else {
260         return E_NO_DEVICE;
261     }
262 
263     return E_NO_ERROR;
264 }
265 
MXC_SPI_GetFlags(mxc_spi_regs_t * spi)266 unsigned int MXC_SPI_GetFlags(mxc_spi_regs_t *spi)
267 {
268     return (unsigned int)MXC_SPI_RevA2_GetFlags((mxc_spi_reva_regs_t *)spi);
269 }
270 
MXC_SPI_ClearFlags(mxc_spi_regs_t * spi)271 void MXC_SPI_ClearFlags(mxc_spi_regs_t *spi)
272 {
273     MXC_SPI_RevA2_ClearFlags((mxc_spi_reva_regs_t *)spi);
274 }
275 
MXC_SPI_EnableInt(mxc_spi_regs_t * spi,unsigned int intEn)276 void MXC_SPI_EnableInt(mxc_spi_regs_t *spi, unsigned int intEn)
277 {
278     MXC_SPI_RevA2_EnableInt((mxc_spi_reva_regs_t *)spi, (uint32_t)intEn);
279 }
280 
MXC_SPI_DisableInt(mxc_spi_regs_t * spi,unsigned int intDis)281 void MXC_SPI_DisableInt(mxc_spi_regs_t *spi, unsigned int intDis)
282 {
283     MXC_SPI_RevA2_DisableInt((mxc_spi_reva_regs_t *)spi, (uint32_t)intDis);
284 }
285 
MXC_SPI_GetPeripheralClock(mxc_spi_regs_t * spi)286 int MXC_SPI_GetPeripheralClock(mxc_spi_regs_t *spi)
287 {
288     int retval;
289 
290     if (spi == MXC_SPI1) {
291         retval = PeripheralClock;
292 #ifdef MXC_SPI0 // SPI0 is not accessible from the RISC core.
293     } else if (spi == MXC_SPI0) {
294         int sys_clk = (MXC_GCR->clkctrl & MXC_F_GCR_CLKCTRL_SYSCLK_SEL) >>
295                       MXC_F_GCR_CLKCTRL_SYSCLK_SEL_POS;
296         switch (sys_clk) {
297         case MXC_SYS_CLOCK_IPO:
298             retval = IPO_FREQ;
299             break;
300         case MXC_SYS_CLOCK_IBRO:
301             retval = IBRO_FREQ;
302             break;
303         case MXC_SYS_CLOCK_ISO:
304             retval = ISO_FREQ;
305             break;
306         case MXC_SYS_CLOCK_INRO:
307             retval = INRO_FREQ;
308             break;
309         case MXC_SYS_CLOCK_ERTCO:
310             retval = ERTCO_FREQ;
311             break;
312         case MXC_SYS_CLOCK_EXTCLK:
313             retval = EXTCLK_FREQ;
314             break;
315         default:
316             return E_BAD_STATE;
317         }
318 #endif // MXC_SPI0
319     } else {
320         return E_BAD_PARAM;
321     }
322 
323     retval /= 2;
324 
325     return retval;
326 }
327 
MXC_SPI_SetTSControl(mxc_spi_regs_t * spi,mxc_spi_tscontrol_t ts_control)328 int MXC_SPI_SetTSControl(mxc_spi_regs_t *spi, mxc_spi_tscontrol_t ts_control)
329 {
330     return MXC_SPI_RevA2_SetTSControl((mxc_spi_reva_regs_t *)spi, ts_control);
331 }
332 
MXC_SPI_GetTSControl(mxc_spi_regs_t * spi)333 mxc_spi_tscontrol_t MXC_SPI_GetTSControl(mxc_spi_regs_t *spi)
334 {
335     return MXC_SPI_RevA2_GetTSControl((mxc_spi_reva_regs_t *)spi);
336 }
337 
MXC_SPI_SetFrequency(mxc_spi_regs_t * spi,unsigned int hz)338 int MXC_SPI_SetFrequency(mxc_spi_regs_t *spi, unsigned int hz)
339 {
340     return MXC_SPI_RevA2_SetFrequency((mxc_spi_reva_regs_t *)spi, hz);
341 }
342 
MXC_SPI_GetFrequency(mxc_spi_regs_t * spi)343 unsigned int MXC_SPI_GetFrequency(mxc_spi_regs_t *spi)
344 {
345     return MXC_SPI_RevA2_GetFrequency((mxc_spi_reva_regs_t *)spi);
346 }
347 
MXC_SPI_SetFrameSize(mxc_spi_regs_t * spi,int frame_size)348 int MXC_SPI_SetFrameSize(mxc_spi_regs_t *spi, int frame_size)
349 {
350     return MXC_SPI_RevA2_SetFrameSize((mxc_spi_reva_regs_t *)spi, frame_size);
351 }
352 
MXC_SPI_GetFrameSize(mxc_spi_regs_t * spi)353 int MXC_SPI_GetFrameSize(mxc_spi_regs_t *spi)
354 {
355     return MXC_SPI_RevA2_GetFrameSize((mxc_spi_reva_regs_t *)spi);
356 }
357 
MXC_SPI_SetInterface(mxc_spi_regs_t * spi,mxc_spi_interface_t mode)358 int MXC_SPI_SetInterface(mxc_spi_regs_t *spi, mxc_spi_interface_t mode)
359 {
360     return MXC_SPI_RevA2_SetInterface((mxc_spi_reva_regs_t *)spi, mode);
361 }
362 
MXC_SPI_GetInterface(mxc_spi_regs_t * spi)363 mxc_spi_interface_t MXC_SPI_GetInterface(mxc_spi_regs_t *spi)
364 {
365     return MXC_SPI_RevA2_GetInterface((mxc_spi_reva_regs_t *)spi);
366 }
367 
MXC_SPI_SetClkMode(mxc_spi_regs_t * spi,mxc_spi_clkmode_t clk_mode)368 int MXC_SPI_SetClkMode(mxc_spi_regs_t *spi, mxc_spi_clkmode_t clk_mode)
369 {
370     return MXC_SPI_RevA2_SetClkMode((mxc_spi_reva_regs_t *)spi, clk_mode);
371 }
372 
MXC_SPI_GetClkMode(mxc_spi_regs_t * spi)373 mxc_spi_clkmode_t MXC_SPI_GetClkMode(mxc_spi_regs_t *spi)
374 {
375     return MXC_SPI_RevA2_GetClkMode((mxc_spi_reva_regs_t *)spi);
376 }
377 
MXC_SPI_SetCallback(mxc_spi_regs_t * spi,mxc_spi_callback_t completeCB,void * data)378 int MXC_SPI_SetCallback(mxc_spi_regs_t *spi, mxc_spi_callback_t completeCB, void *data)
379 {
380     return MXC_SPI_RevA2_SetCallback((mxc_spi_reva_regs_t *)spi, completeCB, data);
381 }
382 
MXC_SPI_GetActive(mxc_spi_regs_t * spi)383 int MXC_SPI_GetActive(mxc_spi_regs_t *spi)
384 {
385     return MXC_SPI_RevA2_GetActive((mxc_spi_reva_regs_t *)spi);
386 }
387 
MXC_SPI_ReadyForSleep(mxc_spi_regs_t * spi)388 int MXC_SPI_ReadyForSleep(mxc_spi_regs_t *spi)
389 {
390     return MXC_SPI_RevA2_ReadyForSleep((mxc_spi_reva_regs_t *)spi);
391 }
392 
MXC_SPI_SetDummyTX(mxc_spi_regs_t * spi,uint16_t tx_value)393 int MXC_SPI_SetDummyTX(mxc_spi_regs_t *spi, uint16_t tx_value)
394 {
395     return MXC_SPI_RevA2_SetDummyTX((mxc_spi_reva_regs_t *)spi, tx_value);
396 }
397 
MXC_SPI_StartTransmission(mxc_spi_regs_t * spi)398 int MXC_SPI_StartTransmission(mxc_spi_regs_t *spi)
399 {
400     return MXC_SPI_RevA2_StartTransmission((mxc_spi_reva_regs_t *)spi);
401 }
402 
MXC_SPI_AbortTransmission(mxc_spi_regs_t * spi)403 int MXC_SPI_AbortTransmission(mxc_spi_regs_t *spi)
404 {
405     return MXC_SPI_RevA2_AbortTransmission((mxc_spi_reva_regs_t *)spi);
406 }
407 
MXC_SPI_GetTXFIFOAvailable(mxc_spi_regs_t * spi)408 unsigned int MXC_SPI_GetTXFIFOAvailable(mxc_spi_regs_t *spi)
409 {
410     return MXC_SPI_RevA2_GetTXFIFOAvailable((mxc_spi_reva_regs_t *)spi);
411 }
412 
MXC_SPI_GetRXFIFOAvailable(mxc_spi_regs_t * spi)413 unsigned int MXC_SPI_GetRXFIFOAvailable(mxc_spi_regs_t *spi)
414 {
415     return MXC_SPI_RevA2_GetRXFIFOAvailable((mxc_spi_reva_regs_t *)spi);
416 }
417 
MXC_SPI_ClearTXFIFO(mxc_spi_regs_t * spi)418 void MXC_SPI_ClearTXFIFO(mxc_spi_regs_t *spi)
419 {
420     MXC_SPI_RevA2_ClearTXFIFO((mxc_spi_reva_regs_t *)spi);
421 }
422 
MXC_SPI_ClearRXFIFO(mxc_spi_regs_t * spi)423 void MXC_SPI_ClearRXFIFO(mxc_spi_regs_t *spi)
424 {
425     MXC_SPI_RevA2_ClearRXFIFO((mxc_spi_reva_regs_t *)spi);
426 }
427 
MXC_SPI_SetTXThreshold(mxc_spi_regs_t * spi,unsigned int numBytes)428 int MXC_SPI_SetTXThreshold(mxc_spi_regs_t *spi, unsigned int numBytes)
429 {
430     return (int)MXC_SPI_RevA2_SetTXThreshold((mxc_spi_reva_regs_t *)spi, numBytes);
431 }
432 
MXC_SPI_SetRXThreshold(mxc_spi_regs_t * spi,unsigned int numBytes)433 int MXC_SPI_SetRXThreshold(mxc_spi_regs_t *spi, unsigned int numBytes)
434 {
435     return (int)MXC_SPI_RevA2_SetRXThreshold((mxc_spi_reva_regs_t *)spi, numBytes);
436 }
437 
MXC_SPI_GetTXThreshold(mxc_spi_regs_t * spi)438 unsigned int MXC_SPI_GetTXThreshold(mxc_spi_regs_t *spi)
439 {
440     return (unsigned int)MXC_SPI_RevA2_GetTXThreshold((mxc_spi_reva_regs_t *)spi);
441 }
442 
MXC_SPI_GetRXThreshold(mxc_spi_regs_t * spi)443 unsigned int MXC_SPI_GetRXThreshold(mxc_spi_regs_t *spi)
444 {
445     return (unsigned int)MXC_SPI_RevA2_GetRXThreshold((mxc_spi_reva_regs_t *)spi);
446 }
447 
448 /* ** DMA-Specific Functions ** */
449 
MXC_SPI_DMA_Init(mxc_spi_regs_t * spi,mxc_dma_regs_t * dma,bool use_dma_tx,bool use_dma_rx)450 int MXC_SPI_DMA_Init(mxc_spi_regs_t *spi, mxc_dma_regs_t *dma, bool use_dma_tx, bool use_dma_rx)
451 {
452     return MXC_SPI_RevA2_DMA_Init((mxc_spi_reva_regs_t *)spi, (mxc_dma_reva_regs_t *)dma,
453                                   use_dma_tx, use_dma_rx);
454 }
455 
MXC_SPI_DMA_GetInitialized(mxc_spi_regs_t * spi)456 bool MXC_SPI_DMA_GetInitialized(mxc_spi_regs_t *spi)
457 {
458     return MXC_SPI_RevA2_DMA_GetInitialized((mxc_spi_reva_regs_t *)spi);
459 }
460 
MXC_SPI_DMA_GetTXChannel(mxc_spi_regs_t * spi)461 int MXC_SPI_DMA_GetTXChannel(mxc_spi_regs_t *spi)
462 {
463     return MXC_SPI_RevA2_DMA_GetTXChannel((mxc_spi_reva_regs_t *)spi);
464 }
465 
MXC_SPI_DMA_GetRXChannel(mxc_spi_regs_t * spi)466 int MXC_SPI_DMA_GetRXChannel(mxc_spi_regs_t *spi)
467 {
468     return MXC_SPI_RevA2_DMA_GetRXChannel((mxc_spi_reva_regs_t *)spi);
469 }
470 
MXC_SPI_DMA_SetRequestSelect(mxc_spi_regs_t * spi,bool use_dma_tx,bool use_dma_rx)471 int MXC_SPI_DMA_SetRequestSelect(mxc_spi_regs_t *spi, bool use_dma_tx, bool use_dma_rx)
472 {
473     int8_t spi_num;
474     int tx_reqsel = -1;
475     int rx_reqsel = -1;
476 
477     spi_num = MXC_SPI_GET_IDX(spi);
478     if (spi_num < 0 || spi_num >= MXC_SPI_INSTANCES) {
479         return E_INVALID;
480     }
481 
482     if (use_dma_tx) {
483         switch (spi_num) {
484         case 0:
485             tx_reqsel = MXC_DMA_REQUEST_SPI1TX;
486             break;
487 
488         case 1:
489             tx_reqsel = MXC_DMA_REQUEST_SPI0TX;
490             break;
491 
492         default:
493             return E_BAD_PARAM;
494         }
495     }
496 
497     if (use_dma_rx) {
498         switch (spi_num) {
499         case 0:
500             rx_reqsel = MXC_DMA_REQUEST_SPI1RX;
501             break;
502 
503         case 1:
504             rx_reqsel = MXC_DMA_REQUEST_SPI0RX;
505             break;
506 
507         default:
508             return E_BAD_PARAM;
509         }
510     }
511 
512     return MXC_SPI_RevA2_DMA_SetRequestSelect((mxc_spi_reva_regs_t *)spi, tx_reqsel, rx_reqsel);
513 }
514 
515 /* ** Transaction Functions ** */
516 
MXC_SPI_MasterTransaction(mxc_spi_req_t * req)517 int MXC_SPI_MasterTransaction(mxc_spi_req_t *req)
518 {
519     return MXC_SPI_RevA2_ControllerTransaction((mxc_spi_reva_regs_t *)(req->spi), req->txData,
520                                                req->txLen, req->rxData, req->rxLen, req->ssDeassert,
521                                                req->ssIdx);
522 }
523 
MXC_SPI_MasterTransactionAsync(mxc_spi_req_t * req)524 int MXC_SPI_MasterTransactionAsync(mxc_spi_req_t *req)
525 {
526     int error;
527 
528     // Users can set their own callback and pass in their own data if they choose to.
529     if (req->completeCB != NULL) {
530         error = MXC_SPI_RevA2_SetCallback((mxc_spi_reva_regs_t *)(req->spi), req->completeCB, req);
531         if (error != E_NO_ERROR) {
532             return error;
533         }
534     }
535 
536     return MXC_SPI_RevA2_ControllerTransactionAsync((mxc_spi_reva_regs_t *)(req->spi), req->txData,
537                                                     req->txLen, req->rxData, req->rxLen,
538                                                     req->ssDeassert, req->ssIdx);
539 }
540 
MXC_SPI_MasterTransactionDMA(mxc_spi_req_t * req)541 int MXC_SPI_MasterTransactionDMA(mxc_spi_req_t *req)
542 {
543     int error;
544 
545     // Users can set their own callback and pass in their own data if they choose to.
546     if (req->completeCB != NULL) {
547         error = MXC_SPI_RevA2_SetCallback((mxc_spi_reva_regs_t *)(req->spi), req->completeCB, req);
548         if (error != E_NO_ERROR) {
549             return error;
550         }
551     }
552 
553     return MXC_SPI_RevA2_ControllerTransactionDMA((mxc_spi_reva_regs_t *)(req->spi), req->txData,
554                                                   req->txLen, req->rxData, req->rxLen,
555                                                   req->ssDeassert, req->ssIdx,
556                                                   (mxc_dma_reva_regs_t *)MXC_DMA);
557 }
558 
MXC_SPI_ControllerTransaction(mxc_spi_req_t * req)559 int MXC_SPI_ControllerTransaction(mxc_spi_req_t *req)
560 {
561     return MXC_SPI_RevA2_ControllerTransaction((mxc_spi_reva_regs_t *)(req->spi), req->txData,
562                                                req->txLen, req->rxData, req->rxLen, req->ssDeassert,
563                                                req->ssIdx);
564 }
565 
MXC_SPI_ControllerTransactionAsync(mxc_spi_req_t * req)566 int MXC_SPI_ControllerTransactionAsync(mxc_spi_req_t *req)
567 {
568     int error;
569 
570     // Users can set their own callback and pass in their own data if they choose to.
571     if (req->completeCB != NULL) {
572         error = MXC_SPI_RevA2_SetCallback((mxc_spi_reva_regs_t *)(req->spi), req->completeCB, req);
573         if (error != E_NO_ERROR) {
574             return error;
575         }
576     }
577 
578     return MXC_SPI_RevA2_ControllerTransactionAsync((mxc_spi_reva_regs_t *)(req->spi), req->txData,
579                                                     req->txLen, req->rxData, req->rxLen,
580                                                     req->ssDeassert, req->ssIdx);
581 }
582 
MXC_SPI_ControllerTransactionDMA(mxc_spi_req_t * req)583 int MXC_SPI_ControllerTransactionDMA(mxc_spi_req_t *req)
584 {
585     int error;
586 
587     // Users can set their own callback and pass in their own data if they choose to.
588     if (req->completeCB != NULL) {
589         error = MXC_SPI_RevA2_SetCallback((mxc_spi_reva_regs_t *)(req->spi), req->completeCB, req);
590         if (error != E_NO_ERROR) {
591             return error;
592         }
593     }
594 
595     return MXC_SPI_RevA2_ControllerTransactionDMA((mxc_spi_reva_regs_t *)(req->spi), req->txData,
596                                                   req->txLen, req->rxData, req->rxLen,
597                                                   req->ssDeassert, req->ssIdx,
598                                                   (mxc_dma_reva_regs_t *)MXC_DMA);
599 }
600 
MXC_SPI_SlaveTransaction(mxc_spi_req_t * req)601 int MXC_SPI_SlaveTransaction(mxc_spi_req_t *req)
602 {
603     return MXC_SPI_RevA2_TargetTransaction((mxc_spi_reva_regs_t *)(req->spi), req->txData,
604                                            req->txLen, req->rxData, req->rxLen);
605 }
606 
MXC_SPI_SlaveTransactionAsync(mxc_spi_req_t * req)607 int MXC_SPI_SlaveTransactionAsync(mxc_spi_req_t *req)
608 {
609     int error;
610 
611     // Users can set their own callback and pass in their own data if they choose to.
612     if (req->completeCB != NULL) {
613         error = MXC_SPI_RevA2_SetCallback((mxc_spi_reva_regs_t *)(req->spi), req->completeCB, req);
614         if (error != E_NO_ERROR) {
615             return error;
616         }
617     }
618 
619     return MXC_SPI_RevA2_TargetTransactionAsync((mxc_spi_reva_regs_t *)(req->spi), req->txData,
620                                                 req->txLen, req->rxData, req->rxLen);
621 }
622 
MXC_SPI_SlaveTransactionDMA(mxc_spi_req_t * req)623 int MXC_SPI_SlaveTransactionDMA(mxc_spi_req_t *req)
624 {
625     int error;
626 
627     // Users can set their own callback and pass in their own data if they choose to.
628     if (req->completeCB != NULL) {
629         error = MXC_SPI_RevA2_SetCallback((mxc_spi_reva_regs_t *)(req->spi), req->completeCB, req);
630         if (error != E_NO_ERROR) {
631             return error;
632         }
633     }
634 
635     return MXC_SPI_RevA2_TargetTransactionDMA((mxc_spi_reva_regs_t *)(req->spi), req->txData,
636                                               req->txLen, req->rxData, req->rxLen,
637                                               (mxc_dma_reva_regs_t *)MXC_DMA);
638 }
639 
MXC_SPI_TargetTransaction(mxc_spi_req_t * req)640 int MXC_SPI_TargetTransaction(mxc_spi_req_t *req)
641 {
642     return MXC_SPI_RevA2_TargetTransaction((mxc_spi_reva_regs_t *)(req->spi), req->txData,
643                                            req->txLen, req->rxData, req->rxLen);
644 }
645 
MXC_SPI_TargetTransactionAsync(mxc_spi_req_t * req)646 int MXC_SPI_TargetTransactionAsync(mxc_spi_req_t *req)
647 {
648     int error;
649 
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     return MXC_SPI_RevA2_TargetTransactionAsync((mxc_spi_reva_regs_t *)(req->spi), req->txData,
656                                                 req->txLen, req->rxData, req->rxLen);
657 }
658 
MXC_SPI_TargetTransactionDMA(mxc_spi_req_t * req)659 int MXC_SPI_TargetTransactionDMA(mxc_spi_req_t *req)
660 {
661     int error;
662 
663     error = MXC_SPI_RevA2_SetCallback((mxc_spi_reva_regs_t *)(req->spi), req->completeCB, req);
664     if (error != E_NO_ERROR) {
665         return error;
666     }
667 
668     return MXC_SPI_RevA2_TargetTransactionDMA((mxc_spi_reva_regs_t *)(req->spi), req->txData,
669                                               req->txLen, req->rxData, req->rxLen,
670                                               (mxc_dma_reva_regs_t *)MXC_DMA);
671 }
672 
673 /* ** Handler Functions ** */
674 
MXC_SPI_AsyncHandler(mxc_spi_regs_t * spi)675 void MXC_SPI_AsyncHandler(mxc_spi_regs_t *spi)
676 {
677     MXC_SPI_RevA2_Handler((mxc_spi_reva_regs_t *)spi);
678 }
679 
MXC_SPI_Handler(mxc_spi_regs_t * spi)680 void MXC_SPI_Handler(mxc_spi_regs_t *spi)
681 {
682     MXC_SPI_RevA2_Handler((mxc_spi_reva_regs_t *)spi);
683 }
684 
MXC_SPI_DMA_TX_Handler(mxc_spi_regs_t * spi)685 void MXC_SPI_DMA_TX_Handler(mxc_spi_regs_t *spi)
686 {
687     MXC_SPI_RevA2_DMA_TX_Handler((mxc_spi_reva_regs_t *)spi);
688 }
689 
MXC_SPI_DMA_RX_Handler(mxc_spi_regs_t * spi)690 void MXC_SPI_DMA_RX_Handler(mxc_spi_regs_t *spi)
691 {
692     MXC_SPI_RevA2_DMA_RX_Handler((mxc_spi_reva_regs_t *)spi);
693 }
694 
695 /* ** Unsupported-Legacy Functions from Previous Implementation ** */
696 
MXC_SPI_SetDataSize(mxc_spi_regs_t * spi,int dataSize)697 int MXC_SPI_SetDataSize(mxc_spi_regs_t *spi, int dataSize)
698 {
699     return MXC_SPI_RevA2_SetFrameSize((mxc_spi_reva_regs_t *)spi, dataSize);
700 }
701 
MXC_SPI_GetDataSize(mxc_spi_regs_t * spi)702 int MXC_SPI_GetDataSize(mxc_spi_regs_t *spi)
703 {
704     return MXC_SPI_RevA2_GetFrameSize((mxc_spi_reva_regs_t *)spi);
705 }
706 
MXC_SPI_SetWidth(mxc_spi_regs_t * spi,mxc_spi_width_t spiWidth)707 int MXC_SPI_SetWidth(mxc_spi_regs_t *spi, mxc_spi_width_t spiWidth)
708 {
709     switch (spiWidth) {
710     case SPI_WIDTH_3WIRE:
711         return MXC_SPI_SetInterface(spi, MXC_SPI_INTERFACE_3WIRE);
712 
713     case SPI_WIDTH_STANDARD:
714         return MXC_SPI_SetInterface(spi, MXC_SPI_INTERFACE_STANDARD);
715 
716     case SPI_WIDTH_DUAL:
717         return MXC_SPI_SetInterface(spi, MXC_SPI_INTERFACE_DUAL);
718         break;
719 
720     case SPI_WIDTH_QUAD:
721         return MXC_SPI_SetInterface(spi, MXC_SPI_INTERFACE_QUAD);
722 
723     default:
724         return E_BAD_PARAM;
725     }
726 }
727 
MXC_SPI_GetWidth(mxc_spi_regs_t * spi)728 mxc_spi_width_t MXC_SPI_GetWidth(mxc_spi_regs_t *spi)
729 {
730     mxc_spi_interface_t if_mode;
731 
732     if_mode = MXC_SPI_GetInterface(spi);
733 
734     switch (if_mode) {
735     case MXC_SPI_INTERFACE_STANDARD:
736         return SPI_WIDTH_STANDARD;
737 
738     case MXC_SPI_INTERFACE_QUAD:
739         return SPI_WIDTH_QUAD;
740 
741     case MXC_SPI_INTERFACE_DUAL:
742         return SPI_WIDTH_DUAL;
743 
744     case MXC_SPI_INTERFACE_3WIRE:
745         return SPI_WIDTH_3WIRE;
746 
747     default:
748         return SPI_WIDTH_STANDARD;
749     }
750 }
751 
MXC_SPI_AbortAsync(mxc_spi_regs_t * spi)752 void MXC_SPI_AbortAsync(mxc_spi_regs_t *spi)
753 {
754     MXC_SPI_AbortTransmission(spi);
755 }
756 
MXC_SPI_SetSlave(mxc_spi_regs_t * spi,int ssIdx)757 int MXC_SPI_SetSlave(mxc_spi_regs_t *spi, int ssIdx)
758 {
759     return E_NOT_SUPPORTED;
760 }
761 
MXC_SPI_GetSlave(mxc_spi_regs_t * spi)762 int MXC_SPI_GetSlave(mxc_spi_regs_t *spi)
763 {
764     return E_NOT_SUPPORTED;
765 }
766 
MXC_SPI_SetMode(mxc_spi_regs_t * spi,mxc_spi_mode_t spiMode)767 int MXC_SPI_SetMode(mxc_spi_regs_t *spi, mxc_spi_mode_t spiMode)
768 {
769     switch (spiMode) {
770     case SPI_MODE_0:
771         return MXC_SPI_SetClkMode(spi, MXC_SPI_CLKMODE_0);
772 
773     case SPI_MODE_1:
774         return MXC_SPI_SetClkMode(spi, MXC_SPI_CLKMODE_1);
775 
776     case SPI_MODE_2:
777         return MXC_SPI_SetClkMode(spi, MXC_SPI_CLKMODE_2);
778 
779     case SPI_MODE_3:
780         return MXC_SPI_SetClkMode(spi, MXC_SPI_CLKMODE_3);
781 
782     default:
783         return E_BAD_PARAM;
784     }
785 }
786 
MXC_SPI_GetMode(mxc_spi_regs_t * spi)787 mxc_spi_mode_t MXC_SPI_GetMode(mxc_spi_regs_t *spi)
788 {
789     mxc_spi_clkmode_t clk_mode;
790 
791     clk_mode = MXC_SPI_GetClkMode(spi);
792 
793     switch (clk_mode) {
794     case MXC_SPI_CLKMODE_0:
795         return SPI_MODE_0;
796 
797     case MXC_SPI_CLKMODE_1:
798         return SPI_MODE_1;
799 
800     case MXC_SPI_CLKMODE_2:
801         return SPI_MODE_2;
802 
803     case MXC_SPI_CLKMODE_3:
804         return SPI_MODE_3;
805 
806     default:
807         return SPI_MODE_0;
808     }
809 }
810 
MXC_SPI_SetDefaultTXData(mxc_spi_regs_t * spi,unsigned int defaultTXData)811 int MXC_SPI_SetDefaultTXData(mxc_spi_regs_t *spi, unsigned int defaultTXData)
812 {
813     return MXC_SPI_RevA2_SetDummyTX((mxc_spi_reva_regs_t *)spi, defaultTXData);
814 }
815 
MXC_SPI_HWSSControl(mxc_spi_regs_t * spi,int state)816 void MXC_SPI_HWSSControl(mxc_spi_regs_t *spi, int state)
817 {
818     MXC_ASSERT(0);
819 }
820