summaryrefslogtreecommitdiffstats
path: root/bsps/arm/altera-cyclone-v
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2018-04-23 09:45:28 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2018-04-23 15:18:43 +0200
commita2dad96ab736f66ed54421cad53caf31f250e181 (patch)
tree1935320b5b52276ed2e52741cdae71637f209f77 /bsps/arm/altera-cyclone-v
parentbsps/arm: Remove unused stm32f* files (diff)
downloadrtems-a2dad96ab736f66ed54421cad53caf31f250e181.tar.bz2
bsps: Move I2C drivers to bsps
This patch is a part of the BSP source reorganization. Update #3285.
Diffstat (limited to 'bsps/arm/altera-cyclone-v')
-rw-r--r--bsps/arm/altera-cyclone-v/i2c/i2cdrv-config.c24
-rw-r--r--bsps/arm/altera-cyclone-v/i2c/i2cdrv-config.h37
-rw-r--r--bsps/arm/altera-cyclone-v/i2c/i2cdrv.c215
3 files changed, 276 insertions, 0 deletions
diff --git a/bsps/arm/altera-cyclone-v/i2c/i2cdrv-config.c b/bsps/arm/altera-cyclone-v/i2c/i2cdrv-config.c
new file mode 100644
index 0000000000..3c29b61e50
--- /dev/null
+++ b/bsps/arm/altera-cyclone-v/i2c/i2cdrv-config.c
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2014 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <info@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <bsp.h>
+#include "i2cdrv-config.h"
+
+const i2cdrv_configuration i2cdrv_config[CYCLONE_V_NO_I2C] = {
+ {
+ .controller = ALT_I2C_I2C0,
+ .device_name = "/dev/i2c0",
+ .speed = CYCLONE_V_I2C0_SPEED,
+ }
+};
diff --git a/bsps/arm/altera-cyclone-v/i2c/i2cdrv-config.h b/bsps/arm/altera-cyclone-v/i2c/i2cdrv-config.h
new file mode 100644
index 0000000000..650974751e
--- /dev/null
+++ b/bsps/arm/altera-cyclone-v/i2c/i2cdrv-config.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2014 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <info@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#ifndef XXX_H
+#define XXX_H
+
+#include <rtems.h>
+#include <bsp/alt_i2c.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+typedef struct {
+ ALT_I2C_CTLR_t controller;
+ char *device_name;
+ uint32_t speed;
+} i2cdrv_configuration;
+
+extern const i2cdrv_configuration i2cdrv_config[];
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* XXX_H */
diff --git a/bsps/arm/altera-cyclone-v/i2c/i2cdrv.c b/bsps/arm/altera-cyclone-v/i2c/i2cdrv.c
new file mode 100644
index 0000000000..3ea23551d8
--- /dev/null
+++ b/bsps/arm/altera-cyclone-v/i2c/i2cdrv.c
@@ -0,0 +1,215 @@
+/*
+ * Copyright (c) 2014 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <info@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <bsp.h>
+#include <bsp/i2cdrv.h>
+#include <assert.h>
+#include <rtems/libio.h>
+#include "i2cdrv-config.h"
+
+typedef struct {
+ ALT_I2C_DEV_t i2c_dev;
+ rtems_id mutex;
+} i2cdrv_entry;
+
+i2cdrv_entry i2cdrv_table[CYCLONE_V_NO_I2C];
+
+static ALT_I2C_DEV_t *get_device(i2cdrv_entry *e)
+{
+ return &e->i2c_dev;
+}
+
+static rtems_status_code init_i2c_module(
+ i2cdrv_entry *e,
+ const i2cdrv_configuration *cfg
+)
+{
+ ALT_STATUS_CODE asc = ALT_E_SUCCESS;
+ ALT_I2C_CTLR_t controller = cfg->controller;
+ ALT_I2C_DEV_t *dev = get_device(e);
+ ALT_I2C_MASTER_CONFIG_t i2c_cfg = {
+ .addr_mode = ALT_I2C_ADDR_MODE_7_BIT,
+ .restart_enable = false,
+ };
+
+ asc = alt_i2c_init(controller, dev);
+ if ( asc != ALT_E_SUCCESS ) {
+ return RTEMS_IO_ERROR;
+ }
+ asc = alt_i2c_op_mode_set(dev, ALT_I2C_MODE_MASTER);
+ if ( asc != ALT_E_SUCCESS ) {
+ return RTEMS_IO_ERROR;
+ }
+ asc = alt_i2c_master_config_speed_set(dev, &i2c_cfg, cfg->speed);
+ if ( asc != ALT_E_SUCCESS ) {
+ return RTEMS_IO_ERROR;
+ }
+ asc = alt_i2c_master_config_set(dev, &i2c_cfg);
+ if ( asc != ALT_E_SUCCESS ) {
+ return RTEMS_IO_ERROR;
+ }
+ asc = alt_i2c_enable(dev);
+ if ( asc != ALT_E_SUCCESS ) {
+ return RTEMS_IO_ERROR;
+ }
+
+ return RTEMS_SUCCESSFUL;
+}
+
+rtems_device_driver i2cdrv_initialize(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg
+)
+{
+ rtems_status_code sc = RTEMS_SUCCESSFUL;
+
+ for ( size_t i = 0; i < CYCLONE_V_NO_I2C; ++i ) {
+ i2cdrv_entry *e = &i2cdrv_table[i];
+ const i2cdrv_configuration *cfg = &i2cdrv_config[i];
+
+ sc = rtems_io_register_name(cfg->device_name, major, i);
+ assert(sc == RTEMS_SUCCESSFUL);
+
+ sc = rtems_semaphore_create(
+ rtems_build_name ('I', '2', 'C', '0' + i),
+ 0,
+ RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY | RTEMS_INHERIT_PRIORITY,
+ 0,
+ &e->mutex
+ );
+ assert(sc == RTEMS_SUCCESSFUL);
+
+ sc = init_i2c_module(e, cfg);
+ if ( sc != RTEMS_SUCCESSFUL ) {
+ /* I2C is not usable at this point. Releasing the mutex would allow the
+ * usage which could lead to undefined behaviour. */
+ return sc;
+ }
+
+ sc = rtems_semaphore_release(e->mutex);
+ assert(sc == RTEMS_SUCCESSFUL);
+ }
+
+ return sc;
+}
+
+rtems_device_driver i2cdrv_open(
+ rtems_device_major_number major,
+ rtems_device_major_number minor,
+ void *arg
+)
+{
+ rtems_status_code sc = RTEMS_SUCCESSFUL;
+ i2cdrv_entry *e = &i2cdrv_table[minor];
+
+ sc = rtems_semaphore_obtain(e->mutex, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
+ return sc;
+}
+
+rtems_device_driver i2cdrv_close(
+ rtems_device_major_number major,
+ rtems_device_major_number minor,
+ void *arg
+)
+{
+ rtems_status_code sc = RTEMS_SUCCESSFUL;
+ i2cdrv_entry *e = &i2cdrv_table[minor];
+
+ sc = rtems_semaphore_release(e->mutex);
+ return sc;
+}
+
+rtems_device_driver i2cdrv_read(
+ rtems_device_major_number major,
+ rtems_device_major_number minor,
+ void *arg
+)
+{
+ rtems_status_code sc = RTEMS_SUCCESSFUL;
+ i2cdrv_entry *e = &i2cdrv_table[minor];
+ rtems_libio_rw_args_t *rw = arg;
+ ALT_I2C_DEV_t *dev = get_device(e);
+ ALT_STATUS_CODE asc = ALT_E_SUCCESS;
+
+ asc = alt_i2c_master_receive(dev, rw->buffer, rw->count, true, true);
+ if ( asc == ALT_E_SUCCESS ) {
+ rw->bytes_moved = rw->count;
+ } else {
+ sc = RTEMS_IO_ERROR;
+ }
+
+ return sc;
+}
+
+rtems_device_driver i2cdrv_write(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg
+)
+{
+ rtems_status_code sc = RTEMS_SUCCESSFUL;
+ i2cdrv_entry *e = &i2cdrv_table[minor];
+ rtems_libio_rw_args_t *rw = arg;
+ ALT_I2C_DEV_t *dev = get_device(e);
+ ALT_STATUS_CODE asc = ALT_E_SUCCESS;
+
+ asc = alt_i2c_master_transmit(dev, rw->buffer, rw->count, true, true);
+ if ( asc == ALT_E_SUCCESS ) {
+ rw->bytes_moved = rw->count;
+ } else {
+ sc = RTEMS_IO_ERROR;
+ }
+
+ return sc;
+}
+
+static rtems_status_code ioctl_set_slave_address(
+ i2cdrv_entry *e,
+ rtems_libio_ioctl_args_t *args
+)
+{
+ ALT_I2C_DEV_t *dev = get_device(e);
+ ALT_STATUS_CODE asc = ALT_E_SUCCESS;
+ uint32_t address = (uint32_t) args->buffer;
+
+ asc = alt_i2c_master_target_set(dev, address);
+ if ( asc != ALT_E_SUCCESS ) {
+ return RTEMS_IO_ERROR;
+ }
+
+ return RTEMS_SUCCESSFUL;
+}
+
+rtems_device_driver i2cdrv_ioctl(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg
+)
+{
+ rtems_status_code sc = RTEMS_SUCCESSFUL;
+ i2cdrv_entry *e = &i2cdrv_table[minor];
+ rtems_libio_ioctl_args_t *args = arg;
+
+ switch (args->command) {
+ case I2C_IOC_SET_SLAVE_ADDRESS:
+ sc = ioctl_set_slave_address(e, args);
+ break;
+ default:
+ sc = RTEMS_INVALID_NUMBER;
+ break;
+ }
+
+ return sc;
+}