aboutsummaryrefslogtreecommitdiff
path: root/i2c/sw/tc_i2c.c
diff options
context:
space:
mode:
Diffstat (limited to 'i2c/sw/tc_i2c.c')
-rw-r--r--i2c/sw/tc_i2c.c82
1 files changed, 58 insertions, 24 deletions
diff --git a/i2c/sw/tc_i2c.c b/i2c/sw/tc_i2c.c
index da1ab14..613d1c6 100644
--- a/i2c/sw/tc_i2c.c
+++ b/i2c/sw/tc_i2c.c
@@ -37,7 +37,6 @@
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
-#include <linux/i2c-dev.h>
#include <sys/ioctl.h>
#include <stdint.h>
@@ -47,7 +46,7 @@ extern int debug;
/* ---------------- I2C low-level code ---------------- */
-static int i2cfd;
+static int i2cfd = -1;
static void dump(char *label, const uint8_t *buf, size_t len)
{
@@ -65,25 +64,28 @@ static void i2c_close(void)
close(i2cfd);
}
-int i2c_open(char *dev, int addr)
+static int i2c_open(void)
{
- i2cfd = open(dev, O_RDWR);
+ if (i2cfd >= 0)
+ return 0;
+
+ i2cfd = open(I2C_dev, O_RDWR);
if (i2cfd < 0) {
- fprintf(stderr, "Unable to open %s: ", dev);
+ fprintf(stderr, "Unable to open %s: ", I2C_dev);
perror("");
i2cfd = 0;
return 1;
}
- if (ioctl(i2cfd, I2C_SLAVE, addr) < 0) {
- fprintf(stderr, "Unable to set I2C slave device 0x%02x: ", addr);
+ if (ioctl(i2cfd, I2C_SLAVE, I2C_addr) < 0) {
+ fprintf(stderr, "Unable to set I2C slave device 0x%02x: ", I2C_addr);
perror("");
return 1;
}
if (atexit(i2c_close) != 0) {
- fprintf(stderr, "Unable to set I2C atexit handler.");
- return 1;
+ fprintf(stderr, "Unable to set I2C atexit handler.");
+ return 1;
}
return 0;
@@ -91,6 +93,9 @@ int i2c_open(char *dev, int addr)
static int i2c_write(const uint8_t *buf, size_t len)
{
+ if (i2c_open() != 0)
+ return 1;
+
dump("write ", buf, len);
if (write(i2cfd, buf, len) != len) {
@@ -103,6 +108,9 @@ static int i2c_write(const uint8_t *buf, size_t len)
static int i2c_read(uint8_t *b)
{
+ if (i2c_open() != 0)
+ return 1;
+
/* read() on the i2c device only returns one byte at a time,
* and tc_get_resp() needs to parse the response one byte at a time
*/
@@ -235,20 +243,20 @@ static int tc_get_read_resp_expected(off_t offset, const uint8_t *data)
{
uint8_t buf[9];
uint8_t expected[9] = { SOR, READ_OK, (offset >> 8) & 0xff, offset & 0xff,
- data[0], data[1], data[2], data[3], EOR };
+ data[0], data[1], data[2], data[3], EOR };
dump("expect", expected, 9);
return (tc_get_resp(buf, sizeof(buf)) ||
- tc_compare(buf, expected, sizeof(buf)));
+ tc_compare(buf, expected, sizeof(buf)));
}
int tc_write(off_t offset, const uint8_t *buf, size_t len)
{
for (; len > 0; offset++, buf += 4, len -= 4) {
- if (tc_send_write_cmd(offset, buf) ||
+ if (tc_send_write_cmd(offset, buf) ||
tc_get_write_resp(offset))
- return 1;
+ return 1;
}
return 0;
@@ -257,9 +265,9 @@ int tc_write(off_t offset, const uint8_t *buf, size_t len)
int tc_read(off_t offset, uint8_t *buf, size_t len)
{
for (; len > 0; offset++, buf += 4, len -= 4) {
- if (tc_send_read_cmd(offset) ||
+ if (tc_send_read_cmd(offset) ||
tc_get_read_resp(offset, buf))
- return 1;
+ return 1;
}
return 0;
@@ -268,30 +276,56 @@ int tc_read(off_t offset, uint8_t *buf, size_t len)
int tc_expected(off_t offset, const uint8_t *buf, size_t len)
{
for (; len > 0; offset++, buf += 4, len -= 4) {
- if (tc_send_read_cmd(offset) ||
+ if (tc_send_read_cmd(offset) ||
tc_get_read_resp_expected(offset, buf))
- return 1;
+ return 1;
}
return 0;
}
+int tc_init(off_t offset)
+{
+ uint8_t buf[4] = { 0, 0, 0, CTRL_INIT_CMD };
+
+ return tc_write(offset, buf, 4);
+}
+
+int tc_next(off_t offset)
+{
+ uint8_t buf[4] = { 0, 0, 0, CTRL_NEXT_CMD };
+
+ return tc_write(offset, buf, 4);
+}
+
int tc_wait(off_t offset, uint8_t status, int *count)
{
uint8_t buf[4];
int i;
for (i = 1; ; ++i) {
- if (count && (*count > 0) && (i >= *count)) {
- fprintf(stderr, "tc_wait timed out\n");
- return 1;
- }
+ if (count && (*count > 0) && (i >= *count)) {
+ fprintf(stderr, "tc_wait timed out\n");
+ return 1;
+ }
if (tc_read(offset, buf, 4) != 0)
return -1;
if (buf[3] & status) {
- if (count)
- *count = i;
+ if (count)
+ *count = i;
return 0;
- }
+ }
}
}
+
+int tc_wait_ready(off_t offset)
+{
+ int limit = 10;
+ return tc_wait(offset, STATUS_READY_BIT, &limit);
+}
+
+int tc_wait_valid(off_t offset)
+{
+ int limit = 10;
+ return tc_wait(offset, STATUS_VALID_BIT, &limit);
+}