samples: usb-c: sink: Add USB-C Subsystem Sink Sample
Implementing USB-C Sink functionality can be difficult. This sample application serves as an example of how to create an application with Power Delivery Sink functionality. Signed-off-by: Sam Hurst <sbh1187@gmail.com>
This commit is contained in:
parent
e90f1b66d8
commit
e2f5fcd91a
10 changed files with 581 additions and 7 deletions
|
@ -110,6 +110,24 @@
|
|||
status = "okay";
|
||||
};
|
||||
|
||||
&adc2 {
|
||||
pinctrl-0 = <&adc2_in8_pc2>;
|
||||
pinctrl-names = "default";
|
||||
status = "okay";
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
channel@8 {
|
||||
reg = <8>;
|
||||
zephyr,gain = "ADC_GAIN_1";
|
||||
zephyr,reference = "ADC_REF_INTERNAL";
|
||||
zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
|
||||
zephyr,resolution = <12>;
|
||||
zephyr,vref-mv = <3300>;
|
||||
};
|
||||
};
|
||||
|
||||
&ucpd1 {
|
||||
status = "okay";
|
||||
|
||||
|
@ -137,6 +155,8 @@
|
|||
*/
|
||||
psc-ucpdclk = <1>;
|
||||
hbitclkdiv = <27>;
|
||||
pinctrl-0 = <&ucpd1_cc1_pb6 &ucpd1_cc2_pb4>;
|
||||
pinctrl-names = "default";
|
||||
};
|
||||
|
||||
zephyr_udc0: &usb {
|
||||
|
|
|
@ -75,13 +75,6 @@
|
|||
sw4 = &joy_up;
|
||||
watchdog0 = &iwdg;
|
||||
};
|
||||
|
||||
vbus {
|
||||
compatible = "voltage-divider";
|
||||
io-channels = <&adc1 3>;
|
||||
output-ohms = <49900>;
|
||||
full-ohms = <(330000 + 49900)>;
|
||||
};
|
||||
};
|
||||
|
||||
&clk_hsi {
|
||||
|
@ -116,6 +109,18 @@
|
|||
pinctrl-0 = <&adc1_in3_pa3>;
|
||||
pinctrl-names = "default";
|
||||
status = "okay";
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
channel@3 {
|
||||
reg = <3>;
|
||||
zephyr,gain = "ADC_GAIN_1";
|
||||
zephyr,reference = "ADC_REF_INTERNAL";
|
||||
zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
|
||||
zephyr,resolution = <12>;
|
||||
zephyr,vref-mv = <3300>;
|
||||
};
|
||||
};
|
||||
|
||||
&ucpd2 {
|
||||
|
|
7
samples/subsys/usb_c/sink/CMakeLists.txt
Normal file
7
samples/subsys/usb_c/sink/CMakeLists.txt
Normal file
|
@ -0,0 +1,7 @@
|
|||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
cmake_minimum_required(VERSION 3.20.0)
|
||||
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
|
||||
project(usb_c_sink)
|
||||
|
||||
target_sources(app PRIVATE src/main.c)
|
109
samples/subsys/usb_c/sink/README.rst
Normal file
109
samples/subsys/usb_c/sink/README.rst
Normal file
|
@ -0,0 +1,109 @@
|
|||
.. _usb-c-sink-sample:
|
||||
|
||||
Basic USB-C SINK
|
||||
################
|
||||
|
||||
Overview
|
||||
********
|
||||
|
||||
This example demonstrates how to create a USB-C Power Delivery application
|
||||
using the USB-C subsystem. The application implements a USB-C Sink device.
|
||||
|
||||
After the USB-C Sink device is plugged into a Power Delivery charger, it
|
||||
negotiates with the charger to provide 5V@100mA and displays all
|
||||
Power Delivery Objects (PDOs) provided by the charger.
|
||||
|
||||
.. _usb-c-sink-sample-requirements:
|
||||
|
||||
Requirements
|
||||
************
|
||||
The TCPC device used by the sample is specified in the devicetree
|
||||
node that's compatible with ``usb-c-connector``.
|
||||
The sample has been tested on :ref:`b_g474e_dpow1_board` and
|
||||
:ref:`stm32g081b_eval_board`. Overlay files for the two boards
|
||||
are provided.
|
||||
|
||||
Building and Running
|
||||
********************
|
||||
|
||||
Build and flash as follows, changing ``b_g474e_dpow1`` for your board:
|
||||
|
||||
.. zephyr-app-commands::
|
||||
:zephyr-app: samples/subsys/usb-c/sink
|
||||
:board: b_g474e_dpow1
|
||||
:goals: build flash
|
||||
:compact:
|
||||
|
||||
Connect a charger and see console output:
|
||||
|
||||
Sample Output
|
||||
=============
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
Unattached.SNK
|
||||
AttachWait.SNK
|
||||
Attached.SNK
|
||||
PE_SNK_Startup
|
||||
PRL_INIT
|
||||
PRL_HR_Wait_for_Request
|
||||
PRL_Tx_PHY_Layer_Reset
|
||||
PRL_Tx_Wait_for_Message_Request
|
||||
PE_SNK_Discovery
|
||||
PE_SNK_Wait_For_Capabilities
|
||||
RECV 4161/4 [0]0a01912c [1]0002d12c [2]0004b12c [3]000640e1
|
||||
PE_SNK_Evaluate_Capability
|
||||
PE_SNK_Select_Capability
|
||||
PRL_Tx_Wait_for_PHY_response
|
||||
PWR 3A0
|
||||
|
||||
RECV 0363/0
|
||||
PRL_Tx_Wait_for_Message_Request
|
||||
PE_SNK_Transition_Sink
|
||||
RECV 0566/0
|
||||
Source Caps:
|
||||
PDO 0:
|
||||
Type: FIXED
|
||||
Current: 3000
|
||||
Voltage: 5000
|
||||
Peak Current: 0
|
||||
Uchunked Support: 0
|
||||
Dual Role Data: 1
|
||||
USB Comms: 0
|
||||
Unconstrained Pwr: 1
|
||||
USB Susspend: 0
|
||||
Dual Role Power: 0
|
||||
PDO 1:
|
||||
Type: FIXED
|
||||
Current: 3000
|
||||
Voltage: 9000
|
||||
Peak Current: 0
|
||||
Uchunked Support: 0
|
||||
Dual Role Data: 0
|
||||
USB Comms: 0
|
||||
Unconstrained Pwr: 0
|
||||
USB Susspend: 0
|
||||
Dual Role Power: 0
|
||||
PDO 2:
|
||||
Type: FIXED
|
||||
Current: 3000
|
||||
Voltage: 15000
|
||||
Peak Current: 0
|
||||
Uchunked Support: 0
|
||||
Dual Role Data: 0
|
||||
USB Comms: 0
|
||||
Unconstrained Pwr: 0
|
||||
USB Susspend: 0
|
||||
Dual Role Power: 0
|
||||
PDO 3:
|
||||
Type: FIXED
|
||||
Current: 2250
|
||||
Voltage: 20000
|
||||
Peak Current: 0
|
||||
Uchunked Support: 0
|
||||
Dual Role Data: 0
|
||||
USB Comms: 0
|
||||
Unconstrained Pwr: 0
|
||||
USB Susspend: 0
|
||||
Dual Role Power: 0
|
||||
PE_SNK_Ready
|
34
samples/subsys/usb_c/sink/boards/b_g474e_dpow1.overlay
Normal file
34
samples/subsys/usb_c/sink/boards/b_g474e_dpow1.overlay
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright (c) 2022 The Chromium OS Authors.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
*/
|
||||
|
||||
#include <dt-bindings/usb-c/pd.h>
|
||||
|
||||
/ {
|
||||
/* usbc.rst vbus-voltage-divider-adc start */
|
||||
vbus1: vbus {
|
||||
compatible = "zephyr,usb-c-vbus-adc";
|
||||
io-channels = <&adc2 8>;
|
||||
output-ohms = <49900>;
|
||||
full-ohms = <(330000 + 49900)>;
|
||||
};
|
||||
/* usbc.rst vbus-voltage-divider-adc end */
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
/* usbc.rst usbc-port start */
|
||||
port1: usbc-port@1 {
|
||||
compatible = "usb-c-connector";
|
||||
reg = <1>;
|
||||
tcpc = <&ucpd1>;
|
||||
vbus = <&vbus1>;
|
||||
power-role = "sink";
|
||||
sink-pdos = <PDO_FIXED(5000, 100, 0)>;
|
||||
};
|
||||
/* usbc.rst usbc-port end */
|
||||
};
|
||||
};
|
34
samples/subsys/usb_c/sink/boards/stm32g081b_eval.overlay
Normal file
34
samples/subsys/usb_c/sink/boards/stm32g081b_eval.overlay
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright (c) 2022 The Chromium OS Authors.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
*/
|
||||
|
||||
#include <dt-bindings/usb-c/pd.h>
|
||||
|
||||
/ {
|
||||
vbus2: vbus {
|
||||
compatible = "zephyr,usb-c-vbus-adc";
|
||||
io-channels = <&adc1 3>;
|
||||
output-ohms = <49900>;
|
||||
full-ohms = <(330000 + 49900)>;
|
||||
|
||||
/* Pin B14 is used to control VBUS Discharge for Port2 */
|
||||
discharge-gpios = <&gpiob 14 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port1: usbc-port@1 {
|
||||
compatible = "usb-c-connector";
|
||||
reg = <1>;
|
||||
tcpc = <&ucpd2>;
|
||||
vbus = <&vbus2>;
|
||||
power-role = "sink";
|
||||
sink-pdos = <PDO_FIXED(5000, 100, 0)>;
|
||||
};
|
||||
};
|
||||
};
|
4
samples/subsys/usb_c/sink/prj.conf
Normal file
4
samples/subsys/usb_c/sink/prj.conf
Normal file
|
@ -0,0 +1,4 @@
|
|||
CONFIG_USBC_STACK=y
|
||||
CONFIG_USBC_THREAD_PRIORITY=10
|
||||
CONFIG_ADC=y
|
||||
CONFIG_LOG=y
|
12
samples/subsys/usb_c/sink/sample.yaml
Normal file
12
samples/subsys/usb_c/sink/sample.yaml
Normal file
|
@ -0,0 +1,12 @@
|
|||
sample:
|
||||
name: USB-C SINK
|
||||
tests:
|
||||
sample.usbc.sink:
|
||||
depends_on: tcpc
|
||||
tags: usbc
|
||||
platform_allow: b_g474e_dpow1
|
||||
harness: console
|
||||
harness_config:
|
||||
type: one_line
|
||||
regex:
|
||||
- "Unattached.SNK"
|
339
samples/subsys/usb_c/sink/src/main.c
Normal file
339
samples/subsys/usb_c/sink/src/main.c
Normal file
|
@ -0,0 +1,339 @@
|
|||
/*
|
||||
* Copyright (c) 2022 The Chromium OS Authors.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/device.h>
|
||||
#include <zephyr/devicetree.h>
|
||||
#include <zephyr/drivers/gpio.h>
|
||||
#include <zephyr/usb_c/usbc.h>
|
||||
|
||||
#include <zephyr/logging/log.h>
|
||||
LOG_MODULE_REGISTER(main, LOG_LEVEL_DBG);
|
||||
|
||||
#define PORT1_NODE DT_NODELABEL(port1)
|
||||
#define PORT1_POWER_ROLE DT_ENUM_IDX(DT_NODELABEL(port1), power_role)
|
||||
|
||||
#if (PORT1_POWER_ROLE != TC_ROLE_SINK)
|
||||
#error "Unsupported board: Only Sink device supported"
|
||||
#endif
|
||||
|
||||
#define SINK_PDO(node_id, prop, idx) (DT_PROP_BY_IDX(node_id, prop, idx)),
|
||||
|
||||
/* usbc.rst port data object start */
|
||||
/**
|
||||
* @brief A structure that encapsulates Port data.
|
||||
*/
|
||||
static struct port1_data_t {
|
||||
/** Sink Capabilities */
|
||||
uint32_t snk_caps[DT_PROP_LEN(DT_NODELABEL(port1), sink_pdos)];
|
||||
/** Number of Sink Capabilities */
|
||||
int snk_cap_cnt;
|
||||
/** Source Capabilities */
|
||||
uint32_t src_caps[PDO_MAX_DATA_OBJECTS];
|
||||
/** Number of Source Capabilities */
|
||||
int src_cap_cnt;
|
||||
/* Power Supply Ready flag */
|
||||
atomic_t ps_ready;
|
||||
} port1_data = {
|
||||
.snk_caps = {DT_FOREACH_PROP_ELEM(DT_NODELABEL(port1), sink_pdos, SINK_PDO)},
|
||||
.snk_cap_cnt = DT_PROP_LEN(DT_NODELABEL(port1), sink_pdos),
|
||||
.src_caps = {0},
|
||||
.src_cap_cnt = 0,
|
||||
.ps_ready = 0
|
||||
};
|
||||
|
||||
/* usbc.rst port data object end */
|
||||
|
||||
/**
|
||||
* @brief Builds a Request Data Object (RDO) with the following properties:
|
||||
* - Maximum operating current 100mA
|
||||
* - Operating current is 100mA
|
||||
* - Unchunked Extended Messages Not Supported
|
||||
* - No USB Suspend
|
||||
* - Not USB Communications Capable
|
||||
* - No capability mismatch
|
||||
* - Does not Giveback
|
||||
* - Select object position 1 (5V Power Data Object (PDO))
|
||||
*
|
||||
* @note Generally a sink application would build an RDO from the
|
||||
* Source Capabilities stored in the dpm_data object
|
||||
*/
|
||||
static uint32_t build_rdo(const struct port1_data_t *dpm_data)
|
||||
{
|
||||
union pd_rdo rdo;
|
||||
|
||||
/* Maximum operating current 100mA (GIVEBACK = 0) */
|
||||
rdo.fixed.min_or_max_operating_current = PD_CONVERT_MA_TO_FIXED_PDO_CURRENT(100);
|
||||
/* Operating current 100mA */
|
||||
rdo.fixed.operating_current = PD_CONVERT_MA_TO_FIXED_PDO_CURRENT(100);
|
||||
/* Unchunked Extended Messages Not Supported */
|
||||
rdo.fixed.unchunked_ext_msg_supported = 0;
|
||||
/* No USB Suspend */
|
||||
rdo.fixed.no_usb_suspend = 1;
|
||||
/* Not USB Communications Capable */
|
||||
rdo.fixed.usb_comm_capable = 0;
|
||||
/* No capability mismatch */
|
||||
rdo.fixed.cap_mismatch = 0;
|
||||
/* Don't giveback */
|
||||
rdo.fixed.giveback = 0;
|
||||
/* Object position 1 (5V PDO) */
|
||||
rdo.fixed.object_pos = 1;
|
||||
|
||||
return rdo.raw_value;
|
||||
}
|
||||
|
||||
static void display_pdo(const int idx,
|
||||
const uint32_t pdo_value)
|
||||
{
|
||||
union pd_fixed_supply_pdo_source pdo;
|
||||
|
||||
/* Default to fixed supply pdo source until type is detected */
|
||||
pdo.raw_value = pdo_value;
|
||||
|
||||
LOG_INF("PDO %d:", idx);
|
||||
switch (pdo.type) {
|
||||
case PDO_FIXED: {
|
||||
LOG_INF("\tType: FIXED");
|
||||
LOG_INF("\tCurrent: %d",
|
||||
PD_CONVERT_FIXED_PDO_CURRENT_TO_MA(pdo.max_current));
|
||||
LOG_INF("\tVoltage: %d",
|
||||
PD_CONVERT_FIXED_PDO_VOLTAGE_TO_MV(pdo.voltage));
|
||||
LOG_INF("\tPeak Current: %d", pdo.peak_current);
|
||||
LOG_INF("\tUchunked Support: %d",
|
||||
pdo.unchunked_ext_msg_supported);
|
||||
LOG_INF("\tDual Role Data: %d",
|
||||
pdo.dual_role_data);
|
||||
LOG_INF("\tUSB Comms: %d",
|
||||
pdo.usb_comms_capable);
|
||||
LOG_INF("\tUnconstrained Pwr: %d",
|
||||
pdo.unconstrained_power);
|
||||
LOG_INF("\tUSB Suspend: %d",
|
||||
pdo.usb_suspend_supported);
|
||||
LOG_INF("\tDual Role Power: %d",
|
||||
pdo.dual_role_power);
|
||||
}
|
||||
break;
|
||||
case PDO_BATTERY: {
|
||||
union pd_battery_supply_pdo_source pdo;
|
||||
|
||||
pdo.raw_value = pdo_value;
|
||||
LOG_INF("\tType: BATTERY");
|
||||
LOG_INF("\tMin Voltage: %d",
|
||||
PD_CONVERT_BATTERY_PDO_VOLTAGE_TO_MV(pdo.min_voltage));
|
||||
LOG_INF("\tMax Voltage: %d",
|
||||
PD_CONVERT_BATTERY_PDO_VOLTAGE_TO_MV(pdo.max_voltage));
|
||||
LOG_INF("\tMax Power: %d",
|
||||
PD_CONVERT_BATTERY_PDO_POWER_TO_MW(pdo.max_power));
|
||||
}
|
||||
break;
|
||||
case PDO_VARIABLE: {
|
||||
union pd_variable_supply_pdo_source pdo;
|
||||
|
||||
pdo.raw_value = pdo_value;
|
||||
LOG_INF("\tType: VARIABLE");
|
||||
LOG_INF("\tMin Voltage: %d",
|
||||
PD_CONVERT_VARIABLE_PDO_VOLTAGE_TO_MV(pdo.min_voltage));
|
||||
LOG_INF("\tMax Voltage: %d",
|
||||
PD_CONVERT_VARIABLE_PDO_VOLTAGE_TO_MV(pdo.max_voltage));
|
||||
LOG_INF("\tMax Current: %d",
|
||||
PD_CONVERT_VARIABLE_PDO_CURRENT_TO_MA(pdo.max_current));
|
||||
}
|
||||
break;
|
||||
case PDO_AUGMENTED: {
|
||||
union pd_augmented_supply_pdo_source pdo;
|
||||
|
||||
pdo.raw_value = pdo_value;
|
||||
LOG_INF("\tType: AUGMENTED");
|
||||
LOG_INF("\tMin Voltage: %d",
|
||||
PD_CONVERT_AUGMENTED_PDO_VOLTAGE_TO_MV(pdo.min_voltage));
|
||||
LOG_INF("\tMax Voltage: %d",
|
||||
PD_CONVERT_AUGMENTED_PDO_VOLTAGE_TO_MV(pdo.max_voltage));
|
||||
LOG_INF("\tMax Current: %d",
|
||||
PD_CONVERT_AUGMENTED_PDO_CURRENT_TO_MA(pdo.max_current));
|
||||
LOG_INF("\tPPS Power Limited: %d", pdo.pps_power_limited);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void display_source_caps(const struct device *dev)
|
||||
{
|
||||
struct port1_data_t *dpm_data = usbc_get_dpm_data(dev);
|
||||
|
||||
LOG_INF("Source Caps:");
|
||||
for (int i = 0; i < dpm_data->src_cap_cnt; i++) {
|
||||
display_pdo(i, dpm_data->src_caps[i]);
|
||||
k_msleep(50);
|
||||
}
|
||||
}
|
||||
|
||||
/* usbc.rst callbacks start */
|
||||
static int port1_policy_cb_get_snk_cap(const struct device *dev,
|
||||
uint32_t **pdos,
|
||||
int *num_pdos)
|
||||
{
|
||||
struct port1_data_t *dpm_data = usbc_get_dpm_data(dev);
|
||||
|
||||
*pdos = dpm_data->snk_caps;
|
||||
num_pdos = &dpm_data->snk_cap_cnt;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void port1_policy_cb_set_src_cap(const struct device *dev,
|
||||
const uint32_t *pdos,
|
||||
const int num_pdos)
|
||||
{
|
||||
struct port1_data_t *dpm_data;
|
||||
int num;
|
||||
int i;
|
||||
|
||||
dpm_data = usbc_get_dpm_data(dev);
|
||||
|
||||
num = num_pdos;
|
||||
if (num > PDO_MAX_DATA_OBJECTS) {
|
||||
num = PDO_MAX_DATA_OBJECTS;
|
||||
}
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
dpm_data->src_caps[i] = *(pdos + i);
|
||||
}
|
||||
|
||||
dpm_data->src_cap_cnt = num;
|
||||
}
|
||||
|
||||
static uint32_t port1_policy_cb_get_rdo(const struct device *dev)
|
||||
{
|
||||
struct port1_data_t *dpm_data = usbc_get_dpm_data(dev);
|
||||
|
||||
return build_rdo(dpm_data);
|
||||
}
|
||||
/* usbc.rst callbacks end */
|
||||
|
||||
/* usbc.rst notify start */
|
||||
static void port1_notify(const struct device *dev,
|
||||
const enum usbc_policy_notify_t policy_notify)
|
||||
{
|
||||
struct port1_data_t *dpm_data = usbc_get_dpm_data(dev);
|
||||
|
||||
switch (policy_notify) {
|
||||
case PROTOCOL_ERROR:
|
||||
break;
|
||||
case MSG_DISCARDED:
|
||||
break;
|
||||
case MSG_ACCEPT_RECEIVED:
|
||||
break;
|
||||
case MSG_REJECTED_RECEIVED:
|
||||
break;
|
||||
case MSG_NOT_SUPPORTED_RECEIVED:
|
||||
break;
|
||||
case TRANSITION_PS:
|
||||
atomic_set_bit(&dpm_data->ps_ready, 0);
|
||||
break;
|
||||
case PD_CONNECTED:
|
||||
break;
|
||||
case NOT_PD_CONNECTED:
|
||||
break;
|
||||
case POWER_CHANGE_0A0:
|
||||
LOG_INF("PWR 0A");
|
||||
break;
|
||||
case POWER_CHANGE_DEF:
|
||||
LOG_INF("PWR DEF");
|
||||
break;
|
||||
case POWER_CHANGE_1A5:
|
||||
LOG_INF("PWR 1A5");
|
||||
break;
|
||||
case POWER_CHANGE_3A0:
|
||||
LOG_INF("PWR 3A0");
|
||||
break;
|
||||
case DATA_ROLE_IS_UFP:
|
||||
break;
|
||||
case DATA_ROLE_IS_DFP:
|
||||
break;
|
||||
case PORT_PARTNER_NOT_RESPONSIVE:
|
||||
LOG_INF("Port Partner not PD Capable");
|
||||
break;
|
||||
case SNK_TRANSITION_TO_DEFAULT:
|
||||
break;
|
||||
case HARD_RESET_RECEIVED:
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* usbc.rst notify end */
|
||||
|
||||
/* usbc.rst check start */
|
||||
bool port1_policy_check(const struct device *dev,
|
||||
const enum usbc_policy_check_t policy_check)
|
||||
{
|
||||
switch (policy_check) {
|
||||
case CHECK_POWER_ROLE_SWAP:
|
||||
/* Reject power role swaps */
|
||||
return false;
|
||||
case CHECK_DATA_ROLE_SWAP_TO_DFP:
|
||||
/* Reject data role swap to DFP */
|
||||
return false;
|
||||
case CHECK_DATA_ROLE_SWAP_TO_UFP:
|
||||
/* Accept data role swap to UFP */
|
||||
return true;
|
||||
case CHECK_SNK_AT_DEFAULT_LEVEL:
|
||||
/* This device is always at the default power level */
|
||||
return true;
|
||||
default:
|
||||
/* Reject all other policy checks */
|
||||
return false;
|
||||
|
||||
}
|
||||
}
|
||||
/* usbc.rst check end */
|
||||
|
||||
void main(void)
|
||||
{
|
||||
const struct device *usbc_port1;
|
||||
|
||||
/* Get the device for this port */
|
||||
usbc_port1 = DEVICE_DT_GET(PORT1_NODE);
|
||||
if (!device_is_ready(usbc_port1)) {
|
||||
LOG_ERR("PORT1 device not ready");
|
||||
return;
|
||||
}
|
||||
|
||||
/* usbc.rst register start */
|
||||
/* Register USB-C Callbacks */
|
||||
|
||||
/* Register Policy Check callback */
|
||||
usbc_set_policy_cb_check(usbc_port1, port1_policy_check);
|
||||
/* Register Policy Notify callback */
|
||||
usbc_set_policy_cb_notify(usbc_port1, port1_notify);
|
||||
/* Register Policy Get Sink Capabilities callback */
|
||||
usbc_set_policy_cb_get_snk_cap(usbc_port1, port1_policy_cb_get_snk_cap);
|
||||
/* Register Policy Set Source Capabilities callback */
|
||||
usbc_set_policy_cb_set_src_cap(usbc_port1, port1_policy_cb_set_src_cap);
|
||||
/* Register Policy Get Request Data Object callback */
|
||||
usbc_set_policy_cb_get_rdo(usbc_port1, port1_policy_cb_get_rdo);
|
||||
/* usbc.rst register end */
|
||||
|
||||
/* usbc.rst user data start */
|
||||
/* Set Application port data object. This object is passed to the policy callbacks */
|
||||
port1_data.ps_ready = ATOMIC_INIT(0);
|
||||
usbc_set_dpm_data(usbc_port1, &port1_data);
|
||||
/* usbc.rst user data end */
|
||||
|
||||
/* usbc.rst usbc start */
|
||||
/* Start the USB-C Subsystem */
|
||||
usbc_start(usbc_port1);
|
||||
/* usbc.rst usbc end */
|
||||
|
||||
while (1) {
|
||||
/* Perform Application Specific functions */
|
||||
if (atomic_test_and_clear_bit(&port1_data.ps_ready, 0)) {
|
||||
/* Display the Source Capabilities */
|
||||
display_source_caps(usbc_port1);
|
||||
}
|
||||
|
||||
/* Arbitrary delay */
|
||||
k_msleep(1000);
|
||||
}
|
||||
}
|
10
samples/subsys/usb_c/usbc.rst
Normal file
10
samples/subsys/usb_c/usbc.rst
Normal file
|
@ -0,0 +1,10 @@
|
|||
.. _usbc-samples:
|
||||
|
||||
USB-C device support samples
|
||||
############################
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
:glob:
|
||||
|
||||
**/*
|
Loading…
Add table
Add a link
Reference in a new issue