Merge pull request #242 from megamind4089/feature/ext-power
[RDY] Driver to control the external power output
This commit is contained in:
commit
e1dcf1514f
13 changed files with 255 additions and 12 deletions
|
@ -31,6 +31,7 @@ target_sources(app PRIVATE src/sensors.c)
|
||||||
target_sources_ifdef(CONFIG_ZMK_DISPLAY app PRIVATE src/display.c)
|
target_sources_ifdef(CONFIG_ZMK_DISPLAY app PRIVATE src/display.c)
|
||||||
target_sources(app PRIVATE src/event_manager.c)
|
target_sources(app PRIVATE src/event_manager.c)
|
||||||
target_sources_ifdef(CONFIG_ZMK_BLE app PRIVATE src/ble_unpair_combo.c)
|
target_sources_ifdef(CONFIG_ZMK_BLE app PRIVATE src/ble_unpair_combo.c)
|
||||||
|
target_sources_ifdef(CONFIG_ZMK_EXT_POWER app PRIVATE src/ext_power_generic.c)
|
||||||
target_sources(app PRIVATE src/events/position_state_changed.c)
|
target_sources(app PRIVATE src/events/position_state_changed.c)
|
||||||
target_sources(app PRIVATE src/events/keycode_state_changed.c)
|
target_sources(app PRIVATE src/events/keycode_state_changed.c)
|
||||||
target_sources(app PRIVATE src/events/modifiers_state_changed.c)
|
target_sources(app PRIVATE src/events/modifiers_state_changed.c)
|
||||||
|
|
|
@ -95,6 +95,10 @@ config ZMK_IDLE_SLEEP_TIMEOUT
|
||||||
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
config ZMK_EXT_POWER
|
||||||
|
bool "Enable support to control external power output"
|
||||||
|
default y
|
||||||
|
|
||||||
config ZMK_DISPLAY
|
config ZMK_DISPLAY
|
||||||
bool "ZMK display support"
|
bool "ZMK display support"
|
||||||
default n
|
default n
|
||||||
|
|
|
@ -29,6 +29,11 @@
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ext-power {
|
||||||
|
compatible = "zmk,ext-power-generic";
|
||||||
|
label = "EXT_POWER";
|
||||||
|
control-gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
&gpiote {
|
&gpiote {
|
||||||
|
|
|
@ -26,6 +26,11 @@
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ext-power {
|
||||||
|
compatible = "zmk,ext-power-generic";
|
||||||
|
label = "EXT_POWER";
|
||||||
|
control-gpios = <&gpio1 9 GPIO_ACTIVE_HIGH>;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
&gpio0 {
|
&gpio0 {
|
||||||
|
|
|
@ -26,6 +26,11 @@
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ext-power {
|
||||||
|
compatible = "zmk,ext-power-generic";
|
||||||
|
label = "EXT_POWER";
|
||||||
|
control-gpios = <&gpio1 9 GPIO_ACTIVE_HIGH>;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
&gpio0 {
|
&gpio0 {
|
||||||
|
|
|
@ -26,6 +26,11 @@
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ext-power {
|
||||||
|
compatible = "zmk,ext-power-generic";
|
||||||
|
label = "EXT_POWER";
|
||||||
|
control-gpios = <&gpio1 9 GPIO_ACTIVE_LOW>;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
&gpio0 {
|
&gpio0 {
|
||||||
|
|
|
@ -14,25 +14,14 @@
|
||||||
static int pinmux_nrfmicro_init(struct device *port) {
|
static int pinmux_nrfmicro_init(struct device *port) {
|
||||||
ARG_UNUSED(port);
|
ARG_UNUSED(port);
|
||||||
|
|
||||||
struct device *p1 = device_get_binding("GPIO_1");
|
|
||||||
|
|
||||||
#if CONFIG_BOARD_NRFMICRO_13
|
#if CONFIG_BOARD_NRFMICRO_13
|
||||||
struct device *p0 = device_get_binding("GPIO_0");
|
struct device *p0 = device_get_binding("GPIO_0");
|
||||||
// enable EXT_VCC (use 0 for nRFMicro 1.3, use 1 for nRFMicro 1.1)
|
|
||||||
gpio_pin_configure(p1, 9, GPIO_OUTPUT);
|
|
||||||
gpio_pin_set(p1, 9, 0);
|
|
||||||
|
|
||||||
#if CONFIG_BOARD_NRFMICRO_CHARGER
|
#if CONFIG_BOARD_NRFMICRO_CHARGER
|
||||||
gpio_pin_configure(p0, 5, GPIO_OUTPUT);
|
gpio_pin_configure(p0, 5, GPIO_OUTPUT);
|
||||||
gpio_pin_set(p0, 5, 0);
|
gpio_pin_set(p0, 5, 0);
|
||||||
#else
|
#else
|
||||||
gpio_pin_configure(p0, 5, GPIO_INPUT);
|
gpio_pin_configure(p0, 5, GPIO_INPUT);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#else
|
|
||||||
// enable EXT_VCC (use 0 for nRFMicro 1.3, use 1 for nRFMicro 1.1)
|
|
||||||
gpio_pin_configure(p1, 9, GPIO_OUTPUT);
|
|
||||||
gpio_pin_set(p1, 9, 1);
|
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# Copyright (c) 2020, Pete Johanson
|
# Copyright (c) 2020, The ZMK Contributors
|
||||||
# SPDX-License-Identifier: MIT
|
# SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
description: Sensor rotate key press/release behavior
|
description: Sensor rotate key press/release behavior
|
||||||
|
|
20
app/dts/bindings/zmk,ext-power-generic.yaml
Normal file
20
app/dts/bindings/zmk,ext-power-generic.yaml
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
#
|
||||||
|
# Copyright (c) 2020, The ZMK Contributors
|
||||||
|
# SPDX-License-Identifier: MIT
|
||||||
|
#
|
||||||
|
|
||||||
|
description: |
|
||||||
|
Generic driver for controlling the external power output
|
||||||
|
by toggling the control-gpio pin status
|
||||||
|
(Only in supported hardware)
|
||||||
|
|
||||||
|
compatible: "zmk,ext-power-generic"
|
||||||
|
|
||||||
|
properties:
|
||||||
|
control-gpios:
|
||||||
|
type: phandle-array
|
||||||
|
required: true
|
||||||
|
label:
|
||||||
|
type: string
|
||||||
|
required: true
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
#
|
||||||
|
# Copyright (c) 2020, The ZMK Contributors
|
||||||
|
# SPDX-License-Identifier: MIT
|
||||||
|
#
|
||||||
|
|
||||||
description: |
|
description: |
|
||||||
Allows defining the collection of sensors bound in the keymap layers
|
Allows defining the collection of sensors bound in the keymap layers
|
||||||
|
|
||||||
|
|
104
app/include/drivers/ext_power.h
Normal file
104
app/include/drivers/ext_power.h
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020 The ZMK Contributors
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <zephyr/types.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <device.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @cond INTERNAL_HIDDEN
|
||||||
|
*
|
||||||
|
* Behavior driver API definition and system call entry points.
|
||||||
|
*
|
||||||
|
* (Internal use only.)
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef int (*ext_power_enable_t)(struct device *dev);
|
||||||
|
typedef int (*ext_power_disable_t)(struct device *dev);
|
||||||
|
typedef int (*ext_power_get_t)(struct device *dev);
|
||||||
|
|
||||||
|
__subsystem struct ext_power_api {
|
||||||
|
ext_power_enable_t enable;
|
||||||
|
ext_power_disable_t disable;
|
||||||
|
ext_power_get_t get;
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* @endcond
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enable the external power output
|
||||||
|
* @param dev Pointer to the device structure for the driver instance.
|
||||||
|
*
|
||||||
|
* @retval 0 If successful.
|
||||||
|
* @retval Negative errno code if failure.
|
||||||
|
*/
|
||||||
|
__syscall int ext_power_enable(struct device *dev);
|
||||||
|
|
||||||
|
static inline int z_impl_ext_power_enable(struct device *dev) {
|
||||||
|
const struct ext_power_api *api = (const struct ext_power_api *)dev->driver_api;
|
||||||
|
|
||||||
|
if (api->enable == NULL) {
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
return api->enable(dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disable the external power output
|
||||||
|
* @param dev Pointer to the device structure for the driver instance.
|
||||||
|
*
|
||||||
|
* @retval 0 If successful.
|
||||||
|
* @retval Negative errno code if failure.
|
||||||
|
*/
|
||||||
|
__syscall int ext_power_disable(struct device *dev);
|
||||||
|
|
||||||
|
static inline int z_impl_ext_power_disable(struct device *dev) {
|
||||||
|
const struct ext_power_api *api = (const struct ext_power_api *)dev->driver_api;
|
||||||
|
|
||||||
|
if (api->disable == NULL) {
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
return api->disable(dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the current status of the external power output
|
||||||
|
* @param dev Pointer to the device structure for the driver instance.
|
||||||
|
*
|
||||||
|
* @retval 0 If ext power is disabled.
|
||||||
|
* @retval 1 if ext power is enabled.
|
||||||
|
* @retval Negative errno code if failure.
|
||||||
|
*/
|
||||||
|
__syscall int ext_power_get(struct device *dev);
|
||||||
|
|
||||||
|
static inline int z_impl_ext_power_get(struct device *dev) {
|
||||||
|
const struct ext_power_api *api = (const struct ext_power_api *)dev->driver_api;
|
||||||
|
|
||||||
|
if (api->get == NULL) {
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
return api->get(dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <syscalls/ext_power.h>
|
91
app/src/ext_power_generic.c
Normal file
91
app/src/ext_power_generic.c
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020 The ZMK Contributors
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define DT_DRV_COMPAT zmk_ext_power_generic
|
||||||
|
|
||||||
|
#include <device.h>
|
||||||
|
#include <init.h>
|
||||||
|
#include <drivers/gpio.h>
|
||||||
|
#include <drivers/ext_power.h>
|
||||||
|
|
||||||
|
#if DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT)
|
||||||
|
|
||||||
|
#include <logging/log.h>
|
||||||
|
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
||||||
|
|
||||||
|
struct ext_power_generic_config {
|
||||||
|
const char *label;
|
||||||
|
const u8_t pin;
|
||||||
|
const u8_t flags;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ext_power_generic_data {
|
||||||
|
struct device *gpio;
|
||||||
|
bool status;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int ext_power_generic_enable(struct device *dev) {
|
||||||
|
struct ext_power_generic_data *data = dev->driver_data;
|
||||||
|
const struct ext_power_generic_config *config = dev->config_info;
|
||||||
|
|
||||||
|
if (gpio_pin_set(data->gpio, config->pin, 1)) {
|
||||||
|
LOG_WRN("Failed to set ext-power control pin");
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
data->status = true;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ext_power_generic_disable(struct device *dev) {
|
||||||
|
struct ext_power_generic_data *data = dev->driver_data;
|
||||||
|
const struct ext_power_generic_config *config = dev->config_info;
|
||||||
|
|
||||||
|
if (gpio_pin_set(data->gpio, config->pin, 0)) {
|
||||||
|
LOG_WRN("Failed to clear ext-power control pin");
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
data->status = false;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ext_power_generic_get(struct device *dev) {
|
||||||
|
struct ext_power_generic_data *data = dev->driver_data;
|
||||||
|
return data->status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ext_power_generic_init(struct device *dev) {
|
||||||
|
struct ext_power_generic_data *data = dev->driver_data;
|
||||||
|
const struct ext_power_generic_config *config = dev->config_info;
|
||||||
|
|
||||||
|
data->gpio = device_get_binding(config->label);
|
||||||
|
if (data->gpio == NULL) {
|
||||||
|
LOG_ERR("Failed to get ext-power control device");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gpio_pin_configure(data->gpio, config->pin, config->flags | GPIO_OUTPUT)) {
|
||||||
|
LOG_ERR("Failed to configure ext-power control pin");
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct ext_power_generic_config config = {
|
||||||
|
.label = DT_INST_GPIO_LABEL(0, control_gpios),
|
||||||
|
.pin = DT_INST_GPIO_PIN(0, control_gpios),
|
||||||
|
.flags = DT_INST_GPIO_FLAGS(0, control_gpios)};
|
||||||
|
|
||||||
|
static struct ext_power_generic_data data = {.status = false};
|
||||||
|
|
||||||
|
static const struct ext_power_api api = {.enable = ext_power_generic_enable,
|
||||||
|
.disable = ext_power_generic_disable,
|
||||||
|
.get = ext_power_generic_get};
|
||||||
|
|
||||||
|
DEVICE_AND_API_INIT(ext_power_generic, DT_INST_LABEL(0), ext_power_generic_init, &data, &config,
|
||||||
|
APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &api);
|
||||||
|
|
||||||
|
#endif /* DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT) */
|
|
@ -15,16 +15,25 @@ LOG_MODULE_REGISTER(zmk, CONFIG_ZMK_LOG_LEVEL);
|
||||||
#include <zmk/matrix.h>
|
#include <zmk/matrix.h>
|
||||||
#include <zmk/kscan.h>
|
#include <zmk/kscan.h>
|
||||||
#include <zmk/display.h>
|
#include <zmk/display.h>
|
||||||
|
#include <drivers/ext_power.h>
|
||||||
|
|
||||||
#define ZMK_KSCAN_DEV DT_LABEL(ZMK_MATRIX_NODE_ID)
|
#define ZMK_KSCAN_DEV DT_LABEL(ZMK_MATRIX_NODE_ID)
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
|
struct device *ext_power;
|
||||||
LOG_INF("Welcome to ZMK!\n");
|
LOG_INF("Welcome to ZMK!\n");
|
||||||
|
|
||||||
if (zmk_kscan_init(ZMK_KSCAN_DEV) != 0) {
|
if (zmk_kscan_init(ZMK_KSCAN_DEV) != 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Enable the external VCC output
|
||||||
|
ext_power = device_get_binding("EXT_POWER");
|
||||||
|
if (ext_power != NULL) {
|
||||||
|
const struct ext_power_api *ext_power_api = ext_power->driver_api;
|
||||||
|
ext_power_api->enable(ext_power);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_ZMK_DISPLAY
|
#ifdef CONFIG_ZMK_DISPLAY
|
||||||
zmk_display_init();
|
zmk_display_init();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue