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@0:3ccfaf358115, 2019-01-18 (annotated)
- Committer:
- Wayne Roberts
- Date:
- Fri Jan 18 14:36:09 2019 -0800
- Revision:
- 0:3ccfaf358115
- Child:
- 2:d7e05c75f240
initial commit
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Wayne Roberts |
0:3ccfaf358115 | 1 | |
Wayne Roberts |
0:3ccfaf358115 | 2 | #include <mbed.h> |
Wayne Roberts |
0:3ccfaf358115 | 3 | #include "smbus.h" |
Wayne Roberts |
0:3ccfaf358115 | 4 | #include "cmds.h" |
Wayne Roberts |
0:3ccfaf358115 | 5 | |
Wayne Roberts |
0:3ccfaf358115 | 6 | #define IRQ_OUT_PIN D6 |
Wayne Roberts |
0:3ccfaf358115 | 7 | |
Wayne Roberts |
0:3ccfaf358115 | 8 | const int SLAVE_ADDRESS = 0xA0; |
Wayne Roberts |
0:3ccfaf358115 | 9 | |
Wayne Roberts |
0:3ccfaf358115 | 10 | RawSerial pc(USBTX, USBRX); |
Wayne Roberts |
0:3ccfaf358115 | 11 | |
Wayne Roberts |
0:3ccfaf358115 | 12 | DigitalOut irqOutPin(IRQ_OUT_PIN); |
Wayne Roberts |
0:3ccfaf358115 | 13 | irq_t irq; |
Wayne Roberts |
0:3ccfaf358115 | 14 | |
Wayne Roberts |
0:3ccfaf358115 | 15 | DigitalIn button(USER_BUTTON); |
Wayne Roberts |
0:3ccfaf358115 | 16 | |
Wayne Roberts |
0:3ccfaf358115 | 17 | |
Wayne Roberts |
0:3ccfaf358115 | 18 | void fill_tx_buf(uint8_t cmd) |
Wayne Roberts |
0:3ccfaf358115 | 19 | { |
Wayne Roberts |
0:3ccfaf358115 | 20 | static uint8_t cnt = 0; |
Wayne Roberts |
0:3ccfaf358115 | 21 | unsigned i; |
Wayne Roberts |
0:3ccfaf358115 | 22 | |
Wayne Roberts |
0:3ccfaf358115 | 23 | /* answering (master read) request here */ |
Wayne Roberts |
0:3ccfaf358115 | 24 | |
Wayne Roberts |
0:3ccfaf358115 | 25 | switch (cmd) { |
Wayne Roberts |
0:3ccfaf358115 | 26 | case CMD_TEST3: |
Wayne Roberts |
0:3ccfaf358115 | 27 | case CMD_TEST12: |
Wayne Roberts |
0:3ccfaf358115 | 28 | case CMD_TEST32: |
Wayne Roberts |
0:3ccfaf358115 | 29 | for (i = 0; i < cmd_to_length[cmd]; i++) |
Wayne Roberts |
0:3ccfaf358115 | 30 | i2c.tx_buf[i] = i + cnt; |
Wayne Roberts |
0:3ccfaf358115 | 31 | cnt++; |
Wayne Roberts |
0:3ccfaf358115 | 32 | break; |
Wayne Roberts |
0:3ccfaf358115 | 33 | case CMD_IRQ: |
Wayne Roberts |
0:3ccfaf358115 | 34 | for (i = 0; i < cmd_to_length[CMD_IRQ]; i++) |
Wayne Roberts |
0:3ccfaf358115 | 35 | i2c.tx_buf[i] = irq.buf[i]; |
Wayne Roberts |
0:3ccfaf358115 | 36 | |
Wayne Roberts |
0:3ccfaf358115 | 37 | /* interrupt was (is being) read, clear it */ |
Wayne Roberts |
0:3ccfaf358115 | 38 | irq.fields.flags.button = 0; |
Wayne Roberts |
0:3ccfaf358115 | 39 | if (irq.buf[0] == 0) |
Wayne Roberts |
0:3ccfaf358115 | 40 | irqOutPin = 0; |
Wayne Roberts |
0:3ccfaf358115 | 41 | |
Wayne Roberts |
0:3ccfaf358115 | 42 | break; |
Wayne Roberts |
0:3ccfaf358115 | 43 | } |
Wayne Roberts |
0:3ccfaf358115 | 44 | } |
Wayne Roberts |
0:3ccfaf358115 | 45 | |
Wayne Roberts |
0:3ccfaf358115 | 46 | void service_i2c_write(uint8_t cmd, uint8_t len, const uint8_t* req) |
Wayne Roberts |
0:3ccfaf358115 | 47 | { |
Wayne Roberts |
0:3ccfaf358115 | 48 | uint8_t s8; |
Wayne Roberts |
0:3ccfaf358115 | 49 | |
Wayne Roberts |
0:3ccfaf358115 | 50 | /* taking master write here */ |
Wayne Roberts |
0:3ccfaf358115 | 51 | |
Wayne Roberts |
0:3ccfaf358115 | 52 | switch (cmd) { |
Wayne Roberts |
0:3ccfaf358115 | 53 | case CMD_TEST3: |
Wayne Roberts |
0:3ccfaf358115 | 54 | case CMD_TEST12: |
Wayne Roberts |
0:3ccfaf358115 | 55 | case CMD_TEST32: |
Wayne Roberts |
0:3ccfaf358115 | 56 | for (s8 = 0; s8 < cmd_to_length[cmd]; s8++) |
Wayne Roberts |
0:3ccfaf358115 | 57 | pc.printf("%02x ", req[s8]); |
Wayne Roberts |
0:3ccfaf358115 | 58 | pc.printf("\r\n"); |
Wayne Roberts |
0:3ccfaf358115 | 59 | break; |
Wayne Roberts |
0:3ccfaf358115 | 60 | default: |
Wayne Roberts |
0:3ccfaf358115 | 61 | pc.printf("??%02x??|\r\n", cmd); |
Wayne Roberts |
0:3ccfaf358115 | 62 | break; |
Wayne Roberts |
0:3ccfaf358115 | 63 | } // ..switch (cmd) |
Wayne Roberts |
0:3ccfaf358115 | 64 | } |
Wayne Roberts |
0:3ccfaf358115 | 65 | |
Wayne Roberts |
0:3ccfaf358115 | 66 | int main() |
Wayne Roberts |
0:3ccfaf358115 | 67 | { |
Wayne Roberts |
0:3ccfaf358115 | 68 | int res; |
Wayne Roberts |
0:3ccfaf358115 | 69 | bool but; |
Wayne Roberts |
0:3ccfaf358115 | 70 | uint8_t cnt = 0; |
Wayne Roberts |
0:3ccfaf358115 | 71 | |
Wayne Roberts |
0:3ccfaf358115 | 72 | pc.baud(115200); |
Wayne Roberts |
0:3ccfaf358115 | 73 | pc.printf("\r\nreset\r\n"); |
Wayne Roberts |
0:3ccfaf358115 | 74 | |
Wayne Roberts |
0:3ccfaf358115 | 75 | res = smbus_init(SLAVE_ADDRESS); |
Wayne Roberts |
0:3ccfaf358115 | 76 | pc.printf("%d = smbus_init()\r\n", res); |
Wayne Roberts |
0:3ccfaf358115 | 77 | |
Wayne Roberts |
0:3ccfaf358115 | 78 | but = button.read(); |
Wayne Roberts |
0:3ccfaf358115 | 79 | while (1) { |
Wayne Roberts |
0:3ccfaf358115 | 80 | service_i2c(); |
Wayne Roberts |
0:3ccfaf358115 | 81 | |
Wayne Roberts |
0:3ccfaf358115 | 82 | if (but != button.read()) { |
Wayne Roberts |
0:3ccfaf358115 | 83 | irq.fields.cnt = cnt++; |
Wayne Roberts |
0:3ccfaf358115 | 84 | irq.fields.flags.button = 1; |
Wayne Roberts |
0:3ccfaf358115 | 85 | irqOutPin = 1; |
Wayne Roberts |
0:3ccfaf358115 | 86 | |
Wayne Roberts |
0:3ccfaf358115 | 87 | but = button.read(); |
Wayne Roberts |
0:3ccfaf358115 | 88 | } |
Wayne Roberts |
0:3ccfaf358115 | 89 | |
Wayne Roberts |
0:3ccfaf358115 | 90 | } // ..while (1) |
Wayne Roberts |
0:3ccfaf358115 | 91 | } |
Wayne Roberts |
0:3ccfaf358115 | 92 |