HWA
Bare metal programming with style
|
A few notes about how HWA works internally.
The base source code of HWA is in the hwa/
directory.
Device-related sources are stored in vendor/architecture/
directories (atmel/avr/
, st/stm32/
, espressif/esp8266/
, ...) where are stored classes/
, devices/
, and examples/
directories.
HW_X() _HW_FC | (f,c,) | | | | |-- |== _hw_read(o,r) |-- |== _hw_atomic_read(o,r) |-- |== _hw_write(o,r,v) |-- |== _hw_write_m(o,r,m,v) |-- |== _hwa_write(o,r,v) |-- |== _hwa_write_m(o,r,m,v) |-- |== _hwa_mmask(o,r) |-- |== _hwa_mvalue(o,r) |-- |== _hwa_ovalue(o,r) | |-- _hwa_setup_r(o,r) |-- _hwa_init_r(o,r,v) |-- _hwa_commit_r(o,r) |-- _hwa_nocommit_r(o,r) | |-- _hw(...) |-- _hwa(...) | |-- HW_ID(o) |-- HW_ISR(oo [,reason] [,naked] ... ) |-- HW_VOID_ISR(o [,reason]) | |---------HW_F() | | | |== HW_ADDRESS(oo) | |== HW_BIT(oo) | |== HW_POSITION(oo) |-- |== hw(...) |-- |== hwa(...) _hwa_setup_o(o) _hwa_init_o(o) _hwa_solve_o(o) _hwa_commit_o(o)
HWA uses the following standardized argument names in its macro definitions:
a
: address of the objectbn
: number of bitsbp
: position of least significant bitc
: class of the objectf
: name of the functionh
: "hw" or "hwa" prefixi
: id of the objectn
: name of the object, may be a patho
: name of a single objectr
: name of a registerra
: relative address of the registerrbn
: number of bits of a logical registerrbp
: position of least significant bit of a logical register in the hardware registerrwm
: register writeable bits maskrfm
: register flags maskrx
: definition of a register (expansion)t
: typevbn
: number of bits in the valuevbp
: position of least significant bit in the value Macros | |
#define | _hw_atomic_read(o, r) |
#define | _hw_read(o, r) |
#define | _hw_write(o, r, v) |
#define | _hw_write_m(o, r, ...) |
#define | _hwa_begin_(g, ...) |
#define | _hwa_begin_reset(r, g, ...) |
#define | _hwa_commit_(...) |
#define | _hwa_commit_o(o) _hwa_commit00( o, hw_##o ) |
#define | _hwa_commit_r(o, r) |
#define | _hwa_init_o(o) _hwa_init00( o, hw_##o ) |
#define | _hwa_init_r(o, r, v) |
#define | _hwa_mmask(o, r) |
#define | _hwa_mvalue(o, r) |
#define | _hwa_nocommit_(...) |
#define | _hwa_ovalue(o, r) |
#define | _hwa_setup_o(o) _hwa_setup00( o, hw_##o ) |
#define | _hwa_setup_r(o, r) |
#define | _hwa_solve_o(o) _hwa_solve00( o, hw_##o ) |
#define | _hwa_write(o, r, v) |
#define | _hwa_write_m(o, r, ...) |
#define | hw_configure__ioa , _hw_cfioa |
#define | hwa_writenp__m11 |
Functions | |
HW_INLINE void | _hw_write_r8 (intptr_t ra, uint8_t rwm, uint8_t rfm, uint8_t mask, uint8_t value) |
HW_INLINE void | _hwa_check_optimizations (uint8_t x) |
HW_INLINE void | _hwa_set__r8 (hwa_r8_t *r, uint8_t v) |
HW_INLINE void | _hwa_write_r8 (hwa_r8_t *r, uint8_t rwm, uint8_t rfm, uint8_t msk, uint8_t v) |
#define _hw_atomic_read | ( | o, | |
r | |||
) |
Read one register of an object with interrupts disabled.
#define _hw_read | ( | o, | |
r | |||
) |
Read one register of an object.
#define _hw_write | ( | o, | |
r, | |||
v | |||
) |
Write one register of an object.
#define _hw_write_m | ( | o, | |
r, | |||
... | |||
) |
Write some bits of a hardware register.
#define _hwa_begin_ | ( | g, | |
... | |||
) |
Create a context to memorize what the hwa(...)
instructions do.
Nothing is written into the hardware until hwa(commit)
is called.
#define _hwa_begin_reset | ( | r, | |
g, | |||
... | |||
) |
Create a context to memorize what the hwa(...)
instructions do.
The context is initialized with the values the registers have after a system reset.
Nothing is written into the hardware until hwa(commit)
is called.
#define _hwa_commit_ | ( | ... | ) |
Generate machine code for the configuration stored in the context.
Solve the configuration stored into the HWA context, then do the required hardware register writes.
#define _hwa_mmask | ( | o, | |
r | |||
) |
Get the mmask of the logical register r
of object o
.
The mmask is set each time a write
is performed. It is reset after the value has been committed.
#define _hwa_nocommit_ | ( | ... | ) |
Same as hwa(commit)
but do not write into hardware.
This is used to put the HWA context in a known state before modifying it.
#define _hwa_write | ( | o, | |
r, | |||
v | |||
) |
Write one register of an object.
#define _hwa_write_m | ( | o, | |
r, | |||
... | |||
) |
Record some bits of a hardware register in the HWA context.
#define hw_configure__ioa , _hw_cfioa |
#define hwa_writenp__m11 |
Write n bits at position p of a hardware register.
HW_INLINE void _hw_write_r8 | ( | intptr_t | ra, |
uint8_t | rwm, | ||
uint8_t | rfm, | ||
uint8_t | mask, | ||
uint8_t | value | ||
) |
Write one 8-bit hardware register.
Write value
through mask
bits of the hardware register at address ra
. Trying to write 1
s into non-writeable bits triggers an error.
ra | address of register. |
rwm | writeable bits mask of the register. |
rfm | flag bits mask of the register. |
mask | mask of bits concerned. |
value | value to write. |
HW_INLINE void _hwa_write_r8 | ( | hwa_r8_t * | r, |
uint8_t | rwm, | ||
uint8_t | rfm, | ||
uint8_t | msk, | ||
uint8_t | v | ||
) |
Write into one 8-bit context register.
Write value v
into msk
bits of the context register pointed by r
. Trying to write 1
s into non-writeable bits triggers an error.
The mask of modified values mmask
is set according to msk
even if the value is not modified. _hwa_commit__r8()
will check if the register has effectively been modified.
r | register pointer. |
rwm | writeable bits mask of the register. |
rfm | flag bits mask of the register. |
msk | mask of bits concerned. |
v | value to write. |