A collection of firmware libraries I've created for AVRs.
I enjoy programming for AVRs because it's low level, and simple. The AVRs I write firmware for are all 8 bit micro-controllers. They have a simple architecture, and there is no OS. When you power the AVR it generally has a bootloader which jumps straight into your program. Firmware is also fun to write because they are well defined, small modules.
Controlling physical things is also relatively simple. AVRs have a number
of buses, each controlling some pins on the physical chip. For example
PORTB on the Atmega168 controls pins 14, 15, 16, 17, 18, and 19. This
means that (ignoring configurations) to pull pin 16 high we simple need to
set the third bit of
PORTB to a one,
PORTB |= 1 < 2.
All parts come with a datasheet, describing the capabilities of the part. This is what you base the software on, or more specifically this is what I use to define the header file. This step is generally very easy, just make a C function for every piece of functionality of the part. Next the datasheet generally gives you enough information to write the implementation of every function, by telling you what each registers do, and what the expected values are. Additionally it will tell you the specifications of the communication method. For example, a part may be able to communicate over SPI. Some parts also have pins which operate outside a standard bus protocol, and the datasheet will tell you how these pins work as well. The last big thing to look for in a datasheet is the expected timings of operations. Sometimes this will effect how you write the implementations, by requiring a delay, or forcing faster code.
An minimal library for use with AVRs, code at nixpulvis/avrm.
Maxim Integrated DS1307 Real Time Clock, code at nixpulvis/ds1307.
MAX7221 LED driver, code at nixpulvis/max7221.
InvenSense MPU 9150 9 DOF IMU, code at nixpulvis/mpu9150.
Nordic nRF24L01 wireless transceiver, code at nixpulvis/nrf24l01.