bsp/altera-cyclone-v: Add a simple I2C driver.

This commit is contained in:
Christian Mauderer
2014-08-11 08:01:26 +02:00
committed by Sebastian Huber
parent 1642d27e4c
commit 3f9cd87d76
11 changed files with 10389 additions and 7 deletions
@@ -56,6 +56,7 @@ include_bsp_HEADERS += hwlib/include/alt_clock_group.h
include_bsp_HEADERS += hwlib/include/alt_clock_manager.h
include_bsp_HEADERS += hwlib/include/alt_generalpurpose_io.h
include_bsp_HEADERS += hwlib/include/alt_hwlibs_ver.h
include_bsp_HEADERS += hwlib/include/alt_i2c.h
include_bsp_HEADERS += hwlib/include/alt_interrupt_common.h
include_bsp_HEADERS += hwlib/include/alt_mpu_registers.h
include_bsp_HEADERS += hwlib/include/alt_reset_manager.h
@@ -125,6 +126,7 @@ CFLAGS += -Wno-missing-prototypes
libbsp_a_SOURCES += hwlib/src/hwmgr/alt_address_space.c
libbsp_a_SOURCES += hwlib/src/hwmgr/alt_clock_manager.c
libbsp_a_SOURCES += hwlib/src/hwmgr/alt_generalpurpose_io.c
libbsp_a_SOURCES += hwlib/src/hwmgr/alt_i2c.c
libbsp_a_SOURCES += hwlib/src/hwmgr/alt_reset_manager.c
#The following Altera hwlib source files have been left out because so far
#they are not required:
@@ -193,6 +195,11 @@ libbsp_a_SOURCES += console/console-config.c
libbsp_a_SOURCES += ../../shared/clockdrv_shell.h
libbsp_a_SOURCES += ../shared/arm-a9mpcore-clock-config.c
# I2C
libbsp_a_SOURCES += i2c/i2cdrv.c
libbsp_a_SOURCES += i2c/i2cdrv-config.c
include_bsp_HEADERS += include/i2cdrv.h
# Cache
libbsp_a_SOURCES += ../../../libcpu/shared/src/cache_manager.c
libbsp_a_SOURCES += ../shared/include/arm-cache-l1.h
@@ -46,6 +46,14 @@ RTEMS_BSPOPTS_HELP([CYCLONE_V_CONFIG_UART_1],[configuration for UART 1])
RTEMS_BSPOPTS_SET([CYCLONE_V_UART_BAUD],[*],[115200U])
RTEMS_BSPOPTS_HELP([CYCLONE_V_UART_BAUD],[baud for UARTs])
RTEMS_BSPOPTS_SET([CYCLONE_V_NO_I2C],[*],[1])
RTEMS_BSPOPTS_HELP([CYCLONE_V_NO_I2C],
[Number of configured I2C buses. Note that each bus has to be configured in an
apropriate i2cdrv_config array.])
RTEMS_BSPOPTS_SET([CYCLONE_V_I2C0_SPEED],[*],[100000])
RTEMS_BSPOPTS_HELP([CYCLONE_V_I2C0_SPEED],[speed for I2C0 in HZ])
RTEMS_CHECK_SMP
AM_CONDITIONAL(HAS_SMP,[test "$rtems_cv_HAS_SMP" = "yes"])
@@ -10,4 +10,43 @@ The hwlib directory contains only those files from Alteras hwlib which are
required by the BSP (the whole hwlib was considered too big).
The directory structure within the hwlib directory is equivalent to Alteras
hwlib directory structure. For easy maintenance only whole files have been
left out.
left out.
Altera provides the hwlib with their SoC Embedded Design Suite (EDS).
HWLIB Version:
--------------
The files have been taken from the following hwlib versions:
|========================================
| Version | File
| |
| 13.0SP1 | include/alt_address_space.h
| 13.0SP1 | include/alt_clock_group.h
| 13.0SP1 | include/alt_clock_manager.h
| 13.0SP1 | include/alt_generalpurpose_io.h
| 13.0SP1 | include/alt_hwlibs_ver.h
| 13.1 | include/alt_i2c.h
| 13.0SP1 | include/alt_interrupt_common.h
| 13.0SP1 | include/alt_mpu_registers.h
| 13.0SP1 | include/alt_reset_manager.h
| 13.0SP1 | include/hwlib.h
| 13.0SP1 | include/socal/alt_clkmgr.h
| 13.0SP1 | include/socal/alt_gpio.h
| 13.1 | include/socal/alt_i2c.h
| 13.0SP1 | include/socal/alt_l3.h
| 13.0SP1 | include/socal/alt_rstmgr.h
| 13.0SP1 | include/socal/alt_sdr.h
| 13.0SP1 | include/socal/alt_sysmgr.h
| 13.0SP1 | include/socal/alt_uart.h
| 13.0SP1 | include/socal/hps.h
| 13.0SP1 | include/socal/socal.h
| 13.0SP1 | src/hwmgr/alt_address_space.c
| 13.0SP1 | src/hwmgr/alt_clock_manager.c
| 13.0SP1 | src/hwmgr/alt_generalpurpose_io.c
| 13.1 | src/hwmgr/alt_i2c.c
| 13.0SP1 | src/hwmgr/alt_reset_manager.c
|========================================
hwlib 13.0SP1 is from SoC EDS 13.0.1.232
hwlib 13.1 is from SoC EDS 14.0.0.200
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -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,
}
};
@@ -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 */
@@ -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;
}
@@ -0,0 +1,76 @@
/*
* 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 I2CDRV_H
#define I2CDRV_H
#include <rtems.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
rtems_device_driver i2cdrv_initialize(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
);
rtems_device_driver i2cdrv_open(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
);
rtems_device_driver i2cdrv_close(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
);
rtems_device_driver i2cdrv_read(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
);
rtems_device_driver i2cdrv_write(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
);
rtems_device_driver i2cdrv_ioctl(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
);
#define I2C_DRIVER_TABLE_ENTRY \
{ \
i2cdrv_initialize, \
i2cdrv_open, \
i2cdrv_close, \
i2cdrv_read, \
i2cdrv_write, \
i2cdrv_ioctl \
}
#define I2C_IOC_SET_SLAVE_ADDRESS 1
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* I2CDRV_H */
@@ -5,18 +5,18 @@ $(srcdir)/preinstall.am: Makefile.am
$(AMPOLISH3) $(srcdir)/Makefile.am > $(srcdir)/preinstall.am
endif
all-am: $(PREINSTALL_FILES)
PREINSTALL_FILES =
CLEANFILES = $(PREINSTALL_FILES)
PREINSTALL_DIRS =
DISTCLEANFILES += $(PREINSTALL_DIRS)
all-local: $(TMPINSTALL_FILES)
TMPINSTALL_FILES =
CLEANFILES = $(TMPINSTALL_FILES)
all-am: $(PREINSTALL_FILES)
PREINSTALL_FILES =
CLEANFILES += $(PREINSTALL_FILES)
CLEANFILES += $(TMPINSTALL_FILES)
$(PROJECT_LIB)/$(dirstamp):
@$(MKDIR_P) $(PROJECT_LIB)
@@ -163,6 +163,10 @@ $(PROJECT_INCLUDE)/bsp/alt_hwlibs_ver.h: hwlib/include/alt_hwlibs_ver.h $(PROJEC
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/alt_hwlibs_ver.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/alt_hwlibs_ver.h
$(PROJECT_INCLUDE)/bsp/alt_i2c.h: hwlib/include/alt_i2c.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/alt_i2c.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/alt_i2c.h
$(PROJECT_INCLUDE)/bsp/alt_interrupt_common.h: hwlib/include/alt_interrupt_common.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/alt_interrupt_common.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/alt_interrupt_common.h
@@ -243,3 +247,7 @@ $(PROJECT_LIB)/linkcmds.altcycv_devkit_smp: startup/linkcmds.altcycv_devkit_smp
$(INSTALL_DATA) $< $(PROJECT_LIB)/linkcmds.altcycv_devkit_smp
TMPINSTALL_FILES += $(PROJECT_LIB)/linkcmds.altcycv_devkit_smp
$(PROJECT_INCLUDE)/bsp/i2cdrv.h: include/i2cdrv.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/i2cdrv.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/i2cdrv.h