SDMP_IOT / Mbed OS AdiSense1000_SmartBabySeat

Fork of Babyseat_NewFirmware_copy_sean by Ross O'Halloran

Revision:
2:625a45555a85
Child:
3:3796776e2c27
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/spi_nucleo.cpp	Fri Aug 25 11:17:37 2017 +0000
@@ -0,0 +1,297 @@
+/*!
+ ******************************************************************************
+ * @file:   spi_nucleo.cpp
+ * @brief:  ADISense1000 OS Dependant wrapper layer for spi
+ *-----------------------------------------------------------------------------
+ *
+ Copyright (c) 2017 Emutex Ltd. / Analog Devices, Inc.
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification,
+ are permitted provided that the following conditions are met:
+ - Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ - Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ - Modified versions of the software must be conspicuously marked as such.
+ - This software is licensed solely and exclusively for use with processors
+ manufactured by or for Analog Devices, Inc.
+ - This software may not be combined or merged with other code in any manner
+ that would cause the software to become subject to terms and conditions
+ which differ from those listed here.
+ - Neither the name of Analog Devices, Inc. nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+ - The use of this software may or may not infringe the patent rights of one
+ or more patent holders.  This license does not release you from the
+ requirement that you obtain separate licenses from these patent holders
+ to use this software.
+
+ THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES, INC. AND CONTRIBUTORS "AS IS" AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
+ TITLE, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ NO EVENT SHALL ANALOG DEVICES, INC. OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, PUNITIVE OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, DAMAGES ARISING OUT OF CLAIMS OF INTELLECTUAL
+ PROPERTY RIGHTS INFRINGEMENT; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *****************************************************************************/
+/******************************************************************************/
+/* Include Files                                                              */
+/******************************************************************************/
+#include "inc/spi_nucleo.h"
+
+#define BUFFER_SIZE 256
+#define CMD_BIT 7
+
+#define SPI_MODE_0 0
+#define SPI_FRAME_SIZE_8 8
+#define SPI_CLOCK_FREQUENCY_700KHZ 700000
+#define DEVICE_SPI_ASYNCH 1
+#define TIMEOUT_3_SEC 3.0
+
+// DummyByte config defines
+#define SPI_CHIP_TYPE_ADDR 0x03
+#define SPI_CHIP_TYPE_VALUE 0x07
+#define READ_CMD 0x00
+#define MAX_SYNC_ATTEMPTS 50
+#define DUMMY_BYTE_COUNT 1
+
+#define CHECK_BIT(var, pos) ((var) & (1 << (pos)))
+
+SPI spi(SPI_MOSI, SPI_MISO, SPI_SCK);
+DigitalOut chipSel(D10, 1);
+
+event_callback_t callbck;
+Timer timeout;
+
+volatile int intType;
+volatile bool cbkFired;
+
+static uint8_t rxBuff[BUFFER_SIZE];
+
+void callbackFired(int event)
+{
+    cbkFired = true;
+    intType = event;
+}
+
+static int transferComplete()
+{
+    int rc = 0;
+
+    timeout.start();
+    while ((cbkFired != true) && (intType != SPI_EVENT_COMPLETE))
+    {
+        if (timeout.read() >  TIMEOUT_3_SEC)
+        {
+            rc = -1;
+            break;
+        }
+    }
+    timeout.stop();
+
+    cbkFired = false;
+    intType = 0;
+
+    return rc;
+}
+
+static int spiWrite(uint8_t *data, uint8_t txSize, bool bCsHold)
+{
+    int rc;
+
+    // Assert chip select
+    if (!bCsHold)
+    {
+        chipSel = 0;
+    }
+
+    rc  = spi.transfer(data, txSize, (uint8_t *)NULL, 0,
+                       callbck, SPI_EVENT_COMPLETE);
+
+    rc = transferComplete();
+
+    // De assert chip select
+    if (!bCsHold)
+    {
+        chipSel = 1;
+    }
+
+    return rc;
+}
+
+static int spiRead(uint8_t *data, uint16_t rxSize, bool bCsHold)
+{
+    int rc;
+
+    // Assert chip select
+    chipSel = 0;
+
+    // Send read command address
+    rc  = spi.transfer(data, REG_CMD_SIZE, (uint8_t *)NULL, 0,
+                       callbck, SPI_EVENT_COMPLETE);
+
+    rc = transferComplete();
+
+    if (rc < 0)
+    {
+        chipSel = 1;
+        return rc;
+    }
+
+    for (int i = 0; i < DUMMY_BYTE_COUNT; i++) {
+        rc = spi.write(0);
+    }
+
+    // Retrieve data from slave
+    rc  = spi.transfer((uint8_t *)NULL, rxSize, rxBuff, rxSize,
+                       callbck, SPI_EVENT_COMPLETE);
+
+    rc = transferComplete();
+
+    if (rc < 0)
+    {
+        chipSel = 1;
+        return rc;
+    }
+
+    // De assert chip select
+    if (!bCsHold)
+    {
+        chipSel = 1;
+    }
+
+    return rc;
+}
+
+static int syncWithAdisense1000()
+{
+    uint8_t txBuff[20];
+    uint8_t nRxLen = 1;
+    bool bCsHoldOff = false;
+    uint16_t nAttempts = 0;
+
+    memset(txBuff, 0, sizeof(txBuff));
+
+    txBuff[0] = READ_CMD;
+    txBuff[1] = SPI_CHIP_TYPE_ADDR;
+
+    while (rxBuff[0] != SPI_CHIP_TYPE_VALUE)
+    {
+        if(spiRead(txBuff, nRxLen, bCsHoldOff) < 0)
+        {
+            return -1;
+        }
+
+        if (nAttempts >= MAX_SYNC_ATTEMPTS)
+        {
+            return -1;
+        }
+
+        nAttempts++;
+        wait_ms(100);
+    }
+   /* TODO: Reminder not to forget about the following routine which was previously
+      used: Not valid currently as we are hardcoding the dummy byte count
+      This is a temporary fix until we have a defined spi protocall.
+      This function reads the spi chip type (fixed value) and determines how many
+      dummy bytes need to be sent in a spi read transaction.
+      The dummy bytes varies depending on clock speed, debug/release build on
+      adisense, and will keep varying as the code grows. So this elimantes the need
+      to manually modify the dummy bytes.
+     */
+
+    return 0;
+}
+
+/*!
+ * @brief Register a new spi connection
+ *
+ * @param[in] spiConfig    spi settings for connection
+ *
+ * @return Status
+ *         - #ADI_SENSE_SUCCESS Call completed successfully.
+ *         - todo
+ *
+ */
+ADI_SENSE_RESULT ADISense1000_HostSpiOpen(spiSettings spiConfig)
+{
+    /*
+       For v0.1 we are using the mbed api.
+       The digital classes are declared globally.
+       Parameters are placeholders for future revisions.
+       */
+
+    cbkFired = false;
+    intType = 0;
+
+    callbck.attach(callbackFired);
+
+    spi.format(SPI_FRAME_SIZE_8, SPI_MODE_0);
+    spi.frequency(SPI_CLOCK_FREQUENCY_700KHZ);
+
+    if (syncWithAdisense1000() != ADI_SENSE_SUCCESS)
+        return ADI_SENSE_FAILURE;
+
+    return ADI_SENSE_SUCCESS;
+}
+
+/*!
+ * @brief Transfer data to slave device
+ *
+ * @param[in] pData     array with transfer data
+ * @param[in] nTxLen    number of bytes to transfer
+ * @param[in] bCsHold   keep cs high/low after transfer
+ *
+ * @return Status
+ *         - #ADI_SENSE_SUCCESS Call completed successfully.
+ *         - todo
+ *
+ */
+ADI_SENSE_RESULT
+ADISense1000_HostSpiTransfer(uint8_t *pData, uint16_t nTxLen, bool bCsHold)
+{
+    int txWrite = CHECK_BIT(pData[0], CMD_BIT);
+
+    if (txWrite)
+    {
+        if (spiWrite(pData, nTxLen, bCsHold) < 0)
+            return ADI_SENSE_FAILURE;
+        else
+            return ADI_SENSE_SUCCESS;
+    }
+
+    if(spiRead(pData, nTxLen, bCsHold) < 0)
+        return ADI_SENSE_FAILURE;
+
+    memcpy(pData, rxBuff, nTxLen);
+
+    return ADI_SENSE_SUCCESS;
+}
+
+
+/*!
+ * @brief Close spi connection
+ *
+ * @param[in]
+ *
+ * @return Status
+ *         - #ADI_SENSE_SUCCESS Call completed successfully.
+ *         - todo
+ *
+ */
+ADI_SENSE_RESULT ADISense1000_HostSpiClose()
+{
+    return ADI_SENSE_SUCCESS;
+}
+/**
+ * @}
+ */
+