Commit 4b6a533f9c4ae9a5f820d4998ffbfe7dcd16b02f

Authored by Arkadiusz Materek
Committed by Arek M
1 parent 4eb18d49

DALI tests

.cproject
@@ -142,6 +142,7 @@ @@ -142,6 +142,7 @@
142 <option id="org.eclipse.cdt.cross.arm.gnu.c.compiler.option.preprocessor.def.91794738" name="Defined symbols (-D)" superClass="org.eclipse.cdt.cross.arm.gnu.c.compiler.option.preprocessor.def" useByScannerDiscovery="false" valueType="definedSymbols"> 142 <option id="org.eclipse.cdt.cross.arm.gnu.c.compiler.option.preprocessor.def.91794738" name="Defined symbols (-D)" superClass="org.eclipse.cdt.cross.arm.gnu.c.compiler.option.preprocessor.def" useByScannerDiscovery="false" valueType="definedSymbols">
143 <listOptionValue builtIn="false" value="CPU_CLOCK=32000000"/> 143 <listOptionValue builtIn="false" value="CPU_CLOCK=32000000"/>
144 <listOptionValue builtIn="false" value="XMC1200_T038x0200"/> 144 <listOptionValue builtIn="false" value="XMC1200_T038x0200"/>
  145 + <listOptionValue builtIn="false" value="DALI_TEST"/>
145 </option> 146 </option>
146 <option id="org.eclipse.cdt.cross.arm.gnu.c.compiler.option.warnings.toerrors.1701168972" name="Warnings as errors (-Werror)" superClass="org.eclipse.cdt.cross.arm.gnu.c.compiler.option.warnings.toerrors" useByScannerDiscovery="false" value="true" valueType="boolean"/> 147 <option id="org.eclipse.cdt.cross.arm.gnu.c.compiler.option.warnings.toerrors.1701168972" name="Warnings as errors (-Werror)" superClass="org.eclipse.cdt.cross.arm.gnu.c.compiler.option.warnings.toerrors" useByScannerDiscovery="false" value="true" valueType="boolean"/>
147 <option id="org.eclipse.cdt.cross.arm.gnu.c.compiler.option.misc.unsignedbitfields.1660069779" name="Bitfields are unsigned (-funsigned-bitfields)" superClass="org.eclipse.cdt.cross.arm.gnu.c.compiler.option.misc.unsignedbitfields" useByScannerDiscovery="false" value="true" valueType="boolean"/> 148 <option id="org.eclipse.cdt.cross.arm.gnu.c.compiler.option.misc.unsignedbitfields.1660069779" name="Bitfields are unsigned (-funsigned-bitfields)" superClass="org.eclipse.cdt.cross.arm.gnu.c.compiler.option.misc.unsignedbitfields" useByScannerDiscovery="false" value="true" valueType="boolean"/>
@@ -164,6 +165,7 @@ @@ -164,6 +165,7 @@
164 <option id="org.eclipse.cdt.cross.arm.gnu.cpp.compiler.option.preprocessor.def.1564220828" name="Defined symbols (-D)" superClass="org.eclipse.cdt.cross.arm.gnu.cpp.compiler.option.preprocessor.def" useByScannerDiscovery="false" valueType="definedSymbols"> 165 <option id="org.eclipse.cdt.cross.arm.gnu.cpp.compiler.option.preprocessor.def.1564220828" name="Defined symbols (-D)" superClass="org.eclipse.cdt.cross.arm.gnu.cpp.compiler.option.preprocessor.def" useByScannerDiscovery="false" valueType="definedSymbols">
165 <listOptionValue builtIn="false" value="CPU_CLOCK=32000000"/> 166 <listOptionValue builtIn="false" value="CPU_CLOCK=32000000"/>
166 <listOptionValue builtIn="false" value="XMC1200_T038x0200"/> 167 <listOptionValue builtIn="false" value="XMC1200_T038x0200"/>
  168 + <listOptionValue builtIn="false" value="DALI_TEST"/>
167 </option> 169 </option>
168 <option id="org.eclipse.cdt.cross.arm.gnu.cpp.compiler.option.preprocessor.nostdincpp.1743927048" name="Do not search system C++ directories (-nostdinc++)" superClass="org.eclipse.cdt.cross.arm.gnu.cpp.compiler.option.preprocessor.nostdincpp" useByScannerDiscovery="false" value="true" valueType="boolean"/> 170 <option id="org.eclipse.cdt.cross.arm.gnu.cpp.compiler.option.preprocessor.nostdincpp.1743927048" name="Do not search system C++ directories (-nostdinc++)" superClass="org.eclipse.cdt.cross.arm.gnu.cpp.compiler.option.preprocessor.nostdincpp" useByScannerDiscovery="false" value="true" valueType="boolean"/>
169 <option id="org.eclipse.cdt.cross.arm.gnu.cpp.compiler.option.optimization.shortenums.561358169" name="Short enumerations (-fshort-enums)" superClass="org.eclipse.cdt.cross.arm.gnu.cpp.compiler.option.optimization.shortenums" useByScannerDiscovery="false" value="true" valueType="boolean"/> 171 <option id="org.eclipse.cdt.cross.arm.gnu.cpp.compiler.option.optimization.shortenums.561358169" name="Short enumerations (-fshort-enums)" superClass="org.eclipse.cdt.cross.arm.gnu.cpp.compiler.option.optimization.shortenums" useByScannerDiscovery="false" value="true" valueType="boolean"/>
src/test/assert.cpp 0 โ†’ 100644
  1 +/*
  2 + * Copyright (c) 2015-2016, Arkadiusz Materek (arekmat@poczta.fm)
  3 + *
  4 + * All right reversed. Usage for commercial on not commercial
  5 + * purpose without written permission is not allowed.
  6 + *
  7 + * This program is distributed in the hope that it will be useful,
  8 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10 + */
  11 +
  12 +#include "assert.hpp"
  13 +
  14 +volatile int gFaliuresCount = 0;
  15 +
  16 +void testLogFailure(const char* str) {
  17 + gFaliuresCount++;
  18 +}
src/test/assert.hpp 0 โ†’ 100644
  1 +/*
  2 + * Copyright (c) 2015-2016, Arkadiusz Materek (arekmat@poczta.fm)
  3 + *
  4 + * All right reversed. Usage for commercial on not commercial
  5 + * purpose without written permission is not allowed.
  6 + *
  7 + * This program is distributed in the hope that it will be useful,
  8 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10 + */
  11 +
  12 +#ifndef TEST_H_
  13 +#define TEST_H_
  14 +
  15 +void testLogFailure(const char* str);
  16 +
  17 +#define STR_LINE(x) #x
  18 +#define STR_LINE_(x) STR_LINE(x)
  19 +
  20 +#define TEST_FALIURE(cond) testLogFailure("") //testLogFailure(__FILE__ ":" STR_LINE_(__LINE__))
  21 +
  22 +#define TEST_SUCCESS(cond)
  23 +
  24 +#define TEST_ASSERT(cond) \
  25 + do { \
  26 + if (!(cond)) { \
  27 + TEST_FALIURE(cond); \
  28 + } else { \
  29 + TEST_SUCCESS(cond); \
  30 + } \
  31 + } while(0)
  32 +
  33 +#endif // TEST_H_
src/test/mocks.cpp 0 โ†’ 100644
  1 +/*
  2 + * Copyright (c) 2015-2016, Arkadiusz Materek (arekmat@poczta.fm)
  3 + *
  4 + * All right reversed. Usage for commercial on not commercial
  5 + * purpose without written permission is not allowed.
  6 + *
  7 + * This program is distributed in the hope that it will be useful,
  8 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10 + */
  11 +
  12 +#include "mocks.hpp"
  13 +
  14 +#ifdef DALI_TEST
  15 +
  16 +#include <string.h>
  17 +
  18 +namespace dali {
  19 +
  20 +const uint8_t kMemoryBank0[] = { //
  21 + 0x0E, // 00 size - 1
  22 + 0xFF, // 01 checksum
  23 + 0x01, // 02 number of banks
  24 + 0x00, // 03 GTIN byte 0
  25 + 0x00, // 04 GTIN byte 1
  26 + 0x00, // 05 GTIN byte 2
  27 + 0x00, // 06 GTIN byte 3
  28 + 0x00, // 07 GTIN byte 4
  29 + 0x00, // 08 GTIN byte 5
  30 + 0x00, // 09 firmware version (major)
  31 + 0x00, // 0A firmware version (minor)
  32 + 0x00, // 0B serial number byte 1
  33 + 0x00, // 0C serial number byte 2
  34 + 0x00, // 0D serial number byte 3
  35 + 0x00, // 0E serial number byte 4
  36 + 0x00, // additional control gear information
  37 +};
  38 +
  39 +uint8_t gMemoryBank1[] = { //
  40 + 0x0E, // 00 size - 1
  41 + 0x00, // 01 checksum
  42 + 0x00, // 02 memory bank 1 lock byte (read-only if not 0x55)
  43 + 0x00, // 03 OEM GTIN byte 0
  44 + 0x00, // 04 OEM GTIN byte 1
  45 + 0x00, // 05 OEM GTIN byte 2
  46 + 0x00, // 06 OEM GTIN byte 3
  47 + 0x00, // 07 OEM GTIN byte 4
  48 + 0x00, // 08 OEM GTIN byte 5
  49 + 0x00, // 09 OEM serial number byte 1
  50 + 0x00, // 0A OEM serial number byte 2
  51 + 0x00, // 0B OEM serial number byte 3
  52 + 0x00, // 0C OEM serial number byte 4
  53 + 0x00, // 0D Subsystem (bit 4 to bit 7) Device number (bit 0 to bit 3)
  54 + 0x00, // 0E Lamp type number (lockable)
  55 + 0x00, // 0F Lamp type number
  56 +};
  57 +
  58 +uint8_t gMemoryBank2[] = { //
  59 + 0x0E, // 00 size - 1
  60 + 0x00, // 01 checksum
  61 + 0x00, // 02 memory bank 2 lock byte (read-only if not 0x55)
  62 + 0x00, // 03
  63 + 0x00, // 04
  64 + 0x00, // 05
  65 + 0x00, // 06
  66 + 0x00, // 07
  67 + 0x00, // 08
  68 + 0x00, // 09
  69 + 0x00, // 0A
  70 + 0x00, // 0B
  71 + 0x00, // 0C
  72 + 0x00, // 0D
  73 + 0x00, // 0E
  74 + 0x00, // 0F
  75 +};
  76 +
  77 +typedef struct {
  78 + int32_t x;
  79 + int32_t y;
  80 +} Point;
  81 +
  82 +MemoryMock::MemoryMock(size_t size) :
  83 + writeError(false), mDataSize(size) {
  84 + reset();
  85 +}
  86 +
  87 +size_t MemoryMock::dataSize() {
  88 + return mDataSize;
  89 +}
  90 +
  91 +size_t MemoryMock::dataWrite(uintptr_t addr, const uint8_t* data, size_t size) {
  92 + if (addr + size > mDataSize) {
  93 + return 0;
  94 + }
  95 + if (writeError) {
  96 + return 0;
  97 + }
  98 + memcpy(mData + addr, data, size);
  99 + return size;
  100 +}
  101 +
  102 +const uint8_t* MemoryMock::data(uintptr_t addr, size_t size) {
  103 + if (addr + size > mDataSize) {
  104 + return nullptr;
  105 + }
  106 + return mData + addr;
  107 +}
  108 +
  109 +size_t MemoryMock::tempSize() {
  110 + return 32;
  111 +}
  112 +
  113 +size_t MemoryMock::tempWrite(uintptr_t addr, const uint8_t* data, size_t size) {
  114 + if (addr + size > sizeof(mTemp)) {
  115 + return 0;
  116 + }
  117 + memcpy(mTemp + addr, data, size);
  118 + return size;
  119 +}
  120 +
  121 +const uint8_t* MemoryMock::tempData(uintptr_t addr, size_t size) {
  122 + if (addr + size > sizeof(mTemp)) {
  123 + return nullptr;
  124 + }
  125 + return mTemp + addr;
  126 +}
  127 +
  128 +void MemoryMock::reset() {
  129 + memset(&mData, 0, sizeof(mData));
  130 + memset(&mTemp, 0xff, sizeof(mTemp));
  131 +}
  132 +
  133 +LampMock::LampMock()
  134 + : mFadeTime(0)
  135 +#ifdef DALI_DT8
  136 + , mColorChangeTime(0)
  137 +#endif
  138 +{
  139 + memset(mClients, 0, sizeof(mClients));
  140 + memset(mPrimary, 0, sizeof(mPrimary));
  141 +}
  142 +
  143 +Status LampMock::registerClient(ILampClient* c) {
  144 + for (uint16_t i = 0; i < kMaxClients; ++i) {
  145 + if (mClients[i] == nullptr) {
  146 + mClients[i] = c;
  147 + return dali::Status::OK;
  148 + }
  149 + }
  150 + return dali::Status::ERROR;
  151 +}
  152 +
  153 +Status LampMock::unregisterClient(ILampClient* c) {
  154 + for (uint16_t i = 0; i < kMaxClients; ++i) {
  155 + if (mClients[i] == c) {
  156 + mClients[i] = nullptr;
  157 + return dali::Status::OK;
  158 + }
  159 + }
  160 + return dali::Status::ERROR;
  161 +}
  162 +
  163 +void LampMock::setLevel(uint16_t level, uint32_t fadeTime) {
  164 + mLevel = level;
  165 + mFadeTime = fadeTime;
  166 +}
  167 +
  168 +uint16_t LampMock::getLevel() {
  169 + return mLevel;
  170 +}
  171 +
  172 +bool LampMock::isFading() {
  173 + return (mFadeTime != 0);
  174 +}
  175 +
  176 +void LampMock::abortFading() {
  177 + mFadeTime = 0;
  178 +}
  179 +
  180 +#ifdef DALI_DT8
  181 +
  182 +void LampMock::setPrimary(const uint16_t primary[], uint8_t size, uint32_t changeTime) {
  183 + if (size > 6) {
  184 + size = 6;
  185 + }
  186 + for (uint16_t i = 0; i < size; ++i) {
  187 + mPrimary[i] = primary[i];
  188 + }
  189 + mColorChangeTime = changeTime;
  190 +}
  191 +
  192 +void LampMock::getPrimary(uint16_t primary[], uint8_t size) {
  193 + for (uint16_t i = 0; i < size; ++i) {
  194 + primary[i] = mPrimary[i];
  195 + }
  196 +}
  197 +
  198 +bool LampMock::isColorChanging() {
  199 + return (mColorChangeTime != 0);
  200 +}
  201 +
  202 +void LampMock::abortColorChanging() {
  203 + mColorChangeTime = 0;
  204 +}
  205 +
  206 +#endif // DALI_DT8
  207 +
  208 +void LampMock::onLampStateChnaged(ILampState state) {
  209 + for (uint16_t i = 0; i < kMaxClients; ++i) {
  210 + if (mClients[i] != nullptr) {
  211 + mClients[i]->onLampStateChnaged(state);
  212 + }
  213 + }
  214 +}
  215 +
  216 +TimerMock::TimerMock() :
  217 + time(0) {
  218 + memset(tasks, 0, sizeof(tasks));
  219 +}
  220 +
  221 +uint64_t TimerMock::getTime() {
  222 + return time;
  223 +}
  224 +
  225 +Status TimerMock::schedule(ITimerTask* task, uint32_t delay, uint32_t period) {
  226 + for (uint8_t i = 0; i < kMaxTasks; ++i) {
  227 + TaskInfo* taskInfo = &tasks[i];
  228 + if (taskInfo->task == nullptr) {
  229 + taskInfo->task = task;
  230 + taskInfo->time = time + delay;
  231 + taskInfo->period = period;
  232 + return dali::Status::OK;
  233 + }
  234 + }
  235 + return Status::ERROR;
  236 +}
  237 +
  238 +void TimerMock::cancel(ITimerTask* task) {
  239 + for (uint8_t i = 0; i < kMaxTasks; ++i) {
  240 + TaskInfo* taskInfo = &tasks[i];
  241 + if (taskInfo->task == task) {
  242 + taskInfo->task = nullptr;
  243 + }
  244 + }
  245 +}
  246 +
  247 +uint32_t TimerMock::randomize() {
  248 + return 0xabdef;
  249 +}
  250 +
  251 +void TimerMock::run(uint64_t now) {
  252 + uint64_t end = now + time;
  253 + while (time < end) {
  254 + uint32_t timeMin = end;
  255 + for (uint8_t i = 0; i < kMaxTasks; ++i) {
  256 + TaskInfo* taskInfo = &tasks[i];
  257 +
  258 + if (taskInfo->task != nullptr) {
  259 + if (taskInfo->time <= timeMin) {
  260 + time = timeMin = taskInfo->time;
  261 + }
  262 + if (taskInfo->time <= time) {
  263 + taskInfo->task->timerTaskRun();
  264 + if (taskInfo->period != 0) {
  265 + taskInfo->time += taskInfo->period;
  266 + } else {
  267 + taskInfo->task = nullptr;
  268 + }
  269 + }
  270 + }
  271 + }
  272 + time = timeMin;
  273 + }
  274 +}
  275 +
  276 +BusMock::BusMock() :
  277 + mState(IBusState::CONNECTED) {
  278 + memset(mClients, 0, sizeof(mClients));
  279 +}
  280 +
  281 +Status BusMock::registerClient(IBusClient* c) {
  282 + for (uint16_t i = 0; i < kMaxClients; ++i) {
  283 + if (mClients[i] == nullptr) {
  284 + mClients[i] = c;
  285 + c->onBusStateChanged(mState);
  286 + return dali::Status::OK;
  287 + }
  288 + }
  289 + return dali::Status::ERROR;
  290 +}
  291 +
  292 +Status BusMock::unregisterClient(IBusClient* c) {
  293 + for (uint16_t i = 0; i < kMaxClients; ++i) {
  294 + if (mClients[i] == c) {
  295 + mClients[i] = nullptr;
  296 + return dali::Status::OK;
  297 + }
  298 + }
  299 + return dali::Status::ERROR;
  300 +}
  301 +
  302 +Status BusMock::sendAck(uint8_t ack) {
  303 + this->ack = ack;
  304 + return Status::OK;
  305 +}
  306 +
  307 +void BusMock::onDataReceived(uint64_t timeMs, uint16_t data) {
  308 + for (uint8_t i = 0; i < kMaxClients; ++i) {
  309 + if (mClients[i] != nullptr) {
  310 + mClients[i]->onDataReceived(timeMs, data);
  311 + }
  312 + }
  313 +}
  314 +
  315 +void BusMock::onBusStateChanged(IBusState state) {
  316 + mState = state;
  317 + for (uint8_t i = 0; i < kMaxClients; ++i) {
  318 + if (mClients[i] != nullptr) {
  319 + mClients[i]->onBusStateChanged(state);
  320 + }
  321 + }
  322 +}
  323 +
  324 +void LampControllerListenerMock::onLampStateChnaged(ILamp::ILampState state) {
  325 + capturedState = state;
  326 +}
  327 +
  328 +uint8_t BusControllerListenerMock::getShortAddr() {
  329 + return addr;
  330 +}
  331 +
  332 +uint16_t BusControllerListenerMock::getGroups() {
  333 + return groups;
  334 +}
  335 +
  336 +void BusControllerListenerMock::onBusDisconnected() {
  337 +}
  338 +
  339 +Status BusControllerListenerMock::handleCommand(uint16_t repeatCount, Command cmd, uint8_t param) {
  340 + capturedRepeatCount = repeatCount;
  341 + capturedCmd = cmd;
  342 + capturedParam = param;
  343 + return Status::OK;
  344 +}
  345 +
  346 +Status BusControllerListenerMock::handleIgnoredCommand(Command cmd, uint8_t param) {
  347 + capturedRepeatCount = 0;
  348 + capturedCmd = Command::INVALID;
  349 + capturedParam = 0xff;
  350 + return Status::INVALID;
  351 +}
  352 +
  353 +void BusControllerListenerMock::reset(uint8_t addr, uint16_t groups) {
  354 + this->addr = addr;
  355 + this->groups = groups;
  356 + capturedCmd = Command::INVALID;
  357 + capturedParam = 0xff;
  358 +}
  359 +
  360 +} // namespace dali
  361 +
  362 +#endif // DALI_TEST
src/test/mocks.hpp 0 โ†’ 100644
  1 +/*
  2 + * Copyright (c) 2015-2016, Arkadiusz Materek (arekmat@poczta.fm)
  3 + *
  4 + * All right reversed. Usage for commercial on not commercial
  5 + * purpose without written permission is not allowed.
  6 + *
  7 + * This program is distributed in the hope that it will be useful,
  8 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10 + */
  11 +
  12 +#ifndef DALI_TEST_MOCK_HPP_
  13 +#define DALI_TEST_MOCK_HPP_
  14 +
  15 +#include <dali/dali_dt8.hpp>
  16 +#include <dali/controller/bus.hpp>
  17 +#include <dali/controller/lamp.hpp>
  18 +
  19 +#include <string.h>
  20 +
  21 +namespace dali {
  22 +
  23 +class MemoryMock: public IMemory {
  24 +public:
  25 + MemoryMock(size_t size);
  26 + virtual ~MemoryMock() {
  27 + }
  28 +
  29 + size_t dataSize() override;
  30 + size_t dataWrite(uintptr_t addr, const uint8_t* data, size_t size) override;
  31 + const uint8_t* data(uintptr_t addr, size_t size) override;
  32 +
  33 + size_t tempSize() override;
  34 + size_t tempWrite(uintptr_t addr, const uint8_t* data, size_t size) override;
  35 + const uint8_t* tempData(uintptr_t addr, size_t size) override;
  36 +
  37 + void reset();
  38 + bool writeError;
  39 + size_t mDataSize;
  40 + uint8_t mData[252];
  41 + uint8_t mTemp[32];
  42 +};
  43 +
  44 +class LampMock:
  45 +#ifdef DALI_DT8
  46 + public ILampDT8
  47 +#else
  48 + public ILamp
  49 +#endif // DALI_DT8
  50 +{
  51 +public:
  52 +
  53 + static const uint16_t kMaxClients = 2;
  54 +
  55 + LampMock();
  56 + virtual ~LampMock() {
  57 + }
  58 +
  59 + Status registerClient(ILampClient* c) override;
  60 + Status unregisterClient(ILampClient* c) override;
  61 + void setLevel(uint16_t level, uint32_t fadeTime) override;
  62 + uint16_t getLevel() override;
  63 + bool isFading() override;
  64 + void abortFading() override;
  65 +
  66 +#ifdef DALI_DT8
  67 + void setPrimary(const uint16_t primary[], uint8_t size, uint32_t changeTime) override;
  68 + void getPrimary(uint16_t primary[], uint8_t size) override;
  69 + bool isColorChanging() override;
  70 + void abortColorChanging() override;
  71 +#endif // DALI_DT8
  72 +
  73 + void setState(ILampState state) {
  74 + onLampStateChnaged(state);
  75 + }
  76 +
  77 + bool mPowerOn;
  78 + uint16_t mLevel;
  79 + uint32_t mFadeTime;
  80 +#ifdef DALI_DT8
  81 + uint16_t mPrimary[6];
  82 + uint32_t mColorChangeTime;
  83 +#endif // DALI_DT8
  84 +
  85 +private:
  86 + ILampClient* mClients[kMaxClients];
  87 +
  88 + void onLampStateChnaged(ILampState state);
  89 +};
  90 +
  91 +class BusMock: public IBus {
  92 +public:
  93 +
  94 + static const uint16_t kMaxClients = 2;
  95 +
  96 + BusMock();
  97 + virtual ~BusMock() {
  98 + }
  99 +
  100 + Status registerClient(IBusClient* c) override;
  101 + Status unregisterClient(IBusClient* c) override;
  102 + Status sendAck(uint8_t ack) override;
  103 +
  104 + void handleReceivedData(uint64_t timeMs, uint16_t data) {
  105 + ack = 0xffff;
  106 + onDataReceived(timeMs, data);
  107 + }
  108 +
  109 + void setState(IBusState state) {
  110 + onBusStateChanged(state);
  111 + }
  112 +
  113 + uint16_t ack;
  114 +
  115 +private:
  116 + IBusClient* mClients[kMaxClients];
  117 + IBusState mState;
  118 +
  119 + void onDataReceived(uint64_t timeMs, uint16_t data);
  120 + void onBusStateChanged(IBusState state);
  121 +};
  122 +
  123 +class TimerMock: public ITimer {
  124 +public:
  125 +
  126 + static const uint8_t kMaxTasks = 2;
  127 +
  128 + typedef struct {
  129 + ITimer::ITimerTask* task;
  130 + uint64_t time;
  131 + uint32_t period;
  132 + } TaskInfo;
  133 +
  134 + TimerMock();
  135 + virtual ~TimerMock() {
  136 + }
  137 +
  138 + uint64_t getTime() override;
  139 + Status schedule(ITimerTask* task, uint32_t delay, uint32_t period) override;
  140 + void cancel(ITimerTask* task) override;
  141 + uint32_t randomize() override;
  142 + void run(uint64_t now);
  143 +
  144 + uint64_t time;
  145 + TaskInfo tasks[kMaxTasks];
  146 +};
  147 +
  148 +class LampControllerListenerMock: public controller::Lamp::Listener {
  149 +public:
  150 + void onLampStateChnaged(ILamp::ILampState state);
  151 +
  152 + ILamp::ILampState capturedState;
  153 +};
  154 +
  155 +class BusControllerListenerMock: public controller::Bus::Listener {
  156 +public:
  157 + uint8_t getShortAddr() override;
  158 + uint16_t getGroups() override;
  159 + void onBusDisconnected() override;
  160 + Status handleCommand(uint16_t repeat, Command cmd, uint8_t param) override;
  161 + Status handleIgnoredCommand(Command cmd, uint8_t param) override;
  162 + void reset(uint8_t addr, uint16_t groups);
  163 +
  164 + uint8_t addr;
  165 + uint16_t groups;
  166 + uint16_t capturedRepeatCount;
  167 + Command capturedCmd;
  168 + uint8_t capturedParam;
  169 +};
  170 +
  171 +} // namespace dali
  172 +
  173 +#endif // DALI_TEST_MOCK_HPP_
src/test/tests.cpp 0 โ†’ 100644
  1 +/*
  2 + * Copyright (c) 2015-2016, Arkadiusz Materek (arekmat@poczta.fm)
  3 + *
  4 + * All right reversed. Usage for commercial on not commercial
  5 + * purpose without written permission is not allowed.
  6 + *
  7 + * This program is distributed in the hope that it will be useful,
  8 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10 + */
  11 +
  12 +#ifdef DALI_TEST
  13 +
  14 +#include "tests.hpp"
  15 +
  16 +#include "assert.hpp"
  17 +#include "mocks.hpp"
  18 +
  19 +#include <dali/config.hpp>
  20 +#include <dali/slave.hpp>
  21 +
  22 +#include <string.h>
  23 +
  24 +namespace dali {
  25 +
  26 +namespace {
  27 +
  28 +CreateSlave gCreateSlave;
  29 +MemoryMock* gMemory;
  30 +LampMock* gLamp;
  31 +BusMock* gBus;
  32 +TimerMock* gTimer;
  33 +Slave* gSlave;
  34 +
  35 +uint16_t genData(uint8_t addr, Command cmd) {
  36 + uint16_t data = ((uint16_t) addr << 8) | (uint16_t) cmd;
  37 + data |= 0x0100;
  38 + return data;
  39 +}
  40 +
  41 +uint16_t genData(Command cmd, uint8_t param = 0) {
  42 + return (((uint16_t) cmd - (uint16_t) Command::_SPECIAL_COMMAND) << 8) | (uint16_t) param;
  43 +}
  44 +
  45 +uint16_t genDataDPC(uint8_t addr, uint8_t param) {
  46 + uint16_t data = ((uint16_t) addr << 8) | (uint16_t) param;
  47 + data &= ~0x0100;
  48 + return data;
  49 +}
  50 +
  51 +static const Command kConfigureCommand[] = {
  52 + Command::ADD_TO_GROUP_0,
  53 + Command::ADD_TO_GROUP_1,
  54 + Command::ADD_TO_GROUP_2,
  55 + Command::ADD_TO_GROUP_3,
  56 + Command::ADD_TO_GROUP_4,
  57 + Command::ADD_TO_GROUP_5,
  58 + Command::ADD_TO_GROUP_6,
  59 + Command::ADD_TO_GROUP_7,
  60 + Command::ADD_TO_GROUP_8,
  61 + Command::ADD_TO_GROUP_9,
  62 + Command::ADD_TO_GROUP_A,
  63 + Command::ADD_TO_GROUP_B,
  64 + Command::ADD_TO_GROUP_C,
  65 + Command::ADD_TO_GROUP_D,
  66 + Command::ADD_TO_GROUP_E,
  67 + Command::ADD_TO_GROUP_F,
  68 + Command::STORE_DTR_AS_SCENE_0,
  69 + Command::STORE_DTR_AS_SCENE_1,
  70 + Command::STORE_DTR_AS_SCENE_2,
  71 + Command::STORE_DTR_AS_SCENE_3,
  72 + Command::STORE_DTR_AS_SCENE_4,
  73 + Command::STORE_DTR_AS_SCENE_5,
  74 + Command::STORE_DTR_AS_SCENE_6,
  75 + Command::STORE_DTR_AS_SCENE_7,
  76 + Command::STORE_DTR_AS_SCENE_8,
  77 + Command::STORE_DTR_AS_SCENE_9,
  78 + Command::STORE_DTR_AS_SCENE_A,
  79 + Command::STORE_DTR_AS_SCENE_B,
  80 + Command::STORE_DTR_AS_SCENE_C,
  81 + Command::STORE_DTR_AS_SCENE_D,
  82 + Command::STORE_DTR_AS_SCENE_E,
  83 + Command::STORE_DTR_AS_SCENE_F,
  84 + Command::STORE_DTR_AS_MAX_LEVEL,
  85 + Command::STORE_DTR_AS_MIN_LEVEL,
  86 + Command::STORE_DTR_AS_SYS_FAIL_LEVEL,
  87 + Command::STORE_DTR_AS_POWER_ON_LEVEL,
  88 + Command::STORE_DTR_AS_FADE_TIME,
  89 + Command::STORE_DTR_AS_FADE_RATE,
  90 + Command::OFF };
  91 +
  92 +static const Command kQueryCommand[] = {
  93 + Command::QUERY_GROUPS_L,
  94 + Command::QUERY_GROUPS_H,
  95 + Command::QUERY_SCENE_0_LEVEL,
  96 + Command::QUERY_SCENE_1_LEVEL,
  97 + Command::QUERY_SCENE_2_LEVEL,
  98 + Command::QUERY_SCENE_3_LEVEL,
  99 + Command::QUERY_SCENE_4_LEVEL,
  100 + Command::QUERY_SCENE_5_LEVEL,
  101 + Command::QUERY_SCENE_6_LEVEL,
  102 + Command::QUERY_SCENE_7_LEVEL,
  103 + Command::QUERY_SCENE_8_LEVEL,
  104 + Command::QUERY_SCENE_9_LEVEL,
  105 + Command::QUERY_SCENE_A_LEVEL,
  106 + Command::QUERY_SCENE_B_LEVEL,
  107 + Command::QUERY_SCENE_C_LEVEL,
  108 + Command::QUERY_SCENE_D_LEVEL,
  109 + Command::QUERY_SCENE_E_LEVEL,
  110 + Command::QUERY_SCENE_F_LEVEL,
  111 + Command::QUERY_MAX_LEVEL,
  112 + Command::QUERY_MIN_LEVEL,
  113 + Command::QUERY_SYS_FAILURE_LEVEL,
  114 + Command::QUERY_POWER_ON_LEVEL,
  115 + Command::QUERY_FADE_TIME_OR_RATE,
  116 + Command::QUERY_ACTUAL_LEVEL };
  117 +
  118 +static const uint8_t kQueryResponse[] = {
  119 + 0,
  120 + 0,
  121 + 255,
  122 + 255,
  123 + 255,
  124 + 255,
  125 + 255,
  126 + 255,
  127 + 255,
  128 + 255,
  129 + 255,
  130 + 255,
  131 + 255,
  132 + 255,
  133 + 255,
  134 + 255,
  135 + 255,
  136 + 255,
  137 + 254,
  138 + DALI_PHISICAL_MIN_LEVEL,
  139 + 254,
  140 + 254,
  141 + 7,
  142 + 254, };
  143 +
  144 +void testReset() {
  145 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_PHISICAL_MIN_LEVEL));
  146 + TEST_ASSERT(gBus->ack == DALI_PHISICAL_MIN_LEVEL);
  147 +
  148 + for (uint16_t i = 0; i < 39; i++) {
  149 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, i + 1));
  150 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, kConfigureCommand[i]));
  151 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, kConfigureCommand[i]));
  152 + }
  153 +
  154 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  155 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  156 +
  157 + for (uint16_t i = 0; i < 24; i++) {
  158 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, kQueryCommand[i]));
  159 + TEST_ASSERT(gBus->ack == kQueryResponse[i]);
  160 + }
  161 +
  162 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_STATUS));
  163 + TEST_ASSERT((gBus->ack & 0b100000) == 0b100000);
  164 +}
  165 +
  166 +void testResetTimeoutCommandInBetween() {
  167 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  168 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  169 +
  170 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::ADD_TO_GROUP_0));
  171 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::ADD_TO_GROUP_0));
  172 +
  173 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  174 + gTimer->run(150);
  175 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  176 +
  177 + gTimer->run(300);
  178 +
  179 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_GROUPS_L));
  180 + TEST_ASSERT(gBus->ack == 0x01);
  181 +
  182 + // must be sent within 100ms
  183 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  184 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_CONTROL_GEAR));
  185 + TEST_ASSERT(gBus->ack == 0xffff);
  186 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  187 +
  188 + gTimer->run(300);
  189 +
  190 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_GROUPS_L));
  191 + TEST_ASSERT(gBus->ack == 0x01);
  192 +
  193 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::ADD_TO_GROUP_0));
  194 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::ADD_TO_GROUP_0));
  195 +
  196 + // must be sent within 100ms
  197 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  198 + gBus->handleReceivedData(gTimer->time, genData(0x80 | (5 << 1) | 0x01, Command::QUERY_CONTROL_GEAR));
  199 + TEST_ASSERT(gBus->ack == 0xffff);
  200 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  201 +
  202 + gTimer->run(300);
  203 +
  204 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_GROUPS_L));
  205 + TEST_ASSERT(gBus->ack == 0x00);
  206 +}
  207 +
  208 +void test100msTimeout() {
  209 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  210 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  211 +
  212 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_PHISICAL_MIN_LEVEL));
  213 + TEST_ASSERT(gBus->ack == DALI_PHISICAL_MIN_LEVEL);
  214 +
  215 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 1));
  216 +
  217 + for (uint16_t i = 0; i < 38; i++) {
  218 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, kConfigureCommand[i]));
  219 + gTimer->run(150);
  220 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, kConfigureCommand[i]));
  221 + }
  222 +
  223 + gTimer->run(100);
  224 +
  225 + for (uint16_t i = 0; i < 23; i++) {
  226 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, kQueryCommand[i]));
  227 + TEST_ASSERT(gBus->ack == kQueryResponse[i]);
  228 + }
  229 +
  230 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_STATUS));
  231 + TEST_ASSERT((gBus->ack & ~(1 << 6)) >> 3 == 0b100);
  232 +}
  233 +
  234 +void testCommandsInBetween() {
  235 + const uint8_t addr[] = { DALI_MASK, (5 << 1) | 1, 0x80 | (15 << 1) | 1 };
  236 +
  237 + for (uint16_t a = 0; a < 3; a++) {
  238 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  239 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  240 +
  241 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_PHISICAL_MIN_LEVEL));
  242 + TEST_ASSERT(gBus->ack == DALI_PHISICAL_MIN_LEVEL);
  243 +
  244 + // min, max level
  245 + for (uint16_t i = 32; i < 34; i++) {
  246 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, DALI_PHISICAL_MIN_LEVEL + 1));
  247 +
  248 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, kConfigureCommand[i]));
  249 + gBus->handleReceivedData(gTimer->time, genData(addr[a], Command::STEP_DOWN));
  250 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, kConfigureCommand[i]));
  251 + }
  252 +
  253 + // scene 0-15
  254 + for (uint16_t i = 16; i < 32; i++) {
  255 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 10));
  256 +
  257 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, kConfigureCommand[i]));
  258 + gBus->handleReceivedData(gTimer->time, genData(addr[a], Command::STEP_DOWN));
  259 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, kConfigureCommand[i]));
  260 + }
  261 +
  262 + // fail, powen on, fad time, fade rate level
  263 + for (uint16_t i = 34; i < 38; i++) {
  264 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 10));
  265 +
  266 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, kConfigureCommand[i]));
  267 + gBus->handleReceivedData(gTimer->time, genData(addr[a], Command::STEP_DOWN));
  268 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, kConfigureCommand[i]));
  269 + }
  270 +
  271 + // add to group 0-15
  272 + for (uint16_t i = 0; i < 16; i++) {
  273 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 10));
  274 +
  275 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, kConfigureCommand[i]));
  276 + gBus->handleReceivedData(gTimer->time, genData(addr[a], Command::STEP_DOWN));
  277 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, kConfigureCommand[i]));
  278 + }
  279 +
  280 + gTimer->run(200); // TODO if won't wait next command will be ignored. Is is OK?
  281 +
  282 + if (a == 0) {
  283 + for (uint16_t i = 0; i < 24; i++) {
  284 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, kQueryCommand[i]));
  285 + TEST_ASSERT(gBus->ack == kQueryResponse[i]);
  286 + }
  287 +
  288 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_ACTUAL_LEVEL));
  289 + TEST_ASSERT(gBus->ack == DALI_LEVEL_MAX);
  290 + } else {
  291 + // min, max level
  292 + for (uint16_t i = 18; i < 20; i++) {
  293 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, kQueryCommand[i]));
  294 + TEST_ASSERT(gBus->ack == DALI_PHISICAL_MIN_LEVEL + 1);
  295 + }
  296 +
  297 + // scene 0-15
  298 + for (uint16_t i = 2; i < 18; i++) {
  299 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, kQueryCommand[i]));
  300 + TEST_ASSERT(gBus->ack == 10);
  301 + }
  302 +
  303 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_GROUPS_L));
  304 + TEST_ASSERT(gBus->ack == 0xff);
  305 +
  306 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_GROUPS_H));
  307 + TEST_ASSERT(gBus->ack == 0xff);
  308 +
  309 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_FADE_TIME_OR_RATE));
  310 + TEST_ASSERT(gBus->ack == 0xaa);
  311 +
  312 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_SYS_FAILURE_LEVEL));
  313 + TEST_ASSERT(gBus->ack == 10);
  314 +
  315 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_POWER_ON_LEVEL));
  316 + TEST_ASSERT(gBus->ack == 10);
  317 +
  318 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_ACTUAL_LEVEL));
  319 + TEST_ASSERT(gBus->ack == DALI_PHISICAL_MIN_LEVEL + 1);
  320 + }
  321 + }
  322 +}
  323 +
  324 +void testQueryVersionNumber() {
  325 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  326 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  327 +
  328 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_VERSION_NUMBER));
  329 + TEST_ASSERT(gBus->ack == DALI_VERSION);
  330 +}
  331 +
  332 +void testStoreAcctualLevelInDtr() {
  333 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  334 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  335 +
  336 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_PHISICAL_MIN_LEVEL));
  337 + TEST_ASSERT(gBus->ack == DALI_PHISICAL_MIN_LEVEL);
  338 +
  339 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 255));
  340 +
  341 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_ACTUAL_LEVEL_IN_DTR));
  342 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_ACTUAL_LEVEL_IN_DTR));
  343 +
  344 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_CONTENT_DTR));
  345 + TEST_ASSERT(gBus->ack == DALI_LEVEL_MAX);
  346 +
  347 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::OFF));
  348 +
  349 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_ACTUAL_LEVEL_IN_DTR));
  350 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_ACTUAL_LEVEL_IN_DTR));
  351 +
  352 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_CONTENT_DTR));
  353 + TEST_ASSERT(gBus->ack == 0);
  354 +
  355 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RECALL_MIN_LEVEL));
  356 +
  357 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_ACTUAL_LEVEL_IN_DTR));
  358 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_ACTUAL_LEVEL_IN_DTR));
  359 +
  360 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_CONTENT_DTR));
  361 + TEST_ASSERT(gBus->ack == DALI_PHISICAL_MIN_LEVEL);
  362 +
  363 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RECALL_MAX_LEVEL));
  364 +
  365 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_ACTUAL_LEVEL_IN_DTR));
  366 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_ACTUAL_LEVEL_IN_DTR));
  367 +
  368 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_CONTENT_DTR));
  369 + TEST_ASSERT(gBus->ack == DALI_LEVEL_MAX);
  370 +}
  371 +
  372 +void testPresistenceMemory() {
  373 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  374 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  375 +
  376 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_PHISICAL_MIN_LEVEL));
  377 + TEST_ASSERT(gBus->ack == DALI_PHISICAL_MIN_LEVEL);
  378 +
  379 + for (uint16_t i = 0; i < 32; i++) {
  380 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 10));
  381 +
  382 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, kConfigureCommand[i]));
  383 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, kConfigureCommand[i]));
  384 + }
  385 +
  386 + // min, max level
  387 + for (uint16_t i = 32; i < 34; i++) {
  388 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, DALI_PHISICAL_MIN_LEVEL + 1));
  389 +
  390 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, kConfigureCommand[i]));
  391 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, kConfigureCommand[i]));
  392 + }
  393 +
  394 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 11));
  395 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_SHORT_ADDR));
  396 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_SHORT_ADDR));
  397 +
  398 + // fail, powen on, fad time, fade rate level
  399 + for (uint16_t i = 34; i < 38; i++) {
  400 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 11));
  401 +
  402 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, kConfigureCommand[i]));
  403 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, kConfigureCommand[i]));
  404 + }
  405 +
  406 + // fail, powen on, fad time, fade rate level
  407 + for (uint16_t i = 34; i < 38; i++) {
  408 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 10));
  409 +
  410 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, kConfigureCommand[i]));
  411 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, kConfigureCommand[i]));
  412 + }
  413 +
  414 + gSlave->notifyPowerDown();
  415 + delete gSlave; // simulate power off
  416 + gSlave = gCreateSlave(gMemory, gLamp, gBus, gTimer);
  417 + TEST_ASSERT(gSlave != nullptr);
  418 +
  419 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_GROUPS_L));
  420 + TEST_ASSERT(gBus->ack == 0xff);
  421 +
  422 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_GROUPS_H));
  423 + TEST_ASSERT(gBus->ack == 0xff);
  424 +
  425 + for (uint16_t i = 2; i < 18; i++) {
  426 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, kQueryCommand[i]));
  427 + TEST_ASSERT(gBus->ack == 10);
  428 + }
  429 +
  430 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_POWER_ON_LEVEL));
  431 + TEST_ASSERT(gBus->ack == 10);
  432 +
  433 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_SYS_FAILURE_LEVEL));
  434 + TEST_ASSERT(gBus->ack == 10);
  435 +
  436 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_FADE_TIME_OR_RATE));
  437 + TEST_ASSERT(gBus->ack == 0xaa);
  438 +
  439 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_MAX_LEVEL));
  440 + TEST_ASSERT(gBus->ack == DALI_PHISICAL_MIN_LEVEL + 1);
  441 +
  442 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_MIN_LEVEL));
  443 + TEST_ASSERT(gBus->ack == DALI_PHISICAL_MIN_LEVEL + 1);
  444 +}
  445 +
  446 +void testSequenceDtr1() {
  447 + const uint8_t level[] = { 0, 1, DALI_PHISICAL_MIN_LEVEL, (DALI_PHISICAL_MIN_LEVEL + 254) / 2, 254, 255, 0 };
  448 +
  449 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  450 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  451 +
  452 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_PHISICAL_MIN_LEVEL));
  453 + TEST_ASSERT(gBus->ack == DALI_PHISICAL_MIN_LEVEL);
  454 +
  455 + for (uint16_t i = 0; i < 7; i++) {
  456 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_1, level[i]));
  457 +
  458 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_CONTENT_DTR1));
  459 + TEST_ASSERT(gBus->ack == level[i]);
  460 + }
  461 +}
  462 +
  463 +void testSequenceDtr2() {
  464 + const uint8_t level[] = { 0, 1, DALI_PHISICAL_MIN_LEVEL, (DALI_PHISICAL_MIN_LEVEL + 254) / 2, 254, 255, 0 };
  465 +
  466 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  467 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  468 +
  469 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_PHISICAL_MIN_LEVEL));
  470 + TEST_ASSERT(gBus->ack == DALI_PHISICAL_MIN_LEVEL);
  471 +
  472 + for (uint16_t i = 0; i < 7; i++) {
  473 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_2, level[i]));
  474 +
  475 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_CONTENT_DTR2));
  476 + TEST_ASSERT(gBus->ack == level[i]);
  477 + }
  478 +}
  479 +
  480 +void testStoreDtrAsMaxLevel() {
  481 + const uint8_t value[] = { 255, 0, 253 };
  482 + const uint8_t max[] = { 254, DALI_PHISICAL_MIN_LEVEL + 1, 253 };
  483 + const uint8_t level[] = { 254, DALI_PHISICAL_MIN_LEVEL + 1, DALI_PHISICAL_MIN_LEVEL + 1 };
  484 +
  485 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  486 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  487 +
  488 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_PHISICAL_MIN_LEVEL));
  489 + TEST_ASSERT(gBus->ack == DALI_PHISICAL_MIN_LEVEL);
  490 +
  491 + for (uint16_t i = 0; i < 3; i++) {
  492 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, DALI_PHISICAL_MIN_LEVEL + 1));
  493 +
  494 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_MIN_LEVEL));
  495 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_MIN_LEVEL));
  496 +
  497 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_RESET_STATE));
  498 + TEST_ASSERT(gBus->ack == 0xffff);
  499 +
  500 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_STATUS));
  501 + TEST_ASSERT(gBus->ack != 0xffff && (gBus->ack & 0b00100000) == 0);
  502 +
  503 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, value[i]));
  504 +
  505 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_MAX_LEVEL));
  506 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_MAX_LEVEL));
  507 +
  508 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_MAX_LEVEL));
  509 + TEST_ASSERT(gBus->ack == max[i]);
  510 +
  511 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_ACTUAL_LEVEL));
  512 + TEST_ASSERT(gBus->ack == level[i]);
  513 + }
  514 +}
  515 +
  516 +void testStoreDtrAsMinLevel() {
  517 + const uint8_t value[] = { DALI_PHISICAL_MIN_LEVEL + 1, 254, 0 };
  518 + const uint8_t min[] = { DALI_PHISICAL_MIN_LEVEL + 1, 253, DALI_PHISICAL_MIN_LEVEL };
  519 + const uint8_t level[] = { DALI_PHISICAL_MIN_LEVEL + 1, 253, 253 };
  520 +
  521 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  522 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  523 +
  524 + gBus->handleReceivedData(gTimer->time, genDataDPC(DALI_MASK, DALI_PHISICAL_MIN_LEVEL)); // TODO test i==0 expects actual level at min
  525 +
  526 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_PHISICAL_MIN_LEVEL));
  527 + TEST_ASSERT(gBus->ack == DALI_PHISICAL_MIN_LEVEL);
  528 +
  529 + for (uint16_t i = 0; i < 3; i++) {
  530 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 253));
  531 +
  532 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_MAX_LEVEL));
  533 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_MAX_LEVEL));
  534 +
  535 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_RESET_STATE));
  536 + TEST_ASSERT(gBus->ack == 0xffff);
  537 +
  538 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_STATUS));
  539 + TEST_ASSERT(gBus->ack != 0xffff && (gBus->ack & 0b00100000) == 0);
  540 +
  541 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, value[i]));
  542 +
  543 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_MIN_LEVEL));
  544 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_MIN_LEVEL));
  545 +
  546 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_MIN_LEVEL));
  547 + TEST_ASSERT(gBus->ack == min[i]);
  548 +
  549 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_ACTUAL_LEVEL));
  550 + TEST_ASSERT(gBus->ack == level[i]);
  551 + }
  552 +}
  553 +
  554 +void testStoreDtrAsSysFailureLevel() {
  555 + const uint8_t value[] = { 252, 255, 254, 0, 1 };
  556 + const uint8_t sys[] = { 252, 255, 254, 0, 1 };
  557 + const uint8_t level[] = { 252, 252, 253, 0, DALI_PHISICAL_MIN_LEVEL + 1 };
  558 +
  559 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  560 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  561 +
  562 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_PHISICAL_MIN_LEVEL));
  563 + TEST_ASSERT(gBus->ack == DALI_PHISICAL_MIN_LEVEL);
  564 +
  565 + for (uint16_t i = 0; i < 5; i++) {
  566 +
  567 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 253));
  568 +
  569 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_MAX_LEVEL));
  570 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_MAX_LEVEL));
  571 +
  572 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, DALI_PHISICAL_MIN_LEVEL + 1));
  573 +
  574 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_MIN_LEVEL));
  575 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_MIN_LEVEL));
  576 +
  577 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, value[i]));
  578 +
  579 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_SYS_FAIL_LEVEL));
  580 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_SYS_FAIL_LEVEL));
  581 +
  582 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_SYS_FAILURE_LEVEL));
  583 + TEST_ASSERT(gBus->ack == sys[i]);
  584 +
  585 + gBus->setState(IBus::IBusState::DISCONNECTED); // disconnect interface
  586 +
  587 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_ACTUAL_LEVEL));
  588 + TEST_ASSERT(gBus->ack == level[i]);
  589 +
  590 + gBus->setState(IBus::IBusState::CONNECTED); // disconnect interface
  591 +
  592 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_ACTUAL_LEVEL));
  593 + TEST_ASSERT(gBus->ack == level[i]);
  594 + }
  595 +}
  596 +
  597 +void testStoreDtrAsPowerOnLevel() {
  598 + const uint8_t mid = (DALI_PHISICAL_MIN_LEVEL + 254) / 2;
  599 + const uint8_t value[] = { 0, mid, 255 };
  600 + const uint8_t power[] = { 0, mid, 255 };
  601 + const uint8_t level[] = { 0, mid, DALI_PHISICAL_MIN_LEVEL };
  602 +
  603 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  604 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  605 +
  606 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_PHISICAL_MIN_LEVEL));
  607 + TEST_ASSERT(gBus->ack == DALI_PHISICAL_MIN_LEVEL);
  608 +
  609 + for (uint16_t i = 0; i < 3; i++) {
  610 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, value[i]));
  611 +
  612 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_POWER_ON_LEVEL));
  613 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_POWER_ON_LEVEL));
  614 +
  615 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_POWER_ON_LEVEL));
  616 + TEST_ASSERT(gBus->ack == power[i]);
  617 +
  618 + gSlave->notifyPowerDown();
  619 + delete gSlave; // simulate power off
  620 + gSlave = gCreateSlave(gMemory, gLamp, gBus, gTimer);
  621 + TEST_ASSERT(gSlave != nullptr);
  622 +
  623 + gSlave->notifyPowerUp();
  624 +
  625 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_ACTUAL_LEVEL));
  626 + TEST_ASSERT(gBus->ack == level[i]);
  627 + }
  628 +}
  629 +
  630 +void testStoreDtrAsFadeTime() {
  631 + const uint8_t value[] = { 15, 0, 5, 128 };
  632 + const uint8_t fadeRateTime[] = { 0xf7, 0x07, 0x57, 0xF7 };
  633 +
  634 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  635 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  636 +
  637 + for (uint16_t i = 0; i < 4; i++) {
  638 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, value[i]));
  639 +
  640 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_FADE_TIME));
  641 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_FADE_TIME));
  642 +
  643 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_FADE_TIME_OR_RATE));
  644 + TEST_ASSERT(gBus->ack == fadeRateTime[i]);
  645 + }
  646 +
  647 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_RESET_STATE));
  648 + TEST_ASSERT(gBus->ack == 0xffff);
  649 +
  650 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_STATUS));
  651 + TEST_ASSERT(gBus->ack != 0xffff && (gBus->ack & 0b00100000) == 0);
  652 +}
  653 +
  654 +void testStoreDtrAsFadeRate() {
  655 + const uint8_t value[] = { 15, 0, 5, 128, 1 };
  656 + const uint8_t fadeRateTime[] = { 0x0F, 0x01, 0x05, 0x0F, 0x01 };
  657 +
  658 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  659 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  660 +
  661 + for (uint16_t i = 0; i < 5; i++) {
  662 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, value[i]));
  663 +
  664 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_FADE_RATE));
  665 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_FADE_RATE));
  666 +
  667 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_FADE_TIME_OR_RATE));
  668 + TEST_ASSERT(gBus->ack == fadeRateTime[i]);
  669 + }
  670 +
  671 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_RESET_STATE));
  672 + TEST_ASSERT(gBus->ack == 0xffff);
  673 +
  674 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_STATUS));
  675 + TEST_ASSERT(gBus->ack != 0xffff && (gBus->ack & 0b00100000) == 0);
  676 +}
  677 +
  678 +void testStoreDtrAsSceneGoToScene() {
  679 + const uint8_t value[] = { 1, 0, 255, 252, 254 };
  680 + const uint8_t scene[] = { 1, 0, 255, 252, 254 };
  681 + const uint8_t level[] = { DALI_PHISICAL_MIN_LEVEL + 1, 0, 0, 252, 253 };
  682 +
  683 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  684 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  685 +
  686 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_PHISICAL_MIN_LEVEL));
  687 + TEST_ASSERT(gBus->ack == DALI_PHISICAL_MIN_LEVEL);
  688 +
  689 + for (uint16_t i = 0; i < 16; i++) {
  690 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 253));
  691 +
  692 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_MAX_LEVEL));
  693 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_MAX_LEVEL));
  694 +
  695 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, DALI_PHISICAL_MIN_LEVEL + 1));
  696 +
  697 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_MIN_LEVEL));
  698 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_MIN_LEVEL));
  699 +
  700 + Command storeDtrAsScene = (Command) ((uint16_t) Command::STORE_DTR_AS_SCENE_0 + i);
  701 + Command querySceneLevel = (Command) ((uint16_t) Command::QUERY_SCENE_0_LEVEL + i);
  702 + Command goToScene = (Command) ((uint16_t) Command::GO_TO_SCENE_0 + i);
  703 +
  704 + for (uint16_t k = 0; k < 5; k++) {
  705 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, value[k]));
  706 +
  707 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, storeDtrAsScene));
  708 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, storeDtrAsScene));
  709 +
  710 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, querySceneLevel));
  711 + TEST_ASSERT(gBus->ack == scene[k]);
  712 +
  713 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, goToScene));
  714 +
  715 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_ACTUAL_LEVEL));
  716 + TEST_ASSERT(gBus->ack == level[k]);
  717 + }
  718 + }
  719 +}
  720 +
  721 +void testRemoveFromScene() {
  722 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  723 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  724 +
  725 + for (uint16_t i = 0; i < 16; i++) {
  726 + Command storeDtrAsScene = (Command) ((uint16_t) Command::STORE_DTR_AS_SCENE_0 + i);
  727 + Command removeFromScene = (Command) ((uint16_t) Command::REMOVE_FROM_SCENE_0 + i);
  728 +
  729 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 127));
  730 +
  731 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, storeDtrAsScene));
  732 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, storeDtrAsScene));
  733 +
  734 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_RESET_STATE));
  735 + TEST_ASSERT(gBus->ack == 0xffff);
  736 +
  737 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_STATUS));
  738 + TEST_ASSERT(gBus->ack != 0xffff && (gBus->ack & 0b00100000) == 0);
  739 +
  740 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, removeFromScene));
  741 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, removeFromScene));
  742 +
  743 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_RESET_STATE));
  744 + TEST_ASSERT(gBus->ack == 0xff);
  745 +
  746 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_STATUS));
  747 + TEST_ASSERT(gBus->ack != 0xffff && (gBus->ack & 0b00100000) != 0);
  748 + }
  749 +}
  750 +
  751 +void testAddToGroupRemoveFromGroup() {
  752 + const uint8_t group[] = { 1, 2, 4, 8, 16, 32, 64, 128, 1, 2, 4, 8, 16, 32, 64, 128 };
  753 +
  754 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  755 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  756 +
  757 + for (uint16_t i = 0; i < 16; i++) {
  758 + Command addToGroup = Command((uint16_t) Command::ADD_TO_GROUP_0 + i);
  759 + Command removeFromGroup = Command((uint16_t) Command::REMOVE_FROM_GROUP_0 + i);
  760 + uint8_t groupAddr = (i << 1) | 0x81;
  761 +
  762 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, addToGroup));
  763 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, addToGroup));
  764 +
  765 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_RESET_STATE));
  766 + TEST_ASSERT(gBus->ack == 0xffff);
  767 +
  768 + gBus->handleReceivedData(gTimer->time, genData(groupAddr, Command::QUERY_STATUS));
  769 + TEST_ASSERT(gBus->ack != 0xffff && (gBus->ack & 0b00100000) == 0);
  770 +
  771 + if (i <= 7) {
  772 + gBus->handleReceivedData(gTimer->time, genData(groupAddr, Command::QUERY_GROUPS_L));
  773 + } else {
  774 + gBus->handleReceivedData(gTimer->time, genData(groupAddr, Command::QUERY_GROUPS_H));
  775 + }
  776 + TEST_ASSERT(gBus->ack == group[i]);
  777 +
  778 + gBus->handleReceivedData(gTimer->time, genData(groupAddr, removeFromGroup));
  779 + gBus->handleReceivedData(gTimer->time, genData(groupAddr, removeFromGroup));
  780 +
  781 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_RESET_STATE));
  782 + TEST_ASSERT(gBus->ack == 0xff);
  783 +
  784 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_STATUS));
  785 + TEST_ASSERT(gBus->ack != 0xffff && (gBus->ack & 0b00100000) != 0);
  786 + }
  787 +}
  788 +
  789 +void testStoreDtrAsShortAddr() {
  790 + const uint8_t value[] = { 3, 127, 31, 129, 30, 1, 255 };
  791 + const uint8_t addr1[] = { DALI_MASK, 1, 63, 15, 15, 15, 0 };
  792 + const uint8_t addr2[] = { 1, 63, 15, 15, 15, 0, 255 };
  793 + const uint16_t test1[] = { 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xff };
  794 +
  795 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  796 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  797 +
  798 + for (uint16_t i = 0; i < 7; i++) {
  799 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, value[i]));
  800 +
  801 + gBus->handleReceivedData(gTimer->time, genData(addr1[i] << 1, Command::STORE_DTR_AS_SHORT_ADDR));
  802 + gBus->handleReceivedData(gTimer->time, genData(addr1[i] << 1, Command::STORE_DTR_AS_SHORT_ADDR));
  803 +
  804 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_MISSING_SHORT_ADDR));
  805 + TEST_ASSERT(gBus->ack == test1[i]);
  806 +
  807 + gBus->handleReceivedData(gTimer->time, genData(addr2[i] << 1, Command::QUERY_STATUS));
  808 + if (test1[i] == 0xff) {
  809 + TEST_ASSERT(gBus->ack != 0xffff && (gBus->ack & 0b01000000) != 0);
  810 + } else {
  811 + TEST_ASSERT(gBus->ack != 0xffff && (gBus->ack & 0b01000000) == 0);
  812 + }
  813 + }
  814 +
  815 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 3));
  816 +
  817 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_SHORT_ADDR));
  818 + gTimer->run(150);
  819 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_SHORT_ADDR));
  820 +
  821 + gBus->handleReceivedData(gTimer->time, genData(1 << 1, Command::QUERY_CONTROL_GEAR));
  822 + TEST_ASSERT(gBus->ack == 0xffff);
  823 +
  824 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 5));
  825 +
  826 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_SHORT_ADDR));
  827 +
  828 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_CONTROL_GEAR));
  829 + TEST_ASSERT(gBus->ack == 0xffff);
  830 +
  831 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_SHORT_ADDR));
  832 +
  833 + gTimer->run(200); // TODO if won't wait next command will be ignored. Is is OK?
  834 +
  835 + gBus->handleReceivedData(gTimer->time, genData(2 << 1, Command::QUERY_CONTROL_GEAR));
  836 + TEST_ASSERT(gBus->ack == 0xffff);
  837 +
  838 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 7));
  839 +
  840 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_SHORT_ADDR));
  841 +
  842 + gBus->handleReceivedData(gTimer->time, genData(9 << 1, Command::QUERY_CONTROL_GEAR));
  843 + TEST_ASSERT(gBus->ack == 0xffff);
  844 +
  845 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_SHORT_ADDR));
  846 +
  847 + gBus->handleReceivedData(gTimer->time, genData(3 << 1, Command::QUERY_CONTROL_GEAR));
  848 + TEST_ASSERT(gBus->ack == 0xff);
  849 +
  850 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, DALI_MASK));
  851 +
  852 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_SHORT_ADDR));
  853 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_SHORT_ADDR));
  854 +
  855 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_STATUS));
  856 + TEST_ASSERT(gBus->ack != 0xffff && (gBus->ack & 0b01000000) != 0);
  857 +}
  858 +
  859 +void testMemoryBank0() {
  860 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 0)); // addr
  861 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_1, 0)); // bank
  862 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_2, 0)); // data
  863 +
  864 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::READ_MEMORY_LOCATION));
  865 + TEST_ASSERT(gBus->ack == 15);
  866 +
  867 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_CONTENT_DTR));
  868 + TEST_ASSERT(gBus->ack == 1);
  869 +
  870 + uint8_t checksum = 0;
  871 + for (uint16_t i = 0; i < 15; i++) {
  872 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_CONTENT_DTR2));
  873 + TEST_ASSERT(gBus->ack != 0xffff);
  874 + uint8_t next = (uint8_t) gBus->ack;
  875 +
  876 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::READ_MEMORY_LOCATION));
  877 + TEST_ASSERT(gBus->ack != 0xffff);
  878 + uint8_t answer = (uint8_t) gBus->ack;
  879 + TEST_ASSERT(answer == next);
  880 + checksum += answer;
  881 + }
  882 +
  883 + TEST_ASSERT(checksum == 0);
  884 +
  885 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::READ_MEMORY_LOCATION));
  886 + TEST_ASSERT(gBus->ack == 0xffff);
  887 +
  888 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 5));
  889 +
  890 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::READ_MEMORY_LOCATION));
  891 + TEST_ASSERT(gBus->ack != 0xffff);
  892 + uint8_t value = 255 - (uint8_t) gBus->ack;
  893 +
  894 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 5));
  895 +
  896 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::ENABLE_WRITE_MEMORY));
  897 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::ENABLE_WRITE_MEMORY));
  898 +
  899 + gBus->handleReceivedData(gTimer->time, genData(Command::WRITE_MEMORY_LOCATION, value));
  900 + TEST_ASSERT(gBus->ack == 0xffff);
  901 +
  902 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 5));
  903 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::READ_MEMORY_LOCATION));
  904 + TEST_ASSERT(gBus->ack != 0xffff);
  905 + TEST_ASSERT((uint8_t ) gBus->ack != value);
  906 +}
  907 +
  908 +void testMemoryBank1() {
  909 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 2)); // addr
  910 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_1, 0)); // bank
  911 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_2, 0)); // data
  912 +
  913 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::READ_MEMORY_LOCATION));
  914 + TEST_ASSERT(gBus->ack != 0xffff);
  915 + TEST_ASSERT(gBus->ack > 0);
  916 +
  917 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 0)); // addr
  918 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_1, 1)); // bank
  919 +
  920 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::READ_MEMORY_LOCATION));
  921 + TEST_ASSERT(gBus->ack != 0xffff);
  922 + uint16_t size = (uint8_t) gBus->ack;
  923 +
  924 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 2)); // addr
  925 +
  926 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::ENABLE_WRITE_MEMORY));
  927 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::ENABLE_WRITE_MEMORY));
  928 +
  929 + gBus->handleReceivedData(gTimer->time, genData(Command::WRITE_MEMORY_LOCATION, 0x55));
  930 + TEST_ASSERT(gBus->ack == 0x55);
  931 +
  932 + for (uint8_t i = 3; i <= size; i++) {
  933 + uint8_t value = 255 - i;
  934 + gBus->handleReceivedData(gTimer->time, genData(Command::WRITE_MEMORY_LOCATION, value));
  935 + TEST_ASSERT(gBus->ack != 0xffff);
  936 + TEST_ASSERT((uint8_t )gBus->ack == value);
  937 + }
  938 +
  939 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 1)); // addr
  940 +
  941 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::READ_MEMORY_LOCATION));
  942 + TEST_ASSERT(gBus->ack != 0xffff);
  943 + uint8_t checksum = (uint8_t) gBus->ack;
  944 +
  945 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::READ_MEMORY_LOCATION));
  946 + TEST_ASSERT(gBus->ack == 0x55);
  947 +
  948 + checksum += (uint8_t) gBus->ack;
  949 +
  950 + for (uint8_t i = 3; i <= size; i++) {
  951 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::READ_MEMORY_LOCATION));
  952 + TEST_ASSERT(gBus->ack == 255 - i);
  953 + checksum += (uint8_t) gBus->ack;
  954 + }
  955 +
  956 + TEST_ASSERT(checksum == 0);
  957 +}
  958 +
  959 +void testOtherMemoryBanks() {
  960 + // TODO write tests
  961 +}
  962 +
  963 +void testEnableWriteMemory() {
  964 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 2)); // addr
  965 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_1, 0)); // bank
  966 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_2, 0)); // data
  967 +
  968 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::READ_MEMORY_LOCATION));
  969 + TEST_ASSERT(gBus->ack != 0xffff);
  970 + TEST_ASSERT(gBus->ack > 0);
  971 +
  972 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 2)); // addr
  973 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_1, 1)); // bank
  974 +
  975 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::ENABLE_WRITE_MEMORY));
  976 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::ENABLE_WRITE_MEMORY));
  977 +
  978 + gBus->handleReceivedData(gTimer->time, genData(Command::WRITE_MEMORY_LOCATION, 0x55));
  979 + TEST_ASSERT(gBus->ack == 0x55);
  980 +
  981 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 2)); // addr
  982 +
  983 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::READ_MEMORY_LOCATION));
  984 + TEST_ASSERT(gBus->ack == 0x55);
  985 +
  986 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 2)); // addr
  987 +
  988 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::ENABLE_WRITE_MEMORY));
  989 +
  990 + gBus->handleReceivedData(gTimer->time, genData(Command::WRITE_MEMORY_LOCATION, 0x05));
  991 + TEST_ASSERT(gBus->ack == 0xffff);
  992 +
  993 + gTimer->run(200); // TODO if won't wait next command will be ignored. Is is OK?
  994 +
  995 + uint8_t addr[] = { DALI_MASK, 0x81 };
  996 + uint16_t write[] = { 0xffff, 0x01 };
  997 + uint16_t read[] = { 0x55, 0x01 };
  998 +
  999 + for (uint8_t i = 0; i < 2; ++i) {
  1000 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 2)); // addr
  1001 +
  1002 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::ENABLE_WRITE_MEMORY));
  1003 + gBus->handleReceivedData(gTimer->time, genData(addr[i], Command::RECALL_MIN_LEVEL));
  1004 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::ENABLE_WRITE_MEMORY));
  1005 +
  1006 + gBus->handleReceivedData(gTimer->time, genData(Command::WRITE_MEMORY_LOCATION, i));
  1007 + TEST_ASSERT(gBus->ack == write[i]);
  1008 +
  1009 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 2)); // addr
  1010 +
  1011 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::READ_MEMORY_LOCATION));
  1012 + TEST_ASSERT(gBus->ack == read[i]);
  1013 + }
  1014 +
  1015 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::ENABLE_WRITE_MEMORY));
  1016 + gTimer->run(150);
  1017 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::ENABLE_WRITE_MEMORY));
  1018 +
  1019 + gBus->handleReceivedData(gTimer->time, genData(Command::WRITE_MEMORY_LOCATION, 0x02));
  1020 + TEST_ASSERT(gBus->ack == 0xffff);
  1021 +
  1022 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::ENABLE_WRITE_MEMORY));
  1023 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::ENABLE_WRITE_MEMORY));
  1024 +
  1025 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RECALL_MIN_LEVEL));
  1026 +
  1027 + gBus->handleReceivedData(gTimer->time, genData(Command::WRITE_MEMORY_LOCATION, 0x03));
  1028 + TEST_ASSERT(gBus->ack == 0xffff);
  1029 +}
  1030 +
  1031 +void randomizeAddress(uint8_t& x, uint8_t& y, uint8_t& z) {
  1032 + uint8_t i = 0;
  1033 + for (; i <= 50; ++i) {
  1034 + gBus->handleReceivedData(gTimer->time, genData(Command::RANDOMISE, 0));
  1035 + gBus->handleReceivedData(gTimer->time, genData(Command::RANDOMISE, 0));
  1036 +
  1037 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_RANDOM_ADDR_H));
  1038 + TEST_ASSERT(gBus->ack != 0xffff);
  1039 + x = (uint8_t) gBus->ack;
  1040 +
  1041 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_RANDOM_ADDR_M));
  1042 + TEST_ASSERT(gBus->ack != 0xffff);
  1043 + y = (uint8_t) gBus->ack;
  1044 +
  1045 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_RANDOM_ADDR_L));
  1046 + TEST_ASSERT(gBus->ack != 0xffff);
  1047 + z = (uint8_t) gBus->ack;
  1048 + if ((x != 0) && (x != 255) && (y != 0) && (y != 255) && (z != 0) && (z != 255)) {
  1049 + break;
  1050 + }
  1051 + }
  1052 +}
  1053 +
  1054 +void compareCheck(uint8_t r, uint8_t s, uint8_t t, uint16_t ack) {
  1055 + gBus->handleReceivedData(gTimer->time, genData(Command::SEARCHADDRH, r));
  1056 + gBus->handleReceivedData(gTimer->time, genData(Command::SEARCHADDRM, s));
  1057 + gBus->handleReceivedData(gTimer->time, genData(Command::SEARCHADDRL, t));
  1058 +
  1059 + gBus->handleReceivedData(gTimer->time, genData(Command::COMPARE));
  1060 + TEST_ASSERT(gBus->ack == ack);
  1061 +}
  1062 +
  1063 +void withdrawCheck(uint8_t r, uint8_t s, uint8_t t, uint8_t x, uint8_t y, uint8_t z, uint16_t ack) {
  1064 + gBus->handleReceivedData(gTimer->time, genData(Command::SEARCHADDRH, r));
  1065 + gBus->handleReceivedData(gTimer->time, genData(Command::SEARCHADDRM, s));
  1066 + gBus->handleReceivedData(gTimer->time, genData(Command::SEARCHADDRL, t));
  1067 +
  1068 + gBus->handleReceivedData(gTimer->time, genData(Command::WITHDRAW, 0));
  1069 +
  1070 + gBus->handleReceivedData(gTimer->time, genData(Command::SEARCHADDRH, x));
  1071 + gBus->handleReceivedData(gTimer->time, genData(Command::SEARCHADDRM, y));
  1072 + gBus->handleReceivedData(gTimer->time, genData(Command::SEARCHADDRL, z));
  1073 +
  1074 + gBus->handleReceivedData(gTimer->time, genData(Command::COMPARE, 0));
  1075 + TEST_ASSERT(gBus->ack == ack);
  1076 +}
  1077 +
  1078 +void queryShortAddrCheck(uint8_t r, uint8_t s, uint8_t t, uint16_t ack) {
  1079 + gBus->handleReceivedData(gTimer->time, genData(Command::SEARCHADDRH, r));
  1080 + gBus->handleReceivedData(gTimer->time, genData(Command::SEARCHADDRM, s));
  1081 + gBus->handleReceivedData(gTimer->time, genData(Command::SEARCHADDRL, t));
  1082 +
  1083 + gBus->handleReceivedData(gTimer->time, genData(Command::QUERY_SHORT_ADDRESS));
  1084 + TEST_ASSERT(gBus->ack == ack);
  1085 +}
  1086 +
  1087 +void programShortAddrCheck(uint8_t r, uint8_t s, uint8_t t, uint8_t a, uint16_t ack) {
  1088 + gBus->handleReceivedData(gTimer->time, genData(Command::SEARCHADDRH, r));
  1089 + gBus->handleReceivedData(gTimer->time, genData(Command::SEARCHADDRM, s));
  1090 + gBus->handleReceivedData(gTimer->time, genData(Command::SEARCHADDRL, t));
  1091 +
  1092 + gBus->handleReceivedData(gTimer->time, genData(Command::PROGRAM_SHORT_ADDRESS, a));
  1093 +
  1094 + gBus->handleReceivedData(gTimer->time, genData(a, Command::QUERY_CONTROL_GEAR));
  1095 + TEST_ASSERT(gBus->ack == ack);
  1096 +}
  1097 +
  1098 +void testPhisicalAddressAllocation() {
  1099 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  1100 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  1101 +
  1102 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 255));
  1103 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_SHORT_ADDR));
  1104 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_SHORT_ADDR));
  1105 +
  1106 + gBus->handleReceivedData(gTimer->time, genData(Command::INITIALISE, 0));
  1107 + gBus->handleReceivedData(gTimer->time, genData(Command::INITIALISE, 0));
  1108 +
  1109 + // >> TODO not in test scenario but randomAddr and searchAddr is 0xffffff so QUERY SHORT ADDRESS will answer
  1110 + gBus->handleReceivedData(gTimer->time, genData(Command::RANDOMISE));
  1111 + gBus->handleReceivedData(gTimer->time, genData(Command::RANDOMISE));
  1112 + // <<
  1113 +
  1114 + gBus->handleReceivedData(gTimer->time, genData(Command::PHYSICAL_SELECTION));
  1115 +
  1116 + gBus->handleReceivedData(gTimer->time, genData(Command::QUERY_SHORT_ADDRESS));
  1117 + TEST_ASSERT(gBus->ack == 0xffff);
  1118 +
  1119 + // simulate lamp disconnect
  1120 + gLamp->setState(ILamp::ILampState::DISCONNECTED);
  1121 +
  1122 + // >> 10s timeout
  1123 + gBus->handleReceivedData(gTimer->time, genData(Command::QUERY_SHORT_ADDRESS));
  1124 + TEST_ASSERT(gBus->ack == 0xff);
  1125 + // << 10s timeout
  1126 +
  1127 + gBus->handleReceivedData(gTimer->time, genData(Command::PROGRAM_SHORT_ADDRESS, 1));
  1128 +
  1129 + gBus->handleReceivedData(gTimer->time, genData(0, Command::QUERY_CONTROL_GEAR));
  1130 + TEST_ASSERT(gBus->ack == 0xff);
  1131 +
  1132 + // simulate lamp connect
  1133 + gLamp->setState(ILamp::ILampState::OK);
  1134 +
  1135 + gBus->handleReceivedData(gTimer->time, genData(Command::PHYSICAL_SELECTION));
  1136 +
  1137 + gBus->handleReceivedData(gTimer->time, genData(Command::QUERY_SHORT_ADDRESS));
  1138 + TEST_ASSERT(gBus->ack == 0xffff);
  1139 +
  1140 + gBus->handleReceivedData(gTimer->time, genData(Command::TERMINATE));
  1141 +
  1142 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 255));
  1143 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_SHORT_ADDR));
  1144 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_SHORT_ADDR));
  1145 +
  1146 + gBus->handleReceivedData(gTimer->time, genData(Command::TERMINATE));
  1147 +}
  1148 +
  1149 +void testInitialize15min() {
  1150 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  1151 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  1152 +
  1153 + gBus->handleReceivedData(gTimer->time, genData(Command::TERMINATE));
  1154 +
  1155 + gBus->handleReceivedData(gTimer->time, genData(Command::QUERY_SHORT_ADDRESS));
  1156 + TEST_ASSERT(gBus->ack == 0xffff);
  1157 +
  1158 + gBus->handleReceivedData(gTimer->time, genData(Command::INITIALISE, 0));
  1159 + gBus->handleReceivedData(gTimer->time, genData(Command::INITIALISE, 0));
  1160 +
  1161 + gBus->handleReceivedData(gTimer->time, genData(Command::QUERY_SHORT_ADDRESS));
  1162 + TEST_ASSERT(gBus->ack == 0xff);
  1163 +
  1164 + gTimer->run(1000 * 60 * 60 * 13); // 13min
  1165 +
  1166 + gBus->handleReceivedData(gTimer->time, genData(Command::QUERY_SHORT_ADDRESS));
  1167 + TEST_ASSERT(gBus->ack == 0xff);
  1168 +
  1169 + gTimer->run(1000 * 60 * 60 * 4); // 4min
  1170 +
  1171 + gBus->handleReceivedData(gTimer->time, genData(Command::QUERY_SHORT_ADDRESS));
  1172 + TEST_ASSERT(gBus->ack == 0xffff);
  1173 +
  1174 + gBus->handleReceivedData(gTimer->time, genData(Command::TERMINATE));
  1175 +}
  1176 +
  1177 +void testTerminate() {
  1178 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  1179 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  1180 +
  1181 + gBus->handleReceivedData(gTimer->time, genData(Command::TERMINATE));
  1182 +
  1183 + gBus->handleReceivedData(gTimer->time, genData(Command::INITIALISE, 0));
  1184 + gBus->handleReceivedData(gTimer->time, genData(Command::INITIALISE, 0));
  1185 +
  1186 + gBus->handleReceivedData(gTimer->time, genData(Command::QUERY_SHORT_ADDRESS));
  1187 + TEST_ASSERT(gBus->ack == 0xff);
  1188 +
  1189 + gBus->handleReceivedData(gTimer->time, genData(Command::TERMINATE));
  1190 +
  1191 + gBus->handleReceivedData(gTimer->time, genData(Command::QUERY_SHORT_ADDRESS));
  1192 + TEST_ASSERT(gBus->ack == 0xffff);
  1193 +}
  1194 +
  1195 +void testInitializeShortAddr() {
  1196 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  1197 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  1198 +
  1199 + gBus->handleReceivedData(gTimer->time, genData(Command::TERMINATE));
  1200 +
  1201 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 3));
  1202 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_SHORT_ADDR));
  1203 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_SHORT_ADDR));
  1204 +
  1205 + gBus->handleReceivedData(gTimer->time, genData(Command::INITIALISE, 5));
  1206 + gBus->handleReceivedData(gTimer->time, genData(Command::INITIALISE, 5));
  1207 +
  1208 + gBus->handleReceivedData(gTimer->time, genData(Command::QUERY_SHORT_ADDRESS));
  1209 + TEST_ASSERT(gBus->ack == 0xffff);
  1210 +
  1211 + gBus->handleReceivedData(gTimer->time, genData(Command::TERMINATE));
  1212 +
  1213 + gBus->handleReceivedData(gTimer->time, genData(Command::INITIALISE, 255));
  1214 + gBus->handleReceivedData(gTimer->time, genData(Command::INITIALISE, 255));
  1215 +
  1216 + gBus->handleReceivedData(gTimer->time, genData(Command::QUERY_SHORT_ADDRESS));
  1217 + TEST_ASSERT(gBus->ack == 0xffff);
  1218 +
  1219 + gBus->handleReceivedData(gTimer->time, genData(Command::TERMINATE));
  1220 +
  1221 + gBus->handleReceivedData(gTimer->time, genData(Command::INITIALISE, 3));
  1222 + gBus->handleReceivedData(gTimer->time, genData(Command::INITIALISE, 3));
  1223 +
  1224 + gBus->handleReceivedData(gTimer->time, genData(Command::QUERY_SHORT_ADDRESS));
  1225 + TEST_ASSERT(gBus->ack == 3);
  1226 +
  1227 + gBus->handleReceivedData(gTimer->time, genData(Command::TERMINATE));
  1228 +}
  1229 +
  1230 +void testInitializeNoShortAddr() {
  1231 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  1232 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  1233 +
  1234 + gBus->handleReceivedData(gTimer->time, genData(Command::TERMINATE));
  1235 +
  1236 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 255));
  1237 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_SHORT_ADDR));
  1238 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_SHORT_ADDR));
  1239 +
  1240 + gBus->handleReceivedData(gTimer->time, genData(Command::INITIALISE, 5));
  1241 + gBus->handleReceivedData(gTimer->time, genData(Command::INITIALISE, 5));
  1242 +
  1243 + gBus->handleReceivedData(gTimer->time, genData(Command::QUERY_SHORT_ADDRESS));
  1244 + TEST_ASSERT(gBus->ack == 0xffff);
  1245 +
  1246 + gBus->handleReceivedData(gTimer->time, genData(Command::TERMINATE));
  1247 +
  1248 + gBus->handleReceivedData(gTimer->time, genData(Command::INITIALISE, 255));
  1249 + gBus->handleReceivedData(gTimer->time, genData(Command::INITIALISE, 255));
  1250 +
  1251 + gBus->handleReceivedData(gTimer->time, genData(Command::QUERY_SHORT_ADDRESS));
  1252 + TEST_ASSERT(gBus->ack == 0xff);
  1253 +
  1254 + gBus->handleReceivedData(gTimer->time, genData(Command::TERMINATE));
  1255 +}
  1256 +
  1257 +void testInitialize100msTimeout() {
  1258 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  1259 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  1260 +
  1261 + gBus->handleReceivedData(gTimer->time, genData(Command::TERMINATE));
  1262 +
  1263 + gBus->handleReceivedData(gTimer->time, genData(Command::INITIALISE, 0));
  1264 + gTimer->run(150);
  1265 + gBus->handleReceivedData(gTimer->time, genData(Command::INITIALISE, 0));
  1266 +
  1267 + gBus->handleReceivedData(gTimer->time, genData(Command::QUERY_SHORT_ADDRESS));
  1268 + TEST_ASSERT(gBus->ack == 0xffff);
  1269 +
  1270 + gBus->handleReceivedData(gTimer->time, genData(Command::TERMINATE));
  1271 +}
  1272 +
  1273 +void testInitializeCommandInBetween() {
  1274 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  1275 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  1276 +
  1277 + gBus->handleReceivedData(gTimer->time, genData(Command::TERMINATE));
  1278 +
  1279 + gBus->handleReceivedData(gTimer->time, genData(Command::INITIALISE, 0));
  1280 +
  1281 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_CONTROL_GEAR));
  1282 + TEST_ASSERT(gBus->ack == 0xffff);
  1283 +
  1284 + gBus->handleReceivedData(gTimer->time, genData(Command::INITIALISE, 0));
  1285 +
  1286 + gBus->handleReceivedData(gTimer->time, genData(Command::QUERY_SHORT_ADDRESS));
  1287 + TEST_ASSERT(gBus->ack == 0xffff);
  1288 +
  1289 + gBus->handleReceivedData(gTimer->time, genData(Command::TERMINATE));
  1290 +
  1291 + gBus->handleReceivedData(gTimer->time, genData(Command::INITIALISE, 0));
  1292 +
  1293 + gBus->handleReceivedData(gTimer->time, genData(0x8b, Command::QUERY_CONTROL_GEAR));
  1294 + TEST_ASSERT(gBus->ack == 0xffff);
  1295 +
  1296 + gBus->handleReceivedData(gTimer->time, genData(Command::INITIALISE, 0));
  1297 +
  1298 + gBus->handleReceivedData(gTimer->time, genData(Command::QUERY_SHORT_ADDRESS));
  1299 + TEST_ASSERT(gBus->ack == 0xff);
  1300 +
  1301 + gBus->handleReceivedData(gTimer->time, genData(Command::TERMINATE));
  1302 +}
  1303 +
  1304 +void testRandomizeResetValues() {
  1305 + uint32_t randomAddr;
  1306 +
  1307 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  1308 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  1309 +
  1310 + randomAddr = 0;
  1311 +
  1312 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_RANDOM_ADDR_H));
  1313 + TEST_ASSERT(gBus->ack != 0xffff);
  1314 + randomAddr |= gBus->ack << 16;
  1315 +
  1316 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_RANDOM_ADDR_M));
  1317 + TEST_ASSERT(gBus->ack != 0xffff);
  1318 + randomAddr |= gBus->ack << 8;
  1319 +
  1320 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_RANDOM_ADDR_L));
  1321 + TEST_ASSERT(gBus->ack != 0xffff);
  1322 + randomAddr |= gBus->ack << 0;
  1323 +
  1324 + TEST_ASSERT(randomAddr == 0x00ffffff);
  1325 +
  1326 + gBus->handleReceivedData(gTimer->time, genData(Command::INITIALISE, 0));
  1327 + gBus->handleReceivedData(gTimer->time, genData(Command::INITIALISE, 0));
  1328 +
  1329 + gBus->handleReceivedData(gTimer->time, genData(Command::RANDOMISE, 0));
  1330 + gBus->handleReceivedData(gTimer->time, genData(Command::RANDOMISE, 0));
  1331 +
  1332 + randomAddr = 0;
  1333 +
  1334 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_RANDOM_ADDR_H));
  1335 + TEST_ASSERT(gBus->ack != 0xffff);
  1336 + randomAddr |= gBus->ack << 16;
  1337 +
  1338 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_RANDOM_ADDR_M));
  1339 + TEST_ASSERT(gBus->ack != 0xffff);
  1340 + randomAddr |= gBus->ack << 8;
  1341 +
  1342 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_RANDOM_ADDR_L));
  1343 + TEST_ASSERT(gBus->ack != 0xffff);
  1344 + randomAddr |= gBus->ack << 0;
  1345 +
  1346 + TEST_ASSERT(randomAddr != 0x00ffffff);
  1347 +
  1348 + randomAddr = 0;
  1349 +
  1350 + gSlave->notifyPowerDown();
  1351 + delete gSlave; // simulate power off
  1352 + gSlave = gCreateSlave(gMemory, gLamp, gBus, gTimer);
  1353 + TEST_ASSERT(gSlave != nullptr);
  1354 +
  1355 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_RANDOM_ADDR_H));
  1356 + TEST_ASSERT(gBus->ack != 0xffff);
  1357 + randomAddr |= gBus->ack << 16;
  1358 +
  1359 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_RANDOM_ADDR_M));
  1360 + TEST_ASSERT(gBus->ack != 0xffff);
  1361 + randomAddr |= gBus->ack << 8;
  1362 +
  1363 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_RANDOM_ADDR_L));
  1364 + TEST_ASSERT(gBus->ack != 0xffff);
  1365 + randomAddr |= gBus->ack << 0;
  1366 +
  1367 + TEST_ASSERT(randomAddr == randomAddr);
  1368 +
  1369 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  1370 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  1371 +
  1372 + randomAddr = 0;
  1373 +
  1374 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_RANDOM_ADDR_H));
  1375 + TEST_ASSERT(gBus->ack != 0xffff);
  1376 + randomAddr |= gBus->ack << 16;
  1377 +
  1378 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_RANDOM_ADDR_M));
  1379 + TEST_ASSERT(gBus->ack != 0xffff);
  1380 + randomAddr |= gBus->ack << 8;
  1381 +
  1382 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_RANDOM_ADDR_L));
  1383 + TEST_ASSERT(gBus->ack != 0xffff);
  1384 + randomAddr |= gBus->ack << 0;
  1385 +
  1386 + TEST_ASSERT(randomAddr == 0x00ffffff);
  1387 +
  1388 + gBus->handleReceivedData(gTimer->time, genData(Command::TERMINATE));
  1389 +}
  1390 +
  1391 +void testRandomize100msTimeout() {
  1392 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  1393 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  1394 +
  1395 + gBus->handleReceivedData(gTimer->time, genData(Command::INITIALISE, 0));
  1396 + gBus->handleReceivedData(gTimer->time, genData(Command::INITIALISE, 0));
  1397 +
  1398 + gBus->handleReceivedData(gTimer->time, genData(Command::RANDOMISE, 0));
  1399 + gTimer->run(150);
  1400 + gBus->handleReceivedData(gTimer->time, genData(Command::RANDOMISE, 0));
  1401 +
  1402 + uint32_t randomAddr = 0;
  1403 +
  1404 + gTimer->run(100);
  1405 +
  1406 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_RANDOM_ADDR_H));
  1407 + TEST_ASSERT(gBus->ack != 0xffff);
  1408 + randomAddr |= gBus->ack << 16;
  1409 +
  1410 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_RANDOM_ADDR_M));
  1411 + TEST_ASSERT(gBus->ack != 0xffff);
  1412 + randomAddr |= gBus->ack << 8;
  1413 +
  1414 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_RANDOM_ADDR_L));
  1415 + TEST_ASSERT(gBus->ack != 0xffff);
  1416 + randomAddr |= gBus->ack << 0;
  1417 +
  1418 + TEST_ASSERT(randomAddr == 0x00ffffff);
  1419 +
  1420 + gBus->handleReceivedData(gTimer->time, genData(Command::TERMINATE));
  1421 +}
  1422 +
  1423 +void testRandomizeCommandInBetween() {
  1424 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  1425 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  1426 +
  1427 + gBus->handleReceivedData(gTimer->time, genData(Command::INITIALISE, 0));
  1428 + gBus->handleReceivedData(gTimer->time, genData(Command::INITIALISE, 0));
  1429 +
  1430 + gBus->handleReceivedData(gTimer->time, genData(Command::RANDOMISE, 0));
  1431 +
  1432 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_CONTROL_GEAR));
  1433 + TEST_ASSERT(gBus->ack == 0xffff);
  1434 +
  1435 + gBus->handleReceivedData(gTimer->time, genData(Command::RANDOMISE, 0));
  1436 +
  1437 + gTimer->run(100);
  1438 +
  1439 + uint32_t randomAddr = 0;
  1440 +
  1441 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_RANDOM_ADDR_H));
  1442 + TEST_ASSERT(gBus->ack != 0xffff);
  1443 + randomAddr |= gBus->ack << 16;
  1444 +
  1445 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_RANDOM_ADDR_M));
  1446 + TEST_ASSERT(gBus->ack != 0xffff);
  1447 + randomAddr |= gBus->ack << 8;
  1448 +
  1449 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_RANDOM_ADDR_L));
  1450 + TEST_ASSERT(gBus->ack != 0xffff);
  1451 + randomAddr |= gBus->ack << 0;
  1452 +
  1453 + TEST_ASSERT(randomAddr == 0x00ffffff);
  1454 +
  1455 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  1456 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  1457 +
  1458 + gBus->handleReceivedData(gTimer->time, genData(Command::RANDOMISE, 0));
  1459 +
  1460 + gBus->handleReceivedData(gTimer->time, genData(0x8b, Command::QUERY_CONTROL_GEAR));
  1461 + TEST_ASSERT(gBus->ack == 0xffff);
  1462 +
  1463 + gBus->handleReceivedData(gTimer->time, genData(Command::RANDOMISE, 0));
  1464 +
  1465 + randomAddr = 0;
  1466 +
  1467 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_RANDOM_ADDR_H));
  1468 + TEST_ASSERT(gBus->ack != 0xffff);
  1469 + randomAddr |= gBus->ack << 16;
  1470 +
  1471 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_RANDOM_ADDR_M));
  1472 + TEST_ASSERT(gBus->ack != 0xffff);
  1473 + randomAddr |= gBus->ack << 8;
  1474 +
  1475 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_RANDOM_ADDR_L));
  1476 + TEST_ASSERT(gBus->ack != 0xffff);
  1477 + randomAddr |= gBus->ack << 0;
  1478 +
  1479 + TEST_ASSERT(randomAddr != 0x00ffffff);
  1480 +
  1481 + gBus->handleReceivedData(gTimer->time, genData(Command::TERMINATE));
  1482 +}
  1483 +
  1484 +void testCompare() {
  1485 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  1486 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  1487 +
  1488 + gBus->handleReceivedData(gTimer->time, genData(Command::INITIALISE, 0));
  1489 + gBus->handleReceivedData(gTimer->time, genData(Command::INITIALISE, 0));
  1490 +
  1491 + uint8_t x = 0;
  1492 + uint8_t y = 0;
  1493 + uint8_t z = 0;
  1494 +
  1495 + randomizeAddress(x, y, z);
  1496 +
  1497 + TEST_ASSERT((x != 0) && (x != 255));
  1498 + TEST_ASSERT((y != 0) && (y != 255));
  1499 + TEST_ASSERT((z != 0) && (z != 255));
  1500 +
  1501 + for (uint8_t k = 1; k <= 7; ++k) {
  1502 + switch (k) {
  1503 + case 1:
  1504 + compareCheck(x + 1, y, z, DALI_ACK_YES);
  1505 + break;
  1506 + case 2:
  1507 + compareCheck(x, y + 1, z, DALI_ACK_YES);
  1508 + break;
  1509 + case 3:
  1510 + compareCheck(x, y, z + 1, DALI_ACK_YES);
  1511 + break;
  1512 + case 4:
  1513 + compareCheck(x - 1, y, z, 0xffff);
  1514 + break;
  1515 + case 5:
  1516 + compareCheck(x, y - 1, z, 0xffff);
  1517 + break;
  1518 + case 6:
  1519 + compareCheck(x, y, z - 1, 0xffff);
  1520 + break;
  1521 + case 7:
  1522 + compareCheck(x, y, z, DALI_ACK_YES);
  1523 + break;
  1524 + }
  1525 + }
  1526 +
  1527 + gBus->handleReceivedData(gTimer->time, genData(Command::TERMINATE));
  1528 +}
  1529 +
  1530 +void testWithdraw() {
  1531 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  1532 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  1533 +
  1534 + gBus->handleReceivedData(gTimer->time, genData(Command::INITIALISE, 0));
  1535 + gBus->handleReceivedData(gTimer->time, genData(Command::INITIALISE, 0));
  1536 +
  1537 + uint8_t x = 0;
  1538 + uint8_t y = 0;
  1539 + uint8_t z = 0;
  1540 +
  1541 + randomizeAddress(x, y, z);
  1542 +
  1543 + TEST_ASSERT((x != 0) && (x != 255));
  1544 + TEST_ASSERT((y != 0) && (y != 255));
  1545 + TEST_ASSERT((z != 0) && (z != 255));
  1546 +
  1547 + for (uint8_t k = 1; k <= 7; ++k) {
  1548 + gBus->handleReceivedData(gTimer->time, genData(Command::TERMINATE));
  1549 +
  1550 + gBus->handleReceivedData(gTimer->time, genData(Command::INITIALISE, 0));
  1551 + gBus->handleReceivedData(gTimer->time, genData(Command::INITIALISE, 0));
  1552 +
  1553 + switch (k) {
  1554 + case 1:
  1555 + withdrawCheck(x + 1, y, z, x, y, z, DALI_ACK_YES);
  1556 + break;
  1557 + case 2:
  1558 + withdrawCheck(x, y + 1, z, x, y, z, DALI_ACK_YES);
  1559 + break;
  1560 + case 3:
  1561 + withdrawCheck(x, y, z + 1, x, y, z, DALI_ACK_YES);
  1562 + break;
  1563 + case 4:
  1564 + withdrawCheck(x - 1, y, z, x, y, z, DALI_ACK_YES);
  1565 + break;
  1566 + case 5:
  1567 + withdrawCheck(x, y - 1, z, x, y, z, DALI_ACK_YES);
  1568 + break;
  1569 + case 6:
  1570 + withdrawCheck(x, y, z - 1, x, y, z, DALI_ACK_YES);
  1571 + break;
  1572 + case 7:
  1573 + withdrawCheck(x, y, z, x, y, z, 0xffff);
  1574 + break;
  1575 + }
  1576 + }
  1577 +
  1578 + gBus->handleReceivedData(gTimer->time, genData(Command::INITIALISE, 0));
  1579 + gBus->handleReceivedData(gTimer->time, genData(Command::INITIALISE, 0));
  1580 +
  1581 + gBus->handleReceivedData(gTimer->time, genData(Command::COMPARE, 0));
  1582 + TEST_ASSERT(gBus->ack == 0xffff);
  1583 +
  1584 + gBus->handleReceivedData(gTimer->time, genData(Command::TERMINATE));
  1585 +}
  1586 +
  1587 +void testProgramShortAddr() {
  1588 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  1589 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  1590 +
  1591 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 255));
  1592 +
  1593 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_SHORT_ADDR));
  1594 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_SHORT_ADDR));
  1595 +
  1596 + gBus->handleReceivedData(gTimer->time, genData(Command::TERMINATE));
  1597 +
  1598 + gBus->handleReceivedData(gTimer->time, genData(Command::INITIALISE, 0));
  1599 + gBus->handleReceivedData(gTimer->time, genData(Command::INITIALISE, 0));
  1600 +
  1601 + uint8_t x = 0;
  1602 + uint8_t y = 0;
  1603 + uint8_t z = 0;
  1604 +
  1605 + randomizeAddress(x, y, z);
  1606 +
  1607 + TEST_ASSERT((x != 0) && (x != 255));
  1608 + TEST_ASSERT((y != 0) && (y != 255));
  1609 + TEST_ASSERT((z != 0) && (z != 255));
  1610 +
  1611 + for (uint8_t k = 1; k <= 7; ++k) {
  1612 + uint8_t a = 2 * k + 1;
  1613 + switch (k) {
  1614 + case 1:
  1615 + programShortAddrCheck(x + 1, y, z, a, 0xffff);
  1616 + break;
  1617 + case 2:
  1618 + programShortAddrCheck(x, y + 1, z, a, 0xffff);
  1619 + break;
  1620 + case 3:
  1621 + programShortAddrCheck(x, y, z + 1, a, 0xffff);
  1622 + break;
  1623 + case 4:
  1624 + programShortAddrCheck(x - 1, y, z, a, 0xffff);
  1625 + break;
  1626 + case 5:
  1627 + programShortAddrCheck(x, y - 1, z, a, 0xffff);
  1628 + break;
  1629 + case 6:
  1630 + programShortAddrCheck(x, y, z - 1, a, 0xffff);
  1631 + break;
  1632 + case 7:
  1633 + programShortAddrCheck(x, y, z, a, DALI_MASK);
  1634 + break;
  1635 + }
  1636 +
  1637 + }
  1638 +
  1639 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 255));
  1640 +
  1641 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_SHORT_ADDR));
  1642 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_SHORT_ADDR));
  1643 +
  1644 + gBus->handleReceivedData(gTimer->time, genData(Command::TERMINATE));
  1645 +}
  1646 +
  1647 +void testVerifyShortAddr() {
  1648 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  1649 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  1650 +
  1651 + gBus->handleReceivedData(gTimer->time, genData(Command::INITIALISE, 0));
  1652 + gBus->handleReceivedData(gTimer->time, genData(Command::INITIALISE, 0));
  1653 +
  1654 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 21));
  1655 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_SHORT_ADDR));
  1656 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_SHORT_ADDR));
  1657 +
  1658 + gBus->handleReceivedData(gTimer->time, genData(Command::VERIFY_SHORT_ADDRESS, 5));
  1659 + TEST_ASSERT(gBus->ack == 0xffff);
  1660 +
  1661 + gBus->handleReceivedData(gTimer->time, genData(Command::VERIFY_SHORT_ADDRESS, 31));
  1662 + TEST_ASSERT(gBus->ack == 0xffff);
  1663 +
  1664 + gBus->handleReceivedData(gTimer->time, genData(Command::VERIFY_SHORT_ADDRESS, 21));
  1665 + TEST_ASSERT(gBus->ack == 0xff);
  1666 +
  1667 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 255));
  1668 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_SHORT_ADDR));
  1669 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_SHORT_ADDR));
  1670 +
  1671 + gBus->handleReceivedData(gTimer->time, genData(Command::TERMINATE));
  1672 +}
  1673 +
  1674 +void testQueryShortAddr() {
  1675 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  1676 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  1677 +
  1678 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 27));
  1679 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_SHORT_ADDR));
  1680 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_SHORT_ADDR));
  1681 +
  1682 + gBus->handleReceivedData(gTimer->time, genData(Command::TERMINATE));
  1683 +
  1684 + gBus->handleReceivedData(gTimer->time, genData(Command::INITIALISE, 0));
  1685 + gBus->handleReceivedData(gTimer->time, genData(Command::INITIALISE, 0));
  1686 +
  1687 + uint8_t x = 0;
  1688 + uint8_t y = 0;
  1689 + uint8_t z = 0;
  1690 +
  1691 + randomizeAddress(x, y, z);
  1692 +
  1693 + TEST_ASSERT((x != 0) && (x != 255));
  1694 + TEST_ASSERT((y != 0) && (y != 255));
  1695 + TEST_ASSERT((z != 0) && (z != 255));
  1696 +
  1697 + for (uint8_t k = 1; k <= 7; ++k) {
  1698 + switch (k) {
  1699 + case 1:
  1700 + queryShortAddrCheck(x + 1, y, z, 0xffff);
  1701 + break;
  1702 + case 2:
  1703 + queryShortAddrCheck(x, y + 1, z, 0xffff);
  1704 + break;
  1705 + case 3:
  1706 + queryShortAddrCheck(x, y, z + 1, 0xffff);
  1707 + break;
  1708 + case 4:
  1709 + queryShortAddrCheck(x - 1, y, z, 0xffff);
  1710 + break;
  1711 + case 5:
  1712 + queryShortAddrCheck(x, y - 1, z, 0xffff);
  1713 + break;
  1714 + case 6:
  1715 + queryShortAddrCheck(x, y, z - 1, 0xffff);
  1716 + break;
  1717 + case 7:
  1718 + queryShortAddrCheck(x, y, z, 27);
  1719 + break;
  1720 + }
  1721 +
  1722 + }
  1723 +
  1724 + gBus->handleReceivedData(gTimer->time, genData(Command::TERMINATE));
  1725 +}
  1726 +
  1727 +void testSearchAddrReset() {
  1728 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  1729 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  1730 +
  1731 + gBus->handleReceivedData(gTimer->time, genData(Command::INITIALISE, 0));
  1732 + gBus->handleReceivedData(gTimer->time, genData(Command::INITIALISE, 0));
  1733 +
  1734 + gBus->handleReceivedData(gTimer->time, genData(Command::SEARCHADDRH, 16));
  1735 + gBus->handleReceivedData(gTimer->time, genData(Command::SEARCHADDRM, 32));
  1736 + gBus->handleReceivedData(gTimer->time, genData(Command::SEARCHADDRL, 64));
  1737 +
  1738 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  1739 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  1740 +
  1741 + gBus->handleReceivedData(gTimer->time, genData(Command::COMPARE, 0));
  1742 + TEST_ASSERT(gBus->ack == 0xff);
  1743 +
  1744 + gBus->handleReceivedData(gTimer->time, genData(Command::TERMINATE));
  1745 +}
  1746 +
  1747 +/////////////////////////////////////////////////////////////////
  1748 +void apiTestConfiguration() {
  1749 + gSlave = gCreateSlave(gMemory, gLamp, gBus, gTimer);
  1750 + TEST_ASSERT(gSlave != nullptr);
  1751 +
  1752 + testReset();
  1753 + testResetTimeoutCommandInBetween();
  1754 + test100msTimeout();
  1755 + testCommandsInBetween();
  1756 + testQueryVersionNumber();
  1757 + testStoreAcctualLevelInDtr();
  1758 + testPresistenceMemory();
  1759 + testSequenceDtr1();
  1760 + testSequenceDtr2();
  1761 + testStoreDtrAsMaxLevel();
  1762 + testStoreDtrAsMinLevel();
  1763 + testStoreDtrAsSysFailureLevel();
  1764 + testStoreDtrAsPowerOnLevel();
  1765 + testStoreDtrAsFadeTime();
  1766 + testStoreDtrAsFadeRate();
  1767 + testStoreDtrAsSceneGoToScene();
  1768 + testRemoveFromScene();
  1769 + testAddToGroupRemoveFromGroup();
  1770 + testStoreDtrAsShortAddr();
  1771 + testMemoryBank0();
  1772 + testMemoryBank1();
  1773 + testOtherMemoryBanks();
  1774 + testEnableWriteMemory();
  1775 +
  1776 + gSlave->notifyPowerDown();
  1777 + delete gSlave;
  1778 +}
  1779 +
  1780 +void apiTestArcPower() {
  1781 + // TODO write tests
  1782 +}
  1783 +
  1784 +void apiTestQuery() {
  1785 + // TODO write tests
  1786 +}
  1787 +
  1788 +void apiTestInitialization() {
  1789 + gSlave = gCreateSlave(gMemory, gLamp, gBus, gTimer);
  1790 + TEST_ASSERT(gSlave != nullptr);
  1791 +
  1792 + testPhisicalAddressAllocation();
  1793 + testInitialize15min();
  1794 + testTerminate();
  1795 + testInitializeShortAddr();
  1796 + testInitializeNoShortAddr();
  1797 + testInitialize100msTimeout();
  1798 + testInitializeCommandInBetween();
  1799 + testRandomizeResetValues();
  1800 + testRandomize100msTimeout();
  1801 + testRandomizeCommandInBetween();
  1802 + testCompare();
  1803 + testWithdraw();
  1804 + testProgramShortAddr();
  1805 + testVerifyShortAddr();
  1806 + testQueryShortAddr();
  1807 + testSearchAddrReset();
  1808 +
  1809 + gSlave->notifyPowerDown();
  1810 + delete gSlave; // simulate power off
  1811 +}
  1812 +
  1813 +//void apiTestMagicPassword() {
  1814 +// gSlave = gCreateSlave(gMemory, gLamp, gBus, gTimer);
  1815 +// TEST_ASSERT(gSlave != nullptr);
  1816 +//
  1817 +// gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 0)); // addr
  1818 +// gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_1, 0)); // bank
  1819 +//
  1820 +// gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::READ_MEMORY_LOCATION));
  1821 +// TEST_ASSERT(gBus->ack == 15);
  1822 +//
  1823 +// uint8_t data[15];
  1824 +//
  1825 +// gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 0x0f)); // magic password addr
  1826 +// gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::ENABLE_WRITE_MEMORY));
  1827 +// gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::ENABLE_WRITE_MEMORY));
  1828 +// gBus->handleReceivedData(gTimer->time, genData(Command::WRITE_MEMORY_LOCATION, 0xca));
  1829 +//
  1830 +// gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 0)); // addr
  1831 +// for (uint16_t i = 0; i < 15; i++) {
  1832 +// gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::READ_MEMORY_LOCATION));
  1833 +// TEST_ASSERT(gBus->ack != 0xffff);
  1834 +// data[i] = (uint8_t) gBus->ack;
  1835 +// }
  1836 +//
  1837 +// gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 3)); // addr
  1838 +// gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::ENABLE_WRITE_MEMORY));
  1839 +// gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::ENABLE_WRITE_MEMORY));
  1840 +// for (uint16_t i = 3; i < 15; i++) {
  1841 +// gBus->handleReceivedData(gTimer->time, genData(Command::WRITE_MEMORY_LOCATION, ~data[i]));
  1842 +// TEST_ASSERT(gBus->ack != 0xffff);
  1843 +// }
  1844 +//
  1845 +// gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 3)); // addr
  1846 +// for (uint16_t i = 3; i < 15; i++) {
  1847 +// gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::READ_MEMORY_LOCATION));
  1848 +// TEST_ASSERT(gBus->ack != 0xffff);
  1849 +// uint8_t expected = ~((uint8_t) gBus->ack);
  1850 +// TEST_ASSERT(data[i] == expected);
  1851 +// }
  1852 +//
  1853 +// gSlave->notifyPowerDown();
  1854 +// delete gSlave; // simulate power off
  1855 +//}
  1856 +
  1857 +} // namespace
  1858 +
  1859 +void unitTests() {
  1860 +// controller::Memory::unitTest();
  1861 +// controller::Lamp::unitTest();
  1862 +// controller::QueryStore::unitTest();
  1863 +// controller::Bus::unitTest();
  1864 +// controller::Initialization::unitTest();
  1865 +}
  1866 +
  1867 +void apiTests(CreateSlave createSlave) {
  1868 + gCreateSlave = createSlave;
  1869 +
  1870 + gMemory = new MemoryMock(252);
  1871 + gLamp = new LampMock();
  1872 + gBus = new BusMock();
  1873 + gTimer = new TimerMock();
  1874 +
  1875 + apiTestConfiguration();
  1876 + apiTestInitialization();
  1877 + apiTestArcPower();
  1878 + apiTestQuery();
  1879 +// apiTestMagicPassword();
  1880 +
  1881 + delete gTimer;
  1882 + delete gBus;
  1883 + delete gLamp;
  1884 + delete gMemory;
  1885 +}
  1886 +
  1887 +} // namespace dali
  1888 +
  1889 +#endif // DALI_TEST
src/test/tests.hpp 0 โ†’ 100644
  1 +/*/*
  2 + * Copyright (c) 2015-2016, Arkadiusz Materek (arekmat@poczta.fm)
  3 + *
  4 + * All right reversed. Usage for commercial on not commercial
  5 + * purpose without written permission is not allowed.
  6 + *
  7 + * This program is distributed in the hope that it will be useful,
  8 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10 + */
  11 +
  12 +#ifndef DALI_DALI_TEST_HPP_
  13 +#define DALI_DALI_TEST_HPP_
  14 +
  15 +#ifdef DALI_TEST
  16 +
  17 +#include <dali/slave.hpp>
  18 +
  19 +namespace dali {
  20 +
  21 +typedef Slave* (*CreateSlave)(IMemory* memoryDriver, ILamp* lampDriver, IBus* busDriver, ITimer* timer);
  22 +
  23 +void unitTests();
  24 +void apiTests(CreateSlave createSlave);
  25 +
  26 +} // namespace dali
  27 +
  28 +#endif // DALI_TEST
  29 +
  30 +#endif // DALI_DALI_TEST_HPP_
src/test/tests_dt8.cpp 0 โ†’ 100644
  1 +/*
  2 + * Copyright (c) 2015-2016, Arkadiusz Materek (arekmat@poczta.fm)
  3 + *
  4 + * All right reversed. Usage for commercial on not commercial
  5 + * purpose without written permission is not allowed.
  6 + *
  7 + * This program is distributed in the hope that it will be useful,
  8 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10 + */
  11 +
  12 +#include "tests_dt8.hpp"
  13 +
  14 +#ifdef DALI_TEST
  15 +
  16 +#ifdef DALI_DT8
  17 +
  18 +#include "assert.hpp"
  19 +#include "mocks.hpp"
  20 +
  21 +#include <dali/controller/color_dt8.hpp>
  22 +#include <dali/controller/lamp_dt8.hpp>
  23 +#include <dali/controller/memory_dt8.hpp>
  24 +#include <dali/controller/query_store_dt8.hpp>
  25 +
  26 +namespace dali {
  27 +namespace {
  28 +
  29 +CreateSlave gCreateSlave;
  30 +MemoryMock* gMemory;
  31 +LampMock* gLamp;
  32 +BusMock* gBus;
  33 +TimerMock* gTimer;
  34 +Slave* gSlave;
  35 +
  36 +uint16_t genData(uint8_t addr, Command cmd) {
  37 + uint16_t data = ((uint16_t) addr << 8) | (uint16_t) cmd;
  38 + data |= 0x0100;
  39 + return data;
  40 +}
  41 +
  42 +uint16_t genData(uint8_t addr, CommandDT8 cmd) {
  43 + uint16_t data = ((uint16_t) addr << 8) | (uint16_t) cmd;
  44 + data |= 0x0100;
  45 + return data;
  46 +}
  47 +
  48 +uint16_t genData(Command cmd, uint8_t param = 0) {
  49 + return (((uint16_t) cmd - (uint16_t) Command::_SPECIAL_COMMAND) << 8) | (uint16_t) param;
  50 +}
  51 +
  52 +uint16_t genDataDPC(uint8_t addr, uint8_t param) {
  53 + uint16_t data = ((uint16_t) addr << 8) | (uint16_t) param;
  54 + data &= ~0x0100;
  55 + return data;
  56 +}
  57 +
  58 +uint16_t set16bitValue(uint8_t value) {
  59 + uint8_t msb, lsb;
  60 + if (value == 0) {
  61 + msb = 0;
  62 + lsb = 0;
  63 + } else if (value == 255) {
  64 + msb = 255;
  65 + lsb = 255;
  66 + } else if (value == 254) {
  67 + msb = 255;
  68 + lsb = 254;
  69 + } else {
  70 + msb = value;
  71 + lsb = 255 - value;
  72 + }
  73 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, lsb));
  74 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_1, msb));
  75 +
  76 + return ((uint16_t) msb << 8) + lsb;
  77 +}
  78 +
  79 +uint16_t setSpecific16bitValue(uint16_t value) {
  80 + uint8_t msb = (uint8_t) (value >> 8);
  81 + uint8_t lsb = (uint8_t) (value & 0xff);
  82 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, lsb));
  83 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_1, msb));
  84 +
  85 + return ((uint16_t) msb << 8) + lsb;
  86 +}
  87 +
  88 +uint16_t get16bitValue() {
  89 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_CONTENT_DTR));
  90 + TEST_ASSERT(gBus->ack != 0xffff);
  91 + uint8_t lsb = gBus->ack;
  92 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_CONTENT_DTR1));
  93 + TEST_ASSERT(gBus->ack != 0xffff);
  94 + uint8_t msb = gBus->ack;
  95 + return ((uint16_t) msb << 8) | lsb;
  96 +}
  97 +
  98 +uint16_t get16bitColourValue() {
  99 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  100 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  101 + TEST_ASSERT(gBus->ack != 0xffff);
  102 + uint8_t qryVal = gBus->ack;
  103 + uint16_t val = get16bitValue();
  104 + TEST_ASSERT(qryVal == (uint8_t )(val >> 8));
  105 + return val;
  106 +}
  107 +
  108 +void getCurrentPointXY(uint16_t* x, uint16_t* y) {
  109 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 0));
  110 + *x = get16bitColourValue();
  111 +
  112 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 1));
  113 + *y = get16bitColourValue();
  114 +}
  115 +
  116 +void goto_xy_Coordinate(uint16_t x, uint16_t y) {
  117 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  118 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_TYPE_FEATURES));
  119 + TEST_ASSERT((gBus->ack & 0x01) == 1);
  120 +
  121 + setSpecific16bitValue(x);
  122 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  123 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_X_COORDINATE_WORD));
  124 +
  125 + setSpecific16bitValue(y);
  126 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  127 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_Y_COORDINATE_WORD));
  128 +
  129 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  130 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::ACTIVATE));
  131 +}
  132 +
  133 +void xyModeGetMainPointxy(uint16_t* x, uint16_t* y) {
  134 +// R R G G B B
  135 +// 0 0 1 1 2 2
  136 +// x y x y x y
  137 +// 0.8 0.25 0.1 0.9 0.15 0
  138 +// 52428 16383 6553 58981 9830 0
  139 +
  140 + uint32_t xMain = 0;
  141 + uint32_t yMain = 0;
  142 + uint16_t xStart = 0;
  143 + uint16_t yStart = 0;
  144 +
  145 + const uint16_t out_of_range_x[] = { 52428, 6553, 9830 };
  146 + const uint16_t out_of_range_y[] = { 16383, 58981, 0 };
  147 +
  148 + uint16_t in_range_x[] = { 0, 0, 0 };
  149 + uint16_t in_range_y[] = { 0, 0, 0 };
  150 +
  151 + getCurrentPointXY(&xStart, &yStart);
  152 +
  153 + for (uint16_t i = 0; i < 3; ++i) {
  154 + goto_xy_Coordinate(out_of_range_x[i], out_of_range_y[i]);
  155 +
  156 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  157 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_STATUS));
  158 + TEST_ASSERT(gBus->ack != 0xffff);
  159 + if ((gBus->ack & 0x01) == 0) {
  160 + //Out of range not set when xy out of range!
  161 + TEST_ASSERT(false);
  162 + }
  163 + getCurrentPointXY(&in_range_x[i], &in_range_y[i]);
  164 + goto_xy_Coordinate(in_range_x[i], in_range_y[i]);
  165 +
  166 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  167 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_STATUS));
  168 + TEST_ASSERT(gBus->ack != 0xffff);
  169 + TEST_ASSERT((gBus->ack & 0x01) == 0);
  170 +
  171 + xMain = xMain + in_range_x[i];
  172 + yMain = yMain + in_range_y[i];
  173 +
  174 + goto_xy_Coordinate(xStart, yStart);
  175 + }
  176 +
  177 + *x = xMain / 3;
  178 + *y = yMain / 3;
  179 +}
  180 +
  181 +void getMainPointxy(uint16_t* x, uint16_t* y) {
  182 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 82));
  183 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  184 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  185 +
  186 + uint8_t nrPrim = gBus->ack;
  187 +
  188 + uint16_t xMain = 0;
  189 + uint16_t yMain = 0;
  190 +
  191 + switch (nrPrim) {
  192 + case 0:
  193 + case 1:
  194 + case 255:
  195 + // DUT has less than 2 known primaries so this sequence has no use!
  196 + xyModeGetMainPointxy(&xMain, &yMain);
  197 + break;
  198 +
  199 + default:
  200 + uint16_t cntPrimX = nrPrim;
  201 + uint16_t cntPrimY = nrPrim;
  202 + uint16_t xMax = 65535;
  203 + uint16_t yMax = 65535;
  204 + uint16_t xMin = 0;
  205 + uint16_t yMin = 0;
  206 + uint32_t xMain32 = 0;
  207 + uint32_t yMain32 = 0;
  208 + for (uint8_t i = 0; i < nrPrim; ++i) {
  209 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 64 + (i * 3)));
  210 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  211 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  212 +
  213 + uint16_t val = get16bitValue();
  214 +
  215 + if (val > 49151) {
  216 + if (val == 65535) {
  217 + // Primary [i] x needs calibration!
  218 + TEST_ASSERT(false);
  219 + } else {
  220 + // Primary [i] x out of visible range!
  221 + TEST_ASSERT(false);
  222 + }
  223 + cntPrimX = cntPrimX - 1;
  224 + } else {
  225 + if (val > xMax)
  226 + xMax = val;
  227 + if (val < xMin)
  228 + xMin = val;
  229 +
  230 + xMain32 = xMain32 + val;
  231 + }
  232 + }
  233 +
  234 + TEST_ASSERT(xMax - xMin >= 3);
  235 +
  236 + for (uint8_t i = 0; i < nrPrim; ++i) {
  237 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 65 + (i * 3)));
  238 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  239 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  240 +
  241 + uint16_t val = get16bitValue();
  242 +
  243 + if (val > 55705) {
  244 + if (val == 65535) {
  245 + // Primary [i] y needs calibration!
  246 + TEST_ASSERT(false);
  247 + } else {
  248 + // Primary [i] y out of visible range!
  249 + TEST_ASSERT(false);
  250 + }
  251 + cntPrimY = cntPrimY - 1;
  252 + } else {
  253 + if (val > yMax)
  254 + yMax = val;
  255 + if (val < yMin)
  256 + yMin = val;
  257 +
  258 + yMain32 = yMain32 + val;
  259 + }
  260 + }
  261 +
  262 + TEST_ASSERT(yMax - yMin >= 3);
  263 +
  264 + xMain = xMain32 / cntPrimX;
  265 + yMain = yMain32 / cntPrimY;
  266 + break;
  267 + }
  268 + goto_xy_Coordinate(xMain, yMain);
  269 + *x = xMain;
  270 + *y = yMain;
  271 +}
  272 +
  273 +void findTwoValid_xy_Points(uint16_t* point1_x, uint16_t* point1_y, uint16_t* point2_x, uint16_t* point2_y) {
  274 + uint16_t xMain = 0xffff;
  275 + uint16_t yMain = 0xffff;
  276 +
  277 + getMainPointxy(&xMain, &yMain);
  278 +
  279 + *point1_x = xMain;
  280 + *point1_y = yMain;
  281 + *point2_x = xMain;
  282 + *point2_y = yMain;
  283 +
  284 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  285 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_STATUS));
  286 + TEST_ASSERT(gBus->ack != 0xffff);
  287 + TEST_ASSERT((gBus->ack & 0x01) == 0);
  288 +
  289 + const CommandDT8 command[] = {
  290 + CommandDT8::X_COORDINATE_STEP_UP,
  291 + CommandDT8::X_COORDINATE_STEP_DOWN,
  292 + CommandDT8::Y_COORDINATE_STEP_UP,
  293 + CommandDT8::Y_COORDINATE_STEP_DOWN };
  294 +
  295 + for (uint8_t i = 0; i < 4; ++i) {
  296 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  297 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, command[i]));
  298 +
  299 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  300 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_STATUS));
  301 + TEST_ASSERT(gBus->ack != 0xffff);
  302 + if ((gBus->ack & 0x01) == 0) {
  303 + uint16_t point_x = 0xffff;
  304 + uint16_t point_y = 0xffff;
  305 + getCurrentPointXY(&point_x, &point_y);
  306 +
  307 + *point2_x = point_x;
  308 + *point2_y = point_y;
  309 + return;
  310 + } else {
  311 + goto_xy_Coordinate(xMain, yMain);
  312 + }
  313 + }
  314 + // Unable to find second "xy-In Range" point!
  315 + TEST_ASSERT(false);
  316 +}
  317 +
  318 +void load_xy_Coordinate(uint16_t x, uint16_t y) {
  319 + setSpecific16bitValue(x);
  320 +
  321 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  322 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_X_COORDINATE_WORD));
  323 +
  324 + setSpecific16bitValue(y);
  325 +
  326 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  327 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_Y_COORDINATE_WORD));
  328 +}
  329 +
  330 +uint16_t findValidTcValue() {
  331 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  332 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  333 + gTimer->run(300);
  334 +
  335 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 129));
  336 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  337 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  338 +
  339 + uint16_t coolest = get16bitValue();
  340 +
  341 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 131));
  342 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  343 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  344 +
  345 + uint16_t warmest = get16bitValue();
  346 +
  347 + uint16_t validTcValue = (coolest + warmest) / 2;
  348 +
  349 + setSpecific16bitValue(validTcValue);
  350 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  351 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_COLOUR_TEMPERATURE));
  352 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  353 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::ACTIVATE));
  354 +
  355 + TEST_ASSERT(warmest - coolest >= 3);
  356 +
  357 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  358 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_STATUS));
  359 + TEST_ASSERT((gBus->ack & 0x02) == 0);
  360 +
  361 + return validTcValue;
  362 +}
  363 +
  364 +void activateColourType(uint8_t type) {
  365 + set16bitValue(255);
  366 +
  367 + switch (type) {
  368 + case DALI_DT8_COLOR_TYPE_XY:
  369 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  370 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_X_COORDINATE_WORD));
  371 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  372 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_Y_COORDINATE_WORD));
  373 + break;
  374 + case DALI_DT8_COLOR_TYPE_TC:
  375 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  376 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_COLOUR_TEMPERATURE));
  377 + break;
  378 + case DALI_DT8_COLOR_TYPE_PRIMARY_N:
  379 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_2, 0));
  380 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  381 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_PRIMARY_N_DIMLEVEL));
  382 + break;
  383 + case DALI_DT8_COLOR_TYPE_RGBWAF:
  384 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_2, 255));
  385 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  386 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_RGB_DIMLEVEL));
  387 + break;
  388 + }
  389 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  390 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::ACTIVATE));
  391 +
  392 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  393 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_STATUS));
  394 +
  395 + switch (type) {
  396 + case DALI_DT8_COLOR_TYPE_XY:
  397 + TEST_ASSERT((gBus->ack & 0xf0) >> 4 == 1);
  398 + break;
  399 + case DALI_DT8_COLOR_TYPE_TC:
  400 + TEST_ASSERT((gBus->ack & 0xf0) >> 4 == 2);
  401 + break;
  402 + case DALI_DT8_COLOR_TYPE_PRIMARY_N:
  403 + TEST_ASSERT((gBus->ack & 0xf0) >> 4 == 4);
  404 + break;
  405 + case DALI_DT8_COLOR_TYPE_RGBWAF:
  406 + TEST_ASSERT((gBus->ack & 0xf0) >> 4 == 8);
  407 + break;
  408 + }
  409 +}
  410 +
  411 +void testResetIndependentColourType() {
  412 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 208));
  413 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  414 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  415 + TEST_ASSERT(gBus->ack == 255);
  416 +
  417 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 240));
  418 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  419 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  420 + TEST_ASSERT(gBus->ack == 255);
  421 +
  422 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_POWER_ON_LEVEL));
  423 + TEST_ASSERT(gBus->ack == 254);
  424 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 240));
  425 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  426 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  427 + switch (gBus->ack) {
  428 + case 0x10: // DT8_COLOR_TYPE_XY
  429 + case 0x20: // DT8_COLOR_TYPE_TC
  430 + case 0x40: // DT8_COLOR_TYPE_PRIMARY_N
  431 + case 0x80: // DT8_COLOR_TYPE_RGBWAF
  432 + break;
  433 + default:
  434 + TEST_ASSERT(false);
  435 + }
  436 +
  437 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_SYS_FAILURE_LEVEL));
  438 + TEST_ASSERT(gBus->ack == 254);
  439 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 240));
  440 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  441 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  442 + switch (gBus->ack) {
  443 + case 0x10: // DT8_COLOR_TYPE_XY
  444 + case 0x20: // DT8_COLOR_TYPE_TC
  445 + case 0x40: // DT8_COLOR_TYPE_PRIMARY_N
  446 + case 0x80: // DT8_COLOR_TYPE_RGBWAF
  447 + break;
  448 + default:
  449 + TEST_ASSERT(false);
  450 + }
  451 +
  452 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  453 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_GEAR_FEATURES_STATUS));
  454 + TEST_ASSERT((gBus->ack & 0x01) != 0);
  455 + TEST_ASSERT((gBus->ack & 0x3E) == 0);
  456 +
  457 + for (uint8_t i = 0; i < 16; ++i) {
  458 + Command querySceneCommand = (Command) ((uint8_t) Command::QUERY_SCENE_0_LEVEL + i);
  459 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, querySceneCommand));
  460 + TEST_ASSERT(gBus->ack == 255);
  461 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 240));
  462 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  463 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  464 + TEST_ASSERT(gBus->ack == 255);
  465 + }
  466 +}
  467 +
  468 +void testResetDefault(uint8_t colorType) {
  469 + set16bitValue(255);
  470 +
  471 + const uint8_t dtr[] = { //
  472 + 192, // 0
  473 + 193, // 1
  474 + 224, // 2
  475 + 225, // 3
  476 + 194, // 4
  477 + 226, // 5
  478 + 192, // 6
  479 + 193, // 7
  480 + 224, // 8
  481 + 225, // 9
  482 + 195, // 10
  483 + 196, // 11
  484 + 197, // 12
  485 + 198, // 13
  486 + 199, // 14
  487 + 200, // 15
  488 + 227, // 16
  489 + 228, // 17
  490 + 229, // 18
  491 + 230, // 19
  492 + 231, // 20
  493 + 232, // 21
  494 + 201, // 22
  495 + 202, // 23
  496 + 203, // 24
  497 + 204, // 25
  498 + 205, // 26
  499 + 206, // 27
  500 + 207, // 28
  501 + 233, // 29
  502 + 234, // 30
  503 + 235, // 31
  504 + 236, // 32
  505 + 237, // 33
  506 + 238, // 34
  507 + 239, // 35
  508 + 15, // 36
  509 + };
  510 +
  511 + uint16_t imin = 0;
  512 + uint16_t imax = 0;
  513 + switch (colorType) {
  514 + case DALI_DT8_COLOR_TYPE_XY:
  515 + imin = 0;
  516 + imax = 3;
  517 + break;
  518 + case DALI_DT8_COLOR_TYPE_TC:
  519 + imin = 4;
  520 + imax = 5;
  521 + break;
  522 + case DALI_DT8_COLOR_TYPE_PRIMARY_N:
  523 + imin = 6;
  524 + imax = 21;
  525 + break;
  526 + case DALI_DT8_COLOR_TYPE_RGBWAF:
  527 + imin = 22;
  528 + imax = 36;
  529 + break;
  530 + }
  531 +
  532 + for (uint16_t i = imin; i <= imax; ++i) {
  533 + if (i <= 21) {
  534 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, dtr[i]));
  535 + uint16_t val = get16bitColourValue();
  536 + TEST_ASSERT(val == 0xffff);
  537 + } else {
  538 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  539 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_TYPE_FEATURES));
  540 + TEST_ASSERT(gBus->ack != 0xffff);
  541 + uint8_t nrChan = (gBus->ack & 0xE0) >> 5;
  542 + uint16_t control = 0;
  543 + for (uint8_t j = 0; j < nrChan; ++j) {
  544 + control = control + (1 << j);
  545 + }
  546 + control = 0x40 | control;
  547 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, dtr[i]));
  548 + uint16_t val = get16bitColourValue();
  549 + if (i < 36) {
  550 + TEST_ASSERT((val & 0xff00) == 0xff00);
  551 + } else {
  552 + TEST_ASSERT((val & 0xff00) == (control << 8));
  553 + }
  554 + }
  555 + }
  556 + for (uint16_t j = 0; j < 16; ++j) {
  557 + Command querySceneCommand = (Command) ((uint8_t) Command::QUERY_SCENE_0_LEVEL + j);
  558 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, querySceneCommand));
  559 + TEST_ASSERT(gBus->ack == 255);
  560 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 240));
  561 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  562 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  563 + TEST_ASSERT(gBus->ack == 255);
  564 + }
  565 +}
  566 +
  567 +void getMainPoitXY(uint16_t* x, uint16_t* y) {
  568 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 82));
  569 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  570 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  571 +
  572 + uint32_t xMain = 0;
  573 + uint32_t yMain = 0;
  574 +
  575 + if (gBus->ack == 0 || gBus->ack > 6) {
  576 + // DUT has less than 2 known primaries so this sequence has no use!
  577 + xyModeGetMainPointxy(x, y);
  578 + xMain = *x;
  579 + yMain = *y;
  580 + } else {
  581 + uint8_t nrPrim = gBus->ack;
  582 +
  583 + uint16_t cntPrimX = nrPrim;
  584 + uint16_t cntPrimY = nrPrim;
  585 + uint16_t xMin = 65535;
  586 + uint16_t xMax = 0;
  587 + uint16_t yMin = 65535;
  588 + uint16_t yMax = 0;
  589 +
  590 + for (uint16_t i = 0; i < nrPrim; ++i) {
  591 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 64 + i * 3));
  592 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  593 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  594 + TEST_ASSERT(gBus->ack != 0xffff);
  595 + uint16_t value = get16bitValue();
  596 +
  597 + if (value > 49151) {
  598 + if (value == 65535) {
  599 + // Primary needs calibration!
  600 + TEST_ASSERT(false);
  601 + } else {
  602 + // Primary x out of visible range!
  603 + TEST_ASSERT(false);
  604 + }
  605 + cntPrimX--;
  606 + } else {
  607 + xMain = xMain + value;
  608 + if (value > xMax)
  609 + xMax = value;
  610 + if (value < xMin)
  611 + xMin = value;
  612 + }
  613 + }
  614 + if (xMax - xMin < 3) {
  615 + // Limited x-range!
  616 + TEST_ASSERT(false);
  617 + }
  618 +
  619 + for (uint16_t i = 0; i < nrPrim; ++i) {
  620 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 65 + i * 3));
  621 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  622 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  623 + TEST_ASSERT(gBus->ack != 0xffff);
  624 + uint16_t value = get16bitValue();
  625 +
  626 + if (value > 55705) {
  627 + if (value == 65535) {
  628 + // Primary needs calibration!
  629 + TEST_ASSERT(false);
  630 + } else {
  631 + // Primary x out of visible range!
  632 + TEST_ASSERT(false);
  633 + }
  634 + cntPrimY--;
  635 + } else {
  636 + yMain = yMain + value;
  637 + if (value > yMax)
  638 + yMax = value;
  639 + if (value < yMin)
  640 + yMin = value;
  641 + }
  642 + }
  643 + if (yMax - yMin < 3) {
  644 + // Limited y-range!
  645 + TEST_ASSERT(false);
  646 + }
  647 +
  648 + xMain /= cntPrimX;
  649 + yMain /= cntPrimY;
  650 + }
  651 +
  652 + *x = (uint16_t) xMain;
  653 + *y = (uint16_t) yMain;
  654 +
  655 + goto_xy_Coordinate(*x, *y);
  656 +}
  657 +
  658 +void testReset_xy() {
  659 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  660 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_TYPE_FEATURES));
  661 + TEST_ASSERT(gBus->ack != 0xffff);
  662 + bool capable = (gBus->ack & 0x01) != 0;
  663 + uint16_t xMain = 128;
  664 + uint16_t yMain = 130;
  665 + if (capable) {
  666 + getMainPoitXY(&xMain, &yMain);
  667 + }
  668 +
  669 + for (uint16_t i = 0; i < 16; ++i) {
  670 + setSpecific16bitValue(xMain);
  671 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  672 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_X_COORDINATE_WORD));
  673 +
  674 + Command storeDtrAsScene = (Command) ((uint8_t) Command::STORE_DTR_AS_SCENE_0 + i);
  675 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, storeDtrAsScene));
  676 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, storeDtrAsScene));
  677 + }
  678 +
  679 + setSpecific16bitValue(xMain);
  680 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  681 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_X_COORDINATE_WORD));
  682 +
  683 + setSpecific16bitValue(yMain);
  684 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  685 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_Y_COORDINATE_WORD));
  686 +
  687 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_ACTUAL_LEVEL));
  688 + TEST_ASSERT(gBus->ack == 254);
  689 +
  690 + const uint8_t dtr[] = { 192, 193, 224, 225 };
  691 + const uint16_t expected[] = { xMain, yMain, xMain, yMain };
  692 + for (uint16_t i = 0; i < 4; ++i) {
  693 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, dtr[i]));
  694 + if (capable) {
  695 + uint16_t value = get16bitColourValue();
  696 + TEST_ASSERT(value == expected[i]);
  697 + } else {
  698 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  699 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  700 + uint16_t value = get16bitValue();
  701 + TEST_ASSERT(value == 0xffff);
  702 + }
  703 + }
  704 +
  705 + if (capable) {
  706 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  707 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_STATUS));
  708 + TEST_ASSERT(gBus->ack != 0xffff);
  709 + uint8_t status = gBus->ack;
  710 +
  711 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  712 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  713 + gTimer->run(300);
  714 +
  715 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  716 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_STATUS));
  717 + TEST_ASSERT(gBus->ack == status);
  718 +
  719 + for (uint16_t i = 0; i < 4; ++i) {
  720 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, dtr[i]));
  721 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  722 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  723 + uint16_t value = get16bitValue();
  724 + TEST_ASSERT(value == 0xffff);
  725 + }
  726 + }
  727 +
  728 + for (uint16_t i = 0; i < 16; ++i) {
  729 + Command querySceneCommand = (Command) ((uint8_t) Command::QUERY_SCENE_0_LEVEL + i);
  730 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, querySceneCommand));
  731 +
  732 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 240));
  733 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  734 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  735 + uint16_t value = get16bitValue();
  736 + TEST_ASSERT(value == 0xffff);
  737 + }
  738 +}
  739 +
  740 +void tcSavePhysicalLimits(uint16_t* phLimits0, uint16_t* phLimits1) {
  741 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 129));
  742 + *phLimits0 = get16bitColourValue();
  743 +
  744 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 131));
  745 + *phLimits1 = get16bitColourValue();
  746 +}
  747 +
  748 +void testReset_Tc() {
  749 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  750 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_TYPE_FEATURES));
  751 + TEST_ASSERT(gBus->ack != 0xffff);
  752 + bool capable = (gBus->ack & DALI_DT8_COLOUR_TYPE_FEATURES_TC) != 0;
  753 + uint16_t tcValue = capable ? findValidTcValue() : 128;
  754 +
  755 + for (uint16_t i = 0; i < 16; ++i) {
  756 + setSpecific16bitValue(tcValue);
  757 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  758 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_COLOUR_TEMPERATURE));
  759 +
  760 + Command storeDtrAsScene = (Command) ((uint8_t) Command::STORE_DTR_AS_SCENE_0 + i);
  761 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, storeDtrAsScene));
  762 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, storeDtrAsScene));
  763 + }
  764 +
  765 + setSpecific16bitValue(tcValue);
  766 +
  767 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  768 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_COLOUR_TEMPERATURE));
  769 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_2, 0));
  770 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  771 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::STORE_COLOUR_TEMPERATURE_LIMIT));
  772 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::STORE_COLOUR_TEMPERATURE_LIMIT));
  773 +
  774 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  775 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_COLOUR_TEMPERATURE));
  776 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_2, 1));
  777 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  778 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::STORE_COLOUR_TEMPERATURE_LIMIT));
  779 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::STORE_COLOUR_TEMPERATURE_LIMIT));
  780 +
  781 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_ACTUAL_LEVEL));
  782 + TEST_ASSERT(gBus->ack == 254);
  783 +
  784 + if (capable) {
  785 + const uint8_t dtr[] = { 194, 226, 128, 130 };
  786 + for (uint16_t i = 0; i < 4; ++i) {
  787 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, dtr[i]));
  788 + if (capable) {
  789 + uint16_t value = get16bitColourValue();
  790 + TEST_ASSERT(value == tcValue);
  791 + } else {
  792 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  793 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  794 + uint16_t value = get16bitValue();
  795 + TEST_ASSERT(value == 0xffff);
  796 + }
  797 + }
  798 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  799 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_STATUS));
  800 + TEST_ASSERT(gBus->ack != 0xffff);
  801 + uint8_t status = gBus->ack;
  802 +
  803 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  804 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  805 + gTimer->run(300);
  806 +
  807 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  808 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_STATUS));
  809 + TEST_ASSERT(gBus->ack == status);
  810 +
  811 + uint16_t coolest = 0xffff;
  812 + uint16_t warmest = 0xffff;
  813 +
  814 + tcSavePhysicalLimits(&coolest, &warmest);
  815 +
  816 + const uint16_t expected[] = { 0xffff, 0xffff, coolest, warmest };
  817 + for (uint16_t i = 0; i < 4; ++i) {
  818 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, dtr[i]));
  819 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  820 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  821 + uint16_t value = get16bitValue();
  822 + TEST_ASSERT(value == expected[i]);
  823 + }
  824 + }
  825 +
  826 + for (uint16_t i = 0; i < 16; ++i) {
  827 + Command querySceneCommand = (Command) ((uint8_t) Command::QUERY_SCENE_0_LEVEL + i);
  828 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, querySceneCommand));
  829 +
  830 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 240));
  831 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  832 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  833 + uint16_t value = get16bitValue();
  834 + TEST_ASSERT(value == 0xffff);
  835 + }
  836 +}
  837 +
  838 +void load_PrimaryN(uint16_t* point) {
  839 + for (uint16_t i = 0; i < 6; ++i) {
  840 + setSpecific16bitValue(point[i]);
  841 +
  842 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_2, i));
  843 +
  844 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  845 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_PRIMARY_N_DIMLEVEL));
  846 + }
  847 +}
  848 +
  849 +void findTwoValid_PrimaryN_Points(uint16_t* point1, uint16_t* point2) {
  850 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  851 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_TYPE_FEATURES));
  852 + TEST_ASSERT(gBus->ack != 0xffff);
  853 + uint16_t nrPrim = (gBus->ack & 0x1C) >> 2;
  854 +
  855 + for (uint16_t i = 0; i < 6; ++i) {
  856 + if (i < nrPrim) {
  857 + point1[i] = 1 + i;
  858 + point2[i] = 65534 - i;
  859 + } else {
  860 + point1[i] = 65535;
  861 + point2[i] = 65535;
  862 + }
  863 + }
  864 +
  865 + load_PrimaryN(point1);
  866 +
  867 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  868 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::ACTIVATE));
  869 +}
  870 +
  871 +void testReset_PrimaryN() {
  872 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  873 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_TYPE_FEATURES));
  874 + TEST_ASSERT(gBus->ack != 0xffff);
  875 + uint8_t nrPrim = (gBus->ack & DALI_DT8_COLOUR_TYPE_FEATURES_PRIMARY_N) >> 2;
  876 + bool capable = nrPrim > 0;
  877 + if (!capable)
  878 + nrPrim = 6;
  879 +
  880 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_2, 0));
  881 +
  882 + for (uint16_t i = 0; i < 16; ++i) {
  883 + setSpecific16bitValue(0x8000 + i);
  884 +
  885 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  886 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_PRIMARY_N_DIMLEVEL));
  887 +
  888 + Command storeDtrAsScene = (Command) ((uint8_t) Command::STORE_DTR_AS_SCENE_0 + i);
  889 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, storeDtrAsScene));
  890 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, storeDtrAsScene));
  891 +
  892 + Command querySceneCommand = (Command) ((uint8_t) Command::QUERY_SCENE_0_LEVEL + i);
  893 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, querySceneCommand));
  894 + TEST_ASSERT(gBus->ack == i);
  895 +
  896 + // FIXME How to QUERY_SCENE_0_LEVEL can be (0x8000 + i)
  897 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 227));
  898 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  899 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  900 + TEST_ASSERT(gBus->ack != 0xffff);
  901 +
  902 + uint16_t value = get16bitValue();
  903 + if (capable) {
  904 + TEST_ASSERT(value == 0x8000 + i);
  905 + } else {
  906 + TEST_ASSERT(value == 0xffff);
  907 + }
  908 + }
  909 +
  910 + uint16_t point1[6];
  911 + uint16_t point2[6];
  912 + findTwoValid_PrimaryN_Points(point1, point2);
  913 + load_PrimaryN(point2);
  914 +
  915 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_ACTUAL_LEVEL));
  916 + TEST_ASSERT(gBus->ack == 254);
  917 +
  918 + for (uint16_t i = 0; i < 6; ++i) {
  919 + uint16_t value;
  920 + if (capable) {
  921 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 195 + i));
  922 + value = get16bitColourValue();
  923 + TEST_ASSERT(value == point2[i]);
  924 +
  925 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 227 + i));
  926 + value = get16bitColourValue();
  927 + TEST_ASSERT(value == point1[i]);
  928 + } else {
  929 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 195 + i));
  930 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  931 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  932 + value = get16bitValue();
  933 + TEST_ASSERT(value == 0xffff);
  934 +
  935 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 227 + i));
  936 + value = get16bitColourValue();
  937 + TEST_ASSERT(value == 0xffff);
  938 + }
  939 + }
  940 +
  941 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  942 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_STATUS));
  943 + TEST_ASSERT(gBus->ack != 0xffff);
  944 + uint8_t status = gBus->ack;
  945 +
  946 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  947 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  948 + gTimer->run(300);
  949 +
  950 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  951 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_STATUS));
  952 + TEST_ASSERT(gBus->ack == status);
  953 +
  954 + for (uint16_t i = 0; i < 6; ++i) {
  955 + uint16_t value;
  956 +
  957 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 195 + i));
  958 + value = get16bitColourValue();
  959 + TEST_ASSERT(value == 0xffff);
  960 +
  961 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 227 + i));
  962 + value = get16bitColourValue();
  963 + TEST_ASSERT(value == 0xffff);
  964 + }
  965 +
  966 + for (uint16_t i = 0; i < 16; ++i) {
  967 + Command querySceneCommand = (Command) ((uint8_t) Command::QUERY_SCENE_0_LEVEL + i);
  968 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, querySceneCommand));
  969 + TEST_ASSERT(gBus->ack == 255);
  970 +
  971 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 240));
  972 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  973 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  974 + TEST_ASSERT(gBus->ack == 255);
  975 + }
  976 +}
  977 +
  978 +void load_RGBWAF(uint8_t point[]) {
  979 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, point[0]));
  980 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_1, point[1]));
  981 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_2, point[2]));
  982 +
  983 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  984 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_RGB_DIMLEVEL));
  985 +
  986 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, point[3]));
  987 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_1, point[4]));
  988 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_2, point[5]));
  989 +
  990 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  991 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_WAF_DIMLEVEL));
  992 +}
  993 +
  994 +void findTwoValid_RGBWAF_Pionts(uint8_t* point1, uint8_t* point2) {
  995 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  996 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_TYPE_FEATURES));
  997 + TEST_ASSERT(gBus->ack != 0xffff);
  998 +
  999 + uint8_t nrChannels = gBus->ack >> 5;
  1000 +
  1001 + for (uint8_t i = 0; i < 6; ++i) {
  1002 + if (i < nrChannels) {
  1003 + point1[i] = 1 + i;
  1004 + point2[i] = 254 - i;
  1005 + } else {
  1006 + point1[i] = 255;
  1007 + point2[i] = 255;
  1008 + }
  1009 + }
  1010 + load_RGBWAF(point1);
  1011 +
  1012 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1013 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::ACTIVATE));
  1014 +}
  1015 +
  1016 +void testReset_RGBWAF() {
  1017 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1018 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_TYPE_FEATURES));
  1019 + TEST_ASSERT(gBus->ack != 0xffff);
  1020 + uint8_t nrChan = (gBus->ack & 0xE0) >> 5;
  1021 + bool capable = nrChan > 0;
  1022 + nrChan = capable ? nrChan : 6;
  1023 +
  1024 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 0x7F));
  1025 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1026 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_RGBWAF_CONTROL));
  1027 +
  1028 + uint8_t point1[6] = { 0, 0, 0, 0, 0, 0 };
  1029 + uint8_t point2[6] = { 0, 0, 0, 0, 0, 0 };
  1030 + findTwoValid_RGBWAF_Pionts(point1, point2);
  1031 +
  1032 + for (uint8_t i = 0; i < 16; ++i) {
  1033 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 0x7F));
  1034 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1035 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_RGBWAF_CONTROL));
  1036 +
  1037 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 128));
  1038 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_RGB_DIMLEVEL));
  1039 +
  1040 + Command storeDtrAsScene = (Command) ((uint16_t) Command::STORE_DTR_AS_SCENE_0 + i);
  1041 + Command querySceneLevel = (Command) ((uint16_t) Command::QUERY_SCENE_0_LEVEL + i);
  1042 +
  1043 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, storeDtrAsScene));
  1044 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, storeDtrAsScene));
  1045 +
  1046 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, querySceneLevel));
  1047 + if (capable) {
  1048 + TEST_ASSERT(gBus->ack == 128);
  1049 + }
  1050 + }
  1051 +
  1052 + load_RGBWAF(point2);
  1053 +
  1054 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 0x40));
  1055 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1056 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_RGBWAF_CONTROL));
  1057 +
  1058 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_ACTUAL_LEVEL));
  1059 +
  1060 + uint8_t control = 0;
  1061 + if (capable) {
  1062 + for (uint8_t i = 0; i < nrChan; ++i) {
  1063 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 201 + i));
  1064 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1065 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  1066 + TEST_ASSERT(gBus->ack == point2[i]);
  1067 +
  1068 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 233 + i));
  1069 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1070 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  1071 + TEST_ASSERT(gBus->ack == point1[i]);
  1072 +
  1073 + control = (1 << i) + control;
  1074 + }
  1075 +
  1076 + control = 0x40 | control;
  1077 +
  1078 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 207));
  1079 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1080 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  1081 + TEST_ASSERT(gBus->ack == 0x40);
  1082 +
  1083 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 239));
  1084 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1085 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  1086 + TEST_ASSERT(gBus->ack == control);
  1087 +
  1088 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1089 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_STATUS));
  1090 + TEST_ASSERT(gBus->ack != 0xffff);
  1091 + uint8_t status = gBus->ack;
  1092 +
  1093 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  1094 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  1095 + gTimer->run(300);
  1096 +
  1097 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1098 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_STATUS));
  1099 + TEST_ASSERT(gBus->ack == status);
  1100 +
  1101 + for (uint8_t i = 0; i < nrChan; ++i) {
  1102 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 201 + i));
  1103 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1104 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  1105 + TEST_ASSERT(gBus->ack == 255);
  1106 +
  1107 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 233 + i));
  1108 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1109 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  1110 + TEST_ASSERT(gBus->ack == 255);
  1111 + }
  1112 +
  1113 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 207));
  1114 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1115 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  1116 + TEST_ASSERT(gBus->ack == 255);
  1117 +
  1118 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 239));
  1119 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1120 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  1121 + TEST_ASSERT(gBus->ack == 255);
  1122 + } else {
  1123 + for (uint8_t i = 0; i < nrChan; ++i) {
  1124 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 227 + i));
  1125 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1126 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  1127 + TEST_ASSERT(gBus->ack == 255);
  1128 + }
  1129 +
  1130 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 207));
  1131 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1132 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  1133 + TEST_ASSERT(gBus->ack == 255);
  1134 +
  1135 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 239));
  1136 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1137 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  1138 + TEST_ASSERT(gBus->ack == 255);
  1139 + }
  1140 +
  1141 + for (uint8_t i = 0; i < 16; ++i) {
  1142 + Command querySceneCommand = (Command) ((uint8_t) Command::QUERY_SCENE_0_LEVEL + i);
  1143 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, querySceneCommand));
  1144 + TEST_ASSERT(gBus->ack == 255);
  1145 +
  1146 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 240));
  1147 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1148 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  1149 + TEST_ASSERT(gBus->ack == 255);
  1150 + }
  1151 +}
  1152 +
  1153 +void testResetNoChange_xy() {
  1154 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1155 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_TYPE_FEATURES));
  1156 + TEST_ASSERT(gBus->ack != 0 && gBus->ack <= 255);
  1157 + if ((gBus->ack & 0x01) == 0x01) {
  1158 + uint16_t xMain = 0xffff;
  1159 + uint16_t yMain = 0xffff;
  1160 +
  1161 + getMainPointxy(&xMain, &yMain);
  1162 +
  1163 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 0));
  1164 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1165 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  1166 + uint16_t val = get16bitValue();
  1167 + TEST_ASSERT(val == xMain);
  1168 +
  1169 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 1));
  1170 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1171 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  1172 + val = get16bitValue();
  1173 + TEST_ASSERT(val == yMain);
  1174 +
  1175 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  1176 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  1177 + gTimer->run(300);
  1178 +
  1179 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 0));
  1180 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1181 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  1182 + val = get16bitValue();
  1183 + TEST_ASSERT(val == xMain);
  1184 +
  1185 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 1));
  1186 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1187 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  1188 + val = get16bitValue();
  1189 + TEST_ASSERT(val == yMain);
  1190 + }
  1191 +}
  1192 +
  1193 +void tcRestorePhysicalLimits(uint16_t coolest, uint16_t warmest) {
  1194 + setSpecific16bitValue(coolest);
  1195 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_2, 2));
  1196 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1197 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::STORE_COLOUR_TEMPERATURE_LIMIT));
  1198 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::STORE_COLOUR_TEMPERATURE_LIMIT));
  1199 +
  1200 + setSpecific16bitValue(warmest);
  1201 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_2, 3));
  1202 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1203 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::STORE_COLOUR_TEMPERATURE_LIMIT));
  1204 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::STORE_COLOUR_TEMPERATURE_LIMIT));
  1205 +}
  1206 +
  1207 +void testResetNoChange_Tc() {
  1208 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1209 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_TYPE_FEATURES));
  1210 + TEST_ASSERT(gBus->ack != 0 && gBus->ack <= 255);
  1211 + if ((gBus->ack & 0x02) == 0x02) {
  1212 + uint16_t tcValue = findValidTcValue();
  1213 +
  1214 + uint16_t coolest = 0xffff;
  1215 + uint16_t warmest = 0xffff;
  1216 +
  1217 + tcSavePhysicalLimits(&coolest, &warmest);
  1218 +
  1219 + setSpecific16bitValue(tcValue);
  1220 +
  1221 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_2, 2));
  1222 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1223 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::STORE_COLOUR_TEMPERATURE_LIMIT));
  1224 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::STORE_COLOUR_TEMPERATURE_LIMIT));
  1225 +
  1226 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_2, 3));
  1227 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1228 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::STORE_COLOUR_TEMPERATURE_LIMIT));
  1229 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::STORE_COLOUR_TEMPERATURE_LIMIT));
  1230 +
  1231 + const uint8_t dtr[] = { 2, 129, 131 };
  1232 + for (uint8_t i = 0; i < 3; ++i) {
  1233 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, dtr[i]));
  1234 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1235 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  1236 + uint16_t value = get16bitValue();
  1237 + TEST_ASSERT(value == tcValue);
  1238 + }
  1239 +
  1240 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  1241 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  1242 + gTimer->run(300);
  1243 +
  1244 + for (uint8_t i = 0; i < 3; ++i) {
  1245 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, dtr[i]));
  1246 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1247 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  1248 + uint16_t value = get16bitValue();
  1249 + TEST_ASSERT(value == tcValue);
  1250 + }
  1251 +
  1252 + tcRestorePhysicalLimits(coolest, warmest);
  1253 + }
  1254 +}
  1255 +
  1256 +void save_PrimaryN(uint16_t x[], uint16_t y[], uint16_t ty[]) {
  1257 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1258 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_TYPE_FEATURES));
  1259 + TEST_ASSERT(gBus->ack != 0 && gBus->ack <= 255);
  1260 + uint8_t nrPrim = (gBus->ack & 0x1C) >> 2;
  1261 + for (uint8_t i = 0; i < nrPrim; ++i) {
  1262 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 64 + 3 * i));
  1263 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1264 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  1265 + x[i] = get16bitValue();
  1266 +
  1267 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 65 + 3 * i));
  1268 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1269 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  1270 + y[i] = get16bitValue();
  1271 +
  1272 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 66 + 3 * i));
  1273 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1274 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  1275 + ty[i] = get16bitValue();
  1276 + }
  1277 +}
  1278 +
  1279 +void restore_PrimaryN(uint16_t x[], uint16_t y[], uint16_t ty[]) {
  1280 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1281 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_TYPE_FEATURES));
  1282 + TEST_ASSERT(gBus->ack != 0 && gBus->ack <= 255);
  1283 + uint8_t nrPrim = (gBus->ack & 0x1C) >> 2;
  1284 + for (uint8_t i = 0; i < nrPrim; ++i) {
  1285 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_2, i));
  1286 +
  1287 + setSpecific16bitValue(x[i]);
  1288 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1289 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_X_COORDINATE_WORD));
  1290 +
  1291 + setSpecific16bitValue(y[i]);
  1292 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1293 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_Y_COORDINATE_WORD));
  1294 +
  1295 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1296 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::STORE_XY_COORDINATE_PRIMARY_N));
  1297 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::STORE_XY_COORDINATE_PRIMARY_N));
  1298 +
  1299 + setSpecific16bitValue(ty[i]);
  1300 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1301 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::STORE_TY_PRIMARY_N));
  1302 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::STORE_TY_PRIMARY_N));
  1303 + }
  1304 +}
  1305 +
  1306 +void testResetNoChange_PrimaryN() {
  1307 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1308 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_TYPE_FEATURES));
  1309 + TEST_ASSERT(gBus->ack != 0 && gBus->ack <= 255);
  1310 + uint8_t nrPrim = (gBus->ack & 0x1C) >> 2;
  1311 + if (nrPrim > 0) {
  1312 + for (uint8_t i = 0; i < nrPrim; ++i) {
  1313 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_2, i));
  1314 +
  1315 + setSpecific16bitValue(0x8000 + i);
  1316 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1317 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_PRIMARY_N_DIMLEVEL));
  1318 + }
  1319 +
  1320 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1321 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::ACTIVATE));
  1322 +
  1323 + uint16_t xPrimary[6];
  1324 + uint16_t yPrimary[6];
  1325 + uint16_t TYPrimary[6];
  1326 + save_PrimaryN(xPrimary, yPrimary, TYPrimary);
  1327 +
  1328 + for (uint8_t i = 0; i < nrPrim; ++i) {
  1329 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_2, i));
  1330 +
  1331 + setSpecific16bitValue(0x8000 + i);
  1332 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1333 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_X_COORDINATE_WORD));
  1334 +
  1335 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1336 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_Y_COORDINATE_WORD));
  1337 +
  1338 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1339 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::STORE_XY_COORDINATE_PRIMARY_N));
  1340 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::STORE_XY_COORDINATE_PRIMARY_N));
  1341 +
  1342 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1343 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::STORE_TY_PRIMARY_N));
  1344 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::STORE_TY_PRIMARY_N));
  1345 + }
  1346 +
  1347 + for (uint8_t i = 0; i < nrPrim; ++i) {
  1348 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 3 + i));
  1349 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1350 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  1351 + uint16_t value = get16bitValue();
  1352 + TEST_ASSERT(value == 0x8000 + i);
  1353 +
  1354 + for (uint8_t j = 0; j < 3; ++j) {
  1355 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 64 + (3 * i + j)));
  1356 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1357 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  1358 + uint16_t value = get16bitValue();
  1359 + TEST_ASSERT(value == 0x8000 + i);
  1360 + }
  1361 + }
  1362 +
  1363 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  1364 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  1365 + gTimer->run(300);
  1366 +
  1367 + for (uint8_t i = 0; i < nrPrim; ++i) {
  1368 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 3 + i));
  1369 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1370 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  1371 + uint16_t value = get16bitValue();
  1372 + TEST_ASSERT(value == 0x8000 + i);
  1373 +
  1374 + for (uint8_t j = 0; j < 3; ++j) {
  1375 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 64 + (3 * i + j)));
  1376 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1377 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  1378 + uint16_t value = get16bitValue();
  1379 + TEST_ASSERT(value == 0x8000 + i);
  1380 + }
  1381 + }
  1382 +
  1383 + restore_PrimaryN(xPrimary, yPrimary, TYPrimary);
  1384 + }
  1385 +}
  1386 +
  1387 +void testResetNoChange_RGBWAF() {
  1388 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1389 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_TYPE_FEATURES));
  1390 + TEST_ASSERT(gBus->ack != 0 && gBus->ack <= 255);
  1391 + uint8_t nrChan = (gBus->ack & 0xE0) >> 5;
  1392 + if (nrChan > 0) {
  1393 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 0x7F));
  1394 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1395 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_RGBWAF_CONTROL));
  1396 +
  1397 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 0x80));
  1398 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_1, 0x81));
  1399 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_2, 0x82));
  1400 +
  1401 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1402 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_RGB_DIMLEVEL));
  1403 +
  1404 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 0x83));
  1405 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_1, 0x84));
  1406 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_2, 0x85));
  1407 +
  1408 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1409 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_WAF_DIMLEVEL));
  1410 +
  1411 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1412 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::ACTIVATE));
  1413 +
  1414 + uint8_t control = 0;
  1415 + for (uint8_t i = 0; i < nrChan; ++i) {
  1416 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 9 + i));
  1417 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1418 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  1419 + TEST_ASSERT(gBus->ack == 0x80 + i);
  1420 +
  1421 + control = control + (1 << i);
  1422 + }
  1423 +
  1424 + control = 0x40 | control;
  1425 +
  1426 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 15));
  1427 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1428 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  1429 + TEST_ASSERT(gBus->ack == control);
  1430 +
  1431 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  1432 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  1433 + gTimer->run(300);
  1434 +
  1435 + for (uint8_t i = 0; i < nrChan; ++i) {
  1436 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 9 + i));
  1437 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1438 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  1439 + TEST_ASSERT(gBus->ack == 0x80 + i);
  1440 + }
  1441 +
  1442 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 15));
  1443 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1444 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  1445 + TEST_ASSERT(gBus->ack == control);
  1446 + }
  1447 +}
  1448 +
  1449 +void testReset() {
  1450 + // must called after connected
  1451 +
  1452 + testResetIndependentColourType();
  1453 +
  1454 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1455 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_TYPE_FEATURES));
  1456 + TEST_ASSERT(gBus->ack != 0xffff);
  1457 +
  1458 + uint8_t features = gBus->ack;
  1459 + bool supp[4];
  1460 + supp[0] = (features & DALI_DT8_COLOUR_TYPE_FEATURES_XY) != 0;
  1461 + supp[1] = (features & DALI_DT8_COLOUR_TYPE_FEATURES_TC) != 0;
  1462 + supp[2] = (features & DALI_DT8_COLOUR_TYPE_FEATURES_PRIMARY_N) != 0;
  1463 + supp[3] = (features & DALI_DT8_COLOUR_TYPE_FEATURES_RGBWAF) != 0;
  1464 +
  1465 + uint16_t j = 0;
  1466 + uint16_t i = 0;
  1467 + do {
  1468 + switch (i) {
  1469 + case 0:
  1470 + if (supp[i]) {
  1471 + activateColourType(DALI_DT8_COLOR_TYPE_XY);
  1472 + if (j == 0) {
  1473 + testResetDefault(DALI_DT8_COLOR_TYPE_XY);
  1474 + } else {
  1475 + testReset_xy();
  1476 + testResetNoChange_xy();
  1477 + }
  1478 + }
  1479 + break;
  1480 + case 1:
  1481 + if (supp[i]) {
  1482 + activateColourType(DALI_DT8_COLOR_TYPE_TC);
  1483 + if (j == 0) {
  1484 + testResetDefault(DALI_DT8_COLOR_TYPE_TC);
  1485 + } else {
  1486 + testReset_Tc();
  1487 + testResetNoChange_Tc();
  1488 + }
  1489 + }
  1490 + break;
  1491 + case 2:
  1492 + if (supp[i]) {
  1493 + activateColourType(DALI_DT8_COLOR_TYPE_PRIMARY_N);
  1494 + if (j == 0) {
  1495 + testResetDefault(DALI_DT8_COLOR_TYPE_PRIMARY_N);
  1496 + } else {
  1497 + testReset_PrimaryN();
  1498 + testResetNoChange_PrimaryN();
  1499 + }
  1500 + }
  1501 + break;
  1502 + case 3:
  1503 + if (supp[i]) {
  1504 + activateColourType(DALI_DT8_COLOR_TYPE_RGBWAF);
  1505 + if (j == 0) {
  1506 + testResetDefault(DALI_DT8_COLOR_TYPE_RGBWAF);
  1507 + } else {
  1508 + testReset_RGBWAF();
  1509 + testResetNoChange_RGBWAF();
  1510 + }
  1511 + }
  1512 + break;
  1513 + }
  1514 + if (++i > 3) {
  1515 + i = 0;
  1516 + j++;
  1517 + }
  1518 + } while (j <= 1);
  1519 +}
  1520 +
  1521 +void testQueryGearFeaturesStatus() {
  1522 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  1523 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  1524 + gTimer->run(300);
  1525 +
  1526 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1527 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_GEAR_FEATURES_STATUS));
  1528 + TEST_ASSERT(gBus->ack != 0xffff);
  1529 + TEST_ASSERT((gBus->ack & 0x3E) == 0);
  1530 + TEST_ASSERT((gBus->ack & 0x1) != 0);
  1531 + TEST_ASSERT((gBus->ack & 0x40) == 0); // automatic calibration not supported
  1532 + TEST_ASSERT((gBus->ack & 0x80) == 0); // automatic calibration recovery not supported
  1533 +}
  1534 +
  1535 +void xyOutOfRangeCheck() {
  1536 + uint16_t xMain = 0xffff;
  1537 + uint16_t yMain = 0xffff;
  1538 +
  1539 + getMainPointxy(&xMain, &yMain);
  1540 +
  1541 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1542 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_STATUS));
  1543 + TEST_ASSERT((gBus->ack & 0x01) == 0);
  1544 +
  1545 + const uint16_t xpoint1[] = { 0xFFFE, xMain };
  1546 + const uint16_t ypoint1[] = { yMain, 0xFFFE };
  1547 + const uint16_t xpoint2[] = { 0, xMain };
  1548 + const uint16_t ypoint2[] = { yMain, 0 };
  1549 + uint16_t point1[] = { 0xFFFF, 0xFFFF };
  1550 + uint16_t point2[] = { 0xFFFF, 0xFFFF };
  1551 + for (uint8_t i = 0; i < 2; ++i) {
  1552 + goto_xy_Coordinate(xpoint1[i], ypoint1[i]);
  1553 +
  1554 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1555 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_STATUS));
  1556 + TEST_ASSERT((gBus->ack & 0x01) != 0);
  1557 +
  1558 + getCurrentPointXY(&point1[0], &point1[1]);
  1559 + TEST_ASSERT(point1[i] < 0xFFFE);
  1560 +
  1561 + goto_xy_Coordinate(xMain, yMain);
  1562 +
  1563 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1564 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_STATUS));
  1565 + TEST_ASSERT((gBus->ack & 0x01) == 0);
  1566 +
  1567 + goto_xy_Coordinate(xpoint2[i], ypoint2[i]);
  1568 +
  1569 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1570 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_STATUS));
  1571 + TEST_ASSERT((gBus->ack & 0x01) != 0);
  1572 +
  1573 + getCurrentPointXY(&point2[0], &point2[1]);
  1574 + TEST_ASSERT(point2[i] != 0);
  1575 +
  1576 + goto_xy_Coordinate(xMain, yMain);
  1577 +
  1578 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1579 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_STATUS));
  1580 + TEST_ASSERT((gBus->ack & 0x01) == 0);
  1581 + }
  1582 +}
  1583 +
  1584 +void tcOutOfRangePhysWarmest() {
  1585 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  1586 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  1587 + gTimer->run(300);
  1588 +
  1589 + uint16_t coolest = 0xffff;
  1590 + uint16_t warmest = 0xffff;
  1591 + tcSavePhysicalLimits(&coolest, &warmest);
  1592 + TEST_ASSERT(coolest != 0xffff);
  1593 + TEST_ASSERT(warmest != 0xffff);
  1594 +
  1595 + setSpecific16bitValue(warmest - 1);
  1596 +
  1597 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_2, 3));
  1598 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1599 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::STORE_COLOUR_TEMPERATURE_LIMIT));
  1600 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::STORE_COLOUR_TEMPERATURE_LIMIT));
  1601 +
  1602 + setSpecific16bitValue(warmest - 1);
  1603 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1604 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_COLOUR_TEMPERATURE));
  1605 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1606 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::ACTIVATE));
  1607 +
  1608 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1609 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_STATUS));
  1610 + TEST_ASSERT((gBus->ack & 0x02) == 0);
  1611 +
  1612 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1613 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::COLOUR_TEMPERATURE_STEP_WARMER));
  1614 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1615 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_STATUS));
  1616 + TEST_ASSERT((gBus->ack & 0x02) == 0x02);
  1617 +
  1618 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1619 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::COLOUR_TEMPERATURE_STEP_COOLER));
  1620 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1621 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_STATUS));
  1622 + TEST_ASSERT((gBus->ack & 0x02) == 0);
  1623 +
  1624 + setSpecific16bitValue(warmest);
  1625 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1626 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_COLOUR_TEMPERATURE));
  1627 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1628 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::ACTIVATE));
  1629 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1630 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_STATUS));
  1631 + TEST_ASSERT((gBus->ack & 0x02) == 0x02);
  1632 +
  1633 + setSpecific16bitValue(warmest - 1);
  1634 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1635 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_COLOUR_TEMPERATURE));
  1636 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1637 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::ACTIVATE));
  1638 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1639 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_STATUS));
  1640 + TEST_ASSERT((gBus->ack & 0x02) == 0);
  1641 +
  1642 + tcRestorePhysicalLimits(coolest, warmest);
  1643 +}
  1644 +
  1645 +void rcOutOfRangeCheckPhysCoolest() {
  1646 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  1647 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  1648 + gTimer->run(300);
  1649 +
  1650 + uint16_t coolest = 0xffff;
  1651 + uint16_t warmest = 0xffff;
  1652 + tcSavePhysicalLimits(&coolest, &warmest);
  1653 + TEST_ASSERT(coolest != 0xffff);
  1654 + TEST_ASSERT(warmest != 0xffff);
  1655 +
  1656 + setSpecific16bitValue(coolest + 1);
  1657 +
  1658 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_2, 2));
  1659 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1660 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::STORE_COLOUR_TEMPERATURE_LIMIT));
  1661 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::STORE_COLOUR_TEMPERATURE_LIMIT));
  1662 +
  1663 + setSpecific16bitValue(coolest + 1);
  1664 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1665 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_COLOUR_TEMPERATURE));
  1666 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1667 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::ACTIVATE));
  1668 +
  1669 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1670 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_STATUS));
  1671 + TEST_ASSERT((gBus->ack & 0x02) == 0);
  1672 +
  1673 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1674 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::COLOUR_TEMPERATURE_STEP_COOLER));
  1675 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1676 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_STATUS));
  1677 + TEST_ASSERT((gBus->ack & 0x02) == 0x02);
  1678 +
  1679 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1680 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::COLOUR_TEMPERATURE_STEP_WARMER));
  1681 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1682 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_STATUS));
  1683 + TEST_ASSERT((gBus->ack & 0x02) == 0);
  1684 +
  1685 + setSpecific16bitValue(coolest);
  1686 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1687 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_COLOUR_TEMPERATURE));
  1688 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1689 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::ACTIVATE));
  1690 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1691 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_STATUS));
  1692 + TEST_ASSERT((gBus->ack & 0x02) == 0x02);
  1693 +
  1694 + setSpecific16bitValue(coolest + 1);
  1695 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1696 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_COLOUR_TEMPERATURE));
  1697 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1698 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::ACTIVATE));
  1699 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1700 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_STATUS));
  1701 + TEST_ASSERT((gBus->ack & 0x02) == 0);
  1702 +
  1703 + tcRestorePhysicalLimits(coolest, warmest);
  1704 +}
  1705 +
  1706 +void tcOutOfRangeCheck() {
  1707 + tcOutOfRangePhysWarmest();
  1708 + rcOutOfRangeCheckPhysCoolest();
  1709 +}
  1710 +
  1711 +void checkOnlyOneColourTypeActive() {
  1712 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1713 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_STATUS));
  1714 + TEST_ASSERT(gBus->ack > 0 && gBus->ack < 255);
  1715 + uint8_t curActive = (gBus->ack & 0xF0) >> 4;
  1716 + uint8_t nrBitSet = 0;
  1717 + for (uint8_t i = 0; i < 4; ++i) {
  1718 + if ((curActive & (1 << i)) != 0) {
  1719 + nrBitSet = nrBitSet + 1;
  1720 + }
  1721 + }
  1722 + TEST_ASSERT(nrBitSet == 1);
  1723 +}
  1724 +
  1725 +void activateAndCheck(uint8_t colourType, uint8_t curActive) {
  1726 + uint8_t skipMsg = 0;
  1727 +
  1728 + do {
  1729 + set16bitValue(255);
  1730 +
  1731 + switch (colourType) {
  1732 + case 0:
  1733 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1734 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_X_COORDINATE_WORD));
  1735 +
  1736 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1737 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_X_COORDINATE_WORD));
  1738 +
  1739 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1740 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::ACTIVATE));
  1741 +
  1742 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1743 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_STATUS));
  1744 + TEST_ASSERT((((gBus->ack & 0xF0) >> 4) != (1 << curActive)) || (skipMsg == 1));
  1745 + break;
  1746 +
  1747 + case 1:
  1748 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1749 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_COLOUR_TEMPERATURE));
  1750 +
  1751 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1752 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::ACTIVATE));
  1753 +
  1754 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1755 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_STATUS));
  1756 + TEST_ASSERT((((gBus->ack & 0xF0) >> 4) != (1 << curActive)) || (skipMsg == 1));
  1757 + break;
  1758 +
  1759 + case 2:
  1760 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_2, 0));
  1761 +
  1762 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1763 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_PRIMARY_N_DIMLEVEL));
  1764 +
  1765 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1766 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::ACTIVATE));
  1767 +
  1768 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1769 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_STATUS));
  1770 + TEST_ASSERT((((gBus->ack & 0xF0) >> 4) != (1 << curActive)) || (skipMsg == 1));
  1771 + break;
  1772 +
  1773 + case 3:
  1774 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_2, 255));
  1775 +
  1776 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1777 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_RGB_DIMLEVEL));
  1778 +
  1779 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1780 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::ACTIVATE));
  1781 +
  1782 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1783 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_STATUS));
  1784 + TEST_ASSERT((((gBus->ack & 0xF0) >> 4) != (1 << curActive)) || (skipMsg == 1));
  1785 + break;
  1786 +
  1787 + default:
  1788 + TEST_ASSERT(false);
  1789 + break;
  1790 + }
  1791 +
  1792 + if (colourType != curActive) {
  1793 + checkOnlyOneColourTypeActive();
  1794 + colourType = curActive;
  1795 + skipMsg = 1;
  1796 + } else {
  1797 + break;
  1798 + }
  1799 + } while (true);
  1800 +}
  1801 +
  1802 +void testQueryColourStatus() {
  1803 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  1804 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  1805 + gTimer->run(300);
  1806 +
  1807 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1808 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_STATUS));
  1809 + TEST_ASSERT(gBus->ack != 0xffff);
  1810 + uint8_t curActive = (gBus->ack & 0xF0) >> 4;
  1811 +
  1812 + bool cur[4];
  1813 + cur[0] = curActive & 0x01;
  1814 + cur[1] = curActive & 0x02;
  1815 + cur[2] = curActive & 0x04;
  1816 + cur[3] = curActive & 0x08;
  1817 +
  1818 + switch (curActive) {
  1819 + case 0x01:
  1820 + case 0x02:
  1821 + case 0x04:
  1822 + case 0x08:
  1823 + break;
  1824 + default:
  1825 + TEST_ASSERT(false);
  1826 + break;
  1827 + }
  1828 +
  1829 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1830 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_TYPE_FEATURES));
  1831 + TEST_ASSERT(gBus->ack != 0xffff);
  1832 +
  1833 + bool supp[4];
  1834 + supp[0] = (gBus->ack & 0x01) != 0;
  1835 + supp[1] = (gBus->ack & 0x02) != 0;
  1836 + supp[2] = (gBus->ack & 0x1C) != 0;
  1837 + supp[3] = (gBus->ack & 0xE0) != 0;
  1838 +
  1839 + uint8_t i = 0;
  1840 + while (i < 4) {
  1841 + if (cur[i] != 0) {
  1842 + uint8_t activeColourType = i;
  1843 + uint8_t otherColourType = i;
  1844 + i = 0;
  1845 +
  1846 + // TODO I don't undestand 12.7.1.2
  1847 + while (i < 4) {
  1848 + if (supp[i] && (i != activeColourType)) {
  1849 + otherColourType = i;
  1850 + activateAndCheck(otherColourType, activeColourType);
  1851 + activeColourType = otherColourType;
  1852 + i = 0;
  1853 + while (i < 4) {
  1854 + if (supp[i] && (i != activeColourType)) {
  1855 + activateAndCheck(i, activeColourType);
  1856 + }
  1857 + i++;
  1858 + }
  1859 + }
  1860 + i++;
  1861 + }
  1862 +
  1863 + if (supp[0]) {
  1864 + xyOutOfRangeCheck();
  1865 + }
  1866 +
  1867 + if (supp[1]) {
  1868 + tcOutOfRangeCheck();
  1869 + }
  1870 + break;
  1871 + }
  1872 + i++;
  1873 + }
  1874 + TEST_ASSERT(curActive != 255); // any active color found
  1875 +}
  1876 +
  1877 +void testQueryColourTypeFeatures() {
  1878 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  1879 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  1880 + gTimer->run(300);
  1881 +
  1882 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1883 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_TYPE_FEATURES));
  1884 + TEST_ASSERT(gBus->ack != 0xffff);
  1885 + TEST_ASSERT(gBus->ack != 0);
  1886 + TEST_ASSERT(((gBus->ack & 0x1C) >> 2) <= 6);
  1887 + TEST_ASSERT(((gBus->ack & 0xE0) >> 5) <= 6);
  1888 +}
  1889 +
  1890 +void testQueryColorValueHelper(uint8_t i, uint8_t features, uint8_t featuresMask, uint8_t statusMask,
  1891 + const bool supp[]) {
  1892 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1893 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_TYPE_FEATURES));
  1894 + TEST_ASSERT(gBus->ack != 0xffff);
  1895 + uint8_t nrPrim = (gBus->ack & 0x1C) >> 2;
  1896 + uint8_t nrChan = (gBus->ack & 0xE0) >> 5;
  1897 +
  1898 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_1, 0xAA));
  1899 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, i));
  1900 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1901 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  1902 +
  1903 + if ((features & featuresMask) != 0) {
  1904 + TEST_ASSERT(gBus->ack != 0xffff);
  1905 + if (statusMask != 0) {
  1906 + for (uint8_t col = 0; col < 4; ++col) {
  1907 + if (supp[col]) {
  1908 + activateColourType(col);
  1909 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_1, 0xAA));
  1910 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, i));
  1911 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1912 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  1913 +
  1914 + uint16_t val = get16bitValue();
  1915 +
  1916 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1917 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_STATUS));
  1918 + TEST_ASSERT(gBus->ack != 0xffff);
  1919 + uint8_t status = gBus->ack;
  1920 +
  1921 + if ((status & statusMask) != 0) {
  1922 + if (((col == 2) && ((i >= 3) && (i < 9) && (i - 3 >= nrPrim))) ||
  1923 + ((col == 3) && ((i >= 9) && (i < 15) && (i - 9 >= nrChan)))) {
  1924 + // FIXME for Primary N and RGBWAF out of range primaries fails!
  1925 + TEST_ASSERT(val == 0xffff);
  1926 + } else {
  1927 + TEST_ASSERT(val != 0xffff);
  1928 + }
  1929 + } else {
  1930 + TEST_ASSERT(val == 0xffff);
  1931 + }
  1932 + }
  1933 + }
  1934 + }
  1935 + } else {
  1936 + // TODO Command 250: "QUERY COLOUR VALUE"
  1937 + // Querying the number of primaries, the x-coordinate, y-coordinate and TY of primary N shall be
  1938 + // independent of the implemented colour type. If the control gear does not know the
  1939 + // coordinates, or the primary is not there, the answer shall be "MASK".
  1940 + if (i >= 64 && i <= 82) {
  1941 + TEST_ASSERT(gBus->ack == 255);
  1942 + uint16_t value = get16bitValue();
  1943 + TEST_ASSERT(value == 65535);
  1944 + } else {
  1945 + TEST_ASSERT(gBus->ack == 0xffff);
  1946 + uint16_t value = get16bitValue();
  1947 + TEST_ASSERT(value == (0xAA00 | i));
  1948 + }
  1949 + }
  1950 +}
  1951 +
  1952 +void testQueryColourValue() {
  1953 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  1954 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  1955 + gTimer->run(300);
  1956 +
  1957 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  1958 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_TYPE_FEATURES));
  1959 + TEST_ASSERT(gBus->ack != 0xffff);
  1960 +
  1961 + uint8_t features = gBus->ack;
  1962 + bool supp[4];
  1963 + supp[0] = (features & DALI_DT8_COLOUR_TYPE_FEATURES_XY) != 0;
  1964 + supp[1] = (features & DALI_DT8_COLOUR_TYPE_FEATURES_TC) != 0;
  1965 + supp[2] = (features & DALI_DT8_COLOUR_TYPE_FEATURES_PRIMARY_N) != 0;
  1966 + supp[3] = (features & DALI_DT8_COLOUR_TYPE_FEATURES_RGBWAF) != 0;
  1967 +
  1968 + // TODO supp[0] Has DUT exchangeable light sources ?
  1969 + // If the control gear has exchangeable light source(s) and does not support automatic
  1970 + // calibration then the control gear shall also support colour type primary N.
  1971 +
  1972 + for (uint8_t i = 0; i < 2; ++i) {
  1973 + uint8_t featureMask = 0b00000001;
  1974 + uint8_t statusMask = 0b00010000;
  1975 + testQueryColorValueHelper(i, features, featureMask, statusMask, supp);
  1976 + }
  1977 +
  1978 + for (uint8_t i = 2; i < 3; ++i) {
  1979 + uint8_t featureMask = 0b00000010;
  1980 + uint8_t statusMask = 0b00100000;
  1981 + testQueryColorValueHelper(i, features, featureMask, statusMask, supp);
  1982 + }
  1983 +
  1984 + for (uint8_t i = 3; i < 9; ++i) {
  1985 + uint8_t featureMask = 0b00011100;
  1986 + uint8_t statusMask = 0b01000000;
  1987 + testQueryColorValueHelper(i, features, featureMask, statusMask, supp);
  1988 + }
  1989 +
  1990 + for (uint8_t i = 9; i < 16; ++i) {
  1991 + uint8_t featureMask = 0b11100000;
  1992 + uint8_t statusMask = 0b10000000;
  1993 + testQueryColorValueHelper(i, features, featureMask, statusMask, supp);
  1994 + }
  1995 +
  1996 + for (uint8_t i = 16; i < 64; ++i) {
  1997 + uint8_t featureMask = 0;
  1998 + uint8_t statusMask = 0;
  1999 + testQueryColorValueHelper(i, features, featureMask, statusMask, supp);
  2000 + }
  2001 +
  2002 + for (uint8_t i = 64; i < 83; ++i) {
  2003 + uint8_t featureMask = 0b00011100;
  2004 + uint8_t statusMask = 00000000;
  2005 + testQueryColorValueHelper(i, features, featureMask, statusMask, supp);
  2006 + }
  2007 +
  2008 + for (uint8_t i = 83; i < 128; ++i) {
  2009 + uint8_t featureMask = 0;
  2010 + uint8_t statusMask = 0;
  2011 + testQueryColorValueHelper(i, features, featureMask, statusMask, supp);
  2012 + }
  2013 +
  2014 + for (uint8_t i = 128; i < 132; ++i) {
  2015 + uint8_t featureMask = 0b00000010;
  2016 + uint8_t statusMask = 0b00000000;
  2017 + testQueryColorValueHelper(i, features, featureMask, statusMask, supp);
  2018 + }
  2019 +
  2020 + for (uint8_t i = 132; i < 192; ++i) {
  2021 + uint8_t featureMask = 0;
  2022 + uint8_t statusMask = 0;
  2023 + testQueryColorValueHelper(i, features, featureMask, statusMask, supp);
  2024 + }
  2025 +
  2026 + for (uint8_t i = 192; i < 194; ++i) {
  2027 + uint8_t featureMask = 0b00011101;
  2028 + uint8_t statusMask = 0b00000000;
  2029 + testQueryColorValueHelper(i, features, featureMask, statusMask, supp);
  2030 + }
  2031 +
  2032 + for (uint8_t i = 194; i < 195; ++i) {
  2033 + uint8_t featureMask = 0b00000010;
  2034 + uint8_t statusMask = 0b00000000;
  2035 + testQueryColorValueHelper(i, features, featureMask, statusMask, supp);
  2036 + }
  2037 +
  2038 + for (uint8_t i = 195; i < 201; ++i) {
  2039 + uint8_t featureMask = 0b00011100;
  2040 + uint8_t statusMask = 0b00000000;
  2041 + testQueryColorValueHelper(i, features, featureMask, statusMask, supp);
  2042 + }
  2043 +
  2044 + for (uint8_t i = 201; i < 208; ++i) {
  2045 + uint8_t featureMask = 0b11100000;
  2046 + uint8_t statusMask = 0b00000000;
  2047 + testQueryColorValueHelper(i, features, featureMask, statusMask, supp);
  2048 + }
  2049 +
  2050 + for (uint8_t i = 208; i < 209; ++i) {
  2051 + uint8_t featureMask = 0b11111111;
  2052 + uint8_t statusMask = 0b00000000;
  2053 + testQueryColorValueHelper(i, features, featureMask, statusMask, supp);
  2054 + }
  2055 +
  2056 + for (uint8_t i = 209; i < 224; ++i) {
  2057 + uint8_t featureMask = 0;
  2058 + uint8_t statusMask = 0;
  2059 + testQueryColorValueHelper(i, features, featureMask, statusMask, supp);
  2060 + }
  2061 +
  2062 + for (uint8_t i = 224; i < 226; ++i) {
  2063 + uint8_t featureMask = 0b00000001;
  2064 + uint8_t statusMask = 0b00000000;
  2065 + testQueryColorValueHelper(i, features, featureMask, statusMask, supp);
  2066 + }
  2067 +
  2068 + for (uint8_t i = 226; i < 227; ++i) {
  2069 + uint8_t featureMask = 0b00000010;
  2070 + uint8_t statusMask = 0b00000000;
  2071 + testQueryColorValueHelper(i, features, featureMask, statusMask, supp);
  2072 + }
  2073 +
  2074 + for (uint8_t i = 227; i < 233; ++i) {
  2075 + uint8_t featureMask = 0b00011100;
  2076 + uint8_t statusMask = 0b00000000;
  2077 + testQueryColorValueHelper(i, features, featureMask, statusMask, supp);
  2078 + }
  2079 +
  2080 + for (uint8_t i = 233; i < 240; ++i) {
  2081 + uint8_t featureMask = 0b11100000;
  2082 + uint8_t statusMask = 0b00000000;
  2083 + testQueryColorValueHelper(i, features, featureMask, statusMask, supp);
  2084 + }
  2085 +
  2086 + for (uint16_t i = 240; i < 241; ++i) {
  2087 + uint8_t featureMask = 0b11111111;
  2088 + uint8_t statusMask = 0b00000000;
  2089 + testQueryColorValueHelper(i, features, featureMask, statusMask, supp);
  2090 + }
  2091 +
  2092 + for (uint16_t i = 241; i < 256; ++i) {
  2093 + uint8_t featureMask = 0;
  2094 + uint8_t statusMask = 0;
  2095 + testQueryColorValueHelper((uint8_t) i, features, featureMask, statusMask, supp);
  2096 + }
  2097 +}
  2098 +
  2099 +void testQueryRGBWAFControl() {
  2100 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  2101 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  2102 + gTimer->run(300);
  2103 +
  2104 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2105 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_TYPE_FEATURES));
  2106 + TEST_ASSERT(gBus->ack != 0xffff);
  2107 +
  2108 + uint8_t nrChan = (gBus->ack & 0xE0) >> 5;
  2109 + if (nrChan > 0) {
  2110 + const uint8_t control[] = { 0x00, 0x40, 0x80 };
  2111 + for (uint8_t i = 0; i < 3; ++i) {
  2112 + uint8_t allSet = 0;
  2113 + for (uint8_t j = 0; j < nrChan; ++j) {
  2114 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2115 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_RGBWAF_CONTROL));
  2116 + TEST_ASSERT(gBus->ack != 0xffff);
  2117 +
  2118 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, control[i] + (1 << j)));
  2119 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2120 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_RGBWAF_CONTROL));
  2121 +
  2122 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 207));
  2123 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2124 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  2125 + TEST_ASSERT(gBus->ack == control[i] + (1 << j));
  2126 +
  2127 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 208));
  2128 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2129 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  2130 + TEST_ASSERT(gBus->ack == 0x80);
  2131 +
  2132 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2133 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::ACTIVATE));
  2134 +
  2135 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 207));
  2136 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2137 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  2138 + TEST_ASSERT(gBus->ack == 255);
  2139 +
  2140 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2141 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_RGBWAF_CONTROL));
  2142 + TEST_ASSERT((gBus->ack & 0x3F) == (1 << j));
  2143 +
  2144 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, control[i]));
  2145 +
  2146 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2147 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_RGBWAF_CONTROL));
  2148 +
  2149 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2150 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::ACTIVATE));
  2151 +
  2152 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2153 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_RGBWAF_CONTROL));
  2154 + TEST_ASSERT((gBus->ack & 0x3F) == 0);
  2155 +
  2156 + allSet = allSet + (1 << j);
  2157 + }
  2158 +
  2159 + for (uint8_t j = 0; j < nrChan; ++j) {
  2160 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, allSet + control[i]));
  2161 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2162 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_RGBWAF_CONTROL));
  2163 +
  2164 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2165 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::ACTIVATE));
  2166 +
  2167 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2168 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_RGBWAF_CONTROL));
  2169 + TEST_ASSERT(gBus->ack == allSet + control[i]);
  2170 +
  2171 + uint8_t actual = gBus->ack;
  2172 +
  2173 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 15));
  2174 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2175 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  2176 + TEST_ASSERT(gBus->ack == actual);
  2177 + }
  2178 + }
  2179 + }
  2180 +}
  2181 +
  2182 +void testQueryAssignedColour() {
  2183 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  2184 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  2185 + gTimer->run(300);
  2186 +
  2187 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2188 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_TYPE_FEATURES));
  2189 + TEST_ASSERT(gBus->ack != 0xffff);
  2190 + uint8_t nrChan = (gBus->ack & 0xE0) >> 5;
  2191 +
  2192 + if (nrChan > 0) {
  2193 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 0));
  2194 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2195 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_ASSIGNED_COLOUR));
  2196 + TEST_ASSERT(gBus->ack != 0xffff);
  2197 +
  2198 + for (uint8_t i = 0; i < 6; ++i) {
  2199 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, i));
  2200 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2201 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_ASSIGNED_COLOUR));
  2202 + TEST_ASSERT(gBus->ack != 0xffff);
  2203 + if (i < nrChan) {
  2204 + TEST_ASSERT(gBus->ack <= 6);
  2205 + } else {
  2206 + TEST_ASSERT(gBus->ack == 255);
  2207 + }
  2208 + }
  2209 + }
  2210 +}
  2211 +
  2212 +uint8_t get_actual_xy(uint16_t* x, uint16_t* y) {
  2213 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 240));
  2214 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2215 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  2216 + TEST_ASSERT(gBus->ack != 0xffff);
  2217 + uint8_t colour_type = gBus->ack;
  2218 +
  2219 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 224));
  2220 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2221 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  2222 + TEST_ASSERT(gBus->ack != 0xffff);
  2223 + *x = get16bitValue();
  2224 +
  2225 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 225));
  2226 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2227 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  2228 + TEST_ASSERT(gBus->ack != 0xffff);
  2229 + *y = get16bitValue();
  2230 +
  2231 + return colour_type;
  2232 +}
  2233 +
  2234 +void findTwoValid_Tc_Points(uint16_t* coolest, uint16_t* warmest) {
  2235 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 130));
  2236 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2237 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  2238 + *warmest = get16bitValue();
  2239 + TEST_ASSERT(*warmest != 0);
  2240 + TEST_ASSERT(*warmest != 0xffff);
  2241 +
  2242 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 128));
  2243 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2244 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  2245 + *coolest = get16bitValue();
  2246 + TEST_ASSERT(*coolest != 0);
  2247 + TEST_ASSERT(*coolest != 0xffff);
  2248 +
  2249 + TEST_ASSERT(*warmest > *coolest);
  2250 +
  2251 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2252 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_COLOUR_TEMPERATURE));
  2253 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2254 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::ACTIVATE));
  2255 +}
  2256 +
  2257 +void load_Tc(uint16_t tc) {
  2258 + setSpecific16bitValue(tc);
  2259 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2260 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_COLOUR_TEMPERATURE));
  2261 +}
  2262 +
  2263 +uint8_t get_actual_Tc(uint16_t* tc) {
  2264 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 240));
  2265 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2266 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  2267 + TEST_ASSERT(gBus->ack != 0xffff);
  2268 + uint8_t colour_type = gBus->ack;
  2269 +
  2270 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 226));
  2271 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2272 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  2273 + TEST_ASSERT(gBus->ack != 0xffff);
  2274 +
  2275 + *tc = get16bitValue();
  2276 +
  2277 + return colour_type;
  2278 +}
  2279 +
  2280 +uint16_t setTemporaries(uint8_t col, uint16_t val) {
  2281 + uint16_t result = 0xffff;
  2282 + switch (col) {
  2283 + case 0:
  2284 + result = set16bitValue(val);
  2285 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2286 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_X_COORDINATE_WORD));
  2287 +
  2288 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2289 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_Y_COORDINATE_WORD));
  2290 + break;
  2291 + case 1:
  2292 + result = set16bitValue(val);
  2293 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2294 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_COLOUR_TEMPERATURE));
  2295 + break;
  2296 + case 2:
  2297 + result = set16bitValue(val);
  2298 + for (uint8_t prim = 0; prim < 6; ++prim) {
  2299 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_2, prim));
  2300 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2301 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_PRIMARY_N_DIMLEVEL));
  2302 + }
  2303 + break;
  2304 + case 3:
  2305 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 0x7F));
  2306 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2307 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_RGBWAF_CONTROL));
  2308 +
  2309 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, val));
  2310 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_1, val));
  2311 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_2, val));
  2312 +
  2313 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2314 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_RGB_DIMLEVEL));
  2315 +
  2316 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2317 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_WAF_DIMLEVEL));
  2318 + result = (val & 0xff) | ((val & 0xff) << 8);
  2319 + break;
  2320 +
  2321 + default:
  2322 + TEST_ASSERT(false);
  2323 + }
  2324 + return result;
  2325 +}
  2326 +
  2327 +void testAutoActivateOffHerlper(uint8_t col, uint16_t val, bool autoaAtivation) {
  2328 + setTemporaries(col, val);
  2329 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::OFF));
  2330 +
  2331 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_STATUS));
  2332 + TEST_ASSERT(gBus->ack != 0xffff);
  2333 + TEST_ASSERT((gBus->ack & 0b00000100) == 0);
  2334 +
  2335 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_ACTUAL_LEVEL));
  2336 + TEST_ASSERT(gBus->ack == 0);
  2337 +
  2338 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 208));
  2339 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2340 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  2341 +
  2342 + if (autoaAtivation) {
  2343 + TEST_ASSERT(gBus->ack == 0xff);
  2344 + } else {
  2345 + TEST_ASSERT(gBus->ack != 0xff);
  2346 + }
  2347 +
  2348 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RECALL_MAX_LEVEL));
  2349 +}
  2350 +
  2351 +void testEnableDeviceTypeApplicationExtendedConfigurationCommands() {
  2352 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  2353 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  2354 + gTimer->run(300);
  2355 +
  2356 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 0));
  2357 +
  2358 + for (uint16_t i = 0; i < 255; ++i) {
  2359 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2360 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::STORE_GEAR_FEATURES_STATUS));
  2361 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, i));
  2362 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::STORE_GEAR_FEATURES_STATUS));
  2363 +
  2364 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2365 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_GEAR_FEATURES_STATUS));
  2366 + TEST_ASSERT(gBus->ack != 0xffff);
  2367 + TEST_ASSERT((gBus->ack & 0x01) != 0);
  2368 +
  2369 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 1));
  2370 +
  2371 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2372 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::STORE_GEAR_FEATURES_STATUS));
  2373 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::STORE_GEAR_FEATURES_STATUS));
  2374 +
  2375 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 0));
  2376 + }
  2377 +}
  2378 +
  2379 +void testSetTemporaryXCoordinate() {
  2380 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  2381 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  2382 + gTimer->run(300);
  2383 +
  2384 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2385 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_TYPE_FEATURES));
  2386 + TEST_ASSERT(gBus->ack != 0xffff);
  2387 +
  2388 + uint8_t support = 0;
  2389 + if ((gBus->ack & 0x01) == 0x01) {
  2390 + support |= 0x10; // FXIME
  2391 + }
  2392 + if ((gBus->ack & 0x1C) > 0) {
  2393 + support |= 0x40 | 0x10; // FXIME
  2394 + }
  2395 + if (support == 0) {
  2396 + // DUT is not capable to perform this test!
  2397 + return;
  2398 + }
  2399 +
  2400 + uint8_t i = 0;
  2401 + while (true) {
  2402 + uint16_t expected = set16bitValue(i);
  2403 +
  2404 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2405 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_X_COORDINATE_WORD));
  2406 +
  2407 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 192));
  2408 + uint16_t val = get16bitColourValue();
  2409 + TEST_ASSERT(val == expected);
  2410 +
  2411 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 208));
  2412 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2413 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  2414 + TEST_ASSERT((gBus->ack & support) != 0); // FXIME
  2415 +
  2416 + switch (i) {
  2417 + case 0:
  2418 + i = 1;
  2419 + break;
  2420 + case 1:
  2421 + i = 128;
  2422 + break;
  2423 + case 128:
  2424 + i = 254;
  2425 + break;
  2426 + case 254:
  2427 + i = 255;
  2428 + break;
  2429 + default:
  2430 + return;
  2431 + }
  2432 + }
  2433 +}
  2434 +
  2435 +void testSetTemporaryYCoordinate() {
  2436 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  2437 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  2438 + gTimer->run(300);
  2439 +
  2440 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2441 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_TYPE_FEATURES));
  2442 + TEST_ASSERT(gBus->ack != 0xffff);
  2443 +
  2444 + uint8_t support = 0;
  2445 + if ((gBus->ack & 0x01) == 0x01) {
  2446 + support |= 0x10; // FXIME
  2447 + }
  2448 + if ((gBus->ack & 0x1C) > 0) {
  2449 + support |= 0x40 | 0x10; // FXIME
  2450 + }
  2451 + if (support == 0) {
  2452 + // DUT is not capable to perform this test!
  2453 + return;
  2454 + }
  2455 +
  2456 + uint8_t i = 0;
  2457 + while (true) {
  2458 + uint16_t expected = set16bitValue(i);
  2459 +
  2460 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2461 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_Y_COORDINATE_WORD));
  2462 +
  2463 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 193));
  2464 + uint16_t val = get16bitColourValue();
  2465 + TEST_ASSERT(val == expected);
  2466 +
  2467 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 208));
  2468 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2469 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  2470 + TEST_ASSERT((gBus->ack & support) != 0); // FXIME
  2471 +
  2472 + switch (i) {
  2473 + case 0:
  2474 + i = 1;
  2475 + break;
  2476 + case 1:
  2477 + i = 128;
  2478 + break;
  2479 + case 128:
  2480 + i = 254;
  2481 + break;
  2482 + case 254:
  2483 + i = 255;
  2484 + break;
  2485 + default:
  2486 + return;
  2487 + }
  2488 + }
  2489 +}
  2490 +
  2491 +void testActivate() {
  2492 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  2493 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  2494 + gTimer->run(300);
  2495 +
  2496 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2497 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_TYPE_FEATURES));
  2498 + TEST_ASSERT(gBus->ack != 0xffff);
  2499 +
  2500 + uint8_t features = gBus->ack;
  2501 + bool supp[4];
  2502 + supp[0] = (features & DALI_DT8_COLOUR_TYPE_FEATURES_XY) != 0;
  2503 + supp[1] = (features & DALI_DT8_COLOUR_TYPE_FEATURES_TC) != 0;
  2504 + supp[2] = (features & DALI_DT8_COLOUR_TYPE_FEATURES_PRIMARY_N) != 0;
  2505 + supp[3] = (features & DALI_DT8_COLOUR_TYPE_FEATURES_RGBWAF) != 0;
  2506 +
  2507 + for (uint8_t i = 0; i < 4; ++i) {
  2508 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2509 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_STATUS));
  2510 + TEST_ASSERT(gBus->ack != 0xffff);
  2511 +
  2512 + uint8_t startStatus = gBus->ack;
  2513 +
  2514 + set16bitValue(128);
  2515 +
  2516 + switch (i) {
  2517 + case 0:
  2518 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2519 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_X_COORDINATE_WORD));
  2520 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2521 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::ACTIVATE));
  2522 +
  2523 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2524 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_STATUS));
  2525 + TEST_ASSERT(gBus->ack != 0xffff);
  2526 +
  2527 + if (supp[i]) {
  2528 + TEST_ASSERT((gBus->ack & 0xE2) == 0);
  2529 + TEST_ASSERT((gBus->ack & 0x10) != 0);
  2530 + } else {
  2531 + TEST_ASSERT(startStatus == gBus->ack);
  2532 + }
  2533 +
  2534 + break;
  2535 + case 1:
  2536 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2537 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_COLOUR_TEMPERATURE));
  2538 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2539 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::ACTIVATE));
  2540 +
  2541 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2542 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_STATUS));
  2543 + TEST_ASSERT(gBus->ack != 0xffff);
  2544 +
  2545 + if (supp[i]) {
  2546 + TEST_ASSERT((gBus->ack & 0xD1) == 0);
  2547 + TEST_ASSERT((gBus->ack & 0x20) != 0);
  2548 + } else {
  2549 + TEST_ASSERT(startStatus == gBus->ack);
  2550 + }
  2551 +
  2552 + break;
  2553 + case 2:
  2554 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_2, 0)); // FIXME For invalid DTR2 SET_TEMPORARY_PRIMARY_N_DIMLEVEL should be ignored
  2555 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2556 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_PRIMARY_N_DIMLEVEL));
  2557 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2558 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::ACTIVATE));
  2559 +
  2560 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2561 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_STATUS));
  2562 + TEST_ASSERT(gBus->ack != 0xffff);
  2563 +
  2564 + if (supp[i]) {
  2565 + TEST_ASSERT((gBus->ack & 0xB3) == 0);
  2566 + TEST_ASSERT((gBus->ack & 0x40) != 0);
  2567 + } else {
  2568 + TEST_ASSERT(startStatus == gBus->ack);
  2569 + }
  2570 +
  2571 + break;
  2572 +
  2573 + case 3:
  2574 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2575 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_RGB_DIMLEVEL));
  2576 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2577 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::ACTIVATE));
  2578 +
  2579 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2580 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_STATUS));
  2581 + TEST_ASSERT(gBus->ack != 0xffff);
  2582 +
  2583 + if (supp[i]) {
  2584 + TEST_ASSERT((gBus->ack & 0x73) == 0);
  2585 + TEST_ASSERT((gBus->ack & 0x80) != 0);
  2586 + } else {
  2587 + TEST_ASSERT(startStatus == gBus->ack);
  2588 + }
  2589 +
  2590 + break;
  2591 + }
  2592 +
  2593 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 208));
  2594 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2595 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  2596 + TEST_ASSERT(gBus->ack == 255);
  2597 +
  2598 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 15));
  2599 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_FADE_TIME));
  2600 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_FADE_TIME));
  2601 +
  2602 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_STATUS));
  2603 + TEST_ASSERT((gBus->ack & 0b00010000) == 0);
  2604 +
  2605 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2606 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::ACTIVATE));
  2607 +
  2608 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_STATUS));
  2609 + TEST_ASSERT((gBus->ack != 0xffff));
  2610 +// TEST_ASSERT((gBus->ack & 0b00010000) == 0b00010000); // FIXME How to start fade with temporary color type mask???
  2611 +
  2612 + gBus->handleReceivedData(gTimer->time, genDataDPC(DALI_MASK, 255));
  2613 +
  2614 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_STATUS));
  2615 + TEST_ASSERT((gBus->ack & 0b00010000) == 0);
  2616 +
  2617 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 0));
  2618 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_FADE_TIME));
  2619 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_FADE_TIME));
  2620 + }
  2621 +}
  2622 +
  2623 +void testXCoordinateStepUp() {
  2624 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  2625 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  2626 + gTimer->run(300);
  2627 +
  2628 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2629 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_TYPE_FEATURES));
  2630 + TEST_ASSERT(gBus->ack != 0 && gBus->ack <= 255);
  2631 +
  2632 + uint8_t features = gBus->ack;
  2633 + bool supp[4];
  2634 + supp[0] = (features & DALI_DT8_COLOUR_TYPE_FEATURES_XY) != 0;
  2635 + supp[1] = (features & DALI_DT8_COLOUR_TYPE_FEATURES_TC) != 0;
  2636 + supp[2] = (features & DALI_DT8_COLOUR_TYPE_FEATURES_PRIMARY_N) != 0;
  2637 + supp[3] = (features & DALI_DT8_COLOUR_TYPE_FEATURES_RGBWAF) != 0;
  2638 +
  2639 + if (supp[0]) {
  2640 + uint16_t xMain = 0xffff;
  2641 + uint16_t yMain = 0xffff;
  2642 +
  2643 + getMainPointxy(&xMain, &yMain);
  2644 +
  2645 + uint8_t startStatus = 0;
  2646 +
  2647 + const CommandDT8 command[] = {
  2648 + CommandDT8::X_COORDINATE_STEP_UP,
  2649 + CommandDT8::X_COORDINATE_STEP_DOWN,
  2650 + CommandDT8::Y_COORDINATE_STEP_UP,
  2651 + CommandDT8::Y_COORDINATE_STEP_DOWN };
  2652 + for (uint8_t i = 1; i < 4; ++i) {
  2653 + if (supp[i]) {
  2654 + for (uint8_t j = 0; j < 4; ++j) {
  2655 + activateColourType(i);
  2656 +
  2657 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2658 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_STATUS));
  2659 + TEST_ASSERT(gBus->ack != 0xffff);
  2660 + startStatus = gBus->ack & 0xF3;
  2661 +
  2662 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2663 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, command[j]));
  2664 +
  2665 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2666 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_STATUS));
  2667 + TEST_ASSERT(gBus->ack != 0xffff);
  2668 + TEST_ASSERT((gBus->ack & 0xF3) == startStatus);
  2669 +
  2670 + activateColourType(0);
  2671 +
  2672 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 0));
  2673 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2674 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  2675 + uint16_t value = get16bitValue();
  2676 + if (value != xMain) {
  2677 + if (value == 0xffff) {
  2678 + // X-coordinate not remembered after mode change!
  2679 + TEST_ASSERT(false);
  2680 + } else {
  2681 + // X-coordinate changed when not in XY-mode!
  2682 + TEST_ASSERT(false);
  2683 + }
  2684 + }
  2685 +
  2686 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 1));
  2687 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2688 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  2689 + value = get16bitValue();
  2690 + if (value != yMain) {
  2691 + if (value == 0xffff) {
  2692 + // Y-coordinate not remembered after mode change!
  2693 + TEST_ASSERT(false);
  2694 + } else {
  2695 + // Y-coordinate changed when not in XY-mode!
  2696 + TEST_ASSERT(false);
  2697 + }
  2698 + }
  2699 + }
  2700 + }
  2701 + }
  2702 + if (startStatus == 0) {
  2703 + // DUT is only xy capable!
  2704 + }
  2705 + }
  2706 +}
  2707 +
  2708 +void testXCoordinateStepDown() {
  2709 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2710 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_TYPE_FEATURES));
  2711 + TEST_ASSERT(gBus->ack != 0 && gBus->ack <= 255);
  2712 +
  2713 + if ((gBus->ack & 0x01) == 0x01) {
  2714 + uint16_t xMain = 0xffff;
  2715 + uint16_t yMain = 0xffff;
  2716 + uint16_t point_x = 0xffff;
  2717 + uint16_t point_y = 0xffff;
  2718 +
  2719 + getMainPointxy(&xMain, &yMain);
  2720 +
  2721 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2722 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::Y_COORDINATE_STEP_UP));
  2723 +
  2724 + getCurrentPointXY(&point_x, &point_y);
  2725 +
  2726 + TEST_ASSERT(point_x == xMain);
  2727 +
  2728 + if (point_y != yMain + 256) {
  2729 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2730 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_STATUS));
  2731 + TEST_ASSERT(gBus->ack != 0xffff && (gBus->ack & 0x01) == 0x01);
  2732 + TEST_ASSERT(point_y != yMain);
  2733 + }
  2734 +
  2735 + yMain = point_y;
  2736 + xMain = point_x;
  2737 +
  2738 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2739 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::Y_COORDINATE_STEP_DOWN));
  2740 +
  2741 + getCurrentPointXY(&point_x, &point_y);
  2742 +
  2743 + TEST_ASSERT(point_x == xMain);
  2744 +
  2745 + if (point_y != yMain - 256) {
  2746 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2747 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_STATUS));
  2748 + TEST_ASSERT(gBus->ack != 0xffff && (gBus->ack & 0x01) == 0x01);
  2749 + TEST_ASSERT(point_y != yMain);
  2750 + }
  2751 +
  2752 + getMainPointxy(&xMain, &yMain);
  2753 +
  2754 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2755 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::X_COORDINATE_STEP_UP));
  2756 +
  2757 + getCurrentPointXY(&point_x, &point_y);
  2758 +
  2759 + TEST_ASSERT(point_y == yMain);
  2760 +
  2761 + if (point_x != xMain + 256) {
  2762 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2763 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_STATUS));
  2764 + TEST_ASSERT(gBus->ack != 0xffff && (gBus->ack & 0x01) == 0x01);
  2765 + TEST_ASSERT(point_x != xMain);
  2766 + }
  2767 +
  2768 + yMain = point_y;
  2769 + xMain = point_x;
  2770 +
  2771 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2772 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::X_COORDINATE_STEP_DOWN));
  2773 +
  2774 + getCurrentPointXY(&point_x, &point_y);
  2775 +
  2776 + TEST_ASSERT(point_y == yMain);
  2777 +
  2778 + if (point_x != xMain - 256) {
  2779 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2780 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_STATUS));
  2781 + TEST_ASSERT(gBus->ack != 0xffff && (gBus->ack & 0x01) == 0x01);
  2782 + TEST_ASSERT(point_x != xMain);
  2783 + }
  2784 + }
  2785 +}
  2786 +
  2787 +void testCheckAllTcValues() {
  2788 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  2789 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  2790 + gTimer->run(300);
  2791 +
  2792 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 129));
  2793 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2794 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  2795 +
  2796 + uint16_t coolest = get16bitValue();
  2797 +
  2798 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 131));
  2799 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2800 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  2801 +
  2802 + uint16_t warmest = get16bitValue();
  2803 +
  2804 + const uint16_t value[] = { 0, 1, coolest, warmest, 65534, 65535, (uint16_t) ((coolest + warmest) >> 1) };
  2805 + const uint16_t expected[] = { 0, coolest, coolest, warmest, warmest, 65535, (uint16_t) ((coolest + warmest) >> 1) };
  2806 +
  2807 + for (uint8_t i = 0; i < 7; ++i) {
  2808 + setSpecific16bitValue(value[i]);
  2809 +
  2810 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2811 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_COLOUR_TEMPERATURE));
  2812 +
  2813 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2814 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::ACTIVATE));
  2815 +
  2816 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 2));
  2817 +
  2818 + uint16_t val = get16bitColourValue();
  2819 + if (value[i] == 0 || value[i] == 65535) {
  2820 + if (val == expected[i]) {
  2821 + if (expected[i] == 0) {
  2822 + // Undefined value 0 has effect!
  2823 + TEST_ASSERT(false);
  2824 + } else {
  2825 + // Maskโ€™ not handled correctly!
  2826 + TEST_ASSERT(false);
  2827 + }
  2828 + }
  2829 + } else {
  2830 + TEST_ASSERT(val == expected[i]);
  2831 + }
  2832 + }
  2833 +}
  2834 +
  2835 +void testSetTemporaryColourTemperature() {
  2836 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  2837 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  2838 + gTimer->run(300);
  2839 +
  2840 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2841 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_TYPE_FEATURES));
  2842 + TEST_ASSERT(gBus->ack != 0xffff);
  2843 +
  2844 + if ((gBus->ack & 0x02) == 0x02) {
  2845 + uint16_t tcValue = findValidTcValue();
  2846 +
  2847 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2848 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_STATUS));
  2849 + TEST_ASSERT(gBus->ack != 0xffff);
  2850 + TEST_ASSERT((gBus->ack & 0xDF) == 0);
  2851 +
  2852 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 15));
  2853 +
  2854 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_FADE_TIME));
  2855 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_FADE_TIME));
  2856 +
  2857 + setSpecific16bitValue(tcValue + 1);
  2858 +
  2859 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2860 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_COLOUR_TEMPERATURE));
  2861 +
  2862 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2863 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::ACTIVATE));
  2864 +
  2865 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_STATUS));
  2866 + TEST_ASSERT(gBus->ack != 0xffff);
  2867 + TEST_ASSERT((gBus->ack & 0b00010000) == 0b00010000);
  2868 +
  2869 + gBus->handleReceivedData(gTimer->time, genDataDPC(DALI_MASK, 255));
  2870 +
  2871 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_STATUS));
  2872 + TEST_ASSERT(gBus->ack != 0xffff);
  2873 + TEST_ASSERT((gBus->ack & 0b00010000) == 0b00000000);
  2874 +
  2875 + testCheckAllTcValues();
  2876 + }
  2877 +}
  2878 +
  2879 +void testColourTemperatureTcStepCooler() {
  2880 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  2881 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  2882 +
  2883 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2884 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_TYPE_FEATURES));
  2885 + TEST_ASSERT(gBus->ack != 0xffff);
  2886 +
  2887 + uint8_t features = gBus->ack;
  2888 + bool supp[4];
  2889 + supp[0] = (features & DALI_DT8_COLOUR_TYPE_FEATURES_XY) != 0;
  2890 + supp[1] = (features & DALI_DT8_COLOUR_TYPE_FEATURES_TC) != 0;
  2891 + supp[2] = (features & DALI_DT8_COLOUR_TYPE_FEATURES_PRIMARY_N) != 0;
  2892 + supp[3] = (features & DALI_DT8_COLOUR_TYPE_FEATURES_RGBWAF) != 0;
  2893 +
  2894 + const CommandDT8 command[] = { CommandDT8::COLOUR_TEMPERATURE_STEP_COOLER, CommandDT8::COLOUR_TEMPERATURE_STEP_WARMER };
  2895 + if (supp[1]) {
  2896 + uint16_t tcValue = findValidTcValue();
  2897 + uint8_t startStatus = 0;
  2898 + uint8_t i = 0;
  2899 + while (i < 4) {
  2900 + if (supp[i]) {
  2901 + uint8_t j = 0;
  2902 + while (j < 2) {
  2903 + activateColourType(i);
  2904 +
  2905 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2906 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_STATUS));
  2907 + TEST_ASSERT(gBus->ack != 0xffff);
  2908 +
  2909 + startStatus = gBus->ack & 0xF3;
  2910 +
  2911 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2912 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, command[j]));
  2913 +
  2914 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2915 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_STATUS));
  2916 + TEST_ASSERT(gBus->ack != 0xffff);
  2917 + TEST_ASSERT(startStatus == (gBus->ack & 0xF3));
  2918 +
  2919 + activateColourType(1);
  2920 +
  2921 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 2));
  2922 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2923 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  2924 +
  2925 + uint16_t val = get16bitValue();
  2926 +
  2927 + if (val == tcValue) {
  2928 + // Ok
  2929 + } else if (val == 0xffff) {
  2930 + // Tc-coordinate not remembered after mode change!
  2931 + } else {
  2932 + // Tc-coordinate changed when not in Tc-mode!
  2933 + TEST_ASSERT(false);
  2934 + }
  2935 + j++;
  2936 + }
  2937 + }
  2938 + switch (i) {
  2939 + case 0:
  2940 + i = 2;
  2941 + break;
  2942 + case 2:
  2943 + i = 3;
  2944 + break;
  2945 +
  2946 + default:
  2947 + if (startStatus == 0) {
  2948 + // DUT is only Tc capable!
  2949 + }
  2950 + i = 4; // break
  2951 + break;
  2952 + }
  2953 + }
  2954 + }
  2955 +}
  2956 +
  2957 +void testColourTemperatureStepWarmer() {
  2958 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  2959 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  2960 +
  2961 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2962 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_TYPE_FEATURES));
  2963 + TEST_ASSERT(gBus->ack != 0xffff);
  2964 +
  2965 + if ((gBus->ack & 0x02) == 0x02) {
  2966 + uint16_t tcValue = findValidTcValue();
  2967 + uint16_t pre = tcValue;
  2968 +
  2969 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2970 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::COLOUR_TEMPERATURE_STEP_WARMER));
  2971 +
  2972 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 2));
  2973 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2974 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  2975 +
  2976 + uint16_t val = get16bitValue();
  2977 +
  2978 + if (val == pre) {
  2979 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2980 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_STATUS));
  2981 + TEST_ASSERT(gBus->ack != 0xffff);
  2982 + TEST_ASSERT((gBus->ack & 0x02) == 0x02);
  2983 + TEST_ASSERT((gBus->ack & 0x02) == 0x00);
  2984 + } else {
  2985 + pre = val;
  2986 + }
  2987 +
  2988 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2989 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::COLOUR_TEMPERATURE_STEP_COOLER));
  2990 +
  2991 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 2));
  2992 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2993 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  2994 +
  2995 + val = get16bitValue();
  2996 +
  2997 + if (val == pre) {
  2998 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  2999 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_STATUS));
  3000 + TEST_ASSERT(gBus->ack != 0xffff);
  3001 + TEST_ASSERT((gBus->ack & 0x02) == 0x02);
  3002 + TEST_ASSERT((gBus->ack & 0x02) == 0x00);
  3003 + }
  3004 + }
  3005 +}
  3006 +
  3007 +void testCheckPrimaryNFadingBehaviour(uint8_t nPrim) {
  3008 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  3009 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  3010 +
  3011 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 15));
  3012 +
  3013 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_FADE_TIME));
  3014 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_FADE_TIME));
  3015 +
  3016 + for (uint8_t j = 0; j < nPrim; ++j) {
  3017 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_2, j));
  3018 +
  3019 + setSpecific16bitValue(128);
  3020 +
  3021 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3022 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_PRIMARY_N_DIMLEVEL));
  3023 +
  3024 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3025 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::ACTIVATE));
  3026 +
  3027 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_STATUS));
  3028 + TEST_ASSERT(gBus->ack != 0xffff);
  3029 + TEST_ASSERT((gBus->ack & 0b00010000) == 0b00010000);
  3030 +
  3031 +
  3032 + gBus->handleReceivedData(gTimer->time, genDataDPC(DALI_MASK, 255));
  3033 +
  3034 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_STATUS));
  3035 + TEST_ASSERT(gBus->ack != 0xffff);
  3036 + TEST_ASSERT((gBus->ack & 0b00010000) == 0);
  3037 +
  3038 + }
  3039 +}
  3040 +
  3041 +void testSetTemporaryPrimaryNDimlevel() {
  3042 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  3043 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  3044 +
  3045 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3046 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_TYPE_FEATURES));
  3047 + TEST_ASSERT(gBus->ack != 0xffff);
  3048 +
  3049 + uint8_t nrPrim = (gBus->ack & 0x1C) >> 2;
  3050 +
  3051 + if (nrPrim > 0) {
  3052 + bool outOfBounds = false;
  3053 + uint8_t i = 0;
  3054 + uint16_t checkVal = 0;
  3055 +
  3056 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 82));
  3057 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3058 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  3059 + TEST_ASSERT(gBus->ack == nrPrim);
  3060 +
  3061 + uint16_t j = 0;
  3062 + do {
  3063 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_2, j));
  3064 +
  3065 + uint16_t expVal = set16bitValue(i);
  3066 +
  3067 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3068 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_PRIMARY_N_DIMLEVEL));
  3069 +
  3070 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3071 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::ACTIVATE));
  3072 +
  3073 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3074 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_STATUS));
  3075 + TEST_ASSERT((gBus->ack & 0xB3) == 0);
  3076 +
  3077 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 3 + (j % nrPrim)));
  3078 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3079 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  3080 +
  3081 + uint16_t val = get16bitValue();
  3082 +
  3083 + if (outOfBounds) {
  3084 + TEST_ASSERT(val == checkVal);
  3085 + } else {
  3086 + if (val != expVal) {
  3087 + TEST_ASSERT(val != 1 || expVal != 65535);
  3088 + }
  3089 + }
  3090 +
  3091 + switch (i) {
  3092 + case 0:
  3093 + i = 1;
  3094 + break;
  3095 + case 1:
  3096 + i = 255;
  3097 + break;
  3098 + case 255:
  3099 + i = 254;
  3100 + break;
  3101 + case 254:
  3102 + i = 128;
  3103 + break;
  3104 + default:
  3105 + i = 0;
  3106 + j++;
  3107 + if (j >= nrPrim) {
  3108 + if (!outOfBounds) {
  3109 + outOfBounds = true;
  3110 + checkVal = expVal;
  3111 + }
  3112 + }
  3113 + }
  3114 + } while (j < 256);
  3115 +
  3116 + testCheckPrimaryNFadingBehaviour(nrPrim);
  3117 + }
  3118 +}
  3119 +
  3120 +void testCheckRGBFadingBehaviour() {
  3121 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  3122 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  3123 +
  3124 + uint8_t dimVal = 0xFD;
  3125 +
  3126 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 0x47));
  3127 +
  3128 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3129 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_RGBWAF_CONTROL));
  3130 +
  3131 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, dimVal));
  3132 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_1, dimVal));
  3133 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_2, dimVal));
  3134 +
  3135 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3136 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_RGB_DIMLEVEL));
  3137 +
  3138 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3139 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::ACTIVATE));
  3140 +
  3141 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 15));
  3142 +
  3143 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_FADE_TIME));
  3144 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_FADE_TIME));
  3145 +
  3146 + dimVal = 0xF0;
  3147 +
  3148 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, dimVal));
  3149 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_1, dimVal));
  3150 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_2, dimVal));
  3151 +
  3152 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3153 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_RGB_DIMLEVEL));
  3154 +
  3155 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3156 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::ACTIVATE));
  3157 +
  3158 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_STATUS));
  3159 + TEST_ASSERT(gBus->ack != 0xffff);
  3160 + TEST_ASSERT((gBus->ack & 0b00010000) == 0b00010000);
  3161 +
  3162 + gBus->handleReceivedData(gTimer->time, genDataDPC(DALI_MASK, 255));
  3163 +
  3164 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_STATUS));
  3165 + TEST_ASSERT((gBus->ack & 0b00010000) == 0);
  3166 +}
  3167 +
  3168 +void testSetTemporaryRGBDimlevel() {
  3169 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  3170 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  3171 +
  3172 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3173 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_TYPE_FEATURES));
  3174 + TEST_ASSERT(gBus->ack != 0xffff);
  3175 +
  3176 + const uint8_t dtr[] = { 0, 1, 128, 254, 255 };
  3177 + const uint8_t expected[] = { 0, 1, 128, 254, 254 };
  3178 +
  3179 + if ((gBus->ack & 0xE0) != 0) {
  3180 + for (uint8_t i = 0; i < 5; ++i) {
  3181 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 0x47));
  3182 +
  3183 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3184 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_RGBWAF_CONTROL));
  3185 +
  3186 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, dtr[i]));
  3187 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_1, dtr[i]));
  3188 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_2, dtr[i]));
  3189 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3190 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_RGB_DIMLEVEL));
  3191 +
  3192 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3193 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::ACTIVATE));
  3194 +
  3195 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3196 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_STATUS));
  3197 +
  3198 + TEST_ASSERT(gBus->ack != 0xffff && (gBus->ack & 0x7F) == 0);
  3199 +
  3200 + for (uint8_t j = 9; j < 12; ++j) {
  3201 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, j));
  3202 +
  3203 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3204 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  3205 + TEST_ASSERT(gBus->ack == expected[i]);
  3206 + }
  3207 + }
  3208 + testCheckRGBFadingBehaviour();
  3209 + }
  3210 +}
  3211 +
  3212 +void testCheckWAFFadingBehaviour() {
  3213 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  3214 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  3215 +
  3216 + uint8_t dimVal = 0xFD;
  3217 +
  3218 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 0x78));
  3219 +
  3220 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3221 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_RGBWAF_CONTROL));
  3222 +
  3223 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, dimVal));
  3224 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_1, dimVal));
  3225 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_2, dimVal));
  3226 +
  3227 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3228 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_WAF_DIMLEVEL));
  3229 +
  3230 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3231 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::ACTIVATE));
  3232 +
  3233 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 15));
  3234 +
  3235 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_FADE_TIME));
  3236 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_FADE_TIME));
  3237 +
  3238 + dimVal = 0xF0;
  3239 +
  3240 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, dimVal));
  3241 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_1, dimVal));
  3242 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_2, dimVal));
  3243 +
  3244 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3245 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_WAF_DIMLEVEL));
  3246 +
  3247 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3248 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::ACTIVATE));
  3249 +
  3250 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_STATUS));
  3251 + TEST_ASSERT(gBus->ack != 0xffff);
  3252 + TEST_ASSERT((gBus->ack & 0b00010000) == 0b00010000);
  3253 +
  3254 + gBus->handleReceivedData(gTimer->time, genDataDPC(DALI_MASK, 255));
  3255 +
  3256 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_STATUS));
  3257 + TEST_ASSERT((gBus->ack & 0b00010000) == 0);
  3258 +}
  3259 +
  3260 +void testSetTemporaryWAFDimlevel() {
  3261 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  3262 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  3263 +
  3264 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3265 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_TYPE_FEATURES));
  3266 + TEST_ASSERT(gBus->ack != 0xffff);
  3267 +
  3268 + const uint8_t dtr[] = { 0, 1, 128, 254, 255 };
  3269 + const uint8_t expected[] = { 0, 1, 128, 254, 255 };
  3270 +
  3271 + if ((gBus->ack & 0xE0) > (3 << 5)) { // FIXME what if device dosn't support WAF?
  3272 + for (uint8_t i = 0; i < 5; ++i) {
  3273 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 0x78));
  3274 +
  3275 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3276 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_RGBWAF_CONTROL));
  3277 +
  3278 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, dtr[i]));
  3279 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_1, dtr[i]));
  3280 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_2, dtr[i]));
  3281 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3282 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_WAF_DIMLEVEL));
  3283 +
  3284 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3285 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::ACTIVATE));
  3286 +
  3287 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3288 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_STATUS));
  3289 +
  3290 + TEST_ASSERT(gBus->ack != 0xffff && (gBus->ack & 0x7F) == 0);
  3291 +
  3292 + for (uint8_t j = 12; j < 15; ++j) {
  3293 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, j));
  3294 +
  3295 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3296 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  3297 + TEST_ASSERT(gBus->ack == expected[i]);
  3298 + }
  3299 + }
  3300 + testCheckWAFFadingBehaviour();
  3301 + }
  3302 +}
  3303 +
  3304 +void testChan_Col_Control_ActivationTest(uint8_t nrChan) {
  3305 + uint8_t imax = nrChan == 1 ? 3 : 5;
  3306 +
  3307 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_PHISICAL_MIN_LEVEL));
  3308 + TEST_ASSERT(gBus->ack > 0 && gBus->ack < 255);
  3309 +
  3310 + uint8_t minLevel = gBus->ack == 254 ? 0 : gBus->ack;
  3311 +
  3312 + const uint8_t dtr[] = { 0, 0x40, 0x01, 0x41, 0x3F, 0x7F };
  3313 +// const uint8_t expected[] = { 255, 255, 254, 254, 255, 255 };
  3314 + for (uint8_t i = 0; i <= imax; ++i) {
  3315 + gBus->handleReceivedData(gTimer->time, genDataDPC(DALI_MASK, minLevel));
  3316 +
  3317 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, dtr[i]));
  3318 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3319 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_RGBWAF_CONTROL));
  3320 +
  3321 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3322 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::ACTIVATE));
  3323 +
  3324 + gBus->handleReceivedData(gTimer->time, genDataDPC(DALI_MASK, 254));
  3325 +
  3326 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_ACTUAL_LEVEL));
  3327 +// TEST_ASSERT(gBus->ack == expected[i]); // FIXME RGBWAF
  3328 + }
  3329 +}
  3330 +
  3331 +void testNorm_Col_Control_ActivationTest() {
  3332 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_PHISICAL_MIN_LEVEL));
  3333 + TEST_ASSERT(gBus->ack > 0 && gBus->ack < 255);
  3334 +
  3335 + uint8_t minLevel = gBus->ack == 254 ? 0 : gBus->ack;
  3336 +
  3337 + const uint8_t R_dimlevel[] = { 0x40, 0 };
  3338 + const uint8_t G_dimlevel[] = { 0x20, 0 };
  3339 + const uint8_t B_dimlevel[] = { 0x80, 0 };
  3340 + const uint8_t W_dimlevel[] = { 0x00, 0 };
  3341 + const uint8_t A_dimlevel[] = { 0x64, 0 };
  3342 + const uint8_t F_dimlevel[] = { 0x80, 0 };
  3343 +
  3344 + for (uint8_t i = 0; i < 2; ++i) {
  3345 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, R_dimlevel[i]));
  3346 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_1, G_dimlevel[i]));
  3347 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_2, B_dimlevel[i]));
  3348 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3349 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_RGB_DIMLEVEL));
  3350 +
  3351 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, W_dimlevel[i]));
  3352 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_1, A_dimlevel[i]));
  3353 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_2, F_dimlevel[i]));
  3354 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3355 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_WAF_DIMLEVEL));
  3356 +
  3357 + gBus->handleReceivedData(gTimer->time, genDataDPC(DALI_MASK, minLevel));
  3358 +
  3359 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 0x80));
  3360 +
  3361 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3362 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_RGBWAF_CONTROL));
  3363 +
  3364 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3365 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::ACTIVATE));
  3366 +
  3367 + gBus->handleReceivedData(gTimer->time, genDataDPC(DALI_MASK, 254));
  3368 +
  3369 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_ACTUAL_LEVEL));
  3370 +
  3371 + if (i == 0) {
  3372 +// TEST_ASSERT(gBus->ack != 254); // FXIME RGBWAF
  3373 + } else {
  3374 + TEST_ASSERT(gBus->ack == 254);
  3375 + }
  3376 +
  3377 + gBus->handleReceivedData(gTimer->time, genDataDPC(DALI_MASK, minLevel));
  3378 +
  3379 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 0xBF));
  3380 +
  3381 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3382 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_RGBWAF_CONTROL));
  3383 +
  3384 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3385 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::ACTIVATE));
  3386 +
  3387 + gBus->handleReceivedData(gTimer->time, genDataDPC(DALI_MASK, 254));
  3388 +
  3389 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_ACTUAL_LEVEL));
  3390 +
  3391 + if (i == 0) {
  3392 +// TEST_ASSERT(gBus->ack != 254); // FXIME RGBWAF
  3393 + } else {
  3394 + TEST_ASSERT(gBus->ack == 254);
  3395 + }
  3396 + }
  3397 +}
  3398 +
  3399 +void testTransition_To_Inactive_Test() {
  3400 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3401 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_TYPE_FEATURES));
  3402 + TEST_ASSERT(gBus->ack != 0 && gBus->ack <= 255);
  3403 +
  3404 + uint8_t features = gBus->ack;
  3405 + bool supp[4];
  3406 + supp[0] = (features & DALI_DT8_COLOUR_TYPE_FEATURES_XY) != 0;
  3407 + supp[1] = (features & DALI_DT8_COLOUR_TYPE_FEATURES_TC) != 0;
  3408 + supp[2] = (features & DALI_DT8_COLOUR_TYPE_FEATURES_PRIMARY_N) != 0;
  3409 + supp[3] = (features & DALI_DT8_COLOUR_TYPE_FEATURES_RGBWAF) != 0;
  3410 +
  3411 + const uint8_t control[] = { 0, 0x40 };
  3412 + uint16_t j = 0;
  3413 + uint16_t i = 0;
  3414 + bool other = false;
  3415 + do {
  3416 +
  3417 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 0x3F + control[i]));
  3418 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3419 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_RGBWAF_CONTROL));
  3420 +
  3421 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3422 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::ACTIVATE));
  3423 +
  3424 + switch (j) {
  3425 + case 0:
  3426 + if (supp[j]) {
  3427 + other = true;
  3428 + uint16_t xMain = 0xffff;
  3429 + uint16_t yMain = 0xffff;
  3430 + getMainPointxy(&xMain, &yMain);
  3431 + TEST_ASSERT(xMain > 0 && yMain > 0 && xMain < 0xffff && yMain < 0xffff);
  3432 + }
  3433 + break;
  3434 + case 1:
  3435 + if (supp[j]) {
  3436 + other = true;
  3437 + uint16_t tcValue = findValidTcValue();
  3438 + TEST_ASSERT(tcValue > 0 && tcValue < 0xffff);
  3439 + }
  3440 + break;
  3441 + case 2:
  3442 + if (supp[j]) {
  3443 + other = true;
  3444 + setSpecific16bitValue(61440);
  3445 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_2, 0));
  3446 +
  3447 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3448 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_PRIMARY_N_DIMLEVEL));
  3449 +
  3450 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3451 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::ACTIVATE));
  3452 + }
  3453 + break;
  3454 + }
  3455 +
  3456 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3457 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_RGBWAF_CONTROL));
  3458 + if (other) {
  3459 +// TEST_ASSERT((gBus->ack & 0x3F) == 0); // FXIME RGBWAF
  3460 + }
  3461 +
  3462 + if (++j > 2) {
  3463 + j = 0;
  3464 + i++;
  3465 + }
  3466 + } while (i <= 1);
  3467 +}
  3468 +
  3469 +void testSetRGBWAFControl() {
  3470 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  3471 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  3472 +
  3473 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3474 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_TYPE_FEATURES));
  3475 + TEST_ASSERT(gBus->ack != 0xffff);
  3476 +
  3477 + uint8_t nrChan = (gBus->ack & 0xE0) >> 5;
  3478 +
  3479 + if (nrChan > 0) {
  3480 + // TODO Attach and assign lamps (so DAPC can be checked)
  3481 +
  3482 + testChan_Col_Control_ActivationTest(nrChan);
  3483 + testNorm_Col_Control_ActivationTest();
  3484 + testTransition_To_Inactive_Test();
  3485 + }
  3486 +}
  3487 +
  3488 +void testCopy_xy() {
  3489 + uint16_t xMain = 0;
  3490 + uint16_t yMain = 0;
  3491 +
  3492 + getMainPointxy(&xMain, &yMain);
  3493 +
  3494 + if (xMain == yMain) {
  3495 + uint16_t pointx = xMain + 1;
  3496 + uint16_t pointy = yMain;
  3497 + goto_xy_Coordinate(pointx, pointy);
  3498 +
  3499 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3500 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_STATUS));
  3501 + TEST_ASSERT(gBus->ack != 0xffff);
  3502 +
  3503 + if ((gBus->ack & 0x01) == 1) {
  3504 + pointx = xMain - 1;
  3505 + pointy = yMain;
  3506 + goto_xy_Coordinate(pointx, pointy);
  3507 +
  3508 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3509 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_STATUS));
  3510 + TEST_ASSERT(gBus->ack != 0xffff);
  3511 +
  3512 + if ((gBus->ack & 0x01) == 1) {
  3513 + pointx = xMain;
  3514 + pointy = yMain + 1;
  3515 + goto_xy_Coordinate(pointx, pointy);
  3516 +
  3517 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3518 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_STATUS));
  3519 + TEST_ASSERT(gBus->ack != 0xffff);
  3520 +
  3521 + if ((gBus->ack & 0x01) == 1) {
  3522 + pointx = xMain;
  3523 + pointy = yMain - 1;
  3524 + goto_xy_Coordinate(pointx, pointy);
  3525 +
  3526 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3527 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_STATUS));
  3528 + TEST_ASSERT(gBus->ack != 0xffff);
  3529 +
  3530 + if ((gBus->ack & 0x01) == 1) {
  3531 + TEST_ASSERT(false);
  3532 + } else {
  3533 + xMain = pointx;
  3534 + yMain = pointy;
  3535 + }
  3536 + } else {
  3537 + xMain = pointx;
  3538 + yMain = pointy;
  3539 + }
  3540 + } else {
  3541 + xMain = pointx;
  3542 + yMain = pointy;
  3543 + }
  3544 + } else {
  3545 + xMain = pointx;
  3546 + yMain = pointy;
  3547 + }
  3548 + }
  3549 +
  3550 + const uint8_t dtr[] = { 192, 193, 208, 224, 225, 240 };
  3551 + const uint16_t expected_1[] = { 65535, 65535, 65535, xMain, yMain, 0x10ff };
  3552 + const uint16_t expected_2[] = { xMain, yMain, 0x10ff, xMain, yMain, 0x10ff };
  3553 +
  3554 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_ACTUAL_LEVEL));
  3555 + TEST_ASSERT(gBus->ack != 0xffff);
  3556 +
  3557 + for (uint8_t i = 0; i <= 5; ++i) {
  3558 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, dtr[i]));
  3559 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3560 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  3561 + uint16_t value = get16bitValue();
  3562 + TEST_ASSERT(value == expected_1[i]);
  3563 + }
  3564 +
  3565 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3566 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::COPY_REPORT_TO_TEMPORARY));
  3567 +
  3568 + for (uint8_t i = 0; i <= 5; ++i) {
  3569 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, dtr[i]));
  3570 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3571 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  3572 + uint16_t value = get16bitValue();
  3573 + TEST_ASSERT(value == expected_2[i]);
  3574 + }
  3575 +}
  3576 +
  3577 +void testCopy_Tc() {
  3578 + uint16_t tcValue = findValidTcValue();
  3579 +
  3580 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_ACTUAL_LEVEL));
  3581 + TEST_ASSERT(gBus->ack != 0xffff);
  3582 +
  3583 + const uint8_t dtr[] = { 194, 208, 226, 240 };
  3584 + const uint16_t expected_1[] = { 65535, 65535, tcValue, 0x20ff };
  3585 + const uint16_t expected_2[] = { tcValue, 0x20ff, tcValue, 0x20ff };
  3586 +
  3587 + for (uint8_t i = 0; i <= 3; ++i) {
  3588 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, dtr[i]));
  3589 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3590 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  3591 + uint16_t value = get16bitValue();
  3592 + TEST_ASSERT(value == expected_1[i]);
  3593 + }
  3594 +
  3595 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3596 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::COPY_REPORT_TO_TEMPORARY));
  3597 +
  3598 + for (uint8_t i = 0; i <= 3; ++i) {
  3599 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, dtr[i]));
  3600 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3601 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  3602 + uint16_t value = get16bitValue();
  3603 + TEST_ASSERT(value == expected_2[i]);
  3604 + }
  3605 +}
  3606 +
  3607 +void testPrimaryN_Check1(uint8_t nrPrim) {
  3608 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 208));
  3609 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3610 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  3611 + TEST_ASSERT(gBus->ack == 255);
  3612 +
  3613 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 240));
  3614 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3615 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  3616 + TEST_ASSERT(gBus->ack == 0x40);
  3617 +
  3618 + for (uint8_t i = 0; i < nrPrim; ++i) {
  3619 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 195 + i));
  3620 + uint16_t value = get16bitColourValue();
  3621 + TEST_ASSERT(value == 0xffff);
  3622 +
  3623 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 227 + i));
  3624 + value = get16bitColourValue();
  3625 + TEST_ASSERT(value == 0x8000 + i);
  3626 + }
  3627 +}
  3628 +
  3629 +void testPrimaryN_Check2(uint8_t nrPrim) {
  3630 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 208));
  3631 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3632 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  3633 + TEST_ASSERT(gBus->ack == 0x40);
  3634 +
  3635 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 240));
  3636 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3637 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  3638 + TEST_ASSERT(gBus->ack == 0x40);
  3639 +
  3640 + for (uint8_t i = 0; i < nrPrim; ++i) {
  3641 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 195 + i));
  3642 + uint16_t value = get16bitColourValue();
  3643 + TEST_ASSERT(value == 0x8000 + i);
  3644 +
  3645 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 227 + i));
  3646 + value = get16bitColourValue();
  3647 + TEST_ASSERT(value == 0x8000 + i);
  3648 + }
  3649 +}
  3650 +
  3651 +void testCopy_PrimaryN() {
  3652 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 82));
  3653 +
  3654 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3655 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  3656 + TEST_ASSERT(gBus->ack <= 6);
  3657 + uint8_t nrPrim = gBus->ack;
  3658 +
  3659 + for (uint8_t i = 0; i <= nrPrim; ++i) {
  3660 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_2, i));
  3661 +
  3662 + setSpecific16bitValue(0x8000 + i);
  3663 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3664 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_PRIMARY_N_DIMLEVEL));
  3665 + }
  3666 +
  3667 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3668 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::ACTIVATE));
  3669 +
  3670 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_ACTUAL_LEVEL));
  3671 + TEST_ASSERT(gBus->ack != 0xffff);
  3672 +
  3673 + testPrimaryN_Check1(nrPrim);
  3674 +
  3675 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3676 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::COPY_REPORT_TO_TEMPORARY));
  3677 +
  3678 + testPrimaryN_Check2(nrPrim);
  3679 +}
  3680 +
  3681 +void testRGBWAF_Check1(uint8_t nrChan) {
  3682 + uint8_t control = 0;
  3683 +
  3684 + for (uint8_t i = 0; i < nrChan; ++i) {
  3685 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 201 + i));
  3686 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3687 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  3688 + TEST_ASSERT(gBus->ack == 255);
  3689 +
  3690 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 233 + i));
  3691 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3692 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  3693 + TEST_ASSERT(gBus->ack == 128 + i);
  3694 +
  3695 + control = (1 << i) + control;
  3696 + }
  3697 +
  3698 + control = 0x40 | control;
  3699 +
  3700 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 207));
  3701 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3702 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  3703 + TEST_ASSERT(gBus->ack == 255);
  3704 +
  3705 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 208));
  3706 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3707 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  3708 + TEST_ASSERT(gBus->ack == 255);
  3709 +
  3710 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 239));
  3711 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3712 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  3713 + TEST_ASSERT(gBus->ack == control);
  3714 +
  3715 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 240));
  3716 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3717 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  3718 + TEST_ASSERT(gBus->ack == 0x80);
  3719 +}
  3720 +
  3721 +void testRGBWAF_Check2(uint8_t nrChan) {
  3722 + uint8_t control = 0;
  3723 +
  3724 + for (uint8_t i = 0; i < nrChan; ++i) {
  3725 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 201 + i));
  3726 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3727 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  3728 + TEST_ASSERT(gBus->ack == 128 + i);
  3729 +
  3730 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 233 + i));
  3731 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3732 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  3733 + TEST_ASSERT(gBus->ack == 128 + i);
  3734 +
  3735 + control = (1 << i) + control;
  3736 + }
  3737 +
  3738 + control = 0x40 | control;
  3739 +
  3740 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 207));
  3741 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3742 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  3743 + TEST_ASSERT(gBus->ack == control);
  3744 +
  3745 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 208));
  3746 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3747 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  3748 + TEST_ASSERT(gBus->ack == 0x80);
  3749 +
  3750 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 239));
  3751 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3752 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  3753 + TEST_ASSERT(gBus->ack == control);
  3754 +
  3755 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 240));
  3756 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3757 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  3758 + TEST_ASSERT(gBus->ack == 0x80);
  3759 +}
  3760 +
  3761 +void testCopy_RGBWAF() {
  3762 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3763 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_TYPE_FEATURES));
  3764 + TEST_ASSERT(gBus->ack != 0xffff);
  3765 + uint8_t nrChan = (gBus->ack & 0xE0) >> 5;
  3766 +
  3767 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 0x7F));
  3768 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3769 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_RGBWAF_CONTROL));
  3770 +
  3771 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 128));
  3772 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_1, 129));
  3773 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_2, 130));
  3774 +
  3775 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3776 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_RGB_DIMLEVEL));
  3777 +
  3778 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 131));
  3779 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_1, 132));
  3780 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_2, 133));
  3781 +
  3782 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3783 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_WAF_DIMLEVEL));
  3784 +
  3785 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3786 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::ACTIVATE));
  3787 +
  3788 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_ACTUAL_LEVEL));
  3789 + TEST_ASSERT(gBus->ack != 0xffff);
  3790 +
  3791 + testRGBWAF_Check1(nrChan);
  3792 +
  3793 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3794 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::COPY_REPORT_TO_TEMPORARY));
  3795 +
  3796 + testRGBWAF_Check2(nrChan);
  3797 +}
  3798 +
  3799 +void testCopyReportToTemprary() {
  3800 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  3801 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  3802 + gTimer->run(300);
  3803 +
  3804 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3805 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_TYPE_FEATURES));
  3806 + TEST_ASSERT(gBus->ack != 0 && gBus->ack <= 255);
  3807 +
  3808 + uint8_t features = gBus->ack;
  3809 + bool supp[4];
  3810 + supp[0] = (features & DALI_DT8_COLOUR_TYPE_FEATURES_XY) != 0;
  3811 + supp[1] = (features & DALI_DT8_COLOUR_TYPE_FEATURES_TC) != 0;
  3812 + supp[2] = (features & DALI_DT8_COLOUR_TYPE_FEATURES_PRIMARY_N) != 0;
  3813 + supp[3] = (features & DALI_DT8_COLOUR_TYPE_FEATURES_RGBWAF) != 0;
  3814 +
  3815 + if (supp[0]) {
  3816 + activateColourType(0);
  3817 + testCopy_xy();
  3818 + }
  3819 +
  3820 + if (supp[1]) {
  3821 + activateColourType(1);
  3822 + testCopy_Tc();
  3823 + }
  3824 +
  3825 + if (supp[2]) {
  3826 + activateColourType(2);
  3827 + testCopy_PrimaryN();
  3828 + }
  3829 +
  3830 + if (supp[3]) {
  3831 + activateColourType(3);
  3832 + testCopy_RGBWAF();
  3833 + }
  3834 +}
  3835 +
  3836 +void checkDTR2Behaviour(uint8_t nrPrim) {
  3837 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  3838 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  3839 + gTimer->run(300);
  3840 +
  3841 + uint16_t expVal[] = { 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff };
  3842 + uint8_t i = 0;
  3843 + do {
  3844 + uint16_t j = 0;
  3845 + for (; j < nrPrim; ++j) {
  3846 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_2, j));
  3847 + expVal[j] = set16bitValue(255 - i);
  3848 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3849 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::STORE_TY_PRIMARY_N));
  3850 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::STORE_TY_PRIMARY_N));
  3851 + }
  3852 +
  3853 + for (; j < 256; ++j) {
  3854 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_2, j));
  3855 + set16bitValue(255 - i);
  3856 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3857 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::STORE_TY_PRIMARY_N));
  3858 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::STORE_TY_PRIMARY_N));
  3859 +
  3860 + for (uint8_t k = 0; k < nrPrim; ++k) {
  3861 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 66 + (k * 3)));
  3862 + uint16_t val = get16bitColourValue();
  3863 + TEST_ASSERT(val == expVal[k]);
  3864 + }
  3865 + }
  3866 + switch (i) {
  3867 + case 0:
  3868 + i = 128;
  3869 + break;
  3870 + case 128:
  3871 + i = 255;
  3872 + break;
  3873 + default:
  3874 + i = 0;
  3875 + break;
  3876 + }
  3877 + } while (i != 0);
  3878 +}
  3879 +
  3880 +void testStoreTyPrimaryN() {
  3881 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  3882 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  3883 + gTimer->run(300);
  3884 +
  3885 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3886 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_TYPE_FEATURES));
  3887 + TEST_ASSERT(gBus->ack != 0xffff);
  3888 + uint16_t nrPrim = (gBus->ack & 0x1C) >> 2;
  3889 +
  3890 + if (nrPrim > 0) {
  3891 + uint16_t TYprimary[] = { 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff };
  3892 +
  3893 + for (uint8_t j = 0; j < nrPrim; ++j) {
  3894 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 66 + (j * 3)));
  3895 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3896 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  3897 + TYprimary[j] = get16bitValue();
  3898 + }
  3899 +
  3900 + for (uint8_t k = 0; k < nrPrim; ++k) {
  3901 + uint8_t i = 0;
  3902 + do {
  3903 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_2, k));
  3904 + uint16_t expVal = set16bitValue(i);
  3905 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3906 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::STORE_TY_PRIMARY_N));
  3907 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::STORE_TY_PRIMARY_N));
  3908 +
  3909 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 66 + (k * 3)));
  3910 + uint16_t val = get16bitColourValue();
  3911 + TEST_ASSERT(val == expVal);
  3912 + switch (i) {
  3913 + case 0:
  3914 + i = 128;
  3915 + break;
  3916 + case 128:
  3917 + i = 255;
  3918 + break;
  3919 + default:
  3920 + i = 0;
  3921 + break;
  3922 + }
  3923 + } while (i != 0);
  3924 + }
  3925 +
  3926 + checkDTR2Behaviour(nrPrim);
  3927 +
  3928 + for (uint8_t m = 0; m < nrPrim; ++m) {
  3929 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_2, m));
  3930 + setSpecific16bitValue(TYprimary[m]);
  3931 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3932 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::STORE_TY_PRIMARY_N));
  3933 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::STORE_TY_PRIMARY_N));
  3934 + }
  3935 + }
  3936 +}
  3937 +
  3938 +void checkDTR2Behaviour_xy(uint8_t nrPrim) {
  3939 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  3940 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  3941 + gTimer->run(300);
  3942 +
  3943 + uint8_t i = 0;
  3944 + do {
  3945 + uint16_t j = 0;
  3946 + uint16_t expX[6];
  3947 + uint16_t expY[6];
  3948 + for (; j < nrPrim; ++j) {
  3949 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_2, j));
  3950 +
  3951 + expX[j] = set16bitValue(255 - i);
  3952 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3953 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_X_COORDINATE_WORD));
  3954 +
  3955 + expY[j] = set16bitValue(i);
  3956 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3957 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_Y_COORDINATE_WORD));
  3958 +
  3959 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3960 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::STORE_XY_COORDINATE_PRIMARY_N));
  3961 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::STORE_XY_COORDINATE_PRIMARY_N));
  3962 + }
  3963 +
  3964 + for (; j < 256; ++j) {
  3965 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_2, j));
  3966 +
  3967 + set16bitValue(i);
  3968 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3969 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_X_COORDINATE_WORD));
  3970 +
  3971 + set16bitValue(255 - i);
  3972 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3973 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_Y_COORDINATE_WORD));
  3974 +
  3975 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  3976 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::STORE_XY_COORDINATE_PRIMARY_N));
  3977 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::STORE_XY_COORDINATE_PRIMARY_N));
  3978 +
  3979 + for (uint8_t k = 0; k < nrPrim; ++k) {
  3980 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 64 + (k * 3)));
  3981 + uint16_t val = get16bitColourValue();
  3982 + TEST_ASSERT(val == expX[k]);
  3983 +
  3984 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 65 + (k * 3)));
  3985 + val = get16bitColourValue();
  3986 + TEST_ASSERT(val == expY[k]);
  3987 + }
  3988 + }
  3989 +
  3990 + switch (i) {
  3991 + case 0:
  3992 + i = 128;
  3993 + break;
  3994 + case 128:
  3995 + i = 255;
  3996 + break;
  3997 + default:
  3998 + i = 0;
  3999 + break;
  4000 + }
  4001 + } while (i != 0);
  4002 +}
  4003 +
  4004 +void testStoreXYCoordinatePrimaryN() {
  4005 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  4006 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  4007 + gTimer->run(300);
  4008 +
  4009 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  4010 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_TYPE_FEATURES));
  4011 + TEST_ASSERT(gBus->ack != 0xffff);
  4012 + uint16_t nrPrim = (gBus->ack & 0x1C) >> 2;
  4013 +
  4014 + if (nrPrim > 0) {
  4015 + uint16_t xprimary[6];
  4016 + uint16_t yprimary[6];
  4017 +
  4018 + for (uint8_t j = 0; j < nrPrim; ++j) {
  4019 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 64 + (j * 3)));
  4020 + xprimary[j] = get16bitColourValue();
  4021 +
  4022 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 65 + (j * 3)));
  4023 + yprimary[j] = get16bitColourValue();
  4024 + }
  4025 +
  4026 + uint8_t i = 0;
  4027 + do {
  4028 + for (uint8_t j = 0; j < nrPrim; ++j) {
  4029 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_2, j));
  4030 +
  4031 + uint16_t expX = set16bitValue(i);
  4032 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  4033 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_X_COORDINATE_WORD));
  4034 +
  4035 + uint16_t expY = set16bitValue(255 - i);
  4036 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  4037 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_Y_COORDINATE_WORD));
  4038 +
  4039 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  4040 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::STORE_XY_COORDINATE_PRIMARY_N));
  4041 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::STORE_XY_COORDINATE_PRIMARY_N));
  4042 +
  4043 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 64 + (j * 3)));
  4044 + uint16_t val = get16bitColourValue();
  4045 + TEST_ASSERT(val == expX);
  4046 +
  4047 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 65 + (j * 3)));
  4048 + val = get16bitColourValue();
  4049 + TEST_ASSERT(val == expY);
  4050 + }
  4051 +
  4052 + switch (i) {
  4053 + case 0:
  4054 + i = 128;
  4055 + break;
  4056 + case 128:
  4057 + i = 255;
  4058 + break;
  4059 + default:
  4060 + i = 0;
  4061 + break;
  4062 + }
  4063 + } while (i != 0);
  4064 +
  4065 + checkDTR2Behaviour_xy(nrPrim);
  4066 +
  4067 + for (uint8_t j = 0; j < nrPrim; ++j) {
  4068 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_2, j));
  4069 +
  4070 + setSpecific16bitValue(xprimary[j]);
  4071 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  4072 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_X_COORDINATE_WORD));
  4073 +
  4074 + setSpecific16bitValue(yprimary[j]);
  4075 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  4076 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_Y_COORDINATE_WORD));
  4077 +
  4078 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  4079 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::STORE_XY_COORDINATE_PRIMARY_N));
  4080 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::STORE_XY_COORDINATE_PRIMARY_N));
  4081 + }
  4082 + }
  4083 +}
  4084 +
  4085 +void tcCheckDTR2Behaviour() {
  4086 + const uint8_t ii[] = { 0, 1, 128, 254 };
  4087 + for (uint8_t i = 0; i < 4; ++i) {
  4088 + for (uint16_t j = 4; j < 256; ++j) {
  4089 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_2, j));
  4090 + set16bitValue(ii[i]);
  4091 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  4092 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::STORE_COLOUR_TEMPERATURE_LIMIT));
  4093 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::STORE_COLOUR_TEMPERATURE_LIMIT));
  4094 +
  4095 + uint16_t ans[3];
  4096 + for (uint8_t k = 128; k < 131; ++k) {
  4097 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, k));
  4098 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  4099 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  4100 + ans[k - 128] = get16bitValue();
  4101 + }
  4102 + TEST_ASSERT(ans[0] == 1);
  4103 + TEST_ASSERT(ans[0] == ans[1]);
  4104 + TEST_ASSERT(ans[1] == ans[2]);
  4105 + }
  4106 + }
  4107 +}
  4108 +
  4109 +void tcCheckLimits() {
  4110 + setSpecific16bitValue(1);
  4111 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_2, 2));
  4112 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  4113 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::STORE_COLOUR_TEMPERATURE_LIMIT));
  4114 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::STORE_COLOUR_TEMPERATURE_LIMIT));
  4115 +
  4116 + setSpecific16bitValue(0xfffe);
  4117 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_2, 3));
  4118 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  4119 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::STORE_COLOUR_TEMPERATURE_LIMIT));
  4120 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::STORE_COLOUR_TEMPERATURE_LIMIT));
  4121 +
  4122 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  4123 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  4124 + const uint8_t dtr2[] = { 3, 2, 3, 2, 2, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 3, 3, 2, 2, 2, 3 };
  4125 + const uint16_t tcValue[] = {
  4126 + 0xff00,
  4127 + 0x00ff,
  4128 + 0x000f,
  4129 + 0xfff0,
  4130 + 0x000f,
  4131 + 0x00f0,
  4132 + 0x0001,
  4133 + 0xff00,
  4134 + 0xfffe,
  4135 + 0xff00,
  4136 + 0x00ff,
  4137 + 0xff00,
  4138 + 0xff0f,
  4139 + 0x0001,
  4140 + 0xfffe,
  4141 + 0xffff,
  4142 + 0xff00,
  4143 + 0x00ff,
  4144 + 0xffff,
  4145 + 0x00ff,
  4146 + 0x0001 };
  4147 + const uint16_t expectedPC[] = {
  4148 + 0x0001,
  4149 + 0x00ff,
  4150 + 0x000f,
  4151 + 0xfff0,
  4152 + 0xfff0,
  4153 + 0x00f0,
  4154 + 0x000f,
  4155 + 0x000f,
  4156 + 0x000f,
  4157 + 0xff00,
  4158 + 0x00ff,
  4159 + 0x00ff,
  4160 + 0xff0f,
  4161 + 0x000f,
  4162 + 0xfff0,
  4163 + 0xffff,
  4164 + 0xffff,
  4165 + 0x00ff,
  4166 + 0xffff,
  4167 + 0x00ff,
  4168 + 0x0001 };
  4169 + const uint16_t expectedPW[] = {
  4170 + 0x0001,
  4171 + 0x00ff,
  4172 + 0x000f,
  4173 + 0xfff0,
  4174 + 0x000f,
  4175 + 0x000f,
  4176 + 0x000f,
  4177 + 0x000f,
  4178 + 0x000f,
  4179 + 0x000f,
  4180 + 0x000f,
  4181 + 0x000f,
  4182 + 0x000f,
  4183 + 0x000f,
  4184 + 0x000f,
  4185 + 0xffff,
  4186 + 0xffff,
  4187 + 0x00ff,
  4188 + 0xffff,
  4189 + 0x00ff,
  4190 + 0x0001 };
  4191 + const uint16_t expectedC[] = {
  4192 + 0xff00,
  4193 + 0xff00,
  4194 + 0x000f,
  4195 + 0xfff0,
  4196 + 0xfff0,
  4197 + 0xfff0,
  4198 + 0xfff0,
  4199 + 0xff00,
  4200 + 0xfff0,
  4201 + 0xfff0,
  4202 + 0x00ff,
  4203 + 0xff00,
  4204 + 0xff0f,
  4205 + 0x000f,
  4206 + 0xfff0,
  4207 + 0xffff,
  4208 + 0xff00,
  4209 + 0xff00,
  4210 + 0xffff,
  4211 + 0xffff,
  4212 + 0x0001 };
  4213 + const uint16_t expectedW[] = {
  4214 + 0xff00,
  4215 + 0xff00,
  4216 + 0x000f,
  4217 + 0xfff0,
  4218 + 0xfff0,
  4219 + 0xfff0,
  4220 + 0xfff0,
  4221 + 0xfff0,
  4222 + 0xfff0,
  4223 + 0xfff0,
  4224 + 0xfff0,
  4225 + 0xfff0,
  4226 + 0xfff0,
  4227 + 0xfff0,
  4228 + 0xfff0,
  4229 + 0xffff,
  4230 + 0xff00,
  4231 + 0xff00,
  4232 + 0xffff,
  4233 + 0xffff,
  4234 + 0x0001 };
  4235 +
  4236 + for (uint8_t j = 128; j < 132; ++j) {
  4237 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, j));
  4238 + uint16_t value = get16bitColourValue();
  4239 + switch (j) {
  4240 + case 128:
  4241 + TEST_ASSERT(value == 0x0001);
  4242 + break;
  4243 + case 129:
  4244 + TEST_ASSERT(value == 0x0001);
  4245 + break;
  4246 + case 130:
  4247 + TEST_ASSERT(value == 0xfffe);
  4248 + break;
  4249 + case 131:
  4250 + TEST_ASSERT(value == 0xfffe);
  4251 + break;
  4252 + }
  4253 + }
  4254 +
  4255 + for (uint8_t i = 0; i < 21; ++i) {
  4256 + setSpecific16bitValue(tcValue[i]);
  4257 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_2, dtr2[i]));
  4258 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  4259 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::STORE_COLOUR_TEMPERATURE_LIMIT));
  4260 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::STORE_COLOUR_TEMPERATURE_LIMIT));
  4261 +
  4262 + for (uint8_t j = 128; j < 132; ++j) {
  4263 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, j));
  4264 + uint16_t value = get16bitColourValue();
  4265 + switch (j) {
  4266 + case 128:
  4267 + TEST_ASSERT(value == expectedPC[i]);
  4268 + break;
  4269 + case 129:
  4270 + TEST_ASSERT(value == expectedPW[i]);
  4271 + break;
  4272 + case 130:
  4273 + TEST_ASSERT(value == expectedC[i]);
  4274 + break;
  4275 + case 131:
  4276 + TEST_ASSERT(value == expectedW[i]);
  4277 + break;
  4278 + }
  4279 + }
  4280 + }
  4281 +}
  4282 +
  4283 +void testStoreColourTemperatureLimit() {
  4284 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  4285 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  4286 +
  4287 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  4288 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_TYPE_FEATURES));
  4289 + TEST_ASSERT(gBus->ack != 0xffff);
  4290 + if ((gBus->ack & 0x02) == 0x02) {
  4291 + uint16_t coolest;
  4292 + uint16_t warmest;
  4293 + tcSavePhysicalLimits(&coolest, &warmest);
  4294 + tcCheckLimits();
  4295 + tcCheckDTR2Behaviour();
  4296 + tcRestorePhysicalLimits(coolest, warmest);
  4297 + }
  4298 +}
  4299 +
  4300 +void testStoreGearFeaturesStatus() {
  4301 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  4302 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  4303 + gTimer->run(300);
  4304 +
  4305 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  4306 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_GEAR_FEATURES_STATUS));
  4307 + TEST_ASSERT(gBus->ack != 0xffff);
  4308 +
  4309 + uint8_t features = gBus->ack;
  4310 +
  4311 + if ((features & 0x01) != 0) {
  4312 + features &= 0xfe;
  4313 + } else {
  4314 + features |= 0x01;
  4315 + }
  4316 +
  4317 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, features));
  4318 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  4319 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::STORE_GEAR_FEATURES_STATUS));
  4320 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::STORE_GEAR_FEATURES_STATUS));
  4321 +
  4322 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  4323 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_GEAR_FEATURES_STATUS));
  4324 + TEST_ASSERT(gBus->ack != 0xffff);
  4325 + TEST_ASSERT(gBus->ack == features);
  4326 +
  4327 + if ((features & 0x01) != 0) {
  4328 + features &= 0xfe;
  4329 + } else {
  4330 + features |= 0x01;
  4331 + }
  4332 +
  4333 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, features));
  4334 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  4335 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::STORE_GEAR_FEATURES_STATUS));
  4336 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::STORE_GEAR_FEATURES_STATUS));
  4337 +
  4338 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  4339 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_GEAR_FEATURES_STATUS));
  4340 + TEST_ASSERT(gBus->ack != 0xffff);
  4341 + TEST_ASSERT(gBus->ack == features);
  4342 +}
  4343 +
  4344 +void testAutoActivate_xy(uint8_t min_level, Command command, uint8_t dapc, uint32_t delay, uint8_t expected_level) {
  4345 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  4346 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  4347 +
  4348 + uint16_t point1_x = 0xffff;
  4349 + uint16_t point1_y = 0xffff;
  4350 + uint16_t point2_x = 0xffff;
  4351 + uint16_t point2_y = 0xffff;
  4352 + findTwoValid_xy_Points(&point1_x, &point1_y, &point2_x, &point2_y);
  4353 +
  4354 + load_xy_Coordinate(point2_x, point2_y);
  4355 +
  4356 + gBus->handleReceivedData(gTimer->time, genDataDPC(DALI_MASK, min_level));
  4357 +
  4358 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_ACTUAL_LEVEL));
  4359 + TEST_ASSERT(gBus->ack == min_level);
  4360 +
  4361 + uint16_t point_x = 0xffff;
  4362 + uint16_t point_y = 0xffff;
  4363 + uint8_t colour_type = get_actual_xy(&point_x, &point_y);
  4364 + TEST_ASSERT(colour_type == 0b00010000);
  4365 + TEST_ASSERT(point_x == point2_x);
  4366 + TEST_ASSERT(point_y == point2_y);
  4367 +
  4368 + load_xy_Coordinate(point1_x, point1_y);
  4369 +
  4370 + if (Command::DIRECT_POWER_CONTROL == command) {
  4371 + gBus->handleReceivedData(gTimer->time, genDataDPC(DALI_MASK, dapc));
  4372 + } else {
  4373 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, command));
  4374 + }
  4375 +
  4376 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_ACTUAL_LEVEL));
  4377 + TEST_ASSERT(gBus->ack == expected_level || expected_level == 255);
  4378 +
  4379 + colour_type = get_actual_xy(&point_x, &point_y);
  4380 + TEST_ASSERT(colour_type == 0b00010000);
  4381 + TEST_ASSERT(point_x == point1_x);
  4382 + TEST_ASSERT(point_y == point1_y);
  4383 +
  4384 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 8));
  4385 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_FADE_TIME));
  4386 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_FADE_TIME));
  4387 +
  4388 + load_xy_Coordinate(point2_x, point2_y);
  4389 +
  4390 + gBus->handleReceivedData(gTimer->time, genDataDPC(DALI_MASK, 0));
  4391 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_STATUS));
  4392 + TEST_ASSERT(gBus->ack != 0xffff);
  4393 + TEST_ASSERT((gBus->ack & 0b00010000) != 0);
  4394 +
  4395 + gBus->handleReceivedData(gTimer->time, genDataDPC(DALI_MASK, 255));
  4396 +
  4397 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_STATUS));
  4398 + TEST_ASSERT((gBus->ack & 0b00010000) == 0);
  4399 +
  4400 + uint8_t i = 192;
  4401 + do {
  4402 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, i));
  4403 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  4404 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  4405 + TEST_ASSERT(gBus->ack != 0xffff);
  4406 + uint16_t val = get16bitValue();
  4407 + if (i != 208) {
  4408 + TEST_ASSERT(val == 0xffff);
  4409 + } else {
  4410 + TEST_ASSERT((val & 0xff00) == 0xff00);
  4411 + }
  4412 + switch (i) {
  4413 + case 192:
  4414 + i = 193;
  4415 + break;
  4416 + case 193:
  4417 + i = 208;
  4418 + break;
  4419 + default:
  4420 + i = 0;
  4421 + break;
  4422 + }
  4423 + } while (i != 0);
  4424 +}
  4425 +
  4426 +void testNoAutoActivate_xy(uint8_t min_level, Command command, uint8_t dapc, uint32_t delay, uint8_t expected_level) {
  4427 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  4428 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  4429 +
  4430 + uint16_t point1_x = 0xffff;
  4431 + uint16_t point1_y = 0xffff;
  4432 + uint16_t point2_x = 0xffff;
  4433 + uint16_t point2_y = 0xffff;
  4434 + findTwoValid_xy_Points(&point1_x, &point1_y, &point2_x, &point2_y);
  4435 +
  4436 + load_xy_Coordinate(point2_x, point2_y);
  4437 +
  4438 + gBus->handleReceivedData(gTimer->time, genDataDPC(DALI_MASK, min_level));
  4439 +
  4440 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_ACTUAL_LEVEL));
  4441 + TEST_ASSERT(gBus->ack == min_level);
  4442 +
  4443 + uint16_t point_x = 0xffff;
  4444 + uint16_t point_y = 0xffff;
  4445 + uint8_t colour_type = get_actual_xy(&point_x, &point_y);
  4446 + TEST_ASSERT(colour_type == 0b00010000);
  4447 + TEST_ASSERT(point_x == point2_x);
  4448 + TEST_ASSERT(point_y == point2_y);
  4449 +
  4450 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 0));
  4451 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  4452 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::STORE_GEAR_FEATURES_STATUS));
  4453 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::STORE_GEAR_FEATURES_STATUS));
  4454 +
  4455 + load_xy_Coordinate(point1_x, point1_y);
  4456 +
  4457 + if (Command::DIRECT_POWER_CONTROL == command) {
  4458 + gBus->handleReceivedData(gTimer->time, genDataDPC(DALI_MASK, dapc));
  4459 + } else {
  4460 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, command));
  4461 + }
  4462 +
  4463 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_ACTUAL_LEVEL));
  4464 + TEST_ASSERT(gBus->ack == expected_level || expected_level == 255);
  4465 +
  4466 + colour_type = get_actual_xy(&point_x, &point_y);
  4467 + TEST_ASSERT(colour_type == 0b00010000);
  4468 + TEST_ASSERT(point_x == point2_x);
  4469 + TEST_ASSERT(point_y == point2_y);
  4470 +
  4471 + uint8_t i = 192;
  4472 + uint16_t expected = point1_x;
  4473 + do {
  4474 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, i));
  4475 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  4476 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  4477 + TEST_ASSERT(gBus->ack != 0xffff);
  4478 + uint16_t val = get16bitValue();
  4479 + if (i != 208) {
  4480 + TEST_ASSERT(val == expected);
  4481 + } else {
  4482 + TEST_ASSERT((val & 0xff00) == (expected << 8));
  4483 + }
  4484 + switch (i) {
  4485 + case 192:
  4486 + i = 193;
  4487 + expected = point1_y;
  4488 + break;
  4489 + case 193:
  4490 + i = 208;
  4491 + expected = 0b00010000;
  4492 + break;
  4493 + default:
  4494 + i = 0;
  4495 + break;
  4496 + }
  4497 + } while (i != 0);
  4498 +}
  4499 +
  4500 +void testAutoActivate_Tc(uint8_t min_level, Command command, uint8_t dapc, uint32_t delay, uint8_t expected_level) {
  4501 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  4502 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  4503 +
  4504 + uint16_t point1_Tc = 0;
  4505 + uint16_t point2_Tc = 0;
  4506 + findTwoValid_Tc_Points(&point1_Tc, &point2_Tc);
  4507 +
  4508 + load_Tc(point2_Tc);
  4509 +
  4510 + gTimer->run(500); // to disable DAPC sequence
  4511 + gBus->handleReceivedData(gTimer->time, genDataDPC(DALI_MASK, min_level));
  4512 +
  4513 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_ACTUAL_LEVEL));
  4514 + TEST_ASSERT(gBus->ack == min_level);
  4515 +
  4516 + uint16_t colorTemerature = 0xffff;
  4517 +
  4518 + uint8_t colorType = get_actual_Tc(&colorTemerature);
  4519 + TEST_ASSERT(colorType == 0x20);
  4520 + TEST_ASSERT(colorTemerature == point2_Tc);
  4521 +
  4522 + load_Tc(point1_Tc);
  4523 +
  4524 + if (Command::DIRECT_POWER_CONTROL == command) {
  4525 + gBus->handleReceivedData(gTimer->time, genDataDPC(DALI_MASK, dapc));
  4526 + } else {
  4527 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, command));
  4528 + }
  4529 +
  4530 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_ACTUAL_LEVEL));
  4531 + TEST_ASSERT(gBus->ack != 0xffff);
  4532 + if (expected_level != DALI_MASK) {
  4533 + TEST_ASSERT(gBus->ack == expected_level);
  4534 + }
  4535 +
  4536 + colorTemerature = 0xffff;
  4537 + colorType = get_actual_Tc(&colorTemerature);
  4538 + TEST_ASSERT(colorType == 0x20);
  4539 + TEST_ASSERT(colorTemerature == point1_Tc);
  4540 +
  4541 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 8));
  4542 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_FADE_TIME));
  4543 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_FADE_TIME));
  4544 +
  4545 + load_Tc(point2_Tc);
  4546 +
  4547 + gBus->handleReceivedData(gTimer->time, genDataDPC(DALI_MASK, 0));
  4548 +
  4549 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_STATUS));
  4550 + TEST_ASSERT(gBus->ack != 0xffff);
  4551 + TEST_ASSERT((gBus->ack & 0b00010000) != 0);
  4552 +
  4553 + gBus->handleReceivedData(gTimer->time, genDataDPC(DALI_MASK, 255));
  4554 +
  4555 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_STATUS));
  4556 + TEST_ASSERT(gBus->ack != 0xffff);
  4557 + TEST_ASSERT((gBus->ack & 0b00010000) == 0);
  4558 +
  4559 + uint8_t i = 194;
  4560 + do {
  4561 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, i));
  4562 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  4563 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  4564 + TEST_ASSERT(gBus->ack != 0xffff);
  4565 + uint16_t val = get16bitValue();
  4566 + if (i != 208) {
  4567 + TEST_ASSERT(val == 0xffff);
  4568 + } else {
  4569 + TEST_ASSERT((val & 0xff00) == 0xff00);
  4570 + }
  4571 + switch (i) {
  4572 + case 194:
  4573 + i = 208;
  4574 + break;
  4575 + default:
  4576 + i = 0;
  4577 + break;
  4578 + }
  4579 + } while (i != 0);
  4580 +}
  4581 +
  4582 +void testNoAutoActivate_Tc(uint8_t min_level, Command command, uint8_t dapc, uint32_t delay, uint8_t expected_level) {
  4583 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  4584 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  4585 + gTimer->run(300);
  4586 +
  4587 + uint16_t point1_Tc = 0;
  4588 + uint16_t point2_Tc = 0;
  4589 + findTwoValid_Tc_Points(&point1_Tc, &point2_Tc);
  4590 +
  4591 + load_Tc(point2_Tc);
  4592 +
  4593 +
  4594 + gBus->handleReceivedData(gTimer->time, genDataDPC(DALI_MASK, min_level));
  4595 +
  4596 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_ACTUAL_LEVEL));
  4597 + TEST_ASSERT(gBus->ack == min_level);
  4598 +
  4599 + uint16_t colorTemerature = 0xffff;
  4600 +
  4601 + uint8_t colorType = get_actual_Tc(&colorTemerature);
  4602 + TEST_ASSERT(colorType == 0x20);
  4603 + TEST_ASSERT(colorTemerature == point2_Tc);
  4604 +
  4605 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 0));
  4606 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  4607 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::STORE_GEAR_FEATURES_STATUS));
  4608 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::STORE_GEAR_FEATURES_STATUS));
  4609 +
  4610 + load_Tc(point1_Tc);
  4611 +
  4612 + if (Command::DIRECT_POWER_CONTROL == command) {
  4613 + gBus->handleReceivedData(gTimer->time, genDataDPC(DALI_MASK, dapc));
  4614 + } else {
  4615 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, command));
  4616 + }
  4617 +
  4618 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_ACTUAL_LEVEL));
  4619 + TEST_ASSERT(gBus->ack != 0xffff);
  4620 + if (expected_level != DALI_MASK) {
  4621 + TEST_ASSERT(gBus->ack == expected_level);
  4622 + }
  4623 +
  4624 + colorTemerature = 0xffff;
  4625 + colorType = get_actual_Tc(&colorTemerature);
  4626 + TEST_ASSERT(colorType == 0x20);
  4627 + TEST_ASSERT(colorTemerature == point2_Tc);
  4628 +
  4629 + uint8_t i = 194;
  4630 + uint16_t expected = point1_Tc;
  4631 + do {
  4632 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, i));
  4633 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  4634 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  4635 + TEST_ASSERT(gBus->ack != 0xffff);
  4636 + uint16_t val = get16bitValue();
  4637 + if (i != 208) {
  4638 + TEST_ASSERT(val == expected);
  4639 + } else {
  4640 + TEST_ASSERT((val & 0xff00) == (0xff00 & (expected << 8)));
  4641 + }
  4642 + switch (i) {
  4643 + case 194:
  4644 + i = 208;
  4645 + expected = 0b00100000;
  4646 + break;
  4647 + default:
  4648 + i = 0;
  4649 + break;
  4650 + }
  4651 + } while (i != 0);
  4652 +}
  4653 +
  4654 +uint8_t get_actual_primaryN(uint16_t* point) {
  4655 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 240));
  4656 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  4657 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  4658 + TEST_ASSERT(gBus->ack != 0xffff);
  4659 + uint8_t colour_type = gBus->ack;
  4660 +
  4661 + for (uint8_t i = 0; i < 6; ++ i) {
  4662 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 227 + i));
  4663 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  4664 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  4665 + TEST_ASSERT(gBus->ack != 0xffff);
  4666 + point[i] = get16bitValue();
  4667 + }
  4668 + return colour_type;
  4669 +}
  4670 +
  4671 +
  4672 +void testAutoActivate_PrimaryN(uint8_t min_level, Command command, uint8_t dapc, uint32_t delay, uint8_t expected_level) {
  4673 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  4674 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  4675 + gTimer->run(300);
  4676 +
  4677 + uint16_t point1_PrimaryN[6] = { 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff };
  4678 + uint16_t point2_PrimaryN[6] = { 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff };
  4679 +
  4680 + findTwoValid_PrimaryN_Points(point1_PrimaryN, point2_PrimaryN);
  4681 +
  4682 + load_PrimaryN(point2_PrimaryN);
  4683 +
  4684 + gBus->handleReceivedData(gTimer->time, genDataDPC(DALI_MASK, min_level));
  4685 +
  4686 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_ACTUAL_LEVEL));
  4687 + TEST_ASSERT(gBus->ack == min_level);
  4688 +
  4689 + uint16_t point_PrimaryN[] = { 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff };
  4690 + uint8_t colour_type = get_actual_primaryN(point_PrimaryN);
  4691 +
  4692 + bool value_ok = (point2_PrimaryN[0] == point_PrimaryN[0])
  4693 + && (point2_PrimaryN[1] == point_PrimaryN[1])
  4694 + && (point2_PrimaryN[2] == point_PrimaryN[2])
  4695 + && (point2_PrimaryN[3] == point_PrimaryN[3])
  4696 + && (point2_PrimaryN[4] == point_PrimaryN[4])
  4697 + && (point2_PrimaryN[5] == point_PrimaryN[5]);
  4698 + TEST_ASSERT(value_ok);
  4699 + TEST_ASSERT(colour_type == 0b01000000);
  4700 +
  4701 + load_PrimaryN(point1_PrimaryN);
  4702 +
  4703 + if (Command::DIRECT_POWER_CONTROL == command) {
  4704 + gBus->handleReceivedData(gTimer->time, genDataDPC(DALI_MASK, dapc));
  4705 + } else {
  4706 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, command));
  4707 + }
  4708 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_ACTUAL_LEVEL));
  4709 + TEST_ASSERT(gBus->ack == expected_level || expected_level == 255);
  4710 +
  4711 + colour_type = get_actual_primaryN(point_PrimaryN);
  4712 +
  4713 + value_ok = (point1_PrimaryN[0] == point_PrimaryN[0])
  4714 + && (point1_PrimaryN[1] == point_PrimaryN[1])
  4715 + && (point1_PrimaryN[2] == point_PrimaryN[2])
  4716 + && (point1_PrimaryN[3] == point_PrimaryN[3])
  4717 + && (point1_PrimaryN[4] == point_PrimaryN[4])
  4718 + && (point1_PrimaryN[5] == point_PrimaryN[5]);
  4719 + TEST_ASSERT(value_ok);
  4720 + TEST_ASSERT(colour_type == 0b01000000);
  4721 +
  4722 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 8));
  4723 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_FADE_TIME));
  4724 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_FADE_TIME));
  4725 +
  4726 + load_PrimaryN(point2_PrimaryN);
  4727 +
  4728 + gBus->handleReceivedData(gTimer->time, genDataDPC(DALI_MASK, 0));
  4729 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_STATUS));
  4730 + TEST_ASSERT((gBus->ack & 0b00010000) != 0);
  4731 +
  4732 + gBus->handleReceivedData(gTimer->time, genDataDPC(DALI_MASK, 255));
  4733 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_STATUS));
  4734 + TEST_ASSERT((gBus->ack & 0b00010000) == 0);
  4735 +
  4736 + uint8_t i = 195;
  4737 + do {
  4738 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, i));
  4739 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  4740 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  4741 + uint16_t val = get16bitValue();
  4742 + if (i != 208) {
  4743 + TEST_ASSERT(val == 0xffff);
  4744 + } else {
  4745 + TEST_ASSERT((val & 0xff00) == 0xff00);
  4746 + }
  4747 + switch (i) {
  4748 + case 195:
  4749 + case 196:
  4750 + case 197:
  4751 + case 198:
  4752 + case 199:
  4753 + i = i + 1;
  4754 + break;
  4755 + case 200:
  4756 + i = 208;
  4757 + break;
  4758 + default:
  4759 + i = 0;
  4760 + break;
  4761 + }
  4762 + } while (i != 0);
  4763 +}
  4764 +
  4765 +void testNoAutoActivate_PrimaryN(uint8_t min_level, Command command, uint8_t dapc, uint32_t delay, uint8_t expected_level) {
  4766 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  4767 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  4768 + gTimer->run(300);
  4769 +
  4770 + uint16_t point1_PrimaryN[6] = { 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff };
  4771 + uint16_t point2_PrimaryN[6] = { 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff };
  4772 +
  4773 + findTwoValid_PrimaryN_Points(point1_PrimaryN, point2_PrimaryN);
  4774 +
  4775 + load_PrimaryN(point2_PrimaryN);
  4776 +
  4777 + gBus->handleReceivedData(gTimer->time, genDataDPC(DALI_MASK, min_level));
  4778 +
  4779 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_ACTUAL_LEVEL));
  4780 + TEST_ASSERT(gBus->ack == min_level);
  4781 +
  4782 + uint16_t point_PrimaryN[] = { 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff };
  4783 + uint8_t colour_type = get_actual_primaryN(point_PrimaryN);
  4784 +
  4785 + bool value_ok = (point2_PrimaryN[0] == point_PrimaryN[0])
  4786 + && (point2_PrimaryN[1] == point_PrimaryN[1])
  4787 + && (point2_PrimaryN[2] == point_PrimaryN[2])
  4788 + && (point2_PrimaryN[3] == point_PrimaryN[3])
  4789 + && (point2_PrimaryN[4] == point_PrimaryN[4])
  4790 + && (point2_PrimaryN[5] == point_PrimaryN[5]);
  4791 + TEST_ASSERT(value_ok);
  4792 + TEST_ASSERT(colour_type == 0b01000000);
  4793 +
  4794 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 0));
  4795 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  4796 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::STORE_GEAR_FEATURES_STATUS));
  4797 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::STORE_GEAR_FEATURES_STATUS));
  4798 +
  4799 + load_PrimaryN(point1_PrimaryN);
  4800 + if (Command::DIRECT_POWER_CONTROL == command) {
  4801 + gBus->handleReceivedData(gTimer->time, genDataDPC(DALI_MASK, dapc));
  4802 + } else {
  4803 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, command));
  4804 + }
  4805 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_ACTUAL_LEVEL));
  4806 + TEST_ASSERT(gBus->ack == expected_level || expected_level == 255);
  4807 +
  4808 + colour_type = get_actual_primaryN(point_PrimaryN);
  4809 + value_ok = (point2_PrimaryN[0] == point_PrimaryN[0])
  4810 + && (point2_PrimaryN[1] == point_PrimaryN[1])
  4811 + && (point2_PrimaryN[2] == point_PrimaryN[2])
  4812 + && (point2_PrimaryN[3] == point_PrimaryN[3])
  4813 + && (point2_PrimaryN[4] == point_PrimaryN[4])
  4814 + && (point2_PrimaryN[5] == point_PrimaryN[5]);
  4815 + TEST_ASSERT(value_ok);
  4816 + TEST_ASSERT(colour_type == 0b01000000);
  4817 +
  4818 + uint8_t i = 195;
  4819 + uint8_t j = 0;
  4820 + uint16_t expected = point1_PrimaryN[j];
  4821 + do {
  4822 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, i));
  4823 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  4824 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  4825 + uint16_t val = get16bitValue();
  4826 + if (i != 208) {
  4827 + TEST_ASSERT(val == expected);
  4828 + } else {
  4829 + TEST_ASSERT((val & 0xff00) == (expected << 8));
  4830 + }
  4831 + switch (i) {
  4832 + case 195:
  4833 + case 196:
  4834 + case 197:
  4835 + case 198:
  4836 + case 199:
  4837 + i = i + 1;
  4838 + j++;
  4839 + expected = point1_PrimaryN[j];
  4840 + break;
  4841 + case 200:
  4842 + i = 208;
  4843 + expected = 0b01000000;
  4844 + break;
  4845 + default:
  4846 + i = 0;
  4847 + break;
  4848 + }
  4849 + } while (i != 0);
  4850 +}
  4851 +
  4852 +uint8_t get_actual_RGBWAF(uint8_t* point) {
  4853 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 240));
  4854 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  4855 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  4856 + TEST_ASSERT(gBus->ack != 0xffff);
  4857 + uint8_t colour_type = gBus->ack;
  4858 +
  4859 + for (uint8_t i = 0; i < 6; ++i) {
  4860 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 233 + i));
  4861 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  4862 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  4863 + TEST_ASSERT(gBus->ack != 0xffff);
  4864 + point[i] = gBus->ack;
  4865 + }
  4866 + return colour_type;
  4867 +}
  4868 +
  4869 +void testAutoActivate_RGBWAF(uint8_t min_level, Command command, uint8_t dapc, uint32_t delay, uint8_t expected_level) {
  4870 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  4871 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  4872 + gTimer->run(300);
  4873 +
  4874 + uint8_t point1_RGBWAF[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
  4875 + uint8_t point2_RGBWAF[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
  4876 + findTwoValid_RGBWAF_Pionts(point1_RGBWAF, point2_RGBWAF);
  4877 +
  4878 + load_RGBWAF(point2_RGBWAF);
  4879 +
  4880 + gBus->handleReceivedData(gTimer->time, genDataDPC(DALI_MASK, min_level));
  4881 +
  4882 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_ACTUAL_LEVEL));
  4883 + TEST_ASSERT(gBus->ack == min_level);
  4884 +
  4885 + uint8_t point_RGBWAF[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
  4886 + uint8_t colour_type = get_actual_RGBWAF(point_RGBWAF);
  4887 +
  4888 + bool value_ok = (point2_RGBWAF[0] == point_RGBWAF[0])
  4889 + && (point2_RGBWAF[1] == point_RGBWAF[1])
  4890 + && (point2_RGBWAF[2] == point_RGBWAF[2])
  4891 + && (point2_RGBWAF[3] == point_RGBWAF[3])
  4892 + && (point2_RGBWAF[4] == point_RGBWAF[4])
  4893 + && (point2_RGBWAF[5] == point_RGBWAF[5]);
  4894 + TEST_ASSERT(value_ok);
  4895 + TEST_ASSERT(colour_type == 0b10000000);
  4896 +
  4897 + load_RGBWAF(point1_RGBWAF);
  4898 +
  4899 + if (Command::DIRECT_POWER_CONTROL == command) {
  4900 + gBus->handleReceivedData(gTimer->time, genDataDPC(DALI_MASK, dapc));
  4901 + } else {
  4902 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, command));
  4903 + }
  4904 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_ACTUAL_LEVEL));
  4905 + TEST_ASSERT(gBus->ack == expected_level || expected_level == 255);
  4906 +
  4907 + colour_type = get_actual_RGBWAF(point_RGBWAF);
  4908 +
  4909 + value_ok = (point1_RGBWAF[0] == point_RGBWAF[0])
  4910 + && (point1_RGBWAF[1] == point_RGBWAF[1])
  4911 + && (point1_RGBWAF[2] == point_RGBWAF[2])
  4912 + && (point1_RGBWAF[3] == point_RGBWAF[3])
  4913 + && (point1_RGBWAF[4] == point_RGBWAF[4])
  4914 + && (point1_RGBWAF[5] == point_RGBWAF[5]);
  4915 + TEST_ASSERT(value_ok);
  4916 + TEST_ASSERT(colour_type == 0b10000000);
  4917 +
  4918 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 8));
  4919 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_FADE_TIME));
  4920 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_FADE_TIME));
  4921 +
  4922 + load_RGBWAF(point2_RGBWAF);
  4923 +
  4924 + gBus->handleReceivedData(gTimer->time, genDataDPC(DALI_MASK, 0));
  4925 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_STATUS));
  4926 + TEST_ASSERT((gBus->ack & 0b00010000) != 0);
  4927 +
  4928 + gBus->handleReceivedData(gTimer->time, genDataDPC(DALI_MASK, 255));
  4929 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_STATUS));
  4930 + TEST_ASSERT((gBus->ack & 0b00010000) == 0);
  4931 +
  4932 + uint8_t i = 201;
  4933 + uint8_t j = 0;
  4934 + do {
  4935 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, i));
  4936 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  4937 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  4938 + uint16_t val = get16bitValue();
  4939 + TEST_ASSERT(val == 0xffff);
  4940 + switch (i) {
  4941 + case 201:
  4942 + case 202:
  4943 + case 203:
  4944 + case 204:
  4945 + case 205:
  4946 + i = i + 1;
  4947 + j++;
  4948 + break;
  4949 + case 206:
  4950 + i = 208;
  4951 + break;
  4952 + default:
  4953 + i = 0;
  4954 + break;
  4955 + }
  4956 + } while (i != 0);
  4957 +}
  4958 +
  4959 +void testNoAutoActivate_RGBWAF(uint8_t min_level, Command command, uint8_t dapc, uint32_t delay, uint8_t expected_level) {
  4960 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  4961 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  4962 + gTimer->run(300);
  4963 +
  4964 + uint8_t point1_RGBWAF[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
  4965 + uint8_t point2_RGBWAF[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
  4966 + findTwoValid_RGBWAF_Pionts(point1_RGBWAF, point2_RGBWAF);
  4967 +
  4968 + load_RGBWAF(point2_RGBWAF);
  4969 +
  4970 + gBus->handleReceivedData(gTimer->time, genDataDPC(DALI_MASK, min_level));
  4971 +
  4972 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_ACTUAL_LEVEL));
  4973 + TEST_ASSERT(gBus->ack == min_level);
  4974 +
  4975 + uint8_t point_RGBWAF[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
  4976 + uint8_t colour_type = get_actual_RGBWAF(point_RGBWAF);
  4977 +
  4978 + bool value_ok = (point2_RGBWAF[0] == point_RGBWAF[0])
  4979 + && (point2_RGBWAF[1] == point_RGBWAF[1])
  4980 + && (point2_RGBWAF[2] == point_RGBWAF[2])
  4981 + && (point2_RGBWAF[3] == point_RGBWAF[3])
  4982 + && (point2_RGBWAF[4] == point_RGBWAF[4])
  4983 + && (point2_RGBWAF[5] == point_RGBWAF[5]);
  4984 + TEST_ASSERT(value_ok);
  4985 + TEST_ASSERT(colour_type == 0b10000000);
  4986 +
  4987 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 0));
  4988 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  4989 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::STORE_GEAR_FEATURES_STATUS));
  4990 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::STORE_GEAR_FEATURES_STATUS));
  4991 +
  4992 + load_RGBWAF(point1_RGBWAF);
  4993 +
  4994 + if (Command::DIRECT_POWER_CONTROL == command) {
  4995 + gBus->handleReceivedData(gTimer->time, genDataDPC(DALI_MASK, dapc));
  4996 + } else {
  4997 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, command));
  4998 + }
  4999 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_ACTUAL_LEVEL));
  5000 + TEST_ASSERT(gBus->ack == expected_level || expected_level == 255);
  5001 +
  5002 + colour_type = get_actual_RGBWAF(point_RGBWAF);
  5003 +
  5004 + value_ok = (point2_RGBWAF[0] == point_RGBWAF[0])
  5005 + && (point2_RGBWAF[1] == point_RGBWAF[1])
  5006 + && (point2_RGBWAF[2] == point_RGBWAF[2])
  5007 + && (point2_RGBWAF[3] == point_RGBWAF[3])
  5008 + && (point2_RGBWAF[4] == point_RGBWAF[4])
  5009 + && (point2_RGBWAF[5] == point_RGBWAF[5]);
  5010 + TEST_ASSERT(value_ok);
  5011 + TEST_ASSERT(colour_type == 0b10000000);
  5012 +
  5013 + uint8_t i = 201;
  5014 + uint8_t j = 0;
  5015 + uint16_t expected = point1_RGBWAF[j];
  5016 + do {
  5017 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, i));
  5018 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5019 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  5020 + TEST_ASSERT(gBus->ack == expected);
  5021 + switch (i) {
  5022 + case 201:
  5023 + case 202:
  5024 + case 203:
  5025 + case 204:
  5026 + case 205:
  5027 + i = i + 1;
  5028 + j++;
  5029 + expected = point1_RGBWAF[j];
  5030 + break;
  5031 + case 206:
  5032 + i = 208;
  5033 + expected = 0b10000000;
  5034 + break;
  5035 + default:
  5036 + i = 0;
  5037 + break;
  5038 + }
  5039 + } while (i != 0);
  5040 +}
  5041 +
  5042 +void testAutoActivate_Dapc0Herlper(uint8_t col, uint16_t val, bool autoaAtivation) {
  5043 + setTemporaries(col, val);
  5044 + gBus->handleReceivedData(gTimer->time, genDataDPC(DALI_MASK, 0));
  5045 +
  5046 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_STATUS));
  5047 + TEST_ASSERT((gBus->ack & 0b00000100) == 0);
  5048 +
  5049 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_ACTUAL_LEVEL));
  5050 + TEST_ASSERT(gBus->ack == 0);
  5051 +
  5052 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 208));
  5053 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5054 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  5055 +
  5056 + if (autoaAtivation) {
  5057 + TEST_ASSERT(gBus->ack == 0xff);
  5058 + } else {
  5059 + TEST_ASSERT(gBus->ack != 0xff);
  5060 + }
  5061 +
  5062 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RECALL_MAX_LEVEL));
  5063 +}
  5064 +
  5065 +void toggleAutoActivation(bool autoActivation) {
  5066 + autoActivation = !autoActivation;
  5067 +
  5068 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, autoActivation ? 0x01 : 0x00));
  5069 +
  5070 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5071 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::STORE_GEAR_FEATURES_STATUS));
  5072 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::STORE_GEAR_FEATURES_STATUS));
  5073 +}
  5074 +
  5075 +void testAutoActivate_Dapc0() {
  5076 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  5077 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  5078 +
  5079 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5080 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_TYPE_FEATURES));
  5081 + TEST_ASSERT(gBus->ack != 0xffff);
  5082 +
  5083 + uint8_t features = gBus->ack;
  5084 + bool supp[4];
  5085 + supp[0] = (features & DALI_DT8_COLOUR_TYPE_FEATURES_XY) != 0;
  5086 + supp[1] = (features & DALI_DT8_COLOUR_TYPE_FEATURES_TC) != 0;
  5087 + supp[2] = (features & DALI_DT8_COLOUR_TYPE_FEATURES_PRIMARY_N) != 0;
  5088 + supp[3] = (features & DALI_DT8_COLOUR_TYPE_FEATURES_RGBWAF) != 0;
  5089 +
  5090 + uint16_t val = 128;
  5091 + for (uint8_t col = 0; col < 4; ++col) {
  5092 + if (supp[0]) {
  5093 + testAutoActivate_Dapc0Herlper(0, val, true);
  5094 + toggleAutoActivation(true);
  5095 +
  5096 + testAutoActivate_Dapc0Herlper(0, val, false);
  5097 + toggleAutoActivation(false);
  5098 + }
  5099 + if (supp[1]) {
  5100 + testAutoActivate_Dapc0Herlper(1, val, true);
  5101 + toggleAutoActivation(true);
  5102 +
  5103 + testAutoActivate_Dapc0Herlper(1, val, false);
  5104 + toggleAutoActivation(false);
  5105 + }
  5106 + if (supp[2]) {
  5107 + testAutoActivate_Dapc0Herlper(2, val, true);
  5108 + toggleAutoActivation(true);
  5109 +
  5110 + testAutoActivate_Dapc0Herlper(2, val, false);
  5111 + toggleAutoActivation(false);
  5112 + }
  5113 + if (supp[3]) {
  5114 + testAutoActivate_Dapc0Herlper(3, val, true);
  5115 + toggleAutoActivation(true);
  5116 +
  5117 + testAutoActivate_Dapc0Herlper(3, val, false);
  5118 + toggleAutoActivation(false);
  5119 + }
  5120 + }
  5121 +}
  5122 +
  5123 +void testAutoActivate_Off() {
  5124 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  5125 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  5126 +
  5127 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5128 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_TYPE_FEATURES));
  5129 + TEST_ASSERT(gBus->ack != 0xffff);
  5130 +
  5131 + uint8_t features = gBus->ack;
  5132 + bool supp[4];
  5133 + supp[0] = (features & DALI_DT8_COLOUR_TYPE_FEATURES_XY) != 0;
  5134 + supp[1] = (features & DALI_DT8_COLOUR_TYPE_FEATURES_TC) != 0;
  5135 + supp[2] = (features & DALI_DT8_COLOUR_TYPE_FEATURES_PRIMARY_N) != 0;
  5136 + supp[3] = (features & DALI_DT8_COLOUR_TYPE_FEATURES_RGBWAF) != 0;
  5137 +
  5138 + uint16_t val = 128;
  5139 + for (uint8_t col = 0; col < 4; ++col) {
  5140 + if (supp[col]) {
  5141 + testAutoActivateOffHerlper(col, val, true);
  5142 + toggleAutoActivation(true);
  5143 +
  5144 + testAutoActivateOffHerlper(col, val, false);
  5145 + toggleAutoActivation(false);
  5146 + }
  5147 + if (supp[col]) {
  5148 + testAutoActivateOffHerlper(col, val, true);
  5149 + toggleAutoActivation(true);
  5150 +
  5151 + testAutoActivateOffHerlper(col, val, false);
  5152 + toggleAutoActivation(false);
  5153 + }
  5154 + if (supp[col]) {
  5155 + testAutoActivateOffHerlper(col, val, true);
  5156 + toggleAutoActivation(true);
  5157 +
  5158 + testAutoActivateOffHerlper(col, val, false);
  5159 + toggleAutoActivation(false);
  5160 + }
  5161 + if (supp[col]) {
  5162 + testAutoActivateOffHerlper(col, val, true);
  5163 + toggleAutoActivation(true);
  5164 +
  5165 + testAutoActivateOffHerlper(col, val, false);
  5166 + toggleAutoActivation(false);
  5167 + }
  5168 + }
  5169 +}
  5170 +
  5171 +void testAutomaticActivate() {
  5172 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  5173 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  5174 +
  5175 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5176 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_TYPE_FEATURES));
  5177 + TEST_ASSERT(gBus->ack != 0xffff);
  5178 +
  5179 + uint8_t features = gBus->ack;
  5180 + bool supp[4];
  5181 + supp[0] = (features & DALI_DT8_COLOUR_TYPE_FEATURES_XY) != 0;
  5182 + supp[1] = (features & DALI_DT8_COLOUR_TYPE_FEATURES_TC) != 0;
  5183 + supp[2] = (features & DALI_DT8_COLOUR_TYPE_FEATURES_PRIMARY_N) != 0;
  5184 + supp[3] = (features & DALI_DT8_COLOUR_TYPE_FEATURES_RGBWAF) != 0;
  5185 +
  5186 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_MIN_LEVEL));
  5187 + TEST_ASSERT(gBus->ack != 0xffff);
  5188 + uint8_t minLevel = gBus->ack;
  5189 + uint8_t minLevel1 = minLevel + 1;
  5190 +
  5191 + const Command cmd[] = {
  5192 + Command::DIRECT_POWER_CONTROL,
  5193 + Command::DIRECT_POWER_CONTROL,
  5194 + Command::DIRECT_POWER_CONTROL,
  5195 + Command::OFF,
  5196 + Command::UP,
  5197 + Command::DOWN,
  5198 + Command::STEP_UP,
  5199 + Command::STEP_DOWN,
  5200 + Command::RECALL_MAX_LEVEL,
  5201 + Command::RECALL_MIN_LEVEL,
  5202 + Command::STEP_DOWN_AND_OFF,
  5203 + Command::ON_AND_STEP_UP, };
  5204 +
  5205 + const uint8_t dapc[] = { 0, 254, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
  5206 + const uint32_t delay[] = { 0, 0, 0, 0, 220, 220, 0, 0, 0, 0, 0, 0 };
  5207 + const uint8_t expected[] = { 0, 254, minLevel, 0, DALI_MASK, DALI_MASK, minLevel1, minLevel, 254, minLevel, 0, minLevel1 };
  5208 +
  5209 + for (uint16_t i = 0; i < 12; ++i) {
  5210 + if (supp[0]) {
  5211 + testAutoActivate_xy(minLevel, cmd[i], dapc[i], delay[i], expected[i]);
  5212 + testNoAutoActivate_xy(minLevel, cmd[i], dapc[i], delay[i], expected[i]);
  5213 + }
  5214 + if (supp[1]) {
  5215 + testAutoActivate_Tc(minLevel, cmd[i], dapc[i], delay[i], expected[i]);
  5216 + testNoAutoActivate_Tc(minLevel, cmd[i], dapc[i], delay[i], expected[i]);
  5217 + }
  5218 + if (supp[2]) {
  5219 + testAutoActivate_PrimaryN(minLevel, cmd[i], dapc[i], delay[i], expected[i]);
  5220 + testNoAutoActivate_PrimaryN(minLevel, cmd[i], dapc[i], delay[i], expected[i]);
  5221 + }
  5222 + if (supp[3]) {
  5223 + testAutoActivate_RGBWAF(minLevel, cmd[i], dapc[i], delay[i], expected[i]);
  5224 + testNoAutoActivate_RGBWAF(minLevel, cmd[i], dapc[i], delay[i], expected[i]);
  5225 + }
  5226 + }
  5227 +
  5228 + testAutoActivate_Dapc0();
  5229 + testAutoActivate_Off();
  5230 +}
  5231 +
  5232 +void testAssignColourToLinkedChannel() {
  5233 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  5234 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  5235 + gTimer->run(300);
  5236 +
  5237 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5238 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_TYPE_FEATURES));
  5239 + TEST_ASSERT(gBus->ack != 0xffff);
  5240 + uint8_t nrChan = ((gBus->ack and 0xE0) >> 5);
  5241 + if (nrChan > 0) {
  5242 + for (uint8_t i = 0; i < nrChan; ++i) {
  5243 + uint8_t j = 0;
  5244 + do {
  5245 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 15));
  5246 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5247 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  5248 + TEST_ASSERT(gBus->ack != 0xffff);
  5249 + uint8_t control = gBus->ack;
  5250 +
  5251 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 1 << i));
  5252 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5253 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_RGBWAF_CONTROL));
  5254 +
  5255 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, j));
  5256 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5257 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::ASSIGN_COLOUR_TO_LINKED_CHANNEL));
  5258 +
  5259 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, i));
  5260 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5261 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_ASSIGNED_COLOUR));
  5262 + TEST_ASSERT(gBus->ack != 0xffff);
  5263 + if (j == 0) {
  5264 + TEST_ASSERT(gBus->ack != 0);
  5265 + } else if (j <= 6) {
  5266 + TEST_ASSERT(gBus->ack != j);
  5267 + } else {
  5268 + TEST_ASSERT(gBus->ack != 6);
  5269 + }
  5270 +
  5271 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 207));
  5272 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5273 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  5274 + TEST_ASSERT(gBus->ack == 255);
  5275 +
  5276 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 208));
  5277 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5278 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  5279 + TEST_ASSERT(gBus->ack == 255);
  5280 +
  5281 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 15));
  5282 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5283 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  5284 + TEST_ASSERT(gBus->ack == control);
  5285 +
  5286 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5287 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_GROUPS_H));
  5288 + TEST_ASSERT(gBus->ack == 0x80);
  5289 +
  5290 + switch (j) {
  5291 + case 0:
  5292 + case 1:
  5293 + case 2:
  5294 + case 3:
  5295 + case 4:
  5296 + case 5:
  5297 + case 6:
  5298 + j++;
  5299 + break;
  5300 + case 7:
  5301 + j = 255;
  5302 + break;
  5303 + default:
  5304 + j = 0;
  5305 + break;
  5306 + }
  5307 + } while (j != 0);
  5308 + }
  5309 + }
  5310 +}
  5311 +
  5312 +void testStartAutoCalibration() {
  5313 + // TODO 12.7.2.8
  5314 +}
  5315 +
  5316 +void testPowerOnBehaviour_xy() {
  5317 + uint16_t point1_x = 0xffff;
  5318 + uint16_t point1_y = 0xffff;
  5319 + uint16_t point2_x = 0xffff;
  5320 + uint16_t point2_y = 0xffff;
  5321 + findTwoValid_xy_Points(&point1_x, &point1_y, &point2_x, &point2_y);
  5322 +
  5323 + setSpecific16bitValue(point1_x);
  5324 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5325 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_X_COORDINATE_WORD));
  5326 +
  5327 + setSpecific16bitValue(point1_y);
  5328 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5329 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_Y_COORDINATE_WORD));
  5330 +
  5331 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_PHISICAL_MIN_LEVEL));
  5332 + TEST_ASSERT(gBus->ack != 0xffff);
  5333 + uint8_t phm = gBus->ack;
  5334 +
  5335 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_POWER_ON_LEVEL));
  5336 + TEST_ASSERT(gBus->ack != 0xffff);
  5337 +
  5338 + uint8_t storedPOL;
  5339 + if (gBus->ack == 254) {
  5340 + storedPOL = phm;
  5341 + } else {
  5342 + storedPOL = gBus->ack + 1;
  5343 + }
  5344 +
  5345 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, storedPOL));
  5346 +
  5347 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_POWER_ON_LEVEL));
  5348 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_POWER_ON_LEVEL));
  5349 +
  5350 + goto_xy_Coordinate(point2_x, point2_y);
  5351 +
  5352 + gSlave->notifyPowerDown();
  5353 + delete gSlave; // Simulate power off
  5354 + gSlave = gCreateSlave(gMemory, gLamp, gBus, gTimer); // simulate power on
  5355 + TEST_ASSERT(gSlave != nullptr);
  5356 + gSlave->notifyPowerUp();
  5357 +
  5358 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_ACTUAL_LEVEL));
  5359 + TEST_ASSERT(gBus->ack == storedPOL);
  5360 +
  5361 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5362 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_STATUS));
  5363 + TEST_ASSERT((gBus->ack & 0b00010000) == 0b00010000);
  5364 +
  5365 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 240));
  5366 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5367 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  5368 + TEST_ASSERT(gBus->ack == 0x10);
  5369 +
  5370 + uint8_t dtr[] = {0, 1, 224, 225};
  5371 + uint16_t expected[] = {point1_x, point1_y, point1_x, point1_y};
  5372 + for (uint8_t i = 0; i < 4; ++i) {
  5373 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, dtr[i]));
  5374 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5375 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  5376 + TEST_ASSERT(gBus->ack != 0xffff);
  5377 +
  5378 + uint16_t val = get16bitValue();
  5379 + TEST_ASSERT(val == expected[i]);
  5380 + }
  5381 +
  5382 + goto_xy_Coordinate(point2_x, point2_y);
  5383 +}
  5384 +
  5385 +void testPowerOnBehaviourMask_xy() {
  5386 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_ACTUAL_LEVEL));
  5387 + uint16_t point1_x = 0xffff;
  5388 + uint16_t point1_y = 0xffff;
  5389 + get_actual_xy(&point1_x, &point1_y);
  5390 +
  5391 + setSpecific16bitValue(0xffff);
  5392 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5393 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_X_COORDINATE_WORD));
  5394 +
  5395 + setSpecific16bitValue(0xffff);
  5396 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5397 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_Y_COORDINATE_WORD));
  5398 +
  5399 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_PHISICAL_MIN_LEVEL));
  5400 + TEST_ASSERT(gBus->ack != 0xffff);
  5401 + uint8_t phm = gBus->ack;
  5402 +
  5403 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_POWER_ON_LEVEL));
  5404 + TEST_ASSERT(gBus->ack != 0xffff);
  5405 +
  5406 + uint8_t storedPOL;
  5407 + if (gBus->ack == 254) {
  5408 + storedPOL = phm;
  5409 + } else {
  5410 + storedPOL = gBus->ack + 1;
  5411 + }
  5412 +
  5413 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, storedPOL));
  5414 +
  5415 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_POWER_ON_LEVEL));
  5416 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_POWER_ON_LEVEL));
  5417 +
  5418 + gSlave->notifyPowerDown();
  5419 + delete gSlave; // Simulate power off
  5420 + gSlave = gCreateSlave(gMemory, gLamp, gBus, gTimer); // simulate power on
  5421 + TEST_ASSERT(gSlave != nullptr);
  5422 + gSlave->notifyPowerUp();
  5423 +
  5424 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_ACTUAL_LEVEL));
  5425 + TEST_ASSERT(gBus->ack == storedPOL);
  5426 +
  5427 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5428 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_STATUS));
  5429 + TEST_ASSERT((gBus->ack & 0b00010000) == 0b00010000);
  5430 +
  5431 + uint8_t dtr[] = {0, 1, 224, 225};
  5432 + uint16_t expected[] = {point1_x, point1_y, point1_x, point1_y};
  5433 + for (uint8_t i = 0; i < 4; ++i) {
  5434 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, dtr[i]));
  5435 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5436 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  5437 + TEST_ASSERT(gBus->ack != 0xffff);
  5438 +
  5439 + uint16_t val = get16bitValue();
  5440 + TEST_ASSERT(val == expected[i]);
  5441 + }
  5442 +}
  5443 +
  5444 +void testPowerOnBehaviour_Tc() {
  5445 + uint16_t tcValue = findValidTcValue();
  5446 +
  5447 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 129));
  5448 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5449 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  5450 + TEST_ASSERT(gBus->ack != 0xffff);
  5451 +
  5452 + uint16_t coolest = get16bitValue();
  5453 + TEST_ASSERT(coolest != 0xffff);
  5454 +
  5455 + setSpecific16bitValue(coolest);
  5456 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5457 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_COLOUR_TEMPERATURE));
  5458 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5459 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::ACTIVATE));
  5460 +
  5461 + setSpecific16bitValue(tcValue);
  5462 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5463 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_COLOUR_TEMPERATURE));
  5464 +
  5465 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_PHISICAL_MIN_LEVEL));
  5466 + TEST_ASSERT(gBus->ack != 0xffff);
  5467 + uint8_t phm = gBus->ack;
  5468 +
  5469 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_POWER_ON_LEVEL));
  5470 + TEST_ASSERT(gBus->ack != 0xffff);
  5471 +
  5472 + uint8_t storedPOL;
  5473 + if (gBus->ack == 254) {
  5474 + storedPOL = phm;
  5475 + } else {
  5476 + storedPOL = gBus->ack + 1;
  5477 + }
  5478 +
  5479 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, storedPOL));
  5480 +
  5481 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_POWER_ON_LEVEL));
  5482 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_POWER_ON_LEVEL));
  5483 +
  5484 + gSlave->notifyPowerDown();
  5485 + delete gSlave; // Simulate power off
  5486 + gSlave = gCreateSlave(gMemory, gLamp, gBus, gTimer); // simulate power on
  5487 + TEST_ASSERT(gSlave != nullptr);
  5488 + gSlave->notifyPowerUp();
  5489 +
  5490 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_ACTUAL_LEVEL));
  5491 + TEST_ASSERT(gBus->ack == storedPOL);
  5492 +
  5493 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5494 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_STATUS));
  5495 + TEST_ASSERT((gBus->ack & 0b00100000) == 0b00100000);
  5496 +
  5497 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 240));
  5498 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5499 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  5500 + TEST_ASSERT(gBus->ack == 0x20);
  5501 +
  5502 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 2));
  5503 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5504 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  5505 + TEST_ASSERT(gBus->ack != 0xffff);
  5506 + uint16_t val = get16bitValue();
  5507 + TEST_ASSERT(val == tcValue);
  5508 +
  5509 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 226));
  5510 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5511 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  5512 + val = get16bitValue();
  5513 + TEST_ASSERT(val == tcValue);
  5514 +
  5515 + setSpecific16bitValue(tcValue);
  5516 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5517 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_COLOUR_TEMPERATURE));
  5518 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5519 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::ACTIVATE));
  5520 +}
  5521 +
  5522 +void testPowerOnBehaviourMask_Tc() {
  5523 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_ACTUAL_LEVEL));
  5524 + uint16_t tcValue = 0xffff;
  5525 + get_actual_Tc(&tcValue);
  5526 +
  5527 + set16bitValue(0xff);
  5528 +
  5529 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5530 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_COLOUR_TEMPERATURE));
  5531 +
  5532 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_PHISICAL_MIN_LEVEL));
  5533 + TEST_ASSERT(gBus->ack != 0xffff);
  5534 + uint8_t phm = gBus->ack;
  5535 +
  5536 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_POWER_ON_LEVEL));
  5537 + TEST_ASSERT(gBus->ack != 0xffff);
  5538 +
  5539 + uint8_t storedPOL;
  5540 + if (gBus->ack == 254) {
  5541 + storedPOL = phm;
  5542 + } else {
  5543 + storedPOL = gBus->ack + 1;
  5544 + }
  5545 +
  5546 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, storedPOL));
  5547 +
  5548 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_POWER_ON_LEVEL));
  5549 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_POWER_ON_LEVEL));
  5550 +
  5551 + gSlave->notifyPowerDown();
  5552 + delete gSlave; // Simulate power off
  5553 + gSlave = gCreateSlave(gMemory, gLamp, gBus, gTimer); // simulate power on
  5554 + TEST_ASSERT(gSlave != nullptr);
  5555 + gSlave->notifyPowerUp();
  5556 +
  5557 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_ACTUAL_LEVEL));
  5558 + TEST_ASSERT(gBus->ack == storedPOL);
  5559 +
  5560 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5561 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_STATUS));
  5562 + TEST_ASSERT((gBus->ack & 0b00100000) == 0b00100000);
  5563 +
  5564 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 2));
  5565 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5566 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  5567 + TEST_ASSERT(gBus->ack != 0xffff);
  5568 + uint16_t val = get16bitValue();
  5569 + TEST_ASSERT(val == tcValue);
  5570 +
  5571 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 226));
  5572 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5573 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  5574 + TEST_ASSERT(gBus->ack != 0xffff);
  5575 + val = get16bitValue();
  5576 + TEST_ASSERT(val == tcValue);
  5577 +}
  5578 +
  5579 +void testPowerOnBehaviour_PrimaryN() {
  5580 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 82));
  5581 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5582 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  5583 + TEST_ASSERT(gBus->ack != 0xffff);
  5584 + uint8_t nrPrim = gBus->ack;
  5585 +
  5586 + for (uint8_t i = 0; i < nrPrim; ++i) {
  5587 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_2, i));
  5588 +
  5589 + setSpecific16bitValue(0x8000 + i);
  5590 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5591 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_PRIMARY_N_DIMLEVEL));
  5592 +
  5593 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5594 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::ACTIVATE));
  5595 +
  5596 + setSpecific16bitValue(0xC000 + i);
  5597 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5598 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_PRIMARY_N_DIMLEVEL));
  5599 + }
  5600 +
  5601 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_PHISICAL_MIN_LEVEL));
  5602 + TEST_ASSERT(gBus->ack != 0xffff);
  5603 + uint8_t phm = gBus->ack;
  5604 +
  5605 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_POWER_ON_LEVEL));
  5606 + TEST_ASSERT(gBus->ack != 0xffff);
  5607 +
  5608 + uint8_t storedPOL;
  5609 + if (gBus->ack == 254) {
  5610 + storedPOL = phm;
  5611 + } else {
  5612 + storedPOL = gBus->ack + 1;
  5613 + }
  5614 +
  5615 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, storedPOL));
  5616 +
  5617 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_POWER_ON_LEVEL));
  5618 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_POWER_ON_LEVEL));
  5619 +
  5620 + gSlave->notifyPowerDown();
  5621 + delete gSlave; // Simulate power off
  5622 + gSlave = gCreateSlave(gMemory, gLamp, gBus, gTimer); // simulate power on
  5623 + TEST_ASSERT(gSlave != nullptr);
  5624 + gSlave->notifyPowerUp();
  5625 +
  5626 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_ACTUAL_LEVEL));
  5627 + TEST_ASSERT(gBus->ack == storedPOL);
  5628 +
  5629 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5630 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_STATUS));
  5631 + TEST_ASSERT((gBus->ack & 0b01000000) == 0b01000000);
  5632 +
  5633 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 240));
  5634 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5635 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  5636 + TEST_ASSERT(gBus->ack == 0x40);
  5637 +
  5638 + for (uint8_t i = 0; i < nrPrim; ++i) {
  5639 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 3 + i));
  5640 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5641 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  5642 + TEST_ASSERT(gBus->ack != 0xffff);
  5643 + uint16_t val = get16bitValue();
  5644 + TEST_ASSERT(val == 0xC000 + i);
  5645 +
  5646 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 227 + i));
  5647 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5648 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  5649 + TEST_ASSERT(gBus->ack != 0xffff);
  5650 + val = get16bitValue();
  5651 + TEST_ASSERT(val == 0xC000 + i);
  5652 + }
  5653 +}
  5654 +
  5655 +void testPowerOnBehaviourMask_PrimaryN() {
  5656 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 82));
  5657 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5658 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  5659 + TEST_ASSERT(gBus->ack != 0xffff);
  5660 + uint8_t nrPrim = gBus->ack;
  5661 +
  5662 + for (uint8_t i = 0; i < nrPrim; ++i) {
  5663 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_2, i));
  5664 +
  5665 + setSpecific16bitValue(0x8000 + i);
  5666 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5667 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_PRIMARY_N_DIMLEVEL));
  5668 +
  5669 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5670 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::ACTIVATE));
  5671 +
  5672 + setSpecific16bitValue(0xffff);
  5673 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5674 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_PRIMARY_N_DIMLEVEL));
  5675 + }
  5676 +
  5677 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_PHISICAL_MIN_LEVEL));
  5678 + TEST_ASSERT(gBus->ack != 0xffff);
  5679 + uint8_t phm = gBus->ack;
  5680 +
  5681 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_POWER_ON_LEVEL));
  5682 + TEST_ASSERT(gBus->ack != 0xffff);
  5683 +
  5684 + uint8_t storedPOL;
  5685 + if (gBus->ack == 254) {
  5686 + storedPOL = phm;
  5687 + } else {
  5688 + storedPOL = gBus->ack + 1;
  5689 + }
  5690 +
  5691 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, storedPOL));
  5692 +
  5693 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_POWER_ON_LEVEL));
  5694 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_POWER_ON_LEVEL));
  5695 +
  5696 + gSlave->notifyPowerDown();
  5697 + delete gSlave; // Simulate power off
  5698 + gSlave = gCreateSlave(gMemory, gLamp, gBus, gTimer); // simulate power on
  5699 + TEST_ASSERT(gSlave != nullptr);
  5700 + gSlave->notifyPowerUp();
  5701 +
  5702 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_ACTUAL_LEVEL));
  5703 + TEST_ASSERT(gBus->ack == storedPOL);
  5704 +
  5705 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5706 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_STATUS));
  5707 + TEST_ASSERT((gBus->ack & 0b01000000) == 0b01000000);
  5708 +
  5709 + for (uint8_t i = 0; i < nrPrim; ++i) {
  5710 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 3 + i));
  5711 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5712 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  5713 + TEST_ASSERT(gBus->ack != 0xffff);
  5714 + uint16_t val = get16bitValue();
  5715 + TEST_ASSERT(val == 0x8000 + i);
  5716 +
  5717 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 227 + i));
  5718 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5719 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  5720 + TEST_ASSERT(gBus->ack != 0xffff);
  5721 + val = get16bitValue();
  5722 + TEST_ASSERT(val == 0x8000 + i);
  5723 + }
  5724 +}
  5725 +
  5726 +void testPowerOnBehaviour_RGBWAF() {
  5727 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 82));
  5728 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5729 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_TYPE_FEATURES));
  5730 + TEST_ASSERT(gBus->ack != 0xffff);
  5731 + uint8_t nrChan = (gBus->ack & 0xE0) >> 5;
  5732 +
  5733 + const uint8_t dtr[] = {63, 127, 128};
  5734 +
  5735 + for (uint8_t i = 0; i < 3; ++i) {
  5736 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, dtr[i]));
  5737 +
  5738 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5739 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_RGBWAF_CONTROL));
  5740 +
  5741 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 85 + i));
  5742 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_1, 85 + i));
  5743 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_2, 85 + i));
  5744 +
  5745 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5746 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_RGB_DIMLEVEL));
  5747 +
  5748 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5749 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_WAF_DIMLEVEL));
  5750 +
  5751 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5752 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::ACTIVATE));
  5753 +
  5754 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, dtr[i]));
  5755 +
  5756 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5757 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_RGBWAF_CONTROL));
  5758 +
  5759 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 170 + i));
  5760 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_1, 170 + i));
  5761 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_2, 170 + i));
  5762 +
  5763 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5764 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_RGB_DIMLEVEL));
  5765 +
  5766 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5767 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_WAF_DIMLEVEL));
  5768 +
  5769 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_PHISICAL_MIN_LEVEL));
  5770 + TEST_ASSERT(gBus->ack != 0xffff);
  5771 + uint8_t phm = gBus->ack;
  5772 +
  5773 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_POWER_ON_LEVEL));
  5774 + TEST_ASSERT(gBus->ack != 0xffff);
  5775 +
  5776 + uint8_t storedPOL;
  5777 + if (gBus->ack == 254) {
  5778 + storedPOL = phm;
  5779 + } else {
  5780 + storedPOL = gBus->ack + 1;
  5781 + }
  5782 +
  5783 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, storedPOL));
  5784 +
  5785 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_POWER_ON_LEVEL));
  5786 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_POWER_ON_LEVEL));
  5787 +
  5788 + gSlave->notifyPowerDown();
  5789 + delete gSlave; // Simulate power off
  5790 + gSlave = gCreateSlave(gMemory, gLamp, gBus, gTimer); // simulate power on
  5791 + TEST_ASSERT(gSlave != nullptr);
  5792 + gSlave->notifyPowerUp();
  5793 +
  5794 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_ACTUAL_LEVEL));
  5795 + TEST_ASSERT(gBus->ack == storedPOL);
  5796 +
  5797 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5798 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_STATUS));
  5799 + TEST_ASSERT((gBus->ack & 0x80) == 0x80);
  5800 +
  5801 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 240));
  5802 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5803 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  5804 + TEST_ASSERT(gBus->ack == 0x80);
  5805 +
  5806 + uint8_t control = 0;
  5807 + for (uint8_t j = 0; j < nrChan; ++j) {
  5808 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 9 + j));
  5809 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5810 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  5811 + TEST_ASSERT(gBus->ack != 0xffff);
  5812 + TEST_ASSERT(gBus->ack == 170 + i);
  5813 +
  5814 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 233 + j));
  5815 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5816 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  5817 + TEST_ASSERT(gBus->ack != 0xffff);
  5818 + TEST_ASSERT(gBus->ack == 170 + i);
  5819 +
  5820 + control = (1 << j) + control;
  5821 + }
  5822 +
  5823 + if (dtr[i] == 128) { // TODO check
  5824 + control = 128;
  5825 + } else {
  5826 + control = (dtr[i] & 0xC0) + control;
  5827 + }
  5828 +
  5829 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 15));
  5830 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5831 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  5832 + TEST_ASSERT(gBus->ack == control);
  5833 +
  5834 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 239));
  5835 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5836 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  5837 + TEST_ASSERT(gBus->ack == control);
  5838 + }
  5839 +}
  5840 +
  5841 +void testPowerOnBehaviourMask_RGBWAF() {
  5842 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 82));
  5843 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5844 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_TYPE_FEATURES));
  5845 + TEST_ASSERT(gBus->ack != 0xffff);
  5846 + uint8_t nrChan = (gBus->ack & 0xE0) >> 5;
  5847 +
  5848 + const uint8_t dtr[] = {63, 127, 128};
  5849 +
  5850 + for (uint8_t i = 0; i < 3; ++i) {
  5851 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, dtr[i]));
  5852 +
  5853 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5854 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_RGBWAF_CONTROL));
  5855 +
  5856 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 85 + i));
  5857 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_1, 85 + i));
  5858 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_2, 85 + i));
  5859 +
  5860 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5861 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_RGB_DIMLEVEL));
  5862 +
  5863 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5864 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_WAF_DIMLEVEL));
  5865 +
  5866 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5867 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::ACTIVATE));
  5868 +
  5869 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, dtr[i]));
  5870 +
  5871 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5872 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_RGBWAF_CONTROL));
  5873 +
  5874 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 255));
  5875 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_1, 255));
  5876 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_2, 255));
  5877 +
  5878 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5879 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_RGB_DIMLEVEL));
  5880 +
  5881 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5882 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_WAF_DIMLEVEL));
  5883 +
  5884 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_PHISICAL_MIN_LEVEL));
  5885 + TEST_ASSERT(gBus->ack != 0xffff);
  5886 + uint8_t phm = gBus->ack;
  5887 +
  5888 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_POWER_ON_LEVEL));
  5889 + TEST_ASSERT(gBus->ack != 0xffff);
  5890 +
  5891 + uint8_t storedPOL;
  5892 + if (gBus->ack == 254) {
  5893 + storedPOL = phm;
  5894 + } else {
  5895 + storedPOL = gBus->ack + 1;
  5896 + }
  5897 +
  5898 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, storedPOL));
  5899 +
  5900 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_POWER_ON_LEVEL));
  5901 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_POWER_ON_LEVEL));
  5902 +
  5903 + gSlave->notifyPowerDown();
  5904 + delete gSlave; // Simulate power off
  5905 + gSlave = gCreateSlave(gMemory, gLamp, gBus, gTimer); // simulate power on
  5906 + TEST_ASSERT(gSlave != nullptr);
  5907 + gSlave->notifyPowerUp();
  5908 +
  5909 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_ACTUAL_LEVEL));
  5910 + TEST_ASSERT(gBus->ack == storedPOL);
  5911 +
  5912 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5913 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_STATUS));
  5914 + TEST_ASSERT((gBus->ack & 0b10000000) == 0b10000000);
  5915 +
  5916 + uint8_t control = 0;
  5917 + for (uint8_t j = 0; j < nrChan; ++j) {
  5918 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 9 + j));
  5919 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5920 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  5921 + TEST_ASSERT(gBus->ack != 0xffff);
  5922 + TEST_ASSERT(gBus->ack == 85 + i);
  5923 +
  5924 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 233 + j));
  5925 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5926 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  5927 + TEST_ASSERT(gBus->ack != 0xffff);
  5928 + TEST_ASSERT(gBus->ack == 85 + i);
  5929 +
  5930 + control = (1 << j) + control;
  5931 + }
  5932 +
  5933 + if (dtr[i] == 128) { // TODO check
  5934 + control = 128;
  5935 + } else {
  5936 + control = (dtr[i] & 0xC0) + control;
  5937 + }
  5938 +
  5939 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 15));
  5940 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5941 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  5942 + TEST_ASSERT(gBus->ack == control);
  5943 +
  5944 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 239));
  5945 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5946 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  5947 + TEST_ASSERT(gBus->ack == control);
  5948 + }
  5949 +}
  5950 +
  5951 +void testPowerOnColor() {
  5952 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  5953 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  5954 +
  5955 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5956 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_TYPE_FEATURES));
  5957 + uint8_t features = gBus->ack;
  5958 + bool supp[4];
  5959 + supp[0] = (features & DALI_DT8_COLOUR_TYPE_FEATURES_XY) != 0;
  5960 + supp[1] = (features & DALI_DT8_COLOUR_TYPE_FEATURES_TC) != 0;
  5961 + supp[2] = (features & DALI_DT8_COLOUR_TYPE_FEATURES_PRIMARY_N) != 0;
  5962 + supp[3] = (features & DALI_DT8_COLOUR_TYPE_FEATURES_RGBWAF) != 0;
  5963 +
  5964 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_POWER_ON_LEVEL));
  5965 + TEST_ASSERT(gBus->ack == 254);
  5966 +
  5967 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 240));
  5968 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  5969 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  5970 + TEST_ASSERT(gBus->ack != 0xffff);
  5971 + TEST_ASSERT(gBus->ack != 0xff);
  5972 +
  5973 + if (supp[0]) {
  5974 + activateColourType(0);
  5975 + testPowerOnBehaviour_xy();
  5976 + testPowerOnBehaviourMask_xy();
  5977 + }
  5978 + if (supp[1]) {
  5979 + activateColourType(1);
  5980 + testPowerOnBehaviour_Tc();
  5981 + testPowerOnBehaviourMask_Tc();
  5982 + }
  5983 + if (supp[2]) {
  5984 + activateColourType(2);
  5985 + testPowerOnBehaviour_PrimaryN();
  5986 + testPowerOnBehaviourMask_PrimaryN();
  5987 + }
  5988 + if (supp[3]) {
  5989 + activateColourType(3);
  5990 + testPowerOnBehaviour_RGBWAF();
  5991 + testPowerOnBehaviourMask_RGBWAF();
  5992 + }
  5993 +}
  5994 +
  5995 +void testSystemFailureBehaviour_xy() {
  5996 + uint16_t point1_x = 0xffff;
  5997 + uint16_t point1_y = 0xffff;
  5998 + uint16_t point2_x = 0xffff;
  5999 + uint16_t point2_y = 0xffff;
  6000 + findTwoValid_xy_Points(&point1_x, &point1_y, &point2_x, &point2_y);
  6001 +
  6002 + setSpecific16bitValue(point1_x);
  6003 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  6004 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_X_COORDINATE_WORD));
  6005 +
  6006 + setSpecific16bitValue(point1_y);
  6007 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  6008 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_Y_COORDINATE_WORD));
  6009 +
  6010 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_PHISICAL_MIN_LEVEL));
  6011 + TEST_ASSERT(gBus->ack != 0xffff);
  6012 + uint8_t phm = gBus->ack;
  6013 +
  6014 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_SYS_FAILURE_LEVEL));
  6015 + TEST_ASSERT(gBus->ack != 0xffff);
  6016 +
  6017 + uint8_t storedSFL;
  6018 + if (gBus->ack == 254) {
  6019 + storedSFL = phm;
  6020 + } else {
  6021 + storedSFL = gBus->ack + 1;
  6022 + }
  6023 +
  6024 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, storedSFL));
  6025 +
  6026 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_SYS_FAIL_LEVEL));
  6027 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_SYS_FAIL_LEVEL));
  6028 +
  6029 + goto_xy_Coordinate(point2_x, point2_y);
  6030 +
  6031 + gBus->setState(IBus::IBusState::DISCONNECTED);
  6032 + gTimer->run(1000);
  6033 + gBus->setState(IBus::IBusState::CONNECTED);
  6034 +
  6035 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_ACTUAL_LEVEL));
  6036 + TEST_ASSERT(gBus->ack == storedSFL);
  6037 +
  6038 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  6039 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_STATUS));
  6040 + TEST_ASSERT((gBus->ack & 0b000010000) == 0b000010000);
  6041 +
  6042 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 240));
  6043 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  6044 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  6045 + TEST_ASSERT(gBus->ack == 0x10);
  6046 +
  6047 + const uint8_t dtr[] = {0, 1, 224, 225};
  6048 + const uint16_t expected[] = {point1_x, point1_y, point1_x, point1_y};
  6049 + for (uint8_t i = 0; i < 4; ++ i) {
  6050 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, dtr[i]));
  6051 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  6052 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  6053 + TEST_ASSERT(gBus->ack != 0xffff);
  6054 + uint16_t val = get16bitValue();
  6055 + TEST_ASSERT(val == expected[i]);
  6056 + }
  6057 +
  6058 + goto_xy_Coordinate(point2_x, point2_y);
  6059 +}
  6060 +
  6061 +void testSystemFailureBehaviourMask_xy() {
  6062 + uint16_t point2_x = 0xffff;
  6063 + uint16_t point2_y = 0xffff;
  6064 + get_actual_xy(&point2_x, &point2_y);
  6065 +
  6066 + setSpecific16bitValue(0xffff);
  6067 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  6068 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_X_COORDINATE_WORD));
  6069 +
  6070 + setSpecific16bitValue(0xffff);
  6071 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  6072 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_Y_COORDINATE_WORD));
  6073 +
  6074 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_PHISICAL_MIN_LEVEL));
  6075 + TEST_ASSERT(gBus->ack != 0xffff);
  6076 + uint8_t phm = gBus->ack;
  6077 +
  6078 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_SYS_FAILURE_LEVEL));
  6079 + TEST_ASSERT(gBus->ack != 0xffff);
  6080 +
  6081 + uint8_t storedSFL;
  6082 + if (gBus->ack == 254) {
  6083 + storedSFL = phm;
  6084 + } else {
  6085 + storedSFL = gBus->ack + 1;
  6086 + }
  6087 +
  6088 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, storedSFL));
  6089 +
  6090 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_SYS_FAIL_LEVEL));
  6091 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_SYS_FAIL_LEVEL));
  6092 +
  6093 + goto_xy_Coordinate(point2_x, point2_y);
  6094 +
  6095 + gBus->setState(IBus::IBusState::DISCONNECTED);
  6096 + gTimer->run(1000);
  6097 + gBus->setState(IBus::IBusState::CONNECTED);
  6098 +
  6099 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_ACTUAL_LEVEL));
  6100 + TEST_ASSERT(gBus->ack == storedSFL);
  6101 +
  6102 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  6103 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_STATUS));
  6104 + TEST_ASSERT((gBus->ack & 0b00010000) == 0b00010000);
  6105 +
  6106 + const uint8_t dtr[] = {0, 1, 224, 225};
  6107 + const uint16_t expected[] = {point2_x, point2_y, point2_x, point2_y};
  6108 + for (uint8_t i = 0; i < 4; ++ i) {
  6109 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, dtr[i]));
  6110 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  6111 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  6112 + TEST_ASSERT(gBus->ack != 0xffff);
  6113 + uint16_t val = get16bitValue();
  6114 + TEST_ASSERT(val == expected[i]);
  6115 + }
  6116 +}
  6117 +
  6118 +void testSystemFaliureBehaviour_Tc() {
  6119 + uint16_t tcValue = findValidTcValue();
  6120 +
  6121 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 129));
  6122 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  6123 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  6124 + TEST_ASSERT(gBus->ack != 0xffff);
  6125 +
  6126 + uint16_t coolest = get16bitValue();
  6127 +
  6128 + setSpecific16bitValue(coolest);
  6129 +
  6130 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  6131 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_COLOUR_TEMPERATURE));
  6132 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  6133 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::ACTIVATE));
  6134 +
  6135 + setSpecific16bitValue(tcValue);
  6136 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  6137 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_COLOUR_TEMPERATURE));
  6138 +
  6139 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_PHISICAL_MIN_LEVEL));
  6140 + TEST_ASSERT(gBus->ack != 0xffff);
  6141 + uint8_t phm = gBus->ack;
  6142 +
  6143 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_SYS_FAILURE_LEVEL));
  6144 + TEST_ASSERT(gBus->ack != 0xffff);
  6145 +
  6146 + uint8_t storedSFL;
  6147 + if (gBus->ack == 254) {
  6148 + storedSFL = phm;
  6149 + } else {
  6150 + storedSFL = gBus->ack + 1;
  6151 + }
  6152 +
  6153 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, storedSFL));
  6154 +
  6155 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_SYS_FAIL_LEVEL));
  6156 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_SYS_FAIL_LEVEL));
  6157 +
  6158 + gBus->setState(IBus::IBusState::DISCONNECTED);
  6159 + gTimer->run(1000);
  6160 + gBus->setState(IBus::IBusState::CONNECTED);
  6161 +
  6162 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_ACTUAL_LEVEL));
  6163 + TEST_ASSERT(gBus->ack == storedSFL);
  6164 +
  6165 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  6166 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_STATUS));
  6167 + TEST_ASSERT((gBus->ack & 0b00100000) == 0b00100000);
  6168 +
  6169 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 240));
  6170 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  6171 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  6172 + TEST_ASSERT(gBus->ack == 0x20);
  6173 +
  6174 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 2));
  6175 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  6176 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  6177 + TEST_ASSERT(gBus->ack != 0xffff);
  6178 + uint16_t val = get16bitValue();
  6179 + TEST_ASSERT(val == tcValue);
  6180 +
  6181 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 226));
  6182 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  6183 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  6184 + val = get16bitValue();
  6185 + TEST_ASSERT(val == tcValue);
  6186 +
  6187 + setSpecific16bitValue(tcValue);
  6188 +
  6189 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  6190 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_COLOUR_TEMPERATURE));
  6191 +
  6192 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  6193 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::ACTIVATE));
  6194 +}
  6195 +
  6196 +void testSystemFaliureBehaviourMask_Tc() {
  6197 + uint16_t tcValue = 0xffff;
  6198 + get_actual_Tc(&tcValue);
  6199 +
  6200 + set16bitValue(0xff);
  6201 +
  6202 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  6203 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_COLOUR_TEMPERATURE));
  6204 +
  6205 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_PHISICAL_MIN_LEVEL));
  6206 + TEST_ASSERT(gBus->ack != 0xffff);
  6207 + uint8_t phm = gBus->ack;
  6208 +
  6209 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_SYS_FAILURE_LEVEL));
  6210 + TEST_ASSERT(gBus->ack != 0xffff);
  6211 +
  6212 + uint8_t storedPOL;
  6213 + if (gBus->ack == 254) {
  6214 + storedPOL = phm;
  6215 + } else {
  6216 + storedPOL = gBus->ack + 1;
  6217 + }
  6218 +
  6219 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, storedPOL));
  6220 +
  6221 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_SYS_FAIL_LEVEL));
  6222 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_SYS_FAIL_LEVEL));
  6223 +
  6224 + gBus->setState(IBus::IBusState::DISCONNECTED);
  6225 + gTimer->run(1000);
  6226 + gBus->setState(IBus::IBusState::CONNECTED);
  6227 +
  6228 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  6229 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_STATUS));
  6230 + TEST_ASSERT((gBus->ack & 0b00100000) == 0b00100000);
  6231 +
  6232 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 2));
  6233 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  6234 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  6235 + TEST_ASSERT(gBus->ack != 0xffff);
  6236 + uint16_t val = get16bitValue();
  6237 + TEST_ASSERT(val == tcValue);
  6238 +
  6239 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 226));
  6240 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  6241 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  6242 + val = get16bitValue();
  6243 + TEST_ASSERT(val == tcValue);
  6244 +}
  6245 +
  6246 +void testSystemFaliureBehaviour_PrimaryN() {
  6247 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 82));
  6248 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  6249 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  6250 + TEST_ASSERT(gBus->ack != 0xffff);
  6251 + uint8_t nrPrim = gBus->ack;
  6252 +
  6253 + for (uint8_t i = 0; i < nrPrim; ++i) {
  6254 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_2, i));
  6255 +
  6256 + setSpecific16bitValue(0x8000 + i);
  6257 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  6258 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_PRIMARY_N_DIMLEVEL));
  6259 +
  6260 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  6261 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::ACTIVATE));
  6262 +
  6263 + setSpecific16bitValue(0xC000 + i);
  6264 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  6265 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_PRIMARY_N_DIMLEVEL));
  6266 + }
  6267 +
  6268 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_PHISICAL_MIN_LEVEL));
  6269 + TEST_ASSERT(gBus->ack != 0xffff);
  6270 + uint8_t phm = gBus->ack;
  6271 +
  6272 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_SYS_FAILURE_LEVEL));
  6273 + TEST_ASSERT(gBus->ack != 0xffff);
  6274 +
  6275 + uint8_t storedSFL;
  6276 + if (gBus->ack == 254) {
  6277 + storedSFL = phm;
  6278 + } else {
  6279 + storedSFL = gBus->ack + 1;
  6280 + }
  6281 +
  6282 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, storedSFL));
  6283 +
  6284 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_SYS_FAIL_LEVEL));
  6285 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_SYS_FAIL_LEVEL));
  6286 +
  6287 + gBus->setState(IBus::IBusState::DISCONNECTED);
  6288 + gTimer->run(1000);
  6289 + gBus->setState(IBus::IBusState::CONNECTED);
  6290 +
  6291 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_ACTUAL_LEVEL));
  6292 + TEST_ASSERT(gBus->ack == storedSFL);
  6293 +
  6294 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  6295 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_STATUS));
  6296 + TEST_ASSERT((gBus->ack & 0b01000000) == 0b01000000);
  6297 +
  6298 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 240));
  6299 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  6300 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  6301 + TEST_ASSERT(gBus->ack == 0x40);
  6302 +
  6303 + for (uint8_t i = 0; i < nrPrim; ++i) {
  6304 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 3 + i));
  6305 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  6306 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  6307 + TEST_ASSERT(gBus->ack != 0xffff);
  6308 + uint16_t val = get16bitValue();
  6309 + TEST_ASSERT(val == 0xC000 + i);
  6310 +
  6311 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 227 + i));
  6312 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  6313 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  6314 + TEST_ASSERT(gBus->ack != 0xffff);
  6315 + val = get16bitValue();
  6316 + TEST_ASSERT(val == 0xC000 + i);
  6317 + }
  6318 +}
  6319 +
  6320 +void testSystemFaliureBehaviourMask_PrimaryN() {
  6321 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 82));
  6322 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  6323 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  6324 + TEST_ASSERT(gBus->ack != 0xffff);
  6325 + uint8_t nrPrim = gBus->ack;
  6326 +
  6327 + for (uint8_t i = 0; i < nrPrim; ++i) {
  6328 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_2, i));
  6329 +
  6330 + setSpecific16bitValue(0x8000 + i);
  6331 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  6332 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_PRIMARY_N_DIMLEVEL));
  6333 +
  6334 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  6335 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::ACTIVATE));
  6336 +
  6337 + setSpecific16bitValue(0xffff);
  6338 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  6339 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_PRIMARY_N_DIMLEVEL));
  6340 + }
  6341 +
  6342 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_PHISICAL_MIN_LEVEL));
  6343 + TEST_ASSERT(gBus->ack != 0xffff);
  6344 + uint8_t phm = gBus->ack;
  6345 +
  6346 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_SYS_FAILURE_LEVEL));
  6347 + TEST_ASSERT(gBus->ack != 0xffff);
  6348 +
  6349 + uint8_t storedSFL;
  6350 + if (gBus->ack == 254) {
  6351 + storedSFL = phm;
  6352 + } else {
  6353 + storedSFL = gBus->ack + 1;
  6354 + }
  6355 +
  6356 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, storedSFL));
  6357 +
  6358 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_SYS_FAIL_LEVEL));
  6359 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_SYS_FAIL_LEVEL));
  6360 +
  6361 + gBus->setState(IBus::IBusState::DISCONNECTED);
  6362 + gTimer->run(1000);
  6363 + gBus->setState(IBus::IBusState::CONNECTED);
  6364 +
  6365 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_ACTUAL_LEVEL));
  6366 + TEST_ASSERT(gBus->ack == storedSFL);
  6367 +
  6368 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  6369 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_STATUS));
  6370 + TEST_ASSERT((gBus->ack & 0b01000000) == 0b01000000);
  6371 +
  6372 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 240));
  6373 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  6374 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  6375 + TEST_ASSERT(gBus->ack == 0x40);
  6376 +
  6377 + for (uint8_t i = 0; i < nrPrim; ++i) {
  6378 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 3 + i));
  6379 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  6380 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  6381 + TEST_ASSERT(gBus->ack != 0xffff);
  6382 + uint16_t val = get16bitValue();
  6383 + TEST_ASSERT(val == 0x8000 + i);
  6384 +
  6385 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 227 + i));
  6386 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  6387 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  6388 + TEST_ASSERT(gBus->ack != 0xffff);
  6389 + val = get16bitValue();
  6390 + TEST_ASSERT(val == 0x8000 + i);
  6391 + }
  6392 +}
  6393 +
  6394 +void testSystemFailureBehaviour_RGBWAF() {
  6395 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 82));
  6396 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  6397 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_TYPE_FEATURES));
  6398 + TEST_ASSERT(gBus->ack != 0xffff);
  6399 + uint8_t nrChan = (gBus->ack & 0xE0) >> 5;
  6400 +
  6401 + const uint8_t dtr[] = {63, 127, 128};
  6402 +
  6403 + for (uint8_t i = 0; i < 3; ++i) {
  6404 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, dtr[i]));
  6405 +
  6406 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  6407 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_RGBWAF_CONTROL));
  6408 +
  6409 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 85 + i));
  6410 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_1, 85 + i));
  6411 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_2, 85 + i));
  6412 +
  6413 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  6414 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_RGB_DIMLEVEL));
  6415 +
  6416 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  6417 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_WAF_DIMLEVEL));
  6418 +
  6419 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  6420 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::ACTIVATE));
  6421 +
  6422 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, dtr[i]));
  6423 +
  6424 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  6425 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_RGBWAF_CONTROL));
  6426 +
  6427 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 170 + i));
  6428 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_1, 170 + i));
  6429 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_2, 170 + i));
  6430 +
  6431 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  6432 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_RGB_DIMLEVEL));
  6433 +
  6434 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  6435 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_WAF_DIMLEVEL));
  6436 +
  6437 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_PHISICAL_MIN_LEVEL));
  6438 + TEST_ASSERT(gBus->ack != 0xffff);
  6439 + uint8_t phm = gBus->ack;
  6440 +
  6441 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_SYS_FAILURE_LEVEL));
  6442 + TEST_ASSERT(gBus->ack != 0xffff);
  6443 +
  6444 + uint8_t storedSFL;
  6445 + if (gBus->ack == 254) {
  6446 + storedSFL = phm;
  6447 + } else {
  6448 + storedSFL = gBus->ack + 1;
  6449 + }
  6450 +
  6451 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, storedSFL));
  6452 +
  6453 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_SYS_FAIL_LEVEL));
  6454 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_SYS_FAIL_LEVEL));
  6455 +
  6456 + gBus->setState(IBus::IBusState::DISCONNECTED);
  6457 + gTimer->run(1000);
  6458 + gBus->setState(IBus::IBusState::CONNECTED);
  6459 +
  6460 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_ACTUAL_LEVEL));
  6461 + TEST_ASSERT(gBus->ack == storedSFL);
  6462 +
  6463 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  6464 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_STATUS));
  6465 + TEST_ASSERT((gBus->ack & 0b10000000) == 0b10000000);
  6466 +
  6467 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 240));
  6468 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  6469 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  6470 + TEST_ASSERT(gBus->ack == 0x80);
  6471 +
  6472 + uint8_t control = 0;
  6473 + for (uint8_t j = 0; j < nrChan; ++j) {
  6474 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 9 + j));
  6475 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  6476 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  6477 + TEST_ASSERT(gBus->ack != 0xffff);
  6478 + TEST_ASSERT(gBus->ack == 170 + i);
  6479 +
  6480 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 233 + j));
  6481 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  6482 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  6483 + TEST_ASSERT(gBus->ack != 0xffff);
  6484 + TEST_ASSERT(gBus->ack == 170 + i);
  6485 +
  6486 + control = (1 << j) + control;
  6487 + }
  6488 +
  6489 + if (dtr[i] == 128) { // TODO check
  6490 + control = 128;
  6491 + } else {
  6492 + control = (dtr[i] & 0xC0) + control;
  6493 + }
  6494 +
  6495 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 15));
  6496 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  6497 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  6498 + TEST_ASSERT(gBus->ack == control);
  6499 +
  6500 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 239));
  6501 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  6502 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  6503 + TEST_ASSERT(gBus->ack == control);
  6504 + }
  6505 +}
  6506 +
  6507 +void testSystemFailureBehaviourMask_RGBWAF() {
  6508 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  6509 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_TYPE_FEATURES));
  6510 + TEST_ASSERT(gBus->ack != 0xffff);
  6511 +
  6512 + uint8_t nrChan = (gBus->ack & 0xE0) >> 5;
  6513 +
  6514 + const uint8_t dtr[] = { 63, 127, 128 };
  6515 +
  6516 + for (uint16_t i = 0; i < 3; ++i) {
  6517 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, dtr[i]));
  6518 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  6519 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_RGBWAF_CONTROL));
  6520 +
  6521 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 85 + i));
  6522 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_1, 85 + i));
  6523 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_2, 85 + i));
  6524 +
  6525 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  6526 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_RGB_DIMLEVEL));
  6527 +
  6528 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  6529 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_WAF_DIMLEVEL));
  6530 +
  6531 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  6532 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::ACTIVATE));
  6533 +
  6534 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, dtr[i]));
  6535 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  6536 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::SET_TEMPORARY_RGBWAF_CONTROL));
  6537 +
  6538 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 255));
  6539 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_1, 255));
  6540 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_2, 255));
  6541 +
  6542 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_PHISICAL_MIN_LEVEL));
  6543 + TEST_ASSERT(gBus->ack > 0 && gBus->ack < 255);
  6544 + uint8_t PHM = gBus->ack;
  6545 +
  6546 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_SYS_FAILURE_LEVEL));
  6547 + TEST_ASSERT(gBus->ack != 0xffff);
  6548 + uint8_t storedSFL;
  6549 + if (gBus->ack == 254) {
  6550 + storedSFL = PHM;
  6551 + } else {
  6552 + storedSFL = gBus->ack + 1;
  6553 + }
  6554 +
  6555 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, storedSFL));
  6556 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_SYS_FAIL_LEVEL));
  6557 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_SYS_FAIL_LEVEL));
  6558 +
  6559 + gBus->setState(IBus::IBusState::DISCONNECTED);
  6560 + gTimer->run(1000);
  6561 + gBus->setState(IBus::IBusState::CONNECTED);
  6562 +
  6563 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_ACTUAL_LEVEL));
  6564 + TEST_ASSERT(gBus->ack == storedSFL);
  6565 +
  6566 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  6567 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_STATUS));
  6568 + TEST_ASSERT(gBus->ack != 0xffff);
  6569 + TEST_ASSERT((gBus->ack & 0b10000000) == 0b10000000);
  6570 +
  6571 + uint8_t control = 0;
  6572 +
  6573 + for (uint16_t j = 0; j < nrChan; ++j) {
  6574 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 9 + j));
  6575 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  6576 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  6577 + TEST_ASSERT(gBus->ack == 85 + i);
  6578 +
  6579 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 233 + j));
  6580 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  6581 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  6582 + TEST_ASSERT(gBus->ack == 85 + i);
  6583 +
  6584 + control = (1 << j) + control;
  6585 + }
  6586 +
  6587 + if (dtr[i] == 128) { // TODO check
  6588 + control = 128;
  6589 + } else {
  6590 + control = (dtr[i] & 0xC0) + control;
  6591 + }
  6592 +
  6593 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 15));
  6594 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  6595 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  6596 + TEST_ASSERT(gBus->ack == control);
  6597 +
  6598 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 239));
  6599 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  6600 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  6601 + TEST_ASSERT(gBus->ack == control);
  6602 + }
  6603 +}
  6604 +
  6605 +void testSystemFaliure() {
  6606 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  6607 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  6608 +
  6609 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  6610 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_TYPE_FEATURES));
  6611 + uint8_t features = gBus->ack;
  6612 + bool supp[4];
  6613 + supp[0] = (features & DALI_DT8_COLOUR_TYPE_FEATURES_XY) != 0;
  6614 + supp[1] = (features & DALI_DT8_COLOUR_TYPE_FEATURES_TC) != 0;
  6615 + supp[2] = (features & DALI_DT8_COLOUR_TYPE_FEATURES_PRIMARY_N) != 0;
  6616 + supp[3] = (features & DALI_DT8_COLOUR_TYPE_FEATURES_RGBWAF) != 0;
  6617 +
  6618 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_SYS_FAILURE_LEVEL));
  6619 + TEST_ASSERT(gBus->ack == 254);
  6620 +
  6621 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 240));
  6622 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  6623 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  6624 + TEST_ASSERT(gBus->ack != 0xffff);
  6625 + TEST_ASSERT(gBus->ack != 0xff);
  6626 +
  6627 + if (supp[0]) {
  6628 + activateColourType(0);
  6629 + testSystemFailureBehaviour_xy();
  6630 + testSystemFailureBehaviourMask_xy();
  6631 + }
  6632 + if (supp[1]) {
  6633 + activateColourType(1);
  6634 + testSystemFaliureBehaviour_Tc();
  6635 + testSystemFaliureBehaviourMask_Tc();
  6636 + }
  6637 + if (supp[2]) {
  6638 + activateColourType(2);
  6639 + testSystemFaliureBehaviour_PrimaryN();
  6640 + testSystemFaliureBehaviourMask_PrimaryN();
  6641 + }
  6642 + if (supp[3]) {
  6643 + activateColourType(3);
  6644 + testSystemFailureBehaviour_RGBWAF();
  6645 + testSystemFailureBehaviourMask_RGBWAF();
  6646 + }
  6647 +}
  6648 +
  6649 +void testStoreDTRAsSceneXXX() {
  6650 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  6651 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  6652 +
  6653 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  6654 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_TYPE_FEATURES));
  6655 + uint8_t features = gBus->ack;
  6656 + bool supp[4];
  6657 + supp[0] = (features & DALI_DT8_COLOUR_TYPE_FEATURES_XY) != 0;
  6658 + supp[1] = (features & DALI_DT8_COLOUR_TYPE_FEATURES_TC) != 0;
  6659 + supp[2] = (features & DALI_DT8_COLOUR_TYPE_FEATURES_PRIMARY_N) != 0;
  6660 + supp[3] = (features & DALI_DT8_COLOUR_TYPE_FEATURES_RGBWAF) != 0;
  6661 +
  6662 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  6663 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_STATUS));
  6664 + TEST_ASSERT(gBus->ack != 0xffff);
  6665 +
  6666 + uint8_t actColType = gBus->ack & 0xF0;
  6667 +
  6668 + const uint8_t expColType[] = { 0x10, 0x20, 0x40, 0x80 };
  6669 + const uint8_t dtrVal[] = { 224, 226, 227, 233 };
  6670 + const uint8_t nrQuery[] = { 2, 1, 6, 6 };
  6671 +
  6672 + uint8_t scene = 0;
  6673 + uint8_t phase = 0;
  6674 + uint16_t count = 1;
  6675 + uint8_t col = 0;
  6676 + bool performGotoScene = true;
  6677 + uint16_t expVal = 0;
  6678 + while (scene < 16) {
  6679 + Command storeDtrAsScene = (Command) ((uint16_t) Command::STORE_DTR_AS_SCENE_0 + scene);
  6680 + Command removeFromScene = (Command) ((uint16_t) Command::REMOVE_FROM_SCENE_0 + scene);
  6681 + Command querySceneLevel = (Command) ((uint16_t) Command::QUERY_SCENE_0_LEVEL + scene);
  6682 + Command goToScene = (Command) ((uint16_t) Command::GO_TO_SCENE_0 + scene);
  6683 +
  6684 + if (performGotoScene) {
  6685 + expVal = setTemporaries(col, count);
  6686 +
  6687 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, removeFromScene));
  6688 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, removeFromScene));
  6689 +
  6690 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, count));
  6691 +
  6692 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, storeDtrAsScene));
  6693 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, storeDtrAsScene));
  6694 +
  6695 + // Set report colour settings to scene colour settings
  6696 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, querySceneLevel));
  6697 + TEST_ASSERT(gBus->ack == count);
  6698 + }
  6699 +
  6700 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 240 - (phase * 32)));
  6701 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  6702 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  6703 +
  6704 + if (supp[col]) {
  6705 + if ((phase == 0) || ((phase != 0) && !performGotoScene)) {
  6706 + TEST_ASSERT(gBus->ack == expColType[col]);
  6707 +
  6708 + for (uint8_t k = 0; k < nrQuery[col]; ++k) {
  6709 + if (((phase == 0) && !performGotoScene)) {
  6710 + // FIXME test fails if there are out of range values TC or XY
  6711 + if (col == 0) {
  6712 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, k + 224));
  6713 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  6714 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  6715 + TEST_ASSERT(gBus->ack != 0xffff);
  6716 + expVal = get16bitValue();
  6717 + }
  6718 + if (col == 1) {
  6719 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, k + 226));
  6720 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  6721 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  6722 + TEST_ASSERT(gBus->ack != 0xffff);
  6723 + expVal = get16bitValue();
  6724 + }
  6725 + if (col == 3) {
  6726 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  6727 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_TYPE_FEATURES));
  6728 + TEST_ASSERT(gBus->ack != 0xffff);
  6729 + uint8_t nrChan = (gBus->ack & 0xE0) >> 5;
  6730 +
  6731 + if (k >= nrChan) {
  6732 + expVal = 0xffff;
  6733 + }
  6734 + }
  6735 + }
  6736 +
  6737 + gBus->handleReceivedData(gTimer->time,
  6738 + genData(Command::DATA_TRANSFER_REGISTER, k + dtrVal[col] - (phase * 32)));
  6739 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  6740 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  6741 + TEST_ASSERT(gBus->ack != 0xffff);
  6742 + uint8_t queryResult = gBus->ack;
  6743 + uint16_t val;
  6744 + uint8_t msb;
  6745 + if (col == 3) {
  6746 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_CONTENT_DTR1));
  6747 + TEST_ASSERT(gBus->ack != 0xffff);
  6748 + msb = queryResult;
  6749 + val = queryResult | (queryResult << 8);
  6750 + } else {
  6751 + val = get16bitValue();
  6752 + msb = val >> 8;
  6753 + }
  6754 +
  6755 + if (col == 2) { // FIXME
  6756 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 82));
  6757 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  6758 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  6759 +
  6760 + uint8_t nrPrim = gBus->ack;
  6761 +
  6762 + if (k >= nrPrim) {
  6763 + TEST_ASSERT(val == DALI_DT8_MASK16);
  6764 + } else {
  6765 + TEST_ASSERT((val == expVal) && ((expVal >> 8) == msb));
  6766 + TEST_ASSERT(queryResult == msb);
  6767 + }
  6768 + } else if (col == 3) { // FIXME
  6769 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  6770 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_TYPE_FEATURES));
  6771 + uint8_t nrChan = (gBus->ack & 0xE0) >> 5;
  6772 +
  6773 + if (k >= nrChan) {
  6774 + TEST_ASSERT(val == DALI_DT8_MASK16);
  6775 + } else {
  6776 + TEST_ASSERT((val == expVal) && ((expVal >> 8) == msb));
  6777 + TEST_ASSERT(queryResult == msb);
  6778 + }
  6779 + }
  6780 + }
  6781 +
  6782 + if (col == 3) {
  6783 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 239));
  6784 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  6785 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_VALUE));
  6786 + TEST_ASSERT(gBus->ack != 0xffff);
  6787 + TEST_ASSERT((gBus->ack & 0b11000001) == 0b01000001);
  6788 + }
  6789 + } else {
  6790 + if (performGotoScene) {
  6791 + TEST_ASSERT(gBus->ack == 255);
  6792 + }
  6793 + }
  6794 + } else {
  6795 + if (phase == 0) {
  6796 + if (performGotoScene) {
  6797 + TEST_ASSERT(gBus->ack == 255);
  6798 + } else {
  6799 + TEST_ASSERT(gBus->ack == actColType);
  6800 + }
  6801 + } else {
  6802 + TEST_ASSERT(gBus->ack == 255);
  6803 + }
  6804 + }
  6805 +
  6806 + if (performGotoScene) {
  6807 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  6808 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_STATUS));
  6809 + TEST_ASSERT(gBus->ack != 0xffff);
  6810 +
  6811 + actColType = gBus->ack & 0xF0;
  6812 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, goToScene));
  6813 +
  6814 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_ACTUAL_LEVEL));
  6815 + TEST_ASSERT(gBus->ack != 0xffff);
  6816 +
  6817 + performGotoScene = false;
  6818 + } else {
  6819 + count = count * 2;
  6820 + performGotoScene = true;
  6821 + if (count > 255) {
  6822 + count = 1;
  6823 + col = col + 1;
  6824 + }
  6825 + if (col > 3) {
  6826 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, phase));
  6827 +
  6828 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  6829 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::STORE_GEAR_FEATURES_STATUS));
  6830 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::STORE_GEAR_FEATURES_STATUS));
  6831 +
  6832 + col = 0;
  6833 + phase = (phase + 1) % 2;
  6834 + if (phase == 0) {
  6835 + scene = scene + 1;
  6836 + }
  6837 + }
  6838 + }
  6839 + }
  6840 +}
  6841 +
  6842 +void testEnableDeviceTypeApplicationExtendedCcommands() {
  6843 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  6844 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  6845 +
  6846 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::ADD_TO_GROUP_1));
  6847 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::ADD_TO_GROUP_1));
  6848 +
  6849 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 3));
  6850 +
  6851 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_SHORT_ADDR));
  6852 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_SHORT_ADDR));
  6853 +
  6854 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_PHISICAL_MIN_LEVEL));
  6855 + TEST_ASSERT(gBus->ack > 0 && gBus->ack < 255);
  6856 + uint8_t minlevel = gBus->ack == 254 ? 0 : gBus->ack;
  6857 +
  6858 + const uint8_t addr[] = { DALI_MASK, (1 << 1) | 1, (2 << 1) | 1, 0x80 | (1 << 1) | 1, 0x80 | (2 << 1) | 1 };
  6859 + for (uint8_t i = 0; i < 5; ++i) {
  6860 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  6861 +
  6862 + gBus->handleReceivedData(gTimer->time, genDataDPC(addr[i], minlevel));
  6863 +
  6864 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_COLOUR_TYPE_FEATURES));
  6865 + if (gBus->ack != 0xffff) {
  6866 + switch (i) {
  6867 + case 0:
  6868 + case 1:
  6869 + case 3:
  6870 + TEST_ASSERT(false);
  6871 + break;
  6872 + }
  6873 + } else {
  6874 + switch (i) {
  6875 + case 2:
  6876 + case 4:
  6877 + TEST_ASSERT(false);
  6878 + break;
  6879 + }
  6880 + }
  6881 +
  6882 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_ACTUAL_LEVEL));
  6883 + TEST_ASSERT(gBus->ack != 0xffff);
  6884 +
  6885 + if (gBus->ack != minlevel) {
  6886 + switch (i) {
  6887 + case 0:
  6888 + case 1:
  6889 + case 3:
  6890 + TEST_ASSERT(false);
  6891 + break;
  6892 + }
  6893 + } else {
  6894 + switch (i) {
  6895 + case 2:
  6896 + case 4:
  6897 + TEST_ASSERT(false);
  6898 + break;
  6899 + }
  6900 + }
  6901 +
  6902 + gBus->handleReceivedData(gTimer->time, genDataDPC(addr[i], 254));
  6903 + }
  6904 +
  6905 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::REMOVE_FROM_GROUP_1));
  6906 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::REMOVE_FROM_GROUP_1));
  6907 +
  6908 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, 255));
  6909 +
  6910 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_SHORT_ADDR));
  6911 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::STORE_DTR_AS_SHORT_ADDR));
  6912 +}
  6913 +
  6914 +void testGeneralConfigurationCommands() {
  6915 + testReset(); // 12.2.1.1
  6916 +}
  6917 +
  6918 +void testApplicationExtendedQueryCommands() {
  6919 + testQueryGearFeaturesStatus(); // 12.7.1.1
  6920 + testQueryColourStatus(); // 12.7.1.2
  6921 + testQueryColourTypeFeatures(); // 12.7.1.3
  6922 + testQueryColourValue(); // 12.7.1.4
  6923 + testQueryRGBWAFControl(); // 12.7.1.5
  6924 + testQueryAssignedColour(); // 12.7.1.6
  6925 +}
  6926 +
  6927 +void testApplicationExtendedConfigurationCommands() {
  6928 + testStoreTyPrimaryN(); // 12.7.2.2
  6929 + testStoreXYCoordinatePrimaryN(); // 12.7.2.3
  6930 + testStoreColourTemperatureLimit(); // 12.7.2.4
  6931 + testStoreGearFeaturesStatus(); // 12.7.2.5
  6932 + testAutomaticActivate(); // 12.7.2.6
  6933 + testAssignColourToLinkedChannel(); // 12.7.2.7
  6934 + testStartAutoCalibration(); // 12.7.2.8
  6935 + testPowerOnColor(); // 12.7.2.9
  6936 + testSystemFaliure(); // 12.7.2.10
  6937 + testStoreDTRAsSceneXXX(); // 12.7.2.11
  6938 +}
  6939 +
  6940 +void testEnableDeviceType() {
  6941 + testEnableDeviceTypeApplicationExtendedCcommands(); // 12.7.3.1
  6942 + testEnableDeviceTypeApplicationExtendedConfigurationCommands(); // 12.7.3.2
  6943 +}
  6944 +
  6945 +void testApplicationExtendedControlCommands() {
  6946 + testSetTemporaryXCoordinate(); // 12.7.4.1
  6947 + testSetTemporaryYCoordinate(); // 12.7.4.2
  6948 + testActivate(); // 12.7.4.3
  6949 + testXCoordinateStepUp(); // 12.7.4.4
  6950 + testXCoordinateStepDown(); // 12.7.4.5
  6951 + testSetTemporaryColourTemperature(); // 12.7.4.8
  6952 + testColourTemperatureTcStepCooler(); // 12.7.4.9
  6953 + testColourTemperatureStepWarmer(); // 12.7.4.10
  6954 + testSetTemporaryPrimaryNDimlevel(); // 12.7.4.11
  6955 + testSetTemporaryRGBDimlevel(); // 12.7.4.12
  6956 + testSetTemporaryWAFDimlevel(); // 12.7.4.13
  6957 + testSetRGBWAFControl(); // 12.7.4.14
  6958 + testCopyReportToTemprary(); // 12.7.4.15
  6959 +}
  6960 +
  6961 +
  6962 +void testQueryExtendedVersionNumber() {
  6963 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  6964 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  6965 +
  6966 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_DEVICE_TYPE));
  6967 + TEST_ASSERT(gBus->ack != 0xffff);
  6968 + bool multiple = gBus->ack != 255;
  6969 +
  6970 + for (uint16_t i = 0; i < 255; ++i) {
  6971 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, i));
  6972 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_EXTENDED_VERSION_NUMBER));
  6973 +
  6974 + if (gBus->ack != 0xffff) {
  6975 + if (!multiple) {
  6976 + if (i == 8) {
  6977 + TEST_ASSERT(gBus->ack == 2);
  6978 + } else {
  6979 + TEST_ASSERT(false);
  6980 + }
  6981 + } else {
  6982 + if (i == 8) {
  6983 + TEST_ASSERT(gBus->ack == 2);
  6984 + }
  6985 + }
  6986 + } else {
  6987 + TEST_ASSERT(i != 8);
  6988 + }
  6989 + }
  6990 +}
  6991 +
  6992 +void testReverseddApplicationExtendedCommands() {
  6993 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  6994 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::RESET));
  6995 +
  6996 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_DEVICE_TYPE));
  6997 + TEST_ASSERT(gBus->ack != 0xffff);
  6998 + switch(gBus->ack) {
  6999 + case 255:
  7000 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  7001 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, CommandDT8::QUERY_EXTENDED_VERSION_NUMBER));
  7002 + TEST_ASSERT(gBus->ack != 0xffff);
  7003 + break;
  7004 +
  7005 + case 8: {
  7006 + uint8_t i = 239;
  7007 + do {
  7008 + for (uint16_t k = 0; k < 256; ++k) {
  7009 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER, k));
  7010 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_1, k));
  7011 + gBus->handleReceivedData(gTimer->time, genData(Command::DATA_TRANSFER_REGISTER_2, k));
  7012 + Command command = (Command)i;
  7013 + if (239 <= i && i <= 246) {
  7014 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  7015 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, command));
  7016 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, command));
  7017 + } else {
  7018 + gBus->handleReceivedData(gTimer->time, genData(Command::ENABLE_DEVICE_TYPE_X, 8));
  7019 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, command));
  7020 + }
  7021 + }
  7022 + TEST_ASSERT(gBus->ack == 0xffff);
  7023 +
  7024 + gBus->handleReceivedData(gTimer->time, genData(DALI_MASK, Command::QUERY_RESET_STATE));
  7025 + TEST_ASSERT(gBus->ack == 0xff);
  7026 +
  7027 + switch(i) {
  7028 + case 239:
  7029 + i = 244;
  7030 + break;
  7031 + case 244:
  7032 + i= 253;
  7033 + break;
  7034 + case 253:
  7035 + i = 254;
  7036 + break;
  7037 + default:
  7038 + i = 0;
  7039 + break;
  7040 + }
  7041 + } while (i != 0);
  7042 + break;
  7043 + }
  7044 +
  7045 + default:
  7046 + TEST_ASSERT(false); // Device Does not support type 8. This test is not possible
  7047 + break;
  7048 + }
  7049 +
  7050 +}
  7051 +
  7052 +void testStandardApplicationExtendedCommands() {
  7053 + testQueryExtendedVersionNumber();
  7054 + testReverseddApplicationExtendedCommands();
  7055 +}
  7056 +
  7057 +} // namespace
  7058 +
  7059 +void unitTestsDT8() {
  7060 +// controller::ColorDT8::unitTest();
  7061 +// controller::LampDT8::unitTest();
  7062 +// controller::MemoryDT8::unitTest();
  7063 +// controller::QueryStoreDT8::unitTest();
  7064 +}
  7065 +
  7066 +void apiTestsDT8(CreateSlave createSlave) {
  7067 + apiTests(createSlave);
  7068 +
  7069 + gCreateSlave = createSlave;
  7070 + gMemory = new MemoryMock(252);
  7071 + gLamp = new LampMock();
  7072 + gBus = new BusMock();
  7073 + gTimer = new TimerMock();
  7074 +
  7075 + gSlave = gCreateSlave(gMemory, gLamp, gBus, gTimer);
  7076 + TEST_ASSERT(gSlave != nullptr);
  7077 +
  7078 + gSlave->notifyPowerUp();
  7079 +
  7080 + testGeneralConfigurationCommands();
  7081 + testApplicationExtendedQueryCommands();
  7082 + testApplicationExtendedConfigurationCommands();
  7083 + testEnableDeviceType();
  7084 + testApplicationExtendedControlCommands();
  7085 + testStandardApplicationExtendedCommands();
  7086 +
  7087 + gSlave->notifyPowerDown();
  7088 + delete gSlave; // simulate power off
  7089 +
  7090 + delete gTimer;
  7091 + delete gBus;
  7092 + delete gLamp;
  7093 + delete gMemory;
  7094 +}
  7095 +
  7096 +} // namespace dali
  7097 +
  7098 +#endif // DALI_TEST
  7099 +
  7100 +#endif // DALI_DT8
src/test/tests_dt8.hpp 0 โ†’ 100644
  1 +/*
  2 + * Copyright (c) 2015-2016, Arkadiusz Materek (arekmat@poczta.fm)
  3 + *
  4 + * All right reversed. Usage for commercial on not commercial
  5 + * purpose without written permission is not allowed.
  6 + *
  7 + * This program is distributed in the hope that it will be useful,
  8 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10 + */
  11 +
  12 +#ifndef DALI_TEST_TEST_DT8_HPP_
  13 +#define DALI_TEST_TEST_DT8_HPP_
  14 +
  15 +#ifdef DALI_TEST
  16 +
  17 +#include "tests.hpp"
  18 +
  19 +#include <dali/dali_dt8.hpp>
  20 +
  21 +#ifdef DALI_DT8
  22 +
  23 +namespace dali {
  24 +
  25 +void unitTestsDT8();
  26 +void apiTestsDT8(CreateSlave createSlave);
  27 +
  28 +} // namespace dali
  29 +
  30 +#endif // DALI_DT8
  31 +
  32 +#endif // DALI_TEST
  33 +
  34 +#endif // DALI_TEST_TEST_DT8_HPP_
src/xmc1200/main.cpp
@@ -25,6 +25,18 @@ @@ -25,6 +25,18 @@
25 #include <xmc_gpio.h> 25 #include <xmc_gpio.h>
26 #include <xmc_scu.h> 26 #include <xmc_scu.h>
27 27
  28 +#ifdef DALI_TEST
  29 +
  30 +#include <test/tests_dt8.hpp>
  31 +
  32 +void daliTests() {
  33 + dali::unitTests();
  34 + dali::apiTests(dali::Slave::create);
  35 + dali::unitTestsDT8();
  36 + dali::apiTestsDT8(dali::SlaveDT8::create);
  37 +}
  38 +#endif // DALI_TEST
  39 +
28 dali::Slave* gSlave; 40 dali::Slave* gSlave;
29 41
30 void waitForInterrupt() { 42 void waitForInterrupt() {
@@ -68,6 +80,9 @@ volatile bool gEmergencyMemorySynchronise; @@ -68,6 +80,9 @@ volatile bool gEmergencyMemorySynchronise;
68 int main(void) { 80 int main(void) {
69 xmc::Clock::init(XMC_CPU_FREQ); 81 xmc::Clock::init(XMC_CPU_FREQ);
70 82
  83 +#ifdef DALI_TEST
  84 + daliTests();
  85 +#endif
71 86
72 initPowerDetector(); 87 initPowerDetector();
73 88