blob: 404706a5d86a7e49dd0d41b94ffbb5079efa327f [file] [log] [blame]
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
#include "sw/device/lib/dif/dif_usbdev.h"
#include "gtest/gtest.h"
#include "sw/device/lib/base/mmio.h"
#include "sw/device/lib/base/mock_mmio.h"
#include "sw/device/lib/base/multibits.h"
#include "sw/device/lib/dif/dif_base.h"
#include "sw/device/lib/dif/dif_test_base.h"
#include "usbdev_regs.h" // Generated.
namespace dif_usbdev_unittest {
namespace {
using mock_mmio::MmioTest;
using mock_mmio::MockDevice;
using testing::Test;
class UsbdevTest : public Test, public MmioTest {
protected:
dif_usbdev_t usbdev_ = {
.base_addr = dev().region(),
};
};
TEST_F(UsbdevTest, NullArgsTest) {
dif_usbdev_config_t config;
dif_usbdev_buffer_pool_t buffer_pool;
bool bool_arg;
dif_usbdev_rx_packet_info_t packet_info;
dif_usbdev_buffer_t buffer;
uint8_t uint8_arg;
size_t size_arg;
dif_usbdev_endpoint_id_t endpoint_id;
dif_usbdev_tx_status_t tx_status;
uint16_t uint16_arg;
dif_usbdev_link_state_t link_state;
dif_usbdev_wake_status_t wake_status;
dif_usbdev_phy_pins_sense_t phy_pins_status;
dif_usbdev_phy_pins_drive_t phy_pins_drive;
EXPECT_DIF_BADARG(dif_usbdev_configure(nullptr, &buffer_pool, config));
EXPECT_DIF_BADARG(dif_usbdev_configure(&usbdev_, nullptr, config));
EXPECT_DIF_BADARG(dif_usbdev_fill_available_fifo(nullptr, &buffer_pool));
EXPECT_DIF_BADARG(dif_usbdev_fill_available_fifo(&usbdev_, nullptr));
EXPECT_DIF_BADARG(dif_usbdev_endpoint_setup_enable(nullptr, /*endpoint=*/0,
kDifToggleEnabled));
EXPECT_DIF_BADARG(dif_usbdev_endpoint_out_enable(nullptr, /*endpoint=*/0,
kDifToggleEnabled));
EXPECT_DIF_BADARG(dif_usbdev_endpoint_set_nak_out_enable(
nullptr, /*endpoint=*/0, kDifToggleEnabled));
EXPECT_DIF_BADARG(dif_usbdev_endpoint_stall_enable(nullptr, endpoint_id,
kDifToggleEnabled));
EXPECT_DIF_BADARG(
dif_usbdev_endpoint_stall_get(nullptr, endpoint_id, &bool_arg));
EXPECT_DIF_BADARG(
dif_usbdev_endpoint_stall_get(&usbdev_, endpoint_id, nullptr));
EXPECT_DIF_BADARG(
dif_usbdev_endpoint_iso_enable(nullptr, endpoint_id, kDifToggleEnabled));
EXPECT_DIF_BADARG(
dif_usbdev_endpoint_enable(nullptr, endpoint_id, kDifToggleEnabled));
EXPECT_DIF_BADARG(dif_usbdev_interface_enable(nullptr, kDifToggleEnabled));
EXPECT_DIF_BADARG(dif_usbdev_recv(nullptr, &packet_info, &buffer));
EXPECT_DIF_BADARG(dif_usbdev_recv(&usbdev_, nullptr, &buffer));
EXPECT_DIF_BADARG(dif_usbdev_recv(&usbdev_, &packet_info, nullptr));
EXPECT_DIF_BADARG(dif_usbdev_buffer_read(
nullptr, &buffer_pool, &buffer, &uint8_arg, /*dst_len=*/1, &size_arg));
EXPECT_DIF_BADARG(dif_usbdev_buffer_read(
&usbdev_, nullptr, &buffer, &uint8_arg, /*dst_len=*/1, &size_arg));
EXPECT_DIF_BADARG(dif_usbdev_buffer_read(
&usbdev_, &buffer_pool, nullptr, &uint8_arg, /*dst_len=*/1, &size_arg));
EXPECT_DIF_BADARG(dif_usbdev_buffer_read(&usbdev_, &buffer_pool, &buffer,
nullptr, /*dst_len=*/1, &size_arg));
EXPECT_DIF_BADARG(dif_usbdev_buffer_read(&usbdev_, &buffer_pool, &buffer,
&uint8_arg, /*dst_len=*/1, nullptr));
EXPECT_DIF_BADARG(dif_usbdev_buffer_return(nullptr, &buffer_pool, &buffer));
EXPECT_DIF_BADARG(dif_usbdev_buffer_return(&usbdev_, nullptr, &buffer));
EXPECT_DIF_BADARG(dif_usbdev_buffer_return(&usbdev_, &buffer_pool, nullptr));
EXPECT_DIF_BADARG(dif_usbdev_buffer_request(nullptr, &buffer_pool, &buffer));
EXPECT_DIF_BADARG(dif_usbdev_buffer_request(&usbdev_, nullptr, &buffer));
EXPECT_DIF_BADARG(dif_usbdev_buffer_request(&usbdev_, &buffer_pool, nullptr));
EXPECT_DIF_BADARG(dif_usbdev_buffer_write(nullptr, &buffer, &uint8_arg,
/*src_len=*/1, &size_arg));
EXPECT_DIF_BADARG(dif_usbdev_buffer_write(&usbdev_, nullptr, &uint8_arg,
/*src_len=*/1, &size_arg));
EXPECT_DIF_BADARG(dif_usbdev_buffer_write(&usbdev_, &buffer, nullptr,
/*src_len=*/1, &size_arg));
EXPECT_DIF_BADARG(dif_usbdev_buffer_write(&usbdev_, &buffer, &uint8_arg,
/*src_len=*/1, nullptr));
EXPECT_DIF_BADARG(dif_usbdev_send(nullptr, /*endpoint=*/0, &buffer));
EXPECT_DIF_BADARG(dif_usbdev_send(&usbdev_, /*endpoint=*/0, nullptr));
EXPECT_DIF_BADARG(dif_usbdev_get_tx_sent(nullptr, &uint16_arg));
EXPECT_DIF_BADARG(dif_usbdev_get_tx_sent(&usbdev_, nullptr));
EXPECT_DIF_BADARG(
dif_usbdev_clear_tx_status(nullptr, &buffer_pool, /*endpoint=*/0));
EXPECT_DIF_BADARG(
dif_usbdev_clear_tx_status(&usbdev_, nullptr, /*endpoint=*/0));
EXPECT_DIF_BADARG(
dif_usbdev_get_tx_status(nullptr, /*endpoint=*/0, &tx_status));
EXPECT_DIF_BADARG(
dif_usbdev_get_tx_status(&usbdev_, /*endpoint=*/0, nullptr));
EXPECT_DIF_BADARG(dif_usbdev_address_set(nullptr, /*addr=*/1));
EXPECT_DIF_BADARG(dif_usbdev_address_get(nullptr, &uint8_arg));
EXPECT_DIF_BADARG(dif_usbdev_address_get(&usbdev_, nullptr));
EXPECT_DIF_BADARG(dif_usbdev_clear_data_toggle(nullptr, /*endpoint=*/1));
EXPECT_DIF_BADARG(dif_usbdev_status_get_frame(nullptr, &uint16_arg));
EXPECT_DIF_BADARG(dif_usbdev_status_get_frame(&usbdev_, nullptr));
EXPECT_DIF_BADARG(dif_usbdev_status_get_host_lost(nullptr, &bool_arg));
EXPECT_DIF_BADARG(dif_usbdev_status_get_host_lost(&usbdev_, nullptr));
EXPECT_DIF_BADARG(dif_usbdev_status_get_link_state(nullptr, &link_state));
EXPECT_DIF_BADARG(dif_usbdev_status_get_link_state(&usbdev_, nullptr));
EXPECT_DIF_BADARG(dif_usbdev_status_get_sense(nullptr, &bool_arg));
EXPECT_DIF_BADARG(dif_usbdev_status_get_sense(&usbdev_, nullptr));
EXPECT_DIF_BADARG(
dif_usbdev_status_get_available_fifo_depth(nullptr, &uint8_arg));
EXPECT_DIF_BADARG(
dif_usbdev_status_get_available_fifo_depth(&usbdev_, nullptr));
EXPECT_DIF_BADARG(
dif_usbdev_status_get_available_fifo_full(nullptr, &bool_arg));
EXPECT_DIF_BADARG(
dif_usbdev_status_get_available_fifo_full(&usbdev_, nullptr));
EXPECT_DIF_BADARG(dif_usbdev_status_get_rx_fifo_depth(nullptr, &uint8_arg));
EXPECT_DIF_BADARG(dif_usbdev_status_get_rx_fifo_depth(&usbdev_, nullptr));
EXPECT_DIF_BADARG(dif_usbdev_status_get_rx_fifo_empty(nullptr, &bool_arg));
EXPECT_DIF_BADARG(dif_usbdev_status_get_rx_fifo_empty(&usbdev_, nullptr));
EXPECT_DIF_BADARG(dif_usbdev_set_osc_test_mode(nullptr, kDifToggleEnabled));
EXPECT_DIF_BADARG(dif_usbdev_set_wake_enable(nullptr, kDifToggleEnabled));
EXPECT_DIF_BADARG(dif_usbdev_get_wake_status(nullptr, &wake_status));
EXPECT_DIF_BADARG(dif_usbdev_get_wake_status(&usbdev_, nullptr));
EXPECT_DIF_BADARG(dif_usbdev_resume_link_to_active(nullptr));
EXPECT_DIF_BADARG(dif_usbdev_get_phy_pins_status(nullptr, &phy_pins_status));
EXPECT_DIF_BADARG(dif_usbdev_get_phy_pins_status(&usbdev_, nullptr));
EXPECT_DIF_BADARG(dif_usbdev_set_phy_pins_state(nullptr, kDifToggleEnabled,
phy_pins_drive));
}
TEST_F(UsbdevTest, PhyConfig) {
dif_usbdev_buffer_pool_t buffer_pool;
dif_usbdev_config_t phy_config = {
.have_differential_receiver = kDifToggleEnabled,
.use_tx_d_se0 = kDifToggleDisabled,
.single_bit_eop = kDifToggleDisabled,
.pin_flip = kDifToggleEnabled,
.clock_sync_signals = kDifToggleEnabled,
};
EXPECT_WRITE32(USBDEV_PHY_CONFIG_REG_OFFSET,
{
{USBDEV_PHY_CONFIG_USE_DIFF_RCVR_BIT, 1},
{USBDEV_PHY_CONFIG_TX_USE_D_SE0_BIT, 0},
{USBDEV_PHY_CONFIG_EOP_SINGLE_BIT_BIT, 0},
{USBDEV_PHY_CONFIG_PINFLIP_BIT, 1},
{USBDEV_PHY_CONFIG_USB_REF_DISABLE_BIT, 0},
});
EXPECT_DIF_OK(dif_usbdev_configure(&usbdev_, &buffer_pool, phy_config));
dif_usbdev_phy_pins_sense_t phy_pins_status;
EXPECT_READ32(USBDEV_PHY_PINS_SENSE_REG_OFFSET,
{
{USBDEV_PHY_PINS_SENSE_RX_DP_I_BIT, 1},
{USBDEV_PHY_PINS_SENSE_RX_DN_I_BIT, 0},
{USBDEV_PHY_PINS_SENSE_RX_D_I_BIT, 1},
{USBDEV_PHY_PINS_SENSE_TX_DP_O_BIT, 0},
{USBDEV_PHY_PINS_SENSE_TX_DN_O_BIT, 1},
{USBDEV_PHY_PINS_SENSE_TX_D_O_BIT, 0},
{USBDEV_PHY_PINS_SENSE_TX_SE0_O_BIT, 0},
{USBDEV_PHY_PINS_SENSE_TX_OE_O_BIT, 1},
{USBDEV_PHY_PINS_SENSE_PWR_SENSE_BIT, 1},
});
EXPECT_DIF_OK(dif_usbdev_get_phy_pins_status(&usbdev_, &phy_pins_status));
EXPECT_TRUE(phy_pins_status.rx_dp);
EXPECT_FALSE(phy_pins_status.rx_dn);
EXPECT_TRUE(phy_pins_status.rx_d);
EXPECT_FALSE(phy_pins_status.tx_dp);
EXPECT_TRUE(phy_pins_status.tx_dn);
EXPECT_FALSE(phy_pins_status.tx_d);
EXPECT_FALSE(phy_pins_status.tx_se0);
EXPECT_TRUE(phy_pins_status.output_enable);
EXPECT_TRUE(phy_pins_status.vbus_sense);
dif_usbdev_phy_pins_drive_t overrides = {
.dp = 0,
.dn = 1,
.data = 0,
.se0 = 1,
.output_enable = 1,
.diff_receiver_enable = 0,
.dp_pullup_en = 1,
.dn_pullup_en = 0,
};
EXPECT_WRITE32(
USBDEV_PHY_PINS_DRIVE_REG_OFFSET,
{
{USBDEV_PHY_PINS_DRIVE_DP_O_BIT, overrides.dp},
{USBDEV_PHY_PINS_DRIVE_DN_O_BIT, overrides.dn},
{USBDEV_PHY_PINS_DRIVE_D_O_BIT, overrides.data},
{USBDEV_PHY_PINS_DRIVE_SE0_O_BIT, overrides.se0},
{USBDEV_PHY_PINS_DRIVE_OE_O_BIT, overrides.output_enable},
{USBDEV_PHY_PINS_DRIVE_RX_ENABLE_O_BIT,
overrides.diff_receiver_enable},
{USBDEV_PHY_PINS_DRIVE_DP_PULLUP_EN_O_BIT, overrides.dp_pullup_en},
{USBDEV_PHY_PINS_DRIVE_DN_PULLUP_EN_O_BIT, overrides.dn_pullup_en},
{USBDEV_PHY_PINS_DRIVE_EN_BIT, 1},
});
EXPECT_DIF_OK(
dif_usbdev_set_phy_pins_state(&usbdev_, kDifToggleEnabled, overrides));
EXPECT_WRITE32(USBDEV_PHY_PINS_DRIVE_REG_OFFSET, 0);
EXPECT_DIF_OK(
dif_usbdev_set_phy_pins_state(&usbdev_, kDifToggleDisabled, overrides));
EXPECT_READ32(USBDEV_PHY_CONFIG_REG_OFFSET,
{
{USBDEV_PHY_CONFIG_USE_DIFF_RCVR_BIT, 1},
{USBDEV_PHY_CONFIG_TX_USE_D_SE0_BIT, 0},
{USBDEV_PHY_CONFIG_EOP_SINGLE_BIT_BIT, 0},
{USBDEV_PHY_CONFIG_PINFLIP_BIT, 1},
{USBDEV_PHY_CONFIG_USB_REF_DISABLE_BIT, 0},
{USBDEV_PHY_CONFIG_TX_OSC_TEST_MODE_BIT, 0},
});
EXPECT_WRITE32(USBDEV_PHY_CONFIG_REG_OFFSET,
{
{USBDEV_PHY_CONFIG_USE_DIFF_RCVR_BIT, 1},
{USBDEV_PHY_CONFIG_TX_USE_D_SE0_BIT, 0},
{USBDEV_PHY_CONFIG_EOP_SINGLE_BIT_BIT, 0},
{USBDEV_PHY_CONFIG_PINFLIP_BIT, 1},
{USBDEV_PHY_CONFIG_USB_REF_DISABLE_BIT, 0},
{USBDEV_PHY_CONFIG_TX_OSC_TEST_MODE_BIT, 1},
});
EXPECT_DIF_OK(dif_usbdev_set_osc_test_mode(&usbdev_, kDifToggleEnabled));
EXPECT_READ32(USBDEV_PHY_CONFIG_REG_OFFSET,
{
{USBDEV_PHY_CONFIG_USE_DIFF_RCVR_BIT, 1},
{USBDEV_PHY_CONFIG_TX_USE_D_SE0_BIT, 0},
{USBDEV_PHY_CONFIG_EOP_SINGLE_BIT_BIT, 0},
{USBDEV_PHY_CONFIG_PINFLIP_BIT, 1},
{USBDEV_PHY_CONFIG_USB_REF_DISABLE_BIT, 0},
{USBDEV_PHY_CONFIG_TX_OSC_TEST_MODE_BIT, 1},
});
EXPECT_WRITE32(USBDEV_PHY_CONFIG_REG_OFFSET,
{
{USBDEV_PHY_CONFIG_USE_DIFF_RCVR_BIT, 1},
{USBDEV_PHY_CONFIG_TX_USE_D_SE0_BIT, 0},
{USBDEV_PHY_CONFIG_EOP_SINGLE_BIT_BIT, 0},
{USBDEV_PHY_CONFIG_PINFLIP_BIT, 1},
{USBDEV_PHY_CONFIG_USB_REF_DISABLE_BIT, 0},
{USBDEV_PHY_CONFIG_TX_OSC_TEST_MODE_BIT, 0},
});
EXPECT_DIF_OK(dif_usbdev_set_osc_test_mode(&usbdev_, kDifToggleDisabled));
}
TEST_F(UsbdevTest, ConnectAndConfig) {
// Connect the interface.
EXPECT_READ32(USBDEV_USBCTRL_REG_OFFSET, 0);
EXPECT_WRITE32(USBDEV_USBCTRL_REG_OFFSET, {{USBDEV_USBCTRL_ENABLE_BIT, 1}});
EXPECT_DIF_OK(dif_usbdev_interface_enable(&usbdev_, kDifToggleEnabled));
// Disconnect the interface.
EXPECT_READ32(USBDEV_USBCTRL_REG_OFFSET,
{
{USBDEV_USBCTRL_ENABLE_BIT, 1},
{USBDEV_USBCTRL_DEVICE_ADDRESS_OFFSET, 127},
});
EXPECT_WRITE32(USBDEV_USBCTRL_REG_OFFSET,
{
{USBDEV_USBCTRL_ENABLE_BIT, 0},
{USBDEV_USBCTRL_DEVICE_ADDRESS_OFFSET, 127},
});
EXPECT_DIF_OK(dif_usbdev_interface_enable(&usbdev_, kDifToggleDisabled));
dif_usbdev_endpoint_id_t endpoint = {
.number = 2,
.direction = 1,
};
EXPECT_READ32(USBDEV_EP_IN_ENABLE_REG_OFFSET,
{
{USBDEV_EP_IN_ENABLE_ENABLE_0_BIT, 1},
});
EXPECT_WRITE32(USBDEV_EP_IN_ENABLE_REG_OFFSET,
{
{USBDEV_EP_IN_ENABLE_ENABLE_0_BIT, 1},
{USBDEV_EP_IN_ENABLE_ENABLE_2_BIT, 1},
});
EXPECT_DIF_OK(
dif_usbdev_endpoint_enable(&usbdev_, endpoint, kDifToggleEnabled));
endpoint.number = 6;
endpoint.direction = 0;
EXPECT_READ32(USBDEV_EP_OUT_ENABLE_REG_OFFSET,
{
{USBDEV_EP_OUT_ENABLE_ENABLE_5_BIT, 1},
{USBDEV_EP_OUT_ENABLE_ENABLE_6_BIT, 1},
});
EXPECT_WRITE32(USBDEV_EP_OUT_ENABLE_REG_OFFSET,
{
{USBDEV_EP_OUT_ENABLE_ENABLE_5_BIT, 1},
});
EXPECT_DIF_OK(
dif_usbdev_endpoint_enable(&usbdev_, endpoint, kDifToggleDisabled));
endpoint.number = 11;
endpoint.direction = 0;
EXPECT_READ32(USBDEV_OUT_ISO_REG_OFFSET, {
{USBDEV_OUT_ISO_ISO_5_BIT, 1},
});
EXPECT_WRITE32(USBDEV_OUT_ISO_REG_OFFSET, {
{USBDEV_OUT_ISO_ISO_5_BIT, 1},
{USBDEV_OUT_ISO_ISO_11_BIT, 1},
});
EXPECT_DIF_OK(
dif_usbdev_endpoint_iso_enable(&usbdev_, endpoint, kDifToggleEnabled));
endpoint.number = 7;
endpoint.direction = 1;
EXPECT_READ32(USBDEV_IN_ISO_REG_OFFSET, {
{USBDEV_IN_ISO_ISO_1_BIT, 1},
{USBDEV_IN_ISO_ISO_7_BIT, 1},
});
EXPECT_WRITE32(USBDEV_IN_ISO_REG_OFFSET, {
{USBDEV_IN_ISO_ISO_1_BIT, 1},
});
EXPECT_DIF_OK(
dif_usbdev_endpoint_iso_enable(&usbdev_, endpoint, kDifToggleDisabled));
}
TEST_F(UsbdevTest, OutEndpointConfig) {
EXPECT_READ32(USBDEV_RXENABLE_SETUP_REG_OFFSET,
{
{USBDEV_RXENABLE_SETUP_SETUP_0_BIT, 1},
{USBDEV_RXENABLE_SETUP_SETUP_10_BIT, 1},
{USBDEV_RXENABLE_SETUP_SETUP_11_BIT, 1},
});
EXPECT_WRITE32(USBDEV_RXENABLE_SETUP_REG_OFFSET,
{
{USBDEV_RXENABLE_SETUP_SETUP_0_BIT, 1},
{USBDEV_RXENABLE_SETUP_SETUP_9_BIT, 1},
{USBDEV_RXENABLE_SETUP_SETUP_10_BIT, 1},
{USBDEV_RXENABLE_SETUP_SETUP_11_BIT, 1},
});
EXPECT_DIF_OK(dif_usbdev_endpoint_setup_enable(&usbdev_, /*endpoint=*/9,
kDifToggleEnabled));
EXPECT_READ32(USBDEV_RXENABLE_SETUP_REG_OFFSET,
{
{USBDEV_RXENABLE_SETUP_SETUP_8_BIT, 1},
{USBDEV_RXENABLE_SETUP_SETUP_9_BIT, 1},
{USBDEV_RXENABLE_SETUP_SETUP_10_BIT, 1},
});
EXPECT_WRITE32(USBDEV_RXENABLE_SETUP_REG_OFFSET,
{
{USBDEV_RXENABLE_SETUP_SETUP_8_BIT, 1},
{USBDEV_RXENABLE_SETUP_SETUP_9_BIT, 1},
});
EXPECT_DIF_OK(dif_usbdev_endpoint_setup_enable(&usbdev_, /*endpoint=*/10,
kDifToggleDisabled));
EXPECT_READ32(USBDEV_RXENABLE_OUT_REG_OFFSET,
{
{USBDEV_RXENABLE_OUT_OUT_0_BIT, 1},
{USBDEV_RXENABLE_OUT_OUT_2_BIT, 1},
{USBDEV_RXENABLE_OUT_OUT_9_BIT, 1},
});
EXPECT_WRITE32(USBDEV_RXENABLE_OUT_REG_OFFSET,
{
{USBDEV_RXENABLE_OUT_OUT_0_BIT, 1},
{USBDEV_RXENABLE_OUT_OUT_2_BIT, 1},
{USBDEV_RXENABLE_OUT_OUT_5_BIT, 1},
{USBDEV_RXENABLE_OUT_OUT_9_BIT, 1},
});
EXPECT_DIF_OK(dif_usbdev_endpoint_out_enable(&usbdev_, /*endpoint=*/5,
kDifToggleEnabled));
EXPECT_READ32(USBDEV_RXENABLE_OUT_REG_OFFSET,
{
{USBDEV_RXENABLE_OUT_OUT_1_BIT, 1},
{USBDEV_RXENABLE_OUT_OUT_3_BIT, 1},
{USBDEV_RXENABLE_OUT_OUT_7_BIT, 1},
});
EXPECT_WRITE32(USBDEV_RXENABLE_OUT_REG_OFFSET,
{
{USBDEV_RXENABLE_OUT_OUT_1_BIT, 1},
{USBDEV_RXENABLE_OUT_OUT_7_BIT, 1},
});
EXPECT_DIF_OK(dif_usbdev_endpoint_out_enable(&usbdev_, /*endpoint=*/3,
kDifToggleDisabled));
EXPECT_READ32(USBDEV_SET_NAK_OUT_REG_OFFSET,
{
{USBDEV_SET_NAK_OUT_ENABLE_10_BIT, 1},
});
EXPECT_WRITE32(USBDEV_SET_NAK_OUT_REG_OFFSET,
{
{USBDEV_SET_NAK_OUT_ENABLE_9_BIT, 1},
{USBDEV_SET_NAK_OUT_ENABLE_10_BIT, 1},
});
EXPECT_DIF_OK(dif_usbdev_endpoint_set_nak_out_enable(&usbdev_, /*endpoint=*/9,
kDifToggleEnabled));
EXPECT_READ32(USBDEV_SET_NAK_OUT_REG_OFFSET,
{
{USBDEV_SET_NAK_OUT_ENABLE_8_BIT, 1},
{USBDEV_SET_NAK_OUT_ENABLE_9_BIT, 1},
});
EXPECT_WRITE32(USBDEV_SET_NAK_OUT_REG_OFFSET,
{
{USBDEV_SET_NAK_OUT_ENABLE_9_BIT, 1},
});
EXPECT_DIF_OK(dif_usbdev_endpoint_set_nak_out_enable(&usbdev_, /*endpoint=*/8,
kDifToggleDisabled));
}
TEST_F(UsbdevTest, StallConfig) {
dif_usbdev_endpoint_id_t endpoint = {
.number = 1,
.direction = 1,
};
EXPECT_READ32(USBDEV_IN_STALL_REG_OFFSET,
{
{USBDEV_IN_STALL_ENDPOINT_0_BIT, 1},
});
EXPECT_WRITE32(USBDEV_IN_STALL_REG_OFFSET,
{
{USBDEV_IN_STALL_ENDPOINT_0_BIT, 1},
{USBDEV_IN_STALL_ENDPOINT_1_BIT, 1},
});
EXPECT_DIF_OK(
dif_usbdev_endpoint_stall_enable(&usbdev_, endpoint, kDifToggleEnabled));
endpoint.number = 3;
endpoint.direction = 0;
EXPECT_READ32(USBDEV_OUT_STALL_REG_OFFSET,
{
{USBDEV_OUT_STALL_ENDPOINT_5_BIT, 1},
});
EXPECT_WRITE32(USBDEV_OUT_STALL_REG_OFFSET,
{
{USBDEV_OUT_STALL_ENDPOINT_3_BIT, 1},
{USBDEV_OUT_STALL_ENDPOINT_5_BIT, 1},
});
EXPECT_DIF_OK(
dif_usbdev_endpoint_stall_enable(&usbdev_, endpoint, kDifToggleEnabled));
bool enabled;
endpoint.number = 5;
endpoint.direction = 1;
EXPECT_READ32(USBDEV_IN_STALL_REG_OFFSET,
{
{USBDEV_IN_STALL_ENDPOINT_5_BIT, 1},
});
EXPECT_DIF_OK(dif_usbdev_endpoint_stall_get(&usbdev_, endpoint, &enabled));
EXPECT_TRUE(enabled);
endpoint.number = 11;
endpoint.direction = 0;
EXPECT_READ32(USBDEV_OUT_STALL_REG_OFFSET,
{
{USBDEV_OUT_STALL_ENDPOINT_5_BIT, 1},
{USBDEV_OUT_STALL_ENDPOINT_9_BIT, 1},
{USBDEV_OUT_STALL_ENDPOINT_10_BIT, 1},
});
EXPECT_DIF_OK(dif_usbdev_endpoint_stall_get(&usbdev_, endpoint, &enabled));
EXPECT_FALSE(enabled);
}
TEST_F(UsbdevTest, OutPacket) {
constexpr uint32_t kMaxAvBuffers = 4;
dif_usbdev_buffer_pool_t buffer_pool;
dif_usbdev_config_t phy_config = {
.have_differential_receiver = kDifToggleEnabled,
.use_tx_d_se0 = kDifToggleDisabled,
.single_bit_eop = kDifToggleDisabled,
.pin_flip = kDifToggleDisabled,
.clock_sync_signals = kDifToggleEnabled,
};
EXPECT_WRITE32(USBDEV_PHY_CONFIG_REG_OFFSET,
{
{USBDEV_PHY_CONFIG_USE_DIFF_RCVR_BIT, 1},
{USBDEV_PHY_CONFIG_TX_USE_D_SE0_BIT, 0},
{USBDEV_PHY_CONFIG_EOP_SINGLE_BIT_BIT, 0},
{USBDEV_PHY_CONFIG_PINFLIP_BIT, 0},
{USBDEV_PHY_CONFIG_USB_REF_DISABLE_BIT, 0},
});
EXPECT_DIF_OK(dif_usbdev_configure(&usbdev_, &buffer_pool, phy_config));
// Add buffers to the AV FIFO to receive.
for (uint32_t i = 0; i < kMaxAvBuffers; i++) {
int top = buffer_pool.top;
EXPECT_READ32(USBDEV_USBSTAT_REG_OFFSET,
{
{USBDEV_USBSTAT_FRAME_OFFSET, 10},
{USBDEV_USBSTAT_LINK_STATE_OFFSET,
USBDEV_USBSTAT_LINK_STATE_VALUE_ACTIVE},
{USBDEV_USBSTAT_SENSE_BIT, 1},
{USBDEV_USBSTAT_AV_DEPTH_OFFSET, i},
{USBDEV_USBSTAT_AV_FULL_BIT, 0},
});
EXPECT_WRITE32(
USBDEV_AVBUFFER_REG_OFFSET,
{{USBDEV_AVBUFFER_BUFFER_OFFSET, buffer_pool.buffers[top - i]}});
}
EXPECT_READ32(USBDEV_USBSTAT_REG_OFFSET,
{
{USBDEV_USBSTAT_FRAME_OFFSET, 10},
{USBDEV_USBSTAT_LINK_STATE_OFFSET,
USBDEV_USBSTAT_LINK_STATE_VALUE_ACTIVE},
{USBDEV_USBSTAT_SENSE_BIT, 1},
{USBDEV_USBSTAT_AV_DEPTH_OFFSET, kMaxAvBuffers},
{USBDEV_USBSTAT_AV_FULL_BIT, 1},
});
EXPECT_DIF_OK(dif_usbdev_fill_available_fifo(&usbdev_, &buffer_pool));
// No read data available yet.
dif_usbdev_rx_packet_info_t rx_packet_info;
dif_usbdev_buffer_t buffer;
EXPECT_READ32(USBDEV_USBSTAT_REG_OFFSET,
{
{USBDEV_USBSTAT_FRAME_OFFSET, 15},
{USBDEV_USBSTAT_LINK_STATE_OFFSET,
USBDEV_USBSTAT_LINK_STATE_VALUE_ACTIVE},
{USBDEV_USBSTAT_SENSE_BIT, 1},
{USBDEV_USBSTAT_AV_DEPTH_OFFSET, kMaxAvBuffers},
{USBDEV_USBSTAT_AV_FULL_BIT, 1},
{USBDEV_USBSTAT_RX_EMPTY_BIT, 1},
});
EXPECT_EQ(dif_usbdev_recv(&usbdev_, &rx_packet_info, &buffer),
kDifUnavailable);
// Receive OUT packet all at once.
uint32_t expected_data[4], recvd_data[4];
for (size_t i = 0; i < sizeof(expected_data) / sizeof(expected_data[0]);
i++) {
expected_data[i] = i * 1023;
}
EXPECT_READ32(USBDEV_USBSTAT_REG_OFFSET,
{
{USBDEV_USBSTAT_FRAME_OFFSET, 15},
{USBDEV_USBSTAT_LINK_STATE_OFFSET,
USBDEV_USBSTAT_LINK_STATE_VALUE_ACTIVE},
{USBDEV_USBSTAT_SENSE_BIT, 1},
{USBDEV_USBSTAT_AV_DEPTH_OFFSET, kMaxAvBuffers - 1},
{USBDEV_USBSTAT_AV_FULL_BIT, 0},
{USBDEV_USBSTAT_RX_EMPTY_BIT, 0},
});
EXPECT_READ32(USBDEV_RXFIFO_REG_OFFSET,
{
{USBDEV_RXFIFO_EP_OFFSET, 1},
{USBDEV_RXFIFO_SETUP_BIT, 0},
{USBDEV_RXFIFO_SIZE_OFFSET, sizeof(expected_data)},
{USBDEV_RXFIFO_BUFFER_OFFSET, 0},
});
EXPECT_DIF_OK(dif_usbdev_recv(&usbdev_, &rx_packet_info, &buffer));
EXPECT_EQ(rx_packet_info.endpoint, 1);
EXPECT_EQ(rx_packet_info.length, sizeof(expected_data));
EXPECT_FALSE(rx_packet_info.is_setup);
EXPECT_EQ(buffer.id, 0);
EXPECT_EQ(buffer.offset, 0);
EXPECT_EQ(buffer.remaining_bytes, sizeof(expected_data));
EXPECT_EQ(buffer.type, kDifUsbdevBufferTypeRead);
size_t bytes_written;
for (size_t i = 0; i < sizeof(expected_data) / sizeof(expected_data[0]);
i++) {
EXPECT_READ32(USBDEV_BUFFER_REG_OFFSET + buffer.id * 64 + 4 * i,
expected_data[i]);
}
EXPECT_DIF_OK(dif_usbdev_buffer_read(&usbdev_, &buffer_pool, &buffer,
reinterpret_cast<uint8_t *>(recvd_data),
sizeof(recvd_data), &bytes_written));
EXPECT_EQ(bytes_written, sizeof(recvd_data));
EXPECT_EQ(memcmp(expected_data, recvd_data, sizeof(expected_data)), 0);
// One more received packet to test other offsets.
EXPECT_READ32(USBDEV_USBSTAT_REG_OFFSET,
{
{USBDEV_USBSTAT_FRAME_OFFSET, 25},
{USBDEV_USBSTAT_LINK_STATE_OFFSET,
USBDEV_USBSTAT_LINK_STATE_VALUE_ACTIVE},
{USBDEV_USBSTAT_SENSE_BIT, 1},
{USBDEV_USBSTAT_AV_DEPTH_OFFSET, kMaxAvBuffers - 2},
{USBDEV_USBSTAT_AV_FULL_BIT, 1},
{USBDEV_USBSTAT_RX_EMPTY_BIT, 0},
});
EXPECT_READ32(USBDEV_RXFIFO_REG_OFFSET,
{
{USBDEV_RXFIFO_EP_OFFSET, 0},
{USBDEV_RXFIFO_SETUP_BIT, 1},
{USBDEV_RXFIFO_SIZE_OFFSET, sizeof(expected_data) - 1},
{USBDEV_RXFIFO_BUFFER_OFFSET, 1},
});
EXPECT_DIF_OK(dif_usbdev_recv(&usbdev_, &rx_packet_info, &buffer));
EXPECT_EQ(rx_packet_info.endpoint, 0);
EXPECT_EQ(rx_packet_info.length, sizeof(expected_data) - 1);
EXPECT_TRUE(rx_packet_info.is_setup);
EXPECT_EQ(buffer.id, 1);
EXPECT_EQ(buffer.offset, 0);
EXPECT_EQ(buffer.remaining_bytes, sizeof(expected_data) - 1);
EXPECT_EQ(buffer.type, kDifUsbdevBufferTypeRead);
memset(recvd_data, 0, sizeof(recvd_data));
for (size_t i = 0; i < sizeof(expected_data) / sizeof(expected_data[0]);
i++) {
EXPECT_READ32(USBDEV_BUFFER_REG_OFFSET + buffer.id * 64 + 4 * i,
expected_data[i]);
}
EXPECT_DIF_OK(dif_usbdev_buffer_read(&usbdev_, &buffer_pool, &buffer,
reinterpret_cast<uint8_t *>(recvd_data),
4, &bytes_written));
EXPECT_EQ(bytes_written, 4);
EXPECT_DIF_OK(dif_usbdev_buffer_read(
&usbdev_, &buffer_pool, &buffer,
reinterpret_cast<uint8_t *>(recvd_data) + bytes_written,
sizeof(recvd_data) - bytes_written, &bytes_written));
EXPECT_EQ(bytes_written, sizeof(recvd_data) - 4 - 1);
EXPECT_EQ(memcmp(expected_data, recvd_data, sizeof(expected_data)), 0);
}
TEST_F(UsbdevTest, InPacket) {
dif_usbdev_buffer_pool_t buffer_pool;
dif_usbdev_config_t phy_config = {
.have_differential_receiver = kDifToggleEnabled,
.use_tx_d_se0 = kDifToggleDisabled,
.single_bit_eop = kDifToggleDisabled,
.pin_flip = kDifToggleDisabled,
.clock_sync_signals = kDifToggleEnabled,
};
EXPECT_WRITE32(USBDEV_PHY_CONFIG_REG_OFFSET,
{
{USBDEV_PHY_CONFIG_USE_DIFF_RCVR_BIT, 1},
{USBDEV_PHY_CONFIG_TX_USE_D_SE0_BIT, 0},
{USBDEV_PHY_CONFIG_EOP_SINGLE_BIT_BIT, 0},
{USBDEV_PHY_CONFIG_PINFLIP_BIT, 0},
{USBDEV_PHY_CONFIG_USB_REF_DISABLE_BIT, 0},
});
EXPECT_DIF_OK(dif_usbdev_configure(&usbdev_, &buffer_pool, phy_config));
dif_usbdev_buffer_t buffer;
EXPECT_DIF_OK(dif_usbdev_buffer_request(&usbdev_, &buffer_pool, &buffer));
EXPECT_EQ(buffer.type, kDifUsbdevBufferTypeWrite);
uint32_t data[16];
uint8_t *bytes = reinterpret_cast<uint8_t *>(data);
size_t bytes_written;
EXPECT_DIF_OK(dif_usbdev_buffer_return(&usbdev_, &buffer_pool, &buffer));
EXPECT_EQ(buffer.type, kDifUsbdevBufferTypeStale);
// Can't return a stale buffer.
EXPECT_DIF_BADARG(dif_usbdev_buffer_return(&usbdev_, &buffer_pool, &buffer));
// Can't submit a stale buffer.
EXPECT_DIF_BADARG(dif_usbdev_buffer_write(&usbdev_, &buffer, bytes,
sizeof(data), &bytes_written));
// Request the buffer.
EXPECT_DIF_OK(dif_usbdev_buffer_request(&usbdev_, &buffer_pool, &buffer));
for (size_t i = 0; i < sizeof(data); i++) {
bytes[i] = i;
if (i % 4 == 3) {
EXPECT_WRITE32(USBDEV_BUFFER_REG_OFFSET + buffer.id * 64 + i - 3,
data[i / 4]);
}
}
EXPECT_DIF_OK(dif_usbdev_buffer_write(&usbdev_, &buffer, bytes, sizeof(data),
&bytes_written));
EXPECT_EQ(bytes_written, sizeof(data));
// Queue up the buffer for transmission.
EXPECT_WRITE32(USBDEV_CONFIGIN_5_REG_OFFSET,
{
{USBDEV_CONFIGIN_5_BUFFER_5_OFFSET, buffer.id},
{USBDEV_CONFIGIN_5_SIZE_5_OFFSET, bytes_written},
});
EXPECT_WRITE32(USBDEV_CONFIGIN_5_REG_OFFSET,
{
{USBDEV_CONFIGIN_5_BUFFER_5_OFFSET, buffer.id},
{USBDEV_CONFIGIN_5_SIZE_5_OFFSET, bytes_written},
{USBDEV_CONFIGIN_5_RDY_5_BIT, 1},
});
EXPECT_DIF_OK(dif_usbdev_send(&usbdev_, /*endpoint=*/5, &buffer));
// Get TX status for a buffer with a transmission that had to be canceled. The
// buffer is returned to the free pool.
dif_usbdev_tx_status_t tx_status;
EXPECT_READ32(USBDEV_CONFIGIN_0_REG_OFFSET,
{
{USBDEV_CONFIGIN_0_BUFFER_0_OFFSET, buffer.id},
{USBDEV_CONFIGIN_0_SIZE_0_OFFSET, sizeof(data)},
{USBDEV_CONFIGIN_0_RDY_0_BIT, 0},
{USBDEV_CONFIGIN_0_PEND_0_BIT, 1},
});
EXPECT_READ32(USBDEV_IN_SENT_REG_OFFSET, {
{USBDEV_IN_SENT_SENT_0_BIT, 0},
});
EXPECT_DIF_OK(dif_usbdev_get_tx_status(&usbdev_, /*endpoint=*/0, &tx_status));
EXPECT_EQ(tx_status, kDifUsbdevTxStatusCancelled);
EXPECT_READ32(USBDEV_CONFIGIN_0_REG_OFFSET,
{
{USBDEV_CONFIGIN_0_BUFFER_0_OFFSET, buffer.id},
{USBDEV_CONFIGIN_0_SIZE_0_OFFSET, sizeof(data)},
{USBDEV_CONFIGIN_0_RDY_0_BIT, 0},
{USBDEV_CONFIGIN_0_PEND_0_BIT, 1},
});
EXPECT_WRITE32(USBDEV_CONFIGIN_0_REG_OFFSET,
{{USBDEV_CONFIGIN_0_PEND_0_BIT, 1}});
EXPECT_WRITE32(USBDEV_IN_SENT_REG_OFFSET, {{USBDEV_IN_SENT_SENT_0_BIT, 1}});
EXPECT_DIF_OK(
dif_usbdev_clear_tx_status(&usbdev_, &buffer_pool, /*endpoint=*/0));
// Request a new buffer.
EXPECT_DIF_OK(dif_usbdev_buffer_request(&usbdev_, &buffer_pool, &buffer));
for (size_t i = 0; i < sizeof(data); i++) {
bytes[i] = i;
if (i % 4 == 3) {
EXPECT_WRITE32(USBDEV_BUFFER_REG_OFFSET + buffer.id * 64 + i - 3,
data[i / 4]);
}
}
EXPECT_DIF_OK(dif_usbdev_buffer_write(&usbdev_, &buffer, bytes, sizeof(data),
&bytes_written));
// Queue the buffer for transmission.
EXPECT_WRITE32(USBDEV_CONFIGIN_4_REG_OFFSET,
{
{USBDEV_CONFIGIN_4_BUFFER_4_OFFSET, buffer.id},
{USBDEV_CONFIGIN_4_SIZE_4_OFFSET, sizeof(data)},
});
EXPECT_WRITE32(USBDEV_CONFIGIN_4_REG_OFFSET,
{
{USBDEV_CONFIGIN_4_BUFFER_4_OFFSET, buffer.id},
{USBDEV_CONFIGIN_4_SIZE_4_OFFSET, sizeof(data)},
{USBDEV_CONFIGIN_4_RDY_4_BIT, 1},
});
EXPECT_DIF_OK(dif_usbdev_send(&usbdev_, /*endpoint=*/4, &buffer));
// Get status of an endpoint without a buffer queued for transmission.
EXPECT_READ32(USBDEV_CONFIGIN_7_REG_OFFSET,
{
{USBDEV_CONFIGIN_7_BUFFER_7_OFFSET, buffer.id},
{USBDEV_CONFIGIN_7_SIZE_7_OFFSET, sizeof(data)},
{USBDEV_CONFIGIN_7_RDY_7_BIT, 0},
});
EXPECT_READ32(USBDEV_IN_SENT_REG_OFFSET, {
{USBDEV_IN_SENT_SENT_7_BIT, 0},
});
EXPECT_DIF_OK(dif_usbdev_get_tx_status(&usbdev_, /*endpoint=*/7, &tx_status));
EXPECT_EQ(tx_status, kDifUsbdevTxStatusNoPacket);
// Get TX status for a queued, but not sent buffer.
EXPECT_READ32(USBDEV_CONFIGIN_8_REG_OFFSET,
{
{USBDEV_CONFIGIN_8_BUFFER_8_OFFSET, buffer.id},
{USBDEV_CONFIGIN_8_SIZE_8_OFFSET, sizeof(data)},
{USBDEV_CONFIGIN_8_RDY_8_BIT, 1},
});
EXPECT_DIF_OK(dif_usbdev_get_tx_status(&usbdev_, /*endpoint=*/8, &tx_status));
EXPECT_EQ(tx_status, kDifUsbdevTxStatusPending);
// Buffer was transmitted successfully.
uint16_t endpoints_done;
EXPECT_READ32(USBDEV_IN_SENT_REG_OFFSET, {
{USBDEV_IN_SENT_SENT_3_BIT, 1},
{USBDEV_IN_SENT_SENT_5_BIT, 1},
});
EXPECT_DIF_OK(dif_usbdev_get_tx_sent(&usbdev_, &endpoints_done));
EXPECT_EQ(endpoints_done, (1u << 3) | (1u << 5));
EXPECT_READ32(USBDEV_CONFIGIN_5_REG_OFFSET,
{
{USBDEV_CONFIGIN_5_BUFFER_5_OFFSET, buffer.id},
{USBDEV_CONFIGIN_5_SIZE_5_OFFSET, sizeof(data)},
{USBDEV_CONFIGIN_5_RDY_5_BIT, 0},
});
EXPECT_READ32(USBDEV_IN_SENT_REG_OFFSET, {
{USBDEV_IN_SENT_SENT_3_BIT, 1},
{USBDEV_IN_SENT_SENT_5_BIT, 1},
});
EXPECT_DIF_OK(dif_usbdev_get_tx_status(&usbdev_, /*endpoint=*/5, &tx_status));
EXPECT_EQ(tx_status, kDifUsbdevTxStatusSent);
EXPECT_EQ(buffer.type, kDifUsbdevBufferTypeStale);
EXPECT_READ32(USBDEV_CONFIGIN_5_REG_OFFSET,
{
{USBDEV_CONFIGIN_5_BUFFER_5_OFFSET, buffer.id},
{USBDEV_CONFIGIN_5_SIZE_5_OFFSET, sizeof(data)},
{USBDEV_CONFIGIN_5_RDY_5_BIT, 0},
});
EXPECT_WRITE32(USBDEV_CONFIGIN_5_REG_OFFSET,
{{USBDEV_CONFIGIN_5_PEND_5_BIT, 1}});
EXPECT_WRITE32(USBDEV_IN_SENT_REG_OFFSET, {{USBDEV_IN_SENT_SENT_5_BIT, 1}});
EXPECT_DIF_OK(
dif_usbdev_clear_tx_status(&usbdev_, &buffer_pool, /*endpoint=*/5));
}
TEST_F(UsbdevTest, DeviceAddresses) {
uint8_t address = 101;
EXPECT_READ32(USBDEV_USBCTRL_REG_OFFSET,
{
{USBDEV_USBCTRL_ENABLE_BIT, 1},
{USBDEV_USBCTRL_DEVICE_ADDRESS_OFFSET, 0},
});
EXPECT_WRITE32(USBDEV_USBCTRL_REG_OFFSET,
{
{USBDEV_USBCTRL_ENABLE_BIT, 1},
{USBDEV_USBCTRL_DEVICE_ADDRESS_OFFSET, address},
});
EXPECT_DIF_OK(dif_usbdev_address_set(&usbdev_, address));
EXPECT_READ32(USBDEV_USBCTRL_REG_OFFSET,
{
{USBDEV_USBCTRL_ENABLE_BIT, 1},
{USBDEV_USBCTRL_DEVICE_ADDRESS_OFFSET, 58},
});
EXPECT_DIF_OK(dif_usbdev_address_get(&usbdev_, &address));
EXPECT_EQ(address, 58);
}
TEST_F(UsbdevTest, Status) {
EXPECT_WRITE32(USBDEV_DATA_TOGGLE_CLEAR_REG_OFFSET,
{{USBDEV_DATA_TOGGLE_CLEAR_CLEAR_3_BIT, 1}});
EXPECT_DIF_OK(dif_usbdev_clear_data_toggle(&usbdev_, /*endpoint=*/3));
EXPECT_WRITE32(USBDEV_DATA_TOGGLE_CLEAR_REG_OFFSET,
{{USBDEV_DATA_TOGGLE_CLEAR_CLEAR_9_BIT, 1}});
EXPECT_DIF_OK(dif_usbdev_clear_data_toggle(&usbdev_, /*endpoint=*/9));
uint16_t frame;
EXPECT_READ32(USBDEV_USBSTAT_REG_OFFSET,
{
{USBDEV_USBSTAT_FRAME_OFFSET, 92},
{USBDEV_USBSTAT_SENSE_BIT, 1},
{USBDEV_USBSTAT_LINK_STATE_OFFSET,
USBDEV_USBSTAT_LINK_STATE_VALUE_ACTIVE},
{USBDEV_USBSTAT_AV_DEPTH_OFFSET, 2},
});
EXPECT_DIF_OK(dif_usbdev_status_get_frame(&usbdev_, &frame));
EXPECT_EQ(frame, 92);
bool host_lost;
EXPECT_READ32(USBDEV_USBSTAT_REG_OFFSET,
{
{USBDEV_USBSTAT_FRAME_OFFSET, 18},
{USBDEV_USBSTAT_SENSE_BIT, 1},
{USBDEV_USBSTAT_LINK_STATE_OFFSET,
USBDEV_USBSTAT_LINK_STATE_VALUE_ACTIVE_NOSOF},
{USBDEV_USBSTAT_AV_DEPTH_OFFSET, 2},
{USBDEV_USBSTAT_HOST_LOST_BIT, 1},
});
EXPECT_DIF_OK(dif_usbdev_status_get_host_lost(&usbdev_, &host_lost));
EXPECT_TRUE(host_lost);
EXPECT_READ32(USBDEV_USBSTAT_REG_OFFSET,
{
{USBDEV_USBSTAT_FRAME_OFFSET, 18},
{USBDEV_USBSTAT_LINK_STATE_OFFSET,
USBDEV_USBSTAT_LINK_STATE_VALUE_ACTIVE_NOSOF},
{USBDEV_USBSTAT_SENSE_BIT, 1},
{USBDEV_USBSTAT_AV_DEPTH_OFFSET, 2},
{USBDEV_USBSTAT_HOST_LOST_BIT, 0},
});
EXPECT_DIF_OK(dif_usbdev_status_get_host_lost(&usbdev_, &host_lost));
EXPECT_FALSE(host_lost);
bool vbus_sense;
EXPECT_READ32(USBDEV_USBSTAT_REG_OFFSET,
{
{USBDEV_USBSTAT_FRAME_OFFSET, 31},
{USBDEV_USBSTAT_LINK_STATE_OFFSET,
USBDEV_USBSTAT_LINK_STATE_VALUE_ACTIVE_NOSOF},
{USBDEV_USBSTAT_SENSE_BIT, 1},
});
EXPECT_DIF_OK(dif_usbdev_status_get_sense(&usbdev_, &vbus_sense));
EXPECT_TRUE(vbus_sense);
EXPECT_READ32(USBDEV_USBSTAT_REG_OFFSET,
{
{USBDEV_USBSTAT_FRAME_OFFSET, 31},
{USBDEV_USBSTAT_LINK_STATE_OFFSET,
USBDEV_USBSTAT_LINK_STATE_VALUE_DISCONNECTED},
{USBDEV_USBSTAT_SENSE_BIT, 0},
});
EXPECT_DIF_OK(dif_usbdev_status_get_sense(&usbdev_, &vbus_sense));
EXPECT_FALSE(vbus_sense);
uint8_t av_fifo_depth;
EXPECT_READ32(USBDEV_USBSTAT_REG_OFFSET,
{
{USBDEV_USBSTAT_FRAME_OFFSET, 11},
{USBDEV_USBSTAT_LINK_STATE_OFFSET,
USBDEV_USBSTAT_LINK_STATE_VALUE_ACTIVE},
{USBDEV_USBSTAT_SENSE_BIT, 1},
{USBDEV_USBSTAT_AV_DEPTH_OFFSET, 3},
{USBDEV_USBSTAT_RX_EMPTY_BIT, 1},
});
EXPECT_DIF_OK(
dif_usbdev_status_get_available_fifo_depth(&usbdev_, &av_fifo_depth));
EXPECT_EQ(av_fifo_depth, 3);
bool av_fifo_full;
EXPECT_READ32(USBDEV_USBSTAT_REG_OFFSET,
{
{USBDEV_USBSTAT_FRAME_OFFSET, 12},
{USBDEV_USBSTAT_LINK_STATE_OFFSET,
USBDEV_USBSTAT_LINK_STATE_VALUE_ACTIVE},
{USBDEV_USBSTAT_SENSE_BIT, 1},
{USBDEV_USBSTAT_AV_DEPTH_OFFSET, 4},
{USBDEV_USBSTAT_AV_FULL_BIT, 1},
{USBDEV_USBSTAT_RX_EMPTY_BIT, 1},
});
EXPECT_DIF_OK(
dif_usbdev_status_get_available_fifo_full(&usbdev_, &av_fifo_full));
EXPECT_TRUE(av_fifo_full);
uint8_t rx_fifo_depth;
EXPECT_READ32(USBDEV_USBSTAT_REG_OFFSET,
{
{USBDEV_USBSTAT_FRAME_OFFSET, 12},
{USBDEV_USBSTAT_LINK_STATE_OFFSET,
USBDEV_USBSTAT_LINK_STATE_VALUE_ACTIVE},
{USBDEV_USBSTAT_SENSE_BIT, 1},
{USBDEV_USBSTAT_AV_DEPTH_OFFSET, 4},
{USBDEV_USBSTAT_AV_FULL_BIT, 1},
{USBDEV_USBSTAT_RX_EMPTY_BIT, 0},
{USBDEV_USBSTAT_RX_DEPTH_OFFSET, 2},
});
EXPECT_DIF_OK(dif_usbdev_status_get_rx_fifo_depth(&usbdev_, &rx_fifo_depth));
EXPECT_EQ(rx_fifo_depth, 2);
bool rx_fifo_empty;
EXPECT_READ32(USBDEV_USBSTAT_REG_OFFSET,
{
{USBDEV_USBSTAT_FRAME_OFFSET, 12},
{USBDEV_USBSTAT_LINK_STATE_OFFSET,
USBDEV_USBSTAT_LINK_STATE_VALUE_ACTIVE},
{USBDEV_USBSTAT_SENSE_BIT, 1},
{USBDEV_USBSTAT_AV_DEPTH_OFFSET, 4},
{USBDEV_USBSTAT_AV_FULL_BIT, 1},
{USBDEV_USBSTAT_RX_EMPTY_BIT, 1},
});
EXPECT_DIF_OK(dif_usbdev_status_get_rx_fifo_empty(&usbdev_, &rx_fifo_empty));
EXPECT_TRUE(rx_fifo_empty);
}
TEST_F(UsbdevTest, LinkState) {
dif_usbdev_link_state_t link_state;
EXPECT_READ32(USBDEV_USBSTAT_REG_OFFSET,
{
{USBDEV_USBSTAT_FRAME_OFFSET, 27},
{USBDEV_USBSTAT_SENSE_BIT, 1},
{USBDEV_USBSTAT_LINK_STATE_OFFSET,
USBDEV_USBSTAT_LINK_STATE_VALUE_ACTIVE},
{USBDEV_USBSTAT_AV_DEPTH_OFFSET, 2},
});
EXPECT_DIF_OK(dif_usbdev_status_get_link_state(&usbdev_, &link_state));
EXPECT_EQ(link_state, kDifUsbdevLinkStateActive);
EXPECT_READ32(USBDEV_USBSTAT_REG_OFFSET,
{
{USBDEV_USBSTAT_LINK_STATE_OFFSET,
USBDEV_USBSTAT_LINK_STATE_VALUE_DISCONNECTED},
});
EXPECT_DIF_OK(dif_usbdev_status_get_link_state(&usbdev_, &link_state));
EXPECT_EQ(link_state, kDifUsbdevLinkStateDisconnected);
EXPECT_READ32(USBDEV_USBSTAT_REG_OFFSET,
{
{USBDEV_USBSTAT_SENSE_BIT, 1},
{USBDEV_USBSTAT_LINK_STATE_OFFSET,
USBDEV_USBSTAT_LINK_STATE_VALUE_POWERED},
});
EXPECT_DIF_OK(dif_usbdev_status_get_link_state(&usbdev_, &link_state));
EXPECT_EQ(link_state, kDifUsbdevLinkStatePowered);
EXPECT_READ32(USBDEV_USBSTAT_REG_OFFSET,
{
{USBDEV_USBSTAT_SENSE_BIT, 1},
{USBDEV_USBSTAT_LINK_STATE_OFFSET,
USBDEV_USBSTAT_LINK_STATE_VALUE_POWERED_SUSPENDED},
});
EXPECT_DIF_OK(dif_usbdev_status_get_link_state(&usbdev_, &link_state));
EXPECT_EQ(link_state, kDifUsbdevLinkStatePoweredSuspended);
EXPECT_READ32(USBDEV_USBSTAT_REG_OFFSET,
{
{USBDEV_USBSTAT_SENSE_BIT, 1},
{USBDEV_USBSTAT_LINK_STATE_OFFSET,
USBDEV_USBSTAT_LINK_STATE_VALUE_SUSPENDED},
});
EXPECT_DIF_OK(dif_usbdev_status_get_link_state(&usbdev_, &link_state));
EXPECT_EQ(link_state, kDifUsbdevLinkStateSuspended);
EXPECT_READ32(USBDEV_USBSTAT_REG_OFFSET,
{
{USBDEV_USBSTAT_SENSE_BIT, 1},
{USBDEV_USBSTAT_LINK_STATE_OFFSET,
USBDEV_USBSTAT_LINK_STATE_VALUE_ACTIVE_NOSOF},
});
EXPECT_DIF_OK(dif_usbdev_status_get_link_state(&usbdev_, &link_state));
EXPECT_EQ(link_state, kDifUsbdevLinkStateActiveNoSof);
EXPECT_READ32(USBDEV_USBSTAT_REG_OFFSET,
{
{USBDEV_USBSTAT_SENSE_BIT, 1},
{USBDEV_USBSTAT_LINK_STATE_OFFSET,
USBDEV_USBSTAT_LINK_STATE_VALUE_RESUMING},
});
EXPECT_DIF_OK(dif_usbdev_status_get_link_state(&usbdev_, &link_state));
EXPECT_EQ(link_state, kDifUsbdevLinkStateResuming);
}
TEST_F(UsbdevTest, WakeFromSleep) {
EXPECT_WRITE32(USBDEV_WAKE_CONTROL_REG_OFFSET,
{{USBDEV_WAKE_CONTROL_SUSPEND_REQ_BIT, 1}});
EXPECT_DIF_OK(dif_usbdev_set_wake_enable(&usbdev_, kDifToggleEnabled));
dif_usbdev_wake_status_t wake_status;
EXPECT_READ32(USBDEV_WAKE_EVENTS_REG_OFFSET,
{
{USBDEV_WAKE_EVENTS_MODULE_ACTIVE_BIT, 1},
{USBDEV_WAKE_EVENTS_DISCONNECTED_BIT, 0},
{USBDEV_WAKE_EVENTS_BUS_RESET_BIT, 1},
});
EXPECT_DIF_OK(dif_usbdev_get_wake_status(&usbdev_, &wake_status));
EXPECT_TRUE(wake_status.active);
EXPECT_FALSE(wake_status.disconnected);
EXPECT_TRUE(wake_status.bus_reset);
EXPECT_READ32(USBDEV_USBCTRL_REG_OFFSET,
{
{USBDEV_USBCTRL_ENABLE_BIT, 1},
{USBDEV_USBCTRL_DEVICE_ADDRESS_OFFSET, 88},
{USBDEV_USBCTRL_RESUME_LINK_ACTIVE_BIT, 0},
});
EXPECT_WRITE32(USBDEV_USBCTRL_REG_OFFSET,
{
{USBDEV_USBCTRL_ENABLE_BIT, 1},
{USBDEV_USBCTRL_DEVICE_ADDRESS_OFFSET, 88},
{USBDEV_USBCTRL_RESUME_LINK_ACTIVE_BIT, 1},
});
EXPECT_DIF_OK(dif_usbdev_resume_link_to_active(&usbdev_));
EXPECT_WRITE32(USBDEV_WAKE_CONTROL_REG_OFFSET,
{{USBDEV_WAKE_CONTROL_WAKE_ACK_BIT, 1}});
EXPECT_DIF_OK(dif_usbdev_set_wake_enable(&usbdev_, kDifToggleDisabled));
}
} // namespace
} // namespace dif_usbdev_unittest