Files
TencentOS-tiny/examples/nimble_mesh_models_example_2/main.c
daishengdong b2983383bb add nimble mesh example
need meshctl installed on raspberrypi. nimble offical samples have a lot of pit ...
2019-11-28 11:12:16 +08:00

366 lines
8.0 KiB
C

/*
* 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.
*/
/* Bluetooth: Mesh Generic OnOff, Generic Level, Lighting & Vendor Models
*
* Copyright (c) 2018 Vikrant More
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "console/console.h"
#include "mesh/mesh.h"
#include "app_gpio.h"
#include "storage.h"
#include "ble_mesh.h"
#include "device_composition.h"
#include "no_transition_work_handler.h"
#include "publisher.h"
#include "state_binding.h"
#include "transition.h"
static bool reset;
///////////////////////
// stub-s
/*
* The "pull" of the gpio. This is either an input or an output.
*/
enum hal_gpio_pull {
/** Pull-up/down not enabled */
HAL_GPIO_PULL_NONE = 0,
/** Pull-up enabled */
HAL_GPIO_PULL_UP = 1,
/** Pull-down enabled */
HAL_GPIO_PULL_DOWN = 2
};
typedef enum hal_gpio_pull hal_gpio_pull_t;
/*
* IRQ trigger type.
*/
enum hal_gpio_irq_trigger {
HAL_GPIO_TRIG_NONE = 0,
/** IRQ occurs on rising edge */
HAL_GPIO_TRIG_RISING = 1,
/** IRQ occurs on falling edge */
HAL_GPIO_TRIG_FALLING = 2,
/** IRQ occurs on either edge */
HAL_GPIO_TRIG_BOTH = 3,
/** IRQ occurs when line is low */
HAL_GPIO_TRIG_LOW = 4,
/** IRQ occurs when line is high */
HAL_GPIO_TRIG_HIGH = 5
};
typedef enum hal_gpio_irq_trigger hal_gpio_irq_trig_t;
/* Function proto for GPIO irq handler functions */
typedef void (*hal_gpio_irq_handler_t)(void *arg);
int hal_gpio_irq_init(int pin, hal_gpio_irq_handler_t handler, void *arg,
hal_gpio_irq_trig_t trig, hal_gpio_pull_t pull)
{
// printf("gpio irq init\n");
return 0;
}
void hal_gpio_irq_enable(int pin)
{
// printf("gpio irq enable\n");
}
void hal_gpio_init_out(int led, int s)
{
// printf("gpio init out\n");
}
void hal_gpio_write(int led, int s)
{
// printf("led[%d]: %s\n", s == 0 ? "OFF" : "ON");
}
int hal_gpio_read(int pin)
{
}
int __atomic_load_4(int *p)
{
return *p;
}
int __atomic_fetch_and_4(int *p, int v)
{
return *p & v;
}
int __atomic_fetch_or_4(int *p, int v)
{
return *p | v;
}
int __atomic_exchange_4(int *p, int v)
{
int old = *p;
*p = v;
return old;
}
void unreachable(void)
{
while (1) {
;
}
}
///////////////////////
static void light_default_var_init(void)
{
gen_def_trans_time_srv_user_data.tt = 0x00;
gen_power_onoff_srv_user_data.onpowerup = STATE_DEFAULT;
light_lightness_srv_user_data.light_range_min = LIGHTNESS_MIN;
light_lightness_srv_user_data.light_range_max = LIGHTNESS_MAX;
light_lightness_srv_user_data.last = LIGHTNESS_MAX;
light_lightness_srv_user_data.def = LIGHTNESS_MAX;
/* Following 2 values are as per specification */
light_ctl_srv_user_data.temp_range_min = TEMP_MIN;
light_ctl_srv_user_data.temp_range_max = TEMP_MAX;
light_ctl_srv_user_data.temp_def = TEMP_MIN;
light_ctl_srv_user_data.lightness_temp_last =
(u32_t) ((LIGHTNESS_MAX << 16) | TEMP_MIN);
}
static void light_default_status_init(void)
{
u16_t lightness;
lightness = (u16_t) (light_ctl_srv_user_data.lightness_temp_last >> 16);
if (lightness) {
gen_onoff_srv_root_user_data.onoff = STATE_ON;
} else {
gen_onoff_srv_root_user_data.onoff = STATE_OFF;
}
/* Retrieve Default Lightness & Temperature Values */
if (light_ctl_srv_user_data.lightness_temp_def) {
light_ctl_srv_user_data.lightness_def = (u16_t)
(light_ctl_srv_user_data.lightness_temp_def >> 16);
light_ctl_srv_user_data.temp_def = (u16_t)
(light_ctl_srv_user_data.lightness_temp_def);
}
light_lightness_srv_user_data.def =
light_ctl_srv_user_data.lightness_def;
light_ctl_srv_user_data.temp = light_ctl_srv_user_data.temp_def;
/* Retrieve Range of Lightness & Temperature */
if (light_lightness_srv_user_data.lightness_range) {
light_lightness_srv_user_data.light_range_max = (u16_t)
(light_lightness_srv_user_data.lightness_range >> 16);
light_lightness_srv_user_data.light_range_min = (u16_t)
(light_lightness_srv_user_data.lightness_range);
}
if (light_ctl_srv_user_data.temperature_range) {
light_ctl_srv_user_data.temp_range_max = (u16_t)
(light_ctl_srv_user_data.temperature_range >> 16);
light_ctl_srv_user_data.temp_range_min = (u16_t)
(light_ctl_srv_user_data.temperature_range);
}
switch (gen_power_onoff_srv_user_data.onpowerup) {
case STATE_OFF:
gen_onoff_srv_root_user_data.onoff = STATE_OFF;
state_binding(ONOFF, ONOFF_TEMP);
break;
case STATE_DEFAULT:
gen_onoff_srv_root_user_data.onoff = STATE_ON;
state_binding(ONOFF, ONOFF_TEMP);
break;
case STATE_RESTORE:
light_lightness_srv_user_data.last = (u16_t)
(light_ctl_srv_user_data.lightness_temp_last >> 16);
light_ctl_srv_user_data.temp =
(u16_t) (light_ctl_srv_user_data.lightness_temp_last);
state_binding(ONPOWERUP, ONOFF_TEMP);
break;
}
default_tt = gen_def_trans_time_srv_user_data.tt;
}
void update_light_state(void)
{
u8_t power, color;
power = 100 * ((float) lightness / 65535);
color = 100 * ((float) (temperature + 32768) / 65535);
printk("power-> %d, color-> %d\n", power, color);
if (lightness) {
/* LED1 On */
hal_gpio_write(led_device[0], 0);
} else {
/* LED1 Off */
hal_gpio_write(led_device[0], 1);
}
if (power < 50) {
/* LED3 On */
hal_gpio_write(led_device[2], 0);
} else {
/* LED3 Off */
hal_gpio_write(led_device[2], 1);
}
if (color < 50) {
/* LED4 On */
hal_gpio_write(led_device[3], 0);
} else {
/* LED4 Off */
hal_gpio_write(led_device[3], 1);
}
if (*ptr_counter == 0 || reset == false) {
reset = true;
ble_npl_callout_reset(&no_transition_work, 0);
}
}
static void short_time_multireset_bt_mesh_unprovisioning(void)
{
if (reset_counter >= 4) {
reset_counter = 0;
printk("BT Mesh reset\n");
bt_mesh_reset();
} else {
printk("Reset Counter -> %d\n", reset_counter);
reset_counter++;
}
save_on_flash(RESET_COUNTER);
}
static void reset_counter_timer_handler(struct ble_npl_event *dummy)
{
reset_counter = 0;
save_on_flash(RESET_COUNTER);
printk("Reset Counter set to Zero\n");
}
struct ble_npl_callout reset_counter_timer;
static void init_timers(void)
{
ble_npl_callout_init(&reset_counter_timer, nimble_port_get_dflt_eventq(),
reset_counter_timer_handler, NULL);
ble_npl_callout_reset(&reset_counter_timer,
ble_npl_time_ms_to_ticks32(K_MSEC(7000)));
no_transition_work_init();
}
void bt_initialized(void)
{
light_default_status_init();
update_light_state();
randomize_publishers_TID();
short_time_multireset_bt_mesh_unprovisioning();
}
int ble_boot(void)
{
#ifdef ARCH_sim
mcu_sim_parse_args(argc, argv);
#endif
light_default_var_init();
app_gpio_init();
init_timers();
transition_timers_init();
init_pub();
#if 0 // disable this...
ps_settings_init();
#endif
printk("Initializing...\n");
/* 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;
extern void nimble_port_run(void);
nimble_port_tencentos_tiny_init(nimble_port_run);
return 0;
}
k_task_t ble_boot_task;
k_stack_t ble_boot_stack[512];
int main(void)
{
board_init();
/* Initialize OS */
tos_knl_init();
nimble_port_init();
tos_task_create(&ble_boot_task, "boot", ble_boot, NULL,
4,
ble_boot_stack, sizeof(ble_boot_stack),
0);
tos_knl_start();
}