feat: Board-Tabelle für alle acht Gerätetypen
This commit is contained in:
+2
-1
@@ -29,7 +29,8 @@ set(NL_FW_SOURCES
|
|||||||
src/util/nl_sha256.c
|
src/util/nl_sha256.c
|
||||||
src/util/nl_crc.c
|
src/util/nl_crc.c
|
||||||
src/sys/fwup_hook_default.c
|
src/sys/fwup_hook_default.c
|
||||||
src/sys/sdk_stubs.c)
|
src/sys/sdk_stubs.c
|
||||||
|
src/board/nl_board.c)
|
||||||
|
|
||||||
set(NL_FW ninlight_${NINLIGHT_DEVICE})
|
set(NL_FW ninlight_${NINLIGHT_DEVICE})
|
||||||
add_executable(${NL_FW} ${NL_SDK_BOOT_SOURCES} ${NL_FW_SOURCES} ${NL_SDK_OBJECTS})
|
add_executable(${NL_FW} ${NL_SDK_BOOT_SOURCES} ${NL_FW_SOURCES} ${NL_SDK_OBJECTS})
|
||||||
|
|||||||
@@ -0,0 +1,50 @@
|
|||||||
|
#include "board/nl_board.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#define NONE {-1, NL_PIN_NONE, false, false}
|
||||||
|
#define CH(c, p) {(c), (p), false, false}
|
||||||
|
#define CHL(c, p) {(c), (p), true, false} /* active low */
|
||||||
|
#define CHA(c, p) {(c), (p), false, true} /* antiphase */
|
||||||
|
|
||||||
|
/* SM2135EH current codes: RGB high nibble (15 mA = 1, 40 mA = 6, 45 mA = 7),
|
||||||
|
* WY low nibble (15 mA = 3, 35 mA = 7). Values from qcl_build_config_lamp.h. */
|
||||||
|
#define NO_SM NL_PIN_NONE, NL_PIN_NONE, 0
|
||||||
|
|
||||||
|
const nl_board_t nl_boards[] = {
|
||||||
|
/* R G B CW WW */
|
||||||
|
{"evk", "W600 EVK v1.2", NL_DRV_PWM, true, 2700, 6500, 5000,
|
||||||
|
{CHL(0, NL_PB(18)), CHL(2, NL_PB(16)), CHL(3, NL_PB(15)), CHL(1, NL_PB(13)), CHL(4, NL_PB(8))}, NO_SM},
|
||||||
|
{"e27_rgb", "Klyqa E27 RGB CW/WW", NL_DRV_SM2135EH, true, 2700, 6500, 0,
|
||||||
|
{NONE, NONE, NONE, NONE, NONE}, NL_PB(13), NL_PB(8), 0x17},
|
||||||
|
{"e14_rgb", "Klyqa E14 RGB CW/WW", NL_DRV_SM2135EH, true, 2700, 6500, 0,
|
||||||
|
{NONE, NONE, NONE, NONE, NONE}, NL_PB(8), NL_PB(13), 0x73},
|
||||||
|
{"gu10_rgb", "Klyqa GU10 RGB CW/WW", NL_DRV_SM2135EH, true, 2700, 6500, 0,
|
||||||
|
{NONE, NONE, NONE, NONE, NONE}, NL_PB(8), NL_PB(13), 0x63},
|
||||||
|
{"e27_cw", "Klyqa E27 CW/WW", NL_DRV_PWM, false, 2500, 5000, 600,
|
||||||
|
{NONE, NONE, NONE, CHA(1, NL_PB(13)), CH(4, NL_PB(8))}, NO_SM},
|
||||||
|
{"e14_cw", "Klyqa E14 CW/WW", NL_DRV_PWM, false, 2500, 5000, 600,
|
||||||
|
{NONE, NONE, NONE, CH(2, NL_PB(16)), CH(4, NL_PB(8))}, NO_SM},
|
||||||
|
{"gu10_cw", "Klyqa GU10 CW/WW", NL_DRV_PWM, false, 2500, 5000, 600,
|
||||||
|
{NONE, NONE, NONE, CH(2, NL_PB(16)), CH(4, NL_PB(8))}, NO_SM},
|
||||||
|
/* G95: pin assignment still to be verified on a series bulb (old note: PB16=WW, PB15=CW). */
|
||||||
|
{"g95_cw", "Klyqa G95 Vintage CW/WW", NL_DRV_PWM, false, 2500, 5000, 600,
|
||||||
|
{NONE, NONE, NONE, CH(1, NL_PB(13)), CH(3, NL_PB(15))}, NO_SM},
|
||||||
|
};
|
||||||
|
|
||||||
|
const size_t nl_boards_count = sizeof(nl_boards) / sizeof(nl_boards[0]);
|
||||||
|
|
||||||
|
const nl_board_t *nl_board_find(const char *id)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < nl_boards_count; i++)
|
||||||
|
if (strcmp(nl_boards[i].id, id) == 0)
|
||||||
|
return &nl_boards[i];
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef NINLIGHT_DEVICE_ID
|
||||||
|
const nl_board_t *nl_board_get(void)
|
||||||
|
{
|
||||||
|
return nl_board_find(NINLIGHT_DEVICE_ID);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
#ifndef NL_BOARD_H
|
||||||
|
#define NL_BOARD_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/* GPIO numbers are identical to enum tls_io_name of the W600 SDK (PA_00 = 0, PB_00 = 16). */
|
||||||
|
#define NL_PB(n) ((uint8_t)(16u + (n)))
|
||||||
|
#define NL_PIN_NONE 0xFFu
|
||||||
|
|
||||||
|
typedef enum { NL_CH_R = 0, NL_CH_G, NL_CH_B, NL_CH_CW, NL_CH_WW, NL_CH_COUNT } nl_channel_t;
|
||||||
|
typedef enum { NL_DRV_PWM = 0, NL_DRV_SM2135EH } nl_led_driver_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int8_t pwm_ch; /* PWM unit channel 0..4, -1 = channel not populated */
|
||||||
|
uint8_t pin; /* NL_PB(x) or NL_PIN_NONE */
|
||||||
|
bool active_low; /* LED lights up while the pin is low */
|
||||||
|
bool antiphase; /* inverted PWM output, shifts the pulse (e27_cw cold white) */
|
||||||
|
} nl_pwm_chan_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
const char *id;
|
||||||
|
const char *name;
|
||||||
|
nl_led_driver_t driver;
|
||||||
|
bool has_rgb;
|
||||||
|
uint16_t ct_min; /* Kelvin, warmest */
|
||||||
|
uint16_t ct_max; /* Kelvin, coldest */
|
||||||
|
uint32_t pwm_freq_hz; /* PWM boards */
|
||||||
|
nl_pwm_chan_t pwm[NL_CH_COUNT];
|
||||||
|
uint8_t sm_clk_pin; /* SM2135EH boards */
|
||||||
|
uint8_t sm_dat_pin;
|
||||||
|
uint8_t sm_current; /* (rgb_code << 4) | wy_code, see SM2135EH datasheet */
|
||||||
|
} nl_board_t;
|
||||||
|
|
||||||
|
extern const nl_board_t nl_boards[];
|
||||||
|
extern const size_t nl_boards_count;
|
||||||
|
|
||||||
|
const nl_board_t *nl_board_find(const char *id);
|
||||||
|
|
||||||
|
/* Board selected at build time via NINLIGHT_DEVICE_ID. */
|
||||||
|
const nl_board_t *nl_board_get(void);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -24,3 +24,4 @@ endfunction()
|
|||||||
|
|
||||||
nl_test(test_sha256 test_sha256.c ${NL_SRC}/util/nl_sha256.c)
|
nl_test(test_sha256 test_sha256.c ${NL_SRC}/util/nl_sha256.c)
|
||||||
nl_test(test_crc test_crc.c ${NL_SRC}/util/nl_crc.c)
|
nl_test(test_crc test_crc.c ${NL_SRC}/util/nl_crc.c)
|
||||||
|
nl_test(test_board test_board.c ${NL_SRC}/board/nl_board.c)
|
||||||
|
|||||||
@@ -0,0 +1,114 @@
|
|||||||
|
#include <string.h>
|
||||||
|
#include "unity.h"
|
||||||
|
#include "board/nl_board.h"
|
||||||
|
|
||||||
|
void setUp(void) {}
|
||||||
|
void tearDown(void) {}
|
||||||
|
|
||||||
|
static const char *IDS[] = {"evk", "e27_rgb", "e14_rgb", "gu10_rgb", "e27_cw", "e14_cw", "gu10_cw", "g95_cw"};
|
||||||
|
|
||||||
|
static void test_all_devices_present(void)
|
||||||
|
{
|
||||||
|
TEST_ASSERT_EQUAL_UINT(8, nl_boards_count);
|
||||||
|
for (size_t i = 0; i < 8; i++) {
|
||||||
|
const nl_board_t *b = nl_board_find(IDS[i]);
|
||||||
|
TEST_ASSERT_NOT_NULL_MESSAGE(b, IDS[i]);
|
||||||
|
TEST_ASSERT_EQUAL_STRING(IDS[i], b->id);
|
||||||
|
TEST_ASSERT_NOT_NULL(b->name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_unknown_is_null(void)
|
||||||
|
{
|
||||||
|
TEST_ASSERT_NULL(nl_board_find("e27"));
|
||||||
|
TEST_ASSERT_NULL(nl_board_find(""));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_rgb_flags_and_ct_ranges(void)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < nl_boards_count; i++) {
|
||||||
|
const nl_board_t *b = &nl_boards[i];
|
||||||
|
bool rgb = strstr(b->id, "rgb") != NULL || strcmp(b->id, "evk") == 0;
|
||||||
|
TEST_ASSERT_EQUAL_MESSAGE(rgb, b->has_rgb, b->id);
|
||||||
|
TEST_ASSERT_EQUAL_UINT16(rgb ? 2700 : 2500, b->ct_min);
|
||||||
|
TEST_ASSERT_EQUAL_UINT16(rgb ? 6500 : 5000, b->ct_max);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_pwm_boards_consistent(void)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < nl_boards_count; i++) {
|
||||||
|
const nl_board_t *b = &nl_boards[i];
|
||||||
|
if (b->driver != NL_DRV_PWM)
|
||||||
|
continue;
|
||||||
|
TEST_ASSERT_TRUE(b->pwm_freq_hz > 0);
|
||||||
|
TEST_ASSERT_TRUE(b->pwm[NL_CH_CW].pwm_ch >= 0);
|
||||||
|
TEST_ASSERT_TRUE(b->pwm[NL_CH_WW].pwm_ch >= 0);
|
||||||
|
for (int c = NL_CH_R; c <= NL_CH_B; c++)
|
||||||
|
TEST_ASSERT_EQUAL_MESSAGE(b->has_rgb, b->pwm[c].pwm_ch >= 0, b->id);
|
||||||
|
for (int c = 0; c < NL_CH_COUNT; c++) {
|
||||||
|
if (b->pwm[c].pwm_ch < 0)
|
||||||
|
continue;
|
||||||
|
TEST_ASSERT_TRUE(b->pwm[c].pwm_ch <= 4);
|
||||||
|
for (int d = c + 1; d < NL_CH_COUNT; d++) {
|
||||||
|
if (b->pwm[d].pwm_ch < 0)
|
||||||
|
continue;
|
||||||
|
TEST_ASSERT_NOT_EQUAL(b->pwm[c].pwm_ch, b->pwm[d].pwm_ch);
|
||||||
|
TEST_ASSERT_NOT_EQUAL(b->pwm[c].pin, b->pwm[d].pin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_sm_boards_consistent(void)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < nl_boards_count; i++) {
|
||||||
|
const nl_board_t *b = &nl_boards[i];
|
||||||
|
if (b->driver != NL_DRV_SM2135EH)
|
||||||
|
continue;
|
||||||
|
TEST_ASSERT_TRUE(b->has_rgb);
|
||||||
|
TEST_ASSERT_NOT_EQUAL(NL_PIN_NONE, b->sm_clk_pin);
|
||||||
|
TEST_ASSERT_NOT_EQUAL(NL_PIN_NONE, b->sm_dat_pin);
|
||||||
|
TEST_ASSERT_NOT_EQUAL(b->sm_clk_pin, b->sm_dat_pin);
|
||||||
|
TEST_ASSERT_NOT_EQUAL(0, b->sm_current);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_known_values_from_old_firmware(void)
|
||||||
|
{
|
||||||
|
const nl_board_t *evk = nl_board_find("evk");
|
||||||
|
TEST_ASSERT_EQUAL(NL_DRV_PWM, evk->driver);
|
||||||
|
TEST_ASSERT_EQUAL_UINT32(5000, evk->pwm_freq_hz);
|
||||||
|
TEST_ASSERT_EQUAL_INT8(0, evk->pwm[NL_CH_R].pwm_ch);
|
||||||
|
TEST_ASSERT_EQUAL_UINT8(NL_PB(18), evk->pwm[NL_CH_R].pin);
|
||||||
|
TEST_ASSERT_TRUE(evk->pwm[NL_CH_R].active_low);
|
||||||
|
|
||||||
|
const nl_board_t *e27 = nl_board_find("e27_rgb");
|
||||||
|
TEST_ASSERT_EQUAL(NL_DRV_SM2135EH, e27->driver);
|
||||||
|
TEST_ASSERT_EQUAL_UINT8(NL_PB(13), e27->sm_clk_pin);
|
||||||
|
TEST_ASSERT_EQUAL_UINT8(NL_PB(8), e27->sm_dat_pin);
|
||||||
|
TEST_ASSERT_EQUAL_HEX8(0x17, e27->sm_current);
|
||||||
|
TEST_ASSERT_EQUAL_HEX8(0x73, nl_board_find("e14_rgb")->sm_current);
|
||||||
|
TEST_ASSERT_EQUAL_HEX8(0x63, nl_board_find("gu10_rgb")->sm_current);
|
||||||
|
|
||||||
|
const nl_board_t *e27cw = nl_board_find("e27_cw");
|
||||||
|
TEST_ASSERT_TRUE(e27cw->pwm[NL_CH_CW].antiphase);
|
||||||
|
TEST_ASSERT_EQUAL_UINT8(NL_PB(13), e27cw->pwm[NL_CH_CW].pin);
|
||||||
|
TEST_ASSERT_EQUAL_UINT32(600, e27cw->pwm_freq_hz);
|
||||||
|
|
||||||
|
const nl_board_t *g95 = nl_board_find("g95_cw");
|
||||||
|
TEST_ASSERT_EQUAL_UINT8(NL_PB(15), g95->pwm[NL_CH_WW].pin);
|
||||||
|
TEST_ASSERT_EQUAL_INT8(3, g95->pwm[NL_CH_WW].pwm_ch);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
UNITY_BEGIN();
|
||||||
|
RUN_TEST(test_all_devices_present);
|
||||||
|
RUN_TEST(test_unknown_is_null);
|
||||||
|
RUN_TEST(test_rgb_flags_and_ct_ranges);
|
||||||
|
RUN_TEST(test_pwm_boards_consistent);
|
||||||
|
RUN_TEST(test_sm_boards_consistent);
|
||||||
|
RUN_TEST(test_known_values_from_old_firmware);
|
||||||
|
return UNITY_END();
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user