File indexing completed on 2025-05-11 08:23:46
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include <bsp.h>
0013 #include <i2c.h>
0014 #include <rtems/score/sysstate.h>
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024 static void
0025 i2c_transfer_sema_done_func(void * arg)
0026 {
0027 rtems_id sema = *(rtems_id *)arg;
0028 rtems_semaphore_release(sema);
0029 }
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039 static void
0040 i2c_transfer_poll_done_func(void *arg)
0041 {
0042 bool *poll_done_flag = (bool *)arg;
0043 *poll_done_flag = true;
0044 }
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059 static i2c_message_status
0060 i2c_transfer_wait_sema(i2c_bus_number bus, i2c_message *msg, int nmsg)
0061 {
0062 rtems_status_code sc;
0063 rtems_id sema;
0064 sc = rtems_semaphore_create(
0065 rtems_build_name('I', '2', 'C', 'S'),
0066 0,
0067 RTEMS_COUNTING_SEMAPHORE | RTEMS_NO_INHERIT_PRIORITY |
0068 RTEMS_NO_PRIORITY_CEILING | RTEMS_LOCAL,
0069 0,
0070 &sema
0071 );
0072 if (sc != RTEMS_SUCCESSFUL)
0073 return I2C_RESOURCE_NOT_AVAILABLE;
0074 sc = i2c_transfer(bus, nmsg, msg,
0075 i2c_transfer_sema_done_func, &sema);
0076 if (sc != RTEMS_SUCCESSFUL)
0077 {
0078 rtems_semaphore_delete(sema);
0079 return sc;
0080 }
0081 rtems_semaphore_obtain(sema, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
0082 sc = rtems_semaphore_delete(sema);
0083 return sc;
0084 }
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098 static rtems_status_code
0099 i2c_transfer_wait_poll(i2c_bus_number bus, i2c_message *msg, int nmsg)
0100 {
0101
0102
0103
0104
0105
0106 volatile bool poll_done_flag;
0107 rtems_status_code sc;
0108 poll_done_flag = false;
0109 sc = i2c_transfer(bus, nmsg, msg,
0110 i2c_transfer_poll_done_func,(void *)&poll_done_flag);
0111 if (sc != RTEMS_SUCCESSFUL)
0112 return sc;
0113 while (poll_done_flag == false)
0114 {
0115 i2c_poll(bus);
0116 }
0117 return RTEMS_SUCCESSFUL;
0118 }
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136 i2c_message_status
0137 i2c_transfer_wait(i2c_bus_number bus, i2c_message *msg, int nmsg)
0138 {
0139 rtems_status_code sc;
0140 int i;
0141 if (_System_state_Is_up(_System_state_Get()))
0142 {
0143 sc = i2c_transfer_wait_sema(bus, msg, nmsg);
0144 }
0145 else
0146 {
0147 sc = i2c_transfer_wait_poll(bus, msg, nmsg);
0148 }
0149
0150 if (sc != RTEMS_SUCCESSFUL)
0151 return I2C_RESOURCE_NOT_AVAILABLE;
0152
0153 for (i = 0; i < nmsg; i++)
0154 {
0155 if (msg[i].status != I2C_SUCCESSFUL)
0156 {
0157 return msg[i].status;
0158 }
0159 }
0160 return I2C_SUCCESSFUL;
0161 }
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176 i2c_message_status
0177 i2c_write(i2c_bus_number bus, i2c_address addr, void *buf, int size)
0178 {
0179 i2c_message msg;
0180 msg.addr = addr;
0181 msg.flags = I2C_MSG_WR;
0182 if (addr > 0xff)
0183 msg.flags |= I2C_MSG_ADDR_10;
0184 msg.status = 0;
0185 msg.len = size;
0186 msg.buf = buf;
0187 return i2c_transfer_wait(bus, &msg, 1);
0188 }
0189
0190
0191
0192
0193
0194
0195
0196
0197
0198
0199
0200
0201
0202 i2c_message_status
0203 i2c_wrbyte(i2c_bus_number bus, i2c_address addr, uint8_t cmd)
0204 {
0205 i2c_message msg;
0206 uint8_t data = cmd;
0207 msg.addr = addr;
0208 msg.flags = I2C_MSG_WR;
0209 if (addr > 0xff)
0210 msg.flags |= I2C_MSG_ADDR_10;
0211 msg.status = 0;
0212 msg.len = sizeof(data);
0213 msg.buf = &data;
0214 return i2c_transfer_wait(bus, &msg, 1);
0215 }
0216
0217
0218
0219
0220
0221
0222
0223
0224
0225
0226
0227
0228
0229
0230 i2c_message_status
0231 i2c_read(i2c_bus_number bus, i2c_address addr, void *buf, int size)
0232 {
0233 i2c_message msg;
0234 msg.addr = addr;
0235 msg.flags = 0;
0236 if (addr > 0xff)
0237 msg.flags |= I2C_MSG_ADDR_10;
0238 msg.status = 0;
0239 msg.len = size;
0240 msg.buf = buf;
0241 return i2c_transfer_wait(bus, &msg, 1);
0242 }
0243
0244
0245
0246
0247
0248
0249
0250
0251
0252
0253
0254
0255
0256
0257
0258
0259 i2c_message_status
0260 i2c_wrrd(i2c_bus_number bus, i2c_address addr, void *bufw, int sizew,
0261 void *bufr, int sizer)
0262 {
0263 i2c_message msg[2];
0264 msg[0].addr = addr;
0265 msg[0].flags = I2C_MSG_WR | I2C_MSG_ERRSKIP;
0266 if (addr > 0xff)
0267 msg[0].flags |= I2C_MSG_ADDR_10;
0268 msg[0].status = 0;
0269 msg[0].len = sizew;
0270 msg[0].buf = bufw;
0271
0272 msg[1].addr = addr;
0273 msg[1].flags = 0;
0274 if (addr > 0xff)
0275 msg[1].flags |= I2C_MSG_ADDR_10;
0276 msg[1].status = 0;
0277 msg[1].len = sizer;
0278 msg[1].buf = bufr;
0279
0280 return i2c_transfer_wait(bus, msg, 2);
0281 }
0282
0283
0284
0285
0286
0287
0288
0289
0290
0291
0292
0293
0294
0295
0296
0297 i2c_message_status
0298 i2c_wbrd(i2c_bus_number bus, i2c_address addr, uint8_t cmd,
0299 void *bufr, int sizer)
0300 {
0301 i2c_message msg[2];
0302 uint8_t bufw = cmd;
0303 msg[0].addr = addr;
0304 msg[0].flags = I2C_MSG_WR | I2C_MSG_ERRSKIP;
0305 if (addr > 0xff)
0306 msg[0].flags |= I2C_MSG_ADDR_10;
0307 msg[0].status = 0;
0308 msg[0].len = sizeof(bufw);
0309 msg[0].buf = &bufw;
0310
0311 msg[1].addr = addr;
0312 msg[1].flags = I2C_MSG_ERRSKIP;
0313 if (addr > 0xff)
0314 msg[1].flags |= I2C_MSG_ADDR_10;
0315 msg[1].status = 0;
0316 msg[1].len = sizer;
0317 msg[1].buf = bufr;
0318
0319 return i2c_transfer_wait(bus, msg, 2);
0320 }