Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[rtl872x] hal: make USB CDC a bit quicker by scheduling TX from timer callback delayed by 1ms #2672

Merged
merged 1 commit into from
Aug 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions hal/inc/hal_platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,10 @@
#define HAL_PLATFORM_USB_CDC_TX_FAIL_TIMEOUT_MS (2500)
#endif // HAL_PLATFORM_USB_CDC_TX_FAIL_TIMEOUT_MS

#ifndef HAL_PLATFORM_USB_CDC_TX_PERIOD_MS
#define HAL_PLATFORM_USB_CDC_TX_PERIOD_MS (1)
#endif // HAL_PLATFORM_USB_CDC_TX_PERIOD_MS

#ifndef HAL_PLATFORM_USB_HID
#define HAL_PLATFORM_USB_HID (0)
#endif // HAL_PLATFORM_USB_HID
Expand Down
57 changes: 45 additions & 12 deletions hal/src/rtl872x/usbd_cdc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,20 @@ const uint8_t DUMMY_IN_EP = 0x8a;
CdcClassDriver::CdcClassDriver()
: ClassDriver() {
#if !HAL_PLATFORM_USB_SOF
os_timer_create(&txTimer_, HAL_PLATFORM_USB_CDC_TX_FAIL_TIMEOUT_MS, txTimerCallback, this, true /* oneshot */, nullptr);
os_timer_create(&txTimeoutTimer_, HAL_PLATFORM_USB_CDC_TX_FAIL_TIMEOUT_MS, txTimeoutTimerCallback, this, true /* oneshot */, nullptr);
SPARK_ASSERT(txTimeoutTimer_);
os_timer_create(&txTimer_, HAL_PLATFORM_USB_CDC_TX_PERIOD_MS, txTimerCallback, this, true /* oneshot */, nullptr);
SPARK_ASSERT(txTimer_);
#endif // !HAL_PLATFORM_USB_SOF
}

