SDMP_IOT / Mbed OS AdiSense1000_SmartBabySeat

Fork of Babyseat_NewFirmware_copy_sean by Ross O'Halloran

Committer:
kevin1990
Date:
Fri Aug 25 11:17:37 2017 +0000
Revision:
2:625a45555a85
Child:
3:3796776e2c27
Sensor Channel 0 Type K example

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kevin1990 2:625a45555a85 1 /*!
kevin1990 2:625a45555a85 2 ******************************************************************************
kevin1990 2:625a45555a85 3 * @file: spi_nucleo.cpp
kevin1990 2:625a45555a85 4 * @brief: ADISense1000 OS Dependant wrapper layer for spi
kevin1990 2:625a45555a85 5 *-----------------------------------------------------------------------------
kevin1990 2:625a45555a85 6 *
kevin1990 2:625a45555a85 7 Copyright (c) 2017 Emutex Ltd. / Analog Devices, Inc.
kevin1990 2:625a45555a85 8
kevin1990 2:625a45555a85 9 All rights reserved.
kevin1990 2:625a45555a85 10
kevin1990 2:625a45555a85 11 Redistribution and use in source and binary forms, with or without modification,
kevin1990 2:625a45555a85 12 are permitted provided that the following conditions are met:
kevin1990 2:625a45555a85 13 - Redistributions of source code must retain the above copyright notice,
kevin1990 2:625a45555a85 14 this list of conditions and the following disclaimer.
kevin1990 2:625a45555a85 15 - Redistributions in binary form must reproduce the above copyright notice,
kevin1990 2:625a45555a85 16 this list of conditions and the following disclaimer in the documentation
kevin1990 2:625a45555a85 17 and/or other materials provided with the distribution.
kevin1990 2:625a45555a85 18 - Modified versions of the software must be conspicuously marked as such.
kevin1990 2:625a45555a85 19 - This software is licensed solely and exclusively for use with processors
kevin1990 2:625a45555a85 20 manufactured by or for Analog Devices, Inc.
kevin1990 2:625a45555a85 21 - This software may not be combined or merged with other code in any manner
kevin1990 2:625a45555a85 22 that would cause the software to become subject to terms and conditions
kevin1990 2:625a45555a85 23 which differ from those listed here.
kevin1990 2:625a45555a85 24 - Neither the name of Analog Devices, Inc. nor the names of its
kevin1990 2:625a45555a85 25 contributors may be used to endorse or promote products derived
kevin1990 2:625a45555a85 26 from this software without specific prior written permission.
kevin1990 2:625a45555a85 27 - The use of this software may or may not infringe the patent rights of one
kevin1990 2:625a45555a85 28 or more patent holders. This license does not release you from the
kevin1990 2:625a45555a85 29 requirement that you obtain separate licenses from these patent holders
kevin1990 2:625a45555a85 30 to use this software.
kevin1990 2:625a45555a85 31
kevin1990 2:625a45555a85 32 THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES, INC. AND CONTRIBUTORS "AS IS" AND ANY
kevin1990 2:625a45555a85 33 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
kevin1990 2:625a45555a85 34 TITLE, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
kevin1990 2:625a45555a85 35 NO EVENT SHALL ANALOG DEVICES, INC. OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
kevin1990 2:625a45555a85 36 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, PUNITIVE OR CONSEQUENTIAL DAMAGES
kevin1990 2:625a45555a85 37 (INCLUDING, BUT NOT LIMITED TO, DAMAGES ARISING OUT OF CLAIMS OF INTELLECTUAL
kevin1990 2:625a45555a85 38 PROPERTY RIGHTS INFRINGEMENT; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
kevin1990 2:625a45555a85 39 OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
kevin1990 2:625a45555a85 40 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
kevin1990 2:625a45555a85 41 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
kevin1990 2:625a45555a85 42 EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
kevin1990 2:625a45555a85 43 *
kevin1990 2:625a45555a85 44 *****************************************************************************/
kevin1990 2:625a45555a85 45 /******************************************************************************/
kevin1990 2:625a45555a85 46 /* Include Files */
kevin1990 2:625a45555a85 47 /******************************************************************************/
kevin1990 2:625a45555a85 48 #include "inc/spi_nucleo.h"
kevin1990 2:625a45555a85 49
kevin1990 2:625a45555a85 50 #define BUFFER_SIZE 256
kevin1990 2:625a45555a85 51 #define CMD_BIT 7
kevin1990 2:625a45555a85 52
kevin1990 2:625a45555a85 53 #define SPI_MODE_0 0
kevin1990 2:625a45555a85 54 #define SPI_FRAME_SIZE_8 8
kevin1990 2:625a45555a85 55 #define SPI_CLOCK_FREQUENCY_700KHZ 700000
kevin1990 2:625a45555a85 56 #define DEVICE_SPI_ASYNCH 1
kevin1990 2:625a45555a85 57 #define TIMEOUT_3_SEC 3.0
kevin1990 2:625a45555a85 58
kevin1990 2:625a45555a85 59 // DummyByte config defines
kevin1990 2:625a45555a85 60 #define SPI_CHIP_TYPE_ADDR 0x03
kevin1990 2:625a45555a85 61 #define SPI_CHIP_TYPE_VALUE 0x07
kevin1990 2:625a45555a85 62 #define READ_CMD 0x00
kevin1990 2:625a45555a85 63 #define MAX_SYNC_ATTEMPTS 50
kevin1990 2:625a45555a85 64 #define DUMMY_BYTE_COUNT 1
kevin1990 2:625a45555a85 65
kevin1990 2:625a45555a85 66 #define CHECK_BIT(var, pos) ((var) & (1 << (pos)))
kevin1990 2:625a45555a85 67
kevin1990 2:625a45555a85 68 SPI spi(SPI_MOSI, SPI_MISO, SPI_SCK);
kevin1990 2:625a45555a85 69 DigitalOut chipSel(D10, 1);
kevin1990 2:625a45555a85 70
kevin1990 2:625a45555a85 71 event_callback_t callbck;
kevin1990 2:625a45555a85 72 Timer timeout;
kevin1990 2:625a45555a85 73
kevin1990 2:625a45555a85 74 volatile int intType;
kevin1990 2:625a45555a85 75 volatile bool cbkFired;
kevin1990 2:625a45555a85 76
kevin1990 2:625a45555a85 77 static uint8_t rxBuff[BUFFER_SIZE];
kevin1990 2:625a45555a85 78
kevin1990 2:625a45555a85 79 void callbackFired(int event)
kevin1990 2:625a45555a85 80 {
kevin1990 2:625a45555a85 81 cbkFired = true;
kevin1990 2:625a45555a85 82 intType = event;
kevin1990 2:625a45555a85 83 }
kevin1990 2:625a45555a85 84
kevin1990 2:625a45555a85 85 static int transferComplete()
kevin1990 2:625a45555a85 86 {
kevin1990 2:625a45555a85 87 int rc = 0;
kevin1990 2:625a45555a85 88
kevin1990 2:625a45555a85 89 timeout.start();
kevin1990 2:625a45555a85 90 while ((cbkFired != true) && (intType != SPI_EVENT_COMPLETE))
kevin1990 2:625a45555a85 91 {
kevin1990 2:625a45555a85 92 if (timeout.read() > TIMEOUT_3_SEC)
kevin1990 2:625a45555a85 93 {
kevin1990 2:625a45555a85 94 rc = -1;
kevin1990 2:625a45555a85 95 break;
kevin1990 2:625a45555a85 96 }
kevin1990 2:625a45555a85 97 }
kevin1990 2:625a45555a85 98 timeout.stop();
kevin1990 2:625a45555a85 99
kevin1990 2:625a45555a85 100 cbkFired = false;
kevin1990 2:625a45555a85 101 intType = 0;
kevin1990 2:625a45555a85 102
kevin1990 2:625a45555a85 103 return rc;
kevin1990 2:625a45555a85 104 }
kevin1990 2:625a45555a85 105
kevin1990 2:625a45555a85 106 static int spiWrite(uint8_t *data, uint8_t txSize, bool bCsHold)
kevin1990 2:625a45555a85 107 {
kevin1990 2:625a45555a85 108 int rc;
kevin1990 2:625a45555a85 109
kevin1990 2:625a45555a85 110 // Assert chip select
kevin1990 2:625a45555a85 111 if (!bCsHold)
kevin1990 2:625a45555a85 112 {
kevin1990 2:625a45555a85 113 chipSel = 0;
kevin1990 2:625a45555a85 114 }
kevin1990 2:625a45555a85 115
kevin1990 2:625a45555a85 116 rc = spi.transfer(data, txSize, (uint8_t *)NULL, 0,
kevin1990 2:625a45555a85 117 callbck, SPI_EVENT_COMPLETE);
kevin1990 2:625a45555a85 118
kevin1990 2:625a45555a85 119 rc = transferComplete();
kevin1990 2:625a45555a85 120
kevin1990 2:625a45555a85 121 // De assert chip select
kevin1990 2:625a45555a85 122 if (!bCsHold)
kevin1990 2:625a45555a85 123 {
kevin1990 2:625a45555a85 124 chipSel = 1;
kevin1990 2:625a45555a85 125 }
kevin1990 2:625a45555a85 126
kevin1990 2:625a45555a85 127 return rc;
kevin1990 2:625a45555a85 128 }
kevin1990 2:625a45555a85 129
kevin1990 2:625a45555a85 130 static int spiRead(uint8_t *data, uint16_t rxSize, bool bCsHold)
kevin1990 2:625a45555a85 131 {
kevin1990 2:625a45555a85 132 int rc;
kevin1990 2:625a45555a85 133
kevin1990 2:625a45555a85 134 // Assert chip select
kevin1990 2:625a45555a85 135 chipSel = 0;
kevin1990 2:625a45555a85 136
kevin1990 2:625a45555a85 137 // Send read command address
kevin1990 2:625a45555a85 138 rc = spi.transfer(data, REG_CMD_SIZE, (uint8_t *)NULL, 0,
kevin1990 2:625a45555a85 139 callbck, SPI_EVENT_COMPLETE);
kevin1990 2:625a45555a85 140
kevin1990 2:625a45555a85 141 rc = transferComplete();
kevin1990 2:625a45555a85 142
kevin1990 2:625a45555a85 143 if (rc < 0)
kevin1990 2:625a45555a85 144 {
kevin1990 2:625a45555a85 145 chipSel = 1;
kevin1990 2:625a45555a85 146 return rc;
kevin1990 2:625a45555a85 147 }
kevin1990 2:625a45555a85 148
kevin1990 2:625a45555a85 149 for (int i = 0; i < DUMMY_BYTE_COUNT; i++) {
kevin1990 2:625a45555a85 150 rc = spi.write(0);
kevin1990 2:625a45555a85 151 }
kevin1990 2:625a45555a85 152
kevin1990 2:625a45555a85 153 // Retrieve data from slave
kevin1990 2:625a45555a85 154 rc = spi.transfer((uint8_t *)NULL, rxSize, rxBuff, rxSize,
kevin1990 2:625a45555a85 155 callbck, SPI_EVENT_COMPLETE);
kevin1990 2:625a45555a85 156
kevin1990 2:625a45555a85 157 rc = transferComplete();
kevin1990 2:625a45555a85 158
kevin1990 2:625a45555a85 159 if (rc < 0)
kevin1990 2:625a45555a85 160 {
kevin1990 2:625a45555a85 161 chipSel = 1;
kevin1990 2:625a45555a85 162 return rc;
kevin1990 2:625a45555a85 163 }
kevin1990 2:625a45555a85 164
kevin1990 2:625a45555a85 165 // De assert chip select
kevin1990 2:625a45555a85 166 if (!bCsHold)
kevin1990 2:625a45555a85 167 {
kevin1990 2:625a45555a85 168 chipSel = 1;
kevin1990 2:625a45555a85 169 }
kevin1990 2:625a45555a85 170
kevin1990 2:625a45555a85 171 return rc;
kevin1990 2:625a45555a85 172 }
kevin1990 2:625a45555a85 173
kevin1990 2:625a45555a85 174 static int syncWithAdisense1000()
kevin1990 2:625a45555a85 175 {
kevin1990 2:625a45555a85 176 uint8_t txBuff[20];
kevin1990 2:625a45555a85 177 uint8_t nRxLen = 1;
kevin1990 2:625a45555a85 178 bool bCsHoldOff = false;
kevin1990 2:625a45555a85 179 uint16_t nAttempts = 0;
kevin1990 2:625a45555a85 180
kevin1990 2:625a45555a85 181 memset(txBuff, 0, sizeof(txBuff));
kevin1990 2:625a45555a85 182
kevin1990 2:625a45555a85 183 txBuff[0] = READ_CMD;
kevin1990 2:625a45555a85 184 txBuff[1] = SPI_CHIP_TYPE_ADDR;
kevin1990 2:625a45555a85 185
kevin1990 2:625a45555a85 186 while (rxBuff[0] != SPI_CHIP_TYPE_VALUE)
kevin1990 2:625a45555a85 187 {
kevin1990 2:625a45555a85 188 if(spiRead(txBuff, nRxLen, bCsHoldOff) < 0)
kevin1990 2:625a45555a85 189 {
kevin1990 2:625a45555a85 190 return -1;
kevin1990 2:625a45555a85 191 }
kevin1990 2:625a45555a85 192
kevin1990 2:625a45555a85 193 if (nAttempts >= MAX_SYNC_ATTEMPTS)
kevin1990 2:625a45555a85 194 {
kevin1990 2:625a45555a85 195 return -1;
kevin1990 2:625a45555a85 196 }
kevin1990 2:625a45555a85 197
kevin1990 2:625a45555a85 198 nAttempts++;
kevin1990 2:625a45555a85 199 wait_ms(100);
kevin1990 2:625a45555a85 200 }
kevin1990 2:625a45555a85 201 /* TODO: Reminder not to forget about the following routine which was previously
kevin1990 2:625a45555a85 202 used: Not valid currently as we are hardcoding the dummy byte count
kevin1990 2:625a45555a85 203 This is a temporary fix until we have a defined spi protocall.
kevin1990 2:625a45555a85 204 This function reads the spi chip type (fixed value) and determines how many
kevin1990 2:625a45555a85 205 dummy bytes need to be sent in a spi read transaction.
kevin1990 2:625a45555a85 206 The dummy bytes varies depending on clock speed, debug/release build on
kevin1990 2:625a45555a85 207 adisense, and will keep varying as the code grows. So this elimantes the need
kevin1990 2:625a45555a85 208 to manually modify the dummy bytes.
kevin1990 2:625a45555a85 209 */
kevin1990 2:625a45555a85 210
kevin1990 2:625a45555a85 211 return 0;
kevin1990 2:625a45555a85 212 }
kevin1990 2:625a45555a85 213
kevin1990 2:625a45555a85 214 /*!
kevin1990 2:625a45555a85 215 * @brief Register a new spi connection
kevin1990 2:625a45555a85 216 *
kevin1990 2:625a45555a85 217 * @param[in] spiConfig spi settings for connection
kevin1990 2:625a45555a85 218 *
kevin1990 2:625a45555a85 219 * @return Status
kevin1990 2:625a45555a85 220 * - #ADI_SENSE_SUCCESS Call completed successfully.
kevin1990 2:625a45555a85 221 * - todo
kevin1990 2:625a45555a85 222 *
kevin1990 2:625a45555a85 223 */
kevin1990 2:625a45555a85 224 ADI_SENSE_RESULT ADISense1000_HostSpiOpen(spiSettings spiConfig)
kevin1990 2:625a45555a85 225 {
kevin1990 2:625a45555a85 226 /*
kevin1990 2:625a45555a85 227 For v0.1 we are using the mbed api.
kevin1990 2:625a45555a85 228 The digital classes are declared globally.
kevin1990 2:625a45555a85 229 Parameters are placeholders for future revisions.
kevin1990 2:625a45555a85 230 */
kevin1990 2:625a45555a85 231
kevin1990 2:625a45555a85 232 cbkFired = false;
kevin1990 2:625a45555a85 233 intType = 0;
kevin1990 2:625a45555a85 234
kevin1990 2:625a45555a85 235 callbck.attach(callbackFired);
kevin1990 2:625a45555a85 236
kevin1990 2:625a45555a85 237 spi.format(SPI_FRAME_SIZE_8, SPI_MODE_0);
kevin1990 2:625a45555a85 238 spi.frequency(SPI_CLOCK_FREQUENCY_700KHZ);
kevin1990 2:625a45555a85 239
kevin1990 2:625a45555a85 240 if (syncWithAdisense1000() != ADI_SENSE_SUCCESS)
kevin1990 2:625a45555a85 241 return ADI_SENSE_FAILURE;
kevin1990 2:625a45555a85 242
kevin1990 2:625a45555a85 243 return ADI_SENSE_SUCCESS;
kevin1990 2:625a45555a85 244 }
kevin1990 2:625a45555a85 245
kevin1990 2:625a45555a85 246 /*!
kevin1990 2:625a45555a85 247 * @brief Transfer data to slave device
kevin1990 2:625a45555a85 248 *
kevin1990 2:625a45555a85 249 * @param[in] pData array with transfer data
kevin1990 2:625a45555a85 250 * @param[in] nTxLen number of bytes to transfer
kevin1990 2:625a45555a85 251 * @param[in] bCsHold keep cs high/low after transfer
kevin1990 2:625a45555a85 252 *
kevin1990 2:625a45555a85 253 * @return Status
kevin1990 2:625a45555a85 254 * - #ADI_SENSE_SUCCESS Call completed successfully.
kevin1990 2:625a45555a85 255 * - todo
kevin1990 2:625a45555a85 256 *
kevin1990 2:625a45555a85 257 */
kevin1990 2:625a45555a85 258 ADI_SENSE_RESULT
kevin1990 2:625a45555a85 259 ADISense1000_HostSpiTransfer(uint8_t *pData, uint16_t nTxLen, bool bCsHold)
kevin1990 2:625a45555a85 260 {
kevin1990 2:625a45555a85 261 int txWrite = CHECK_BIT(pData[0], CMD_BIT);
kevin1990 2:625a45555a85 262
kevin1990 2:625a45555a85 263 if (txWrite)
kevin1990 2:625a45555a85 264 {
kevin1990 2:625a45555a85 265 if (spiWrite(pData, nTxLen, bCsHold) < 0)
kevin1990 2:625a45555a85 266 return ADI_SENSE_FAILURE;
kevin1990 2:625a45555a85 267 else
kevin1990 2:625a45555a85 268 return ADI_SENSE_SUCCESS;
kevin1990 2:625a45555a85 269 }
kevin1990 2:625a45555a85 270
kevin1990 2:625a45555a85 271 if(spiRead(pData, nTxLen, bCsHold) < 0)
kevin1990 2:625a45555a85 272 return ADI_SENSE_FAILURE;
kevin1990 2:625a45555a85 273
kevin1990 2:625a45555a85 274 memcpy(pData, rxBuff, nTxLen);
kevin1990 2:625a45555a85 275
kevin1990 2:625a45555a85 276 return ADI_SENSE_SUCCESS;
kevin1990 2:625a45555a85 277 }
kevin1990 2:625a45555a85 278
kevin1990 2:625a45555a85 279
kevin1990 2:625a45555a85 280 /*!
kevin1990 2:625a45555a85 281 * @brief Close spi connection
kevin1990 2:625a45555a85 282 *
kevin1990 2:625a45555a85 283 * @param[in]
kevin1990 2:625a45555a85 284 *
kevin1990 2:625a45555a85 285 * @return Status
kevin1990 2:625a45555a85 286 * - #ADI_SENSE_SUCCESS Call completed successfully.
kevin1990 2:625a45555a85 287 * - todo
kevin1990 2:625a45555a85 288 *
kevin1990 2:625a45555a85 289 */
kevin1990 2:625a45555a85 290 ADI_SENSE_RESULT ADISense1000_HostSpiClose()
kevin1990 2:625a45555a85 291 {
kevin1990 2:625a45555a85 292 return ADI_SENSE_SUCCESS;
kevin1990 2:625a45555a85 293 }
kevin1990 2:625a45555a85 294 /**
kevin1990 2:625a45555a85 295 * @}
kevin1990 2:625a45555a85 296 */
kevin1990 2:625a45555a85 297