+/* 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;
+}