Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:03

0001 /*
0002  * Copyright (c) 2013 Eugeniy Meshcheryakov <eugen@debian.org>
0003  *
0004  * The license and distribution terms for this file may be
0005  * found in the file LICENSE in this distribution or at
0006  * http://www.rtems.org/license/LICENSE.
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     /* wait */;
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       /* wait */;
0079 
0080     regs->dr = e->idle_char;
0081 
0082     while ((regs->sr & SSISR_RNE) == 0)
0083       /* wait */;
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       /* wait */;
0100 
0101     regs->dr = out[i];
0102 
0103     while ((regs->sr & SSISR_RNE) == 0)
0104       /* wait */;
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), /* CLK */
0139     LM3S69XX_PIN_SSI_TX(LM3S69XX_PORT_A, 5), /* TX */
0140     LM3S69XX_PIN_SSI_RX(LM3S69XX_PORT_A, 4)  /* RX */
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), /* CLK */
0161     LM3S69XX_PIN_SSI_TX(LM3S69XX_PORT_E, 3), /* TX */
0162     LM3S69XX_PIN_SSI_RX(LM3S69XX_PORT_E, 2)  /* RX */
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 /* LM3S69XX_NUM_SSI_BLOCKS > 1 */