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.
main.cpp
- Committer:
- Wayne Roberts
- Date:
- 2019-02-03
- Revision:
- 3:0288d257446a
- Parent:
- 2:d7e05c75f240
File content as of revision 3:0288d257446a:
#include <mbed.h> #include "smbus.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); uint8_t test_buf[32]; 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_BUFFER: memcpy(i2c.tx_buf, test_buf, sizeof(test_buf)); 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; } } bool cmd_allowed(uint8_t) { /* return false if slave cannot take this cmd now */ return true; } 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; case CMD_BUFFER: memcpy(test_buf, req, sizeof(test_buf)); break; /* failures: */ case CMD_BUSERR: pc.printf("BUSERR%u\r\n", req[0]); break; case CMD_ARLO: pc.printf("ARLO%u\r\n", req[0]); // req[0] tx_cndtr break; case CMD_TIMEOUT: pc.printf("TIMEOUT%u\r\n", req[0]); // req[0] tx_cndtr 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(I2C_SDA, I2C_SCL, 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) }