From 73cd5f1cdf64e36b841e41f9421b8e374d32dae7 Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Mon, 11 Nov 2019 09:35:56 -0700 Subject: [PATCH] Add i2c slave support to arduino firmware --- src/arch/avr/i2c_slave.c | 87 +++++++++++++++++++ src/arch/avr/include/arch/i2c_slave.h | 7 ++ src/board/arduino/mega2560/battery.c | 8 +- .../arduino/mega2560/include/board/i2c.h | 2 + src/board/arduino/mega2560/main.c | 13 +++ 5 files changed, 115 insertions(+), 2 deletions(-) create mode 100644 src/arch/avr/i2c_slave.c create mode 100644 src/arch/avr/include/arch/i2c_slave.h diff --git a/src/arch/avr/i2c_slave.c b/src/arch/avr/i2c_slave.c new file mode 100644 index 0000000..fa94d58 --- /dev/null +++ b/src/arch/avr/i2c_slave.c @@ -0,0 +1,87 @@ +// Based on https://github.com/thegouger/avr-i2c-slave + +#include +#include +#include +#include + +#include +#include + +static void (* volatile i2c_slave_new_cb)() = NULL; +static void (* volatile i2c_slave_recv_cb)(uint8_t) = NULL; +static uint8_t (* volatile i2c_slave_send_cb)() = NULL; + +void i2c_slave_init(uint8_t address, void (*new_cb)(), void (*recv_cb)(uint8_t), uint8_t (*send_cb)()){ + // ensure correct behavior by stopping before changing callbacks or address + i2c_slave_stop(); + + // clear interrupts + cli(); + + // setup callbacks + i2c_slave_new_cb = new_cb; + i2c_slave_recv_cb = recv_cb; + i2c_slave_send_cb = send_cb; + // load address into TWI address register + TWAR = (address << 1); + // set the TWCR to enable address matching and enable TWI, clear TWINT, enable TWI interrupt + TWCR = (1< + void i2c_init(unsigned long baud); #endif // _BOARD_I2C_H diff --git a/src/board/arduino/mega2560/main.c b/src/board/arduino/mega2560/main.c index 2723c03..67bfa78 100644 --- a/src/board/arduino/mega2560/main.c +++ b/src/board/arduino/mega2560/main.c @@ -1,6 +1,7 @@ #include #include +#include #include #include #include @@ -10,6 +11,16 @@ void init(void) { i2c_init(50000); } +static void i2c_slave_new() {} + +static void i2c_slave_recv(uint8_t data) { + printf("%c", data); +} + +static uint8_t i2c_slave_send() { + return 0; +} + struct Gpio LED = GPIO(B, 7); int main(void) { @@ -22,7 +33,9 @@ int main(void) { battery_debug(); for (;;) { + i2c_slave_init(0x76, i2c_slave_new, i2c_slave_recv, i2c_slave_send); int c = getchar(); + i2c_slave_stop(); if (c == '\r') { putchar('\n'); battery_debug();