Skip to content

CYW43XXX Cordio HCI driver: fixed MCU deep-sleep locking flow #14982

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

Merged
merged 1 commit into from
Aug 13, 2021
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,8 @@ CyH4TransportDriver::CyH4TransportDriver(PinName tx, PinName rx, PinName cts, Pi
bt_device_wake(bt_device_wake_name, PIN_OUTPUT, PullNone, 1),
host_wake_irq_event(host_wake_irq),
dev_wake_irq_event(dev_wake_irq)

{
enabled_powersave = true;
bt_host_wake_active = false;
}

CyH4TransportDriver::CyH4TransportDriver(PinName tx, PinName rx, PinName cts, PinName rts, PinName bt_power_name, int baud) :
Expand All @@ -70,33 +68,24 @@ CyH4TransportDriver::CyH4TransportDriver(PinName tx, PinName rx, PinName cts, Pi

{
enabled_powersave = false;
bt_host_wake_active = false;

sleep_manager_lock_deep_sleep(); // locking deep sleep because this option
// does not include a host wake pin
holding_deep_sleep_lock = true;
}

CyH4TransportDriver::~CyH4TransportDriver()
{
if (holding_deep_sleep_lock)
{
sleep_manager_unlock_deep_sleep();
holding_deep_sleep_lock = false;
}

}

void CyH4TransportDriver::bt_host_wake_rise_irq_handler(void)
{
if (host_wake_irq_event == WAKE_EVENT_ACTIVE_LOW) {
if(bt_host_wake_active == true)
{
/* lock PSoC 6 DeepSleep entry as long as host_wake is asserted */
/* lock MCU Deep Sleep entry as long as host_wake is asserted */
sleep_manager_unlock_deep_sleep();
bt_host_wake_active = false;
}
} else {
/* lock PSoC 6 DeepSleep entry as long as host_wake is asserted */
/* lock MCU Deep Sleep entry as long as host_wake is asserted */
sleep_manager_lock_deep_sleep();
bt_host_wake_active = true;
}
Expand All @@ -105,13 +94,13 @@ void CyH4TransportDriver::bt_host_wake_rise_irq_handler(void)
void CyH4TransportDriver::bt_host_wake_fall_irq_handler(void)
{
if (host_wake_irq_event == WAKE_EVENT_ACTIVE_LOW) {
/* lock PSoC 6 DeepSleep entry as long as host_wake is asserted */
/* lock MCU Deep Sleep entry as long as host_wake is asserted */
sleep_manager_lock_deep_sleep();
bt_host_wake_active = true;
} else {
if(bt_host_wake_active == true)
{
/* lock PSoC 6 DeepSleep entry as long as host_wake is asserted */
/* lock MCU Deep Sleep entry as long as host_wake is asserted */
sleep_manager_unlock_deep_sleep();
bt_host_wake_active = false;
}
Expand Down Expand Up @@ -150,6 +139,18 @@ static void on_controller_irq(void *callback_arg, cyhal_uart_event_t event)

void CyH4TransportDriver::initialize()
{
// Initial MCU Deep Sleep locking. CyH4TransportDriver has the following MCU Deep Sleep locking
// scenarios:
// a) A BT device or MCU does not support Low Power mode (MBED configuration does not include
// MBED_TICKLESS, DEVICE_SLEEP, DEVICE_LPTICKER or CYCFG_BT_LP_ENABLED features).
// In this case, CyH4TransportDriver locks Deep Sleep in the initialize() function and
// unlocks the terminate() function.
// b) A BT device and MCU support Low Power mode.
// In this case, the control of the unlock/lock of the Deep Sleep
// functionality will be done in bt_host_wake_rise_irq_handler and bt_host_wake_fall_irq_handler
// handlers. Finally, CyH4TransportDriver unlocks the Deep Sleep in terminate() function
// (if it was locked before) by checking the bt_host_wake_active flag.
bt_host_wake_active = true;
sleep_manager_lock_deep_sleep();

bt_power = 0;
Expand Down Expand Up @@ -202,7 +203,6 @@ void CyH4TransportDriver::initialize()
if (bt_device_wake_name != NC)
bt_device_wake = WAKE_EVENT_ACTIVE_HIGH;
}
sleep_manager_unlock_deep_sleep();
}

void CyH4TransportDriver::terminate()
Expand Down Expand Up @@ -236,6 +236,13 @@ void CyH4TransportDriver::terminate()
#else
cyhal_uart_free(&uart);
#endif

// Unlock Deep Sleep if it was locked by CyH4TransportDriver before.
if (bt_host_wake_active == true)
{
sleep_manager_unlock_deep_sleep();
bt_host_wake_active = false;
}
}

uint16_t CyH4TransportDriver::write(uint8_t type, uint16_t len, uint8_t *pData)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,6 @@ class CyH4TransportDriver : public CordioHCITransportDriver {
bool enabled_powersave;
uint8_t host_wake_irq_event;
uint8_t dev_wake_irq_event;

bool holding_deep_sleep_lock;
};

} // namespace cypress
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,6 @@ class HCIDriver : public CordioHCIDriver {

virtual void do_initialize()
{
//Prevent PSoC6 to enter deep-sleep till BT initialization is complete
sleep_manager_lock_deep_sleep();
rtos::ThisThread::sleep_for(500ms);
bt_power = 1;
rtos::ThisThread::sleep_for(500ms);
Expand Down Expand Up @@ -175,7 +173,6 @@ class HCIDriver : public CordioHCIDriver {
// Note: Reset is handled by ack_service_pack.
case HCI_VS_CMD_SET_SLEEP_MODE:
HciWriteLeHostSupport();
sleep_manager_unlock_deep_sleep();
break;

case HCI_OPCODE_WRITE_LE_HOST_SUPPORT:
Expand Down