Home | History | Annotate | Download | only in mraa
      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