Configuration & register maps

config.ik holds the few build-time constants the kernel depends on. Most are pre-computed numbers (clock speed, the UART divisor); this page is the lookup table for choosing them, plus the hardware register addresses you reference from the shell with peek / poke / sbi / cbi.

config.ik

@cpu_mhz() -> u16 { return 8 }        # CPU clock in MHz
const NPROC: u8     = 3               # process slots: shell + 2
const UART_UBRR: u16 = 51             # 8 MHz, 9600 baud  (see table below)
@cpu_mhz()

The CPU clock, in MHz. Drivers that need real time (delays, the UART divisor, timer period) read it. It must match the actual clock selected by the fuses (external crystal or internal RC). A mismatch garbles the UART and skews every delay.

NPROC

Number of process slots: the shell (pid 0) plus NPROC - 1 background jobs. Each slot costs a fixed stack (see Memory maps).

UART_UBRR

The USART baud divisor, UBRR. It is pre-computed because the AVR has no floating point at boot; pick it from the table for your clock and baud.

UART_UBRR table

Normal mode (U2X = 0). The formula is:

UBRR = round( F_CPU / (16 * baud) ) - 1

Baud

1 MHz

8 MHz

16 MHz

2400

25

207

416

4800

12

103

207

9600

6 (err)

51

103

14400

3 (err)

34

68

19200

2 (err)

25

51

38400

12

25

57600

8

16

115200

3

8

(err) marks combinations whose rounding error is large enough to be unreliable — prefer a clock that divides the baud cleanly. The kernel default (51) is 9600 baud at 8 MHz, which is exact.

GPIO port registers (ATmega32)

Each port has three registers, addressed in the data space (what peek / poke / sbi / cbi take):

  • DDRx — direction: bit = 1 makes the pin an output, 0 an input.

  • PORTx — output value when an output; the pull-up when an input.

  • PINx — reads the pin’s input level.

Port

PINx

DDRx

PORTx

A

0x39

0x3A

0x3B

B

0x36

0x37

0x38

C

0x33

0x34

0x35

D

0x30

0x31

0x32

So 0x38 is PORTB and 0x37 is DDRB. To drive PB0 high:

sbi 0x37 0      # DDRB bit 0 = output
sbi 0x38 0      # PORTB bit 0 = 1  (PB0 high)
cbi 0x38 0      # PORTB bit 0 = 0  (PB0 low)

To read an input pin, configure it (cbi its DDRx bit, optionally sbi its PORTx bit for the pull-up) and peek the PINx register.

Other useful registers (ATmega32)

Register

Address

Notes

ADCL

0x24

ADC result low byte (read low byte first)

ADCH

0x25

ADC result high byte

SREG

0x5F

status register (bit 7 = global interrupt enable)

TCNT0

0x52

Timer0 counter

UDR

0x2C

USART data register

The Examples page shows these registers used from the shell.