From bdc10744fb338ae197692713a0b48a7ccc36f566 Mon Sep 17 00:00:00 2001 From: JF Date: Sun, 26 Apr 2020 10:25:59 +0200 Subject: Add Nimble in libs directory --- src/libs/mynewt-nimble/apps/blemesh_light/pkg.yml | 37 ++++ .../apps/blemesh_light/src/light_model.c | 242 +++++++++++++++++++++ .../apps/blemesh_light/src/light_model.h | 37 ++++ .../mynewt-nimble/apps/blemesh_light/src/main.c | 113 ++++++++++ .../mynewt-nimble/apps/blemesh_light/src/ws2812.c | 138 ++++++++++++ .../mynewt-nimble/apps/blemesh_light/src/ws2812.h | 42 ++++ .../mynewt-nimble/apps/blemesh_light/syscfg.yml | 63 ++++++ 7 files changed, 672 insertions(+) create mode 100644 src/libs/mynewt-nimble/apps/blemesh_light/pkg.yml create mode 100644 src/libs/mynewt-nimble/apps/blemesh_light/src/light_model.c create mode 100644 src/libs/mynewt-nimble/apps/blemesh_light/src/light_model.h create mode 100644 src/libs/mynewt-nimble/apps/blemesh_light/src/main.c create mode 100644 src/libs/mynewt-nimble/apps/blemesh_light/src/ws2812.c create mode 100644 src/libs/mynewt-nimble/apps/blemesh_light/src/ws2812.h create mode 100644 src/libs/mynewt-nimble/apps/blemesh_light/syscfg.yml (limited to 'src/libs/mynewt-nimble/apps/blemesh_light') diff --git a/src/libs/mynewt-nimble/apps/blemesh_light/pkg.yml b/src/libs/mynewt-nimble/apps/blemesh_light/pkg.yml new file mode 100644 index 00000000..9694f18b --- /dev/null +++ b/src/libs/mynewt-nimble/apps/blemesh_light/pkg.yml @@ -0,0 +1,37 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +pkg.name: apps/blemesh_light +pkg.type: app +pkg.description: Sample application for BLE Mesh node with Light model +pkg.author: "MichaƂ Narajowski " +pkg.homepage: "http://mynewt.apache.org/" +pkg.keywords: + +pkg.deps: + - "@apache-mynewt-core/kernel/os" + - "@apache-mynewt-core/sys/console/full" + - "@apache-mynewt-core/sys/log/full" + - "@apache-mynewt-core/sys/log/modlog" + - "@apache-mynewt-core/sys/stats/full" + - "@apache-mynewt-core/sys/shell" + - nimble/controller + - nimble/host + - nimble/host/services/gap + - nimble/host/services/gatt + - nimble/host/store/ram + - nimble/transport/ram diff --git a/src/libs/mynewt-nimble/apps/blemesh_light/src/light_model.c b/src/libs/mynewt-nimble/apps/blemesh_light/src/light_model.c new file mode 100644 index 00000000..8b00e2c0 --- /dev/null +++ b/src/libs/mynewt-nimble/apps/blemesh_light/src/light_model.c @@ -0,0 +1,242 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include "syscfg/syscfg.h" + +#if MYNEWT_VAL(BLE_MESH_SHELL_MODELS) + +#include "mesh/mesh.h" +#include "bsp.h" +#include "pwm/pwm.h" +#include "light_model.h" +#include "ws2812.h" + +#if (!MYNEWT_VAL(USE_NEOPIXEL)) +#if MYNEWT_VAL(PWM_0) +struct pwm_dev *pwm0; +#endif +#if MYNEWT_VAL(PWM_1) +struct pwm_dev *pwm1; +#endif +#if MYNEWT_VAL(PWM_2) +struct pwm_dev *pwm2; +#endif +#if MYNEWT_VAL(PWM_3) +struct pwm_dev *pwm3; +#endif + +static uint16_t top_val; +#endif + +#if (MYNEWT_VAL(USE_NEOPIXEL)) +static uint32_t neopixel[WS2812_NUM_LED]; +#endif + +static u8_t gen_onoff_state; +static s16_t gen_level_state; + +static void light_set_lightness(u8_t percentage) +{ +#if (!MYNEWT_VAL(USE_NEOPIXEL)) + int rc; + + uint16_t pwm_val = (uint16_t) (percentage * top_val / 100); + +#if MYNEWT_VAL(PWM_0) + rc = pwm_set_duty_cycle(pwm0, 0, pwm_val); + assert(rc == 0); +#endif +#if MYNEWT_VAL(PWM_1) + rc = pwm_set_duty_cycle(pwm1, 0, pwm_val); + assert(rc == 0); +#endif +#if MYNEWT_VAL(PWM_2) + rc = pwm_set_duty_cycle(pwm2, 0, pwm_val); + assert(rc == 0); +#endif +#if MYNEWT_VAL(PWM_3) + rc = pwm_set_duty_cycle(pwm3, 0, pwm_val); + assert(rc == 0); +#endif +#else + int i; + u32_t lightness; + u8_t max_lightness = 0x1f; + + lightness = (u8_t) (percentage * max_lightness / 100); + + for (i = 0; i < WS2812_NUM_LED; i++) { + neopixel[i] = (lightness | lightness << 8 | lightness << 16); + } + ws2812_write(neopixel); +#endif +} + +static void update_light_state(void) +{ + u16_t level = (u16_t)gen_level_state; + int percent = 100 * level / 0xffff; + + if (gen_onoff_state == 0) { + percent = 0; + } + light_set_lightness((uint8_t) percent); +} + +int light_model_gen_onoff_get(struct bt_mesh_model *model, u8_t *state) +{ + *state = gen_onoff_state; + return 0; +} + +int light_model_gen_onoff_set(struct bt_mesh_model *model, u8_t state) +{ + gen_onoff_state = state; + update_light_state(); + return 0; +} + +int light_model_gen_level_get(struct bt_mesh_model *model, s16_t *level) +{ + *level = gen_level_state; + return 0; +} + +int light_model_gen_level_set(struct bt_mesh_model *model, s16_t level) +{ + gen_level_state = level; + if ((u16_t)gen_level_state > 0x0000) { + gen_onoff_state = 1; + } + if ((u16_t)gen_level_state == 0x0000) { + gen_onoff_state = 0; + } + update_light_state(); + return 0; +} + +int light_model_light_lightness_get(struct bt_mesh_model *model, s16_t *lightness) +{ + return light_model_gen_level_get(model, lightness); +} + +int light_model_light_lightness_set(struct bt_mesh_model *model, s16_t lightness) +{ + return light_model_gen_level_set(model, lightness); +} + +#if (!MYNEWT_VAL(USE_NEOPIXEL)) +struct pwm_dev_cfg dev_conf = { + .n_cycles = 0, + .int_prio = 3, +}; + +#if MYNEWT_VAL(PWM_0) +static struct pwm_chan_cfg led1_conf = { + .pin = LED_1, + .inverted = true, +}; +#endif + +#if MYNEWT_VAL(PWM_1) +static struct pwm_chan_cfg led2_conf = { + .pin = LED_2, + .inverted = true, +}; +#endif + +#if MYNEWT_VAL(PWM_2) +static struct pwm_chan_cfg led3_conf = { + .pin = LED_3, + .inverted = true, +}; +#endif +#endif + +#if MYNEWT_VAL(PWM_3) +static struct pwm_chan_cfg led4_conf = { + .pin = LED_4, + .inverted = true, +}; +#endif + +#if (!MYNEWT_VAL(USE_NEOPIXEL)) +void init_pwm_dev(struct pwm_dev **pwm, char *dev_name, struct pwm_chan_cfg *chan_cfg) +{ + int rc = 0; + + *pwm = (struct pwm_dev *) os_dev_open(dev_name, 0, NULL); + assert(pwm); + rc = pwm_configure_device(*pwm, &dev_conf); + assert(rc == 0); + rc = pwm_configure_channel(*pwm, 0, chan_cfg); + assert(rc == 0); + rc = pwm_enable(*pwm); + assert(rc == 0); +} + +int pwm_init(void) +{ + +#if MYNEWT_VAL(PWM_0) + init_pwm_dev(&pwm0, "pwm0", &led1_conf); +#endif + +#if MYNEWT_VAL(PWM_1) + init_pwm_dev(&pwm1, "pwm1", &led2_conf); +#endif + +#if MYNEWT_VAL(PWM_2) + init_pwm_dev(&pwm2, "pwm2", &led3_conf); +#endif + +#if MYNEWT_VAL(PWM_3) + init_pwm_dev(&pwm3, "pwm3", &led4_conf); +#endif + + if (!pwm0) { + return 0; + } + + top_val = (uint16_t) pwm_get_top_value(pwm0); + update_light_state(); + + return 0; +} +#endif +#endif + +int light_model_init(void) +{ +#if MYNEWT_VAL(BLE_MESH_SHELL_MODELS) + int rc; +#if (!MYNEWT_VAL(USE_NEOPIXEL)) + rc = pwm_init(); + assert(rc == 0); +#else + rc = ws2812_init(); + assert(rc == 0); + update_light_state(); +#endif + return rc; +#else + return 0; +#endif +} + diff --git a/src/libs/mynewt-nimble/apps/blemesh_light/src/light_model.h b/src/libs/mynewt-nimble/apps/blemesh_light/src/light_model.h new file mode 100644 index 00000000..7fcdd0c3 --- /dev/null +++ b/src/libs/mynewt-nimble/apps/blemesh_light/src/light_model.h @@ -0,0 +1,37 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + * Copyright (c) 2017 Intel Corporation + * + */ + +#ifndef __BT_MESH_LIGHT_MODEL_H +#define __BT_MESH_LIGHT_MODEL_H + +#include "syscfg/syscfg.h" +#include "mesh/mesh.h" + +int light_model_gen_onoff_get(struct bt_mesh_model *model, u8_t *state); +int light_model_gen_onoff_set(struct bt_mesh_model *model, u8_t state); +int light_model_gen_level_get(struct bt_mesh_model *model, s16_t *level); +int light_model_gen_level_set(struct bt_mesh_model *model, s16_t level); +int light_model_light_lightness_get(struct bt_mesh_model *model, s16_t *lightness); +int light_model_light_lightness_set(struct bt_mesh_model *model, s16_t lightness); +int light_model_init(void); + +#endif diff --git a/src/libs/mynewt-nimble/apps/blemesh_light/src/main.c b/src/libs/mynewt-nimble/apps/blemesh_light/src/main.c new file mode 100644 index 00000000..51d86eb5 --- /dev/null +++ b/src/libs/mynewt-nimble/apps/blemesh_light/src/main.c @@ -0,0 +1,113 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +#include +#include "sysinit/sysinit.h" +#include "os/os.h" +#include "mesh/mesh.h" +#include "console/console.h" +#include "bsp/bsp.h" +#include "shell/shell.h" + +#include "host/ble_hs.h" +#include "mesh/glue.h" +#include "mesh/testing.h" +#include "mesh/model_srv.h" +#include "light_model.h" + + +static void model_bound_cb(u16_t addr, struct bt_mesh_model *model, + u16_t key_idx) +{ + int rc; + + console_printf("Model bound: remote addr 0x%04x key_idx 0x%04x model %p\n", + addr, key_idx, model); + + if (model->id != BT_MESH_MODEL_ID_GEN_LEVEL_SRV) { + return; + } + + /* Hack for demo purposes */ + rc = bt_test_bind_app_key_to_model(model, key_idx, + BT_MESH_MODEL_ID_LIGHT_LIGHTNESS_SRV); + + if (rc) { + console_printf("Failed to bind light lightness srv model to app_key"); + } else { + console_printf("Successfuly bound light lightness srv model to app_key"); + } +} + +static struct bt_test_cb bt_test_cb = { + .mesh_model_bound = model_bound_cb, +}; + +static void +blemesh_on_reset(int reason) +{ + BLE_HS_LOG(ERROR, "Resetting state; reason=%d\n", reason); +} + +static void +blemesh_on_sync(void) +{ + console_printf("Bluetooth initialized\n"); + + shell_register_default_module("mesh"); + + bt_test_cb_register(&bt_test_cb); + + light_model_init(); + bt_mesh_set_gen_onoff_srv_cb(light_model_gen_onoff_get, + light_model_gen_onoff_set); + bt_mesh_set_gen_level_srv_cb(light_model_gen_level_get, + light_model_gen_level_set); + bt_mesh_set_light_lightness_srv_cb(light_model_light_lightness_get, + light_model_light_lightness_set); + + console_printf("Mesh initialized\n"); + + if (IS_ENABLED(CONFIG_SETTINGS)) { + settings_load(); + } + + if (bt_mesh_is_provisioned()) { + printk("Mesh network restored from flash\n"); + } + + /* Hack for demo purposes */ + bt_test_shell_init(); +} + +int +main(void) +{ + /* Initialize OS */ + sysinit(); + + /* Initialize the NimBLE host configuration. */ + ble_hs_cfg.reset_cb = blemesh_on_reset; + ble_hs_cfg.sync_cb = blemesh_on_sync; + ble_hs_cfg.store_status_cb = ble_store_util_status_rr; + + while (1) { + os_eventq_run(os_eventq_dflt_get()); + } + return 0; +} diff --git a/src/libs/mynewt-nimble/apps/blemesh_light/src/ws2812.c b/src/libs/mynewt-nimble/apps/blemesh_light/src/ws2812.c new file mode 100644 index 00000000..f27a182b --- /dev/null +++ b/src/libs/mynewt-nimble/apps/blemesh_light/src/ws2812.c @@ -0,0 +1,138 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include "syscfg/syscfg.h" + +#if (MYNEWT_VAL(USE_NEOPIXEL)) + +#include +#include +#include +#include "sysinit/sysinit.h" +#include "os/os.h" +#include "bsp/bsp.h" +#include "pwm/pwm.h" +#include "nrfx.h" +#include "nrfx_pwm.h" +#include "ws2812.h" + +#define BITS_PER_SEQ (24) +#define BIT0 (0x8000 | 6) +#define BIT1 (0x8000 | 11) + +static const nrfx_pwm_t pwm = NRFX_PWM_INSTANCE(WS2812_PWM); + +static const nrfx_pwm_config_t pwm_config = { + .output_pins = { WS2812_GPIO, NRFX_PWM_PIN_NOT_USED, NRFX_PWM_PIN_NOT_USED, NRFX_PWM_PIN_NOT_USED }, + .irq_priority = 3, + .base_clock = NRF_PWM_CLK_16MHz, + .count_mode = NRF_PWM_MODE_UP, + .top_value = 20, + .load_mode = NRF_PWM_LOAD_COMMON, + .step_mode = NRF_PWM_STEP_AUTO, +}; + +static uint16_t pwm_seq_values[2][BITS_PER_SEQ]; + +static const nrf_pwm_sequence_t pwm_seq[2] = { + { + .values.p_raw = pwm_seq_values[0], + .length = BITS_PER_SEQ, + .repeats = 0, + .end_delay = 0, + }, { + .values.p_raw = pwm_seq_values[1], + .length = BITS_PER_SEQ, + .repeats = 0, + .end_delay = 0, + }, +}; + +static uint32_t led_color[WS2812_NUM_LED]; +static int led_idx; + +static void +load_pixel(void) +{ + uint16_t *seq_values; + uint32_t grb; + int i; + + seq_values = pwm_seq_values[led_idx & 1]; + grb = led_color[led_idx]; + + for (i = 0; i < BITS_PER_SEQ; i++) { + *seq_values = grb & 0x800000 ? BIT1 : BIT0; + grb <<= 1; + seq_values++; + } + + led_idx++; +} + +static void +pwm_handler_func(nrfx_pwm_evt_type_t event_type) +{ + switch (event_type) { + case NRFX_PWM_EVT_END_SEQ0: + case NRFX_PWM_EVT_END_SEQ1: + load_pixel(); + break; + default: + break; + } +} + +int +ws2812_init(void) +{ + nrfx_err_t err; + + err = nrfx_pwm_init(&pwm, &pwm_config, pwm_handler_func); + + return err != NRFX_SUCCESS; +} + +int +ws2812_write(const uint32_t *rgb) +{ + uint32_t grb; + int i; + + for (i = 0; i < WS2812_NUM_LED; i++) { + grb = 0; + grb |= (rgb[i] & 0x00FF00) << 8; + grb |= (rgb[i] & 0xFF0000) >> 8; + grb |= (rgb[i] & 0x0000FF); + + led_color[i] = grb; + } + + led_idx = 0; + + load_pixel(); + load_pixel(); + nrfx_pwm_complex_playback(&pwm, &pwm_seq[0], &pwm_seq[1], WS2812_NUM_LED, + NRFX_PWM_FLAG_SIGNAL_END_SEQ0 | + NRFX_PWM_FLAG_SIGNAL_END_SEQ1 | + NRFX_PWM_FLAG_STOP); + + return 0; +} +#endif diff --git a/src/libs/mynewt-nimble/apps/blemesh_light/src/ws2812.h b/src/libs/mynewt-nimble/apps/blemesh_light/src/ws2812.h new file mode 100644 index 00000000..93b8faf8 --- /dev/null +++ b/src/libs/mynewt-nimble/apps/blemesh_light/src/ws2812.h @@ -0,0 +1,42 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef __WS2812_H__ +#define __WS2812_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define WS2812_PWM 0 +#define WS2812_GPIO 30 +#define WS2812_NUM_LED 32 + +int ws2812_init(void); + +int ws2812_write(const uint32_t *rgb); + +#ifdef __cplusplus +} +#endif + +#endif /* __WS2812_H__ */ diff --git a/src/libs/mynewt-nimble/apps/blemesh_light/syscfg.yml b/src/libs/mynewt-nimble/apps/blemesh_light/syscfg.yml new file mode 100644 index 00000000..82c70dc2 --- /dev/null +++ b/src/libs/mynewt-nimble/apps/blemesh_light/syscfg.yml @@ -0,0 +1,63 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +syscfg.defs: + USE_NEOPIXEL: + value: 0 + +syscfg.vals: + # Enable the shell task. + SHELL_TASK: 1 + + # Set log level to info (disable debug logging). + LOG_LEVEL: 1 + + # Default task settings + OS_MAIN_STACK_SIZE: 768 + + # SMP is not supported in this app, so disable smp-over-shell. + SHELL_MGMT: 0 + + MSYS_1_BLOCK_COUNT: 80 + + BLE_MESH_ADV_BUF_COUNT: 20 + BLE_MESH_TX_SEG_MAX: 6 + + BLE_MESH: 1 + BLE_MESH_SHELL: 1 + BLE_MESH_PROV: 1 + BLE_MESH_PB_ADV: 1 + BLE_MESH_PB_GATT: 1 + BLE_MESH_GATT_PROXY: 1 + BLE_MESH_TESTING: 1 + BLE_MESH_FRIEND: 0 + BLE_MESH_CFG_CLI: 1 + BLE_MESH_HEALTH_CLI: 0 + BLE_MESH_SHELL_MODELS: 1 + BLE_MESH_OOB_OUTPUT_ACTIONS: 0 + BLE_MESH_SETTINGS: 0 + CONFIG_NFFS: 0 + + USE_NEOPIXEL: 0 + +syscfg.vals.BLE_MESH_SHELL_MODELS: + PWM_0: 1 + PWM_1: 1 + PWM_2: 1 + PWM_3: 1 + -- cgit v1.2.3