CdcClassDriver::~CdcClassDriver() {
setName(nullptr);
#if !HAL_PLATFORM_USB_SOF
if (txTimeoutTimer_) {
os_timer_destroy(txTimeoutTimer_, nullptr);
txTimeoutTimer_ = nullptr;
}
if (txTimer_) {
os_timer_destroy(txTimer_, nullptr);
txTimer_ = nullptr;
Expand Down Expand Up @@ -79,6 +85,7 @@ int CdcClassDriver::deinit(unsigned cfgIdx) {
}
}
#if !HAL_PLATFORM_USB_SOF
stopTxTimeoutTimer();
stopTxTimer();
#endif // !HAL_PLATFORM_USB_SOF

Expand Down Expand Up @@ -106,7 +113,7 @@ void CdcClassDriver::setOpenState(bool state) {
if (state != open_) {
if (state) {
#if !HAL_PLATFORM_USB_SOF
stopTxTimer();
stopTxTimeoutTimer();
#endif // !HAL_PLATFORM_USB_SOF
txState_ = false;
txBuffer_.reset();
Expand Down Expand Up @@ -216,7 +223,7 @@ int CdcClassDriver::dataIn(unsigned ep, particle::usbd::EndpointEvent ev, size_t
}

#if !HAL_PLATFORM_USB_SOF
stopTxTimer();
stopTxTimeoutTimer();
#endif // !HAL_PLATFORM_USB_SOF

if (txBuffer_.consumePending() != len) {
Expand Down Expand Up @@ -401,7 +408,7 @@ int CdcClassDriver::startRx() {
return dev_->transferOut(epOutData_, ptr, rxSize);
}

int CdcClassDriver::startTx() {
int CdcClassDriver::startTx(bool holdoff) {
if (txState_) {
return 0;
}
Expand All @@ -415,29 +422,34 @@ int CdcClassDriver::startTx() {
return 0;
}

if (holdoff) {
stopTxTimer();
return startTxTimer();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the use case for holdoff = true? This just delays the start of transmission by 1ms?

}

txState_ = true;
consumable = std::min(consumable, cdc::MAX_DATA_PACKET_SIZE);
auto buf = txBuffer_.consume(consumable);
dev_->transferIn(epInData_, buf, consumable);

#if !HAL_PLATFORM_USB_SOF
stopTxTimer();
startTxTimer();
stopTxTimeoutTimer();
startTxTimeoutTimer();
#endif // !HAL_PLATFORM_USB_SOF
return 0;
}

#if !HAL_PLATFORM_USB_SOF
void CdcClassDriver::txTimerCallback(os_timer_t timer) {
void CdcClassDriver::txTimeoutTimerCallback(os_timer_t timer) {
void* timerId = nullptr;
os_timer_get_id(timer, &timerId);
if (timerId) {
auto self = static_cast<CdcClassDriver*>(timerId);
self->txTimerExpired();
self->txTimeoutTimerExpired();
}
}

void CdcClassDriver::txTimerExpired() {
void CdcClassDriver::txTimeoutTimerExpired() {
std::lock_guard<Device> lk(*dev_);
if (txState_ && open_) {
setOpenState(false);
Expand All @@ -452,6 +464,20 @@ void CdcClassDriver::txTimerExpired() {
txBuffer_.reset();
dev_->unlock();
}

void CdcClassDriver::txTimerCallback(os_timer_t timer) {
void* timerId = nullptr;
os_timer_get_id(timer, &timerId);
if (timerId) {
auto self = static_cast<CdcClassDriver*>(timerId);
self->txTimerExpired();
}
}

void CdcClassDriver::txTimerExpired() {
std::lock_guard<Device> lk(*dev_);
startTx();
}
#endif // !HAL_PLATFORM_USB_SOF

int CdcClassDriver::getNumInterfaces() const {
Expand Down Expand Up @@ -531,8 +557,7 @@ int CdcClassDriver::write(const uint8_t* buf, size_t len) {
{
std::lock_guard<Device> lk(*dev_);
CHECK(txBuffer_.put(buf, writeSize));
// FIXME: call from usbd task thread instead?
startTx();
startTx(true /* holdoff */);
}
return writeSize;
}
Expand All @@ -557,8 +582,16 @@ bool CdcClassDriver::buffersConfigured() const {
}

#if !HAL_PLATFORM_USB_SOF
int CdcClassDriver::startTxTimeoutTimer() {
return os_timer_change(txTimeoutTimer_, OS_TIMER_CHANGE_START, false, HAL_PLATFORM_USB_CDC_TX_FAIL_TIMEOUT_MS, 0, nullptr);
}

int CdcClassDriver::stopTxTimeoutTimer() {
return os_timer_change(txTimeoutTimer_, OS_TIMER_CHANGE_STOP, false, 0, 0, nullptr);
}

int CdcClassDriver::startTxTimer() {
return os_timer_change(txTimer_, OS_TIMER_CHANGE_START, false, HAL_PLATFORM_USB_CDC_TX_FAIL_TIMEOUT_MS, 0, nullptr);
return os_timer_change(txTimer_, OS_TIMER_CHANGE_START, false, HAL_PLATFORM_USB_CDC_TX_PERIOD_MS, 0, nullptr);
}

int CdcClassDriver::stopTxTimer() {
Expand Down
9 changes: 8 additions & 1 deletion hal/src/rtl872x/usbd_cdc.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,15 +98,21 @@ class CdcClassDriver : public particle::usbd::ClassDriver {
void setOpenState(bool state);

int startRx();
int startTx();
int startTx(bool holdoff = false);

#if !HAL_PLATFORM_USB_SOF
int startTxTimeoutTimer();
int stopTxTimeoutTimer();

int startTxTimer();
int stopTxTimer();
#endif // !HAL_PLATFORM_USB_SOF

private:
#if !HAL_PLATFORM_USB_SOF
static void txTimeoutTimerCallback(os_timer_t timer);
void txTimeoutTimerExpired();

static void txTimerCallback(os_timer_t timer);
void txTimerExpired();
#endif // !HAL_PLATFORM_USB_SOF
Expand Down Expand Up @@ -139,6 +145,7 @@ class CdcClassDriver : public particle::usbd::ClassDriver {
uint8_t altSetting_ = 0;

#if !HAL_PLATFORM_USB_SOF
os_timer_t txTimeoutTimer_ = nullptr;
os_timer_t txTimer_ = nullptr;
#endif // !HAL_PLATFORM_USB_SOF
bool useDummyIntEp_ = false;
Expand Down