1/*
2 * Author: Brendan Le Foll <brendan.le.foll@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
31namespace mraa
32{
33
34/**
35 * MRAA SPI Modes
36 */
37typedef 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*/
56class 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