Software
Atmel Software
Atmel has a large set of useful software for the ATM91SAM and other processors. Go to the Atmel AT91SAM software tools web site and downlaod version 1.3 of their AT91SAM7X-EK Software Package. It's available at http://www.atmel.com/dyn/resources/prod_documents/softpack-1.3-at91sam7se-ek-web.zipUnzip the file to a local directory, then open up the file "index.html" in your browser, which will display a web page with links to various software packages. Under the Software Resources header, click on "examples". Next click on the CD icon for the GNU version of the "Basic Twi EEPROM Project". Files of interest are under the at91lib\utility, at91lib\drivers, and at91lib\peripherals subdirectories. The files to use are: async.c, async.h, math.c, math.h, trace.h, twi.c, twi.h, twid.c, twid.h.
Putting the Atmel Software Into the Make Environment
I copied each of the above files into my "heavy" directory and added the "c" files to my Makefile. It would have been nicer to put them in a subdirectory.
Atmel has a nice tracing facility built into their software which is comparable to the nice Debug OSC facility in the Make software. I modified Atmel's "trace.h" function so the trace statements in Atmels code are automagically converted to their corresponding OSC Debug statements. Their trace log levels go from 0-4, whereas Debug uses 3-0. The Atmel code has a unique trace_LEVEL defined at compile time for each file with tracing. In "trace.h", define trace_LOG as follows:
#define trace_LOG(level, ...) { \
if ((level)>=trace_LEVEL) { \
Debug((3-((level)*3/4)), __VA_ARGS__); \
} \
}
I wrote a new ASSERT macro that doesn't waste as much code space. It is in assert.h and assert.c in the attached zip file.
When working on something like this, its hard to remember everything that needed to be changed. Please comment if I've missed anything!
Simple I2C API Functions
The TWI driver API functions of the Atmel code are flexible, but cause excessive driver-specific clutter to appear in application code. I wrote a few functions to simplify things, and placed them in twiapi.c and twiapi.h. They are bundled in the attached zip file. The functions are:
// Two Wire Interface Initialization
void twiInit(void);
// Two Wire Interface Write
// Parameters:
// buf - Pointer to data to send
// length - Number of bytes to send
// addr - 7-bit I2C address of target device.
// LSB is part of the addr (not r/w bit!)
// delayTilNext - Maximum time this operation will take to
// complete. Used to pause the next
// future operation so the device is ready.
void twiWrite(char * buf, int length, int addr, int delayTilNext);
// Two Wire Interface Read
// Parameters:
// buf - Pointer to caller-supplied data buffer
// num - Number of bytes to read
// addr - 7-bit I2C address of target device.
int twiRead(char * buf, int num, int addr);
The twiWrite function has a parameter "delayTilNext" which can be used to enforce a delay after operations that take a long time to complete. When a write is done, the delayTilNext is added to the current time to calculate the time the next operation may begin. Later when the next read or write is done, the current time is compared with the timeForNextOperation and a Sleep is done if sufficient time has not already elapsed.
Note: I've not tested multi-byte reads nor I2C device internal addressing, as my LCD display does not have these features.
Future Enhancements
Right now, this TWI software works just fine when it is used from within one task. However, you'll run into trouble if you attempt to use it from multiple tasks. In the future, I'd like to add semaphore protection of key resources so it can be used by multiple tasks concurrently.
Busy waits. This code has them. I hate them. I'd like to enhance this software to use Atmel's asynchronous mode of operation, which uses interrupts to indicate when operations are completed instead of spin loops waiting on a completion bit to be set in a register. In the meantime, run your I2C code at a lower priority, and add some taskYIELDs or Sleeps to let other tasks run when needed.
Software file changes
In lib_AT91SAM7X256.h, I changed the void parameter on some function prototypes. I don't believe this change was required; I was probably experimenting with compiler warnings. Here is the diff output. Hopefully this will work for you, as I will not be able to check the forum for a few days.
Regards,
Bob
[bobf@www ARM7_AT91SAM7S]$ diff lib_AT91SAM7X256.h ~/fw131/heavy/controller/freertos/portable/GCC/ARM7_AT91SAM7S/lib_AT91SAM7X256.h
60c60
< void (*newHandler)() ) // \arg address of the interrupt handler
---
> void (*newHandler) (void) ) // \arg address of the interrupt handler
135c135
< void (*Handler) (void) ) // \arg Interrupt Handler
---
> void (*Handler) () ) // \arg Interrupt Handler
[bobf@www ARM7_AT91SAM7S]$ diff ioat91sam7x256.h ~/fw131/heavy/controller/freertos/portable/GCC/ARM7_AT91SAM7S/ioat91sam7x256.h
2744c2744
<
---
> #endif
4697c4697
< #endif
---
>
Software file changes
I'm trying this right now, and so far have found:
you need to remember to edit the files from Atmel and
remove the paths to the include files.
I can't get twiapi.c to compile, it keeps barfing when trying
to include the
#include "ioat91sam7x256.h"
#include "lib_AT91SAM7X256.h"
files. Did you make any changes to these files in your
build? I'm getting hundreds of compile errors from these files, mainly what looks like double definitions and assembly errors.
I'm using the latest Yagarto toolset:
yagarto-bu-2.18)gcc-4.2.2-c-c++_nl-1.16.0_gi-6.8.59_20080408. Maybe thats the issue?