Background
Iāve written dozens of programs using the Arduino IDE and using other tools like the ARM mBed toolchain. My priority for this week was to familiarize myself with avr-gcc and the Atmel libraries.
Week 4 Board Programming
I had already programmed my Week 4 board with the provided serial echoing program so I was pretty comfortable with the flashing workflow. I wrote a very simple AVR GCC program to get the board to blink its LED. This was a good hello world for the libraries and IO structure that the Arduino Bootloader abstracts away (specifically all the registers).
I2c Fun?
Arduino Unos
My final project is relying heavily on using busses like I2c to communicate between microcontrollers. Iāve written several I2c programs using the Arduino toolchain and Wire.h so moving to avr-gcc seemed like the logical next step. I decided to spend the majority of the week getting I2c working between two boards. Iāve already started working on the controller board for the final project, but it wasnāt done and I didnāt have time to mill and stuff a new board.
Luckily, I had a couple Arduino Unos lying around. While complete overkill, they break out the IO nicely and one of them was even attached to a breadboard. I decided to use them for figuring out I2c with avr-gcc since they can be used as a generic ATMega 328P target. Example flashing code for Uno target:
$ avr-gcc -mmcu=atmega328p main.o TWI_Master.o -o main
$ avr-objcopy -O ihex -R .eeprom main main.hex
$ avrdude -F -V -c arduino -p ATMEGA328P -P /dev/ttyACM0 -b 115200 -U flash:w:main.hexavrdude: AVR device initialized and ready to accept instructionsReading | ################################################## | 100% 0.00savrdude: Device signature = 0x1e950f (probably m328p)
avrdude: NOTE: āflashā memory has been specified, an erase cycle will be performed
To disable this feature, specify the -D option.
avrdude: erasing chip
avrdude: reading input file āmain.hexā
avrdude: input file main.hex auto detected as Intel Hex
avrdude: writing flash (774 bytes):Writing | ################################################## | 100% 0.14savrdude: 774 bytes of flash writtenavrdude: safemode: Fuses OK (E:00, H:00, L:00)
avrdude done. Thank you.
Atmelās Libraries
One of the goals was to get used to the new workflow that comes with using the avr-gcc toolchain. While I could have modified an Arduino library or downloaded a drop in āArduino-likeā library, I wanted to use the Atmel application note library (Master,Ā Slave).
However, this caused several immediate problems. These libraries were designed for Atmel Studio which meant several libraries had to be exchanged (ioavr.h ā> avr/io.h, inavr.h ā> avr/interrupt.h). These avr-libc libraries are not drop-in replacements so I had to rewrite the interrupt service routine (ISR) function declarations and switch out various low-level function (sei () enables interrupts, _NOP() is the no operation instruction, _delay (unit ms) needs to be imported).
After this has been completed, the modified example code compiled. It sent a byte over I2c to the specified slave address, the slave then added one to the data byte, and then asked for the data back from the slave. My modifications mostly served to test the different addresses and learn about Atmelās library (e.g. turning the LED on for a success).
Debugging
For better or worse, the week was mostly spent debugging the I2c code. After getting the code programmed and hooked up in the identical fashion to my Arduino IDE I2c demo, I wasnāt getting any obvious communication between the two (none of the LEDs lit). I pulled out my Saleae logic analyzer and sure enough there was no signalā¦
Source: AVR-GCC