Skip to content

Commit 41dded9

Browse files
MukundGitHubKyle Kearney
authored andcommitted
Improve Cordio low power assist
Allow more flexibile configuration for BLE radio pins
1 parent e8f325f commit 41dded9

File tree

4 files changed

+283
-26
lines changed

4 files changed

+283
-26
lines changed

features/FEATURE_BLE/targets/TARGET_Cypress/TARGET_CYW43XXX/CyH4TransportDriver.cpp

Lines changed: 95 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,31 +18,59 @@
1818
#if DEVICE_SERIAL && DEVICE_SERIAL_FC
1919

2020
#include "CyH4TransportDriver.h"
21-
#include "cycfg_pins.h"
2221

2322
namespace ble {
2423
namespace vendor {
2524
namespace cypress_ble {
2625

27-
CyH4TransportDriver::CyH4TransportDriver(PinName tx, PinName rx, PinName cts, PinName rts, int baud, PinName bt_host_wake_name, PinName bt_device_wake_name) :
26+
27+
CyH4TransportDriver::CyH4TransportDriver(PinName tx, PinName rx, PinName cts, PinName rts, int baud, PinName bt_host_wake_name, PinName bt_device_wake_name, uint8_t host_wake_irq, uint8_t dev_wake_irq) :
2828
uart(tx, rx, baud), cts(cts), rts(rts),
2929
bt_host_wake_name(bt_host_wake_name),
3030
bt_device_wake_name(bt_device_wake_name),
3131
bt_host_wake(bt_host_wake_name, PIN_INPUT, PullNone, 0),
32-
bt_device_wake(bt_device_wake_name, PIN_OUTPUT, PullDefault, 1)
32+
bt_device_wake(bt_device_wake_name, PIN_OUTPUT, PullDefault, 1),
33+
host_wake_irq_event(host_wake_irq),
34+
dev_wake_irq_event(dev_wake_irq)
3335
{
36+
enabled_powersave = true;
37+
}
38+
39+
CyH4TransportDriver::CyH4TransportDriver(PinName tx, PinName rx, PinName cts, PinName rts, int baud) :
40+
uart(tx, rx, baud),
41+
cts(cts),
42+
rts(rts),
43+
bt_host_wake_name(NC),
44+
bt_device_wake_name(NC),
45+
bt_host_wake(bt_host_wake_name),
46+
bt_device_wake(bt_device_wake_name)
47+
{
48+
enabled_powersave = false;
49+
sleep_manager_lock_deep_sleep();
50+
holding_deep_sleep_lock = true;
51+
}
52+
53+
CyH4TransportDriver::~CyH4TransportDriver()
54+
{
55+
if (holding_deep_sleep_lock)
56+
{
57+
sleep_manager_unlock_deep_sleep();
58+
holding_deep_sleep_lock = false;
59+
}
3460
}
3561

3662
void CyH4TransportDriver::bt_host_wake_irq_handler(void)
3763
{
38-
sleep_manager_lock_deep_sleep();
39-
CyH4TransportDriver::on_controller_irq();
40-
sleep_manager_unlock_deep_sleep();
64+
sleep_manager_lock_deep_sleep();
65+
CyH4TransportDriver::on_controller_irq();
66+
sleep_manager_unlock_deep_sleep();
4167
}
4268

4369
void CyH4TransportDriver::initialize()
4470
{
71+
#if (defined(MBED_TICKLESS) && DEVICE_SLEEP && DEVICE_LPTICKER)
4572
InterruptIn *host_wake_pin;
73+
#endif
4674

4775
uart.format(
4876
/* bits */ 8,
@@ -64,10 +92,20 @@ void CyH4TransportDriver::initialize()
6492
#if (defined(MBED_TICKLESS) && DEVICE_SLEEP && DEVICE_LPTICKER)
6593
//Register IRQ for Host WAKE
6694
host_wake_pin = new InterruptIn(bt_host_wake_name);
67-
host_wake_pin->fall(callback(this, &CyH4TransportDriver::bt_host_wake_irq_handler));
95+
if (host_wake_irq_event == WAKE_EVENT_ACTIVE_LOW) {
96+
host_wake_pin->fall(callback(this, &CyH4TransportDriver::bt_host_wake_irq_handler));
97+
} else {
98+
host_wake_pin->rise(callback(this, &CyH4TransportDriver::bt_host_wake_irq_handler));
99+
}
68100

69101
#endif
70-
bt_device_wake = 0;
102+
if (dev_wake_irq_event == WAKE_EVENT_ACTIVE_LOW) {
103+
if (bt_device_wake_name != NC)
104+
bt_device_wake = WAKE_EVENT_ACTIVE_LOW;
105+
} else {
106+
if (bt_device_wake_name != NC)
107+
bt_device_wake = WAKE_EVENT_ACTIVE_HIGH;
108+
}
71109
wait_ms(500);
72110
}
73111

@@ -105,20 +143,67 @@ void CyH4TransportDriver::on_controller_irq()
105143
void CyH4TransportDriver::assert_bt_dev_wake()
106144
{
107145
#if (defined(MBED_TICKLESS) && DEVICE_SLEEP && DEVICE_LPTICKER)
108-
bt_device_wake = 0;
146+
if (dev_wake_irq_event == WAKE_EVENT_ACTIVE_LOW) {
147+
bt_device_wake = WAKE_EVENT_ACTIVE_LOW;
148+
} else {
149+
bt_device_wake = WAKE_EVENT_ACTIVE_HIGH;
150+
}
109151
#endif
110152
}
111153

112154
void CyH4TransportDriver::deassert_bt_dev_wake()
113155
{
114156
#if (defined(MBED_TICKLESS) && DEVICE_SLEEP && DEVICE_LPTICKER)
115157
//De-assert bt_device_wake
116-
bt_device_wake = 1;
158+
if (dev_wake_irq_event == WAKE_EVENT_ACTIVE_LOW) {
159+
bt_device_wake = WAKE_EVENT_ACTIVE_HIGH;
160+
} else {
161+
bt_device_wake = WAKE_EVENT_ACTIVE_LOW;
162+
}
117163
#endif
118164
}
119165

166+
bool CyH4TransportDriver::get_enabled_powersave()
167+
{
168+
return (enabled_powersave);
169+
}
170+
171+
uint8_t CyH4TransportDriver::get_host_wake_irq_event()
172+
{
173+
return (host_wake_irq_event);
174+
}
175+
176+
uint8_t CyH4TransportDriver::get_dev_wake_irq_event()
177+
{
178+
return (dev_wake_irq_event);
179+
}
180+
181+
120182
} // namespace cypress_ble
121183
} // namespace vendor
122184
} // namespace ble
123185

186+
ble::vendor::cypress_ble::CyH4TransportDriver& ble_cordio_get_default_h4_transport_driver()
187+
{
188+
#if (defined(CYBSP_BT_HOST_WAKE) && defined(CYBSP_BT_DEVICE_WAKE))
189+
static ble::vendor::cypress_ble::CyH4TransportDriver s_transport_driver(
190+
/* TX */ CYBSP_BT_UART_TX, /* RX */ CYBSP_BT_UART_RX,
191+
/* cts */ CYBSP_BT_UART_CTS, /* rts */ CYBSP_BT_UART_RTS, DEF_BT_BAUD_RATE,
192+
CYBSP_BT_HOST_WAKE, CYBSP_BT_DEVICE_WAKE
193+
);
194+
195+
#else
196+
static ble::vendor::cypress_ble::CyH4TransportDriver s_transport_driver(
197+
/* TX */ CYBSP_BT_UART_TX, /* RX */ CYBSP_BT_UART_RX,
198+
/* cts */ CYBSP_BT_UART_CTS, /* rts */ CYBSP_BT_UART_RTS, DEF_BT_BAUD_RATE);
199+
#endif
200+
return s_transport_driver;
201+
}
202+
203+
MBED_WEAK
204+
ble::vendor::cypress_ble::CyH4TransportDriver& ble_cordio_get_h4_transport_driver()
205+
{
206+
return (ble_cordio_get_default_h4_transport_driver());
207+
}
208+
124209
#endif

features/FEATURE_BLE/targets/TARGET_Cypress/TARGET_CYW43XXX/CyH4TransportDriver.h

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
#include "CordioHCITransportDriver.h"
2626
#include "drivers/DigitalInOut.h"
2727

28-
2928
namespace ble {
3029
namespace vendor {
3130
namespace cypress_ble {
@@ -41,12 +40,14 @@ class CyH4TransportDriver : public cordio::CordioHCITransportDriver {
4140
* Initialize the transport driver.
4241
*
4342
*/
44-
CyH4TransportDriver(PinName tx, PinName rx, PinName cts, PinName rts, int baud, PinName bt_host_wake_name, PinName bt_device_wake_name);
43+
CyH4TransportDriver(PinName tx, PinName rx, PinName cts, PinName rts, int baud, PinName bt_host_wake_name, PinName bt_device_wake_name,
44+
uint8_t host_wake_irq = 0, uint8_t dev_wake_irq = 0);
45+
CyH4TransportDriver(PinName tx, PinName rx, PinName cts, PinName rts, int baud);
4546

4647
/**
4748
* Destructor
4849
*/
49-
virtual ~CyH4TransportDriver() { }
50+
virtual ~CyH4TransportDriver();
5051

5152
/**
5253
* @see CordioHCITransportDriver::initialize
@@ -65,7 +66,10 @@ class CyH4TransportDriver : public cordio::CordioHCITransportDriver {
6566

6667
void bt_host_wake_irq_handler();
6768

68-
private:
69+
bool get_enabled_powersave();
70+
uint8_t get_host_wake_irq_event();
71+
uint8_t get_dev_wake_irq_event();
72+
6973
private:
7074
void on_controller_irq();
7175
void assert_bt_dev_wake();
@@ -80,13 +84,28 @@ class CyH4TransportDriver : public cordio::CordioHCITransportDriver {
8084
PinName rts;
8185
PinName bt_host_wake_name;
8286
PinName bt_device_wake_name;
87+
8388
DigitalInOut bt_host_wake;
8489
DigitalInOut bt_device_wake;
90+
91+
bool enabled_powersave;
92+
uint8_t host_wake_irq_event;
93+
uint8_t dev_wake_irq_event;
94+
95+
bool holding_deep_sleep_lock;
96+
8597
};
8698

8799
} // namespace cypress
88100
} // namespace vendor
89101
} // namespace ble
90102

103+
#define DEF_BT_BAUD_RATE (115200)
104+
105+
#define WAKE_EVENT_ACTIVE_HIGH ( 1 ) /* Interrupt Rising Edge */
106+
#define WAKE_EVENT_ACTIVE_LOW ( 0 ) /* Interrupt Falling Edge */
107+
108+
ble::vendor::cypress_ble::CyH4TransportDriver& ble_cordio_get_default_h4_transport_driver();
109+
ble::vendor::cypress_ble::CyH4TransportDriver& ble_cordio_get_h4_transport_driver();
91110
#endif
92111
#endif /* CY_H4TRANSPORT_DRIVER_H_ */

features/FEATURE_BLE/targets/TARGET_Cypress/TARGET_CYW43XXX/HCIDriver.cpp

Lines changed: 40 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
#include <stdbool.h>
2626
#include "hci_mbed_os_adaptation.h"
2727
#include "CyH4TransportDriver.h"
28-
#include "cycfg_pins.h"
2928

3029
extern const int brcm_patch_ram_length;
3130
extern const uint8_t brcm_patchram_buf[];
@@ -57,10 +56,16 @@ class HCIDriver : public cordio::CordioHCIDriver {
5756
public:
5857
HCIDriver(
5958
cordio::CordioHCITransportDriver& transport_driver,
60-
PinName bt_power_name
59+
PinName bt_power_name,
60+
bool ps_enabled,
61+
uint8_t host_wake_irq,
62+
uint8_t dev_wake_irq
6163
) : cordio::CordioHCIDriver(transport_driver),
6264
bt_power_name(bt_power_name),
6365
bt_power(bt_power_name, PIN_OUTPUT, PullUp, 0),
66+
is_powersave_enabled(ps_enabled),
67+
host_wake_irq(host_wake_irq),
68+
dev_wake_irq(dev_wake_irq),
6469
service_pack_index(0),
6570
service_pack_ptr(0),
6671
service_pack_length(0),
@@ -343,11 +348,23 @@ class HCIDriver : public cordio::CordioHCIDriver {
343348
uint8_t *pBuf;
344349
if ((pBuf = hciCmdAlloc(HCI_VS_CMD_SET_SLEEP_MODE, 12)) != NULL)
345350
{
346-
pBuf[HCI_CMD_HDR_LEN] = 0x00; // no sleep
351+
if (is_powersave_on()) {
352+
pBuf[HCI_CMD_HDR_LEN] = 0x01; // sleep
353+
} else {
354+
pBuf[HCI_CMD_HDR_LEN] = 0x00; // no sleep
355+
}
347356
pBuf[HCI_CMD_HDR_LEN + 1] = 0x00; // no idle threshold host (N/A)
348357
pBuf[HCI_CMD_HDR_LEN + 2] = 0x00; // no idle threshold HC (N/A)
349-
pBuf[HCI_CMD_HDR_LEN + 3] = 0x00; // BT WAKE
350-
pBuf[HCI_CMD_HDR_LEN + 4] = 0x00; // HOST WAKE
358+
if (is_powersave_on()) {
359+
pBuf[HCI_CMD_HDR_LEN + 3] = dev_wake_irq; // BT WAKE
360+
} else {
361+
pBuf[HCI_CMD_HDR_LEN + 3] = 0x00; // BT WAKE
362+
}
363+
if (is_powersave_on()) {
364+
pBuf[HCI_CMD_HDR_LEN + 4] = host_wake_irq; // HOST WAKE
365+
} else {
366+
pBuf[HCI_CMD_HDR_LEN + 3] = 0x00; // BT WAKE
367+
}
351368
pBuf[HCI_CMD_HDR_LEN + 5] = 0x00; // Sleep during SCO
352369
pBuf[HCI_CMD_HDR_LEN + 6] = 0x00; // Combining sleep mode and SCM
353370
pBuf[HCI_CMD_HDR_LEN + 7] = 0x00; // Tristate TX
@@ -406,8 +423,18 @@ class HCIDriver : public cordio::CordioHCIDriver {
406423
}
407424
}
408425

426+
bool is_powersave_on(void)
427+
{
428+
return (is_powersave_enabled);
429+
}
430+
409431
PinName bt_power_name;
410432
DigitalInOut bt_power;
433+
434+
bool is_powersave_enabled;
435+
uint8_t host_wake_irq;
436+
uint8_t dev_wake_irq;
437+
411438
size_t service_pack_index;
412439
const uint8_t* service_pack_ptr;
413440
int service_pack_length;
@@ -420,15 +447,16 @@ class HCIDriver : public cordio::CordioHCIDriver {
420447
} // namespace vendor
421448
} // namespace ble
422449

423-
ble::vendor::cordio::CordioHCIDriver& ble_cordio_get_hci_driver() {
424-
static ble::vendor::cypress_ble::CyH4TransportDriver transport_driver(
425-
/* TX */ CYBSP_BT_UART_TX, /* RX */ CYBSP_BT_UART_RX,
426-
/* cts */ CYBSP_BT_UART_CTS, /* rts */ CYBSP_BT_UART_RTS, 115200,
427-
CYBSP_BT_HOST_WAKE, CYBSP_BT_DEVICE_WAKE
428-
);
450+
ble::vendor::cordio::CordioHCIDriver& ble_cordio_get_hci_driver()
451+
{
452+
static ble::vendor::cypress_ble::CyH4TransportDriver& transport_driver =
453+
ble_cordio_get_h4_transport_driver();
429454
static ble::vendor::cypress::HCIDriver hci_driver(
430455
transport_driver,
431-
/* bt_power */ CYBSP_BT_POWER
456+
/* bt_power */ CYBSP_BT_POWER,
457+
transport_driver.get_enabled_powersave(),
458+
transport_driver.get_host_wake_irq_event(),
459+
transport_driver.get_dev_wake_irq_event()
432460
);
433461
return hci_driver;
434462
}

0 commit comments

Comments
 (0)