C API first cut, i2ccl running

This commit is contained in:
James Bowman 2019-02-23 15:44:54 -08:00
parent c03a6f2ffb
commit 11d49d4f20
3 changed files with 90 additions and 70 deletions

View File

@ -257,89 +257,82 @@ void i2c_connect(I2CDriver *sd, const char* portname)
sd->e_ccitt_crc = sd->ccitt_crc; sd->e_ccitt_crc = sd->ccitt_crc;
} }
static int i2c_ack(I2CDriver *sd)
{
uint8_t a[1];
if (readFromSerialPort(sd->port, a, 1) != 1)
return 0;
return (a[0] & 1) != 0;
}
void i2c_getstatus(I2CDriver *sd) void i2c_getstatus(I2CDriver *sd)
{ {
char readbuffer[100]; char readbuffer[100];
int bytesRead; int bytesRead;
char mode[80];
writeToSerialPort(sd->port, "?", 1); writeToSerialPort(sd->port, "?", 1);
bytesRead = readFromSerialPort(sd->port, readbuffer, 80); bytesRead = readFromSerialPort(sd->port, readbuffer, 80);
readbuffer[bytesRead] = 0; readbuffer[bytesRead] = 0;
// printf("%d Bytes were read: %.*s\n", bytesRead, bytesRead, readbuffer); // printf("%d Bytes were read: %.*s\n", bytesRead, bytesRead, readbuffer);
sscanf(readbuffer, "[%15s %8s %" SCNu64 " %f %f %f %d %d %d %x ]", sscanf(readbuffer, "[%15s %8s %" SCNu64 " %f %f %f %c %d %d %d %d %x ]",
sd->model, sd->model,
sd->serial, sd->serial,
&sd->uptime, &sd->uptime,
&sd->voltage_v, &sd->voltage_v,
&sd->current_ma, &sd->current_ma,
&sd->temp_celsius, &sd->temp_celsius,
&sd->a, mode,
&sd->b, &sd->sda,
&sd->cs, &sd->scl,
&sd->speed,
&sd->pullups,
&sd->ccitt_crc &sd->ccitt_crc
); );
sd->mode = mode[0];
} }
void i2c_sel(I2CDriver *sd) void i2c_scan(I2CDriver *sd, uint8_t devices[128])
{ {
writeToSerialPort(sd->port, "s", 1); writeToSerialPort(sd->port, "d", 1);
sd->cs = 0; (void)readFromSerialPort(sd->port, devices + 8, 112);
} }
void i2c_unsel(I2CDriver *sd) int i2c_start(I2CDriver *sd, uint8_t dev, uint8_t op)
{ {
writeToSerialPort(sd->port, "u", 1); uint8_t start[2] = {'s', (dev << 1) | op};
sd->cs = 1; writeToSerialPort(sd->port, start, sizeof(start));
return i2c_ack(sd);
} }
void i2c_seta(I2CDriver *sd, char v) void i2c_stop(I2CDriver *sd)
{ {
char cmd[2] = {'a', v}; writeToSerialPort(sd->port, "p", 1);
writeToSerialPort(sd->port, cmd, 2);
sd->a = v;
} }
void i2c_setb(I2CDriver *sd, char v) int i2c_write(I2CDriver *sd, const uint8_t bytes[], size_t nn)
{
char cmd[2] = {'b', v};
writeToSerialPort(sd->port, cmd, 2);
sd->b = v;
}
void i2c_write(I2CDriver *sd, const char bytes[], size_t nn)
{ {
size_t i; size_t i;
int ack = 1;
for (i = 0; i < nn; i += 64) { for (i = 0; i < nn; i += 64) {
size_t len = ((nn - i) < 64) ? (nn - i) : 64; size_t len = ((nn - i) < 64) ? (nn - i) : 64;
char cmd[65] = {(char)(0xc0 + len - 1)}; uint8_t cmd[65] = {(uint8_t)(0xc0 + len - 1)};
memcpy(cmd + 1, bytes + i, len); memcpy(cmd + 1, bytes + i, len);
writeToSerialPort(sd->port, cmd, 1 + len); writeToSerialPort(sd->port, cmd, 1 + len);
ack = i2c_ack(sd);
} }
crc_update(sd, bytes, nn); crc_update(sd, bytes, nn);
} }
void i2c_read(I2CDriver *sd, char bytes[], size_t nn) void i2c_read(I2CDriver *sd, uint8_t bytes[], size_t nn)
{ {
size_t i; size_t i;
for (i = 0; i < nn; i += 64) {
size_t len = ((nn - i) < 64) ? (nn - i) : 64;
char cmd[65] = {(char)(0x80 + len - 1), 0};
writeToSerialPort(sd->port, cmd, 1 + len);
crc_update(sd, cmd + 1, len);
readFromSerialPort(sd->port, bytes + i, len);
crc_update(sd, bytes + i, len);
}
}
void i2c_writeread(I2CDriver *sd, char bytes[], size_t nn)
{
size_t i;
for (i = 0; i < nn; i += 64) { for (i = 0; i < nn; i += 64) {
size_t len = ((nn - i) < 64) ? (nn - i) : 64; size_t len = ((nn - i) < 64) ? (nn - i) : 64;
char cmd[65] = {(char)(0x80 + len - 1)}; uint8_t cmd[1] = {(uint8_t)(0x80 + len - 1)};
memcpy(cmd + 1, bytes + i, len); writeToSerialPort(sd->port, cmd, 1);
writeToSerialPort(sd->port, cmd, 1 + len);
crc_update(sd, cmd + 1, len);
readFromSerialPort(sd->port, bytes + i, len); readFromSerialPort(sd->port, bytes + i, len);
crc_update(sd, bytes + i, len); crc_update(sd, bytes + i, len);
} }
@ -358,20 +351,41 @@ int i2c_commands(I2CDriver *sd, int argc, char *argv[])
case 'i': case 'i':
i2c_getstatus(sd); i2c_getstatus(sd);
printf("uptime %" SCNu64" %.3f V %.0f mA %.1f C\n", sd->uptime, sd->voltage_v, sd->current_ma, sd->temp_celsius); printf("uptime %" SCNu64" %.3f V %.0f mA %.1f C SDA=%d SCL=%d speed=%d kHz\n",
sd->uptime,
sd->voltage_v,
sd->current_ma,
sd->temp_celsius,
sd->sda,
sd->scl,
sd->speed
);
break; break;
case 's': case 'd':
i2c_sel(sd);
break;
case 'u':
i2c_unsel(sd);
break;
case 'w':
case 't':
{ {
uint8_t devices[128];
int i;
i2c_scan(sd, devices);
printf("\n");
for (i = 8; i < 0x78; i++) {
if (devices[i] == '1')
printf("%02x ", i);
else
printf("-- ");
if ((i % 8) == 7)
printf("\n");
}
printf("\n");
}
break;
case 'w':
{
token = argv[++i];
unsigned int dev = strtol(token, NULL, 0);
token = argv[++i]; token = argv[++i];
char bytes[8192], *endptr = token; char bytes[8192], *endptr = token;
size_t nn = 0; size_t nn = 0;
@ -385,16 +399,25 @@ int i2c_commands(I2CDriver *sd, int argc, char *argv[])
} }
endptr++; endptr++;
} }
i2c_start(sd, dev, 0);
i2c_write(sd, bytes, nn); i2c_write(sd, bytes, nn);
} }
break; break;
case 'r': case 'r':
{ {
token = argv[++i];
unsigned int dev = strtol(token, NULL, 0);
token = argv[++i]; token = argv[++i];
size_t nn = strtol(token, NULL, 0); size_t nn = strtol(token, NULL, 0);
char bytes[8192]; char bytes[8192];
i2c_start(sd, dev, 1);
i2c_read(sd, bytes, nn); i2c_read(sd, bytes, nn);
i2c_stop(sd);
size_t i; size_t i;
for (i = 0; i < nn; i++) for (i = 0; i < nn; i++)
printf("%s0x%02x", i ? "," : "", 0xff & bytes[i]); printf("%s0x%02x", i ? "," : "", 0xff & bytes[i]);
@ -402,16 +425,8 @@ int i2c_commands(I2CDriver *sd, int argc, char *argv[])
} }
break; break;
case 'a': case 'p':
token = argv[++i]; i2c_stop(sd);
if (token != NULL)
i2c_seta(sd, token[0]);
break;
case 'b':
token = argv[++i];
if (token != NULL)
i2c_setb(sd, token[0]);
break; break;
default: default:
@ -420,13 +435,11 @@ int i2c_commands(I2CDriver *sd, int argc, char *argv[])
fprintf(stderr, "\n"); fprintf(stderr, "\n");
fprintf(stderr, "Commands are:"); fprintf(stderr, "Commands are:");
fprintf(stderr, "\n"); fprintf(stderr, "\n");
fprintf(stderr, " i display status information (uptime, voltage, current, temperature)\n"); fprintf(stderr, " i display status information (uptime, voltage, current, temperature)\n");
fprintf(stderr, " s I2C select\n"); fprintf(stderr, " d device scan\n");
fprintf(stderr, " u I2C unselect\n"); fprintf(stderr, " w dev <bytes> write bytes to I2C device dev\n");
fprintf(stderr, " w write bytes to I2C\n"); fprintf(stderr, " p send a STOP\n");
fprintf(stderr, " r N read N bytes from I2C\n"); fprintf(stderr, " r dev N read N bytes from I2C device dev, then STOP\n");
fprintf(stderr, " a 0/1 Set A line\n");
fprintf(stderr, " b 0/1 Set B line\n");
fprintf(stderr, "\n"); fprintf(stderr, "\n");
return 1; return 1;

