From 84fbd01d01ec91c425d4ec9d828a206ffed525e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?King=20K=C3=A9vin?= Date: Tue, 26 Mar 2019 19:34:27 +0100 Subject: [PATCH] BV I2C: use new librarz and add dump8 command --- lib/busvoodoo_i2c.c | 105 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 88 insertions(+), 17 deletions(-) diff --git a/lib/busvoodoo_i2c.c b/lib/busvoodoo_i2c.c index 77531c3..c831dac 100644 --- a/lib/busvoodoo_i2c.c +++ b/lib/busvoodoo_i2c.c @@ -159,15 +159,28 @@ static void busvoodoo_i2c_exit(void) busvoodoo_embedded_pullup(false); // disable embedded pull-ups } -/** read from I2C */ -static void busvoodoo_i2c_read(void) +/** read from I2C + * @return if read operation succeeded + */ +static bool busvoodoo_i2c_read(uint16_t size) { + bool to_return = false; printf("read: "); busvoodoo_led_blue_pulse(BUSVOODOO_LED_PULSE); // pulse blue LED to show we read data - uint8_t data; // to store the data read - switch (i2c_master_read(BUSVOODOO_I2C, &data, 1)) { + uint8_t* data = malloc(size); + if (!data) { + busvoodoo_text_style(BUSVOODOO_TEXT_STYLE_ERROR); + printf("not enough free memory to read\n"); + busvoodoo_text_style(BUSVOODOO_TEXT_STYLE_RESET); + return false; + } + switch (i2c_master_read(BUSVOODOO_I2C, data, size)) { case I2C_MASTER_RC_NONE: // all went fine - printf("%+02x", data); // show data + for (uint16_t i = 0; i < size; i++) { + printf("%+02x ", data[i]); // show data + } + printf("NACK"); + to_return = true; break; case I2C_MASTER_RC_NOT_MASTER: printf("slave not selected"); @@ -194,21 +207,26 @@ static void busvoodoo_i2c_read(void) break; } printf("\n"); + free(data); + return to_return; } /** write to I2C * @param[in] data data to write + * @return if write operation succeeded */ -static void busvoodoo_i2c_write(uint8_t data) +static bool busvoodoo_i2c_write(uint8_t data) { + bool to_return = false; printf("write %+02x: ", data); busvoodoo_led_blue_pulse(BUSVOODOO_LED_PULSE); // pulse blue LED to show we send data switch (i2c_master_write(BUSVOODOO_I2C, &data, 1)) { case I2C_MASTER_RC_NONE: // all went fine - printf("ack"); + printf("ACK"); + to_return = true; break; case I2C_MASTER_RC_NAK: - printf("nack"); + printf("NACK"); break; case I2C_MASTER_RC_NOT_MASTER: printf("slave not selected"); @@ -235,14 +253,17 @@ static void busvoodoo_i2c_write(uint8_t data) break; } printf("\n"); + return to_return; } /** select I2C slave * @param[in] slave slave I2C address * @param[in] write enter read (false) or write (true) mode + * @return if select operation succeeded */ -static void busvoodoo_i2c_select(uint16_t slave, bool write) +static bool busvoodoo_i2c_select(uint16_t slave, bool write) { + bool to_return = false; printf("select slave "); if (10 == busvoodoo_i2c_addressbits) { printf("%+03x", slave); @@ -254,6 +275,7 @@ static void busvoodoo_i2c_select(uint16_t slave, bool write) switch (i2c_master_select_slave(BUSVOODOO_I2C, slave, 10 == busvoodoo_i2c_addressbits, write)) { case I2C_MASTER_RC_NONE: // all went fine printf("selected"); + to_return = true; break; case I2C_MASTER_RC_NAK: printf("no such slave"); @@ -285,6 +307,7 @@ static void busvoodoo_i2c_select(uint16_t slave, bool write) break; } printf("\n"); + return to_return; } /** perform I2C action @@ -304,9 +327,7 @@ static bool busvoodoo_i2c_action(const char* action, uint32_t repetition, bool p if (!perform) { return true; } - for (uint32_t i = 0; i < repetition; i++) { - busvoodoo_i2c_read(); // read from I2C - } + busvoodoo_i2c_read(repetition); // read from I2C } else if (1 == length && '[' == action[0]) { // select slave if (!perform) { return true; @@ -452,13 +473,13 @@ static void busvoodoo_i2c_command_actions(void* argument) if (NULL == argument || 0 == strlen(argument)) { printf("available actions (separated by space or ,):\n"); printf("[/]\tsend start/stop conditions\n"); - printf("0x0r\tselect slave with I2C address to read\n"); - printf("0x0w\tselect slave with I2C address to write\n"); + printf("0x00r\tselect slave with I2C address to read\n"); + printf("0x00w\tselect slave with I2C address to write\n"); printf("0\twrite decimal value\n"); - printf("0x0\twrite hexadecimal value\n"); - printf("0b0\twrite binary value\n"); + printf("0x00\twrite hexadecimal value\n"); + printf("0b00000000\twrite binary value\n"); printf("\"a\"/'a'\twrite ASCII characters\n"); - printf("r\tread value\n"); + printf("r\tread value (last repetition NAKed)\n"); printf("u/m\twait 1 us/ms\n"); printf(":n\trepeat action n times\n"); return; @@ -550,6 +571,48 @@ static void busvoodoo_i2c_command_scan(void* argument) printf("\n%u slave(s) found\n", i2c_slaves); // show summary } +/** read all bytes from an 8-bit memory + * @param[in] argument address of I2C slave memory device + */ +static void busvoodoo_i2c_command_dump8(void* argument) +{ + uint16_t address = *(uint32_t*)argument; // use argument as device address + printf("reading bytes from 8-bit memory device at I2C address "); // display explanation + printf((busvoodoo_i2c_addressbits > 7) ? "%+03x\n" : "%+02x\n", address); // display address + bool rc = (I2C_MASTER_RC_NONE == i2c_master_start(BUSVOODOO_I2C)); // send start condition + printf("start condition: %s\n", rc ? "sent" : "error"); + if (!rc) { + return; + } + rc = busvoodoo_i2c_select(address, true); // select device to write address + if (!rc) { + goto error; + } + rc = busvoodoo_i2c_write(0); // write start address + if (!rc) { + goto error; + } + rc = (I2C_MASTER_RC_NONE == i2c_master_start(BUSVOODOO_I2C)); // send start condition + printf("re-start condition: %s\n", rc ? "sent" : "error"); + if (!rc) { + goto error; + } + rc = busvoodoo_i2c_select(address, false); // select device to write address + if (!rc) { + goto error; + } + rc = busvoodoo_i2c_read(256); // read bytes + if (!rc) { + goto error; + } + rc = (I2C_MASTER_RC_NONE == i2c_master_stop(BUSVOODOO_I2C)); // send start condition + printf("stop condition: %s\n", rc ? "sent" : "error"); + + return; +error: + i2c_master_stop(BUSVOODOO_I2C); // send transaction +} + /** I2C menu commands */ static const struct menu_command_t busvoodoo_i2c_commands[] = { { @@ -576,6 +639,14 @@ static const struct menu_command_t busvoodoo_i2c_commands[] = { .argument_description = NULL, .command_handler = &busvoodoo_i2c_command_scan, }, + { + .shortcut = 'd', + .name = "dump8", + .command_description = "dump 8-bit address space memory", + .argument = MENU_ARGUMENT_HEX, + .argument_description = "0xaddr", + .command_handler = &busvoodoo_i2c_command_dump8, + }, }; const struct busvoodoo_mode_t busvoodoo_i2c_mode = {