Skip to content

Commit

Permalink
samples: boards: firmware for Twinkie V2
Browse files Browse the repository at this point in the history
sample firmware for Twinkie V2 that toggles the LED based on charging
status.

Signed-off-by: Jason Yuan <[email protected]>
  • Loading branch information
ualbertagreen committed Jul 10, 2023
1 parent 07a5e8e commit 62977b0
Show file tree
Hide file tree
Showing 7 changed files with 246 additions and 0 deletions.
9 changes: 9 additions & 0 deletions samples/boards/google_twinkie_v2_pda/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -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 changes: 25 additions & 0 deletions samples/boards/google_twinkie_v2_pda/README.rst
Original file line number Diff line number Diff line change
@@ -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 changes: 4 additions & 0 deletions samples/boards/google_twinkie_v2_pda/prj.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
CONFIG_ADC=y
CONFIG_ADC_STM32=y
CONFIG_GPIO=y
CONFIG_LED=y
6 changes: 6 additions & 0 deletions samples/boards/google_twinkie_v2_pda/sample.yaml
Original file line number Diff line number Diff line change
@@ -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 changes: 102 additions & 0 deletions samples/boards/google_twinkie_v2_pda/src/meas.c
Original file line number Diff line number Diff line change
@@ -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 changes: 36 additions & 0 deletions samples/boards/google_twinkie_v2_pda/src/meas.h
Original file line number Diff line number Diff line change
@@ -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 changes: 64 additions & 0 deletions samples/boards/google_twinkie_v2_pda/src/view.c
Original file line number Diff line number Diff line change
@@ -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);
}
}

0 comments on commit 62977b0

Please sign in to comment.