example of i2c slave device supporting block transfers

Dependencies:   lib_i2c_slave_block

Tested on nucleo board as slave. Use with i2c_master_block_example on raspberry pi as master.

Master I2C write will print on serial terminal 115200. User button will raise an irq; the RPi test program will service the interrupt.

See lib_i2c_slave_block for explanation of code.

Revision:
0:3ccfaf358115
Child:
2:d7e05c75f240
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Fri Jan 18 14:36:09 2019 -0800
@@ -0,0 +1,92 @@
+
+#include <mbed.h>
+#include "smbus.h"
+#include "cmds.h"
+
+#define IRQ_OUT_PIN     D6
+
+const int SLAVE_ADDRESS = 0xA0;
+
+RawSerial pc(USBTX, USBRX);
+
+DigitalOut irqOutPin(IRQ_OUT_PIN);
+irq_t irq;
+
+DigitalIn button(USER_BUTTON);
+
+
+void fill_tx_buf(uint8_t cmd)
+{
+    static uint8_t cnt = 0;
+    unsigned i;
+
+    /* answering (master read) request here */
+
+    switch (cmd) {
+        case CMD_TEST3:
+        case CMD_TEST12:
+        case CMD_TEST32:
+            for (i = 0; i < cmd_to_length[cmd]; i++)
+                i2c.tx_buf[i] = i + cnt;
+            cnt++;
+            break;
+        case CMD_IRQ:
+            for (i = 0; i < cmd_to_length[CMD_IRQ]; i++)
+                i2c.tx_buf[i] = irq.buf[i];
+
+            /* interrupt was (is being) read, clear it */
+            irq.fields.flags.button = 0;
+            if (irq.buf[0] == 0)
+                irqOutPin = 0;
+
+            break;
+    }
+}
+
+void service_i2c_write(uint8_t cmd, uint8_t len, const uint8_t* req)
+{
+    uint8_t s8;
+
+    /* taking master write here */
+
+    switch (cmd) {
+        case CMD_TEST3:
+        case CMD_TEST12:
+        case CMD_TEST32:
+            for (s8 = 0; s8 < cmd_to_length[cmd]; s8++)
+                pc.printf("%02x ", req[s8]);
+            pc.printf("\r\n");
+            break;
+        default:
+            pc.printf("??%02x??|\r\n", cmd);
+            break;
+    } // ..switch (cmd)
+}
+
+int main()
+{
+    int res;
+    bool but;
+    uint8_t cnt = 0;
+
+    pc.baud(115200);
+    pc.printf("\r\nreset\r\n");
+
+    res = smbus_init(SLAVE_ADDRESS);
+    pc.printf("%d = smbus_init()\r\n", res);
+
+    but = button.read();
+    while (1) {
+        service_i2c();
+
+        if (but != button.read()) {
+            irq.fields.cnt = cnt++;
+            irq.fields.flags.button = 1;
+            irqOutPin = 1;
+
+            but = button.read();
+        }
+
+    } // ..while (1)
+}
+