File indexing completed on 2025-05-11 08:22:43
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034 #include <bsp.h>
0035 #include <bsp/i2cdrv.h>
0036 #include <assert.h>
0037 #include <rtems/libio.h>
0038 #include "i2cdrv-config.h"
0039
0040 typedef struct {
0041 ALT_I2C_DEV_t i2c_dev;
0042 rtems_id mutex;
0043 } i2cdrv_entry;
0044
0045 i2cdrv_entry i2cdrv_table[CYCLONE_V_NO_I2C];
0046
0047 static ALT_I2C_DEV_t *get_device(i2cdrv_entry *e)
0048 {
0049 return &e->i2c_dev;
0050 }
0051
0052 static rtems_status_code init_i2c_module(
0053 i2cdrv_entry *e,
0054 const i2cdrv_configuration *cfg
0055 )
0056 {
0057 ALT_STATUS_CODE asc = ALT_E_SUCCESS;
0058 ALT_I2C_CTLR_t controller = cfg->controller;
0059 ALT_I2C_DEV_t *dev = get_device(e);
0060 ALT_I2C_MASTER_CONFIG_t i2c_cfg = {
0061 .addr_mode = ALT_I2C_ADDR_MODE_7_BIT,
0062 .restart_enable = false,
0063 };
0064
0065 asc = alt_i2c_init(controller, dev);
0066 if ( asc != ALT_E_SUCCESS ) {
0067 return RTEMS_IO_ERROR;
0068 }
0069 asc = alt_i2c_op_mode_set(dev, ALT_I2C_MODE_MASTER);
0070 if ( asc != ALT_E_SUCCESS ) {
0071 return RTEMS_IO_ERROR;
0072 }
0073 asc = alt_i2c_master_config_speed_set(dev, &i2c_cfg, cfg->speed);
0074 if ( asc != ALT_E_SUCCESS ) {
0075 return RTEMS_IO_ERROR;
0076 }
0077 asc = alt_i2c_master_config_set(dev, &i2c_cfg);
0078 if ( asc != ALT_E_SUCCESS ) {
0079 return RTEMS_IO_ERROR;
0080 }
0081 asc = alt_i2c_enable(dev);
0082 if ( asc != ALT_E_SUCCESS ) {
0083 return RTEMS_IO_ERROR;
0084 }
0085
0086 return RTEMS_SUCCESSFUL;
0087 }
0088
0089 rtems_device_driver i2cdrv_initialize(
0090 rtems_device_major_number major,
0091 rtems_device_minor_number minor,
0092 void *arg
0093 )
0094 {
0095 rtems_status_code sc = RTEMS_SUCCESSFUL;
0096
0097 for ( size_t i = 0; i < CYCLONE_V_NO_I2C; ++i ) {
0098 i2cdrv_entry *e = &i2cdrv_table[i];
0099 const i2cdrv_configuration *cfg = &i2cdrv_config[i];
0100
0101 sc = rtems_io_register_name(cfg->device_name, major, i);
0102 assert(sc == RTEMS_SUCCESSFUL);
0103
0104 sc = rtems_semaphore_create(
0105 rtems_build_name ('I', '2', 'C', '0' + i),
0106 0,
0107 RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY | RTEMS_INHERIT_PRIORITY,
0108 0,
0109 &e->mutex
0110 );
0111 assert(sc == RTEMS_SUCCESSFUL);
0112
0113 sc = init_i2c_module(e, cfg);
0114 if ( sc != RTEMS_SUCCESSFUL ) {
0115
0116
0117 return sc;
0118 }
0119
0120 sc = rtems_semaphore_release(e->mutex);
0121 assert(sc == RTEMS_SUCCESSFUL);
0122 }
0123
0124 return sc;
0125 }
0126
0127 rtems_device_driver i2cdrv_open(
0128 rtems_device_major_number major,
0129 rtems_device_major_number minor,
0130 void *arg
0131 )
0132 {
0133 rtems_status_code sc = RTEMS_SUCCESSFUL;
0134 i2cdrv_entry *e = &i2cdrv_table[minor];
0135
0136 sc = rtems_semaphore_obtain(e->mutex, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
0137 return sc;
0138 }
0139
0140 rtems_device_driver i2cdrv_close(
0141 rtems_device_major_number major,
0142 rtems_device_major_number minor,
0143 void *arg
0144 )
0145 {
0146 rtems_status_code sc = RTEMS_SUCCESSFUL;
0147 i2cdrv_entry *e = &i2cdrv_table[minor];
0148
0149 sc = rtems_semaphore_release(e->mutex);
0150 return sc;
0151 }
0152
0153 rtems_device_driver i2cdrv_read(
0154 rtems_device_major_number major,
0155 rtems_device_major_number minor,
0156 void *arg
0157 )
0158 {
0159 rtems_status_code sc = RTEMS_SUCCESSFUL;
0160 i2cdrv_entry *e = &i2cdrv_table[minor];
0161 rtems_libio_rw_args_t *rw = arg;
0162 ALT_I2C_DEV_t *dev = get_device(e);
0163 ALT_STATUS_CODE asc = ALT_E_SUCCESS;
0164
0165 asc = alt_i2c_master_receive(dev, rw->buffer, rw->count, true, true);
0166 if ( asc == ALT_E_SUCCESS ) {
0167 rw->bytes_moved = rw->count;
0168 } else {
0169 sc = RTEMS_IO_ERROR;
0170 }
0171
0172 return sc;
0173 }
0174
0175 rtems_device_driver i2cdrv_write(
0176 rtems_device_major_number major,
0177 rtems_device_minor_number minor,
0178 void *arg
0179 )
0180 {
0181 rtems_status_code sc = RTEMS_SUCCESSFUL;
0182 i2cdrv_entry *e = &i2cdrv_table[minor];
0183 rtems_libio_rw_args_t *rw = arg;
0184 ALT_I2C_DEV_t *dev = get_device(e);
0185 ALT_STATUS_CODE asc = ALT_E_SUCCESS;
0186
0187 asc = alt_i2c_master_transmit(dev, rw->buffer, rw->count, true, true);
0188 if ( asc == ALT_E_SUCCESS ) {
0189 rw->bytes_moved = rw->count;
0190 } else {
0191 sc = RTEMS_IO_ERROR;
0192 }
0193
0194 return sc;
0195 }
0196
0197 static rtems_status_code ioctl_set_slave_address(
0198 i2cdrv_entry *e,
0199 rtems_libio_ioctl_args_t *args
0200 )
0201 {
0202 ALT_I2C_DEV_t *dev = get_device(e);
0203 ALT_STATUS_CODE asc = ALT_E_SUCCESS;
0204 uint32_t address = (uint32_t) args->buffer;
0205
0206 asc = alt_i2c_master_target_set(dev, address);
0207 if ( asc != ALT_E_SUCCESS ) {
0208 return RTEMS_IO_ERROR;
0209 }
0210
0211 return RTEMS_SUCCESSFUL;
0212 }
0213
0214 rtems_device_driver i2cdrv_ioctl(
0215 rtems_device_major_number major,
0216 rtems_device_minor_number minor,
0217 void *arg
0218 )
0219 {
0220 rtems_status_code sc = RTEMS_SUCCESSFUL;
0221 i2cdrv_entry *e = &i2cdrv_table[minor];
0222 rtems_libio_ioctl_args_t *args = arg;
0223
0224 switch (args->command) {
0225 case I2C_IOC_SET_SLAVE_ADDRESS:
0226 sc = ioctl_set_slave_address(e, args);
0227 break;
0228 default:
0229 sc = RTEMS_INVALID_NUMBER;
0230 break;
0231 }
0232
0233 return sc;
0234 }