1 /* 2 * Author: Brendan Le Foll <brendan.le.foll (at) intel.com> 3 * Copyright (c) 2014 Intel Corporation. 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining 6 * a copy of this software and associated documentation files (the 7 * "Software"), to deal in the Software without restriction, including 8 * without limitation the rights to use, copy, modify, merge, publish, 9 * distribute, sublicense, and/or sell copies of the Software, and to 10 * permit persons to whom the Software is furnished to do so, subject to 11 * the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be 14 * included in all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 */ 24 25 #pragma once 26 27 #include "spi.h" 28 #include "types.hpp" 29 #include <stdexcept> 30 31 namespace mraa 32 { 33 34 /** 35 * MRAA SPI Modes 36 */ 37 typedef enum { 38 SPI_MODE0 = 0, /**< CPOL = 0, CPHA = 0, Clock idle low, data is clocked in on rising edge, 39 output data (change) on falling edge */ 40 SPI_MODE1 = 1, /**< CPOL = 0, CPHA = 1, Clock idle low, data is clocked in on falling edge, 41 output data (change) on rising edge */ 42 SPI_MODE2 = 2, /**< CPOL = 1, CPHA = 0, Clock idle low, data is clocked in on falling edge, 43 output data (change) on rising edge */ 44 SPI_MODE3 = 3, /**< CPOL = 1, CPHA = 1, Clock idle low, data is clocked in on rising, edge 45 output data (change) on falling edge */ 46 } Spi_Mode; 47 48 49 /** 50 * @brief API to Serial Peripheral Interface 51 * 52 * This file defines the SPI interface for libmraa 53 * 54 * @snippet Spi-pot.cpp Interesting 55 */ 56 class Spi 57 { 58 public: 59 /** 60 * Initialise SPI object using the board mapping to set muxes 61 * 62 * @param bus to use, as listed in the platform definition, normally 0 63 */ 64 Spi(int bus) 65 { 66 m_spi = mraa_spi_init(bus); 67 68 if (m_spi == NULL) { 69 throw std::invalid_argument("Error initialising SPI bus"); 70 } 71 } 72 73 /** 74 * Closes spi bus 75 */ 76 ~Spi() 77 { 78 mraa_spi_stop(m_spi); 79 } 80 81 /** 82 * Set the SPI device mode. see spidev0-3 83 * 84 * @param mode the mode. See Linux spidev doc 85 * @return Result of operation 86 */ 87 Result 88 mode(Spi_Mode mode) 89 { 90 return (Result) mraa_spi_mode(m_spi, (mraa_spi_mode_t) mode); 91 } 92 93 /** 94 * Set the SPI device operating clock frequency 95 * 96 * @param hz the frequency to set in hz 97 * @return Result of operation 98 */ 99 Result 100 frequency(int hz) 101 { 102 return (Result) mraa_spi_frequency(m_spi, hz); 103 } 104 105 /** 106 * Write single byte to the SPI device 107 * 108 * @param data the byte to send 109 * @return data received on the miso line or -1 in case of error 110 */ 111 int 112 writeByte(uint8_t data) 113 { 114 return mraa_spi_write(m_spi, (uint8_t) data); 115 } 116 117 /** 118 * Write single byte to the SPI device 119 * 120 * @param data the byte to send 121 * @return data received on the miso line 122 */ 123 uint16_t 124 write_word(uint16_t data) 125 { 126 return mraa_spi_write_word(m_spi, (uint16_t) data); 127 } 128 129 /** 130 * Write buffer of bytes to SPI device The pointer return has to be 131 * free'd by the caller. It will return a NULL pointer in cases of 132 * error 133 * 134 * @param txBuf buffer to send 135 * @param length size of buffer to send 136 * @return uint8_t* data received on the miso line. Same length as passed in 137 */ 138 uint8_t* 139 write(uint8_t* txBuf, int length) 140 { 141 return mraa_spi_write_buf(m_spi, txBuf, length); 142 } 143 144 #ifndef SWIG 145 /** 146 * Write buffer of bytes to SPI device The pointer return has to be 147 * free'd by the caller. It will return a NULL pointer in cases of 148 * error 149 * 150 * @param txBuf buffer to send 151 * @param length size of buffer (in bytes) to send 152 * @return uint8_t* data received on the miso line. Same length as passed in 153 */ 154 uint16_t* 155 write_word(uint16_t* txBuf, int length) 156 { 157 return mraa_spi_write_buf_word(m_spi, txBuf, length); 158 } 159 #endif 160 161 #ifndef SWIG 162 /** 163 * Transfer data to and from SPI device Receive pointer may be null if 164 * return data is not needed. 165 * 166 * @param txBuf buffer to send 167 * @param rxBuf buffer to optionally receive data from spi device 168 * @param length size of buffer to send 169 * @return Result of operation 170 */ 171 Result 172 transfer(uint8_t* txBuf, uint8_t* rxBuf, int length) 173 { 174 return (Result) mraa_spi_transfer_buf(m_spi, txBuf, rxBuf, length); 175 } 176 177 /** 178 * Transfer data to and from SPI device Receive pointer may be null if 179 * return data is not needed. 180 * 181 * @param txBuf buffer to send 182 * @param rxBuf buffer to optionally receive data from spi device 183 * @param length size of buffer to send 184 * @return Result of operation 185 */ 186 Result 187 transfer_word(uint16_t* txBuf, uint16_t* rxBuf, int length) 188 { 189 return (Result) mraa_spi_transfer_buf_word(m_spi, txBuf, rxBuf, length); 190 } 191 #endif 192 193 /** 194 * Change the SPI lsb mode 195 * 196 * @param lsb Use least significant bit transmission - 0 for msbi 197 * @return Result of operation 198 */ 199 Result 200 lsbmode(bool lsb) 201 { 202 return (Result) mraa_spi_lsbmode(m_spi, (mraa_boolean_t) lsb); 203 } 204 205 /** 206 * Set bits per mode on transaction, default is 8 207 * 208 * @param bits bits per word 209 * @return Result of operation 210 */ 211 Result 212 bitPerWord(unsigned int bits) 213 { 214 return (Result) mraa_spi_bit_per_word(m_spi, bits); 215 } 216 217 private: 218 mraa_spi_context m_spi; 219 }; 220 } 221