Skip to content
Maslov Nikita edited this page Feb 22, 2014 · 1 revision

Cerebellum library can be divided in abstraction layers.

1. MCU peripherals layer

Files: <lib/cerebellum/gpio.h>

At this layer, Cerebellum library implements some useful macroses (really it is not functions, because some operations like GPIO writing and reading are very fast as hard operations, but become ve-e-ery slow if you do it in a wrong very abstract way; see Arduino).

Cerebellum GPIO abstraction is designed as very fast (all macroses expand into native static instructions and run the fastest way; sorry, debuggers) and simple, but implements all options of hardware.

First, there are special macroses: (basic example from the AVR)

GPIO_INIT_OUT(GPxy)
GPIO_INIT_IN(GPxy)
GPIO_INIT_IN_PU(GPxy)

GPIO_READ(GPxy)

GPIO_WRITE_HIGH(GPxy)
GPIO_WRITE_LOW(GPxy)

Each macros take only 1 argument - a special definitions GPxy, where x - letter of port, and y - number of pin (looks like native pin enumeration, isn't it?). In fact, these definitions have not one type as in C, it expands into list of required names and values. For AVR, to control the pin fully, you need PORTx, DDRx, PINx and bit index y. So, the GPxy definition expands this way:

#define GPA0 PORTA, DDRA, PINA, 0

In GPIO_() macros, this definition expands, and GPIO__RAW() macros is called. This trick allows you not to type all these names, but write one word and it will be replaced automatically by prerpocessor.

#define GPIO_WRITE_HIGH(gpio) GPIO_WRITE_HIGH_RAW(gpio)
->
#define GPIO_WRITE_HIGH_RAW(port, ddr, pin, n) (port |= (1<<pin))

/* example */
GPIO_WRITE_HIGH(GPA0) -> GPIO_WRITE_HIGH_RAW(PORTA, DDRA, PINA, 0) ->
-> (PORTA |= (1<<0)) -> asm ("sbi PORTA, 0")

As you see, it looks pretty and work fast. The problem is that you can't store GPxy value in the MCU memory without some tricks, and it can't be used with debugger.

Clone this wiki locally