Skip to content

Commit

Permalink
Added support for block reading and writing (#127)
Browse files Browse the repository at this point in the history
* Added support for block reading and writing

Added three functions to support reading and writing blocks with a specified size to the I2C device. For writing, I added two versions, one that implicitly sends the size as the first byte to the slave device and one that doesn't.
  • Loading branch information
Satharus authored and carbonfix committed Sep 24, 2024
1 parent 8ba9c23 commit 8658ad4
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 3 deletions.
34 changes: 34 additions & 0 deletions src/i2c-dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,4 +70,38 @@ extern inline __s32 i2c_smbus_write_word_data(int fd, int cmd, __u16 value) {
return i2c_smbus_access(fd, I2C_SMBUS_WRITE, cmd, I2C_SMBUS_WORD_DATA, &data);
}

extern inline __s32 i2c_smbus_read_data_block(int fd, int cmd, unsigned char *block, int block_size) {
union i2c_smbus_data data;
if (block_size > I2C_SMBUS_BLOCK_MAX) {
block_size = I2C_SMBUS_BLOCK_MAX;
}
data.block[0] = block_size;
if(i2c_smbus_access(fd, I2C_SMBUS_READ, cmd, I2C_SMBUS_I2C_BLOCK_DATA, &data) < 0) {
return -1;
} else {
memcpy(block, data.block+1, block_size);
return data.block[0];
}
}

extern inline __s32 i2c_smbus_write_data_block(int fd, int cmd, unsigned char *block, int block_size) {
union i2c_smbus_data data;
if (block_size > I2C_SMBUS_BLOCK_MAX) {
block_size = I2C_SMBUS_BLOCK_MAX;
}
data.block[0] = block_size;
memcpy(data.block+1, block, block_size);
return i2c_smbus_access(fd, I2C_SMBUS_WRITE, cmd, I2C_SMBUS_I2C_BLOCK_BROKEN, &data);
}

extern inline __s32 i2c_smbus_write_data_block_with_size(int fd, int cmd, unsigned char *block, int block_size) {
union i2c_smbus_data data;
if (block_size > I2C_SMBUS_BLOCK_MAX) {
block_size = I2C_SMBUS_BLOCK_MAX;
}
data.block[0] = block_size;
memcpy(data.block+1, block, block_size);
return i2c_smbus_access(fd, I2C_SMBUS_WRITE, cmd, I2C_SMBUS_I2C_BLOCK_DATA, &data);
}

#endif
3 changes: 3 additions & 0 deletions src/i2c-dev.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,8 @@ inline __s32 i2c_smbus_read_byte_data(int fd, int cmd);
inline __s32 i2c_smbus_write_byte_data(int fd, int cmd, int value);
inline __s32 i2c_smbus_read_word_data(int fd, int cmd);
inline __s32 i2c_smbus_write_word_data(int fd, int cmd, __u16 value);
inline __s32 i2c_smbus_read_data_block(int fd, int cmd, unsigned char *block, int block_size);
inline __s32 i2c_smbus_write_data_block(int fd, int cmd, unsigned char *block, int block_size);
inline __s32 i2c_smbus_write_data_block_with_size(int fd, int cmd, unsigned char *block, int block_size);

#endif
16 changes: 13 additions & 3 deletions src/wiringx.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,7 @@
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#include <time.h>
#include <termios.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#ifndef __FreeBSD__
Expand Down Expand Up @@ -154,7 +152,7 @@ EXPORT void delayMicroseconds(unsigned int howLong) {
#ifdef _WIN32
sleeper.tv_sec = wSecs;
#else
sleeper.tv_sec = (__time_t)wSecs;
sleeper.tv_sec = (__time_t)wSecs;
#endif
sleeper.tv_nsec = (long)(uSecs * 1000L);
nanosleep(&sleeper, NULL);
Expand Down Expand Up @@ -398,6 +396,10 @@ EXPORT int wiringXI2CReadReg16(int fd, int reg) {
return i2c_smbus_read_word_data(fd, reg);
}

EXPORT int wiringXI2CReadBlockData(int fd, int reg, unsigned char *block, int block_size) {
return i2c_smbus_read_data_block(fd, reg, block, block_size);
}

EXPORT int wiringXI2CWrite(int fd, int data) {
return i2c_smbus_write_byte(fd, data);
}
Expand All @@ -410,6 +412,14 @@ EXPORT int wiringXI2CWriteReg16(int fd, int reg, int data) {
return i2c_smbus_write_word_data(fd, reg, data);
}

EXPORT int wiringXI2CWriteBlockData(int fd, int reg, unsigned char *block, int block_size) {
return i2c_smbus_write_data_block(fd, reg, block, block_size);
}

EXPORT int wiringXI2CWriteBlockDataWithSize(int fd, int reg, unsigned char *block, int block_size) {
return i2c_smbus_write_data_block_with_size(fd, reg, block, block_size);
}

EXPORT int wiringXI2CSetup(const char *path, int devId) {
int fd = 0;

Expand Down
11 changes: 11 additions & 0 deletions src/wiringx.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
extern "C" {
#endif

#include <time.h>
#include <sys/time.h>
#include <errno.h>
#include <syslog.h>

Expand Down Expand Up @@ -66,6 +68,11 @@ typedef struct wiringXSerial_t {
unsigned int flowcontrol;
} wiringXSerial_t;

#ifdef __riscv
typedef time_t __time_t;
typedef suseconds_t __suseconds_t;
#endif

void delayMicroseconds(unsigned int);
int pinMode(int, enum pinmode_t);
int wiringXSetup(char *name, void (*func)(int, char *, int, const char *, ...));
Expand All @@ -80,9 +87,13 @@ int wiringXISR(int, enum isr_mode_t);
int wiringXI2CRead(int);
int wiringXI2CReadReg8(int, int);
int wiringXI2CReadReg16(int, int);
int wiringXI2CReadBlockData(int, int, unsigned char*, int);
int wiringXI2CWrite(int, int);
int wiringXI2CWriteReg8(int, int, int);
int wiringXI2CWriteReg16(int, int, int);
int wiringXI2CWriteBlockData(int, int, unsigned char*, int);
int wiringXI2CWriteBlockDataWithSize(int, int, unsigned char*, int);

int wiringXI2CSetup(const char *, int);

int wiringXSPIGetFd(int channel);
Expand Down

0 comments on commit 8658ad4

Please sign in to comment.