]> rtime.felk.cvut.cz Git - pes-rpp/rpp-lib.git/blobdiff - rpp/src/drv/spi.c
Change license to MIT
[pes-rpp/rpp-lib.git] / rpp / src / drv / spi.c
index 1e86ef625a9b53c158e6e15abff53d75beb505d8..4bb559167cad1ab29172a3c0f5b33b16fafc206c 100644 (file)
+/* Copyright (C) 2012-2013, 2015 Czech Technical University in Prague
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * File : spi.c
+ */
 
-//#include "ul/ul_list.h"
-//#include "drv/spi.h"
-//#include "cpu_def.h"
-#include "ul/ul_list.h"
-#include "drv/drv.h"
+#include "drv/spi.h"
+#include "drv/spi_tms570.h"
 
-int spi_msg_rq_ins(spi_drv_t *ifc, spi_msg_head_t *msg)
-{
-    spi_isr_lock_level_t saveif;
+static boolean_t spi_initialized = FALSE;
 
-    if (!ifc)
-        return -1;
+int spi_init()
+{
+       if (spi_initialized == TRUE)
+               return FAILURE;
+       spi_initialized = TRUE;
 
-    if (!(ifc->flags & SPI_IFC_ON))
-        return -1;
+       spi_tms570_init();
+       return SUCCESS;
+}
 
-    spi_isr_lock(saveif);
-    spi_rq_queue_insert(ifc, msg);
-    spi_isr_unlock(saveif);
-    ifc->ctrl_fnc(ifc, SPI_CTRL_WAKE_RQ, NULL);
-    return 0;
+static int spi_transfer_callback(struct spi_drv *ifc, int code, struct spi_msg *msg)
+{
+       if (msg->private)
+               msg->private = 0;
+       return 0;
 }
 
-int spi_transfer_callback(struct spi_drv *ifc, int code, struct spi_msg_head *msg)
+/*
+ * Send SPI message asynchronously
+ *
+ * This function is thread safe.
+ */
+int spi_msg_rq_ins(spi_msg_t *msg)
 {
-    if (msg->private) {
-        msg->private = 0;
-    }
-    return 0;
+       spi_isr_lock_level_t saveif;
+       spi_drv_t *ifc = spi_tms570_get_iface(msg->dev);
+
+       spi_isr_lock(saveif);
+       spi_rq_queue_insert(ifc, msg);
+       spi_isr_unlock(saveif);
+       ifc->ctrl_fnc(ifc, SPI_CTRL_WAKE_RQ, NULL);
+       return 0;
 }
 
-int spi_transfer(spi_drv_t *ifc, int addr, int rq_len, const void *tx_buf, void *rx_buf)
+/*
+ * Send SPI message synchronously
+ *
+ * This function is thread safe.
+ */
+int spi_transfer(enum spi_device dev, int rq_len, const void *tx_buf, void *rx_buf)
 {
-    spi_msg_head_t msg;
+       spi_msg_t msg;
 
-    msg.flags = 0;
-    //msg.ifc = NULL;
-    spi_rq_queue_init_detached(&msg);
-    msg.addr = addr;
-    msg.rq_len = rq_len;
-    msg.tx_buf = tx_buf;
-    msg.rx_buf = rx_buf;
-    msg.callback = spi_transfer_callback;
-    msg.private = 1;
+       msg.flags = 0;
+       //msg.ifc = NULL;
+       spi_rq_queue_init_detached(&msg);
+       msg.dev = dev;
+       msg.rq_len = rq_len;
+       msg.tx_buf = tx_buf;
+       msg.rx_buf = rx_buf;
+       msg.callback = spi_transfer_callback;
+       msg.private = 1;
 
-    if (spi_msg_rq_ins(ifc, &msg) < 0)
-        return -1;
+       if (spi_msg_rq_ins(&msg) < 0)
+               return -1;
 
-    /* Wait for the request completion */
-    while (msg.private) {
-        __memory_barrier();
-    }
+       /* Wait for the request completion */
+       while (msg.private)
+               __memory_barrier();
 
 
-    if (msg.flags & (SPI_MSG_FAIL | SPI_MSG_ABORT))
-        return -1;
+       if (msg.flags & (SPI_MSG_FAIL | SPI_MSG_ABORT))
+               return -1;
 
-    return msg.rq_len;
+       return msg.rq_len;
 }
 
+#define MIN(a,b) ((a) < (b) ? (a) : (b))
+
+int8_t port_spi_set(const struct port_desc *port, void *values, size_t size)
+{
+       uint8_t rx[24];
+
+       assert(size == port->numchn * port->bpch / 8);
+       assert(size <= sizeof(rx));
+
+       spi_transfer(port->cfg.spi.dev, size, values, rx);
+
+       memcpy(values, rx, MIN(size, port->numchn * port->bpch/8));
+       return SUCCESS;
+}