View File

@ -18,6 +18,11 @@ typedef struct {
float voltage_v, // USB voltage (Volts) float voltage_v, // USB voltage (Volts)
current_ma, // device current (mA) current_ma, // device current (mA)
temp_celsius; // temperature (C) temp_celsius; // temperature (C)
unsigned int mode; // I2C 'I' or bitbang 'B' mode
unsigned int sda; // SDA state, 0 or 1
unsigned int scl; // SCL state, 0 or 1
unsigned int speed; // I2C line speed (in kHz)
unsigned int pullups; // pullup state (6 bits, 1=enabled)
unsigned int unsigned int
ccitt_crc, // Hardware CCITT CRC ccitt_crc, // Hardware CCITT CRC
e_ccitt_crc; // Host CCITT CRC, should match e_ccitt_crc; // Host CCITT CRC, should match
@ -25,8 +30,9 @@ typedef struct {
void i2c_connect(I2CDriver *sd, const char* portname); void i2c_connect(I2CDriver *sd, const char* portname);
void i2c_getstatus(I2CDriver *sd); void i2c_getstatus(I2CDriver *sd);
void i2c_write(I2CDriver *sd, const char bytes[], size_t nn); int i2c_write(I2CDriver *sd, const uint8_t bytes[], size_t nn);
void i2c_read(I2CDriver *sd, char bytes[], size_t nn); void i2c_read(I2CDriver *sd, uint8_t bytes[], size_t nn);
void i2c_stop(I2CDriver *sd);
int i2c_commands(I2CDriver *sd, int argc, char *argv[]); int i2c_commands(I2CDriver *sd, int argc, char *argv[]);

1
c/go
View File

@ -2,6 +2,7 @@ set -e
rm -rf build/* rm -rf build/*
make -f linux/Makefile make -f linux/Makefile
build/i2ccl /dev/ttyUSB0 i
# make -f win32/Makefile # make -f win32/Makefile
# cp build/spicl.exe /data/win10/ # cp build/spicl.exe /data/win10/