Fork of X_NUCLEO_COMMON lib adding 16-bit SPI support

Fork of X_NUCLEO_COMMON by ST

Committer:
apalmieri
Date:
Tue Feb 16 10:01:10 2016 +0000
Revision:
15:923ab55e8d5d
Parent:
14:655c1d3a5d59
Delete useless row

Who changed what in which revision?

UserRevisionLine numberNew contents of line
davide aliprandi <> 9:1f35e8bf427b 1 /**
davide aliprandi <> 9:1f35e8bf427b 2 ******************************************************************************
davide aliprandi <> 9:1f35e8bf427b 3 * @file DevSPI.h
davide aliprandi <> 9:1f35e8bf427b 4 * @author AST / Software Platforms and Cloud
Davidroid 12:165bd6bc00ea 5 * @version V1.0.1
Davidroid 12:165bd6bc00ea 6 * @date February 11th, 2016
davide aliprandi <> 9:1f35e8bf427b 7 * @brief Header file for a special SPI class DevSPI which provides some
davide aliprandi <> 9:1f35e8bf427b 8 * helper function for on-board communication.
davide aliprandi <> 9:1f35e8bf427b 9 ******************************************************************************
davide aliprandi <> 9:1f35e8bf427b 10 * @attention
davide aliprandi <> 9:1f35e8bf427b 11 *
davide aliprandi <> 9:1f35e8bf427b 12 * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
davide aliprandi <> 9:1f35e8bf427b 13 *
davide aliprandi <> 9:1f35e8bf427b 14 * Redistribution and use in source and binary forms, with or without modification,
davide aliprandi <> 9:1f35e8bf427b 15 * are permitted provided that the following conditions are met:
davide aliprandi <> 9:1f35e8bf427b 16 * 1. Redistributions of source code must retain the above copyright notice,
davide aliprandi <> 9:1f35e8bf427b 17 * this list of conditions and the following disclaimer.
davide aliprandi <> 9:1f35e8bf427b 18 * 2. Redistributions in binary form must reproduce the above copyright notice,
davide aliprandi <> 9:1f35e8bf427b 19 * this list of conditions and the following disclaimer in the documentation
davide aliprandi <> 9:1f35e8bf427b 20 * and/or other materials provided with the distribution.
davide aliprandi <> 9:1f35e8bf427b 21 * 3. Neither the name of STMicroelectronics nor the names of its contributors
davide aliprandi <> 9:1f35e8bf427b 22 * may be used to endorse or promote products derived from this software
davide aliprandi <> 9:1f35e8bf427b 23 * without specific prior written permission.
davide aliprandi <> 9:1f35e8bf427b 24 *
davide aliprandi <> 9:1f35e8bf427b 25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
davide aliprandi <> 9:1f35e8bf427b 26 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
davide aliprandi <> 9:1f35e8bf427b 27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
davide aliprandi <> 9:1f35e8bf427b 28 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
davide aliprandi <> 9:1f35e8bf427b 29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
davide aliprandi <> 9:1f35e8bf427b 30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
davide aliprandi <> 9:1f35e8bf427b 31 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
davide aliprandi <> 9:1f35e8bf427b 32 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
davide aliprandi <> 9:1f35e8bf427b 33 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
davide aliprandi <> 9:1f35e8bf427b 34 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
davide aliprandi <> 9:1f35e8bf427b 35 *
davide aliprandi <> 9:1f35e8bf427b 36 ******************************************************************************
davide aliprandi <> 9:1f35e8bf427b 37 */
davide aliprandi <> 9:1f35e8bf427b 38
davide aliprandi <> 9:1f35e8bf427b 39 /* Define to prevent from recursive inclusion --------------------------------*/
davide aliprandi <> 9:1f35e8bf427b 40 #ifndef __DEV_SPI_H
davide aliprandi <> 9:1f35e8bf427b 41 #define __DEV_SPI_H
davide aliprandi <> 9:1f35e8bf427b 42
davide aliprandi <> 9:1f35e8bf427b 43 /* Includes ------------------------------------------------------------------*/
davide aliprandi <> 9:1f35e8bf427b 44 #include "mbed.h"
apalmieri 15:923ab55e8d5d 45
davide aliprandi <> 9:1f35e8bf427b 46 /* Classes -------------------------------------------------------------------*/
davide.aliprandi@st.com 10:da29b5403ca1 47 /** Helper class DevSPI providing functions for SPI communication common for a
davide.aliprandi@st.com 10:da29b5403ca1 48 * series of SPI devices.
davide aliprandi <> 9:1f35e8bf427b 49 */
davide aliprandi <> 9:1f35e8bf427b 50 class DevSPI : public SPI
davide aliprandi <> 9:1f35e8bf427b 51 {
davide aliprandi <> 9:1f35e8bf427b 52 public:
davide aliprandi <> 9:1f35e8bf427b 53 /*
davide aliprandi <> 9:1f35e8bf427b 54 * Create a DevSPI interface.
davide aliprandi <> 9:1f35e8bf427b 55 * @param mosi pin name of the MOSI pin of the SPI device to be used for communication.
davide aliprandi <> 9:1f35e8bf427b 56 * @param miso pin name of the MISO pin of the SPI device to be used for communication.
davide aliprandi <> 9:1f35e8bf427b 57 * @param sclk pin name of the SCLK pin of the SPI device to be used for communication.
davide aliprandi <> 9:1f35e8bf427b 58 */
davide aliprandi <> 9:1f35e8bf427b 59 DevSPI(PinName mosi, PinName miso, PinName sclk) : SPI(mosi, miso, sclk)
davide aliprandi <> 9:1f35e8bf427b 60 {
Davidroid 12:165bd6bc00ea 61 /* Set default configuration. */
Davidroid 12:165bd6bc00ea 62 setup(8, 3, 1E6);
davide aliprandi <> 9:1f35e8bf427b 63 }
davide aliprandi <> 9:1f35e8bf427b 64
davide aliprandi <> 9:1f35e8bf427b 65 /*
davide aliprandi <> 9:1f35e8bf427b 66 * Setup the spi.
davide aliprandi <> 9:1f35e8bf427b 67 * Typically:
davide aliprandi <> 9:1f35e8bf427b 68 * + 8 bit data;
davide aliprandi <> 9:1f35e8bf427b 69 * + high steady state clock;
davide aliprandi <> 9:1f35e8bf427b 70 * + second edge capture;
davide aliprandi <> 9:1f35e8bf427b 71 * + 1MHz clock rate.
davide aliprandi <> 9:1f35e8bf427b 72 *
davide aliprandi <> 9:1f35e8bf427b 73 * @param bits Number of bits per SPI frame (4 - 16)
davide aliprandi <> 9:1f35e8bf427b 74 * @param mode Clock polarity and phase mode (0 - 3)
davide aliprandi <> 9:1f35e8bf427b 75 * @param frequency_hz SCLK frequency in hz (default = 1MHz)
davide aliprandi <> 9:1f35e8bf427b 76 *
davide aliprandi <> 9:1f35e8bf427b 77 * @code
davide aliprandi <> 9:1f35e8bf427b 78 * mode | POL PHA
davide aliprandi <> 9:1f35e8bf427b 79 * -----+--------
davide aliprandi <> 9:1f35e8bf427b 80 * 0 | 0 0
davide aliprandi <> 9:1f35e8bf427b 81 * 1 | 0 1
davide aliprandi <> 9:1f35e8bf427b 82 * 2 | 1 0
davide aliprandi <> 9:1f35e8bf427b 83 * 3 | 1 1
davide aliprandi <> 9:1f35e8bf427b 84 * @endcode
davide aliprandi <> 9:1f35e8bf427b 85 */
davide aliprandi <> 9:1f35e8bf427b 86 void setup(int bits, int mode = 0, int frequency_hz = 1E6)
davide aliprandi <> 9:1f35e8bf427b 87 {
Davidroid 12:165bd6bc00ea 88 /* Set given configuration. */
davide aliprandi <> 9:1f35e8bf427b 89 format(bits, mode);
davide aliprandi <> 9:1f35e8bf427b 90 frequency(frequency_hz);
davide aliprandi <> 9:1f35e8bf427b 91 }
davide aliprandi <> 9:1f35e8bf427b 92
davide aliprandi <> 9:1f35e8bf427b 93 /**
davide aliprandi <> 9:1f35e8bf427b 94 * @brief Writes a buffer to the SPI peripheral device.
davide aliprandi <> 9:1f35e8bf427b 95 * @param[in] pBuffer pointer to the buffer of data to send.
davide aliprandi <> 9:1f35e8bf427b 96 * @param[in] ssel GPIO of the SSEL pin of the SPI device to be used for communication.
davide aliprandi <> 9:1f35e8bf427b 97 * @param[in] NumBytesToWrite number of bytes to write.
davide aliprandi <> 9:1f35e8bf427b 98 * @retval 0 if ok.
davide aliprandi <> 9:1f35e8bf427b 99 * @note When using the SPI in Interrupt-mode, remember to disable interrupts
davide aliprandi <> 9:1f35e8bf427b 100 * before calling this function and to enable them again after.
davide aliprandi <> 9:1f35e8bf427b 101 */
davide aliprandi <> 9:1f35e8bf427b 102 int spi_write(uint8_t* pBuffer, DigitalOut ssel, uint16_t NumBytesToWrite)
davide aliprandi <> 9:1f35e8bf427b 103 {
davide aliprandi <> 9:1f35e8bf427b 104 /* Select the chip. */
davide aliprandi <> 9:1f35e8bf427b 105 ssel = 0;
davide aliprandi <> 9:1f35e8bf427b 106
davide aliprandi <> 9:1f35e8bf427b 107 /* Write data. */
apalmieri 14:655c1d3a5d59 108 if (_bits == 16) {
apalmieri 14:655c1d3a5d59 109 uint16_t dataToWrite;
apalmieri 14:655c1d3a5d59 110 for (int i = 0; i < NumBytesToWrite; i += 2) {
apalmieri 14:655c1d3a5d59 111 dataToWrite = convertFrom8To16(pBuffer);
apalmieri 14:655c1d3a5d59 112 write(dataToWrite);
apalmieri 14:655c1d3a5d59 113 pBuffer += sizeof(uint16_t);
apalmieri 14:655c1d3a5d59 114 }
apalmieri 14:655c1d3a5d59 115
apalmieri 14:655c1d3a5d59 116 } else if(_bits == 8) {
apalmieri 14:655c1d3a5d59 117 for (int i = 0; i < NumBytesToWrite; i++) {
Davidroid 12:165bd6bc00ea 118 write(pBuffer[i]);
apalmieri 14:655c1d3a5d59 119 }
apalmieri 14:655c1d3a5d59 120 }
davide aliprandi <> 9:1f35e8bf427b 121
davide aliprandi <> 9:1f35e8bf427b 122 /* Unselect the chip. */
davide aliprandi <> 9:1f35e8bf427b 123 ssel = 1;
davide aliprandi <> 9:1f35e8bf427b 124
davide aliprandi <> 9:1f35e8bf427b 125 return 0;
davide aliprandi <> 9:1f35e8bf427b 126 }
davide aliprandi <> 9:1f35e8bf427b 127
davide aliprandi <> 9:1f35e8bf427b 128 /**
davide aliprandi <> 9:1f35e8bf427b 129 * @brief Reads a buffer from the SPI peripheral device.
davide aliprandi <> 9:1f35e8bf427b 130 * @param[out] pBuffer pointer to the buffer to read data into.
davide aliprandi <> 9:1f35e8bf427b 131 * @param[in] ssel GPIO of the SSEL pin of the SPI device to be used for communication.
davide aliprandi <> 9:1f35e8bf427b 132 * @param[in] NumBytesToRead number of bytes to read.
davide aliprandi <> 9:1f35e8bf427b 133 * @retval 0 if ok.
davide aliprandi <> 9:1f35e8bf427b 134 * @note When using the SPI in Interrupt-mode, remember to disable interrupts
davide aliprandi <> 9:1f35e8bf427b 135 * before calling this function and to enable them again after.
davide aliprandi <> 9:1f35e8bf427b 136 */
davide aliprandi <> 9:1f35e8bf427b 137 int spi_read(uint8_t* pBuffer, DigitalOut ssel, uint16_t NumBytesToRead)
davide aliprandi <> 9:1f35e8bf427b 138 {
davide aliprandi <> 9:1f35e8bf427b 139 /* Select the chip. */
davide aliprandi <> 9:1f35e8bf427b 140 ssel = 0;
davide aliprandi <> 9:1f35e8bf427b 141
davide aliprandi <> 9:1f35e8bf427b 142 /* Read data. */
apalmieri 14:655c1d3a5d59 143 if (_bits == 16) {
apalmieri 14:655c1d3a5d59 144 uint16_t dataToRead;
apalmieri 14:655c1d3a5d59 145 for (int i = 0; i < NumBytesToRead; i += 2) {
apalmieri 14:655c1d3a5d59 146 dataToRead = write(0x00);
apalmieri 14:655c1d3a5d59 147 convertFrom16To8(dataToRead, pBuffer);
apalmieri 14:655c1d3a5d59 148 pBuffer += sizeof(uint16_t);
apalmieri 14:655c1d3a5d59 149 }
apalmieri 14:655c1d3a5d59 150
apalmieri 14:655c1d3a5d59 151 } else if(_bits == 8) {
apalmieri 14:655c1d3a5d59 152 for (int i = 0; i < NumBytesToRead; i++) {
Davidroid 12:165bd6bc00ea 153 pBuffer[i] = write(0x00);
apalmieri 14:655c1d3a5d59 154 }
apalmieri 14:655c1d3a5d59 155 }
davide aliprandi <> 9:1f35e8bf427b 156
davide aliprandi <> 9:1f35e8bf427b 157 /* Unselect the chip. */
davide aliprandi <> 9:1f35e8bf427b 158 ssel = 1;
davide aliprandi <> 9:1f35e8bf427b 159
davide aliprandi <> 9:1f35e8bf427b 160 return 0;
davide aliprandi <> 9:1f35e8bf427b 161 }
davide aliprandi <> 9:1f35e8bf427b 162
davide aliprandi <> 9:1f35e8bf427b 163 /**
davide aliprandi <> 9:1f35e8bf427b 164 * @brief Reads and write a buffer from/to the SPI peripheral device at the same time.
davide aliprandi <> 9:1f35e8bf427b 165 * @param[out] pBufferToRead pointer to the buffer to read data into.
davide aliprandi <> 9:1f35e8bf427b 166 * @param[in] pBufferToWrite pointer to the buffer of data to send.
davide aliprandi <> 9:1f35e8bf427b 167 * @param[in] ssel GPIO of the SSEL pin of the SPI device to be used for communication.
davide aliprandi <> 9:1f35e8bf427b 168 * @param[in] NumBytes number of bytes to read and write.
davide aliprandi <> 9:1f35e8bf427b 169 * @retval 0 if ok.
davide aliprandi <> 9:1f35e8bf427b 170 * @note When using the SPI in Interrupt-mode, remember to disable interrupts
davide aliprandi <> 9:1f35e8bf427b 171 * before calling this function and to enable them again after.
davide aliprandi <> 9:1f35e8bf427b 172 */
davide aliprandi <> 9:1f35e8bf427b 173 int spi_read_write(uint8_t* pBufferToRead, uint8_t* pBufferToWrite, DigitalOut ssel, uint16_t NumBytes)
davide aliprandi <> 9:1f35e8bf427b 174 {
davide aliprandi <> 9:1f35e8bf427b 175 /* Select the chip. */
davide aliprandi <> 9:1f35e8bf427b 176 ssel = 0;
davide aliprandi <> 9:1f35e8bf427b 177
davide aliprandi <> 9:1f35e8bf427b 178 /* Read and write data at the same time. */
apalmieri 14:655c1d3a5d59 179 if (_bits == 16) {
apalmieri 14:655c1d3a5d59 180 uint16_t dataToRead;
apalmieri 14:655c1d3a5d59 181 uint16_t dataToWrite;
apalmieri 14:655c1d3a5d59 182
apalmieri 14:655c1d3a5d59 183 for (int i = 0; i < NumBytes; i += 2) {
apalmieri 14:655c1d3a5d59 184 dataToWrite = convertFrom8To16(pBufferToWrite);
apalmieri 14:655c1d3a5d59 185
apalmieri 14:655c1d3a5d59 186 dataToRead = write(dataToWrite);
apalmieri 14:655c1d3a5d59 187
apalmieri 14:655c1d3a5d59 188 convertFrom16To8(dataToRead, pBufferToRead);
apalmieri 14:655c1d3a5d59 189
apalmieri 14:655c1d3a5d59 190 pBufferToWrite += sizeof(uint16_t);
apalmieri 14:655c1d3a5d59 191 pBufferToRead += sizeof(uint16_t);
apalmieri 14:655c1d3a5d59 192 }
apalmieri 14:655c1d3a5d59 193
apalmieri 14:655c1d3a5d59 194 } else if(_bits == 8) {
apalmieri 14:655c1d3a5d59 195 for (int i = 0; i < NumBytes; i++) {
apalmieri 11:5d30d6eefa49 196 pBufferToRead[i] = write(pBufferToWrite[i]);
apalmieri 14:655c1d3a5d59 197 }
apalmieri 14:655c1d3a5d59 198 }
davide aliprandi <> 9:1f35e8bf427b 199
davide aliprandi <> 9:1f35e8bf427b 200 /* Unselect the chip. */
davide aliprandi <> 9:1f35e8bf427b 201 ssel = 1;
davide aliprandi <> 9:1f35e8bf427b 202
davide aliprandi <> 9:1f35e8bf427b 203 return 0;
davide aliprandi <> 9:1f35e8bf427b 204 }
apalmieri 14:655c1d3a5d59 205
apalmieri 14:655c1d3a5d59 206 private:
apalmieri 14:655c1d3a5d59 207
apalmieri 14:655c1d3a5d59 208 /**
apalmieri 14:655c1d3a5d59 209 * @brief Converts two uint8_t words into one of uint16_t
apalmieri 14:655c1d3a5d59 210 * @param[in] ptr pointer to the buffer of data to be converted.
apalmieri 14:655c1d3a5d59 211 * @retval 16-bit data.
apalmieri 14:655c1d3a5d59 212 */
apalmieri 14:655c1d3a5d59 213 uint16_t convertFrom8To16(uint8_t *ptr)
apalmieri 14:655c1d3a5d59 214 {
apalmieri 14:655c1d3a5d59 215 uint16_t data16 = 0x0000;
apalmieri 14:655c1d3a5d59 216
apalmieri 14:655c1d3a5d59 217 data16 = *ptr;
apalmieri 14:655c1d3a5d59 218 data16 |= *(++ptr) << 8;
apalmieri 14:655c1d3a5d59 219
apalmieri 14:655c1d3a5d59 220 return data16;
apalmieri 14:655c1d3a5d59 221 }
apalmieri 14:655c1d3a5d59 222
apalmieri 14:655c1d3a5d59 223 /**
apalmieri 14:655c1d3a5d59 224 * @brief Converts one uint16_t word into two uint8_t
apalmieri 14:655c1d3a5d59 225 * @param[in] ptr pointer to the buffer of uint8_t words.
apalmieri 14:655c1d3a5d59 226 * @param[in] 16-bit data.
apalmieri 14:655c1d3a5d59 227 * @retval none.
apalmieri 14:655c1d3a5d59 228 */
apalmieri 14:655c1d3a5d59 229 void convertFrom16To8(uint16_t data16, uint8_t *ptr)
apalmieri 14:655c1d3a5d59 230 {
apalmieri 14:655c1d3a5d59 231 *(ptr) = data16 & 0x00FF;
apalmieri 14:655c1d3a5d59 232 *(++ptr) = (data16 >> 8) & 0x00FF;
apalmieri 14:655c1d3a5d59 233 }
apalmieri 14:655c1d3a5d59 234
davide aliprandi <> 9:1f35e8bf427b 235 };
davide aliprandi <> 9:1f35e8bf427b 236
davide aliprandi <> 9:1f35e8bf427b 237 #endif /* __DEV_SPI_H */