ISSDK  1.8
IoT Sensing Software Development Kit
auto_detection_service.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 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 auto_detection_service.c
11  * @brief The auto detection service file implements auto detection sequence
12  * for discovery of LPC Board and Sensor Shield Board.
13  */
14 
15 #include <stdio.h>
16 #include <stdint.h>
17 
18 #include "diff_p.h"
19 #include "mma9553.h"
20 #include "mpl3115.h"
21 #include "mag3110.h"
22 #include "mma865x.h"
23 #include "fxls8962.h"
24 #include "fxpq3115.h"
25 #include "fxos8700.h"
26 #include "fxas21002.h"
27 #include "fxlc95000.h"
28 #include "fxls8471q.h"
29 
30 #include "issdk_hal.h"
31 #include "gpio_driver.h"
32 #include "systick_utils.h"
33 #include "register_io_spi.h"
34 #include "register_io_i2c.h"
35 #include "auto_detection_shield.h"
36 #include "auto_detection_service.h"
37 
38 #include "fsl_flashiap.h"
39 
40 /*******************************************************************************
41  * Definitions
42  ******************************************************************************/
43 /*!
44 * @brief These variables are specific to SPI access to the FXLS8471 for ADS.
45 */
46 #define FXLS8471Q_SPI_CMD_LEN (2)
47 #define FXLS8471Q_SS_ACTIVE_VALUE SPI_SS_ACTIVE_LOW
48 
49 /*!
50 * @brief These variables are specific to SPI access to the FXLS8962 for ADS.
51 */
52 #define FXLS8962_SPI_CMD_LEN (2)
53 #define FXLS8962_SS_ACTIVE_VALUE SPI_SS_ACTIVE_LOW
54 
55 /*!
56 * @brief These variables are specific to SPI access to the DIFF_P for ADS.
57 */
58 #define DIFF_P_SPI_CMD_LEN (1)
59 #define DIFF_P_SS_ACTIVE_VALUE SPI_SS_ACTIVE_LOW
60 #define ADS_NVM_SECTOR_NUM (ADS_NVM_ADDR / FSL_FEATURE_SYSCON_FLASH_SECTOR_SIZE_BYTES)
61 
62 #define ADS_QUERY_NUM (sizeof(ADS_SensorQueryList) / sizeof(sensorAccess_t))
63 #define ADS_NUM_BOARDS (sizeof(gADS_QueryMap) / ADS_QUERY_NUM)
64 #define SPI_MAX_MSG_SIZE (64)
65 
66 /*******************************************************************************
67 * Constants
68 ******************************************************************************/
69 /*! @brief The Read Version Info Command for FXLC95000. */
70 const uint8_t ReadVersionInfo_MMA9553[4] = {0x00, 0x00, 0x00, 0x0C};
71 
72 /*!
73 * @brief This constant data structure contains the expected valid MCU Device ID combinations.
74 * Refer : LPC5411x User manual - UM10914, Section: 33.5.12
75 */
77  {0x06254113, ADS_LPC_54113J128}, // LPC-54113J128
78  {0x36454113, ADS_LPC_54113J256}, // LPC-54113J256
79  {0x36454114, ADS_LPC_54114J256}, // LPC-54114J256
80 };
81 
82 /*!
83 * @brief This constant data structure contains the expected valid comm/sensor/who_am_i combinations.
84 */
88  {ADS_SPI_DEV, DIFF_P, DIFF_P_WHO_AM_I, DIFF_P_NPS3000VV_WHOAMI_VALUE, 0xFC},
97  {ADS_I2C_EXT, DIFF_P_I2C_ADDR, DIFF_P_WHO_AM_I, DIFF_P_NPS3000VV_WHOAMI_VALUE, 0xFC},
99 };
100 
101 /*!
102 * @brief These are the expected query signatures for the shield boards.
103 */
105  {
106  // FRDM-STBC-AGM01
107  ADS_FAIL, // FXLS8471
108  ADS_FAIL, // FXLS8962
109  ADS_FAIL, // DIFF-P
110  ADS_FAIL, // FXLS8962
111  ADS_OK, // FXAS21002
112  ADS_FAIL, // FXLC95000
113  ADS_OK, // FXOS8700
114  ADS_FAIL, // FXPQ3115
115  ADS_FAIL, // MAG3110
116  ADS_FAIL, // MMA865x
117  ADS_FAIL, // MMA9553
118  ADS_FAIL, // DIFF-P
119  ADS_FAIL, // MPL3115
120  },
121  {
122  // FRDM-STBC-SA9500
123  ADS_FAIL, // FXLS8471
124  ADS_FAIL, // FXLS8962
125  ADS_FAIL, // DIFF-P
126  ADS_FAIL, // FXLS8962
127  ADS_FAIL, // FXAS21002
128  ADS_OK, // FXLC95000
129  ADS_FAIL, // FXOS8700
130  ADS_FAIL, // FXPQ3115
131  ADS_FAIL, // MAG3110
132  ADS_FAIL, // MMA865x
133  ADS_FAIL, // MMA9553
134  ADS_FAIL, // DIFF-P
135  ADS_FAIL, // MPL3115
136  },
137  {
138  // FRDMSTBC-A8471
139  ADS_OK, // FXLS8471
140  ADS_FAIL, // FXLS8962
141  ADS_FAIL, // DIFF-P
142  ADS_FAIL, // FXLS8962
143  ADS_FAIL, // FXAS21002
144  ADS_FAIL, // FXLC95000
145  ADS_FAIL, // FXOS8700
146  ADS_FAIL, // FXPQ3115
147  ADS_FAIL, // MAG3110
148  ADS_FAIL, // MMA865x
149  ADS_FAIL, // MMA9553
150  ADS_FAIL, // DIFF-P
151  ADS_FAIL, // MPL3115
152  },
153  {
154  // FRDMSTBC-P3115
155  ADS_FAIL, // FXLS8471
156  ADS_FAIL, // FXLS8962
157  ADS_FAIL, // DIFF-P
158  ADS_FAIL, // FXLS8962
159  ADS_FAIL, // FXAS21002
160  ADS_FAIL, // FXLC95000
161  ADS_FAIL, // FXOS8700
162  ADS_FAIL, // FXPQ3115
163  ADS_FAIL, // MAG3110
164  ADS_FAIL, // MMA865x
165  ADS_FAIL, // MMA9553
166  ADS_FAIL, // DIFF-P
167  ADS_OK, // MPL3115
168  },
169  {
170  // FRDMSTBC-DIFF-P SPI
171  ADS_FAIL, // FXLS8471
172  ADS_FAIL, // FXLS8962
173  ADS_OK, // DIFF-P
174  ADS_FAIL, // FXLS8962
175  ADS_FAIL, // FXAS21002
176  ADS_FAIL, // FXLC95000
177  ADS_FAIL, // FXOS8700
178  ADS_FAIL, // FXPQ3115
179  ADS_FAIL, // MAG3110
180  ADS_FAIL, // MMA865x
181  ADS_FAIL, // MMA9553
182  ADS_OK, // DIFF-P
183  ADS_FAIL, // MPL3115
184  },
185  {
186  // FRDMSTBC-DIFF-P I2C
187  ADS_FAIL, // FXLS8471
188  ADS_FAIL, // FXLS8962
189  ADS_FAIL, // DIFF-P
190  ADS_FAIL, // FXLS8962
191  ADS_FAIL, // FXAS21002
192  ADS_FAIL, // FXLC95000
193  ADS_FAIL, // FXOS8700
194  ADS_FAIL, // FXPQ3115
195  ADS_FAIL, // MAG3110
196  ADS_FAIL, // MMA865x
197  ADS_FAIL, // MMA9553
198  ADS_OK, // DIFF-P
199  ADS_FAIL, // MPL3115
200  },
201  {
202  // FRDMSTBC-B3115
203  ADS_FAIL, // FXLS8471
204  ADS_FAIL, // FXLS8962
205  ADS_FAIL, // DIFF-P
206  ADS_FAIL, // FXLS8962
207  ADS_FAIL, // FXAS21002
208  ADS_FAIL, // FXLC95000
209  ADS_FAIL, // FXOS8700
210  ADS_OK, // FXPQ3115
211  ADS_FAIL, // MAG3110
212  ADS_FAIL, // MMA865x
213  ADS_FAIL, // MMA9553
214  ADS_FAIL, // DIFF-P
215  ADS_FAIL, // MPL3115
216  },
217  {
218  // FRDM-FXS-MULT2-B
219  ADS_OK, // FXLS8471
220  ADS_FAIL, // FXLS8962
221  ADS_FAIL, // DIFF-P
222  ADS_FAIL, // FXLS8962
223  ADS_OK, // FXAS21002
224  ADS_FAIL, // FXLC95000
225  ADS_OK, // FXOS8700
226  ADS_FAIL, // FXPQ3115
227  ADS_OK, // MAG3110
228  ADS_OK, // MMA865x
229  ADS_OK, // MMA9553
230  ADS_FAIL, // DIFF-P
231  ADS_OK, // MPL3115
232  },
233  {
234  // FRDM-STBC-AGMP03 over SPI
235  ADS_FAIL, // FXLS8471
236  ADS_OK, // FXLS8962
237  ADS_FAIL, // DIFF-P
238  ADS_FAIL, // FXLS8962
239  ADS_FAIL, // FXAS21002
240  ADS_FAIL, // FXLC95000
241  ADS_FAIL, // FXOS8700
242  ADS_FAIL, // FXPQ3115
243  ADS_OK, // MAG3110
244  ADS_FAIL, // MMA865x
245  ADS_FAIL, // MMA9553
246  ADS_FAIL, // DIFF-P
247  ADS_OK, // MPL3115
248  },
249  {
250  // FRDM-STBC-AGMP03 over I2C
251  ADS_FAIL, // FXLS8471
252  ADS_FAIL, // FXLS8962
253  ADS_FAIL, // DIFF-P
254  ADS_OK, // FXLS8962
255  ADS_OK, // FXAS21002
256  ADS_FAIL, // FXLC95000
257  ADS_FAIL, // FXOS8700
258  ADS_FAIL, // FXPQ3115
259  ADS_OK, // MAG3110
260  ADS_FAIL, // MMA865x
261  ADS_FAIL, // MMA9553
262  ADS_FAIL, // DIFF-P
263  ADS_OK, // MPL3115
264  },
265  {
266  // FRDM-STBC-AGM04
267  ADS_FAIL, // FXLS8471
268  ADS_FAIL, // FXLS8962
269  ADS_FAIL, // DIFF-P
270  ADS_FAIL, // FXLS8962
271  ADS_OK, // FXAS21002
272  ADS_FAIL, // FXLC95000
273  ADS_FAIL, // FXOS8700
274  ADS_FAIL, // FXPQ3115
275  ADS_OK, // MAG3110
276  ADS_OK, // MMA865x
277  ADS_FAIL, // MMA9553
278  ADS_FAIL, // DIFF-P
279  ADS_FAIL, // MPL3115
280  },
281 };
282 
283 /*******************************************************************************
284  * Global Variables
285  ******************************************************************************/
286 /*!
287 * @brief This global contains the results from the sensor query.
288 */
290 
292  "FRDM-STBC-AGM01", "FRDM-STBC-SA9500", "FRDMSTBC-A8471",
293  "FRDMSTBC-P3115", "FRDMSTBI-DP300x", "FRDMSTBI-DP300x", "FRDMSTBC-B3115",
294  "FRDM-FXS-MULT2-B", "FRDM-STBC-AGMP03", "FRDM-STBC-AGMP03", "FRDM-STBC-AGM04",
295 };
296 
297 /*!
298 * @brief These values hold the ARM CMSIS Driver interface pointers.
299 */
300 ARM_DRIVER_SPI *SPIdrv = &SPI_S_DRIVER;
301 ARM_DRIVER_I2C *I2CextDrv = &I2C_S1_DRIVER;
303 
310 
311 /*******************************************************************************
312 * FXLS8471 SPI Specific Functions
313 *****************************************************************************/
314 void ADS_FXLS8471Q_SPI_ReadPreprocess(void *pCmdOut, uint32_t offset, uint32_t size)
315 {
316  spiCmdParams_t *pSlaveCmd = pCmdOut;
317 
318  uint8_t *pWBuff = spiRead_CmdBuffer;
319  uint8_t *pRBuff = spiRead_DataBuffer;
320 
321  /* Formatting for Read command of FXLS8471Q SENSOR. */
322  *(pWBuff) = offset & 0x7F; /* offset is the internal register address of the sensor at which write is performed. */
323  *(pWBuff + 1) = offset & 0x80;
324 
325  // Create the slave read command.
326  pSlaveCmd->size = size + FXLS8471Q_SPI_CMD_LEN;
327  pSlaveCmd->pWriteBuffer = pWBuff;
328  pSlaveCmd->pReadBuffer = pRBuff;
329 }
330 
331 void ADS_FXLS8471Q_SPI_WritePreprocess(void *pCmdOut, uint32_t offset, uint32_t size, void *pWritebuffer)
332 {
333  spiCmdParams_t *pSlaveCmd = pCmdOut;
334 
335  uint8_t *pWBuff = spiWrite_CmdDataBuffer;
336  uint8_t *pRBuff = spiWrite_CmdDataBuffer + size + FXLS8471Q_SPI_CMD_LEN;
337 
338  /* Formatting for Write command of FXLS8471Q SENSOR. */
339  *(pWBuff) = offset | 0x80; /* offset is the internal register address of the sensor at which write is performed. */
340  *(pWBuff + 1) = offset & 0x80;
341 
342  /* Copy the slave write command */
343  memcpy(pWBuff + FXLS8471Q_SPI_CMD_LEN, pWritebuffer, size);
344 
345  /* Create the slave command. */
346  pSlaveCmd->size = size + FXLS8471Q_SPI_CMD_LEN;
347  pSlaveCmd->pWriteBuffer = pWBuff;
348  pSlaveCmd->pReadBuffer = pRBuff;
349 }
350 
352 {
355  spiParams_8471.pTargetSlavePinID = &FXLS8471_SPI_CS;
356  spiParams_8471.spiCmdLen = FXLS8471Q_SPI_CMD_LEN;
357  spiParams_8471.ssActiveValue = FXLS8471Q_SS_ACTIVE_VALUE;
358 
359  /* Initialize the Slave Select Pin. */
360  pGPIODriver->pin_init(&FXLS8471_SPI_CS, GPIO_DIRECTION_OUT, NULL, NULL, NULL);
361  if (spiParams_8471.ssActiveValue == SPI_SS_ACTIVE_LOW)
362  {
363  pGPIODriver->set_pin(&FXLS8471_SPI_CS);
364  }
365  else
366  {
367  pGPIODriver->clr_pin(&FXLS8471_SPI_CS);
368  }
369 };
370 
371 ADS_Status_t ADS_FXLS8471Query(uint8_t whoAmiAddr, uint8_t whoAmi)
372 {
373  int32_t status;
374  uint8_t reg;
375  registerDeviceInfo_t deviceInfo = {
376  .deviceInstance = SPI_S_DEVICE_INDEX, .functionParam = NULL, .idleFunction = NULL};
377 
378  /*! Read and store the device's WHO_AM_I.*/
379  status = Register_SPI_Read(SPIdrv, &deviceInfo, &spiParams_8471, whoAmiAddr, 1, &reg);
380  if ((ARM_DRIVER_OK != status) || (whoAmi != reg))
381  {
382  return ADS_FAIL;
383  }
384 
385  return ADS_OK;
386 }
387 
388 /*******************************************************************************
389 * FXLS8962 SPI Specific Functions
390 *****************************************************************************/
391 void ADS_FXLS8962_SPI_ReadPreprocess(void *pCmdOut, uint32_t offset, uint32_t size)
392 {
393  spiCmdParams_t *pSlaveCmd = pCmdOut;
394 
395  uint8_t *pWBuff = spiRead_CmdBuffer;
396  uint8_t *pRBuff = spiRead_DataBuffer;
397 
398  /* Formatting for Read command of FXLS8962 SENSOR. */
399  *(pWBuff) = offset | 0x80; /* offset is the internal register address of the sensor at which write is performed. */
400  *(pWBuff + 1) = 0x00;
401 
402  /* Create the slave read command. */
403  pSlaveCmd->size = size + FXLS8962_SPI_CMD_LEN;
404  pSlaveCmd->pWriteBuffer = pWBuff;
405  pSlaveCmd->pReadBuffer = pRBuff;
406 }
407 
408 void ADS_FXLS8962_SPI_WritePreprocess(void *pCmdOut, uint32_t offset, uint32_t size, void *pWritebuffer)
409 {
410  spiCmdParams_t *pSlaveCmd = pCmdOut;
411 
412  uint8_t *pWBuff = spiWrite_CmdDataBuffer;
413  uint8_t *pRBuff = spiWrite_CmdDataBuffer + size + FXLS8962_SPI_CMD_LEN;
414 
415  /* Formatting for Write command of FXLS8962 SENSOR. */
416  *(pWBuff) = offset & 0x7F; /* offset is the internal register address of the sensor at which write is performed. */
417  *(pWBuff + 1) = 0x00;
418 
419  /* Copy the slave write command */
420  memcpy(pWBuff + FXLS8962_SPI_CMD_LEN, pWritebuffer, size);
421 
422  /* Create the slave command. */
423  pSlaveCmd->size = size + FXLS8962_SPI_CMD_LEN;
424  pSlaveCmd->pWriteBuffer = pWBuff;
425  pSlaveCmd->pReadBuffer = pRBuff;
426 }
427 
429 { /*! Initialize the sensor handle. */
432  spiParams_8962.pTargetSlavePinID = &FXLS8962_CS;
433  spiParams_8962.spiCmdLen = FXLS8962_SPI_CMD_LEN;
434  spiParams_8962.ssActiveValue = FXLS8962_SS_ACTIVE_VALUE;
435 
436  /* Initialize the Slave Select Pin. */
437  pGPIODriver->pin_init(&FXLS8962_CS, GPIO_DIRECTION_OUT, NULL, NULL, NULL);
438  if (spiParams_8962.ssActiveValue == SPI_SS_ACTIVE_LOW)
439  {
440  pGPIODriver->set_pin(&FXLS8962_CS);
441  }
442  else
443  {
444  pGPIODriver->clr_pin(&FXLS8962_CS);
445  }
446 };
447 
448 ADS_Status_t ADS_FXLS8962Query(uint8_t whoAmiAddr, uint8_t whoAmi)
449 {
450  int32_t status;
451  uint8_t reg;
452  registerDeviceInfo_t deviceInfo = {
453  .deviceInstance = SPI_S_DEVICE_INDEX, .functionParam = NULL, .idleFunction = NULL};
454 
455  /*! Read and store the device's WHO_AM_I.*/
456  status = Register_SPI_Read(SPIdrv, &deviceInfo, &spiParams_8962, whoAmiAddr, 1, &reg);
457  if ((ARM_DRIVER_OK != status) || (whoAmi != reg))
458  {
459  return ADS_FAIL;
460  }
461 
462  return ADS_OK;
463 }
464 
465 /*******************************************************************************
466 * DIFF-P SPI Specific Functions
467 *****************************************************************************/
468 void ADS_DIFF_P_SPI_ReadPreprocess(void *pCmdOut, uint32_t offset, uint32_t size)
469 {
470  spiCmdParams_t *pSlaveCmd = pCmdOut;
471 
472  uint8_t *pWBuff = spiRead_CmdBuffer;
473  uint8_t *pRBuff = spiRead_DataBuffer;
474 
475  /* Formatting for Read command of DIFF-P SENSOR. */
476  *(pWBuff) = offset & 0x7F; /* offset is the internal register address of the sensor at which write is performed. */
477 
478  // Create the slave read command.
479  pSlaveCmd->size = size + DIFF_P_SPI_CMD_LEN;
480  pSlaveCmd->pWriteBuffer = pWBuff;
481  pSlaveCmd->pReadBuffer = pRBuff;
482 }
483 
484 void ADS_DIFF_P_SPI_WritePreprocess(void *pCmdOut, uint32_t offset, uint32_t size, void *pWritebuffer)
485 {
486  spiCmdParams_t *pSlaveCmd = pCmdOut;
487 
488  uint8_t *pWBuff = spiWrite_CmdDataBuffer;
489  uint8_t *pRBuff = spiWrite_CmdDataBuffer + size + DIFF_P_SPI_CMD_LEN;
490 
491  /* Formatting for Write command of DIFF-P SENSOR. */
492  *(pWBuff) = offset | 0x80; /* offset is the internal register address of the sensor at which write is performed. */
493 
494  /* Copy the slave write command */
495  memcpy(pWBuff + DIFF_P_SPI_CMD_LEN, pWritebuffer, size);
496 
497  /* Create the slave command. */
498  pSlaveCmd->size = size + DIFF_P_SPI_CMD_LEN;
499  pSlaveCmd->pWriteBuffer = pWBuff;
500  pSlaveCmd->pReadBuffer = pRBuff;
501 }
502 
504 {
507  spiParams_diff_p.pTargetSlavePinID = &DIFF_P_SPI_CS;
508  spiParams_diff_p.spiCmdLen = DIFF_P_SPI_CMD_LEN;
509  spiParams_diff_p.ssActiveValue = DIFF_P_SS_ACTIVE_VALUE;
510 
511  /* Initialize the Slave Select Pin. */
512  pGPIODriver->pin_init(&DIFF_P_SPI_CS, GPIO_DIRECTION_OUT, NULL, NULL, NULL);
513  if (spiParams_diff_p.ssActiveValue == SPI_SS_ACTIVE_LOW)
514  {
515  pGPIODriver->set_pin(&DIFF_P_SPI_CS);
516  }
517  else
518  {
519  pGPIODriver->clr_pin(&DIFF_P_SPI_CS);
520  }
521 };
522 
523 ADS_Status_t ADS_DIFF_PQuery(uint8_t whoAmiAddr, uint8_t whoAmi)
524 {
525  int32_t status;
526  uint8_t reg;
527  registerDeviceInfo_t deviceInfo = {
528  .deviceInstance = SPI_S_DEVICE_INDEX, .functionParam = NULL, .idleFunction = NULL};
529 
530  /*! Read and store the device's WHO_AM_I.*/
531  status = Register_SPI_Read(SPIdrv, &deviceInfo, &spiParams_diff_p, whoAmiAddr, 1, &reg);
532  if ((ARM_DRIVER_OK != status) || (whoAmi != reg))
533  {
534  return ADS_FAIL;
535  }
536 
537  return ADS_OK;
538 }
539 
540 /*******************************************************************************
541 * FXLC95000 Specific Functions
542 *****************************************************************************/
544 {
545  int32_t status;
546  uint16_t partNumber;
547 
548  registerDeviceInfo_t deviceInfo = {
549  .deviceInstance = I2C_S1_DEVICE_INDEX, .functionParam = NULL, .idleFunction = NULL};
550 
551  /* ADS is required to confirm only the presence of FXLC95000 and not the contents of its FLASH.
552  * As such we will not send command to Boot FXLC95000 to Flash.
553  * We send the Get Device Info ROM CI command and validate response. */
554  Register_I2C_BlockWrite(I2CextDrv, &deviceInfo, FXLC95000_I2C_ADDR, 0, GetDeviceInfoCmd, sizeof(GetDeviceInfoCmd));
555  BOARD_DELAY_ms(1);
556 
557  /* Read the Device Info Result.
558  * A valid response COCO indicates command acceptance and by nature Sensor Identity. */
560  FXLC95000_PART_NUMBER_SIZE, (uint8_t *)&partNumber);
561  partNumber = (partNumber >> 8) | (partNumber << 8);
562  if (ARM_DRIVER_OK != status || partNumber != FXLC95000_PART_NUMBER)
563  {
564  return ADS_FAIL;
565  }
566  return ADS_OK;
567 };
568 
569 /*******************************************************************************
570 * MMA9553 Specific Functions
571 *****************************************************************************/
573 {
574  int32_t status;
575  uint8_t cmdRespHdr[MMA9553_HDR_SIZE] = {0};
576 
577  registerDeviceInfo_t deviceInfo = {
578  .deviceInstance = I2C_S1_DEVICE_INDEX, .functionParam = NULL, .idleFunction = NULL};
579 
580  /* We send the Read Version Info command and validate response. */
582  sizeof(ReadVersionInfo_MMA9553));
583  BOARD_DELAY_ms(1);
584 
585  /* Read the Device Info Result.
586  * A valid response COCO and length fields indicate command acceptance and by nature Sensor Identity. */
587  status = Register_I2C_Read(I2CextDrv, &deviceInfo, MMA9553_I2C_ADDR, 0, sizeof(cmdRespHdr), cmdRespHdr);
588  if (ARM_DRIVER_OK != status || (cmdRespHdr[1] & 0x80) != 0x80 || cmdRespHdr[2] != ReadVersionInfo_MMA9553[3] ||
589  cmdRespHdr[3] != ReadVersionInfo_MMA9553[3])
590  {
591  return ADS_FAIL;
592  }
593  return ADS_OK;
594 };
595 
596 /*******************************************************************************
597  * Functions
598  *****************************************************************************/
600 {
601  int32_t status;
602 
603  /*! Initialize the External I2C driver. */
604  status = I2CextDrv->Initialize(I2C_S1_SIGNAL_EVENT);
605  if (ARM_DRIVER_OK != status)
606  {
607  return ARM_DRIVER_ERROR;
608  }
609 
610  /*! Set the External I2C Power mode. */
611  status = I2CextDrv->PowerControl(ARM_POWER_FULL);
612  if (ARM_DRIVER_OK != status)
613  {
614  return ARM_DRIVER_ERROR;
615  }
616 
617  /*! Set the External I2C bus speed. */
618  status = I2CextDrv->Control(ARM_I2C_BUS_SPEED, ARM_I2C_BUS_SPEED_FAST);
619  if (ARM_DRIVER_OK != status)
620  {
621  return ARM_DRIVER_ERROR;
622  }
623 
624  return status;
625 }
626 
628 {
629  int32_t status;
630 
631  /*! Initialize the SPI driver. */
632  status = SPIdrv->Initialize(SPI_S_SIGNAL_EVENT);
633  if (ARM_DRIVER_OK != status)
634  {
635  return ARM_DRIVER_ERROR;
636  }
637 
638  /*! Set the SPI Power mode. */
639  status = SPIdrv->PowerControl(ARM_POWER_FULL);
640  if (ARM_DRIVER_OK != status)
641  {
642  return ARM_DRIVER_ERROR;
643  }
644 
645  /*! Set the SPI Slave speed. */
646  status = SPIdrv->Control(ARM_SPI_MODE_MASTER | ARM_SPI_CPOL1_CPHA0, SPI_S_BAUDRATE);
647  if (ARM_DRIVER_OK != status)
648  {
649  return ARM_DRIVER_ERROR;
650  }
651 
652  return status;
653 }
654 
656 {
657  int32_t status;
658 
659  /*! De-Initialize the External I2C driver. */
660  status = I2CextDrv->Uninitialize();
661  if (ARM_DRIVER_OK != status)
662  {
663  return ARM_DRIVER_ERROR;
664  }
665 
666  return status;
667 }
668 
670 {
671  int32_t status;
672 
673  /*! De-Initialize the SPI0 driver. */
674  status = SPIdrv->Uninitialize();
675  if (ARM_DRIVER_OK != status)
676  {
677  return ARM_DRIVER_ERROR;
678  }
679 
680  return status;
681 }
682 
683 // Private function to detect Shield.
684 int ADS_DetectShield(char *pShieldString, size_t bufferLength)
685 {
686  int32_t status;
687  uint8_t reg;
688  bool match;
689  uint32_t boardFound = ADS_NO_SHIELD_DETECTED;
690  registerDeviceInfo_t deviceInfo = {0};
691 
692  /* We init SPI bus to test for SPI Sensors. */
693  ADS_InitSPIBus();
694 
695  // Execute the SPI queries based on the ADS_SensorQueryList.
696  for (uint32_t i = 0; i < ADS_QUERY_NUM; i++)
697  {
698  if (ADS_SPI_DEV == ADS_SensorQueryList[i].channel)
699  {
701  if (FXLS8962 == ADS_SensorQueryList[i].slaveAddr)
702  {
704  gADS_QueryResults[i] =
705  ADS_FXLS8962Query(ADS_SensorQueryList[i].whoAmIAddr, ADS_SensorQueryList[i].whoAmIValue);
706  continue;
707  }
708  if (FXLS8471 == ADS_SensorQueryList[i].slaveAddr)
709  {
711  gADS_QueryResults[i] =
712  ADS_FXLS8471Query(ADS_SensorQueryList[i].whoAmIAddr, ADS_SensorQueryList[i].whoAmIValue);
713  continue;
714  }
715  if (DIFF_P == ADS_SensorQueryList[i].slaveAddr)
716  {
718  gADS_QueryResults[i] =
719  ADS_DIFF_PQuery(ADS_SensorQueryList[i].whoAmIAddr, ADS_SensorQueryList[i].whoAmIValue);
720  continue;
721  }
722  }
723  }
724 
725  /* We now disable SPI bus and init I2C buses to test for I2C sensors. */
728 
729  // Execute the Ext I2C queries based on the ADS_SensorQueryList.
730  for (uint32_t i = 0; i < ADS_QUERY_NUM; i++)
731  {
732  if (ADS_I2C_EXT == ADS_SensorQueryList[i].channel)
733  {
735  deviceInfo.deviceInstance = I2C_S1_DEVICE_INDEX;
736  if (FXLC95000 == ADS_SensorQueryList[i].slaveAddr)
737  {
739  continue;
740  }
741  if (MMA9553 == ADS_SensorQueryList[i].slaveAddr)
742  {
744  continue;
745  }
746  status = Register_I2C_Read(I2CextDrv, &deviceInfo, ADS_SensorQueryList[i].slaveAddr,
747  ADS_SensorQueryList[i].whoAmIAddr, 1, &reg);
748  if ((ARM_DRIVER_OK != status) ||
749  ((ADS_SensorQueryList[i].whoAmIValue & ADS_SensorQueryList[i].whoAmIMask) !=
750  (reg & ADS_SensorQueryList[i].whoAmIMask)))
751  {
753  }
754  else
755  {
757  }
758  }
759  }
760 
761  /* I2C Sensor verified, disable I2C buses. */
763 
764  // Analyze the responses and return the Sensor Shield or Reference name.
765  for (uint32_t board = 0; board < ADS_NUM_BOARDS; board++)
766  {
767  match = true;
768  for (uint32_t sensor = 0; sensor < ADS_QUERY_NUM; sensor++)
769  {
770  if (gADS_QueryMap[board][sensor] == ADS_NULL)
771  {
772  continue;
773  }
774  if (gADS_QueryMap[board][sensor] != gADS_QueryResults[sensor])
775  {
776  match = false;
777  break;
778  }
779  }
780  if (match)
781  {
782  boardFound = board;
783  break;
784  }
785  }
786 
787  // If a board was found, then put the proper string into the response.
788  if (boardFound != ADS_NO_SHIELD_DETECTED)
789  {
790  strncpy(pShieldString, ADS_ShieldList[boardFound], bufferLength);
791  status = ARM_DRIVER_OK;
792  }
793  else
794  {
795  status = ARM_DRIVER_ERROR;
796  }
797 
798  return status;
799 }
800 
801 // Private function to detect the MCU.
802 int ADS_DetectLPC(char *pBoardString, size_t bufferLength)
803 {
804  int32_t status;
805 
806  // Declare the DEVID Query structure
807  mcuDEVID_t MCUInfo = {.mcuDeviceId = 0, .board = ADS_NO_BOARD_DETECTED};
808 
809  if (pBoardString == NULL)
810  {
811  return ARM_DRIVER_ERROR_PARAMETER;
812  }
813 
814  uint32_t command[5] = {0}, result[4] = {0};
815 
816  command[0] = kIapCmd_FLASHIAP_ReadPartId;
817  iap_entry(command, result);
818 
819  MCUInfo.mcuDeviceId = result[1];
820  // Compare the values extracted to the static table and return detected board.
821  for (uint8_t i = 0; i < (sizeof(ADS_ValidDEVIDValues) / sizeof(mcuDEVID_t)); i++)
822  {
823  if (MCUInfo.mcuDeviceId == ADS_ValidDEVIDValues[i].mcuDeviceId)
824  {
825  MCUInfo.board = ADS_ValidDEVIDValues[i].board;
826  break;
827  }
828  }
829 
830  status = ARM_DRIVER_OK;
831  // Translate the result into the string.
832  switch (MCUInfo.board)
833  {
834  case ADS_LPC_54113J128:
835  strncpy(pBoardString, "LPCXPRESSO54113J128", bufferLength);
836  break;
837  case ADS_LPC_54113J256:
838  strncpy(pBoardString, "LPCXPRESSO54113J256", bufferLength);
839  break;
840  case ADS_LPC_54114J256:
841  strncpy(pBoardString, "LPCXPRESSO54114J256", bufferLength);
842  break;
843  default:
844  status = ARM_DRIVER_ERROR;
845  break;
846  }
847 
848  return status;
849 }
850 
851 // Private function to compare flash contents.
853 {
854  ADSFlashRecord_t flashRecord = {0};
855  uint32_t status;
856 
857  flashRecord.cookie = ADS_COOKIE_VALUE;
858  status = FLASHIAP_Compare(ADS_NVM_ADDR, (uint32_t *)&flashRecord.cookie, sizeof(flashRecord.cookie));
859  // Check that the ADS_COOKIE is as expected.
860  if (kStatus_FLASHIAP_Success != status)
861  {
862  return ADS_NO_FLASH_RECORD; // Flash record is not valid.
863  }
864  else
865  { // Compare the result string with the ADS stored results in Flash.
866  flashRecord.length = strlen(pResultString);
867  strcpy(flashRecord.ADSString, pResultString);
868  status = FLASHIAP_Compare(ADS_NVM_ADDR, (uint32_t *)&flashRecord, sizeof(flashRecord));
869  if (kStatus_FLASHIAP_Success != status)
870  {
872  }
873  else
874  {
876  }
877  }
878 }
879 
880 // Private function to update flash contents.
881 ADS_Status_t ADS_FlashUpdate(char *pResultString)
882 {
883  status_t result;
884  ADS_Status_t retVal = ADS_FAIL;
885  ADSFlashRecord_t flashRecord = {0};
886 
887  // Create the ADS Flash Record.
888  flashRecord.cookie = ADS_COOKIE_VALUE;
889  flashRecord.length = strlen(pResultString);
890  strcpy(flashRecord.ADSString, pResultString);
891 
892  // Setup flash for write.
893  result = FLASHIAP_PrepareSectorForWrite(ADS_NVM_SECTOR_NUM, ADS_NVM_SECTOR_NUM);
894  if (kStatus_FLASHIAP_Success == result)
895  { // Erase the target sector.
896  result = FLASHIAP_EraseSector(ADS_NVM_SECTOR_NUM, ADS_NVM_SECTOR_NUM, SystemCoreClock);
897  if (kStatus_FLASHIAP_Success == result)
898  { // Setup flash for write.
899  result = FLASHIAP_PrepareSectorForWrite(ADS_NVM_SECTOR_NUM, ADS_NVM_SECTOR_NUM);
900  if (kStatus_FLASHIAP_Success == result)
901  { /* Write the ADS Record to the Flash.
902  * Note: Flash write needs to be 32-bit word aligned in length and in multiples of page size. */
903  result = FLASHIAP_CopyRamToFlash(ADS_NVM_ADDR, (uint32_t *)&flashRecord,
904  FSL_FEATURE_SYSCON_FLASH_PAGE_SIZE_BYTES, SystemCoreClock);
905  if (kStatus_FLASHIAP_Success == result)
906  {
907  retVal = ADS_OK;
908  }
909  }
910  }
911  }
912 
913  return retVal;
914 }
915 
916 // API to register Application Name and trigger Board Shield detection.
917 void BOARD_RunADS(const char *appName, char *boardString, char *shieldString, size_t bufferLength)
918 {
919  int32_t position, status = ADS_OK;
920  char finalString[ADS_FLASH_STRING_LENGTH] = {0};
921 
922  status = ADS_DetectLPC(boardString, bufferLength);
923  if (ARM_DRIVER_ERROR == status)
924  {
925  strncpy(boardString, "NotDetected", bufferLength);
926  status = ADS_FAIL;
927  }
928 
929  status = ADS_DetectShield(shieldString, bufferLength);
930  if (ARM_DRIVER_ERROR == status)
931  {
932  strncpy(shieldString, "NotDetected", bufferLength);
933  status = ADS_FAIL;
934  }
935 
936  // Build the string with App Name and Shield Name to write to flash.
937  strncpy(finalString, appName, ADS_FLASH_STRING_LENGTH);
938  position = strlen(appName);
939 
940  finalString[position++] = ':';
941 
942  strncpy(&finalString[position], shieldString, ADS_FLASH_STRING_LENGTH - position);
943  position += strlen(shieldString);
944 
945  /* Fill the remaining string with 0. */
946  memset(&finalString[position], 0, ADS_FLASH_STRING_LENGTH - position);
947 
948  status = ADS_FlashCompare(finalString);
949  if (ADS_FLASH_RECORD_NO_CHANGE != status)
950  {
951  ADS_FlashUpdate(finalString);
952  strcpy(finalString, shieldString);
953  snprintf(shieldString, bufferLength, "Changed:%s", finalString);
954  }
955 }
#define MMA9553_HDR_SIZE
Size of fixed header bytes in sensor commands.
Definition: mma9553.h:14
int ADS_InitI2CBuses()
void(* set_pin)(pinID_t aPinId)
Definition: Driver_GPIO.h:46
void ADS_FXLS8962_SPI_ReadPreprocess(void *pCmdOut, uint32_t offset, uint32_t size)
uint32_t size
#define FXAS21002_WHO_AM_I_WHOAMI_PROD_VALUE
Definition: fxas21002.h:402
char ADSString[ADS_FLASH_STRING_LENGTH]
#define DIFF_P_SPI_CS
#define FXLS8471_SPI_CS
#define ADS_NUM_BOARDS
This structure defines the device specific info required by register I/O.
Definition: sensor_drv.h:102
#define ADS_NVM_SECTOR_NUM
void ADS_FXLS8962_SPI_WritePreprocess(void *pCmdOut, uint32_t offset, uint32_t size, void *pWritebuffer)
int32_t status
The fxls8471q.h file contains the register definitions for fxls8471q sensor driver.
GENERIC_DRIVER_GPIO * pGPIODriver
int ADS_DeInitI2CBuses()
#define I2C_S1_DEVICE_INDEX
Definition: frdm_k64f.h:66
int32_t Register_I2C_Read(ARM_DRIVER_I2C *pCommDrv, registerDeviceInfo_t *devInfo, uint16_t slaveAddress, uint8_t offset, uint8_t length, uint8_t *pOutBuffer)
The interface function to read a sensor register.
void ADS_FXLS8471Q_SPI_WritePreprocess(void *pCmdOut, uint32_t offset, uint32_t size, void *pWritebuffer)
#define MAG3110_I2C_ADDR
void BOARD_DELAY_ms(uint32_t delay_ms)
Function to insert delays.
Definition: systick_utils.c:81
void ADS_InitSPI_DIFF_P()
ADS_Status_t ADS_FXLC95000Query()
#define FXOS8700_WHO_AM_I_PROD_VALUE
Definition: fxos8700.h:146
char shieldString[ADS_MAX_STRING_LENGTH]
The register_io_spi.h file declares low-level interface functions for reading and writing sensor regi...
uint8_t spiRead_DataBuffer[SPI_MAX_MSG_SIZE]
#define ADS_NO_WHO_AM_I
This structure defines the spi slave command format.
#define FXLC95000_PART_NUMBER_OFFSET
Offset of 2-Byte SA95000 Part Number in Device Info Response.
Definition: fxlc95000.h:30
const uint8_t ReadVersionInfo_MMA9553[4]
The Read Version Info Command for FXLC95000.
Access structure of the GPIO Driver.
Definition: Driver_GPIO.h:38
#define FXLC95000_I2C_ADDR
#define ADS_FLASH_STRING_LENGTH
ADS_Status_t ADS_FXLS8471Query(uint8_t whoAmiAddr, uint8_t whoAmi)
#define SPI_SS_ACTIVE_LOW
ADS_FlashStatus_t
This enumeration defines the ADS Flash storage status.
This defines a record type to store ADS results string in Flash memory.
int ADS_DetectShield(char *pShieldString, size_t bufferLength)
#define DIFF_P_SPI_CMD_LEN
These variables are specific to SPI access to the DIFF_P for ADS.
uint8_t spiRead_CmdBuffer[SPI_MAX_MSG_SIZE]
#define FXLS8471Q_WHO_AM_I_WHOAMI_VALUE
Definition: fxls8471q.h:512
void(* clr_pin)(pinID_t aPinId)
Definition: Driver_GPIO.h:47
typedef int32_t(DATA_FORMAT_Append_t))(void *pData
The interface function to append the data on the formated stream.
#define SPI_S_BAUDRATE
Transfer baudrate - 500k.
Definition: frdm_k64f.h:88
uint8_t spiWrite_CmdDataBuffer[SPI_MAX_MSG_SIZE]
#define SPI_S_DEVICE_INDEX
Definition: frdm_k64f.h:89
void ADS_DIFF_P_SPI_WritePreprocess(void *pCmdOut, uint32_t offset, uint32_t size, void *pWritebuffer)
const ADS_Status_t gADS_QueryMap[][ADS_QUERY_NUM]
These are the expected query signatures for the shield boards.
The register_io_i2c.h file declares low-level interface functions for reading and writing sensor regi...
#define DIFF_P_SS_ACTIVE_VALUE
ARM_DRIVER_SPI * SPIdrv
These values hold the ARM CMSIS Driver interface pointers.
This defines a record type to store the communication channel info and WHO_AM_I address/value for var...
#define MMA9553_I2C_ADDR
#define SPI_MAX_MSG_SIZE
fpSpiReadPreprocessFn_t pReadPreprocessFN
The fxas21002.h contains the fxas21002 sensor register definitions and its bit mask.
The SPI Slave Transfer Command Params SDK2.0 Driver.
int ADS_InitSPIBus()
GENERIC_DRIVER_GPIO Driver_GPIO_KSDK
Definition: gpio_driver.c:177
#define FXAS21002_I2C_ADDR
#define ADS_NVM_ADDR
start of the next to last 4K (sector size) of the 1M flash
Definition: frdm_k64f.h:148
int ADS_DetectLPC(char *pBoardString, size_t bufferLength)
#define I2C_S1_DRIVER
Definition: frdm_k64f.h:65
void BOARD_RunADS(const char *appName, char *boardString, char *shieldString, size_t bufferLength)
The function to register Application Name and initialte ADS.
#define ADS_COOKIE_VALUE
#define FXLS8471Q_SS_ACTIVE_VALUE
spiSlaveSpecificParams_t spiParams_8962
#define ADS_NO_SHIELD_DETECTED
ADS_SupportedBoards_t board
void ADS_InitSPI_FXLS8471()
#define DIFF_P_I2C_ADDR
ADS_Status_t ADS_DIFF_PQuery(uint8_t whoAmiAddr, uint8_t whoAmi)
#define FXLS8962_SPI_CMD_LEN
These variables are specific to SPI access to the FXLS8962 for ADS.
#define I2C_S1_SIGNAL_EVENT
Definition: frdm_k64f.h:67
ADS_Status_t ADS_FlashUpdate(char *pResultString)
ADS_Status_t gADS_QueryResults[ADS_QUERY_NUM]
This global contains the results from the sensor query.
int32_t Register_I2C_BlockWrite(ARM_DRIVER_I2C *pCommDrv, registerDeviceInfo_t *devInfo, uint16_t slaveAddress, uint8_t offset, const uint8_t *pBuffer, uint8_t bytesToWrite)
The interface function to write a sensor register.
#define ADS_MAX_STRING_LENGTH
#define FXLC95000_PART_NUMBER_SIZE
The FXLC95000 Size of Part Number.
Definition: fxlc95000.h:33
void ADS_FXLS8471Q_SPI_ReadPreprocess(void *pCmdOut, uint32_t offset, uint32_t size)
#define FXPQ3115_WHOAMI_VALUE
Definition: fxpq3115.h:65
spiSlaveSpecificParams_t spiParams_8471
#define MPL3115_WHOAMI_VALUE
Definition: mpl3115.h:65
char boardString[ADS_MAX_STRING_LENGTH]
ADS_Status_t ADS_MMA9553Query()
#define FXLC95000_PART_NUMBER
The FXLC95000 2-byte packed BCD encoded Part Number (BCD for Last 4 characters).
Definition: fxlc95000.h:36
fpSpiWritePreprocessFn_t pWritePreprocessFN
The auto_detection_shield.h file describes the definitions for Sensor I2C and SPI parameters required...
#define FXLS8471Q_SPI_CMD_LEN
These variables are specific to SPI access to the FXLS8471 for ADS.
void(* pin_init)(pinID_t aPinId, gpio_direction_t dir, void *apPinConfig, gpio_isr_handler_t aIsrHandler, void *apUserData)
Definition: Driver_GPIO.h:41
uint32_t SystemCoreClock
const sensorAccess_t ADS_SensorQueryList[]
This constant data structure contains the expected valid comm/sensor/who_am_i combinations.
#define MMA8652_I2C_ADDR
ARM Systick Utilities.
#define MAG3110_WHOAMI_VALUE
Definition: mag3110.h:37
#define FXPQ3115_I2C_ADDR
ARM_DRIVER_I2C * I2CextDrv
#define SPI_S_DRIVER
Definition: frdm_k64f.h:87
void ADS_DIFF_P_SPI_ReadPreprocess(void *pCmdOut, uint32_t offset, uint32_t size)
spiSlaveSpecificParams_t spiParams_diff_p
enum ADS_Status ADS_Status_t
This defines the return status.
#define SPI_S_SIGNAL_EVENT
Definition: frdm_k64f.h:90
#define MPL3115_I2C_ADDR
This file contains the FXLS8962 Accelerometer register definitions, access macros, and device access functions.
#define FXLS8962_I2C_ADDR
The fxos8700.h file contains the register definitions for FXOS8700 sensor driver. ...
#define FXLS8962_WHOAMI_VALUE
Definition: fxls8962.h:87
#define MMA8652_WHOAMI_VALUE
Definition: mma865x.h:65
#define FXLS8962_CS
#define FXOS8700_I2C_ADDR
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.
void ADS_InitSPI_FXLS8962()
const mcuDEVID_t ADS_ValidDEVIDValues[]
This constant data structure contains the expected valid MCU Device ID combinations. Refer : LPC5411x User manual - UM10914, Section: 33.5.12.
ADS_Status_t ADS_FXLS8962Query(uint8_t whoAmiAddr, uint8_t whoAmi)
ADS_FlashStatus_t ADS_FlashCompare(char *pResultString)
#define FXLS8962_SS_ACTIVE_VALUE
int ADS_DeInitSPIBus()
This defines a record type to store the expected field values of the LPC device ID.
char ADS_ShieldList[][ADS_MAX_STRING_LENGTH]
#define ADS_QUERY_NUM