ISSDK  1.7
IoT Sensing Software Development Kit
register_io_spi.c
Go to the documentation of this file.
1 /*
2  * The Clear BSD License
3  * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
4  * Copyright 2016-2017 NXP
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without modification,
8  * are permitted (subject to the limitations in the disclaimer below) provided
9  * that the following conditions are met:
10  *
11  * o Redistributions of source code must retain the above copyright notice, this list
12  * of conditions and the following disclaimer.
13  *
14  * o Redistributions in binary form must reproduce the above copyright notice, this
15  * list of conditions and the following disclaimer in the documentation and/or
16  * other materials provided with the distribution.
17  *
18  * o Neither the name of the copyright holder nor the names of its
19  * contributors may be used to endorse or promote products derived from this
20  * software without specific prior written permission.
21  *
22  * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
27  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
30  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  */
34 
35 /**
36  * @file register_io_spi.c
37  * @brief The register_io_spi.c file contains definitions for low-level interface functions
38  * for reading and writing sensor registers using CMSIS APIs.
39  */
40 
41 /* Standard C Includes */
42 #include <string.h>
43 
44 /* ISSDK Includes */
45 #include "issdk_hal.h"
46 #include "gpio_driver.h"
47 #include "register_io_spi.h"
48 
49 /*******************************************************************************
50  * Types
51  ******************************************************************************/
52 #define SPI_COUNT (sizeof(spiBases) / sizeof(void *))
53 
54 /*******************************************************************************
55  * Variables
56  ******************************************************************************/
59 volatile bool b_SPI_CompletionFlag[SPI_COUNT] = {false};
60 volatile uint32_t g_SPI_ErrorEvent[SPI_COUNT] = {ARM_SPI_EVENT_TRANSFER_COMPLETE};
61 
62 /*******************************************************************************
63  * Code
64  ******************************************************************************/
65 #if defined(SPI0)
66 /* The SPI0 Signal Event Handler function. */
67 void SPI0_SignalEvent_t(uint32_t event)
68 {
69  if (event != ARM_SPI_EVENT_TRANSFER_COMPLETE)
70  {
71  g_SPI_ErrorEvent[0] = event;
72  }
73  b_SPI_CompletionFlag[0] = true;
74 }
75 #endif
76 
77 #if defined(SPI1)
78 /* The SPI1 Signal Event Handler function. */
79 void SPI1_SignalEvent_t(uint32_t event)
80 {
81  if (event != ARM_SPI_EVENT_TRANSFER_COMPLETE)
82  {
83  g_SPI_ErrorEvent[1] = event;
84  }
85  b_SPI_CompletionFlag[1] = true;
86 }
87 #endif
88 
89 #if defined(SPI2)
90 /* The SPI2 Signal Event Handler function. */
91 void SPI2_SignalEvent_t(uint32_t event)
92 {
93  if (event != ARM_SPI_EVENT_TRANSFER_COMPLETE)
94  {
95  g_SPI_ErrorEvent[2] = event;
96  }
97  b_SPI_CompletionFlag[2] = true;
98 }
99 #endif
100 
101 #if defined(SPI3)
102 /* The SPI3 Signal Event Handler function. */
103 void SPI3_SignalEvent_t(uint32_t event)
104 {
105  if (event != ARM_SPI_EVENT_TRANSFER_COMPLETE)
106  {
107  g_SPI_ErrorEvent[3] = event;
108  }
109  b_SPI_CompletionFlag[3] = true;
110 }
111 #endif
112 
113 #if defined(SPI4)
114 /* The SPI4 Signal Event Handler function. */
115 void SPI4_SignalEvent_t(uint32_t event)
116 {
117  if (event != ARM_SPI_EVENT_TRANSFER_COMPLETE)
118  {
119  g_SPI_ErrorEvent[4] = event;
120  }
121  b_SPI_CompletionFlag[4] = true;
122 }
123 #endif
124 
125 #if defined(SPI5)
126 /* The SPI5 Signal Event Handler function. */
127 void SPI5_SignalEvent_t(uint32_t event)
128 {
129  if (event != ARM_SPI_EVENT_TRANSFER_COMPLETE)
130  {
131  g_SPI_ErrorEvent[5] = event;
132  }
133  b_SPI_CompletionFlag[5] = true;
134 }
135 #endif
136 
137 #if defined(SPI6)
138 /* The SPI6 Signal Event Handler function. */
139 void SPI6_SignalEvent_t(uint32_t event)
140 {
141  if (event != ARM_SPI_EVENT_TRANSFER_COMPLETE)
142  {
143  g_SPI_ErrorEvent[6] = event;
144  }
145  b_SPI_CompletionFlag[6] = true;
146 }
147 #endif
148 
149 #if defined(SPI7)
150 /* The SPI7 Signal Event Handler function. */
151 void SPI7_SignalEvent_t(uint32_t event)
152 {
153  if (event != ARM_SPI_EVENT_TRANSFER_COMPLETE)
154  {
155  g_SPI_ErrorEvent[7] = event;
156  }
157  b_SPI_CompletionFlag[7] = true;
158 }
159 #endif
160 
161 /* Control Slave Select based on inactive/active and active low/high. */
163 {
164  if (ssControl->cmdCode == ssControl->activeValue)
165  {
166  pDspiGpioDriver->set_pin(ssControl->pTargetSlavePinID);
167  }
168  else
169  {
170  pDspiGpioDriver->clr_pin(ssControl->pTargetSlavePinID);
171  }
172 }
173 
174 /*! The interface function to block write sensor registers. */
175 int32_t Register_SPI_BlockWrite(ARM_DRIVER_SPI *pCommDrv,
176  registerDeviceInfo_t *devInfo,
177  void *pWriteParams,
178  uint8_t offset,
179  const uint8_t *pBuffer,
180  uint8_t bytesToWrite)
181 {
182  int32_t status;
183  spiCmdParams_t slaveWriteCmd;
184  spiSlaveSpecificParams_t *pSlaveParams = pWriteParams;
185 
186  spiControlParams_t ss_en_cmd = {
187  .cmdCode = ARM_SPI_SS_ACTIVE,
188  .activeValue = pSlaveParams->ssActiveValue,
189  .pTargetSlavePinID = pSlaveParams->pTargetSlavePinID,
190  };
191  spiControlParams_t ss_dis_cmd = {
192  .cmdCode = ARM_SPI_SS_INACTIVE,
193  .activeValue = pSlaveParams->ssActiveValue,
194  .pTargetSlavePinID = pSlaveParams->pTargetSlavePinID,
195  };
196 
197  pSlaveParams->pWritePreprocessFN(&slaveWriteCmd, offset, bytesToWrite, (void *)pBuffer);
198  b_SPI_CompletionFlag[devInfo->deviceInstance] = false;
199  g_SPI_ErrorEvent[devInfo->deviceInstance] = ARM_SPI_EVENT_TRANSFER_COMPLETE;
200  /*! Write and the value.*/
201  register_spi_control(&ss_en_cmd);
202  status = pCommDrv->Transfer(slaveWriteCmd.pWriteBuffer, slaveWriteCmd.pReadBuffer, slaveWriteCmd.size);
203  if (ARM_DRIVER_OK == status)
204  {
205  /* Wait for completion */
206  while (!b_SPI_CompletionFlag[devInfo->deviceInstance])
207  {
208  if (devInfo->idleFunction)
209  {
210  devInfo->idleFunction(devInfo->functionParam);
211  }
212  else
213  {
214  __NOP();
215  }
216  }
217  if (g_SPI_ErrorEvent[devInfo->deviceInstance] != ARM_SPI_EVENT_TRANSFER_COMPLETE)
218  {
219  status = ARM_DRIVER_ERROR;
220  pCommDrv->Control(ARM_SPI_ABORT_TRANSFER, 0);
221  }
222  }
223  register_spi_control(&ss_dis_cmd);
224 
225  return status;
226 }
227 
228 /*! The interface function to write a sensor register. */
229 int32_t Register_SPI_Write(ARM_DRIVER_SPI *pCommDrv,
230  registerDeviceInfo_t *devInfo,
231  void *pWriteParams,
232  uint8_t offset,
233  uint8_t value,
234  uint8_t mask)
235 {
236  int32_t status;
237  uint8_t regValue;
238  spiCmdParams_t slaveReadCmd, slaveWriteCmd;
239  spiSlaveSpecificParams_t *pSlaveParams = pWriteParams;
240 
241  spiControlParams_t ss_en_cmd = {
242  .cmdCode = ARM_SPI_SS_ACTIVE,
243  .activeValue = pSlaveParams->ssActiveValue,
244  .pTargetSlavePinID = pSlaveParams->pTargetSlavePinID,
245  };
246  spiControlParams_t ss_dis_cmd = {
247  .cmdCode = ARM_SPI_SS_INACTIVE,
248  .activeValue = pSlaveParams->ssActiveValue,
249  .pTargetSlavePinID = pSlaveParams->pTargetSlavePinID,
250  };
251 
252  /*! Set the register based on the values in the register value pair configuration.*/
253  if (mask)
254  {
255  /* Get the formatted SPI Read Command. */
256  pSlaveParams->pReadPreprocessFN(&slaveReadCmd, offset, 1);
257  b_SPI_CompletionFlag[devInfo->deviceInstance] = false;
258  g_SPI_ErrorEvent[devInfo->deviceInstance] = ARM_SPI_EVENT_TRANSFER_COMPLETE;
259  /*! Read the register value.*/
260  register_spi_control(&ss_en_cmd);
261  status = pCommDrv->Transfer(slaveReadCmd.pWriteBuffer, slaveReadCmd.pReadBuffer, slaveReadCmd.size);
262  if (ARM_DRIVER_OK == status)
263  {
264  /* Wait for completion */
265  while (!b_SPI_CompletionFlag[devInfo->deviceInstance])
266  {
267  if (devInfo->idleFunction)
268  {
269  devInfo->idleFunction(devInfo->functionParam);
270  }
271  else
272  {
273  __NOP();
274  }
275  }
276  if (g_SPI_ErrorEvent[devInfo->deviceInstance] != ARM_SPI_EVENT_TRANSFER_COMPLETE)
277  {
278  status = ARM_DRIVER_ERROR;
279  pCommDrv->Control(ARM_SPI_ABORT_TRANSFER, 0);
280  }
281  }
282  register_spi_control(&ss_dis_cmd);
283 
284  /*! 'OR' in the requested values to the current contents of the register */
285  regValue = *(slaveReadCmd.pReadBuffer + pSlaveParams->spiCmdLen);
286  regValue = (regValue & ~mask) | value;
287  }
288  else
289  {
290  /*! Overwrite the register with specified value.*/
291  regValue = value;
292  }
293 
294  pSlaveParams->pWritePreprocessFN(&slaveWriteCmd, offset, 1, &regValue);
295  b_SPI_CompletionFlag[devInfo->deviceInstance] = false;
296  g_SPI_ErrorEvent[devInfo->deviceInstance] = ARM_SPI_EVENT_TRANSFER_COMPLETE;
297  /*! Write and the value.*/
298  register_spi_control(&ss_en_cmd);
299  status = pCommDrv->Transfer(slaveWriteCmd.pWriteBuffer, slaveWriteCmd.pReadBuffer, slaveWriteCmd.size);
300  if (ARM_DRIVER_OK == status)
301  {
302  /* Wait for completion */
303  while (!b_SPI_CompletionFlag[devInfo->deviceInstance])
304  {
305  if (devInfo->idleFunction)
306  {
307  devInfo->idleFunction(devInfo->functionParam);
308  }
309  else
310  {
311  __NOP();
312  }
313  }
314  if (g_SPI_ErrorEvent[devInfo->deviceInstance] != ARM_SPI_EVENT_TRANSFER_COMPLETE)
315  {
316  status = ARM_DRIVER_ERROR;
317  pCommDrv->Control(ARM_SPI_ABORT_TRANSFER, 0);
318  }
319  }
320  register_spi_control(&ss_dis_cmd);
321 
322  return status;
323 }
324 
325 /*! The interface function to read a sensor register. */
326 int32_t Register_SPI_Read(ARM_DRIVER_SPI *pCommDrv,
327  registerDeviceInfo_t *devInfo,
328  void *pReadParams,
329  uint8_t offset,
330  uint8_t length,
331  uint8_t *pOutBuffer)
332 {
333  int32_t status;
334  spiCmdParams_t slaveReadCmd;
335  spiSlaveSpecificParams_t *pSlaveParams = pReadParams;
336 
337  spiControlParams_t ss_en_cmd = {
338  .cmdCode = ARM_SPI_SS_ACTIVE,
339  .activeValue = pSlaveParams->ssActiveValue,
340  .pTargetSlavePinID = pSlaveParams->pTargetSlavePinID,
341  };
342  spiControlParams_t ss_dis_cmd = {
343  .cmdCode = ARM_SPI_SS_INACTIVE,
344  .activeValue = pSlaveParams->ssActiveValue,
345  .pTargetSlavePinID = pSlaveParams->pTargetSlavePinID,
346  };
347 
348  pSlaveParams->pReadPreprocessFN(&slaveReadCmd, offset, length);
349  b_SPI_CompletionFlag[devInfo->deviceInstance] = false;
350  g_SPI_ErrorEvent[devInfo->deviceInstance] = ARM_SPI_EVENT_TRANSFER_COMPLETE;
351  /*! Read the value.*/
352  register_spi_control(&ss_en_cmd);
353  status = pCommDrv->Transfer(slaveReadCmd.pWriteBuffer, slaveReadCmd.pReadBuffer, slaveReadCmd.size);
354  if (ARM_DRIVER_OK == status)
355  {
356  /* Wait for completion */
357  while (!b_SPI_CompletionFlag[devInfo->deviceInstance])
358  {
359  if (devInfo->idleFunction)
360  {
361  devInfo->idleFunction(devInfo->functionParam);
362  }
363  else
364  {
365  __NOP();
366  }
367  }
368  if (g_SPI_ErrorEvent[devInfo->deviceInstance] != ARM_SPI_EVENT_TRANSFER_COMPLETE)
369  {
370  status = ARM_DRIVER_ERROR;
371  pCommDrv->Control(ARM_SPI_ABORT_TRANSFER, 0);
372  }
373  }
374  register_spi_control(&ss_dis_cmd);
375 
376  memcpy(pOutBuffer, slaveReadCmd.pReadBuffer + pSlaveParams->spiCmdLen, length);
377 
378  return status;
379 }
fpSpiWritePreprocessFn_t pWritePreprocessFN
registeridlefunction_t idleFunction
Definition: sensor_drv.h:130
volatile bool b_SPI_CompletionFlag[SPI_COUNT]
volatile uint32_t g_SPI_ErrorEvent[SPI_COUNT]
int32_t Register_SPI_BlockWrite(ARM_DRIVER_SPI *pCommDrv, registerDeviceInfo_t *devInfo, void *pWriteParams, uint8_t offset, const uint8_t *pBuffer, uint8_t bytesToWrite)
The interface function to block write to a sensor register.
int32_t status
GENERIC_DRIVER_GPIO * pDspiGpioDriver
SPI_Type *const spiBases[]
#define SPI_BASE_PTRS
Definition: frdm_ke15z.h:159
void(* set_pin)(pinID_t aPinId)
Definition: Driver_GPIO.h:72
void(* clr_pin)(pinID_t aPinId)
Definition: Driver_GPIO.h:73
The SPI Slave Transfer Command Params SDK2.0 Driver.
#define SPI_COUNT
void register_spi_control(spiControlParams_t *ssControl)
GENERIC_DRIVER_GPIO Driver_GPIO_KSDK
Definition: gpio_driver.c:203
typedef int32_t(DATA_FORMAT_Append_t))(void *pData
The interface function to append the data on the formated stream.
Access structure of the GPIO Driver.
Definition: Driver_GPIO.h:64
int32_t Register_SPI_Read(ARM_DRIVER_SPI *pCommDrv, registerDeviceInfo_t *devInfo, void *pReadParams, uint8_t offset, uint8_t length, uint8_t *pOutBuffer)
The interface function to read a sensor register.
#define SPI_Type
Definition: frdm_ke15z.h:157
The SPI Slave Control Command Params SDK2.0 Driver.
This structure defines the device specific info required by register I/O.
Definition: sensor_drv.h:128
This structure defines the spi slave command format.
The register_io_spi.h file declares low-level interface functions for reading and writing sensor regi...
fpSpiReadPreprocessFn_t pReadPreprocessFN
int32_t Register_SPI_Write(ARM_DRIVER_SPI *pCommDrv, registerDeviceInfo_t *devInfo, void *pWriteParams, uint8_t offset, uint8_t value, uint8_t mask)
The interface function to write a sensor register.