Funktion dali_init


 

Hier wird eine dali_init Funktion für zwei Instanzen des DALI stack beschrieben. 

Hinweis

Die meisten Teile sind auch in der API-Dokumentation beschrieben. 

Zu Beginn der dali_init werden zuerst die Instanzen des Stacks erzeugt. Dann werden weitere Callbacks für den Low Level Treiber initialisiert und danach der Timer gestartet. Damit ist der Treiber einsatzbereit. 

/**************************************************************/ 
/* Variables for two instances of the stack 
**************************************************************/ 
// application controller 
dalilib_action_t action; 
uint8_t bDaliStackReady; 
dalilib_instance_t pDaliStackInstance; 
dalilib_cfg_t ctrl_device_config; 
// LED DT6-Device 
dalilib_action_t actionLED; 
uint8_t bDaliStackReadyLED; // for LED 
dalilib_instance_t pDaliStackInstanceLED; // for LED 
dalilib_cfg_t ctrl_gear_config; 
/**************************************************************/ 
/* initialize the HAL driver and the DALI stack 
**************************************************************/ 
void dali_init(dalill_bus_t* pDalill_bus,dalill_bus_t *pDalill_bus2) 

dalill_base_t dalill_base; 
// For the application controller 
pDaliStackInstance = NULL; 
bDaliStackReady = 0; 
// create new DALI stack instance 
pDaliStackInstance = dalilib_createinstance(); 
if (NULL == pDaliStackInstance) 
{ // error 
return; 

// Tell lowleveldriver from this instance of the stack 
addInstance(pDalill_bus,pDaliStackInstance); 
// create and configure DALI stack as single application controller 
dali_create_application_controller_config(); 
// add Low Level structure to DALI stack instance and vice versa 
ctrl_device_config.context = pDalill_bus; 
// Only one initial value. This will be overwritten by the loop layer of the ll-Driver 
pDalill_bus->context = pDaliStackInstance; 
// initialize DALI stack instance 
if (R_DALILIB_OK != dalilib_init(pDaliStackInstance , &ctrl_device_config)) 

// error 
return; 

// start DALI stack instance 
if (R_DALILIB_OK != dalilib_start(pDaliStackInstance)) 

// error 
return; 

// For the ledDevice 
pDaliStackInstanceLED = NULL; 
bDaliStackReadyLED = 0; 
// create new DALI stack instance 
pDaliStackInstanceLED = dalilib_createinstance(); 
if (NULL == pDaliStackInstanceLED) 
{ // error 
return; 

// Tell lowleveldriver from this instance of the stack 
addInstance(pDalill_bus,pDaliStackInstanceLED); 
// create and configure DALI stack as a LED (DT6-Device) 
dali_create_gear_configLED(); 
// add Low Level structure to DALI stack instance and vice versa 
ctrl_gear_config.context =pDalill_bus; 
// initialize DALI stack instance 
if (R_DALILIB_OK != dalilib_init(pDaliStackInstanceLED , &ctrl_gear_config)) 

// error 
return; 

// start DALI stack instance 
if (R_DALILIB_OK != dalilib_start(pDaliStackInstanceLED)) 

// error 
return; 

// initialize callback functions for DALI Low Level Driver 
dalill_base.debug_mode = 0; 
dalill_base.max_frame_length = 32; 
dalill_base.rx_rcv_high_offset = 50;
dalill_base.rx_rcv_low_offset  = 58;
dalill_base.rx_high_offset = 40; // 60 DALI 2 click 
dalill_base.rx_low_offset = 40; // 60 DALI 2 click 
dalill_base.tx_high_offset = 20; // 35 DALI 2 click 
dalill_base.tx_low_offset = 20; // 35 DALI 2 click 
// Api functions 
dalill_base.dalilltimingHelper = &dalill_timingHelper; 
dalill_base.dalilltoDalilib = &dalill_toDalilib; 
// funtions in dali_ll_hal.c 
dalill_base.getCurrentTimerVal = &dalill_getCurrentTimerVal; 
dalill_base.getTimerPeriod = &dalill_getTimerPeriod; 
dalill_base.setTimerPeriod = &dalill_setTimerPeriod; 
dalill_base.startTimer = &dalill_startTimer; 
// It is important to set this to NULL if no signalling is used !!! 
// or implement a dummy function in dali_ll_hal.c 
dalill_base.signalToThread = &dalill_signalToThread; 
// functions to block and release interrupts 
// It is important to set this pointer to NULL if not used 
dalill_base.enableIRQ = enableIRQ; 
dalill_base.disableIRQ = disableIRQ; 
// create all data for LL-Driver and start the timer 
dalill_createBase(&dalill_base); 

Die Variablen
int16_t dalill_base.rx_high_offset,
int16_t dalill_base.rx_low_offset,
int16_t dalill_base.rx_rcv_high_offset,
int16_t dalill_base.rx_rcv_low_offset,

int16_t dalill_base.tx_high_offset und
int16_t dalill_base.tx_low_offset werden genutzt, um die Schaltzeiten des Interfaces zwischen PCIO und dem DALI-Bus zu kompensieren. 

Das ist notwendig, damit der Treiber beim Senden nicht seine eigenen Signale als Kollision interpretiert und sich damit selbst blockiert. 

Die Variablen
rx_rcv_high_offset,
rx_rcv_low_offset,
rx_high_offset und
rx_low_offset dienen zur Steuerung des Empfangsprozesses. 
tx_high_offset und
tx_low_offset dienen zur Steuerung des Sendeprozesses. 

Die Einheit dieser Variablen ist Mikrosekunden. 

Hinweis

Falls erforderlich sind hier auch negative Werte möglich! 

Vorgehen zur Einstellung 

Hinweis

Die Variablen für die Senderichtung können nur mit Unterstützung eines Dali Tracers oder eines Oszilloskops einstellen werden. 

Sendeoffsets 

Mit tx_high_offset kann die Zeit verändert werden, in der der Pegel eines Halb-Bits auf LOW bleiben soll. Ist diese Zeit zu kurz, muss der Parameter um die entsprechende Zahl vom Mikrosekunden verkleinert werden. 

Mit tx_low_offset kann die Zeit verändert werden, in der der Pegel auf HIGH bleiben soll. Ist diese Zeit zu kurz, muss der Parameter vergrößert werden. 

Die Namensgebung der Parameter bezieht sich dabei auf den Wechsel in den Zielzustand HIGH beziehungsweise LOW. 

Beispiele 

Im folgenden Beispiel sind beide Zeiten zu kurz: 

 

Nach Verkleinerung von tx_high_offset um 10 Mikrosekunden erhält man folgendes Bild: 

 

Nach Vergrößerung von tx_low_offset um 12 Mikrosekunden erhält man folgendes Bild: 

 

Damit ist die Funktion dann fehlerfrei.

Der Low Level Treiber stellt diverse Funktionen zur Verfügung, welche die Bestimmung der tx_xx_offset Parameter vereinfachen. Hierzu gehören die Funktionen:
dalill_stopReceiver,
dalill_startReceiver,
dalill_HW_fail und
dalill_send8bitTestFrame.

In bestimmten Fällen, wenn die rx_xx_offset Parameter noch nicht optimal eingestellt sind, kann der Receiver den Low Level Treiber daran hindern Nachrichten zu versenden. Der Grund hierfür ist, dass während des Sendens eine - eigentlich nicht vorhandene - Kollision festgestellt wird, die den Sendevorgang unterbricht.

Um zuerst die tx_xx_offset Parameter ungestört einstellen zu können, kann der Receiver mittels der Funktion dalill_stopReceiver deaktiviert werden.

Nach der Anpassung der Sende-Parameter kann der Receiver wieder mit startReceiver aktiviert werden.

Mit Hilfe der Funktion send8bitTestFrame ist es weiter möglich, eine Testnachricht mit dem Inhalt 0xFE direkt auf den DALI-BUS zu geben, ohne auf die Funktionen der dali_lib API zurückgreifen zu müssen.

Das ist vor allem für die Geräte interessant, die als control gear konfiguriert werden und normalerweise nicht von sich aus Nachrichten senden können.

Die Funktion dalill_HW_fail hilft dabei festzustellen, ob ein Hardwaredefekt vorliegt und sollte nur nach einem Sendevorgang aufgerufen werden. Ein Rückgabewert von ungleich 0 zeigt dann an, dass entweder keine Nachricht gesendet wurde (Transmitter-Problem) oder die gesendete Nachricht nicht korrekt wieder eingelesen wurde (Receiver-Problem).

Leseoffsets 

Die Einstellung der Lese-Offsets wird bei aktiviertem Receiver durchgeführt.

Sollte der Receiver mit dalill_stopReceiver deaktivert worden sein, kann dieser mittels der Funktion dalill_startReceiver wieder aktiviert werden.

Bei rx_high_offset und rx_low_offset handelt es sich um Parameter, die dazu verwendet werden, um eine Auto-Kollision zu verhindern. Also um zu vermeiden, dass eine gesendete Nachricht vom eigenen Receiver als Kollision auf dem Bus interpretiert wird.

Für die Bestimmung der Werte werden beide Parameter zuerst auf den Wert Null gesetzt und die Testnachricht wird zyklisch gesendet.

Erwartungsgemäß wird die Nachricht nicht komplett gesendet, da durch nicht optimal eingestellte Werte für rx_xx_offset eine Auto-Kollision festgestellt und der Sendevorgang unterbrochen wird.

Die Offsets werden dann in 10er Schritten erhöht.

Sobald die Kollisionen aufhören, wird dieser Wert festgehalten. Die Offsets werden dann weiter erhöht bis erneut Kollisionen gemeldet werden.

Der optimale Offset liegt in der Mitte zwischen dem unteren und dem oberen ermitteltem Wert. Damit sollte ein fehlerfreier Empfang möglich sein.

rx_high_offset und rx_low_offset haben normalerweise die gleichen Werte.

Die beiden Parameter rx_rcv_high_offset und rx_rcv_low_offset dienen dazu, das Timing der Receiver-Interface-Schaltung so anzupassen, das Nachrichten anderer DALI-Bus-Teilnehmer korrekt interpretiert werden. Das ist notwendig, weil durch unterschiedliche DALI-Interface-Schaltungen unterschiedliche Verzögerungszeiten entstehen.

Auch hier können, wie bei rx_xx_offset, nur durch inkrementelles Herantasten verwendbare Parameter gefunden werden. Eine exakte Bestimmung der Timing-Parameter lässt sich allerdings nur mit dem ProbitLab2-Tester in Verbindung mit vorhandenen Debug-Variablen des Low Level Treibers und dem dazugehörenden Vorgehen durchführen.

Bei vorhandenem ProbitLab2-Tester kann MBS bei der Einstellung der Timing-Parameter anleiten und unterstützen.

Sollte kein ProbitLab2-Tester verfügbar sein, kann die Bestimmung der Timing-Parameter von MBS durchgeführt werden.

(siehe auch Produktunterstützung)