Download: AtmelPDFToCHeaders.zip v1.10
This Ruby script converts an AVR register definition table copied from the "Register Summary" section of an Atmel datasheet PDF into a C header file. It is intended for use with avr-gcc.
NOTE that the resultant code can not be mixed with the avr-libc headers! These headers are great on their own, though. More work would need to be done to avr-libc to make it compatible with these headers, since the registers are defined all over the place in the avr-libc headers.
It generates union and bitfield declarations, as well as generating #defines for their usage.
Usage: ruby convertHeaders.rb [-help] [-name chipName] file [...] > myHeader.h -name sets the guard #define in the header (should be unique) -help prints this help
You can use Acrobat Reader to get the tables. If there is more than one register per table row, you will have to hand-edit the text file. Just make sure that you don't modify anything other than that row. Particularly, don't touch the extra spaces!
If there is not more than one register per table row, you can just paste the entire table contents in as copied from Acrobat Reader (on my Linux box, that results in one very long line).
You can get Ruby from http://ruby-lang.org
Here is an excerpt from a generated header file:
/* ADCSRA ($26) (page 217) */
typedef union ADCSRA_t {
uint8_t asByte;
struct {
uint8_t bADPS0 :1;
uint8_t bADPS1 :1;
uint8_t bADPS2 :1;
uint8_t bADIE :1;
uint8_t bADIF :1;
uint8_t bADATE :1;
uint8_t bADSC :1;
uint8_t bADEN :1;
};
struct {
uint8_t fADPS :3;
uint8_t :1; /* ADIE */
uint8_t :1; /* ADIF */
uint8_t :1; /* ADATE */
uint8_t :1; /* ADSC */
uint8_t :1; /* ADEN */
};
} ADCSRA_t;
#define ADCSRA_sfr (*(volatile ADCSRA_t *) (0x26))
#define ADCSRA ADCSRA_sfr.asByte /* entire register */
#define ADPS0 ADCSRA_sfr.bADPS0
#define ADPS1 ADCSRA_sfr.bADPS1
#define ADPS2 ADCSRA_sfr.bADPS2
#define ADIE ADCSRA_sfr.bADIE
#define ADIF ADCSRA_sfr.bADIF
#define ADATE ADCSRA_sfr.bADATE
#define ADSC ADCSRA_sfr.bADSC
#define ADEN ADCSRA_sfr.bADEN
#define ADPS ADCSRA_sfr.fADPS
Note that there are three ways of getting to these bits:
Each named 8-bit register is defined so that you can read and write it directly.
You can set the ADIF flag like this: ADCSRA |= 0x10;
Or you could initialize ADCSRA like this: ADCSRA = 0x1F;
Each named bit from the table is defined so that you can read and write it as if it were a 1-bit wide variable.
An easier way to set ADIF is just like this: ADIF = 1;
Some registers have contiguous multiple-bit ranges. In these cases, convertHeaders will generate the corresponding wider bitfields. So you could set ADPS0,ADPS1, and ADPS2 all at once by going: ADPS = 7;
In addition, each register pair (pairs of 8-bit registers used as a 16-bit register sometimes) is defined as both 8-bit registers and a 16-bit register. Bitfields and individual bits are defined for the 16-bit registers as well, if they're different from the 8-bit versions.
For instance, the ADC register in parts with a 10-bit wide ADC is actually a 16-bit register. It can be referred to as ADC, and the individual halves can be referred to as ADCL and ADCH. Additionally, the individual bits in ADCH may be referred to as either ADCH0..ADCH7 or as ADC8..ADC15.