source: rtems/bsps/arm/altera-cyclone-v/i2c/i2cdrv.c @ 9d41fca

5
Last change on this file since 9d41fca was 9d41fca, checked in by Sebastian Huber <sebastian.huber@…>, on 02/27/19 at 10:39:29

bsp/altera-cyclone-v: Adjust Doxygen file groups

Update #3707.

  • Property mode set to 100644
File size: 4.9 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup RTEMSBSPsARMCycVI2C
5 */
6
7/*
8 * Copyright (c) 2014 embedded brains GmbH.  All rights reserved.
9 *
10 *  embedded brains GmbH
11 *  Dornierstr. 4
12 *  82178 Puchheim
13 *  Germany
14 *  <info@embedded-brains.de>
15 *
16 * The license and distribution terms for this file may be
17 * found in the file LICENSE in this distribution or at
18 * http://www.rtems.org/license/LICENSE.
19 */
20
21#include <bsp.h>
22#include <bsp/i2cdrv.h>
23#include <assert.h>
24#include <rtems/libio.h>
25#include "i2cdrv-config.h"
26
27typedef struct {
28  ALT_I2C_DEV_t i2c_dev;
29  rtems_id mutex;
30} i2cdrv_entry;
31
32i2cdrv_entry i2cdrv_table[CYCLONE_V_NO_I2C];
33
34static ALT_I2C_DEV_t *get_device(i2cdrv_entry *e)
35{
36  return &e->i2c_dev;
37}
38
39static rtems_status_code init_i2c_module(
40  i2cdrv_entry *e,
41  const i2cdrv_configuration *cfg
42)
43{
44  ALT_STATUS_CODE asc = ALT_E_SUCCESS;
45  ALT_I2C_CTLR_t controller = cfg->controller;
46  ALT_I2C_DEV_t *dev = get_device(e);
47  ALT_I2C_MASTER_CONFIG_t i2c_cfg = {
48    .addr_mode = ALT_I2C_ADDR_MODE_7_BIT,
49    .restart_enable = false,
50  };
51
52  asc = alt_i2c_init(controller, dev);
53  if ( asc != ALT_E_SUCCESS ) {
54    return RTEMS_IO_ERROR;
55  }
56  asc = alt_i2c_op_mode_set(dev, ALT_I2C_MODE_MASTER);
57  if ( asc != ALT_E_SUCCESS ) {
58    return RTEMS_IO_ERROR;
59  }
60  asc = alt_i2c_master_config_speed_set(dev, &i2c_cfg, cfg->speed);
61  if ( asc != ALT_E_SUCCESS ) {
62    return RTEMS_IO_ERROR;
63  }
64  asc = alt_i2c_master_config_set(dev, &i2c_cfg);
65  if ( asc != ALT_E_SUCCESS ) {
66    return RTEMS_IO_ERROR;
67  }
68  asc = alt_i2c_enable(dev);
69  if ( asc != ALT_E_SUCCESS ) {
70    return RTEMS_IO_ERROR;
71  }
72
73  return RTEMS_SUCCESSFUL;
74}
75
76rtems_device_driver i2cdrv_initialize(
77  rtems_device_major_number major,
78  rtems_device_minor_number minor,
79  void *arg
80)
81{
82  rtems_status_code sc = RTEMS_SUCCESSFUL;
83
84  for ( size_t i = 0; i < CYCLONE_V_NO_I2C; ++i ) {
85    i2cdrv_entry *e = &i2cdrv_table[i];
86    const i2cdrv_configuration *cfg = &i2cdrv_config[i];
87
88    sc = rtems_io_register_name(cfg->device_name, major, i);
89    assert(sc == RTEMS_SUCCESSFUL);
90
91    sc = rtems_semaphore_create(
92      rtems_build_name ('I', '2', 'C', '0' + i),
93      0,
94      RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY | RTEMS_INHERIT_PRIORITY,
95      0,
96      &e->mutex
97    );
98    assert(sc == RTEMS_SUCCESSFUL);
99
100    sc = init_i2c_module(e, cfg);
101    if ( sc != RTEMS_SUCCESSFUL ) {
102      /* I2C is not usable at this point. Releasing the mutex would allow the
103       * usage which could lead to undefined behaviour. */
104      return sc;
105    }
106
107    sc = rtems_semaphore_release(e->mutex);
108    assert(sc == RTEMS_SUCCESSFUL);
109  }
110
111  return sc;
112}
113
114rtems_device_driver i2cdrv_open(
115  rtems_device_major_number major,
116  rtems_device_major_number minor,
117  void *arg
118)
119{
120  rtems_status_code sc = RTEMS_SUCCESSFUL;
121  i2cdrv_entry *e = &i2cdrv_table[minor];
122
123  sc = rtems_semaphore_obtain(e->mutex, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
124  return sc;
125}
126
127rtems_device_driver i2cdrv_close(
128  rtems_device_major_number major,
129  rtems_device_major_number minor,
130  void *arg
131)
132{
133  rtems_status_code sc = RTEMS_SUCCESSFUL;
134  i2cdrv_entry *e = &i2cdrv_table[minor];
135
136  sc = rtems_semaphore_release(e->mutex);
137  return sc;
138}
139
140rtems_device_driver i2cdrv_read(
141  rtems_device_major_number major,
142  rtems_device_major_number minor,
143  void *arg
144)
145{
146  rtems_status_code sc = RTEMS_SUCCESSFUL;
147  i2cdrv_entry *e = &i2cdrv_table[minor];
148  rtems_libio_rw_args_t *rw  = arg;
149  ALT_I2C_DEV_t *dev = get_device(e);
150  ALT_STATUS_CODE asc = ALT_E_SUCCESS;
151
152  asc = alt_i2c_master_receive(dev, rw->buffer, rw->count, true, true);
153  if ( asc == ALT_E_SUCCESS ) {
154    rw->bytes_moved = rw->count;
155  } else {
156    sc = RTEMS_IO_ERROR;
157  }
158
159  return sc;
160}
161
162rtems_device_driver i2cdrv_write(
163  rtems_device_major_number major,
164  rtems_device_minor_number minor,
165  void *arg
166)
167{
168  rtems_status_code sc = RTEMS_SUCCESSFUL;
169  i2cdrv_entry *e = &i2cdrv_table[minor];
170  rtems_libio_rw_args_t *rw  = arg;
171  ALT_I2C_DEV_t *dev = get_device(e);
172  ALT_STATUS_CODE asc = ALT_E_SUCCESS;
173
174  asc = alt_i2c_master_transmit(dev, rw->buffer, rw->count, true, true);
175  if ( asc == ALT_E_SUCCESS ) {
176    rw->bytes_moved = rw->count;
177  } else {
178    sc = RTEMS_IO_ERROR;
179  }
180
181  return sc;
182}
183
184static rtems_status_code ioctl_set_slave_address(
185  i2cdrv_entry *e,
186  rtems_libio_ioctl_args_t *args
187)
188{
189  ALT_I2C_DEV_t *dev = get_device(e);
190  ALT_STATUS_CODE asc = ALT_E_SUCCESS;
191  uint32_t address = (uint32_t) args->buffer;
192
193  asc = alt_i2c_master_target_set(dev, address);
194  if ( asc != ALT_E_SUCCESS ) {
195    return RTEMS_IO_ERROR;
196  }
197
198  return RTEMS_SUCCESSFUL;
199}
200
201rtems_device_driver i2cdrv_ioctl(
202  rtems_device_major_number major,
203  rtems_device_minor_number minor,
204  void *arg
205)
206{
207  rtems_status_code sc = RTEMS_SUCCESSFUL;
208  i2cdrv_entry *e = &i2cdrv_table[minor];
209  rtems_libio_ioctl_args_t *args = arg;
210
211  switch (args->command) {
212    case I2C_IOC_SET_SLAVE_ADDRESS:
213      sc = ioctl_set_slave_address(e, args);
214      break;
215    default:
216      sc = RTEMS_INVALID_NUMBER;
217      break;
218  }
219
220  return sc;
221}
Note: See TracBrowser for help on using the repository browser.