ADISense1000 Version 2.1 code base

Fork of AdiSense1000_V21 by Sean Wilson

Committer:
kevin1990
Date:
Fri Oct 20 15:58:01 2017 +0000
Revision:
7:4dbae381f693
v0.3 release (New Host api)

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kevin1990 7:4dbae381f693 1 /*!
kevin1990 7:4dbae381f693 2 ******************************************************************************
kevin1990 7:4dbae381f693 3 * @file: adi_sense_spi.cpp
kevin1990 7:4dbae381f693 4 * @brief: ADI Sense OS-dependent wrapper layer for SPI interface
kevin1990 7:4dbae381f693 5 *-----------------------------------------------------------------------------
kevin1990 7:4dbae381f693 6 */
kevin1990 7:4dbae381f693 7
kevin1990 7:4dbae381f693 8 /******************************************************************************
kevin1990 7:4dbae381f693 9 Copyright (c) 2017 Emutex Ltd. / Analog Devices, Inc.
kevin1990 7:4dbae381f693 10
kevin1990 7:4dbae381f693 11 All rights reserved.
kevin1990 7:4dbae381f693 12
kevin1990 7:4dbae381f693 13 Redistribution and use in source and binary forms, with or without modification,
kevin1990 7:4dbae381f693 14 are permitted provided that the following conditions are met:
kevin1990 7:4dbae381f693 15 - Redistributions of source code must retain the above copyright notice,
kevin1990 7:4dbae381f693 16 this list of conditions and the following disclaimer.
kevin1990 7:4dbae381f693 17 - Redistributions in binary form must reproduce the above copyright notice,
kevin1990 7:4dbae381f693 18 this list of conditions and the following disclaimer in the documentation
kevin1990 7:4dbae381f693 19 and/or other materials provided with the distribution.
kevin1990 7:4dbae381f693 20 - Modified versions of the software must be conspicuously marked as such.
kevin1990 7:4dbae381f693 21 - This software is licensed solely and exclusively for use with processors
kevin1990 7:4dbae381f693 22 manufactured by or for Analog Devices, Inc.
kevin1990 7:4dbae381f693 23 - This software may not be combined or merged with other code in any manner
kevin1990 7:4dbae381f693 24 that would cause the software to become subject to terms and conditions
kevin1990 7:4dbae381f693 25 which differ from those listed here.
kevin1990 7:4dbae381f693 26 - Neither the name of Analog Devices, Inc. nor the names of its
kevin1990 7:4dbae381f693 27 contributors may be used to endorse or promote products derived
kevin1990 7:4dbae381f693 28 from this software without specific prior written permission.
kevin1990 7:4dbae381f693 29 - The use of this software may or may not infringe the patent rights of one
kevin1990 7:4dbae381f693 30 or more patent holders. This license does not release you from the
kevin1990 7:4dbae381f693 31 requirement that you obtain separate licenses from these patent holders
kevin1990 7:4dbae381f693 32 to use this software.
kevin1990 7:4dbae381f693 33
kevin1990 7:4dbae381f693 34 THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES, INC. AND CONTRIBUTORS "AS IS" AND ANY
kevin1990 7:4dbae381f693 35 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
kevin1990 7:4dbae381f693 36 TITLE, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
kevin1990 7:4dbae381f693 37 NO EVENT SHALL ANALOG DEVICES, INC. OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
kevin1990 7:4dbae381f693 38 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, PUNITIVE OR CONSEQUENTIAL DAMAGES
kevin1990 7:4dbae381f693 39 (INCLUDING, BUT NOT LIMITED TO, DAMAGES ARISING OUT OF CLAIMS OF INTELLECTUAL
kevin1990 7:4dbae381f693 40 PROPERTY RIGHTS INFRINGEMENT; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
kevin1990 7:4dbae381f693 41 OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
kevin1990 7:4dbae381f693 42 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
kevin1990 7:4dbae381f693 43 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
kevin1990 7:4dbae381f693 44 EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
kevin1990 7:4dbae381f693 45 *
kevin1990 7:4dbae381f693 46 *****************************************************************************/
kevin1990 7:4dbae381f693 47
kevin1990 7:4dbae381f693 48 #include <mbed.h>
kevin1990 7:4dbae381f693 49
kevin1990 7:4dbae381f693 50 #include "inc/adi_sense_spi.h"
kevin1990 7:4dbae381f693 51 #include "inc/adi_sense_log.h"
kevin1990 7:4dbae381f693 52
kevin1990 7:4dbae381f693 53 #define ADI_SENSE_SPI_MODE 0 /* CPOL=0, CPHA=0 */
kevin1990 7:4dbae381f693 54 #define ADI_SENSE_SPI_FRAME_SIZE 8 /* 8-bit frame size */
kevin1990 7:4dbae381f693 55
kevin1990 7:4dbae381f693 56 class SpiContext
kevin1990 7:4dbae381f693 57 {
kevin1990 7:4dbae381f693 58 public:
kevin1990 7:4dbae381f693 59 SpiContext(
kevin1990 7:4dbae381f693 60 PinName mosiPin,
kevin1990 7:4dbae381f693 61 PinName misoPin,
kevin1990 7:4dbae381f693 62 PinName sckPin,
kevin1990 7:4dbae381f693 63 PinName csPin,
kevin1990 7:4dbae381f693 64 unsigned maxSpeed);
kevin1990 7:4dbae381f693 65
kevin1990 7:4dbae381f693 66 int transfer(
kevin1990 7:4dbae381f693 67 void *pTxData,
kevin1990 7:4dbae381f693 68 void *pRxData,
kevin1990 7:4dbae381f693 69 unsigned nLength,
kevin1990 7:4dbae381f693 70 bool bCsHold);
kevin1990 7:4dbae381f693 71
kevin1990 7:4dbae381f693 72 private:
kevin1990 7:4dbae381f693 73 SPI _spi;
kevin1990 7:4dbae381f693 74 DigitalOut _cs;
kevin1990 7:4dbae381f693 75
kevin1990 7:4dbae381f693 76 event_callback_t _callback;
kevin1990 7:4dbae381f693 77 volatile int _cbEvent;
kevin1990 7:4dbae381f693 78 volatile bool _cbFired;
kevin1990 7:4dbae381f693 79
kevin1990 7:4dbae381f693 80 void _cbHandler(
kevin1990 7:4dbae381f693 81 int event);
kevin1990 7:4dbae381f693 82
kevin1990 7:4dbae381f693 83 int _waitForCallback(
kevin1990 7:4dbae381f693 84 void);
kevin1990 7:4dbae381f693 85 };
kevin1990 7:4dbae381f693 86
kevin1990 7:4dbae381f693 87 SpiContext::SpiContext(PinName mosiPin,
kevin1990 7:4dbae381f693 88 PinName misoPin,
kevin1990 7:4dbae381f693 89 PinName sckPin,
kevin1990 7:4dbae381f693 90 PinName csPin,
kevin1990 7:4dbae381f693 91 unsigned maxSpeed)
kevin1990 7:4dbae381f693 92 : _spi(mosiPin, misoPin, sckPin),
kevin1990 7:4dbae381f693 93 _cs(csPin, 1)
kevin1990 7:4dbae381f693 94 {
kevin1990 7:4dbae381f693 95 _cbEvent = 0;
kevin1990 7:4dbae381f693 96 _cbFired = false;
kevin1990 7:4dbae381f693 97 _callback.attach(this, &SpiContext::_cbHandler);
kevin1990 7:4dbae381f693 98
kevin1990 7:4dbae381f693 99 _spi.format(ADI_SENSE_SPI_FRAME_SIZE, ADI_SENSE_SPI_MODE);
kevin1990 7:4dbae381f693 100 _spi.frequency(maxSpeed);
kevin1990 7:4dbae381f693 101 }
kevin1990 7:4dbae381f693 102
kevin1990 7:4dbae381f693 103 void SpiContext::_cbHandler(int event)
kevin1990 7:4dbae381f693 104 {
kevin1990 7:4dbae381f693 105 _cbEvent = event;
kevin1990 7:4dbae381f693 106 _cbFired = true;
kevin1990 7:4dbae381f693 107 }
kevin1990 7:4dbae381f693 108
kevin1990 7:4dbae381f693 109 int SpiContext::_waitForCallback(void)
kevin1990 7:4dbae381f693 110 {
kevin1990 7:4dbae381f693 111 int rc = 0;
kevin1990 7:4dbae381f693 112
kevin1990 7:4dbae381f693 113 while ((_cbFired != true) && (_cbEvent != SPI_EVENT_COMPLETE))
kevin1990 7:4dbae381f693 114 { ; }
kevin1990 7:4dbae381f693 115
kevin1990 7:4dbae381f693 116 _cbFired = false;
kevin1990 7:4dbae381f693 117 _cbEvent = 0;
kevin1990 7:4dbae381f693 118
kevin1990 7:4dbae381f693 119 return rc;
kevin1990 7:4dbae381f693 120 }
kevin1990 7:4dbae381f693 121
kevin1990 7:4dbae381f693 122 int SpiContext::transfer(
kevin1990 7:4dbae381f693 123 void *pTxData,
kevin1990 7:4dbae381f693 124 void *pRxData,
kevin1990 7:4dbae381f693 125 unsigned nLength,
kevin1990 7:4dbae381f693 126 bool bCsHold)
kevin1990 7:4dbae381f693 127 {
kevin1990 7:4dbae381f693 128 int rc = 0;
kevin1990 7:4dbae381f693 129
kevin1990 7:4dbae381f693 130 _cs = 0;
kevin1990 7:4dbae381f693 131
kevin1990 7:4dbae381f693 132 rc = _spi.transfer((uint8_t *)pTxData, nLength,
kevin1990 7:4dbae381f693 133 (uint8_t *)pRxData, nLength,
kevin1990 7:4dbae381f693 134 _callback, SPI_EVENT_COMPLETE);
kevin1990 7:4dbae381f693 135 if (rc < 0)
kevin1990 7:4dbae381f693 136 {
kevin1990 7:4dbae381f693 137 _cs = 1;
kevin1990 7:4dbae381f693 138 return rc;
kevin1990 7:4dbae381f693 139 }
kevin1990 7:4dbae381f693 140
kevin1990 7:4dbae381f693 141 rc = _waitForCallback();
kevin1990 7:4dbae381f693 142 if ((rc < 0) || !bCsHold)
kevin1990 7:4dbae381f693 143 _cs = 1;
kevin1990 7:4dbae381f693 144
kevin1990 7:4dbae381f693 145 return rc;
kevin1990 7:4dbae381f693 146 }
kevin1990 7:4dbae381f693 147
kevin1990 7:4dbae381f693 148 #ifdef __cplusplus
kevin1990 7:4dbae381f693 149 extern "C" {
kevin1990 7:4dbae381f693 150 #endif
kevin1990 7:4dbae381f693 151
kevin1990 7:4dbae381f693 152 /*
kevin1990 7:4dbae381f693 153 * Open the SPI interface and allocate resources
kevin1990 7:4dbae381f693 154 */
kevin1990 7:4dbae381f693 155 ADI_SENSE_RESULT adi_sense_SpiOpen(
kevin1990 7:4dbae381f693 156 ADI_SENSE_PLATFORM_SPI_CONFIG *pConfig,
kevin1990 7:4dbae381f693 157 ADI_SENSE_SPI_HANDLE *phDevice)
kevin1990 7:4dbae381f693 158 {
kevin1990 7:4dbae381f693 159 SpiContext *pCtx = new SpiContext((PinName)pConfig->mosiPin,
kevin1990 7:4dbae381f693 160 (PinName)pConfig->misoPin,
kevin1990 7:4dbae381f693 161 (PinName)pConfig->sckPin,
kevin1990 7:4dbae381f693 162 (PinName)pConfig->csPin,
kevin1990 7:4dbae381f693 163 pConfig->maxSpeedHz);
kevin1990 7:4dbae381f693 164 if (!pCtx)
kevin1990 7:4dbae381f693 165 {
kevin1990 7:4dbae381f693 166 ADI_SENSE_LOG_ERROR("Failed to allocate memory for SPI interface");
kevin1990 7:4dbae381f693 167 return ADI_SENSE_NO_MEM;
kevin1990 7:4dbae381f693 168 }
kevin1990 7:4dbae381f693 169
kevin1990 7:4dbae381f693 170 *phDevice = reinterpret_cast<ADI_SENSE_SPI_HANDLE>(pCtx);
kevin1990 7:4dbae381f693 171 return ADI_SENSE_SUCCESS;
kevin1990 7:4dbae381f693 172 }
kevin1990 7:4dbae381f693 173
kevin1990 7:4dbae381f693 174 /*
kevin1990 7:4dbae381f693 175 * Execute a bi-directional data transfer on the SPI interface
kevin1990 7:4dbae381f693 176 */
kevin1990 7:4dbae381f693 177 ADI_SENSE_RESULT
kevin1990 7:4dbae381f693 178 adi_sense_SpiTransfer(
kevin1990 7:4dbae381f693 179 ADI_SENSE_SPI_HANDLE hDevice,
kevin1990 7:4dbae381f693 180 void *pTxData,
kevin1990 7:4dbae381f693 181 void *pRxData,
kevin1990 7:4dbae381f693 182 unsigned nLength,
kevin1990 7:4dbae381f693 183 bool bCsHold)
kevin1990 7:4dbae381f693 184 {
kevin1990 7:4dbae381f693 185 SpiContext *pCtx = reinterpret_cast<SpiContext *>(hDevice);
kevin1990 7:4dbae381f693 186
kevin1990 7:4dbae381f693 187 if (pCtx->transfer(pTxData, pRxData, nLength, bCsHold) < 0)
kevin1990 7:4dbae381f693 188 {
kevin1990 7:4dbae381f693 189 ADI_SENSE_LOG_ERROR("Failed to complete SPI transfer");
kevin1990 7:4dbae381f693 190 return ADI_SENSE_FAILURE;
kevin1990 7:4dbae381f693 191 }
kevin1990 7:4dbae381f693 192
kevin1990 7:4dbae381f693 193 return ADI_SENSE_SUCCESS;
kevin1990 7:4dbae381f693 194 }
kevin1990 7:4dbae381f693 195
kevin1990 7:4dbae381f693 196 /*
kevin1990 7:4dbae381f693 197 * Close the SPI interface and free resources
kevin1990 7:4dbae381f693 198 */
kevin1990 7:4dbae381f693 199 void adi_sense_SpiClose(
kevin1990 7:4dbae381f693 200 ADI_SENSE_SPI_HANDLE hDevice)
kevin1990 7:4dbae381f693 201 {
kevin1990 7:4dbae381f693 202 SpiContext *pCtx = reinterpret_cast<SpiContext *>(hDevice);
kevin1990 7:4dbae381f693 203
kevin1990 7:4dbae381f693 204 delete pCtx;
kevin1990 7:4dbae381f693 205 }
kevin1990 7:4dbae381f693 206
kevin1990 7:4dbae381f693 207 #ifdef __cplusplus
kevin1990 7:4dbae381f693 208 }
kevin1990 7:4dbae381f693 209 #endif
kevin1990 7:4dbae381f693 210
kevin1990 7:4dbae381f693 211 /*!
kevin1990 7:4dbae381f693 212 * @}
kevin1990 7:4dbae381f693 213 */
kevin1990 7:4dbae381f693 214