Commit a722838a191f6003f7d040cac0da628c17727056 v1.0a8
authorMichel Pollet <buserror@gmail.com>
Sun, 27 Mar 2011 10:44:22 +0000 (11:44 +0100)
committerMichel Pollet <buserror@gmail.com>
Sun, 27 Mar 2011 10:44:22 +0000 (11:44 +0100)
Write a few bytes to an i2c eeprom, read them back...

Signed-off-by: Michel Pollet <buserror@gmail.com>
5 files changed:
examples/board_i2ctest/Makefile
examples/board_i2ctest/README [new file with mode: 0644]
examples/board_i2ctest/atmega48_i2ctest.c
examples/board_i2ctest/avr_twi_master.c
examples/board_i2ctest/i2ctest.c

index ed686fe052a107ede30fe357ccbb3b6c80cc5b3f..01743700521b12e9e1d09393624e14ef48ac7624 100644 (file)
@@ -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 (file)
index 0000000..f65bc4e
--- /dev/null
@@ -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
index 938eaa1eee61e6c54c9b28c0f1331997ae0523a1..5a91326e2a39973c40f3754b2f4adba3acd982ce 100644 (file)
@@ -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 <stdio.h>
 
index 317e27b7dd51dad37ace06cb8d8e1a6a0ae80b7d..1a8a4e37cdc036da5ac45748d9d9b01144f9bffd 100644 (file)
@@ -23,6 +23,8 @@
 *\r
 ****************************************************************************/\r
 \r
+#include <avr/io.h>\r
+#include <avr/interrupt.h>\r
 #include "avr_twi_master.h"\r
 \r
 //static unsigned char TWI_buf[ TWI_BUFFER_SIZE ];    // Transceiver buffer\r
@@ -162,7 +164,12 @@ ISR( TWI_vect )
         if (TWI_sendStop)\r
                TWCR = (1<<TWEN)|                                 // TWI Interface enabled\r
                (0<<TWIE)|(1<<TWINT)|                      // Disable TWI Interrupt and clear the flag\r
-               (0<<TWEA)|(0<<TWSTA)|(1<<TWSTO)|           // Initiate a STOP condition?\r
+               (0<<TWEA)|(0<<TWSTA)|(1<<TWSTO)|           // Initiate a STOP condition\r
+               (0<<TWWC);                                 //\r
+        else\r
+               TWCR = (1<<TWEN)|                                 // TWI Interface enabled\r
+               (0<<TWIE)|(1<<TWINT)|                      // Disable TWI Interrupt and clear the flag\r
+               (0<<TWEA)|(0<<TWSTA)|(0<<TWSTO)|           // DO NOT Initiate a STOP condition\r
                (0<<TWWC);                                 //\r
       }\r
       break;\r
index 9962c91f999ba70cb2f46e04a31379f5529123f0..9d439324841ab3f34439fa9b3b96eb48d1f0a674 100644 (file)
@@ -19,8 +19,6 @@
        along with simavr.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-
-
 #include <stdlib.h>
 #include <stdio.h>
 #include <libgen.h>
 #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 <string.h>
-
-/*
- * 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] = "32<eeprom.in",
-};
-
-void
-i2c_eeprom_init(
-               struct avr_t * avr,
-               i2c_eeprom_t * p,
-               uint8_t addr,
-               uint8_t mask,
-               uint8_t * data,
-               size_t size)
-{
-       memset(p, 0, sizeof(p));
-       memset(p->ee, 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);