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.

Committer:
Wayne Roberts
Date:
Mon Jan 21 18:09:05 2019 -0800
Revision:
2:d7e05c75f240
Parent:
0:3ccfaf358115
Child:
3:0288d257446a
add buffer for read/write integrity test

Who changed what in which revision?

UserRevisionLine numberNew 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 2:d7e05c75f240 17 uint8_t test_buf[32];
Wayne Roberts 0:3ccfaf358115 18
Wayne Roberts 0:3ccfaf358115 19 void fill_tx_buf(uint8_t cmd)
Wayne Roberts 0:3ccfaf358115 20 {
Wayne Roberts 0:3ccfaf358115 21 static uint8_t cnt = 0;
Wayne Roberts 0:3ccfaf358115 22 unsigned i;
Wayne Roberts 0:3ccfaf358115 23
Wayne Roberts 0:3ccfaf358115 24 /* answering (master read) request here */
Wayne Roberts 0:3ccfaf358115 25
Wayne Roberts 0:3ccfaf358115 26 switch (cmd) {
Wayne Roberts 0:3ccfaf358115 27 case CMD_TEST3:
Wayne Roberts 0:3ccfaf358115 28 case CMD_TEST12:
Wayne Roberts 0:3ccfaf358115 29 case CMD_TEST32:
Wayne Roberts 0:3ccfaf358115 30 for (i = 0; i < cmd_to_length[cmd]; i++)
Wayne Roberts 0:3ccfaf358115 31 i2c.tx_buf[i] = i + cnt;
Wayne Roberts 0:3ccfaf358115 32 cnt++;
Wayne Roberts 0:3ccfaf358115 33 break;
Wayne Roberts 2:d7e05c75f240 34 case CMD_BUFFER:
Wayne Roberts 2:d7e05c75f240 35 memcpy(i2c.tx_buf, test_buf, sizeof(test_buf));
Wayne Roberts 2:d7e05c75f240 36 break;
Wayne Roberts 0:3ccfaf358115 37 case CMD_IRQ:
Wayne Roberts 0:3ccfaf358115 38 for (i = 0; i < cmd_to_length[CMD_IRQ]; i++)
Wayne Roberts 0:3ccfaf358115 39 i2c.tx_buf[i] = irq.buf[i];
Wayne Roberts 0:3ccfaf358115 40
Wayne Roberts 0:3ccfaf358115 41 /* interrupt was (is being) read, clear it */
Wayne Roberts 0:3ccfaf358115 42 irq.fields.flags.button = 0;
Wayne Roberts 0:3ccfaf358115 43 if (irq.buf[0] == 0)
Wayne Roberts 0:3ccfaf358115 44 irqOutPin = 0;
Wayne Roberts 0:3ccfaf358115 45
Wayne Roberts 0:3ccfaf358115 46 break;
Wayne Roberts 0:3ccfaf358115 47 }
Wayne Roberts 0:3ccfaf358115 48 }
Wayne Roberts 0:3ccfaf358115 49
Wayne Roberts 2:d7e05c75f240 50 bool cmd_allowed(uint8_t)
Wayne Roberts 2:d7e05c75f240 51 {
Wayne Roberts 2:d7e05c75f240 52 /* return false if slave cannot take this cmd now */
Wayne Roberts 2:d7e05c75f240 53 return true;
Wayne Roberts 2:d7e05c75f240 54 }
Wayne Roberts 2:d7e05c75f240 55
Wayne Roberts 0:3ccfaf358115 56 void service_i2c_write(uint8_t cmd, uint8_t len, const uint8_t* req)
Wayne Roberts 0:3ccfaf358115 57 {
Wayne Roberts 0:3ccfaf358115 58 uint8_t s8;
Wayne Roberts 0:3ccfaf358115 59
Wayne Roberts 0:3ccfaf358115 60 /* taking master write here */
Wayne Roberts 0:3ccfaf358115 61
Wayne Roberts 0:3ccfaf358115 62 switch (cmd) {
Wayne Roberts 0:3ccfaf358115 63 case CMD_TEST3:
Wayne Roberts 0:3ccfaf358115 64 case CMD_TEST12:
Wayne Roberts 0:3ccfaf358115 65 case CMD_TEST32:
Wayne Roberts 0:3ccfaf358115 66 for (s8 = 0; s8 < cmd_to_length[cmd]; s8++)
Wayne Roberts 0:3ccfaf358115 67 pc.printf("%02x ", req[s8]);
Wayne Roberts 0:3ccfaf358115 68 pc.printf("\r\n");
Wayne Roberts 0:3ccfaf358115 69 break;
Wayne Roberts 2:d7e05c75f240 70 case CMD_BUFFER:
Wayne Roberts 2:d7e05c75f240 71 memcpy(test_buf, req, sizeof(test_buf));
Wayne Roberts 2:d7e05c75f240 72 break;
Wayne Roberts 0:3ccfaf358115 73 default:
Wayne Roberts 2:d7e05c75f240 74 pc.printf("??%02x??\r\n", cmd);
Wayne Roberts 0:3ccfaf358115 75 break;
Wayne Roberts 0:3ccfaf358115 76 } // ..switch (cmd)
Wayne Roberts 0:3ccfaf358115 77 }
Wayne Roberts 0:3ccfaf358115 78
Wayne Roberts 0:3ccfaf358115 79 int main()
Wayne Roberts 0:3ccfaf358115 80 {
Wayne Roberts 0:3ccfaf358115 81 int res;
Wayne Roberts 0:3ccfaf358115 82 bool but;
Wayne Roberts 0:3ccfaf358115 83 uint8_t cnt = 0;
Wayne Roberts 0:3ccfaf358115 84
Wayne Roberts 0:3ccfaf358115 85 pc.baud(115200);
Wayne Roberts 0:3ccfaf358115 86 pc.printf("\r\nreset\r\n");
Wayne Roberts 0:3ccfaf358115 87
Wayne Roberts 0:3ccfaf358115 88 res = smbus_init(SLAVE_ADDRESS);
Wayne Roberts 0:3ccfaf358115 89 pc.printf("%d = smbus_init()\r\n", res);
Wayne Roberts 0:3ccfaf358115 90
Wayne Roberts 0:3ccfaf358115 91 but = button.read();
Wayne Roberts 0:3ccfaf358115 92 while (1) {
Wayne Roberts 0:3ccfaf358115 93 service_i2c();
Wayne Roberts 0:3ccfaf358115 94
Wayne Roberts 0:3ccfaf358115 95 if (but != button.read()) {
Wayne Roberts 0:3ccfaf358115 96 irq.fields.cnt = cnt++;
Wayne Roberts 0:3ccfaf358115 97 irq.fields.flags.button = 1;
Wayne Roberts 0:3ccfaf358115 98 irqOutPin = 1;
Wayne Roberts 0:3ccfaf358115 99
Wayne Roberts 0:3ccfaf358115 100 but = button.read();
Wayne Roberts 0:3ccfaf358115 101 }
Wayne Roberts 0:3ccfaf358115 102
Wayne Roberts 0:3ccfaf358115 103 } // ..while (1)
Wayne Roberts 0:3ccfaf358115 104 }
Wayne Roberts 0:3ccfaf358115 105