DALI Low Level Driver - Mainprogramm   


 

Beispiel 

Erläuterung 

Die Funktion dalill_inithardware() enthält alles was zum Initialisieren der Zielhardware notwendig ist. Eventuell muss hier auf automatisch generierten Code zurückgegriffen werden. 

Hier werden die PCIOs und der Timer initialisiert. Der Timer wird hier noch nicht gestartet! 

In der Funktion werden auch die beiden Interrupt Routinen des Low Level Treibers mit auf die entsprechenden Vektoren gelegt. 

Das sind im Fall des LLT die beiden Funktionen dalill_interruptExt für den Dali-Read-Pin und dalill_timerinterrupt2 für den Timer. Beide Funktionen benötigen einen Parameter vom Typ dalill_bus_t*. Dieser ist wie schon beschrieben, für den künftigen Multibusbestrieb vorgesehen. 

#include "dali_ll_hal.h" 
#include "dali_ll.h" 
#include "dali.h" 
dalill_bus_t* pDalill_bus_0; 
void DALI_ThreadFunc(void *argument) // oder main() 

// do hardware initialization 
dalill_initHardware(); 
// init dalistack 
// init dali_ll 
pDalill_bus_0 = dalill_createBusLine(&dalill_getBusState, 

&dalill_setBusStateHigh, 
&dalill_setBusStateLow); 

// init dalilib (API) 
dali_init(pDalill_bus_0,NULL); 
while (1) 

// Dieses if nur in Multitaskingumgebungen mit Signallingcallback 
// Beispielhaft für Rtos 
if (DALI_FLAG == osThreadFlagsWait(DALI_FLAG,osFlagsWaitAny,15)) 

// something to do ?, not necessary if nothing else should be done in main 
while (dalill_isBusy()) 

dalill_processQueues(); 

PCIO-Interrupt (STM32xx), Beispiel 

extern dalill_bus_t* pDalill_bus_0; 
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) 

if(GPIO_Pin == DALI_IN_Pin) 

dalill_interruptExt(pDalill_bus_0); 
} ... 

Für den TimerInterrupt wurde hier beispielhaft eine Vorschaltroutine benutzt, welche dann die echte Interrupt Routine mit dem Parameter versorgt: 

// timerinterrupt needs parameter, so we add it here 
void dalill_timerInterrupt() 

dalill_timerInterrupt2(pDalill_bus_0); 

Und darauffolgend: 

HAL_TIM_RegisterCallback(&htim16, HAL_TIM_PERIOD_ELAPSED_CB_ID, dalill_timerInterrupt); 

Initialisierung

Anschließend wird dalill_createBusLine aufgerufen. Diese hat als Parameter drei Callbackfunktionen, die in dali_ll_hal.c definiert sein müssen. Diese Callbacks dienen zum Testen, Setzen und Zurücksetzen der DALI-Busleitungen. 

Der Pegel HIGH oder LOW bezieht sich dabei auf den DALI-Bus und nicht auf den Wert des PCIO. Das heißt, wenn der PCIO den DALI-Bus invertiert treibt, so wird durch dalill_setBusStateHigh der PCIO auf LOW und damit der Buspegel auf HIGH gesetzt. 

Diese Callbacks werden schon hier gesetzt, damit der Bus unmittelbar nach Einschalten der Hardware auf IDLE gesetzt werden kann und so keine Störungen auf dem Bus erzeugt werden. 

Liefert dalill_createBusLine einen Wert != NULL ist pDalill_bus_0 ein Zeiger auf diese Instanz des Hardwaretreibers. 

Mit diesem Parameter wird nun die Funktion dali_init() im Applikationsmodul aufgerufen. 

Dali_init ist auch in der Dokumentation der DALI-API beschrieben. 

Hauptschleife 

Nach erfolgreich ausgeführten Initialisierungen kann die Hauptschleife ausgeführt werden. 

Mit dalill_isbusy kann getestet werden, ob sich in der Read- und/oder Writequeue Daten befinden, die auf Weiterverarbeitung warten. 

Der Aufruf von dalill_processQueues führt dann dazu, dass alle in beiden Queues vorhandenen Daten verarbeitetet werden. Das heißt, sie werden sowohl an die DALI-API weitergegeben, als auch über den Bus verschickt. Über das Loopinterface werden sie auch an eventuell vorhanden weitere Instanzen der DALI-API weitergegeben. 

Soll in der Hauptschleife nichts anderes getan werden, als den DALI Stack zu bedienen, muss nur die Funktion dalill_processQueues permanent aufgerufen werden. 

Hinweis

Werden hier noch andere Aktionen ausgeführt, so ist darauf zu achten, dass diese nie blockieren und auch nicht länger als wenige Millisekunden dauern um die reibungslose Arbeit des DALI Stacks zu garantieren. 

In Multitasking-Umgebungen wie RTOS kann das hier beschriebene Signalling benutzt werden. 

Hinweis

Weil der Low Level Treiber für jede Instanz der API einen 10 ms Heartbeat erzeugt und damit die Timinghelper-Funktion der API aufruft, wird die Funktion dalill_isbusy im IDLE-Fall spätestens nach 10 ms Daten melden. 

Hier oder im Timinghelper ist eine gute Position, um z. B. eine LED blinken zu lassen, welche die Einsatzbereitschaft des Treibers signalisiert.