Initial commit
This commit is contained in:
		
						commit
						e8b9cd5ace
					
				| 
						 | 
				
			
			@ -0,0 +1,16 @@
 | 
			
		|||
cmake_minimum_required(VERSION 3.20.0)
 | 
			
		||||
# Top-level CMakeLists.txt for the skeleton application.
 | 
			
		||||
#
 | 
			
		||||
# Copyright (c) 2017 Open Source Foundries Limited
 | 
			
		||||
#
 | 
			
		||||
# SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
#
 | 
			
		||||
# This provides a basic application structure suitable for communication using
 | 
			
		||||
# mcumgr.  It can be used as a starting point for new applications.
 | 
			
		||||
 | 
			
		||||
# Standard Zephyr application boilerplate.
 | 
			
		||||
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
 | 
			
		||||
project(tuxpir)
 | 
			
		||||
 | 
			
		||||
FILE(GLOB app_sources src/*.c*)
 | 
			
		||||
target_sources(app PRIVATE ${app_sources})
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,11 @@
 | 
			
		|||
# Use minimal logging mode and disable info/debug logging to reduce flash space
 | 
			
		||||
#CONFIG_LOG_MODE_MINIMAL=y
 | 
			
		||||
#CONFIG_LOG_MAX_LEVEL=2
 | 
			
		||||
#CONFIG_LOG_DEFAULT_LEVEL=2
 | 
			
		||||
 | 
			
		||||
# Disable RTT support
 | 
			
		||||
#CONFIG_USE_SEGGER_RTT=n
 | 
			
		||||
 | 
			
		||||
# Disable Bluetooth PHY update support
 | 
			
		||||
CONFIG_BT_USER_PHY_UPDATE=n
 | 
			
		||||
CONFIG_BT_PHY_UPDATE=n
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,6 @@
 | 
			
		|||
/ {
 | 
			
		||||
   zephyr,user {
 | 
			
		||||
      io-channels = <&adc 2>;
 | 
			
		||||
   };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,105 @@
 | 
			
		|||
CONFIG_ADC=y
 | 
			
		||||
 | 
			
		||||
# Enable MCUmgr and dependencies.
 | 
			
		||||
CONFIG_NET_BUF=y
 | 
			
		||||
CONFIG_ZCBOR=y
 | 
			
		||||
CONFIG_CRC=y
 | 
			
		||||
CONFIG_MCUMGR=y
 | 
			
		||||
CONFIG_STREAM_FLASH=y
 | 
			
		||||
CONFIG_FLASH_MAP=y
 | 
			
		||||
 | 
			
		||||
CONFIG_MCUBOOT_SIGNATURE_KEY_FILE="/home/nignux/Zephyr-dev/tuxpir/mykey.pem"
 | 
			
		||||
 | 
			
		||||
# Some command handlers require a large stack.
 | 
			
		||||
CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2304
 | 
			
		||||
CONFIG_MAIN_STACK_SIZE=2048
 | 
			
		||||
 | 
			
		||||
# Ensure an MCUboot-compatible binary is generated.
 | 
			
		||||
CONFIG_BOOTLOADER_MCUBOOT=y
 | 
			
		||||
 | 
			
		||||
# Enable flash operations.
 | 
			
		||||
CONFIG_FLASH=y
 | 
			
		||||
 | 
			
		||||
# Required by the `taskstat` command.
 | 
			
		||||
CONFIG_THREAD_MONITOR=n
 | 
			
		||||
 | 
			
		||||
# Support for taskstat command
 | 
			
		||||
CONFIG_MCUMGR_GRP_OS_TASKSTAT=n
 | 
			
		||||
 | 
			
		||||
# Enable statistics and statistic names.
 | 
			
		||||
CONFIG_STATS=n
 | 
			
		||||
CONFIG_STATS_NAMES=n
 | 
			
		||||
 | 
			
		||||
# Enable most core commands.
 | 
			
		||||
CONFIG_FLASH=y
 | 
			
		||||
CONFIG_IMG_MANAGER=y
 | 
			
		||||
CONFIG_MCUMGR_GRP_IMG=y
 | 
			
		||||
CONFIG_MCUMGR_GRP_OS=y
 | 
			
		||||
CONFIG_MCUMGR_GRP_STAT=n
 | 
			
		||||
 | 
			
		||||
# Enable logging
 | 
			
		||||
CONFIG_LOG=y
 | 
			
		||||
CONFIG_MCUBOOT_UTIL_LOG_LEVEL_WRN=y
 | 
			
		||||
CONFIG_LOG_DEFAULT_LEVEL=2
 | 
			
		||||
CONFIG_LOG_MAX_LEVEL=3
 | 
			
		||||
CONFIG_LOG_PRINTK=y
 | 
			
		||||
 | 
			
		||||
CONFIG_LOG_BACKEND_BLE=y
 | 
			
		||||
CONFIG_LOG_PROCESS_THREAD_STACK_SIZE=2048
 | 
			
		||||
 | 
			
		||||
#CONFIG_USE_SEGGER_RTT=y
 | 
			
		||||
CONFIG_LOG_BACKEND_RTT=n
 | 
			
		||||
CONFIG_UART_CONSOLE=n
 | 
			
		||||
#CONFIG_RTT_CONSOLE=y
 | 
			
		||||
CONFIG_STDOUT_CONSOLE=n
 | 
			
		||||
 | 
			
		||||
# Disable debug logging
 | 
			
		||||
CONFIG_BT=y
 | 
			
		||||
CONFIG_BT_PERIPHERAL=y
 | 
			
		||||
CONFIG_BT_DEVICE_NAME="TuxPIR"
 | 
			
		||||
 | 
			
		||||
# Allow for large Bluetooth data packets.
 | 
			
		||||
CONFIG_BT_L2CAP_TX_MTU=498
 | 
			
		||||
CONFIG_BT_BUF_ACL_RX_SIZE=502
 | 
			
		||||
CONFIG_BT_BUF_ACL_TX_SIZE=502
 | 
			
		||||
CONFIG_BT_CTLR_DATA_LENGTH_MAX=251
 | 
			
		||||
 | 
			
		||||
# Enable the Bluetooth mcumgr transport (unauthenticated).
 | 
			
		||||
CONFIG_MCUMGR_TRANSPORT_BT=y
 | 
			
		||||
CONFIG_MCUMGR_TRANSPORT_BT_AUTHEN=n
 | 
			
		||||
CONFIG_MCUMGR_TRANSPORT_BT_CONN_PARAM_CONTROL=y
 | 
			
		||||
 | 
			
		||||
# Enable the Shell mcumgr transport.
 | 
			
		||||
CONFIG_BASE64=n
 | 
			
		||||
CONFIG_CRC=n
 | 
			
		||||
CONFIG_SHELL=n
 | 
			
		||||
CONFIG_SHELL_BACKEND_SERIAL=n
 | 
			
		||||
CONFIG_MCUMGR_TRANSPORT_SHELL=n
 | 
			
		||||
 | 
			
		||||
# Enable the mcumgr Packet Reassembly feature over Bluetooth and its configuration dependencies.
 | 
			
		||||
# MCUmgr buffer size is optimized to fit one SMP packet divided into five Bluetooth Write Commands,
 | 
			
		||||
# transmitted with the maximum possible MTU value: 498 bytes.
 | 
			
		||||
CONFIG_MCUMGR_TRANSPORT_BT_REASSEMBLY=y
 | 
			
		||||
CONFIG_MCUMGR_TRANSPORT_NETBUF_SIZE=2475
 | 
			
		||||
CONFIG_MCUMGR_GRP_OS_MCUMGR_PARAMS=y
 | 
			
		||||
CONFIG_MCUMGR_TRANSPORT_WORKQUEUE_STACK_SIZE=4608
 | 
			
		||||
 | 
			
		||||
# Enable the LittleFS file system.
 | 
			
		||||
CONFIG_FILE_SYSTEM=n
 | 
			
		||||
CONFIG_FILE_SYSTEM_LITTLEFS=n
 | 
			
		||||
 | 
			
		||||
# Enable file system commands
 | 
			
		||||
CONFIG_MCUMGR_GRP_FS=n
 | 
			
		||||
 | 
			
		||||
# Enable the storage erase command.
 | 
			
		||||
CONFIG_MCUMGR_GRP_ZBASIC=n
 | 
			
		||||
CONFIG_MCUMGR_GRP_ZBASIC_STORAGE_ERASE=n
 | 
			
		||||
 | 
			
		||||
# Disable Bluetooth ping support
 | 
			
		||||
CONFIG_BT_CTLR_LE_PING=n
 | 
			
		||||
 | 
			
		||||
# Disable shell commands that are not needed
 | 
			
		||||
CONFIG_CLOCK_CONTROL_NRF_SHELL=n
 | 
			
		||||
CONFIG_DEVICE_SHELL=n
 | 
			
		||||
CONFIG_DEVMEM_SHELL=n
 | 
			
		||||
CONFIG_FLASH_SHELL=n
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,154 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (c) 2018-2019 Peter Bigot Consulting, LLC
 | 
			
		||||
 * Copyright (c) 2019-2020 Nordic Semiconductor ASA
 | 
			
		||||
 *
 | 
			
		||||
 * SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <math.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
 | 
			
		||||
#include <zephyr/kernel.h>
 | 
			
		||||
#include <zephyr/init.h>
 | 
			
		||||
#include <zephyr/drivers/gpio.h>
 | 
			
		||||
#include <zephyr/drivers/adc.h>
 | 
			
		||||
#include <zephyr/drivers/sensor.h>
 | 
			
		||||
#include <zephyr/logging/log.h>
 | 
			
		||||
 | 
			
		||||
#include "battery.h"
 | 
			
		||||
 | 
			
		||||
LOG_MODULE_REGISTER(BATTERYVDD, CONFIG_ADC_LOG_LEVEL);
 | 
			
		||||
 | 
			
		||||
#define ZEPHYR_USER DT_PATH(zephyr_user)
 | 
			
		||||
 | 
			
		||||
/* Other boards may use dividers that only reduce battery voltage to
 | 
			
		||||
 * the maximum supported by the hardware (3.6 V)
 | 
			
		||||
 */
 | 
			
		||||
#define BATTERY_ADC_GAIN ADC_GAIN_1_6
 | 
			
		||||
 | 
			
		||||
struct io_channel_config {
 | 
			
		||||
	uint8_t channel;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct divider_config {
 | 
			
		||||
	struct io_channel_config io_channel;
 | 
			
		||||
	struct gpio_dt_spec power_gpios;
 | 
			
		||||
	/* output_ohm is used as a flag value: if it is nonzero then
 | 
			
		||||
	 * the battery is measured through a voltage divider;
 | 
			
		||||
	 * otherwise it is assumed to be directly connected to Vdd.
 | 
			
		||||
	 */
 | 
			
		||||
	uint32_t output_ohm;
 | 
			
		||||
	uint32_t full_ohm;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static const struct divider_config dividervdd_config = {
 | 
			
		||||
	.io_channel = {
 | 
			
		||||
		DT_IO_CHANNELS_INPUT(ZEPHYR_USER),
 | 
			
		||||
	},
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct divider_data {
 | 
			
		||||
	const struct device *adc;
 | 
			
		||||
	struct adc_channel_cfg adc_cfg;
 | 
			
		||||
	struct adc_sequence adc_seq;
 | 
			
		||||
	int16_t raw;
 | 
			
		||||
};
 | 
			
		||||
static struct divider_data dividervdd_data = {
 | 
			
		||||
	.adc = DEVICE_DT_GET(DT_IO_CHANNELS_CTLR(ZEPHYR_USER)),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static int dividervdd_setup(void)
 | 
			
		||||
{
 | 
			
		||||
	const struct divider_config *cfg = ÷rvdd_config;
 | 
			
		||||
	const struct io_channel_config *iocp = &cfg->io_channel;
 | 
			
		||||
	const struct gpio_dt_spec *gcp = &cfg->power_gpios;
 | 
			
		||||
	struct divider_data *ddp = ÷rvdd_data;
 | 
			
		||||
	struct adc_sequence *asp = &ddp->adc_seq;
 | 
			
		||||
	struct adc_channel_cfg *accp = &ddp->adc_cfg;
 | 
			
		||||
	int rc;
 | 
			
		||||
 | 
			
		||||
	if (!device_is_ready(ddp->adc)) {
 | 
			
		||||
		LOG_ERR("ADC device is not ready %s", ddp->adc->name);
 | 
			
		||||
		return -ENOENT;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (gcp->port) {
 | 
			
		||||
		if (!device_is_ready(gcp->port)) {
 | 
			
		||||
			LOG_ERR("%s: device not ready", gcp->port->name);
 | 
			
		||||
			return -ENOENT;
 | 
			
		||||
		}
 | 
			
		||||
		rc = gpio_pin_configure_dt(gcp, GPIO_OUTPUT_INACTIVE);
 | 
			
		||||
		if (rc != 0) {
 | 
			
		||||
			LOG_ERR("Failed to control feed %s.%u: %d",
 | 
			
		||||
				gcp->port->name, gcp->pin, rc);
 | 
			
		||||
			return rc;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	*asp = (struct adc_sequence){
 | 
			
		||||
		.channels = BIT(0),
 | 
			
		||||
		.buffer = &ddp->raw,
 | 
			
		||||
		.buffer_size = sizeof(ddp->raw),
 | 
			
		||||
		.oversampling = 4,
 | 
			
		||||
		.calibrate = true,
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
#ifdef CONFIG_ADC_NRFX_SAADC
 | 
			
		||||
	*accp = (struct adc_channel_cfg){
 | 
			
		||||
		.gain = BATTERY_ADC_GAIN,
 | 
			
		||||
		.reference = ADC_REF_INTERNAL,
 | 
			
		||||
		.acquisition_time = ADC_ACQ_TIME(ADC_ACQ_TIME_MICROSECONDS, 40),
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	accp->input_positive = SAADC_CH_PSELP_PSELP_VDD;
 | 
			
		||||
 | 
			
		||||
	asp->resolution = 14;
 | 
			
		||||
#else /* CONFIG_ADC_var */
 | 
			
		||||
#error Unsupported ADC
 | 
			
		||||
#endif /* CONFIG_ADC_var */
 | 
			
		||||
 | 
			
		||||
	rc = adc_channel_setup(ddp->adc, accp);
 | 
			
		||||
	LOG_INF("Setup VDD AIN%u got %d", iocp->channel, rc);
 | 
			
		||||
 | 
			
		||||
	return rc;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool battery_ok;
 | 
			
		||||
 | 
			
		||||
int batteryvdd_setup()
 | 
			
		||||
{
 | 
			
		||||
	int rc = dividervdd_setup();
 | 
			
		||||
 | 
			
		||||
	battery_ok = (rc == 0);
 | 
			
		||||
	LOG_INF("Battery VDD setup: %d %d", rc, battery_ok);
 | 
			
		||||
	return rc;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//SYS_INIT(batteryvdd_setup, APPLICATION, CONFIG_APPLICATION_INIT_PRIORITY);
 | 
			
		||||
 | 
			
		||||
int16_t batteryvdd_sample(void)
 | 
			
		||||
{
 | 
			
		||||
	int16_t rc = -ENOENT;
 | 
			
		||||
 | 
			
		||||
	if (battery_ok) {
 | 
			
		||||
		struct divider_data *ddp = ÷rvdd_data;
 | 
			
		||||
		//const struct divider_config *dcp = ÷rvdd_config;
 | 
			
		||||
		struct adc_sequence *sp = &ddp->adc_seq;
 | 
			
		||||
 | 
			
		||||
		rc = adc_read(ddp->adc, sp);
 | 
			
		||||
		sp->calibrate = false;
 | 
			
		||||
		if (rc == 0) {
 | 
			
		||||
			int32_t val = ddp->raw;
 | 
			
		||||
 | 
			
		||||
			adc_raw_to_millivolts(adc_ref_internal(ddp->adc),
 | 
			
		||||
					      ddp->adc_cfg.gain,
 | 
			
		||||
					      sp->resolution,
 | 
			
		||||
					      &val);
 | 
			
		||||
				rc = val;
 | 
			
		||||
				LOG_INF("raw %u ~ %u mV", ddp->raw, val);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return rc;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,56 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (c) 2018-2019 Peter Bigot Consulting, LLC
 | 
			
		||||
 *
 | 
			
		||||
 * SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef APPLICATION_BATTERY_H_
 | 
			
		||||
#define APPLICATION_BATTERY_H_
 | 
			
		||||
 | 
			
		||||
/** Enable or disable measurement of the battery voltage.
 | 
			
		||||
 *
 | 
			
		||||
 * @param enable true to enable, false to disable
 | 
			
		||||
 *
 | 
			
		||||
 * @return zero on success, or a negative error code.
 | 
			
		||||
 */
 | 
			
		||||
int battery_measure_enable(bool enable);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int batteryvdd_setup();
 | 
			
		||||
 | 
			
		||||
/** Measure the battery voltage.
 | 
			
		||||
 *
 | 
			
		||||
 * @return the battery voltage in millivolts, or a negative error
 | 
			
		||||
 * code.
 | 
			
		||||
 */
 | 
			
		||||
int16_t batteryvdd_sample(void);
 | 
			
		||||
 | 
			
		||||
/** A point in a battery discharge curve sequence.
 | 
			
		||||
 *
 | 
			
		||||
 * A discharge curve is defined as a sequence of these points, where
 | 
			
		||||
 * the first point has #lvl_pptt set to 10000 and the last point has
 | 
			
		||||
 * #lvl_pptt set to zero.  Both #lvl_pptt and #lvl_mV should be
 | 
			
		||||
 * monotonic decreasing within the sequence.
 | 
			
		||||
 */
 | 
			
		||||
struct battery_level_point {
 | 
			
		||||
	/** Remaining life at #lvl_mV. */
 | 
			
		||||
	uint16_t lvl_pptt;
 | 
			
		||||
 | 
			
		||||
	/** Battery voltage at #lvl_pptt remaining life. */
 | 
			
		||||
	uint16_t lvl_mV;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/** Calculate the estimated battery level based on a measured voltage.
 | 
			
		||||
 *
 | 
			
		||||
 * @param batt_mV a measured battery voltage level.
 | 
			
		||||
 *
 | 
			
		||||
 * @param curve the discharge curve for the type of battery installed
 | 
			
		||||
 * on the system.
 | 
			
		||||
 *
 | 
			
		||||
 * @return the estimated remaining capacity in parts per ten
 | 
			
		||||
 * thousand.
 | 
			
		||||
 */
 | 
			
		||||
uint16_t battery_level_pptt(uint16_t batt_mV,
 | 
			
		||||
				const struct battery_level_point *curve);
 | 
			
		||||
 | 
			
		||||
#endif /* APPLICATION_BATTERY_H_ */
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,229 @@
 | 
			
		|||
/* main.c - Application main entry point */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2015-2016 Intel Corporation
 | 
			
		||||
 *
 | 
			
		||||
 * SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <sys/errno.h>
 | 
			
		||||
#include <zephyr/types.h>
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <zephyr/sys/printk.h>
 | 
			
		||||
#include <zephyr/sys/byteorder.h>
 | 
			
		||||
#include <zephyr/kernel.h>
 | 
			
		||||
 | 
			
		||||
#include <zephyr/bluetooth/bluetooth.h>
 | 
			
		||||
#include <zephyr/bluetooth/hci.h>
 | 
			
		||||
#include <zephyr/bluetooth/conn.h>
 | 
			
		||||
#include <zephyr/bluetooth/uuid.h>
 | 
			
		||||
#include <zephyr/bluetooth/gatt.h>
 | 
			
		||||
#include <zephyr/bluetooth/services/nus.h>
 | 
			
		||||
 | 
			
		||||
#include <zephyr/device.h>
 | 
			
		||||
#include <zephyr/devicetree.h>
 | 
			
		||||
#include <zephyr/drivers/gpio.h>
 | 
			
		||||
 | 
			
		||||
#include <zephyr/logging/log.h>
 | 
			
		||||
LOG_MODULE_REGISTER(main);
 | 
			
		||||
 | 
			
		||||
#include "battery.h"
 | 
			
		||||
 | 
			
		||||
#define GPIO_PORT DT_NODELABEL(gpio0)
 | 
			
		||||
static struct gpio_callback pir_cb_data;
 | 
			
		||||
 | 
			
		||||
bool btconnectable = true;
 | 
			
		||||
 | 
			
		||||
#define STACKSIZE 2048
 | 
			
		||||
#define PRIORITY 7
 | 
			
		||||
 | 
			
		||||
#define SIZE_BTHOME 8
 | 
			
		||||
static uint8_t mfg_bthome_data[SIZE_BTHOME] = { 0xd2, 0xfc, 0x40, 0x0c, 0x00, 0x00, 0x21, 0x00 };
 | 
			
		||||
 | 
			
		||||
     struct bt_data ad[] = {
 | 
			
		||||
        BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)),
 | 
			
		||||
        BT_DATA(BT_DATA_NAME_COMPLETE, CONFIG_BT_DEVICE_NAME, sizeof(CONFIG_BT_DEVICE_NAME) - 1),
 | 
			
		||||
        BT_DATA(BT_DATA_SVC_DATA16, mfg_bthome_data, SIZE_BTHOME),
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
#define BT_UUID_SMP_VAL BT_UUID_128_ENCODE(0x84aa6074, 0x528a, 0x8b86, 0xd34c, 0xb71d1ddc538d)
 | 
			
		||||
 | 
			
		||||
static const struct bt_data sd[] = {
 | 
			
		||||
        BT_DATA_BYTES(BT_DATA_UUID128_ALL,
 | 
			
		||||
                      //BT_UUID_NUS_SRV_VAL,
 | 
			
		||||
                      BT_UUID_SMP_VAL),
 | 
			
		||||
};
 | 
			
		||||
    static void work_publish_adv_handler(struct k_work *work)
 | 
			
		||||
    {
 | 
			
		||||
  btconnectable = false;
 | 
			
		||||
 | 
			
		||||
  bt_le_adv_stop();
 | 
			
		||||
        bt_le_adv_start(BT_LE_ADV_PARAM(BT_LE_ADV_OPT_USE_IDENTITY,BT_GAP_ADV_SLOW_INT_MIN, BT_GAP_ADV_SLOW_INT_MAX, NULL), ad, ARRAY_SIZE(ad), NULL, 0);
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
    K_WORK_DEFINE(work_publish_adv, work_publish_adv_handler);
 | 
			
		||||
 | 
			
		||||
void timer_publish_adv_handler(struct k_timer *stm)
 | 
			
		||||
{
 | 
			
		||||
    k_work_submit(&work_publish_adv);
 | 
			
		||||
                }
 | 
			
		||||
    K_TIMER_DEFINE(timer_publish_adv, timer_publish_adv_handler, NULL);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    void bt_ready(void)
 | 
			
		||||
    {
 | 
			
		||||
        int err;
 | 
			
		||||
 | 
			
		||||
        printk("Bluetooth initialized\n");
 | 
			
		||||
 | 
			
		||||
        /*if (IS_ENABLED(CONFIG_SETTINGS)) {
 | 
			
		||||
          settings_load();
 | 
			
		||||
          }*/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//        err = bt_le_adv_start(BT_LE_ADV_PARAM(BT_LE_ADV_OPT_USE_IDENTITY | BT_LE_ADV_OPT_USE_NAME, BT_GAP_ADV_SLOW_INT_MIN,BT_GAP_ADV_SLOW_INT_MAX, NULL), ad, ARRAY_SIZE(ad), NULL, 0);
 | 
			
		||||
        err = bt_le_adv_start(BT_LE_ADV_PARAM(BT_LE_ADV_OPT_CONNECTABLE,BT_GAP_ADV_SLOW_INT_MIN, BT_GAP_ADV_SLOW_INT_MAX, NULL), ad, ARRAY_SIZE(ad), sd, ARRAY_SIZE(sd));
 | 
			
		||||
        if (err) {
 | 
			
		||||
            printk("Advertising failed to start (err %d)\n", err);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        printk("Advertising successfully started\n");
 | 
			
		||||
 | 
			
		||||
        k_timer_start(&timer_publish_adv, K_SECONDS(60), K_NO_WAIT);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void connected(struct bt_conn *conn, uint8_t err)
 | 
			
		||||
{
 | 
			
		||||
        if (err) {
 | 
			
		||||
                LOG_ERR("Connection failed (err 0x%02x)", err);
 | 
			
		||||
        } else {
 | 
			
		||||
                LOG_WRN("Connected");
 | 
			
		||||
        k_timer_stop(&timer_publish_adv);
 | 
			
		||||
        }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void disconnected(struct bt_conn *conn, uint8_t reason)
 | 
			
		||||
{
 | 
			
		||||
        LOG_WRN("Disconnected (reason 0x%02x)", reason);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
BT_CONN_CB_DEFINE(conn_callbacks) = {
 | 
			
		||||
        .connected = connected,
 | 
			
		||||
        .disconnected = disconnected,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void update_adv()
 | 
			
		||||
{
 | 
			
		||||
  if(btconnectable == true)
 | 
			
		||||
  {
 | 
			
		||||
    bt_le_adv_update_data(ad, ARRAY_SIZE(ad), sd, ARRAY_SIZE(sd));
 | 
			
		||||
  } else {
 | 
			
		||||
    bt_le_adv_update_data(ad, ARRAY_SIZE(ad), NULL, 0);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*void print_heap_info(void) 
 | 
			
		||||
{
 | 
			
		||||
extern struct k_heap _system_heap;
 | 
			
		||||
struct sys_memory_stats stats;
 | 
			
		||||
    sys_heap_runtime_stats_get(&_system_heap.heap, &stats);
 | 
			
		||||
 | 
			
		||||
    printk("\n");
 | 
			
		||||
    printk("INFO: Allocated Heap = %zu\n", stats.allocated_bytes);
 | 
			
		||||
    printk("INFO: Free Heap = %zu\n", stats.free_bytes);
 | 
			
		||||
    printk("INFO: Max Allocated Heap = %zu\n", stats.max_allocated_bytes);
 | 
			
		||||
    printk("\n");
 | 
			
		||||
 | 
			
		||||
    return;
 | 
			
		||||
}*/
 | 
			
		||||
 | 
			
		||||
    static void work_battery_handler(struct k_work *work)
 | 
			
		||||
    {
 | 
			
		||||
        uint16_t batt_mV = (uint16_t) batteryvdd_sample();
 | 
			
		||||
  LOG_INF("Battery %d mV", batt_mV);
 | 
			
		||||
  mfg_bthome_data[4] = (uint8_t) batt_mV;
 | 
			
		||||
  mfg_bthome_data[5] = (uint8_t) (batt_mV >> 8);
 | 
			
		||||
  update_adv();
 | 
			
		||||
    }
 | 
			
		||||
    K_WORK_DEFINE(work_battery, work_battery_handler);
 | 
			
		||||
void timer_battery_handler(struct k_timer *stm)
 | 
			
		||||
{
 | 
			
		||||
  k_work_submit(&work_battery);
 | 
			
		||||
}
 | 
			
		||||
    K_TIMER_DEFINE(timer_battery, timer_battery_handler, NULL);
 | 
			
		||||
 | 
			
		||||
static void work_piroff_handler(struct k_work *work)
 | 
			
		||||
    {
 | 
			
		||||
  //const struct device *dev = DEVICE_DT_GET(GPIO_PORT);
 | 
			
		||||
  //uint8_t state = (uint8_t) gpio_pin_get(dev, 5);
 | 
			
		||||
  //LOG_INF("PIR changed to %d", state);
 | 
			
		||||
  LOG_INF("Reset motion");
 | 
			
		||||
  mfg_bthome_data[7] = 0;
 | 
			
		||||
  update_adv();
 | 
			
		||||
    }
 | 
			
		||||
    K_WORK_DEFINE(work_piroff, work_piroff_handler);
 | 
			
		||||
 | 
			
		||||
void timer_pir_handler(struct k_timer *stm)
 | 
			
		||||
{
 | 
			
		||||
  k_work_submit(&work_piroff);
 | 
			
		||||
}
 | 
			
		||||
    K_TIMER_DEFINE(timer_pir, timer_pir_handler, NULL);
 | 
			
		||||
 | 
			
		||||
static void work_piron_handler(struct k_work *work)
 | 
			
		||||
    {
 | 
			
		||||
  //const struct device *dev = DEVICE_DT_GET(GPIO_PORT);
 | 
			
		||||
  //uint8_t state = (uint8_t) gpio_pin_get(dev, 5);
 | 
			
		||||
  LOG_INF("Motion detected");
 | 
			
		||||
  mfg_bthome_data[7] = 1;
 | 
			
		||||
  update_adv();
 | 
			
		||||
  k_timer_stop(&timer_pir);
 | 
			
		||||
  k_timer_start(&timer_pir, K_SECONDS(60), K_NO_WAIT);
 | 
			
		||||
    }
 | 
			
		||||
    K_WORK_DEFINE(work_piron, work_piron_handler);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void pir_changed(const struct device *dev, struct gpio_callback *cb,
 | 
			
		||||
                    uint32_t pins)
 | 
			
		||||
{
 | 
			
		||||
  k_work_submit(&work_piron);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void init_gpio_pir()
 | 
			
		||||
{
 | 
			
		||||
  const struct device *dev = DEVICE_DT_GET(GPIO_PORT);
 | 
			
		||||
  gpio_pin_configure(dev, 5, GPIO_INPUT);
 | 
			
		||||
  gpio_pin_interrupt_configure(dev, 5, GPIO_INT_EDGE_RISING);
 | 
			
		||||
  LOG_INF("PIR starting state %d", gpio_pin_get(dev, 5));
 | 
			
		||||
  gpio_init_callback(&pir_cb_data, pir_changed, BIT(5));
 | 
			
		||||
  gpio_add_callback(dev, &pir_cb_data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 int main() 
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
 // k_msleep(250);
 | 
			
		||||
// k_work_submit(&work_battery);
 | 
			
		||||
//  k_timer_start(&timer_battery, K_SECONDS(3600), K_SECONDS(3600));
 | 
			
		||||
 | 
			
		||||
 int err = bt_enable(NULL);
 | 
			
		||||
        if (err) {
 | 
			
		||||
                LOG_ERR("Bluetooth init failed (err %d)", err);
 | 
			
		||||
                return -1;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
  bt_ready();
 | 
			
		||||
 | 
			
		||||
  init_gpio_pir();
 | 
			
		||||
 | 
			
		||||
        batteryvdd_setup();
 | 
			
		||||
 | 
			
		||||
 k_work_submit(&work_battery);
 | 
			
		||||
  k_timer_start(&timer_battery, K_SECONDS(3600), K_SECONDS(3600));
 | 
			
		||||
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
		Loading…
	
		Reference in New Issue