spi: Add 16bit wide convenience functions for spi
authorMichael Ring <michael.ring@swisscom.com>
Tue, 17 Feb 2015 15:34:01 +0000 (15:34 +0000)
committerBrendan Le Foll <brendan.le.foll@intel.com>
Tue, 17 Feb 2015 15:39:54 +0000 (15:39 +0000)
Signed-off-by: Michael Ring <mail@michael-ring.org>
Signed-off-by: Brendan Le Foll <brendan.le.foll@intel.com>
api/mraa/spi.h
api/mraa/spi.hpp
src/spi/spi.c

index 0b7a993..3530ebd 100644 (file)
@@ -104,6 +104,14 @@ mraa_result_t mraa_spi_frequency(mraa_spi_context dev, int hz);
  */
 uint8_t mraa_spi_write(mraa_spi_context dev, uint8_t data);
 
+/** Write Two Bytes to the SPI device.
+*
+* @param dev The Spi context
+* @param data Data to send
+* @return Data received on the miso line
+*/
+uint16_t mraa_spi_write_word(mraa_spi_context dev, uint16_t data);
+
 /** Write Buffer of bytes to the SPI device. The pointer return has to be
  * free'd by the caller. It will return a NULL pointer in cases of error.
  *
@@ -114,6 +122,16 @@ uint8_t mraa_spi_write(mraa_spi_context dev, uint8_t data);
  */
 uint8_t* mraa_spi_write_buf(mraa_spi_context dev, uint8_t* data, int length);
 
+/** Write Buffer of uint16 to the SPI device. The pointer return has to be
+* free'd by the caller. It will return a NULL pointer in cases of error.
+*
+* @param dev The Spi context
+* @param data to send
+* @param length elements (in bytes) within buffer, Max 4096
+* @return Data received on the miso line, same length as passed in
+*/
+uint16_t* mraa_spi_write_buf_word(mraa_spi_context dev, uint16_t* data, int length);
+
 /** Transfer Buffer of bytes to the SPI device. Both send and recv buffers
  * are passed in
  *
@@ -125,6 +143,17 @@ uint8_t* mraa_spi_write_buf(mraa_spi_context dev, uint8_t* data, int length);
  */
 mraa_result_t mraa_spi_transfer_buf(mraa_spi_context dev, uint8_t* data, uint8_t* rxbuf, int length);
 
