Thursday, September 25, 2008

SPI success!

I've had no luck getting the atmega168 to talk to a DS1307 RTC chip over i2c. My colleague Greg suggested using an RTC which uses SPI. After getting my hands on a couple DS1305s, I wired it up, and wrote some code to bit-bang SPI using several pins on port C. (I didn't use the hardware SPI support because those pins are used for in-system programming.) I tried it out, and---nothing. Every register read would return 0, which seemed a bit odd.

Eventually, I replaced the DS1305 with some LEDs, and wired the atmega168 pin I was using for input from the DS1305 to +5V, and noticed that even though the LEDs were blinking correctly (I slowed the SPI protocol way down), I was still getting 0 when I did the read.

Long story short, AVRs have different registers for reading and writing ports. For example, PORTC means "write to port C", while PINC means "read from port C". I, of course, was trying to read from the output register. Fixed the code, and presto, my test program worked. All it does is repeatedly writes an incrementing counter to one of the DS1305 RAM addresses, and reads it back.

The obligatory picture:

The DS1305 is the chip just to the right of the atmega168.

Next step: use a MAX7219 to drive the 7-segment displays.

No comments: