File indexing completed on 2025-05-11 08:23:03
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <bsp.h>
0010 #include <bspopts.h>
0011 #include <bsp/ssi.h>
0012 #include <bsp/syscon.h>
0013 #include <bsp/io.h>
0014 #include <bsp/lm3s69xx.h>
0015
0016 typedef struct {
0017 rtems_libi2c_bus_t bus;
0018 volatile lm3s69xx_ssi *regs;
0019 int bus_number;
0020 uint16_t idle_char;
0021 uint8_t cs_pin;
0022 lm3s69xx_gpio_config io_configs[3];
0023 } lm3s69xx_ssi_bus_entry;
0024
0025 static rtems_status_code lm3s69xx_ssi_init(rtems_libi2c_bus_t *bus)
0026 {
0027 lm3s69xx_ssi_bus_entry *e = (lm3s69xx_ssi_bus_entry *)bus;
0028 volatile lm3s69xx_ssi* regs = e->regs;
0029 uint32_t clock_div = LM3S69XX_SYSTEM_CLOCK / 2 / LM3S69XX_SSI_CLOCK;
0030
0031 lm3s69xx_gpio_set_config_array(e->io_configs, 3);
0032
0033 lm3s69xx_syscon_enable_ssi_clock(e->bus_number, true);
0034 regs->cr1 = 0;
0035 regs->cpsr = SSI_CPSRDIV(2);
0036 regs->cr0 = SSICR0_SCR(clock_div - 1) | SSICR0_SPO | SSICR0_SPH | SSICR0_FRF(0) | SSICR0_DSS(7);
0037 regs->cr1 = SSICR1_SSE;
0038
0039 return RTEMS_SUCCESSFUL;
0040 }
0041
0042 static rtems_status_code lm3s69xx_ssi_send_start(rtems_libi2c_bus_t *bus)
0043 {
0044 return RTEMS_SUCCESSFUL;
0045 }
0046
0047 static rtems_status_code lm3s69xx_ssi_send_stop(rtems_libi2c_bus_t *bus)
0048 {
0049 lm3s69xx_ssi_bus_entry *e = (lm3s69xx_ssi_bus_entry *)bus;
0050 volatile lm3s69xx_ssi* regs = e->regs;
0051
0052 while ((regs->sr & SSISR_BSY) != 0)
0053 ;
0054
0055 lm3s69xx_gpio_set_pin(e->cs_pin, true);
0056
0057 return RTEMS_SUCCESSFUL;
0058 }
0059
0060 static rtems_status_code lm3s69xx_ssi_send_addr(rtems_libi2c_bus_t *bus,
0061 uint32_t addr, int rw)
0062 {
0063 lm3s69xx_ssi_bus_entry *e = (lm3s69xx_ssi_bus_entry *)bus;
0064 e->cs_pin = addr;
0065 lm3s69xx_gpio_set_pin(e->cs_pin, false);
0066
0067 return RTEMS_SUCCESSFUL;
0068 }
0069
0070 static int lm3s69xx_ssi_read(rtems_libi2c_bus_t *bus, unsigned char *in, int n)
0071 {
0072 lm3s69xx_ssi_bus_entry *e = (lm3s69xx_ssi_bus_entry *)bus;
0073 volatile lm3s69xx_ssi* regs = e->regs;
0074 int i;
0075
0076 for (i = 0; i < n; i++) {
0077 while ((regs->sr & SSISR_TNF) == 0)
0078 ;
0079
0080 regs->dr = e->idle_char;
0081
0082 while ((regs->sr & SSISR_RNE) == 0)
0083 ;
0084
0085 in[i] = regs->dr & 0xff;
0086 }
0087
0088 return n;
0089 }
0090
0091 static int lm3s69xx_ssi_write(rtems_libi2c_bus_t *bus, unsigned char *out, int n)
0092 {
0093 lm3s69xx_ssi_bus_entry *e = (lm3s69xx_ssi_bus_entry *)bus;
0094 volatile lm3s69xx_ssi* regs = e->regs;
0095 int i;
0096
0097 for (i = 0; i < n; i++) {
0098 while ((regs->sr & SSISR_TNF) == 0)
0099 ;
0100
0101 regs->dr = out[i];
0102
0103 while ((regs->sr & SSISR_RNE) == 0)
0104 ;
0105
0106 uint32_t dummy = regs->dr;
0107 (void)dummy;
0108 }
0109
0110 return n;
0111 }
0112
0113 static int lm3s69xx_ssi_ioctl(rtems_libi2c_bus_t *bus, int cmd, void *arg)
0114 {
0115 return -RTEMS_NOT_DEFINED;
0116 }
0117
0118 static const rtems_libi2c_bus_ops_t lm3s69xx_ssi_ops = {
0119 .init = lm3s69xx_ssi_init,
0120 .send_start = lm3s69xx_ssi_send_start,
0121 .send_stop = lm3s69xx_ssi_send_stop,
0122 .send_addr = lm3s69xx_ssi_send_addr,
0123 .read_bytes = lm3s69xx_ssi_read,
0124 .write_bytes = lm3s69xx_ssi_write,
0125 .ioctl = lm3s69xx_ssi_ioctl
0126 };
0127
0128 static lm3s69xx_ssi_bus_entry ssi_0_bus = {
0129 .bus = {
0130 .ops = &lm3s69xx_ssi_ops,
0131 .size = sizeof(lm3s69xx_ssi_bus_entry)
0132 },
0133 .regs = (volatile lm3s69xx_ssi *)LM3S69XX_SSI_0_BASE,
0134 .bus_number = 0,
0135 .idle_char = 0xffff,
0136 .io_configs = {
0137 #if defined(LM3S69XX_MCU_LM3S3749) || defined(LM3S69XX_MCU_LM3S6965) || defined(LM3S69XX_MCU_LM4F120)
0138 LM3S69XX_PIN_SSI_TX(LM3S69XX_PORT_A, 2),
0139 LM3S69XX_PIN_SSI_TX(LM3S69XX_PORT_A, 5),
0140 LM3S69XX_PIN_SSI_RX(LM3S69XX_PORT_A, 4)
0141 #else
0142 #error No GPIO pin definitions for SSI 0
0143 #endif
0144 }
0145 };
0146
0147 rtems_libi2c_bus_t * const lm3s69xx_ssi_0 = &ssi_0_bus.bus;
0148
0149 #if LM3S69XX_NUM_SSI_BLOCKS > 1
0150 static lm3s69xx_ssi_bus_entry ssi_1_bus = {
0151 .bus = {
0152 .ops = &lm3s69xx_ssi_ops,
0153 .size = sizeof(lm3s69xx_ssi_bus_entry)
0154 },
0155 .regs = (volatile lm3s69xx_ssi *)LM3S69XX_SSI_1_BASE,
0156 .bus_number = 1,
0157 .idle_char = 0xffff,
0158 .io_configs = {
0159 #if defined(LM3S69XX_MCU_LM3S3749) || defined(LM3S69XX_MCU_LM4F120)
0160 LM3S69XX_PIN_SSI_TX(LM3S69XX_PORT_E, 0),
0161 LM3S69XX_PIN_SSI_TX(LM3S69XX_PORT_E, 3),
0162 LM3S69XX_PIN_SSI_RX(LM3S69XX_PORT_E, 2)
0163 #else
0164 #error No GPIO pin definitions for SSI 1
0165 #endif
0166 }
0167 };
0168
0169 rtems_libi2c_bus_t * const lm3s69xx_ssi_1 = &ssi_1_bus.bus;
0170 #endif