mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2026-08-31 11:47:47 +08:00
bsp/altera-cyclone-v: Add a simple I2C driver.
This commit is contained in:
committed by
Sebastian Huber
parent
1642d27e4c
commit
3f9cd87d76
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user