Vybhav Kadaba / Mbed OS EV-PRO-MW1001_test2
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers admw_spi.cpp Source File

admw_spi.cpp

Go to the documentation of this file.
00001 /******************************************************************************
00002 Copyright 2017 (c) Analog Devices, Inc.
00003 
00004 All rights reserved.
00005 
00006 Redistribution and use in source and binary forms, with or without
00007 modification, are permitted provided that the following conditions are met:
00008   - Redistributions of source code must retain the above copyright
00009     notice, this list of conditions and the following disclaimer.
00010   - Redistributions in binary form must reproduce the above copyright
00011     notice, this list of conditions and the following disclaimer in
00012     the documentation and/or other materials provided with the
00013     distribution.
00014   - Neither the name of Analog Devices, Inc. nor the names of its
00015     contributors may be used to endorse or promote products derived
00016     from this software without specific prior written permission.
00017   - The use of this software may or may not infringe the patent rights
00018     of one or more patent holders. This license does not release you
00019     from the requirement that you obtain separate licenses from these
00020     patent holders to use this software.
00021   - Use of the software either in source or binary form, must be run
00022     on or directly connected to an Analog Devices Inc. component.
00023 
00024 THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
00025 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
00026 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
00027 IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
00028 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00029 LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
00030 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00031 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00032 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00033 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00034  *
00035  *****************************************************************************/
00036 
00037 /*!
00038  ******************************************************************************
00039  * @file:
00040  * @brief:  ADMW OS-dependent wrapper layer for SPI interface
00041  *-----------------------------------------------------------------------------
00042  */
00043 
00044 #include <mbed.h>
00045 
00046 #include "inc/admw_spi.h"
00047 #include "inc/admw_log.h"
00048 
00049 #define ADMW_SPI_MODE       0 /* CPOL=0, CPHA=0 */
00050 #define ADMW_SPI_FRAME_SIZE 8 /* 8-bit frame size */
00051 
00052 
00053 #ifdef __cplusplus
00054 extern "C" {
00055 #endif
00056 
00057 
00058 // Struct to contain anything needed to identify the SPI device
00059 // This is returned as a ADMW_SPI_HANDLE*, and is required to use
00060 // the other SPI functions
00061 typedef struct {
00062     SPI *_spi;
00063     DigitalOut *_cs;
00064     DigitalOut *_wakeup;
00065 } SpiContext_t;
00066 
00067 
00068 /*
00069  * Open the SPI interface and allocate resources
00070  */
00071 ADMW_RESULT  admw_SpiOpen(
00072     ADMW_PLATFORM_SPI_CONFIG *pConfig,
00073     ADMW_SPI_HANDLE  *phDevice)
00074 {
00075     SpiContext_t *pCtx = (SpiContext_t*)malloc(sizeof(*pCtx));
00076     if(!pCtx) {
00077         ADMW_LOG_ERROR("Failed to allocate memory for SPI device");
00078         return ADMW_NO_MEM ;
00079     }
00080     
00081     pCtx->_spi = new SPI((PinName)pConfig->mosiPin,
00082                 (PinName)pConfig->misoPin,
00083                 (PinName)pConfig->sckPin);
00084     pCtx->_cs = new DigitalOut((PinName)pConfig->csPin, 1);
00085     
00086     pCtx->_spi->format(ADMW_SPI_FRAME_SIZE, ADMW_SPI_MODE);
00087     pCtx->_spi->frequency(pConfig->maxSpeedHz);
00088     
00089     pCtx->_wakeup = new DigitalOut((PinName)pConfig->wakeupPin, 1);
00090     
00091     *phDevice = (ADMW_SPI_HANDLE )pCtx;
00092     
00093     return ADMW_SUCCESS ;
00094 }
00095 
00096 ADMW_RESULT 
00097 admw_SpiReceive(
00098     ADMW_SPI_HANDLE  hDevice,
00099     void *pTxData,
00100     void *pRxData,
00101     unsigned nLength,
00102     bool bCsHold)
00103 {
00104     SpiContext_t *pCtx = (SpiContext_t*)hDevice;
00105     
00106     pCtx->_spi->format(ADMW_SPI_FRAME_SIZE, 1);
00107     
00108     int rc = 0;
00109    
00110     *(pCtx->_wakeup) = 1;
00111      wait_ms(0.03);
00112     
00113     *(pCtx->_cs) = 0;
00114     
00115      
00116     
00117     rc  = pCtx->_spi->write((char*)(pTxData), pTxData ? nLength : 0,
00118                      (char*)(pRxData), pRxData ? nLength : 0);
00119     
00120     if ((rc < 0) || !bCsHold)
00121         *(pCtx->_cs) = 1;
00122     
00123        *(pCtx->_wakeup) = 0;
00124        
00125     if (rc < 0)
00126     {
00127         ADMW_LOG_ERROR("Failed to complete SPI transfer");
00128         return ADMW_FAILURE ;
00129     }
00130     
00131     pCtx->_spi->format(ADMW_SPI_FRAME_SIZE, ADMW_SPI_MODE);
00132     
00133     return ADMW_SUCCESS ;
00134 }
00135 
00136 /*
00137  * Execute a bi-directional data transfer on the SPI interface
00138  */
00139 ADMW_RESULT 
00140 admw_SpiTransfer(
00141     ADMW_SPI_HANDLE  hDevice,
00142     void *pTxData,
00143     void *pRxData,
00144     unsigned nLength,
00145     bool bCsHold)
00146 {
00147     int rc = 0;
00148     
00149     SpiContext_t *pCtx = (SpiContext_t*)hDevice;
00150 
00151     *(pCtx->_wakeup) = 1;
00152      wait_ms(0.03);    
00153     *(pCtx->_cs) = 0;
00154     
00155     rc  = pCtx->_spi->write((char*)(pTxData), pTxData ? nLength : 0,
00156                      (char*)(pRxData), pRxData ? nLength : 0);
00157     
00158     if ((rc < 0) || !bCsHold)
00159         *(pCtx->_cs) = 1;
00160  
00161     *(pCtx->_wakeup) = 0;
00162         
00163     if (rc < 0)
00164     {
00165         ADMW_LOG_ERROR("Failed to complete SPI transfer");
00166         return ADMW_FAILURE ;
00167     }
00168     
00169     return ADMW_SUCCESS ;
00170 }
00171 
00172 /*
00173  * Close the SPI interface and free resources
00174  */
00175 void admw_SpiClose(
00176     ADMW_SPI_HANDLE  hDevice)
00177 {
00178     SpiContext_t *pCtx = (SpiContext_t *)hDevice;
00179 
00180     delete pCtx->_spi;
00181     delete pCtx->_cs;
00182     delete pCtx->_wakeup;
00183     
00184     free(pCtx);
00185 }
00186 
00187 #ifdef __cplusplus
00188 }
00189 #endif
00190 
00191 /*!
00192  * @}
00193  */