This is a continuation of several previous threads involving Mega4809 Xplained Pro and TWI/I2C. Some of those threads are:
In the fourth one, Ron Sutherland suggested a review of the Arduino mega4809 TWI module since it was written by Microchip. I did that review and found it bloated, in the usual Arduino style. BUT, it was also relatively easy to modify to use as a library for non-Arduino environments. The code can be found at:
Here is what I did to modify this library:
1. twi.h: Add the following code at the top of the file:
#define TWI_MUX 0 //TWI_MASTER on PA3:PA2 #define F_CPU 10000000UL //my configuration #define F_CPU_CORRECTED F_CPU //for twi.h #define TWISCL (1<<3) //PA3 #define TWISDA (1<<2) //PA2 #define false 0 #define true 1
2. twi.c: comment out #include "Arduino.h"
3. twi.c add #include <avr/interrupt.h>
4. twi.c in "TWI_MasterInit()" add before #ifdef NO_EXTERNAL_I2C_PULLUP
//Configure TWI Master IO //PORTMUX.TWISPIROUTEA default for Master SCL/SDA on PA[3:2] PORTA.DIRSET = TWISCL + TWISDA; //TWI pins as output PORTA.PIN3CTRL = 1<<3; //SCL pullup on for testing PORTA.PIN2CTRL = 1<<3; //SDA pullup on for testing
5. twi.c in "TWI_MasterInit()" remove
#ifdef NO_EXTERNAL_I2C_PULLUP pinMode(PIN_WIRE_SDA, INPUT_PULLUP); pinMode(PIN_WIRE_SCL, INPUT_PULLUP); #endif
Thats all it takes! You DO have to enable interrupts in your code, somewhere before the first use of the read or write functions. You also have to define a write buffer and a read buffer that are passed, by pointer, to the read and write functions.
TWI_MasterRead() and TWI_MasterWrite() are just wrappers that call the "do-everything" TWI_MasterWriteRead(). If you need to do the common sequence of start, write a register address, then read from that register, you need to call TWI_MasterWriteRead() directly or first do a TWI_MasterWrite() with the stop flag false to send the register address, then do a TWI_MasterRead() with the stop flag set to get the data at the register location.
The modified library is attached for your convenience. It should work for ATmega 808/9, ATmega 1608/9, ATmega3208/9 and ATmega4808/9.
I plan, in the near future, to modify the library to remove the need for an interrupt and to clean up some details. But, at least as a master, this code works.