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