Hi,
I started from your
Bluetooth Mesh NLC: Lightness Controller/Energy Monitor sample
and I tried to insert a Light CTL Server model in the project.
After a lot of effort now I manage to build and to flash the FW in my nRF52840DK.
By means of another DK with Light CTL Client I can transmit a temp light value to the DK with CTL Server, but soon after receiving the value the system crashes with this error:
<err> os: ***** BUS FAULT *****
[00:01:52.372,619] <err> os: Precise data bus error
[00:01:52.372,619] <err> os: BFAR Address: 0x80b662ba
[00:01:52.372,650] <err> os: Imprecise data bus error
[00:01:52.372,680] <err> os: r0/a1: 0x00000000 r1/a2: 0x00000000 r2/a3: 0x80b662b6
[00:01:52.372,680] <err> os: r3/a4: 0x2000e874 r12/ip: 0x00000000 r14/lr: 0x00063d29
[00:01:52.372,711] <err> os: xpsr: 0x41000000
[00:01:52.372,711] <err> os: s[ 0]: 0x00000000 s[ 1]: 0x00000000 s[ 2]: 0x00007fff s[ 3]: 0x200026e8
[00:01:52.372,741] <err> os: s[ 4]: 0x00000010 s[ 5]: 0x000516ab s[ 6]: 0x00000000 s[ 7]: 0x2000e8e8
[00:01:52.372,772] <err> os: s[ 8]: 0x00000000 s[ 9]: 0x00000000 s[10]: 0x2000ea8c s[11]: 0x00000001
[00:01:52.372,802] <err> os: s[12]: 0x00000082 s[13]: 0x00000000 s[14]: 0x2000e874 s[15]: 0x00000000
[00:01:52.372,802] <err> os: fpscr: 0x2000ea8c
[00:01:52.372,802] <err> os: Faulting instruction address (r15/pc): 0x0005e8a2
[00:01:52.372,863] <err> os: >>> ZEPHYR FATAL ERROR 26: Unknown error on CPU 0
[00:01:52.372,894] <err> os: Current thread: 0x20004f90 (BT RX WQ)
[00:01:52.491,973] <err> os: Halting system
I insert the most important snippets of FW so to show you what I'm talking about.
I hope that you can help me to make CTL server and Light CTRL server to live together.
Thank you in advance
static struct bt_mesh_elem elements[] = {
BT_MESH_ELEM(1,
BT_MESH_MODEL_LIST(
BT_MESH_MODEL_CFG_SRV,
BT_MESH_MODEL_HEALTH_SRV(&health_srv, &health_pub),
BT_MESH_MODEL_LIGHTNESS_SRV(&my_ctx.lightness_srv),
BT_MESH_MODEL_LIGHT_CTL_SRV(&ctl_srv_inst),
BT_MESH_MODEL_LIGHT_TEMP_SRV(&ctl_srv_inst.temp_srv),
BT_MESH_MODEL_SCENE_SRV(&scene_srv),
BT_MESH_MODEL_SENSOR_CLI(&sensor_cli),
BT_MESH_MODEL_DFU_SRV(&dfu_srv)),
BT_MESH_MODEL_NONE),
BT_MESH_ELEM(2,
BT_MESH_MODEL_LIST(
BT_MESH_MODEL_LIGHT_CTRL_SRV(&light_ctrl_srv)),
BT_MESH_MODEL_NONE),
static void light_set(struct bt_mesh_lightness_srv *srv,
struct bt_mesh_msg_ctx *ctx,
const struct bt_mesh_lightness_set *set,
struct bt_mesh_lightness_status *rsp)
{
struct lightness_ctx *l_ctx =
CONTAINER_OF(srv, struct lightness_ctx, lightness_srv);
start_new_light_trans(set, l_ctx);
rsp->current = l_ctx->rem_time ? l_ctx->current_lvl : l_ctx->target_lvl;
rsp->target = l_ctx->target_lvl;
rsp->remaining_time = set->transition ? set->transition->time : 0;
}
static void light_get(struct bt_mesh_lightness_srv *srv,
struct bt_mesh_msg_ctx *ctx,
struct bt_mesh_lightness_status *rsp)
{
struct lightness_ctx *l_ctx =
CONTAINER_OF(srv, struct lightness_ctx, lightness_srv);
rsp->current = bt_mesh_lightness_clamp(&l_ctx->lightness_srv, l_ctx->current_lvl);
rsp->target = l_ctx->target_lvl;
rsp->remaining_time = l_ctx->rem_time;
}
static const struct bt_mesh_lightness_srv_handlers lightness_srv_handlers = {
.light_set = light_set,
.light_get = light_get,
};
static struct lightness_ctx my_ctx = {
.lightness_srv = BT_MESH_LIGHTNESS_SRV_INIT(&lightness_srv_handlers)
};
/**** Snippet per CTL server ****/
static void handle_temp_set(struct bt_mesh_light_temp_srv *srv,
struct bt_mesh_msg_ctx *ctx,
const struct bt_mesh_light_temp_set *set,
struct bt_mesh_light_temp_status *rsp)
{
/* 1. Estrarre i dati dal pacchetto ricevuto */
// set->temp è la temperatura colore in Kelvin (range 800 - 20000)
uint16_t temperatura_kelvin = set->params.temp;
// set->delta_uv è la deviazione dalla linea del corpo nero (solitamente 0)
int16_t delta_uv = set->params.delta_uv;
/* 2. Logica di controllo LED */
printk("HCL Update: Temperatura = %u K, Delta_UV = %d\n",
temperatura_kelvin, delta_uv);
// Qui chiamerai la tua funzione driver per i LED fisici, ad esempio:
// update_led_mixing(temperatura_kelvin, delta_uv);
/* 3. Gestire la risposta (Status) */
/* Se rsp non è NULL, lo stack invierà una risposta al client.
* Dobbiamo riempire i campi con lo stato attuale dopo il cambiamento. */
if (rsp) {
rsp->current.temp = temperatura_kelvin;
rsp->current.delta_uv = delta_uv;
/* Se non c'è una transizione in corso (fade), target e current sono uguali */
rsp->target.temp = temperatura_kelvin;
rsp->target.delta_uv = delta_uv;
rsp->remaining_time = 0;
}
}
static void handle_lightness_set(struct bt_mesh_lightness_srv *srv,
struct bt_mesh_msg_ctx *ctx,
const struct bt_mesh_lightness_set *set,
struct bt_mesh_lightness_status *rsp)
{
uint16_t lightness = set->lvl; // Range 0 - 65535
// Aggiorna i tuoi LED
// update_led_brightness(lightness);
if (rsp) {
rsp->current = lightness;
rsp->target = lightness;
rsp->remaining_time = 0;
}
}
// Callback per la Luminosità (Elemento 1)
static const struct bt_mesh_lightness_srv_handlers lightness_handlers = {
.light_set = handle_lightness_set,
};
// Callback per la Temperatura (Elemento 2)
static const struct bt_mesh_light_temp_srv_handlers temp_handlers = {
.set = handle_temp_set,
};
/* 3. Inizializza il CTL SRV */
static struct bt_mesh_light_ctl_srv ctl_srv_inst = {
.lightness_srv = {
.handlers = &lightness_handlers,
},
.temp_srv = {
.handlers = &temp_handlers,
},
};
/**** End Snippet per CTL server ****/
static struct bt_mesh_light_ctrl_srv light_ctrl_srv =
BT_MESH_LIGHT_CTRL_SRV_INIT(&my_ctx.lightness_srv);