source: rtems/c/src/lib/libbsp/arm/lm3s69xx/ssi/ssi.c @ c499856

4.115
Last change on this file since c499856 was c499856, checked in by Chris Johns <chrisj@…>, on 03/20/14 at 21:10:47

Change all references of rtems.com to rtems.org.

  • Property mode set to 100644
File size: 4.3 KB
Line 
1/*
2 * Copyright © 2013 Eugeniy Meshcheryakov <eugen@debian.org>
3 *
4 * The license and distribution terms for this file may be
5 * found in the file LICENSE in this distribution or at
6 * http://www.rtems.org/license/LICENSE.
7 */
8
9#include <bsp.h>
10#include <bspopts.h>
11#include <bsp/ssi.h>
12#include <bsp/syscon.h>
13#include <bsp/io.h>
14#include <bsp/lm3s69xx.h>
15
16typedef struct {
17  rtems_libi2c_bus_t bus;
18  volatile lm3s69xx_ssi *regs;
19  int bus_number;
20  uint16_t idle_char;
21  uint8_t cs_pin;
22  lm3s69xx_gpio_config io_configs[3];
23} lm3s69xx_ssi_bus_entry;
24
25static rtems_status_code lm3s69xx_ssi_init(rtems_libi2c_bus_t *bus)
26{
27  lm3s69xx_ssi_bus_entry *e = (lm3s69xx_ssi_bus_entry *)bus;
28  volatile lm3s69xx_ssi* regs = e->regs;
29  uint32_t clock_div = LM3S69XX_SYSTEM_CLOCK / 2 / LM3S69XX_SSI_CLOCK;
30
31  lm3s69xx_gpio_set_config_array(e->io_configs, 3);
32
33  lm3s69xx_syscon_enable_ssi_clock(e->bus_number, true);
34  regs->cr1 = 0;
35  regs->cpsr = SSI_CPSRDIV(2);
36  regs->cr0 = SSICR0_SCR(clock_div - 1) | SSICR0_SPO | SSICR0_SPH | SSICR0_FRF(0) | SSICR0_DSS(7);
37  regs->cr1 = SSICR1_SSE;
38
39  return RTEMS_SUCCESSFUL;
40}
41
42static rtems_status_code lm3s69xx_ssi_send_start(rtems_libi2c_bus_t *bus)
43{
44  return RTEMS_SUCCESSFUL;
45}
46
47static rtems_status_code lm3s69xx_ssi_send_stop(rtems_libi2c_bus_t *bus)
48{
49  lm3s69xx_ssi_bus_entry *e = (lm3s69xx_ssi_bus_entry *)bus;
50  volatile lm3s69xx_ssi* regs = e->regs;
51
52  while ((regs->sr & SSISR_BSY) != 0)
53    /* wait */;
54
55  lm3s69xx_gpio_set_pin(e->cs_pin, true);
56
57  return RTEMS_SUCCESSFUL;
58}
59
60static rtems_status_code lm3s69xx_ssi_send_addr(rtems_libi2c_bus_t *bus,
61        uint32_t addr, int rw)
62{
63  lm3s69xx_ssi_bus_entry *e = (lm3s69xx_ssi_bus_entry *)bus;
64  e->cs_pin = addr;
65  lm3s69xx_gpio_set_pin(e->cs_pin, false);
66
67  return RTEMS_SUCCESSFUL;
68}
69
70static int lm3s69xx_ssi_read(rtems_libi2c_bus_t *bus, unsigned char *in, int n)
71{
72  lm3s69xx_ssi_bus_entry *e = (lm3s69xx_ssi_bus_entry *)bus;
73  volatile lm3s69xx_ssi* regs = e->regs;
74  int i;
75
76  for (i = 0; i < n; i++) {
77    while ((regs->sr & SSISR_TNF) == 0)
78      /* wait */;
79
80    regs->dr = e->idle_char;
81
82    while ((regs->sr & SSISR_RNE) == 0)
83      /* wait */;
84
85    in[i] = regs->dr & 0xff;
86  }
87
88  return n;
89}
90
91static int lm3s69xx_ssi_write(rtems_libi2c_bus_t *bus, unsigned char *out, int n)
92{
93  lm3s69xx_ssi_bus_entry *e = (lm3s69xx_ssi_bus_entry *)bus;
94  volatile lm3s69xx_ssi* regs = e->regs;
95  int i;
96
97  for (i = 0; i < n; i++) {
98    while ((regs->sr & SSISR_TNF) == 0)
99      /* wait */;
100
101    regs->dr = out[i];
102
103    while ((regs->sr & SSISR_RNE) == 0)
104      /* wait */;
105
106    uint32_t dummy = regs->dr;
107    (void)dummy;
108  }
109
110  return n;
111}
112
113static int lm3s69xx_ssi_ioctl(rtems_libi2c_bus_t *bus, int cmd, void *arg)
114{
115  return -RTEMS_NOT_DEFINED;
116}
117
118static const rtems_libi2c_bus_ops_t lm3s69xx_ssi_ops = {
119  .init = lm3s69xx_ssi_init,
120  .send_start = lm3s69xx_ssi_send_start,
121  .send_stop = lm3s69xx_ssi_send_stop,
122  .send_addr = lm3s69xx_ssi_send_addr,
123  .read_bytes = lm3s69xx_ssi_read,
124  .write_bytes = lm3s69xx_ssi_write,
125  .ioctl = lm3s69xx_ssi_ioctl
126};
127
128static lm3s69xx_ssi_bus_entry ssi_0_bus = {
129  .bus = {
130    .ops = &lm3s69xx_ssi_ops,
131    .size = sizeof(lm3s69xx_ssi_bus_entry)
132  },
133  .regs = (volatile lm3s69xx_ssi *)LM3S69XX_SSI_0_BASE,
134  .bus_number = 0,
135  .idle_char = 0xffff,
136  .io_configs = {
137#if defined(LM3S69XX_MCU_LM3S3749) || defined(LM3S69XX_MCU_LM3S6965) || defined(LM3S69XX_MCU_LM4F120)
138    LM3S69XX_PIN_SSI_TX(LM3S69XX_PORT_A, 2), /* CLK */
139    LM3S69XX_PIN_SSI_TX(LM3S69XX_PORT_A, 5), /* TX */
140    LM3S69XX_PIN_SSI_RX(LM3S69XX_PORT_A, 4)  /* RX */
141#else
142#error No GPIO pin definitions for SSI 0
143#endif
144  }
145};
146
147rtems_libi2c_bus_t * const lm3s69xx_ssi_0 = &ssi_0_bus.bus;
148
149#if LM3S69XX_NUM_SSI_BLOCKS > 1
150static lm3s69xx_ssi_bus_entry ssi_1_bus = {
151  .bus = {
152    .ops = &lm3s69xx_ssi_ops,
153    .size = sizeof(lm3s69xx_ssi_bus_entry)
154  },
155  .regs = (volatile lm3s69xx_ssi *)LM3S69XX_SSI_1_BASE,
156  .bus_number = 1,
157  .idle_char = 0xffff,
158  .io_configs = {
159#if defined(LM3S69XX_MCU_LM3S3749) || defined(LM3S69XX_MCU_LM4F120)
160    LM3S69XX_PIN_SSI_TX(LM3S69XX_PORT_E, 0), /* CLK */
161    LM3S69XX_PIN_SSI_TX(LM3S69XX_PORT_E, 3), /* TX */
162    LM3S69XX_PIN_SSI_RX(LM3S69XX_PORT_E, 2)  /* RX */
163#else
164#error No GPIO pin definitions for SSI 1
165#endif
166  }
167};
168
169rtems_libi2c_bus_t * const lm3s69xx_ssi_1 = &ssi_1_bus.bus;
170#endif /* LM3S69XX_NUM_SSI_BLOCKS > 1 */
Note: See TracBrowser for help on using the repository browser.