-
Notifications
You must be signed in to change notification settings - Fork 6.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
samples: boards: firmware for Twinkie V2
sample firmware for Twinkie V2 that toggles the LED based on charging status. Signed-off-by: Jason Yuan <[email protected]>
- Loading branch information
1 parent
f60d8f5
commit 65cf6e8
Showing
7 changed files
with
299 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
CONFIG_ADC=y | ||
CONFIG_ADC_STM32=y | ||
CONFIG_GPIO=y |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
/* | ||
* Copyright (c) 2023 The ChromiumOS Authors | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
#include <zephyr/kernel.h> | ||
#include <zephyr/smf.h> | ||
#include <zephyr/drivers/gpio.h> | ||
|
||
#include <zephyr/device.h> | ||
|
||
#include "meas.h" | ||
|
||
/* The devicetree node identifier for the led aliases. */ | ||
#define LED0_NODE DT_ALIAS(led0) | ||
#define LED1_NODE DT_ALIAS(led1) | ||
#define LED2_NODE DT_ALIAS(led2) | ||
|
||
static const struct gpio_dt_spec led0 = GPIO_DT_SPEC_GET(LED0_NODE, gpios); | ||
static const struct gpio_dt_spec led1 = GPIO_DT_SPEC_GET(LED1_NODE, gpios); | ||
static const struct gpio_dt_spec led2 = GPIO_DT_SPEC_GET(LED2_NODE, gpios); | ||
|
||
enum led_t { | ||
LED_OFF, | ||
LED_RED, | ||
LED_GREEN, | ||
LED_BLUE | ||
}; | ||
|
||
static void set_led(enum led_t led) | ||
{ | ||
switch (led) { | ||
case LED_OFF: | ||
gpio_pin_set_dt(&led0, 0); | ||
gpio_pin_set_dt(&led1, 0); | ||
gpio_pin_set_dt(&led2, 0); | ||
break; | ||
case LED_RED: | ||
gpio_pin_set_dt(&led0, 1); | ||
gpio_pin_set_dt(&led1, 0); | ||
gpio_pin_set_dt(&led2, 0); | ||
break; | ||
case LED_GREEN: | ||
gpio_pin_set_dt(&led0, 0); | ||
gpio_pin_set_dt(&led1, 1); | ||
gpio_pin_set_dt(&led2, 0); | ||
break; | ||
case LED_BLUE: | ||
gpio_pin_set_dt(&led0, 0); | ||
gpio_pin_set_dt(&led1, 0); | ||
gpio_pin_set_dt(&led2, 1); | ||
break; | ||
} | ||
} | ||
|
||
int view_init(void) | ||
{ | ||
int ret; | ||
|
||
if (!device_is_ready(led0.port)) { | ||
return -EIO; | ||
} | ||
|
||
if (!device_is_ready(led1.port)) { | ||
return -EIO; | ||
} | ||
|
||
if (!device_is_ready(led2.port)) { | ||
return -EIO; | ||
} | ||
|
||
ret = gpio_pin_configure_dt(&led0, GPIO_OUTPUT_ACTIVE); | ||
if (ret < 0) { | ||
return ret; | ||
} | ||
|
||
ret = gpio_pin_configure_dt(&led1, GPIO_OUTPUT_ACTIVE); | ||
if (ret < 0) { | ||
return ret; | ||
} | ||
|
||
ret = gpio_pin_configure_dt(&led2, GPIO_OUTPUT_ACTIVE); | ||
if (ret < 0) { | ||
return ret; | ||
} | ||
|
||
return 0; | ||
} | ||
|
||
#define CHARGING_VOLTAGE 5000 | ||
#define CHARGING_CURRENT 1000 | ||
|
||
void main(void) | ||
{ | ||
meas_init(); | ||
view_init(); | ||
|
||
int32_t vbus_v = 0; | ||
int32_t vbus_c = 0; | ||
|
||
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_GREEN); | ||
} else { | ||
set_led(LED_BLUE); | ||
} | ||
} else { | ||
set_led(LED_RED); | ||
} | ||
|
||
k_usleep(500); | ||
} | ||
} |