1 /*
2  * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
3  * Copyright 2016-2017 NXP
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 
9 /**
10  * @file register_io_spi.c
11  * @brief The register_io_spi.c file contains definitions for low-level interface functions
12  * for reading and writing sensor registers using CMSIS APIs.
13  */
14 
15 /* Standard C Includes */
16 #include <string.h>
17 
18 /* ISSDK Includes */
19 #include "issdk_hal.h"
20 #include "gpio_driver.h"
21 #include "register_io_spi.h"
22 
23 /*******************************************************************************
24  * Types
25  ******************************************************************************/
26 #define SPI_COUNT (sizeof(spiBases) / sizeof(void *))
27 
28 /*******************************************************************************
29  * Variables
30  ******************************************************************************/
31 GENERIC_DRIVER_GPIO *pDspiGpioDriver = &Driver_GPIO_KSDK;
32 #if defined(CPU_MCXN947VDF_cm33_core0) || defined(CPU_MCXN548VDF_cm33_core0)
33 LPSPI_Type *const spiBases[] = LPSPI_BASE_PTRS;
34 #else
35 SPI_Type *const spiBases[] = SPI_BASE_PTRS;
36 #endif
37 volatile bool b_SPI_CompletionFlag[SPI_COUNT] = {false};
38 volatile uint32_t g_SPI_ErrorEvent[SPI_COUNT] = {ARM_SPI_EVENT_TRANSFER_COMPLETE};
39 
40 /*******************************************************************************
41  * Code
42  ******************************************************************************/
43 #if defined(SPI0)
44 /* The SPI0 Signal Event Handler function. */
SPI0_SignalEvent_t(uint32_t event)45 void SPI0_SignalEvent_t(uint32_t event)
46 {
47     if (event != ARM_SPI_EVENT_TRANSFER_COMPLETE)
48     {
49         g_SPI_ErrorEvent[0] = event;
50     }
51     b_SPI_CompletionFlag[0] = true;
52 }
53 #endif
54 
55 #if defined(SPI1)
56 /* The SPI1 Signal Event Handler function. */
SPI1_SignalEvent_t(uint32_t event)57 void SPI1_SignalEvent_t(uint32_t event)
58 {
59     if (event != ARM_SPI_EVENT_TRANSFER_COMPLETE)
60     {
61         g_SPI_ErrorEvent[1] = event;
62     }
63     b_SPI_CompletionFlag[1] = true;
64 }
65 #endif
66 
67 #if defined(SPI2)
68 /* The SPI2 Signal Event Handler function. */
SPI2_SignalEvent_t(uint32_t event)69 void SPI2_SignalEvent_t(uint32_t event)
70 {
71     if (event != ARM_SPI_EVENT_TRANSFER_COMPLETE)
72     {
73         g_SPI_ErrorEvent[2] = event;
74     }
75     b_SPI_CompletionFlag[2] = true;
76 }
77 #endif
78 
79 #if defined(SPI3)
80 /* The SPI3 Signal Event Handler function. */
SPI3_SignalEvent_t(uint32_t event)81 void SPI3_SignalEvent_t(uint32_t event)
82 {
83     if (event != ARM_SPI_EVENT_TRANSFER_COMPLETE)
84     {
85         g_SPI_ErrorEvent[3] = event;
86     }
87     b_SPI_CompletionFlag[3] = true;
88 }
89 #endif
90 
91 #if defined(SPI4)
92 /* The SPI4 Signal Event Handler function. */
SPI4_SignalEvent_t(uint32_t event)93 void SPI4_SignalEvent_t(uint32_t event)
94 {
95     if (event != ARM_SPI_EVENT_TRANSFER_COMPLETE)
96     {
97         g_SPI_ErrorEvent[4] = event;
98     }
99     b_SPI_CompletionFlag[4] = true;
100 }
101 #endif
102 
103 #if defined(SPI5)
104 /* The SPI5 Signal Event Handler function. */
SPI5_SignalEvent_t(uint32_t event)105 void SPI5_SignalEvent_t(uint32_t event)
106 {
107     if (event != ARM_SPI_EVENT_TRANSFER_COMPLETE)
108     {
109         g_SPI_ErrorEvent[5] = event;
110     }
111     b_SPI_CompletionFlag[5] = true;
112 }
113 #endif
114 
115 #if defined(SPI6)
116 /* The SPI6 Signal Event Handler function. */
SPI6_SignalEvent_t(uint32_t event)117 void SPI6_SignalEvent_t(uint32_t event)
118 {
119     if (event != ARM_SPI_EVENT_TRANSFER_COMPLETE)
120     {
121         g_SPI_ErrorEvent[6] = event;
122     }
123     b_SPI_CompletionFlag[6] = true;
124 }
125 #endif
126 
127 #ifndef CPU_LPC55S06JBD64
128 #if defined(SPI7)
129 /* The SPI7 Signal Event Handler function. */
SPI7_SignalEvent_t(uint32_t event)130 void SPI7_SignalEvent_t(uint32_t event)
131 {
132     if (event != ARM_SPI_EVENT_TRANSFER_COMPLETE)
133     {
134         g_SPI_ErrorEvent[7] = event;
135     }
136     b_SPI_CompletionFlag[7] = true;
137 }
138 #endif
139 #if defined(SPI8)
140 /* The SPI7 Signal Event Handler function. */
SPI8_SignalEvent_t(uint32_t event)141 void SPI8_SignalEvent_t(uint32_t event)
142 {
143     if (event != ARM_SPI_EVENT_TRANSFER_COMPLETE)
144     {
145         g_SPI_ErrorEvent[8] = event;
146     }
147     b_SPI_CompletionFlag[8] = true;
148 }
149 #endif
150 #endif
151 
152 /* Control Slave Select based on inactive/active and active low/high. */
register_spi_control(spiControlParams_t * ssControl)153 void register_spi_control(spiControlParams_t *ssControl)
154 {
155     if (ssControl->cmdCode == ssControl->activeValue)
156     {
157         pDspiGpioDriver->set_pin(ssControl->pTargetSlavePinID);
158     }
159     else
160     {
161         pDspiGpioDriver->clr_pin(ssControl->pTargetSlavePinID);
162     }
163 }
164 
165 /*! The interface function to block write sensor registers. */
Register_SPI_BlockWrite(ARM_DRIVER_SPI * pCommDrv,registerDeviceInfo_t * devInfo,void * pWriteParams,uint8_t offset,const uint8_t * pBuffer,uint8_t bytesToWrite)166 int32_t Register_SPI_BlockWrite(ARM_DRIVER_SPI *pCommDrv,
167                                 registerDeviceInfo_t *devInfo,
168                                 void *pWriteParams,
169                                 uint8_t offset,
170                                 const uint8_t *pBuffer,
171                                 uint8_t bytesToWrite)
172 {
173     int32_t status;
174     spiCmdParams_t slaveWriteCmd;
175     spiSlaveSpecificParams_t *pSlaveParams = pWriteParams;
176 
177     spiControlParams_t ss_en_cmd = {
178         .cmdCode = ARM_SPI_SS_ACTIVE,
179         .activeValue = pSlaveParams->ssActiveValue,
180         .pTargetSlavePinID = pSlaveParams->pTargetSlavePinID,
181     };
182     spiControlParams_t ss_dis_cmd = {
183         .cmdCode = ARM_SPI_SS_INACTIVE,
184         .activeValue = pSlaveParams->ssActiveValue,
185         .pTargetSlavePinID = pSlaveParams->pTargetSlavePinID,
186     };
187 
188     pSlaveParams->pWritePreprocessFN(&slaveWriteCmd, offset, bytesToWrite, (void *)pBuffer);
189     b_SPI_CompletionFlag[devInfo->deviceInstance] = false;
190     g_SPI_ErrorEvent[devInfo->deviceInstance] = ARM_SPI_EVENT_TRANSFER_COMPLETE;
191     /*! Write and the value.*/
192     register_spi_control(&ss_en_cmd);
193     status = pCommDrv->Transfer(slaveWriteCmd.pWriteBuffer, slaveWriteCmd.pReadBuffer, slaveWriteCmd.size);
194     if (ARM_DRIVER_OK == status)
195     {
196         /* Wait for completion */
197         while (!b_SPI_CompletionFlag[devInfo->deviceInstance])
198         {
199             if (devInfo->idleFunction)
200             {
201                 devInfo->idleFunction(devInfo->functionParam);
202             }
203             else
204             {
205                 __NOP();
206             }
207         }
208         if (g_SPI_ErrorEvent[devInfo->deviceInstance] != ARM_SPI_EVENT_TRANSFER_COMPLETE)
209         {
210             status = ARM_DRIVER_ERROR;
211             pCommDrv->Control(ARM_SPI_ABORT_TRANSFER, 0);
212         }
213     }
214     register_spi_control(&ss_dis_cmd);
215 
216     return status;
217 }
218 
219 /*! The interface function to write a sensor register. */
Register_SPI_Write(ARM_DRIVER_SPI * pCommDrv,registerDeviceInfo_t * devInfo,void * pWriteParams,uint8_t offset,uint8_t value,uint8_t mask)220 int32_t Register_SPI_Write(ARM_DRIVER_SPI *pCommDrv,
221                            registerDeviceInfo_t *devInfo,
222                            void *pWriteParams,
223                            uint8_t offset,
224                            uint8_t value,
225                            uint8_t mask)
226 {
227     int32_t status;
228     uint8_t regValue;
229     spiCmdParams_t slaveReadCmd, slaveWriteCmd;
230     spiSlaveSpecificParams_t *pSlaveParams = pWriteParams;
231 
232     spiControlParams_t ss_en_cmd = {
233         .cmdCode = ARM_SPI_SS_ACTIVE,
234         .activeValue = pSlaveParams->ssActiveValue,
235         .pTargetSlavePinID = pSlaveParams->pTargetSlavePinID,
236     };
237     spiControlParams_t ss_dis_cmd = {
238         .cmdCode = ARM_SPI_SS_INACTIVE,
239         .activeValue = pSlaveParams->ssActiveValue,
240         .pTargetSlavePinID = pSlaveParams->pTargetSlavePinID,
241     };
242 
243     /*! Set the register based on the values in the register value pair configuration.*/
244     if (mask)
245     {
246         /* Get the formatted SPI Read Command. */
247         pSlaveParams->pReadPreprocessFN(&slaveReadCmd, offset, 1);
248         b_SPI_CompletionFlag[devInfo->deviceInstance] = false;
249         g_SPI_ErrorEvent[devInfo->deviceInstance] = ARM_SPI_EVENT_TRANSFER_COMPLETE;
250         /*! Read the register value.*/
251         register_spi_control(&ss_en_cmd);
252         status = pCommDrv->Transfer(slaveReadCmd.pWriteBuffer, slaveReadCmd.pReadBuffer, slaveReadCmd.size);
253         if (ARM_DRIVER_OK == status)
254         {
255             /* Wait for completion */
256             while (!b_SPI_CompletionFlag[devInfo->deviceInstance])
257             {
258                 if (devInfo->idleFunction)
259                 {
260                     devInfo->idleFunction(devInfo->functionParam);
261                 }
262                 else
263                 {
264                     __NOP();
265                 }
266             }
267             if (g_SPI_ErrorEvent[devInfo->deviceInstance] != ARM_SPI_EVENT_TRANSFER_COMPLETE)
268             {
269                 status = ARM_DRIVER_ERROR;
270                 pCommDrv->Control(ARM_SPI_ABORT_TRANSFER, 0);
271             }
272         }
273         register_spi_control(&ss_dis_cmd);
274 
275         /*! 'OR' in the requested values to the current contents of the register */
276         regValue = *(slaveReadCmd.pReadBuffer + pSlaveParams->spiCmdLen);
277         regValue = (regValue & ~mask) | value;
278     }
279     else
280     {
281         /*! Overwrite the register with specified value.*/
282         regValue = value;
283     }
284 
285     pSlaveParams->pWritePreprocessFN(&slaveWriteCmd, offset, 1, &regValue);
286     b_SPI_CompletionFlag[devInfo->deviceInstance] = false;
287     g_SPI_ErrorEvent[devInfo->deviceInstance] = ARM_SPI_EVENT_TRANSFER_COMPLETE;
288     /*! Write and the value.*/
289     register_spi_control(&ss_en_cmd);
290     status = pCommDrv->Transfer(slaveWriteCmd.pWriteBuffer, slaveWriteCmd.pReadBuffer, slaveWriteCmd.size);
291     if (ARM_DRIVER_OK == status)
292     {
293         /* Wait for completion */
294         while (!b_SPI_CompletionFlag[devInfo->deviceInstance])
295         {
296             if (devInfo->idleFunction)
297             {
298                 devInfo->idleFunction(devInfo->functionParam);
299             }
300             else
301             {
302                 __NOP();
303             }
304         }
305         if (g_SPI_ErrorEvent[devInfo->deviceInstance] != ARM_SPI_EVENT_TRANSFER_COMPLETE)
306         {
307             status = ARM_DRIVER_ERROR;
308             pCommDrv->Control(ARM_SPI_ABORT_TRANSFER, 0);
309         }
310     }
311     register_spi_control(&ss_dis_cmd);
312 
313     return status;
314 }
315 
316 /*! The interface function to read a sensor register. */
Register_SPI_Read(ARM_DRIVER_SPI * pCommDrv,registerDeviceInfo_t * devInfo,void * pReadParams,uint8_t offset,uint8_t length,uint8_t * pOutBuffer)317 int32_t Register_SPI_Read(ARM_DRIVER_SPI *pCommDrv,
318                           registerDeviceInfo_t *devInfo,
319                           void *pReadParams,
320                           uint8_t offset,
321                           uint8_t length,
322                           uint8_t *pOutBuffer)
323 {
324     int32_t status;
325     spiCmdParams_t slaveReadCmd;
326     spiSlaveSpecificParams_t *pSlaveParams = pReadParams;
327 
328     spiControlParams_t ss_en_cmd = {
329         .cmdCode = ARM_SPI_SS_ACTIVE,
330         .activeValue = pSlaveParams->ssActiveValue,
331         .pTargetSlavePinID = pSlaveParams->pTargetSlavePinID,
332     };
333     spiControlParams_t ss_dis_cmd = {
334         .cmdCode = ARM_SPI_SS_INACTIVE,
335         .activeValue = pSlaveParams->ssActiveValue,
336         .pTargetSlavePinID = pSlaveParams->pTargetSlavePinID,
337     };
338 
339     pSlaveParams->pReadPreprocessFN(&slaveReadCmd, offset, length);
340     b_SPI_CompletionFlag[devInfo->deviceInstance] = false;
341     g_SPI_ErrorEvent[devInfo->deviceInstance] = ARM_SPI_EVENT_TRANSFER_COMPLETE;
342     /*! Read the value.*/
343     register_spi_control(&ss_en_cmd);
344     status = pCommDrv->Transfer(slaveReadCmd.pWriteBuffer, slaveReadCmd.pReadBuffer, slaveReadCmd.size);
345     if (ARM_DRIVER_OK == status)
346     {
347         /* Wait for completion */
348         while (!b_SPI_CompletionFlag[devInfo->deviceInstance])
349         {
350             if (devInfo->idleFunction)
351             {
352                 devInfo->idleFunction(devInfo->functionParam);
353             }
354             else
355             {
356                 __NOP();
357             }
358         }
359         if (g_SPI_ErrorEvent[devInfo->deviceInstance] != ARM_SPI_EVENT_TRANSFER_COMPLETE)
360         {
361             status = ARM_DRIVER_ERROR;
362             pCommDrv->Control(ARM_SPI_ABORT_TRANSFER, 0);
363         }
364     }
365     register_spi_control(&ss_dis_cmd);
366 
367     memcpy(pOutBuffer, slaveReadCmd.pReadBuffer + pSlaveParams->spiCmdLen, length);
368 
369     return status;
370 }
371