samples: boards: firmware for Twinkie V2
sample firmware for Twinkie V2 that toggles the LED based on charging status. Signed-off-by: Jason Yuan <jasonyuan@google.com>
This commit is contained in:
parent
8fb198bf01
commit
ad555d08d8
7 changed files with 246 additions and 0 deletions
9
samples/boards/google_twinkie_v2_pda/CMakeLists.txt
Normal file
9
samples/boards/google_twinkie_v2_pda/CMakeLists.txt
Normal file
|
@ -0,0 +1,9 @@
|
|||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
cmake_minimum_required(VERSION 3.20.0)
|
||||
|
||||
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
|
||||
project(google_twinkie_v2)
|
||||
|
||||
FILE(GLOB app_sources src/*.c)
|
||||
target_sources(app PRIVATE ${app_sources})
|
25
samples/boards/google_twinkie_v2_pda/README.rst
Normal file
25
samples/boards/google_twinkie_v2_pda/README.rst
Normal file
|
@ -0,0 +1,25 @@
|
|||
.. _google_twinkie_v2_pda:
|
||||
|
||||
Twinkie Power Delivery
|
||||
######################
|
||||
|
||||
Overview
|
||||
********
|
||||
|
||||
This provides access to :ref:`Twinkie <google_twinkie_v2_board>` so you can try out
|
||||
the supported features.
|
||||
|
||||
Building and Running
|
||||
********************
|
||||
|
||||
Build and flash Twinkie as follows:
|
||||
|
||||
.. zephyr-app-commands::
|
||||
:zephyr-app: samples/boards/google_pda
|
||||
:board: google_twinkie_v2
|
||||
:goals: build flash
|
||||
:compact:
|
||||
|
||||
After flashing, the LED will start red. Putting the Twinkie in between any
|
||||
usbc connection will cause the LED to turn blue. The LED will turn green instead
|
||||
if the device is currently charging.
|
4
samples/boards/google_twinkie_v2_pda/prj.conf
Normal file
4
samples/boards/google_twinkie_v2_pda/prj.conf
Normal file
|
@ -0,0 +1,4 @@
|
|||
CONFIG_ADC=y
|
||||
CONFIG_ADC_STM32=y
|
||||
CONFIG_GPIO=y
|
||||
CONFIG_LED=y
|
6
samples/boards/google_twinkie_v2_pda/sample.yaml
Normal file
6
samples/boards/google_twinkie_v2_pda/sample.yaml
Normal file
|
@ -0,0 +1,6 @@
|
|||
sample:
|
||||
name: Twinkie V2 usb Vbus snooper
|
||||
tests:
|
||||
sample.board.google_twinkie_v2:
|
||||
platform_allow: google_twinkie_v2
|
||||
tags: usb
|
102
samples/boards/google_twinkie_v2_pda/src/meas.c
Normal file
102
samples/boards/google_twinkie_v2_pda/src/meas.c
Normal file
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
* Copyright (c) 2023 The ChromiumOS Authors
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/drivers/adc.h>
|
||||
#include <zephyr/drivers/adc/voltage_divider.h>
|
||||
#include <zephyr/drivers/adc/current_sense_amplifier.h>
|
||||
|
||||
/* The devicetree node identifier for the adc aliases. */
|
||||
#define VBUS_V_MEAS_NODE DT_ALIAS(vbus)
|
||||
#define VBUS_C_MEAS_NODE DT_ALIAS(cbus)
|
||||
|
||||
static const struct voltage_divider_dt_spec adc_vbus_v =
|
||||
VOLTAGE_DIVIDER_DT_SPEC_GET(VBUS_V_MEAS_NODE);
|
||||
static const struct current_sense_amplifier_dt_spec adc_vbus_c =
|
||||
CURRENT_SENSE_AMPLIFIER_DT_SPEC_GET(VBUS_C_MEAS_NODE);
|
||||
|
||||
int meas_vbus_v(int32_t *v)
|
||||
{
|
||||
int ret;
|
||||
int32_t sample_buffer = 0;
|
||||
|
||||
/* Structure defining an ADC sampling sequence */
|
||||
struct adc_sequence sequence = {
|
||||
.buffer = &sample_buffer,
|
||||
/* buffer size in bytes, not number of samples */
|
||||
.buffer_size = sizeof(sample_buffer),
|
||||
.calibrate = true,
|
||||
};
|
||||
adc_sequence_init_dt(&adc_vbus_v.port, &sequence);
|
||||
|
||||
ret = adc_read(adc_vbus_v.port.dev, &sequence);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
*v = sample_buffer;
|
||||
ret = adc_raw_to_millivolts_dt(&adc_vbus_v.port, v);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = voltage_divider_scale_dt(&adc_vbus_v, v);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int meas_vbus_c(int32_t *c)
|
||||
{
|
||||
int ret;
|
||||
int32_t sample_buffer = 0;
|
||||
|
||||
/* Structure defining an ADC sampling sequence */
|
||||
struct adc_sequence sequence = {
|
||||
.buffer = &sample_buffer,
|
||||
/* buffer size in bytes, not number of samples */
|
||||
.buffer_size = sizeof(sample_buffer),
|
||||
.calibrate = true,
|
||||
};
|
||||
adc_sequence_init_dt(&adc_vbus_c.port, &sequence);
|
||||
|
||||
ret = adc_read(adc_vbus_c.port.dev, &sequence);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
*c = sample_buffer;
|
||||
ret = adc_raw_to_millivolts_dt(&adc_vbus_c.port, c);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* prescaling the voltage offset */
|
||||
*c -= adc_vbus_c.port.vref_mv / 2;
|
||||
current_sense_amplifier_scale_dt(&adc_vbus_c, c);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int meas_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = adc_channel_setup_dt(&adc_vbus_v.port);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = adc_channel_setup_dt(&adc_vbus_c.port);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
36
samples/boards/google_twinkie_v2_pda/src/meas.h
Normal file
36
samples/boards/google_twinkie_v2_pda/src/meas.h
Normal file
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright (c) 2023 The ChromiumOS Authors
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef __MEAS_H__
|
||||
#define __MEAS_H__
|
||||
|
||||
/**
|
||||
* @brief Initializes the measurement module, sets up all the adc channels through the device tree
|
||||
* binding
|
||||
*
|
||||
* @return 0 on success
|
||||
*/
|
||||
int meas_init(void);
|
||||
|
||||
/**
|
||||
* @brief Measure the voltage on VBUS
|
||||
*
|
||||
* @param v pointer where VBUS voltage, in millivolts, is stored
|
||||
*
|
||||
* @return 0 on success
|
||||
*/
|
||||
int meas_vbus_v(int32_t *v);
|
||||
|
||||
/**
|
||||
* @brief Measure the current on VBUS
|
||||
*
|
||||
* @param c pointer where VBUS current, in milliamperes, is stored
|
||||
*
|
||||
* @return 0 on success
|
||||
*/
|
||||
int meas_vbus_c(int32_t *c);
|
||||
|
||||
#endif
|
64
samples/boards/google_twinkie_v2_pda/src/view.c
Normal file
64
samples/boards/google_twinkie_v2_pda/src/view.c
Normal file
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Copyright (c) 2023 The ChromiumOS Authors
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr/device.h>
|
||||
#include <zephyr/drivers/led.h>
|
||||
#include <zephyr/kernel.h>
|
||||
|
||||
#include "meas.h"
|
||||
|
||||
enum led_color_t {
|
||||
LED_RED,
|
||||
LED_GREEN,
|
||||
LED_BLUE,
|
||||
};
|
||||
|
||||
static void set_led(const struct device *const led, enum led_color_t led_color)
|
||||
{
|
||||
if (led_color != LED_RED) {
|
||||
led_off(led, LED_RED);
|
||||
}
|
||||
if (led_color != LED_GREEN) {
|
||||
led_off(led, LED_GREEN);
|
||||
}
|
||||
if (led_color != LED_BLUE) {
|
||||
led_off(led, LED_BLUE);
|
||||
}
|
||||
led_on(led, led_color);
|
||||
}
|
||||
|
||||
#define CHARGING_VOLTAGE 5000
|
||||
#define CHARGING_CURRENT 1000
|
||||
|
||||
void main(void)
|
||||
{
|
||||
meas_init();
|
||||
|
||||
const struct device *const led = DEVICE_DT_GET_ONE(gpio_leds);
|
||||
int32_t vbus_v = 0;
|
||||
int32_t vbus_c = 0;
|
||||
|
||||
if (!device_is_ready(led)) {
|
||||
return;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
meas_vbus_v(&vbus_v);
|
||||
meas_vbus_c(&vbus_c);
|
||||
|
||||
if (vbus_v > CHARGING_VOLTAGE) {
|
||||
if (vbus_c > CHARGING_CURRENT) {
|
||||
set_led(led, LED_GREEN);
|
||||
} else {
|
||||
set_led(led, LED_BLUE);
|
||||
}
|
||||
} else {
|
||||
set_led(led, LED_RED);
|
||||
}
|
||||
|
||||
k_usleep(500);
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue