From a722838a191f6003f7d040cac0da628c17727056 Mon Sep 17 00:00:00 2001 From: Michel Pollet Date: Sun, 27 Mar 2011 11:44:22 +0100 Subject: [PATCH] examples: Working i2c master test board Write a few bytes to an i2c eeprom, read them back... Signed-off-by: Michel Pollet --- examples/board_i2ctest/Makefile | 2 + examples/board_i2ctest/README | 15 +++ examples/board_i2ctest/atmega48_i2ctest.c | 2 +- examples/board_i2ctest/avr_twi_master.c | 9 +- examples/board_i2ctest/i2ctest.c | 117 +--------------------- 5 files changed, 30 insertions(+), 115 deletions(-) create mode 100644 examples/board_i2ctest/README diff --git a/examples/board_i2ctest/Makefile b/examples/board_i2ctest/Makefile index ed686fe..0174370 100644 --- a/examples/board_i2ctest/Makefile +++ b/examples/board_i2ctest/Makefile @@ -37,10 +37,12 @@ all: obj atmega48_${target}.axf ${target} include ${simavr}/Makefile.common atmega48_${target}.axf: atmega48_${target}.c +atmega48_${target}.axf: avr_twi_master.c avr_twi_master.h board = ${OBJ}/${target}.elf ${board} : ${OBJ}/${target}.o +${board} : ${OBJ}/i2c_eeprom.o ${board} : ${simavr}/simavr/${OBJ}/libsimavr.a ${target}: ${board} diff --git a/examples/board_i2ctest/README b/examples/board_i2ctest/README new file mode 100644 index 0000000..f65bc4e --- /dev/null +++ b/examples/board_i2ctest/README @@ -0,0 +1,15 @@ + +This contains a sample program to demonstrate the use of simavr +using 'custom' code, and own "peripherals". It shows how it is +possible to "hook" code to the AVR pins, and also how to make +"peripherals" and also hook them up to AVR pins. + +This demo demonstrate how to write a i2c/twi "peripheral" and hook it to +an AVR, and then run a firmware that behaves as a TWI "master" to talk to it. + +The code uses a generic i2c "eeprom" were the AVR writes some bytes, +then read them again. The AVR code is based on the Atmel reference +implementation, with quite a few changes to make it more functional. + +Thid "board" doesn't use opengl, the eeprom will display what the +transactions are. \ No newline at end of file diff --git a/examples/board_i2ctest/atmega48_i2ctest.c b/examples/board_i2ctest/atmega48_i2ctest.c index 938eaa1..5a91326 100644 --- a/examples/board_i2ctest/atmega48_i2ctest.c +++ b/examples/board_i2ctest/atmega48_i2ctest.c @@ -27,7 +27,7 @@ #include "avr_mcu_section.h" AVR_MCU(F_CPU, "atmega48"); -#include "avr_twi_master.c" +#include "avr_twi_master.h" #include diff --git a/examples/board_i2ctest/avr_twi_master.c b/examples/board_i2ctest/avr_twi_master.c index 317e27b..1a8a4e3 100644 --- a/examples/board_i2ctest/avr_twi_master.c +++ b/examples/board_i2ctest/avr_twi_master.c @@ -23,6 +23,8 @@ * ****************************************************************************/ +#include +#include #include "avr_twi_master.h" //static unsigned char TWI_buf[ TWI_BUFFER_SIZE ]; // Transceiver buffer @@ -162,7 +164,12 @@ ISR( TWI_vect ) if (TWI_sendStop) TWCR = (1<. */ - - #include #include #include @@ -31,106 +29,7 @@ #include "sim_elf.h" #include "sim_gdb.h" #include "sim_vcd_file.h" - - -typedef struct i2c_eeprom_t { - avr_irq_t * irq; // irq list - uint8_t addr_base; - uint8_t addr_mask; - - uint8_t selected; // selected address - int index; // byte index - - uint16_t reg_addr; // read/write address register - int size; // also implies the address size, one or two byte - uint8_t ee[4096]; -} i2c_eeprom_t; - -#include - -/* - * called when a RESET signal is sent - */ -static void -i2c_eeprom_in_hook( - struct avr_irq_t * irq, - uint32_t value, - void * param) -{ - i2c_eeprom_t * p = (i2c_eeprom_t*)param; - avr_twi_msg_irq_t v; - v.u.v = value; - - if (v.u.twi.msg & TWI_COND_STOP) { - if (p->selected) { - // it was us ! - printf("eeprom received stop\n"); - } - p->selected = 0; - p->index = 0; - p->reg_addr = 0; - } - if (v.u.twi.msg & TWI_COND_START) { - p->selected = 0; - p->index = 0; - if ((p->addr_base & p->addr_mask) == (v.u.twi.addr & p->addr_mask)) { - // it's us ! - p->selected = v.u.twi.addr; - avr_raise_irq(p->irq + TWI_IRQ_MISO, - avr_twi_irq_msg(TWI_COND_ACK, p->selected, 1)); - } - } - if (p->selected) { - if (v.u.twi.msg & TWI_COND_WRITE) { - printf("eeprom write %02x\n", v.u.twi.data); - // address size is how many bytes we use for address register - avr_raise_irq(p->irq + TWI_IRQ_MISO, - avr_twi_irq_msg(TWI_COND_ACK, p->selected, 1)); - int addr_size = p->size > 256 ? 2 : 1; - if (p->index < addr_size) { - p->reg_addr |= (v.u.twi.data << (p->index * 8)); - printf("eeprom set address to %04x\n", p->reg_addr); - } else { - printf("eeprom WRITE data %04x: %02x\n", p->reg_addr, v.u.twi.data); - p->ee[p->reg_addr++] = v.u.twi.data; - } - p->reg_addr &= (p->size -1); - p->index++; - } - if (v.u.twi.msg & TWI_COND_READ) { - printf("eeprom READ data %04x: %02x\n", p->reg_addr, p->ee[p->reg_addr]); - uint8_t data = p->ee[p->reg_addr++]; - avr_raise_irq(p->irq + TWI_IRQ_MISO, - avr_twi_irq_msg(TWI_COND_READ, p->selected, data)); - p->reg_addr &= (p->size -1); - p->index++; - } - } -} - -static const char * _ee_irq_names[2] = { - [TWI_IRQ_MISO] = "8>eeprom.out", - [TWI_IRQ_MOSI] = "32ee, 0xff, sizeof(p->ee)); - p->irq = avr_alloc_irq(&avr->irq_pool, 0, 2, _ee_irq_names); - avr_irq_register_notify(p->irq + TWI_IRQ_MOSI, i2c_eeprom_in_hook, p); - - p->size = size > sizeof(p->ee) ? sizeof(p->ee) : size; - if (data) - memcpy(p->ee, data, p->size); -} +#include "i2c_eeprom.h" avr_t * avr = NULL; avr_vcd_t vcd_file; @@ -141,9 +40,7 @@ int main(int argc, char *argv[]) { elf_firmware_t f; const char * fname = "atmega48_i2ctest.axf"; - char path[256]; - sprintf(path, "%s/%s", dirname(argv[0]), fname); printf("Firmware pathname is %s\n", fname); elf_read_firmware(fname, &f); @@ -160,13 +57,8 @@ int main(int argc, char *argv[]) // initialize our 'peripheral' i2c_eeprom_init(avr, &ee, 0xa0, 0xfe, NULL, 1024); - // "connect" the IRQs of the button to the port pin of the AVR - avr_connect_irq( - ee.irq + TWI_IRQ_MISO, - avr_io_getirq(avr, AVR_IOCTL_TWI_GETIRQ(0), TWI_IRQ_MISO)); - avr_connect_irq( - avr_io_getirq(avr, AVR_IOCTL_TWI_GETIRQ(0), TWI_IRQ_MOSI), - ee.irq + TWI_IRQ_MOSI ); + i2c_eeprom_attach(avr, &ee, AVR_IOCTL_TWI_GETIRQ(0)); + ee.verbose = 1; // even if not setup at startup, activate gdb if crashing avr->gdb_port = 1234; @@ -187,8 +79,7 @@ int main(int argc, char *argv[]) avr_io_getirq(avr, AVR_IOCTL_TWI_GETIRQ(0), TWI_IRQ_STATUS), 8 /* bits */ , "TWSR" ); - printf( "Demo launching:\n" - ); + printf( "Demo launching:\n"); while (1) avr_run(avr); -- 2.39.5