#ifndef _TMS570_RPP_SPI_DEF_H
#define _TMS570_RPP_SPI_DEF_H
-#include "drv/spi_tms570.h"
+/* Identifiers of SPI devices (=chips) */
-/* Identifiers of SPI devices (=chips) bound to particular
- * interfaces */
-
-enum spi_ifc1_devices {
+enum spi_device {
SPIDEV_MC33972 = 0,
SPIDEV_NCV7608_2x,
-};
-enum spi_ifc2_devices {
- SPIDEV_SDCARD = 0
-};
-enum spi_ifc3_devices {
- SPIDEV_MCP4922_1 = 0,
+ SPIDEV_SDCARD,
+ SPIDEV_MCP4922_1,
SPIDEV_MCP4922_2,
- SPIDEV_MCP4922_3
-};
-enum spi_ifc4_devices {
- SPIDEV_L99H01 = 0,
+ SPIDEV_MCP4922_3,
+ SPIDEV_L99H01,
SPIDEV_TJA1082_1,
- SPIDEV_TJA1082_2
-};
+ SPIDEV_TJA1082_2,
-extern spi_tms570_iface_t spi_ifcs[4];
+ _SPIDEV_COUNT
+};
#endif
#include "drv/gio.h"
#include "drv/sci.h"
+#ifdef TARGET_HAS_SPI
+#include "drv/spi.h"
+#endif
+
#ifdef TARGET_TMS570_RPP
#include "drv/dac.h"
#include "drv/din.h"
#include "drv/hout.h"
#include "drv/lout.h"
#include "drv/mout.h"
-#include "drv/spi.h"
#endif /* TARGET_TMS570_RPP */
#endif /* __DRV_H */
#include "sys/ti_drv_gio.h"
#include "sys/ti_drv_adc.h"
#include "drv/port_def.h"
+#ifdef TARGET_HAS_SPI
+#include "drv/spi_def.h"
+#endif
/**
* Port descriptor.
struct {
enum pin_name *pins;
} gioset;
+#ifdef TARGET_HAS_SPI
struct {
- uint8_t ifc; /**< SPI interface */
- uint8_t cs; /**< SPI chipselect */
+ enum spi_device dev;
} spi;
+#endif
struct {
adcBASE_t *reg;
uint32_t group;
-/**
+/*
+ * Copyright (C) 2015 Czech Technical University in Prague
*
- * @file spi.h
+ * Authors:
+ * - Michal Sojka <sojkam1@fel.cvut.cz>
*
- * @copyright Copyright (C) 2012-2013, 2015 Czech Technical University in Prague
+ * This document contains proprietary information belonging to Czech
+ * Technical University in Prague. Passing on and copying of this
+ * document, and communication of its contents is not permitted
+ * without prior written authorization.
*
+ * Abstract: Platform independent SPI API.
*/
#ifndef _SPI_DRV_H_
#define _SPI_DRV_H_
-#include "drv/spi_tms570.h"
#include "drv/port.h"
+#include "drv/spi_def.h"
+#include "ul/ul_list.h"
+
+/* Flags */
+#define SPI_MSG_FINISHED 0x040
+#define SPI_MSG_ABORT 0x020
+#define SPI_MSG_FAIL 0x010
+
+#define SPI_CTRL_WAKE_RQ 1
+
+struct spi_drv;
+
+typedef struct spi_msg {
+ uint16_t flags; // message flags
+ enum spi_device dev; // message destination
+
+ //uint16_t size_mode; // message frame len and mode
+ uint16_t rq_len; // requested transfer length
+ const uint8_t *tx_buf; // pointer to TX data
+ uint8_t *rx_buf; // pointer to RX data
+
+ ul_list_node_t node;
+ int (*callback)(struct spi_drv *ifc, int code, struct spi_msg *msg); // Called when whole transfer is finished
+ long private; // If set -- msg is processed by HW
+} spi_msg_t;
+
+typedef int (spi_ctrl_fnc_t)(struct spi_drv *ifc, int ctrl, void *p);
+
+typedef struct spi_drv {
+ uint16_t flags; // Flags
+ //uint16_t self_addr;
+ ul_list_head_t rq_queue; // Queue containing MSG requests to process
+ spi_msg_t *msg_act; // MSG being actually processed
+ spi_ctrl_fnc_t *ctrl_fnc; // Device dependent function responsible for sending data
+ //long private;
+} spi_drv_t;
UL_LIST_CUST_DEC(spi_rq_queue, spi_drv_t, spi_msg_t, rq_queue, node)
-int spi_transfer(spi_drv_t *ifc, int addr, int rq_len, const void *tx_buf, void *rx_buf);
-int spi_msg_rq_ins(spi_drv_t *ifc, spi_msg_t *msg);
+int spi_init();
+int spi_transfer(enum spi_device dev, int rq_len, const void *tx_buf, void *rx_buf);
+int spi_msg_rq_ins(spi_msg_t *msg);
int8_t port_spi_set(const struct port_desc *port, void *values, size_t size);
#endif /* _SPI_DRV_H_ */
#ifndef DRV_SPI_DEF_H
#define DRV_SPI_DEF_H
-/* Definition of spi names (enum spi_id) */
+/* Definition of spi names (enum spi_device) */
#if defined(TARGET_POSIX)
-//#include "drv/_rm48_hdk/spi_def.h"
+#include "drv/_rm48_hdk/spi_def.h"
#elif defined(TARGET_RM48_HDK)
-//#include "drv/_rm48_hdk/spi_def.h"
+#include "drv/_rm48_hdk/spi_def.h"
#elif defined(TARGET_TMS570_HDK)
-//#include "drv/_tms570_hdk/spi_def.h"
+#include "drv/_tms570_hdk/spi_def.h"
#elif defined(TARGET_TMS570_HYDCTR)
-//#include "drv/_tms570_hydctr/spi_def.h"
+#include "drv/_tms570_hydctr/spi_def.h"
#elif defined(TARGET_TMS570_RPP)
#include "drv/_tms570_rpp/spi_def.h"
#else
#ifndef _MYSPI_H_
#define _MYSPI_H_
-//#include "sys_common.h"
-//#include "drv_spi.h"
-#include "ul/ul_list.h"
#include "types.h"
#include "sys/cpu_def.h"
-
-#define SPI_IFC_ON 1
-#define SPI_CTRL_WAKE_RQ 1
+#include "drv/spi.h"
/* ------------------------------------------------------------------------- */
-#define SPI_MSG_FINISHED 0x040
-#define SPI_MSG_ABORT 0x020
-#define SPI_MSG_FAIL 0x010
-
#define SPI_BR_FORMAT0 1000000 /**< Clock rate for data format 0 in Hz. */
#define SPI_BR_FORMAT1 1000000 /**< Clock rate for data format 0 in Hz. */
#define SPI_BR_FORMAT2 1000000 /**< Clock rate for data format 0 in Hz. */
#define SPI_BR_FORMAT3 1000000 /**< Clock rate for data format 0 in Hz. */
-
-struct spi_drv;
-
-typedef int (spi_ctrl_fnc_t)(struct spi_drv *ifc, int ctrl, void *p);
-
-typedef struct spi_msg {
- uint16_t flags; // message flags
- uint16_t addr; // message destination address -- used as index into the "address translation table"*/
-
- //uint16_t size_mode; // message frame len and mode
- uint16_t rq_len; // requested transfer length
- const uint8_t *tx_buf; // pointer to TX data
- uint8_t *rx_buf; // pointer to RX data
-
- ul_list_node_t node;
- //struct spi_drv *ifc;
- int (*callback)(struct spi_drv *ifc, int code, struct spi_msg *msg); // Called when whole transfer is finished
- long private; // If set -- msg is processed by HW
-} spi_msg_t;
-
-typedef struct spi_drv {
- uint16_t flags; // Flags
- //uint16_t self_addr;
- ul_list_head_t rq_queue; // Queue containing MSG requests to process
- spi_msg_t *msg_act; // MSG being actually processed
- spi_ctrl_fnc_t *ctrl_fnc; // Device dependent function responsible for sending data
- //long private;
-} spi_drv_t;
-
/* ------------------------------------------------------------------------- */
typedef unsigned long spi_isr_lock_level_t;
/* ------------------------------------------------------------------------- */
-#define spi_compat_REG2 ((spiBASE_compat_t *)0xFFF7F600U)
-#define spi_compat_REG4 ((spiBASE_compat_t *)0xFFF7FA00U)
-#define mibspi_compat_REG1 ((spiBASE_compat_t *)0xFFF7F400U)
-#define mibspi_compat_REG3 ((spiBASE_compat_t *)0xFFF7F800U)
-#define mibspi_compat_REG5 ((spiBASE_compat_t *)0xFFF7FC00U) /* NOT USED ON RPP BOARD */
-
-
-#define SPI_FLG_TXINT_m (1 << 9)
-#define SPI_FLG_RXINT_m (1 << 8)
-
-#define SPI_INT0_TXINTENA_m (1 << 9)
-#define SPI_INT0_RXINTENA_m (1 << 8)
-
-#define SPI_DAT1_CSHOLD_m (1 << 28)
-
/* Used as CSNR in DATA1 reg */
enum spiChipSelect {
SPI_CS_NONE = 0x00FF,
SPI_CS_DMM2 = 0x0400
};
-
-
-typedef volatile struct spiBase {
- uint32_t GCR0; /**< 0x0000: Global Control 0 */
-#if ((__little_endian__ == 1) || (__LITTLE_ENDIAN__ == 1))
- uint32_t GCR1 : 8U; /**< 0x0007: Global Control 1 */
- uint32_t PD : 1U; /**< 0x0006: Power down bit */
- uint32_t : 7U;
- uint32_t LB : 1U; /**< 0x0005: Loop back bit */
- uint32_t : 7U;
- uint32_t ENA : 1U; /**< 0x0004: SPI Enable bit */
- uint32_t : 7U;
- uint32_t INT0 : 16U; /**< 0x000A: Interrupt Enable bits */
- uint32_t DMAREQEN : 1U; /**< 0x0009: DMA Request enable */
- uint32_t : 7U;
- uint32_t ENAHIGHZ : 1U; /**< 0x0008: Enable HIGHZ outputs */
- uint32_t : 7U;
-#else
- uint32_t : 7U;
- uint32_t ENA : 1U; /**< 0x0004: SPI Enable bit */
- uint32_t : 7U;
- uint32_t LB : 1U; /**< 0x0005: Loop back bit */
- uint32_t : 7U;
- uint32_t PD : 1U; /**< 0x0006: Power down bit */
- uint32_t GCR1 : 8U; /**< 0x0007: Global Control 1 */
- uint32_t : 7U;
- uint32_t ENAHIGHZ : 1U; /**< 0x0008: Enable HIGHZ outputs */
- uint32_t : 7U;
- uint32_t DMAREQEN : 1U; /**< 0x0009: DMA Request enable */
- uint32_t INT0 : 16U; /**< 0x000A: Interrupt Enable bits */
-#endif
- uint32_t LVL; /**< 0x000C: Interrupt Level */
-#if ((__little_endian__ == 1) || (__LITTLE_ENDIAN__ == 1))
- uint32_t FLG : 16U; /**< 0x0012: Interrupt flags */
- uint32_t : 8U;
- uint32_t BUFINIT : 1U; /**< 0x0010: Buffer initialization active flag */
- uint32_t : 7U;
-#else
- uint32_t : 7U;
- uint32_t BUFINIT : 1U; /**< 0x0010: Buffer initialization active flag */
- uint32_t : 8U;
- uint32_t FLG : 16U; /**< 0x0012: Interrupt flags */
-#endif
- uint32_t PCFUN; /**< 0x0014: Function Pin Enable */
- uint32_t PCDIR; /**< 0x0018: Pin Direction */
- uint32_t PCDIN; /**< 0x001C: Pin Input Latch */
- uint32_t PCDOUT; /**< 0x0020: Pin Output Latch */
- uint32_t PCSET; /**< 0x0024: Output Pin Set */
- uint32_t PCCLR; /**< 0x0028: Output Pin Clr */
- uint32_t PCPDR; /**< 0x002C: Open Drain Output Enable */
- uint32_t PCDIS; /**< 0x0030: Pullup/Pulldown Disable */
- uint32_t PCPSL; /**< 0x0034: Pullup/Pulldown Selection */
- uint32_t DAT0; /**< 0x0038: Transmit Data */
- uint32_t DAT1; /**< 0x003C: Transmit Data with Format and Chip Select */
- uint32_t BUF; /**< 0x0040: Receive Buffer */
- uint32_t EMU; /**< 0x0044: Emulation Receive Buffer */
- uint32_t DELAY; /**< 0x0048: Delays */
- uint32_t CSDEF; /**< 0x004C: Default Chip Select */
- uint32_t FMT0; /**< 0x0050: Data Format 0 */
- uint32_t FMT1; /**< 0x0054: Data Format 1 */
- uint32_t FMT2; /**< 0x0058: Data Format 2 */
- uint32_t FMT3; /**< 0x005C: Data Format 3 */
- uint32_t INTVECT0; /**< 0x0060: Interrupt Vector 0 */
- uint32_t INTVECT1; /**< 0x0064: Interrupt Vector 1 */
- uint32_t SRSEL; /**< 0x0068: Slew Rate Select */
-
- uint32_t PMCTRL; /**< 0x006C: Parallel Mode Control */
-#if ((__little_endian__ == 1) || (__LITTLE_ENDIAN__ == 1))
- uint32_t MIBSPIE : 16U; /**< 0x0072: MibSPI Enable */
- uint32_t RAMACCESS : 16U; /**< 0x0070: RX Ram Write Access Enable */
-#else
- uint32_t RAMACCESS : 16U; /**< 0x0070: RX Ram Write Access Enable */
- uint32_t MIBSPIE : 16U; /**< 0x0072: MibSPI Enable */
-#endif
-
- uint32_t RESERVED[48U]; /**< 0x006C to 0x0130: Reserved */
- uint32_t IOLPKTSTCR; /**< 0x0134: IO loopback */
-} spiBASE_compat_t;
-
+enum spi_iface {
+ SPI_IFACE1,
+ SPI_IFACE2,
+ SPI_IFACE3,
+ SPI_IFACE4,
+ SPI_IFACE5,
+};
/* SPI devices connected to SPI interface */
typedef struct spi_dev {
+ enum spi_iface iface;
unsigned int cs; /* Combination of CS (+GPIO CS) necessary to enable the device */
- unsigned char dfsel; /* Data word format */
+ unsigned char dfsel; /* Data word format (FMTx registers) */
unsigned char wdel; /* Enable the delay counter at the end of the current transaction */
unsigned char cshold; /* Chip select hold mode */
unsigned int dlen; /* Data len needed for one complete transfer */
} spi_dev_t;
-/* SPI interface */
-typedef struct spi_tms570_iface {
- spi_drv_t spi_drv;
- spiBASE_compat_t *reg; /* Base Reg. for SPI device register array */
- unsigned txcnt; /* No. of transfered bytes for msg_act */
- unsigned rxcnt; /* No. of received bytes for msg_act */
- spi_dev_t *spi_devs; /* Pointer to table holding information about SPI devices bound to the interface */
- uint32_t transfer_ctrl; /* Transfer configuration -- upper 16 bits of SPIDAT1 register */
- /* TODO: Add FMT description here if we need different formats */
-} spi_tms570_iface_t;
+extern const spi_dev_t spi_devs[_SPIDEV_COUNT];
+
+typedef struct spi_tms570_iface spi_tms570_iface_t;
-//extern spi_tms570_iface_t spi_tms570_ifcs[4];
-//extern spi_dev_t spi_devs[];
-int spi_tms570_init(spi_tms570_iface_t *ifcs, int count);
+spi_drv_t *spi_tms570_get_iface(enum spi_device dev);
-spi_drv_t *spi_find_drv(char *name, int number);
+void spi_tms570_init();
+int spi_msg_rq_ins(spi_msg_t *msg);
#endif /* _MYSPI_H_ */
#include "drv/gio_names.h"
#include "drv/gio_tab.h"
#include "drv/spi.h"
-#include "drv/spi_tms570.h"
#include "drv/adc.h"
// Lists of pins assigned to the gio ports
.numchn = 1,
.bpch = 24,
.set = port_spi_set,
- .cfg = { .spi = { .ifc = 1, .cs = 0 } },
+ .cfg = { .spi = { .dev = SPIDEV_MC33972 } },
},
[PORT_ID_HOUTDIAG] = {
.name = "HOUTDIAG",
.bpch = 32,
.get = NULL,
.set = port_spi_set,
- .cfg = { .spi = { .ifc = 1, .cs = 1 }, },
+ .cfg = { .spi = { .dev = SPIDEV_NCV7608_2x }, },
},
[PORT_ID_DAC1_2] = {
.name = "DAC12",
.bpch = 16,
.get = NULL,
.set = port_spi_set,
- .cfg = { .spi = { .ifc = 3, .cs = 0 }, },
+ .cfg = { .spi = { .dev = SPIDEV_MCP4922_1 }, },
},
[PORT_ID_DAC3_4] = {
.name = "DAC34",
.bpch = 16,
.get = NULL,
.set = port_spi_set,
- .cfg = { .spi = { .ifc = 3, .cs = 1 }, },
+ .cfg = { .spi = { .dev = SPIDEV_MCP4922_2 }, },
},
[PORT_ID_DACDREF] = {
.name = "DACDREF", /* Reference voltage for DIN */
.bpch = 16,
.get = NULL,
.set = port_spi_set,
- .cfg = { .spi = { .ifc = 3, .cs = 2 }, },
+ .cfg = { .spi = { .dev = SPIDEV_MCP4922_3 }, },
},
[PORT_ID_HBR] = {
.name = "HBR",
.bpch = 16,
.get = NULL,
.set = port_spi_set,
- .cfg = { .spi = { .ifc = 4, .cs = 0 }, },
+ .cfg = { .spi = { .dev = SPIDEV_L99H01 }, },
},
[PORT_ID_FRAY1] = {
.name = "FRAY1",
.bpch = 16,
.get = NULL,
.set = port_spi_set,
- .cfg = { .spi = { .ifc = 4, .cs = 1 }, },
+ .cfg = { .spi = { .dev = SPIDEV_TJA1082_1 }, },
},
[PORT_ID_FRAY2] = {
.name = "FRAY2",
.bpch = 16,
.get = NULL,
.set = port_spi_set,
- .cfg = { .spi = { .ifc = 4, .cs = 2 }, },
+ .cfg = { .spi = { .dev = SPIDEV_TJA1082_2 }, },
},
[PORT_ID_MOUTEN] = {
.name = "MOUTEN",
#include "drv/spi_def.h"
#include "drv/spi_tms570.h"
-static spi_dev_t spi_ifc1_devs[] = {
+const spi_dev_t spi_devs[_SPIDEV_COUNT] = {
[SPIDEV_MC33972] = {
+ .iface = SPI_IFACE1,
.cs = SPI_CS_3,
.dfsel = 0,
.wdel = 0,
.dlen = 0
},
[SPIDEV_NCV7608_2x] = {
+ .iface = SPI_IFACE1,
.cs = SPI_CS_4,
.dfsel = 0,
.wdel = 0,
.cshold = 1,
.dlen = 0
- }
-};
+ },
-static spi_dev_t spi_ifc2_devs[] = {
[SPIDEV_SDCARD] = {
+ .iface = SPI_IFACE2,
.cs = SPI_CS_0,
.dfsel = 0,
.wdel = 0,
.cshold = 1,
.dlen = 0
- }
-};
+ },
-static spi_dev_t spi_ifc3_devs[] = {
[SPIDEV_MCP4922_1] = {
+ .iface = SPI_IFACE3,
.cs = SPI_CS_0,
.dfsel = 1,
.wdel = 0,
.dlen = 0
},
[SPIDEV_MCP4922_2] = {
+ .iface = SPI_IFACE3,
.cs = SPI_CS_4,
.dfsel = 1,
.wdel = 0,
.dlen = 0
},
[SPIDEV_MCP4922_3] = {
+ .iface = SPI_IFACE3,
.cs = SPI_CS_5,
.dfsel = 1,
.wdel = 0,
.cshold = 1,
.dlen = 0
- }
-};
+ },
-static spi_dev_t spi_ifc4_devs[] = {
[SPIDEV_L99H01] = {
+ .iface = SPI_IFACE4,
.cs = SPI_CS_0 | SPI_CS_DMM0,
.dfsel = 1,
.wdel = 0,
.dlen = 0
},
[SPIDEV_TJA1082_1] = {
+ .iface = SPI_IFACE4,
.cs = SPI_CS_0 | SPI_CS_DMM1,
.dfsel = 0,
.wdel = 0,
.dlen = 0
},
[SPIDEV_TJA1082_2] = {
+ .iface = SPI_IFACE4,
.cs = SPI_CS_0 | SPI_CS_DMM2,
.dfsel = 0,
.wdel = 0,
.dlen = 0
}
};
-
-/* Each SPI interface has its own static spi_tms570_drv_t struct
- Index to this array is "SPI Interface ID -1" */
-spi_tms570_iface_t spi_ifcs[4] = {
- [0] = {
- .reg = mibspi_compat_REG1,
- .spi_devs = spi_ifc1_devs,
- },
- [1] = {
- .reg = spi_compat_REG2,
- .spi_devs = spi_ifc2_devs,
- },
- [2] = {
- .reg = mibspi_compat_REG3,
- .spi_devs = spi_ifc3_devs,
- },
- [3] = {
- .reg = spi_compat_REG4,
- .spi_devs = spi_ifc4_devs,
- },
-};
// PWM is available for HBR control.
#include "drv/drv.h"
#include <os/semphr.h>
-#include "drv/spi.h"
+#include "drv/spi_tms570.h"
#include "drv/gio_tab.h"
//Flag variable if pwm was initialized and is ready to start.
// SPI message format definition for watchdog reset command
spi_msg_t hbr_spi_wdg = {
.flags = 0,
- .addr = 0,
+ .dev = SPIDEV_L99H01,
.rq_len = 2,
.tx_buf = (uint8_t *)&hbr_spi_wdg_tx_shd,
.rx_buf = (uint8_t *)&hbr_spi_wdg_rx_shd,
*/
void drv_hbr_wdg_task(void *p)
{
- spi_drv_t *ifc;
-
- ifc = spi_find_drv(NULL, 4);
-
- if (ifc == NULL) {
- wdg_start = FALSE;
- vTaskDelete(NULL);
- }
-
portTickType xLastWakeTime;
xLastWakeTime = xTaskGetTickCount();
wdg_start = FALSE;
}
else
- spi_msg_rq_ins(ifc, &hbr_spi_wdg);
+ spi_msg_rq_ins(&hbr_spi_wdg);
xSemaphoreGive(wdg_sync);
}
}
dmmInit();
gioInit();
hetInit();
- //spi_tms570_init();
+ //spi_init();
}
/**
* File : spi.c
*/
-//#include "ul/ul_list.h"
-//#include "drv/spi.h"
-//#include "cpu_def.h"
-//#include "ul/ul_list.h"
#include "drv/spi.h"
+#include "drv/spi_tms570.h"
-int spi_msg_rq_ins(spi_drv_t *ifc, spi_msg_t *msg)
+static boolean_t spi_initialized = FALSE;
+
+int spi_init()
{
- spi_isr_lock_level_t saveif;
+ if (spi_initialized == TRUE)
+ return FAILURE;
+ spi_initialized = TRUE;
- if (!ifc)
- return -1;
+ spi_tms570_init();
+ return SUCCESS;
+}
- if (!(ifc->flags & SPI_IFC_ON))
- return -1;
+static int spi_transfer_callback(struct spi_drv *ifc, int code, struct spi_msg *msg)
+{
+ if (msg->private)
+ msg->private = 0;
+ return 0;
+}
+
+/*
+ * Send SPI message asynchronously
+ *
+ * This function is thread safe.
+ */
+int spi_msg_rq_ins(spi_msg_t *msg)
+{
+ 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);
return 0;
}
-int spi_transfer_callback(struct spi_drv *ifc, int code, struct spi_msg *msg)
-{
- if (msg->private)
- msg->private = 0;
- return 0;
-}
-
/*
+ * Send SPI message synchronously
+ *
* This function is thread safe.
*/
-int spi_transfer(spi_drv_t *ifc, int addr, int rq_len, const void *tx_buf, void *rx_buf)
+int spi_transfer(enum spi_device dev, int rq_len, const void *tx_buf, void *rx_buf)
{
spi_msg_t msg;
msg.flags = 0;
//msg.ifc = NULL;
spi_rq_queue_init_detached(&msg);
- msg.addr = addr;
+ 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)
+ if (spi_msg_rq_ins(&msg) < 0)
return -1;
/* Wait for the request completion */
int8_t port_spi_set(const struct port_desc *port, void *values, size_t size)
{
- spi_drv_t *ifc;
uint8_t rx[4];
assert(port->numchn == 1);
assert(size == port->bpch/8);
assert(size <= sizeof(rx));
- ifc = spi_find_drv(NULL, port->cfg.spi.ifc);
- if (ifc == NULL)
- return FAILURE;
-
- if (!(ifc->flags & SPI_IFC_ON))
- return FAILURE;
-
- spi_transfer(ifc, port->cfg.spi.cs, size, values, rx);
+ spi_transfer(port->cfg.spi.dev, size, values, rx);
memcpy(values, rx, MIN(size, port->numchn * port->bpch/8));
return SUCCESS;
#include "drv/spi.h"
#include "sys/port.h"
-//#include "drv_spi.h"
-//#include "sys_common.h"
-//#include "ti_drv_dmm.h"
#include "sys/ti_drv_dmm.h"
#include "drv/spi_def.h"
+#include "drv/spi_tms570.h"
+
+#define SPI_FLG_TXINT_m (1 << 9)
+#define SPI_FLG_RXINT_m (1 << 8)
+
+#define SPI_INT0_TXINTENA_m (1 << 9)
+#define SPI_INT0_RXINTENA_m (1 << 8)
+
+#define SPI_DAT1_CSHOLD_m (1 << 28)
+
+typedef volatile struct spiBase {
+ uint32_t GCR0; /**< 0x0000: Global Control 0 */
+#if ((__little_endian__ == 1) || (__LITTLE_ENDIAN__ == 1))
+ uint32_t GCR1 : 8U; /**< 0x0007: Global Control 1 */
+ uint32_t PD : 1U; /**< 0x0006: Power down bit */
+ uint32_t : 7U;
+ uint32_t LB : 1U; /**< 0x0005: Loop back bit */
+ uint32_t : 7U;
+ uint32_t ENA : 1U; /**< 0x0004: SPI Enable bit */
+ uint32_t : 7U;
+ uint32_t INT0 : 16U; /**< 0x000A: Interrupt Enable bits */
+ uint32_t DMAREQEN : 1U; /**< 0x0009: DMA Request enable */
+ uint32_t : 7U;
+ uint32_t ENAHIGHZ : 1U; /**< 0x0008: Enable HIGHZ outputs */
+ uint32_t : 7U;
+#else
+ uint32_t : 7U;
+ uint32_t ENA : 1U; /**< 0x0004: SPI Enable bit */
+ uint32_t : 7U;
+ uint32_t LB : 1U; /**< 0x0005: Loop back bit */
+ uint32_t : 7U;
+ uint32_t PD : 1U; /**< 0x0006: Power down bit */
+ uint32_t GCR1 : 8U; /**< 0x0007: Global Control 1 */
+ uint32_t : 7U;
+ uint32_t ENAHIGHZ : 1U; /**< 0x0008: Enable HIGHZ outputs */
+ uint32_t : 7U;
+ uint32_t DMAREQEN : 1U; /**< 0x0009: DMA Request enable */
+ uint32_t INT0 : 16U; /**< 0x000A: Interrupt Enable bits */
+#endif
+ uint32_t LVL; /**< 0x000C: Interrupt Level */
+#if ((__little_endian__ == 1) || (__LITTLE_ENDIAN__ == 1))
+ uint32_t FLG : 16U; /**< 0x0012: Interrupt flags */
+ uint32_t : 8U;
+ uint32_t BUFINIT : 1U; /**< 0x0010: Buffer initialization active flag */
+ uint32_t : 7U;
+#else
+ uint32_t : 7U;
+ uint32_t BUFINIT : 1U; /**< 0x0010: Buffer initialization active flag */
+ uint32_t : 8U;
+ uint32_t FLG : 16U; /**< 0x0012: Interrupt flags */
+#endif
+ uint32_t PCFUN; /**< 0x0014: Function Pin Enable */
+ uint32_t PCDIR; /**< 0x0018: Pin Direction */
+ uint32_t PCDIN; /**< 0x001C: Pin Input Latch */
+ uint32_t PCDOUT; /**< 0x0020: Pin Output Latch */
+ uint32_t PCSET; /**< 0x0024: Output Pin Set */
+ uint32_t PCCLR; /**< 0x0028: Output Pin Clr */
+ uint32_t PCPDR; /**< 0x002C: Open Drain Output Enable */
+ uint32_t PCDIS; /**< 0x0030: Pullup/Pulldown Disable */
+ uint32_t PCPSL; /**< 0x0034: Pullup/Pulldown Selection */
+ uint32_t DAT0; /**< 0x0038: Transmit Data */
+ uint32_t DAT1; /**< 0x003C: Transmit Data with Format and Chip Select */
+ uint32_t BUF; /**< 0x0040: Receive Buffer */
+ uint32_t EMU; /**< 0x0044: Emulation Receive Buffer */
+ uint32_t DELAY; /**< 0x0048: Delays */
+ uint32_t CSDEF; /**< 0x004C: Default Chip Select */
+ uint32_t FMT0; /**< 0x0050: Data Format 0 */
+ uint32_t FMT1; /**< 0x0054: Data Format 1 */
+ uint32_t FMT2; /**< 0x0058: Data Format 2 */
+ uint32_t FMT3; /**< 0x005C: Data Format 3 */
+ uint32_t INTVECT0; /**< 0x0060: Interrupt Vector 0 */
+ uint32_t INTVECT1; /**< 0x0064: Interrupt Vector 1 */
+ uint32_t SRSEL; /**< 0x0068: Slew Rate Select */
+
+ uint32_t PMCTRL; /**< 0x006C: Parallel Mode Control */
+#if ((__little_endian__ == 1) || (__LITTLE_ENDIAN__ == 1))
+ uint32_t MIBSPIE : 16U; /**< 0x0072: MibSPI Enable */
+ uint32_t RAMACCESS : 16U; /**< 0x0070: RX Ram Write Access Enable */
+#else
+ uint32_t RAMACCESS : 16U; /**< 0x0070: RX Ram Write Access Enable */
+ uint32_t MIBSPIE : 16U; /**< 0x0072: MibSPI Enable */
+#endif
+
+ uint32_t RESERVED[48U]; /**< 0x006C to 0x0130: Reserved */
+ uint32_t IOLPKTSTCR; /**< 0x0134: IO loopback */
+} spiBASE_compat_t;
+
+#define spi_compat_REG2 ((spiBASE_compat_t *)0xFFF7F600U)
+#define spi_compat_REG4 ((spiBASE_compat_t *)0xFFF7FA00U)
+#define mibspi_compat_REG1 ((spiBASE_compat_t *)0xFFF7F400U)
+#define mibspi_compat_REG3 ((spiBASE_compat_t *)0xFFF7F800U)
+#define mibspi_compat_REG5 ((spiBASE_compat_t *)0xFFF7FC00U) /* NOT USED ON RPP BOARD */
+
+/* SPI interface */
+struct spi_tms570_iface {
+ spi_drv_t spi_drv;
+ spiBASE_compat_t *reg; /* Base Reg. for SPI device register array */
+ unsigned txcnt; /* No. of transfered bytes for msg_act */
+ unsigned rxcnt; /* No. of received bytes for msg_act */
+ spi_dev_t *spi_devs; /* Pointer to table holding information about SPI devices bound to the interface */
+ uint32_t transfer_ctrl; /* Transfer configuration -- upper 16 bits of SPIDAT1 register */
+ /* TODO: Add FMT description here if we need different formats */
+};
+
+spi_tms570_iface_t spi_iface[5] = {
+ [SPI_IFACE1] = { .reg = mibspi_compat_REG1, },
+ [SPI_IFACE2] = { .reg = spi_compat_REG2, },
+ [SPI_IFACE3] = { .reg = mibspi_compat_REG3, },
+ [SPI_IFACE4] = { .reg = spi_compat_REG4, },
+ [SPI_IFACE5] = { .reg = mibspi_compat_REG5, },
+};
+
+spi_drv_t *spi_tms570_get_iface(enum spi_device dev)
+{
+ return &spi_iface[spi_devs[dev].iface].spi_drv;
+}
static int spi_tms570_ctrl_fnc(spi_drv_t *ifc, int ctrl, void *p);
spiREG->ENA = 1U;
}
-static boolean_t spi_initialized = FALSE;
+static void init_iface(spi_tms570_iface_t *iface)
+{
+ spiInit(iface->reg);
+ iface->spi_drv.ctrl_fnc = spi_tms570_ctrl_fnc;
+ spi_rq_queue_init_head(&(iface->spi_drv));
+ iface->spi_drv.msg_act = NULL;
+ iface->spi_drv.flags = 0;
+}
-int spi_tms570_init(spi_tms570_iface_t *ifcs, int count)
+void spi_tms570_init()
{
- if (spi_initialized == TRUE)
- return FAILURE;
- spi_initialized = TRUE;
int i;
- for (i = 0; i < count; i++) {
- spiInit(ifcs[i].reg);
- ifcs[i].spi_drv.ctrl_fnc = spi_tms570_ctrl_fnc;
- spi_rq_queue_init_head(&(ifcs[i].spi_drv));
- ifcs[i].spi_drv.msg_act = NULL;
- ifcs[i].spi_drv.flags = SPI_IFC_ON;
- }
+ for (i = 0; i < ARRAY_SIZE(spi_iface); i++)
+ init_iface(&spi_iface[i]);
//dmmREG->PC5 = (1 << DMM_DATA5); /* Set to L */
//dmmREG->PC5 = (1 << DMM_DATA6); /* Set to L */
-
- return SUCCESS;
}
switch (ctrl) {
case SPI_CTRL_WAKE_RQ:
- if (!(ifc->flags & SPI_IFC_ON))
- return -1;
if (spi_rq_queue_is_empty(ifc))
return 0;
void spi_tms570_isr(int spi_ifc, uint32_t flags)
{
spi_msg_t *msg;
- spi_tms570_iface_t *iface = &spi_ifcs[spi_ifc];
+ spi_tms570_iface_t *iface = &spi_iface[spi_ifc];
+ const spi_dev_t *dev;
spi_isr_lock_level_t saveif;
uint8_t val_to_wr;
uint32_t cs;
iface->txcnt = 0;
iface->rxcnt = 0;
- cs = iface->spi_devs[msg->addr].cs;
+ dev = &spi_devs[msg->dev];
+ cs = dev->cs;
iface->transfer_ctrl =
(cs & 0xff) << 16
- | (iface->spi_devs[msg->addr].wdel & 0x1) << 26
- | (iface->spi_devs[msg->addr].cshold & 0x1) << 28
- | (iface->spi_devs[msg->addr].dfsel & 0x3) << 24;
+ | (dev->wdel & 0x1) << 26
+ | (dev->cshold & 0x1) << 28
+ | (dev->dfsel & 0x3) << 24;
/* GPIO CS -- setting the multiplexer */
if (cs > 0xff) {
}
}
-spi_drv_t *spi_find_drv(char *name, int number)
-{
- if (number < 1 || number > ARRAY_SIZE(spi_ifcs))
- return NULL;
-
- return &spi_ifcs[number - 1].spi_drv;
-}
-
#pragma INTERRUPT(spi2LowLevelInterrupt, IRQ)
void spi2LowLevelInterrupt(void)
{
#ifndef FREERTOS_POSIX
#include "drv/dac.h"
-#include "drv/spi_def.h"
+#include "drv/spi.h"
#endif
RPP_MUTEX_DEFINE(mutex_dac);
return FAILURE;
initialized = TRUE;
#ifndef FREERTOS_POSIX
- spi_tms570_init(spi_ifcs, ARRAY_SIZE(spi_ifcs));
+ spi_init();
#endif
// Configure board
// FIXME find out why board has default output of ~3.8V
dmmInit();
gioInit();
hetInit();
- spi_tms570_init(spi_ifcs, ARRAY_SIZE(spi_ifcs));
+ spi_init();
#endif
return SUCCESS;
if (rpp_fr_state >= RPP_FR_DRV_INITIALIZED)
return FAILURE;
#ifndef FREERTOS_POSIX
- spi_tms570_init(spi_ifcs, ARRAY_SIZE(spi_ifcs));
+ spi_init();
#endif
if (!RPP_MUTEX_INIT(mutex_fr))
return FAILURE;
#ifndef FREERTOS_POSIX
dmmInit();
hetInit();
- spi_tms570_init(spi_ifcs, ARRAY_SIZE(spi_ifcs));
+ spi_init();
#endif
return SUCCESS;
}
return FAILURE;
initialized = TRUE;
#ifndef FREERTOS_POSIX
- spi_tms570_init(spi_ifcs, ARRAY_SIZE(spi_ifcs));
+ spi_init();
#endif
// FIXME: Implement.