STM32 HAL Peripherals
The concrete STM32 HAL drivers that implement the core peripheral interfaces of kbox-stack — the driver catalog, transceivers, construction order, and interrupt callbacks.
Each hardware concern in kbox-stack is an I<X> interface defined in the
portable core; see Peripheral Interfaces.
This page lists the concrete STM32 (HAL) drivers that implement them and how
you construct and feed them.
Driver catalog
| Core interface | STM32 (HAL) driver | Constructor arguments |
|---|---|---|
IBusDriver | HalKnxBusDriver | (UART_HandleTypeDef& uart, DMA_HandleTypeDef& hdmaRx, DMA_HandleTypeDef& hdmaTx, void (*uartInitFunc)(void), IClock&, IWatchDog&) |
IFlash | HalFlash | (uint16_t flashBaseAddress, uint16_t flashTailAddress) |
ILed | HalLed | (GPIO_TypeDef* gpioPort, uint16_t gpioPin, IClock&) |
IButton | BaseButton | () (portable; no HAL handles) |
IClock | BaseClock | () (portable; driven by a 1 ms timer tick) |
IWatchDog | HalIWDGWatchDog | (IWDG_HandleTypeDef& watchDog) |
ITransmitter | Ncn5130 / ElmosE98123 | see below |
BaseClock and BaseButton carry no STM32 handles — they are portable helpers.
BaseClock counts milliseconds/seconds from an external Tick() (the example
calls it from the 1 ms TIM2 interrupt); BaseButton just forwards an interrupt
to a registered callback. Everything else is a true HAL driver holding ST HAL
handles.
Transmitters
The transmitter (an ITransmitter) drives the analog KNX front-end that couples
the MCU UART to the TP1 bus. It sits on top of the bus driver.
#include <Stack/Peripheral/Transmitter/Ncn5130.h>
Ncn5130 transmitter(busDriver, clock, watchDog);Ncn5130(IBusDriver& busDriver, IClock& clock, IWatchDog& watchDog) — it needs
the clock and watchdog because bringing up the transceiver involves timed delays.
It exposes Init() and SetIndividualAddress(KnxAddress&).
#include <Stack/Peripheral/Transmitter/ElmosE98123.h>
ElmosE98123 transmitter(busDriver);ElmosE98123(IBusDriver& busDriver) — the Elmos front-end takes only the bus
driver. Swap this in place of Ncn5130 if your board uses an Elmos transceiver;
the rest of the construction is unchanged.
Constructing the peripherals
Build the peripherals at file scope in dependency order — a later object references earlier ones. This is the exact order from the example:
HalIWDGWatchDog watchDog(hiwdg);
BaseClock clock;
// Bus driver first: it owns the UART + DMA and needs clock + watchdog.
HalKnxBusDriver busDriver(huart2, hdma_usart2_rx, hdma_usart2_tx,
MX_USART2_UART_Init, clock, watchDog);
// Transmitter sits on the bus driver.
Ncn5130 transmitter(busDriver, clock, watchDog);
// Persistent flash, LEDs, button.
HalFlash baseFlash(0x0801u, 0xF400u);
HalLed indicatorLed(GPIOB, YELLOW_LED_Pin, clock);
HalLed knxLed(GPIOB, RED_LED_Pin, clock);
BaseButton button;These are then passed into MakeStack(...) — see
Your First Application for
the full stack assembly.
Interrupt callbacks
The Hal* drivers are event-driven: ST HAL interrupt callbacks must be routed
to them. Wire these three (from the example's main.cpp):
// Data arrived on the KNX UART (USART2, DMA RX): feed the bus driver.
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef* huart, uint16_t Size) {
if (huart->Instance == USART2) {
busDriver.OnInterupt(Size);
}
}
// USART error: let the bus driver recover.
void HAL_UART_ErrorCallback(UART_HandleTypeDef* huart) {
if (huart->Instance == USART2) {
busDriver.OnError();
}
}
// GPIO (button) interrupt: the KNX programming button toggles address mode.
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {
if (GPIO_Pin == KNX_BUTTON_Pin) {
stack.OnButtonPress();
}
}Route the button through stack.OnButtonPress() (not directly to the
BaseButton). The stack owns programming-mode entry/exit; the button object is
what the stack registers its own handler on.