feat(sacn): Slotzahl je Board und vier Settings-Felder
This commit is contained in:
@@ -49,3 +49,8 @@ const nl_board_t *nl_board_get(void)
|
|||||||
return nl_board_find(NINLIGHT_DEVICE_ID);
|
return nl_board_find(NINLIGHT_DEVICE_ID);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
uint8_t nl_board_dmx_slots(const nl_board_t *b)
|
||||||
|
{
|
||||||
|
return (b != NULL && b->has_rgb) ? 6u : 3u;
|
||||||
|
}
|
||||||
|
|||||||
@@ -41,4 +41,8 @@ const nl_board_t *nl_board_find(const char *id);
|
|||||||
/* Board selected at build time via NINLIGHT_DEVICE_ID. */
|
/* Board selected at build time via NINLIGHT_DEVICE_ID. */
|
||||||
const nl_board_t *nl_board_get(void);
|
const nl_board_t *nl_board_get(void);
|
||||||
|
|
||||||
|
/* Slots, die eine Lampe im DMX-Universe belegt: Dimmer + R,G,B,CW,WW bzw. Dimmer + CW,WW.
|
||||||
|
* Steht hier, damit API, Uebernahme-Schicht und Doku dieselbe Zahl benutzen. */
|
||||||
|
uint8_t nl_board_dmx_slots(const nl_board_t *b);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -38,6 +38,12 @@ typedef struct {
|
|||||||
* really has to start right behind the header (no padding). Compile-time, gnu99-compatible. */
|
* really has to start right behind the header (no padding). Compile-time, gnu99-compatible. */
|
||||||
typedef char nl_settings_layout_check[offsetof(rec_t, data) == sizeof(rec_hdr_t) ? 1 : -1];
|
typedef char nl_settings_layout_check[offsetof(rec_t, data) == sizeof(rec_hdr_t) ? 1 : -1];
|
||||||
|
|
||||||
|
/* Die Satzlaenge muss ein Vielfaches von 4 bleiben - sonst zeigt NL_SETTINGS_CRC_OFF() woanders
|
||||||
|
* hin als offsetof(rec_t, crc), und jeder gespeicherte Datensatz faellt beim naechsten Boot
|
||||||
|
* durch die CRC-Pruefung. Wer hier anstoesst, fuegt ein Fuellbyte hinzu, statt die Pruefung
|
||||||
|
* zu entfernen. */
|
||||||
|
typedef char nl_settings_size_check[(sizeof(nl_settings_t) % 4u == 0u) ? 1 : -1];
|
||||||
|
|
||||||
static uint32_t s_addr[2];
|
static uint32_t s_addr[2];
|
||||||
|
|
||||||
void nl_settings_defaults(nl_settings_t *s)
|
void nl_settings_defaults(nl_settings_t *s)
|
||||||
@@ -49,6 +55,10 @@ void nl_settings_defaults(nl_settings_t *s)
|
|||||||
s->fade_out_ms = 500;
|
s->fade_out_ms = 500;
|
||||||
s->transition_ms = 300;
|
s->transition_ms = 300;
|
||||||
s->wake_on_change = 0;
|
s->wake_on_change = 0;
|
||||||
|
s->sacn_enabled = 1;
|
||||||
|
s->sacn_universe = 1;
|
||||||
|
s->sacn_start_slot = 1;
|
||||||
|
s->sacn_hold = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void nl_settings_init(uint32_t addr_a, uint32_t addr_b)
|
void nl_settings_init(uint32_t addr_a, uint32_t addr_b)
|
||||||
|
|||||||
@@ -28,6 +28,11 @@ typedef struct {
|
|||||||
* switching on or off. */
|
* switching on or off. */
|
||||||
uint8_t wake_on_change; /* if set, such a change also switches the lamp on when it was
|
uint8_t wake_on_change; /* if set, such a change also switches the lamp on when it was
|
||||||
* off, unless the same call says "on": false. */
|
* off, unless the same call says "on": false. */
|
||||||
|
uint8_t sacn_enabled; /* sACN/E1.31-Empfang aktiv (Vorgabe 1) */
|
||||||
|
uint16_t sacn_universe; /* 1..63999 (Vorgabe 1) */
|
||||||
|
uint16_t sacn_start_slot; /* 1..512 (Vorgabe 1) */
|
||||||
|
uint8_t sacn_hold; /* 0 = nach dem Timeout zurueck zum HA-Zustand, 1 = halten */
|
||||||
|
uint8_t _padding[2]; /* padding for 4-byte alignment of sizeof(nl_settings_t) */
|
||||||
} nl_settings_t;
|
} nl_settings_t;
|
||||||
|
|
||||||
void nl_settings_defaults(nl_settings_t *s);
|
void nl_settings_defaults(nl_settings_t *s);
|
||||||
|
|||||||
@@ -106,6 +106,13 @@ static void test_known_values_from_old_firmware(void)
|
|||||||
TEST_ASSERT_EQUAL_INT8(3, g95->pwm[NL_CH_WW].pwm_ch);
|
TEST_ASSERT_EQUAL_INT8(3, g95->pwm[NL_CH_WW].pwm_ch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_dmx_slots(void)
|
||||||
|
{
|
||||||
|
TEST_ASSERT_EQUAL_UINT8(6, nl_board_dmx_slots(nl_board_find("gu10_rgb")));
|
||||||
|
TEST_ASSERT_EQUAL_UINT8(3, nl_board_dmx_slots(nl_board_find("g95_cw")));
|
||||||
|
TEST_ASSERT_EQUAL_UINT8(6, nl_board_dmx_slots(nl_board_find("evk")));
|
||||||
|
}
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
UNITY_BEGIN();
|
UNITY_BEGIN();
|
||||||
@@ -115,5 +122,6 @@ int main(void)
|
|||||||
RUN_TEST(test_pwm_boards_consistent);
|
RUN_TEST(test_pwm_boards_consistent);
|
||||||
RUN_TEST(test_sm_boards_consistent);
|
RUN_TEST(test_sm_boards_consistent);
|
||||||
RUN_TEST(test_known_values_from_old_firmware);
|
RUN_TEST(test_known_values_from_old_firmware);
|
||||||
|
RUN_TEST(test_dmx_slots);
|
||||||
return UNITY_END();
|
return UNITY_END();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -182,6 +182,60 @@ static void test_erase(void)
|
|||||||
TEST_ASSERT_FALSE(nl_settings_load(&out));
|
TEST_ASSERT_FALSE(nl_settings_load(&out));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_sacn_defaults(void)
|
||||||
|
{
|
||||||
|
nl_settings_t s;
|
||||||
|
TEST_ASSERT_FALSE(nl_settings_load(&s));
|
||||||
|
TEST_ASSERT_EQUAL_UINT8(1, s.sacn_enabled);
|
||||||
|
TEST_ASSERT_EQUAL_UINT16(1, s.sacn_universe);
|
||||||
|
TEST_ASSERT_EQUAL_UINT16(1, s.sacn_start_slot);
|
||||||
|
TEST_ASSERT_EQUAL_UINT8(0, s.sacn_hold);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_sacn_roundtrip(void)
|
||||||
|
{
|
||||||
|
nl_settings_t in = sample("dmx"), out;
|
||||||
|
in.sacn_enabled = 0;
|
||||||
|
in.sacn_universe = 4711;
|
||||||
|
in.sacn_start_slot = 300;
|
||||||
|
in.sacn_hold = 1;
|
||||||
|
TEST_ASSERT_EQUAL_INT(0, nl_settings_save(&in));
|
||||||
|
TEST_ASSERT_TRUE(nl_settings_load(&out));
|
||||||
|
TEST_ASSERT_EQUAL_UINT8(0, out.sacn_enabled);
|
||||||
|
TEST_ASSERT_EQUAL_UINT16(4711, out.sacn_universe);
|
||||||
|
TEST_ASSERT_EQUAL_UINT16(300, out.sacn_start_slot);
|
||||||
|
TEST_ASSERT_EQUAL_UINT8(1, out.sacn_hold);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ein Datensatz aus einer Firmware VOR sACN: die vier Felder muessen als echte Vorgaben
|
||||||
|
* zurueckkommen, nicht als Null - sonst waere sACN auf jeder aktualisierten Lampe aus. */
|
||||||
|
static void test_record_without_sacn_gets_defaults(void)
|
||||||
|
{
|
||||||
|
nl_settings_t in = sample("alt"), out;
|
||||||
|
uint32_t crc;
|
||||||
|
nl_settings_save(&in);
|
||||||
|
{
|
||||||
|
uint16_t shorter = (uint16_t)offsetof(nl_settings_t, sacn_enabled);
|
||||||
|
memcpy(&fake_flash_mem[NL_FL_SETTINGS_A + 6], &shorter, 2);
|
||||||
|
crc = nl_crc32(0, &fake_flash_mem[NL_FL_SETTINGS_A], 12 + shorter);
|
||||||
|
memcpy(&fake_flash_mem[NL_FL_SETTINGS_A + 12 + shorter], &crc, 4);
|
||||||
|
}
|
||||||
|
TEST_ASSERT_TRUE(nl_settings_load(&out));
|
||||||
|
TEST_ASSERT_EQUAL_STRING("alt", out.name);
|
||||||
|
TEST_ASSERT_EQUAL_STRING("ninHome", out.wifi_ssid);
|
||||||
|
TEST_ASSERT_EQUAL_UINT8(1, out.sacn_enabled);
|
||||||
|
TEST_ASSERT_EQUAL_UINT16(1, out.sacn_universe);
|
||||||
|
TEST_ASSERT_EQUAL_UINT16(1, out.sacn_start_slot);
|
||||||
|
TEST_ASSERT_EQUAL_UINT8(0, out.sacn_hold);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Die Satzlaenge muss durch 4 teilbar bleiben, sonst laufen Schreiber und Leser beim CRC
|
||||||
|
* auseinander (siehe NL_SETTINGS_CRC_OFF in nl_settings.c). */
|
||||||
|
static void test_record_size_stays_aligned(void)
|
||||||
|
{
|
||||||
|
TEST_ASSERT_EQUAL_UINT(0, sizeof(nl_settings_t) % 4u);
|
||||||
|
}
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
UNITY_BEGIN();
|
UNITY_BEGIN();
|
||||||
@@ -196,5 +250,9 @@ int main(void)
|
|||||||
RUN_TEST(test_ota_pending_default_and_roundtrip);
|
RUN_TEST(test_ota_pending_default_and_roundtrip);
|
||||||
RUN_TEST(test_crc_offset_matches_reader);
|
RUN_TEST(test_crc_offset_matches_reader);
|
||||||
RUN_TEST(test_erase);
|
RUN_TEST(test_erase);
|
||||||
|
RUN_TEST(test_sacn_defaults);
|
||||||
|
RUN_TEST(test_sacn_roundtrip);
|
||||||
|
RUN_TEST(test_record_without_sacn_gets_defaults);
|
||||||
|
RUN_TEST(test_record_size_stays_aligned);
|
||||||
return UNITY_END();
|
return UNITY_END();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user