+/** Transfer Buffer of uint16 to the SPI device. Both send and recv buffers
+* are passed in
+*
+* @param dev The Spi context
+* @param data to send
+* @param rxbuf buffer to recv data back, may be NULL
+* @param length elements (in bytes) within buffer, Max 4096
+* @return Result of operation
+*/
+mraa_result_t mraa_spi_transfer_buf_word(mraa_spi_context dev, uint16_t* data, uint16_t* rxbuf, int length);
+
 /**
  * Change the SPI lsb mode
  *
index d11cb7d..7ab1f9f 100644 (file)
@@ -100,6 +100,16 @@ class Spi {
         }
 
         /**
+         * Write single byte to the SPI device
+         *
+         * @param data the byte to send
+         * @return data received on the miso line
+         */
+        uint16_t write_word(uint16_t data) {
+            return mraa_spi_write_word(m_spi, (uint16_t) data);
+        }
+
+        /**
          * Write buffer of bytes to SPI device The pointer return has to be
         * free'd by the caller. It will return a NULL pointer in cases of
         * error
@@ -112,6 +122,19 @@ class Spi {
             return mraa_spi_write_buf(m_spi, txBuf, length);
         }
 
+        /**
+         * Write buffer of bytes to SPI device The pointer return has to be
+         * free'd by the caller. It will return a NULL pointer in cases of
+         * error
+         *
+         * @param txBuf buffer to send
+         * @param length size of buffer (in bytes) to send
+         * @return uint8_t* data received on the miso line. Same length as passed in
+         */
+        uint16_t* write_word(uint16_t* txBuf, int length) {
+            return mraa_spi_write_buf_word(m_spi, txBuf, length);
+        }
+
 #ifndef SWIG
         /**
          * Transfer data to and from SPI device Receive pointer may be null if
@@ -125,6 +148,19 @@ class Spi {
         mraa_result_t transfer(uint8_t* txBuf, uint8_t* rxBuf, int length) {
             return mraa_spi_transfer_buf(m_spi, txBuf, rxBuf, length);
         }
+
+        /**
+         * Transfer data to and from SPI device Receive pointer may be null if
+         * return data is not needed.
+         *
+         * @param data buffer to send
+         * @param rxBuf buffer to optionally receive data from spi device
+         * @param length size of buffer to send
+         * @return Result of operation
+         */
+        mraa_result_t transfer_word(uint16_t* txBuf, uint16_t* rxBuf, int length) {
+            return mraa_spi_transfer_buf_word(m_spi, txBuf, rxBuf, length);
+        }
 #endif
 
         /**
index c5d7997..89fbe67 100644 (file)
@@ -256,6 +256,27 @@ mraa_spi_write(mraa_spi_context dev, uint8_t data)
     return recv;
 }
 
+uint16_t
+mraa_spi_write_word(mraa_spi_context dev, uint16_t data) {
+    struct spi_ioc_transfer msg;
+    memset(&msg, 0, sizeof(msg));
+
+    uint16_t length = 2;
+
+    uint16_t recv = 0;
+    msg.tx_buf = (unsigned long) &data;
+    msg.rx_buf = (unsigned long) &recv;
+    msg.speed_hz = dev->clock;
+    msg.bits_per_word = dev->bpw;
+    msg.delay_usecs = 0;
+    msg.len = length;
+    if (ioctl(dev->devfd, SPI_IOC_MESSAGE(1), &msg) < 0) {
+        syslog(LOG_ERR, "spi: Failed to perform dev transfer");
+        return -1;
+    }
+    return recv;
+}
+
 mraa_result_t
 mraa_spi_transfer_buf(mraa_spi_context dev, uint8_t* data, uint8_t* rxbuf, int length)
 {
@@ -275,6 +296,24 @@ mraa_spi_transfer_buf(mraa_spi_context dev, uint8_t* data, uint8_t* rxbuf, int l
     return MRAA_SUCCESS;
 }
 
+mraa_result_t
+mraa_spi_transfer_buf_word(mraa_spi_context dev, uint16_t *data, uint16_t *rxbuf, int length) {
+    struct spi_ioc_transfer msg;
+    memset(&msg, 0, sizeof(msg));
+
+    msg.tx_buf = (unsigned long) data;
+    msg.rx_buf = (unsigned long) rxbuf;
+    msg.speed_hz = dev->clock;
+    msg.bits_per_word = dev->bpw;
+    msg.delay_usecs = 0;
+    msg.len = length;
+    if (ioctl(dev->devfd, SPI_IOC_MESSAGE(1), &msg) < 0) {
+        syslog(LOG_ERR, "spi: Failed to perform dev transfer");
+        return MRAA_ERROR_INVALID_RESOURCE;
+    }
+    return MRAA_SUCCESS;
+}
+
 uint8_t*
 mraa_spi_write_buf(mraa_spi_context dev, uint8_t* data, int length)
 {
@@ -287,6 +326,19 @@ mraa_spi_write_buf(mraa_spi_context dev, uint8_t* data, int length)
     return recv;
 }
 
+uint16_t *
+mraa_spi_write_buf_word(mraa_spi_context dev, uint16_t *data, int length) {
+    uint16_t* recv = malloc(sizeof(uint16_t) * length);
+
+    if (mraa_spi_transfer_buf_word(dev, data, recv, length) != MRAA_SUCCESS) {
+        free(recv);
+        return NULL;
+    }
+    return recv;
+}
+
+
+
 mraa_result_t
 mraa_spi_stop(mraa_spi_context dev)
 {