Including SPI 3-wires class

Fork of X_NUCLEO_COMMON_SPI3W by Licio Mapelli

Committer:
mapellil
Date:
Fri May 12 13:12:59 2017 +0000
Revision:
22:62b662a23496
Child:
23:a42a4217ff73
Added SPI3W support (q&d implementation hack addressing directly HAL, hacked stm_spi_api.c file is required)

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mapellil 22:62b662a23496 1 /**
mapellil 22:62b662a23496 2 ******************************************************************************
mapellil 22:62b662a23496 3 * @file SPI3W.cpp
mapellil 22:62b662a23496 4 * @author CLab
mapellil 22:62b662a23496 5 * @version V1.0.0
mapellil 22:62b662a23496 6 * @date 5 August 2016
mapellil 22:62b662a23496 7 * @brief Implementation of an SPI 3 wires driver.
mapellil 22:62b662a23496 8 ******************************************************************************
mapellil 22:62b662a23496 9 * @attention
mapellil 22:62b662a23496 10 *
mapellil 22:62b662a23496 11 * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
mapellil 22:62b662a23496 12 *
mapellil 22:62b662a23496 13 * Redistribution and use in source and binary forms, with or without modification,
mapellil 22:62b662a23496 14 * are permitted provided that the following conditions are met:
mapellil 22:62b662a23496 15 * 1. Redistributions of source code must retain the above copyright notice,
mapellil 22:62b662a23496 16 * this list of conditions and the following disclaimer.
mapellil 22:62b662a23496 17 * 2. Redistributions in binary form must reproduce the above copyright notice,
mapellil 22:62b662a23496 18 * this list of conditions and the following disclaimer in the documentation
mapellil 22:62b662a23496 19 * and/or other materials provided with the distribution.
mapellil 22:62b662a23496 20 * 3. Neither the name of STMicroelectronics nor the names of its contributors
mapellil 22:62b662a23496 21 * may be used to endorse or promote products derived from this software
mapellil 22:62b662a23496 22 * without specific prior written permission.
mapellil 22:62b662a23496 23 *
mapellil 22:62b662a23496 24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
mapellil 22:62b662a23496 25 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
mapellil 22:62b662a23496 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
mapellil 22:62b662a23496 27 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
mapellil 22:62b662a23496 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
mapellil 22:62b662a23496 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
mapellil 22:62b662a23496 30 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
mapellil 22:62b662a23496 31 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
mapellil 22:62b662a23496 32 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
mapellil 22:62b662a23496 33 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
mapellil 22:62b662a23496 34 *
mapellil 22:62b662a23496 35 ******************************************************************************
mapellil 22:62b662a23496 36 */
mapellil 22:62b662a23496 37
mapellil 22:62b662a23496 38 #include "mbed.h"
mapellil 22:62b662a23496 39 #include "SPI3W.h"
mapellil 22:62b662a23496 40 //#include "SensorTile.h"
mapellil 22:62b662a23496 41
mapellil 22:62b662a23496 42
mapellil 22:62b662a23496 43 /* Class Implementation ------------------------------------------------------*/
mapellil 22:62b662a23496 44
mapellil 22:62b662a23496 45 /** Constructor
mapellil 22:62b662a23496 46 * @param spi3w object of an helper class which handles the spi peripheral
mapellil 22:62b662a23496 47 * @param
mapellil 22:62b662a23496 48 */
mapellil 22:62b662a23496 49
mapellil 22:62b662a23496 50 SPI3W::SPI3W (PinName spi_sda, PinName spi_sdi, PinName spi_clk) : SPI(spi_sda, spi_sdi, spi_clk, NC)
mapellil 22:62b662a23496 51 {
mapellil 22:62b662a23496 52 }
mapellil 22:62b662a23496 53
mapellil 22:62b662a23496 54
mapellil 22:62b662a23496 55 uint8_t SPI3W::Sensor_IO_SPI_CS_Enable(DigitalOut * _cs_pin)
mapellil 22:62b662a23496 56 {
mapellil 22:62b662a23496 57 *_cs_pin = 0;
mapellil 22:62b662a23496 58 return 0;
mapellil 22:62b662a23496 59 }
mapellil 22:62b662a23496 60
mapellil 22:62b662a23496 61 uint8_t SPI3W::Sensor_IO_SPI_CS_Disable(DigitalOut * _cs_pin)
mapellil 22:62b662a23496 62 {
mapellil 22:62b662a23496 63 *_cs_pin = 1;
mapellil 22:62b662a23496 64 return 0;
mapellil 22:62b662a23496 65 }
mapellil 22:62b662a23496 66
mapellil 22:62b662a23496 67
mapellil 22:62b662a23496 68 /**
mapellil 22:62b662a23496 69 * @brief Writes a buffer to the sensor
mapellil 22:62b662a23496 70 * @param handle instance handle
mapellil 22:62b662a23496 71 * @param WriteAddr specifies the internal sensor address register to be written to
mapellil 22:62b662a23496 72 * @param pBuffer pointer to data buffer
mapellil 22:62b662a23496 73 * @param nBytesToWrite number of bytes to be written
mapellil 22:62b662a23496 74 * @retval 0 in case of success
mapellil 22:62b662a23496 75 * @retval 1 in case of failure
mapellil 22:62b662a23496 76 */
mapellil 22:62b662a23496 77 uint8_t SPI3W::Sensor_IO_SPI_Write( DigitalOut * _cs_pin, uint8_t WriteAddr, uint8_t *pBuffer, uint16_t nBytesToWrite )
mapellil 22:62b662a23496 78 {
mapellil 22:62b662a23496 79 uint8_t i;
mapellil 22:62b662a23496 80
mapellil 22:62b662a23496 81 // Select the correct device
mapellil 22:62b662a23496 82 Sensor_IO_SPI_CS_Enable(_cs_pin);
mapellil 22:62b662a23496 83
mapellil 22:62b662a23496 84 write(WriteAddr);
mapellil 22:62b662a23496 85
mapellil 22:62b662a23496 86 for(i=0;i<nBytesToWrite;i++)
mapellil 22:62b662a23496 87 {
mapellil 22:62b662a23496 88 write(pBuffer[i]);
mapellil 22:62b662a23496 89 }
mapellil 22:62b662a23496 90 // Deselect the device
mapellil 22:62b662a23496 91 Sensor_IO_SPI_CS_Disable(_cs_pin);
mapellil 22:62b662a23496 92
mapellil 22:62b662a23496 93 return 0;
mapellil 22:62b662a23496 94 }
mapellil 22:62b662a23496 95
mapellil 22:62b662a23496 96 /**
mapellil 22:62b662a23496 97 * @brief Writes a buffer to the sensor
mapellil 22:62b662a23496 98 * @param handle instance handle
mapellil 22:62b662a23496 99 * @param WriteAddr specifies the internal sensor address register to be written to
mapellil 22:62b662a23496 100 * @param pBuffer pointer to data buffer
mapellil 22:62b662a23496 101 * @param nBytesToWrite number of bytes to be written
mapellil 22:62b662a23496 102 * @retval 0 in case of success
mapellil 22:62b662a23496 103 * @retval 1 in case of failure
mapellil 22:62b662a23496 104 */
mapellil 22:62b662a23496 105 uint8_t SPI3W::Sensor_IO_Write( DigitalOut * _cs_pin, uint8_t WriteAddr, uint8_t *pBuffer, uint16_t nBytesToWrite )
mapellil 22:62b662a23496 106 {
mapellil 22:62b662a23496 107 return Sensor_IO_SPI_Write( _cs_pin, WriteAddr, pBuffer, nBytesToWrite );
mapellil 22:62b662a23496 108 }
mapellil 22:62b662a23496 109
mapellil 22:62b662a23496 110
mapellil 22:62b662a23496 111 /**
mapellil 22:62b662a23496 112 * @brief This function reads a single byte on SPI 3-wire.
mapellil 22:62b662a23496 113 * @param xSpiHandle : SPI Handler.
mapellil 22:62b662a23496 114 * @param val : value.
mapellil 22:62b662a23496 115 * @retval None
mapellil 22:62b662a23496 116 */
mapellil 22:62b662a23496 117 void SPI3W::SPI_Read(SPI_HandleTypeDef* xSpiHandle, uint8_t *val)
mapellil 22:62b662a23496 118 {
mapellil 22:62b662a23496 119 /* In master RX mode the clock is automaticaly generated on the SPI enable.
mapellil 22:62b662a23496 120 So to guarantee the clock generation for only one data, the clock must be
mapellil 22:62b662a23496 121 disabled after the first bit and before the latest bit */
mapellil 22:62b662a23496 122 /* Interrupts should be disabled during this operation */
mapellil 22:62b662a23496 123
mapellil 22:62b662a23496 124 __disable_irq();
mapellil 22:62b662a23496 125
mapellil 22:62b662a23496 126 __HAL_SPI_ENABLE(xSpiHandle);
mapellil 22:62b662a23496 127 __asm("dsb\n");
mapellil 22:62b662a23496 128 __asm("dsb\n");
mapellil 22:62b662a23496 129 __HAL_SPI_DISABLE(xSpiHandle);
mapellil 22:62b662a23496 130
mapellil 22:62b662a23496 131 __enable_irq();
mapellil 22:62b662a23496 132
mapellil 22:62b662a23496 133 *val = spi_slave_read(&_spi);
mapellil 22:62b662a23496 134 }
mapellil 22:62b662a23496 135
mapellil 22:62b662a23496 136 /**
mapellil 22:62b662a23496 137 * @brief This function reads multiple bytes on SPI 3-wire.
mapellil 22:62b662a23496 138 * @param xSpiHandle: SPI Handler.
mapellil 22:62b662a23496 139 * @param val: value.
mapellil 22:62b662a23496 140 * @param nBytesToRead: number of bytes to read.
mapellil 22:62b662a23496 141 * @retval None
mapellil 22:62b662a23496 142 */
mapellil 22:62b662a23496 143 void SPI3W::SPI_Read_nBytes(SPI_HandleTypeDef* xSpiHandle, uint8_t *val, uint16_t nBytesToRead)
mapellil 22:62b662a23496 144 {
mapellil 22:62b662a23496 145 int tmp=0;
mapellil 22:62b662a23496 146 /* Interrupts should be disabled during this operation */
mapellil 22:62b662a23496 147 __disable_irq();
mapellil 22:62b662a23496 148 __HAL_SPI_ENABLE(xSpiHandle);
mapellil 22:62b662a23496 149
mapellil 22:62b662a23496 150 /* In master RX mode the clock is automaticaly generated on the SPI enable.
mapellil 22:62b662a23496 151 So to guarantee the clock generation for only one data, the clock must be
mapellil 22:62b662a23496 152 disabled after the first bit and before the latest bit of the last Byte received */
mapellil 22:62b662a23496 153 /* __DSB instruction are inserted to garantee that clock is Disabled in the right timeframe */
mapellil 22:62b662a23496 154 __DSB();
mapellil 22:62b662a23496 155 __DSB();
mapellil 22:62b662a23496 156
mapellil 22:62b662a23496 157 /* Transfer loop */
mapellil 22:62b662a23496 158 for (int i=0; i<nBytesToRead; i++) *(val+i) = spi_slave_read(&_spi);
mapellil 22:62b662a23496 159
mapellil 22:62b662a23496 160 __HAL_SPI_DISABLE(xSpiHandle);
mapellil 22:62b662a23496 161
mapellil 22:62b662a23496 162 __enable_irq();
mapellil 22:62b662a23496 163
mapellil 22:62b662a23496 164 tmp = spi_slave_read(&_spi);
mapellil 22:62b662a23496 165 }
mapellil 22:62b662a23496 166
mapellil 22:62b662a23496 167
mapellil 22:62b662a23496 168 /**
mapellil 22:62b662a23496 169 * @brief Reads a from the sensor to buffer
mapellil 22:62b662a23496 170 * @param handle instance handle
mapellil 22:62b662a23496 171 * @param ReadAddr specifies the internal sensor address register to be read from
mapellil 22:62b662a23496 172 * @param pBuffer pointer to data buffer
mapellil 22:62b662a23496 173 * @param nBytesToRead number of bytes to be read
mapellil 22:62b662a23496 174 * @retval 0 in case of success
mapellil 22:62b662a23496 175 * @retval 1 in case of failure
mapellil 22:62b662a23496 176 */
mapellil 22:62b662a23496 177 uint8_t SPI3W::Sensor_IO_SPI_Read( DigitalOut * _cs_pin, uint8_t ReadAddr, uint8_t *pBuffer, uint16_t nBytesToRead )
mapellil 22:62b662a23496 178 {
mapellil 22:62b662a23496 179
mapellil 22:62b662a23496 180 /* Select the correct device */
mapellil 22:62b662a23496 181 Sensor_IO_SPI_CS_Enable(_cs_pin);
mapellil 22:62b662a23496 182
mapellil 22:62b662a23496 183 /* Write Reg Address */
mapellil 22:62b662a23496 184 write(ReadAddr | 0x80);
mapellil 22:62b662a23496 185
mapellil 22:62b662a23496 186 /* Disable the SPI and change the data line to input */
mapellil 22:62b662a23496 187 __HAL_SPI_DISABLE(&_spi.spi.handle);
mapellil 22:62b662a23496 188
mapellil 22:62b662a23496 189 SPI_1LINE_RX(&_spi.spi.handle);
mapellil 22:62b662a23496 190
mapellil 22:62b662a23496 191 /* Check if we need to read one byte or more */
mapellil 22:62b662a23496 192 if(nBytesToRead > 1U)
mapellil 22:62b662a23496 193 {
mapellil 22:62b662a23496 194 SPI_Read_nBytes(&_spi.spi.handle, pBuffer, nBytesToRead);
mapellil 22:62b662a23496 195 }
mapellil 22:62b662a23496 196 else
mapellil 22:62b662a23496 197 {
mapellil 22:62b662a23496 198 SPI_Read(&_spi.spi.handle, pBuffer);
mapellil 22:62b662a23496 199 }
mapellil 22:62b662a23496 200
mapellil 22:62b662a23496 201 /* Deselect the device */
mapellil 22:62b662a23496 202 Sensor_IO_SPI_CS_Disable(_cs_pin);
mapellil 22:62b662a23496 203
mapellil 22:62b662a23496 204 /* Change the data line to output and enable the SPI */
mapellil 22:62b662a23496 205 SPI_1LINE_TX(&_spi.spi.handle);
mapellil 22:62b662a23496 206
mapellil 22:62b662a23496 207 return 0;
mapellil 22:62b662a23496 208 }
mapellil 22:62b662a23496 209
mapellil 22:62b662a23496 210
mapellil 22:62b662a23496 211 /**
mapellil 22:62b662a23496 212 * @brief Reads from the sensor to a buffer
mapellil 22:62b662a23496 213 * @param handle instance handle
mapellil 22:62b662a23496 214 * @param ReadAddr specifies the internal sensor address register to be read from
mapellil 22:62b662a23496 215 * @param pBuffer pointer to data buffer
mapellil 22:62b662a23496 216 * @param nBytesToRead number of bytes to be read
mapellil 22:62b662a23496 217 * @retval 0 in case of success
mapellil 22:62b662a23496 218 * @retval 1 in case of failure
mapellil 22:62b662a23496 219 */
mapellil 22:62b662a23496 220 uint8_t SPI3W::Sensor_IO_Read( DigitalOut * _cs_pin, uint8_t ReadAddr, uint8_t *pBuffer, uint16_t nBytesToRead )
mapellil 22:62b662a23496 221 {
mapellil 22:62b662a23496 222 return Sensor_IO_SPI_Read( _cs_pin, ReadAddr, pBuffer, nBytesToRead );
mapellil 22:62b662a23496 223 }
mapellil 22:62b662a23496 224
mapellil 22:62b662a23496 225
mapellil 22:62b662a23496 226 uint8_t SPI3W::spi3w_read(uint8_t * pBuffer, DigitalOut * _cs_pin, uint8_t RegisterAddr, uint16_t NumByteToRead)
mapellil 22:62b662a23496 227 {
mapellil 22:62b662a23496 228 return Sensor_IO_Read( _cs_pin, RegisterAddr, pBuffer, NumByteToRead );
mapellil 22:62b662a23496 229 }
mapellil 22:62b662a23496 230
mapellil 22:62b662a23496 231 uint8_t SPI3W::spi3w_write(uint8_t * pBuffer, DigitalOut * _cs_pin, uint8_t RegisterAddr, uint16_t NumByteToWrite)
mapellil 22:62b662a23496 232 {
mapellil 22:62b662a23496 233 return Sensor_IO_Write( _cs_pin, RegisterAddr, pBuffer, NumByteToWrite );
mapellil 22:62b662a23496 234 }
mapellil 22:62b662a23496 235