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, ®Value);
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