mirror of https://github.com/ARMmbed/mbed-os.git
Improve Cordio low power assist
Allow more flexibile configuration for BLE radio pinspull/11367/head
parent
e8f325fe33
commit
41dded9ec5
|
@ -18,19 +18,45 @@
|
|||
#if DEVICE_SERIAL && DEVICE_SERIAL_FC
|
||||
|
||||
#include "CyH4TransportDriver.h"
|
||||
#include "cycfg_pins.h"
|
||||
|
||||
namespace ble {
|
||||
namespace vendor {
|
||||
namespace cypress_ble {
|
||||
|
||||
CyH4TransportDriver::CyH4TransportDriver(PinName tx, PinName rx, PinName cts, PinName rts, int baud, PinName bt_host_wake_name, PinName bt_device_wake_name) :
|
||||
|
||||
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) :
|
||||
uart(tx, rx, baud), cts(cts), rts(rts),
|
||||
bt_host_wake_name(bt_host_wake_name),
|
||||
bt_device_wake_name(bt_device_wake_name),
|
||||
bt_host_wake(bt_host_wake_name, PIN_INPUT, PullNone, 0),
|
||||
bt_device_wake(bt_device_wake_name, PIN_OUTPUT, PullDefault, 1)
|
||||
bt_device_wake(bt_device_wake_name, PIN_OUTPUT, PullDefault, 1),
|
||||
host_wake_irq_event(host_wake_irq),
|
||||
dev_wake_irq_event(dev_wake_irq)
|
||||
{
|
||||
enabled_powersave = true;
|
||||
}
|
||||
|
||||
CyH4TransportDriver::CyH4TransportDriver(PinName tx, PinName rx, PinName cts, PinName rts, int baud) :
|
||||
uart(tx, rx, baud),
|
||||
cts(cts),
|
||||
rts(rts),
|
||||
bt_host_wake_name(NC),
|
||||
bt_device_wake_name(NC),
|
||||
bt_host_wake(bt_host_wake_name),
|
||||
bt_device_wake(bt_device_wake_name)
|
||||
{
|
||||
enabled_powersave = false;
|
||||
sleep_manager_lock_deep_sleep();
|
||||
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_irq_handler(void)
|
||||
|
@ -42,7 +68,9 @@ void CyH4TransportDriver::bt_host_wake_irq_handler(void)
|
|||
|
||||
void CyH4TransportDriver::initialize()
|
||||
{
|
||||
#if (defined(MBED_TICKLESS) && DEVICE_SLEEP && DEVICE_LPTICKER)
|
||||
InterruptIn *host_wake_pin;
|
||||
#endif
|
||||
|
||||
uart.format(
|
||||
/* bits */ 8,
|
||||
|
@ -64,10 +92,20 @@ void CyH4TransportDriver::initialize()
|
|||
#if (defined(MBED_TICKLESS) && DEVICE_SLEEP && DEVICE_LPTICKER)
|
||||
//Register IRQ for Host WAKE
|
||||
host_wake_pin = new InterruptIn(bt_host_wake_name);
|
||||
if (host_wake_irq_event == WAKE_EVENT_ACTIVE_LOW) {
|
||||
host_wake_pin->fall(callback(this, &CyH4TransportDriver::bt_host_wake_irq_handler));
|
||||
} else {
|
||||
host_wake_pin->rise(callback(this, &CyH4TransportDriver::bt_host_wake_irq_handler));
|
||||
}
|
||||
|
||||
#endif
|
||||
bt_device_wake = 0;
|
||||
if (dev_wake_irq_event == WAKE_EVENT_ACTIVE_LOW) {
|
||||
if (bt_device_wake_name != NC)
|
||||
bt_device_wake = WAKE_EVENT_ACTIVE_LOW;
|
||||
} else {
|
||||
if (bt_device_wake_name != NC)
|
||||
bt_device_wake = WAKE_EVENT_ACTIVE_HIGH;
|
||||
}
|
||||
wait_ms(500);
|
||||
}
|
||||
|
||||
|
@ -105,7 +143,11 @@ void CyH4TransportDriver::on_controller_irq()
|
|||
void CyH4TransportDriver::assert_bt_dev_wake()
|
||||
{
|
||||
#if (defined(MBED_TICKLESS) && DEVICE_SLEEP && DEVICE_LPTICKER)
|
||||
bt_device_wake = 0;
|
||||
if (dev_wake_irq_event == WAKE_EVENT_ACTIVE_LOW) {
|
||||
bt_device_wake = WAKE_EVENT_ACTIVE_LOW;
|
||||
} else {
|
||||
bt_device_wake = WAKE_EVENT_ACTIVE_HIGH;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -113,12 +155,55 @@ void CyH4TransportDriver::deassert_bt_dev_wake()
|
|||
{
|
||||
#if (defined(MBED_TICKLESS) && DEVICE_SLEEP && DEVICE_LPTICKER)
|
||||
//De-assert bt_device_wake
|
||||
bt_device_wake = 1;
|
||||
if (dev_wake_irq_event == WAKE_EVENT_ACTIVE_LOW) {
|
||||
bt_device_wake = WAKE_EVENT_ACTIVE_HIGH;
|
||||
} else {
|
||||
bt_device_wake = WAKE_EVENT_ACTIVE_LOW;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool CyH4TransportDriver::get_enabled_powersave()
|
||||
{
|
||||
return (enabled_powersave);
|
||||
}
|
||||
|
||||
uint8_t CyH4TransportDriver::get_host_wake_irq_event()
|
||||
{
|
||||
return (host_wake_irq_event);
|
||||
}
|
||||
|
||||
uint8_t CyH4TransportDriver::get_dev_wake_irq_event()
|
||||
{
|
||||
return (dev_wake_irq_event);
|
||||
}
|
||||
|
||||
|
||||
} // namespace cypress_ble
|
||||
} // namespace vendor
|
||||
} // namespace ble
|
||||
|
||||
ble::vendor::cypress_ble::CyH4TransportDriver& ble_cordio_get_default_h4_transport_driver()
|
||||
{
|
||||
#if (defined(CYBSP_BT_HOST_WAKE) && defined(CYBSP_BT_DEVICE_WAKE))
|
||||
static ble::vendor::cypress_ble::CyH4TransportDriver s_transport_driver(
|
||||
/* TX */ CYBSP_BT_UART_TX, /* RX */ CYBSP_BT_UART_RX,
|
||||
/* cts */ CYBSP_BT_UART_CTS, /* rts */ CYBSP_BT_UART_RTS, DEF_BT_BAUD_RATE,
|
||||
CYBSP_BT_HOST_WAKE, CYBSP_BT_DEVICE_WAKE
|
||||
);
|
||||
|
||||
#else
|
||||
static ble::vendor::cypress_ble::CyH4TransportDriver s_transport_driver(
|
||||
/* TX */ CYBSP_BT_UART_TX, /* RX */ CYBSP_BT_UART_RX,
|
||||
/* cts */ CYBSP_BT_UART_CTS, /* rts */ CYBSP_BT_UART_RTS, DEF_BT_BAUD_RATE);
|
||||
#endif
|
||||
return s_transport_driver;
|
||||
}
|
||||
|
||||
MBED_WEAK
|
||||
ble::vendor::cypress_ble::CyH4TransportDriver& ble_cordio_get_h4_transport_driver()
|
||||
{
|
||||
return (ble_cordio_get_default_h4_transport_driver());
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
#include "CordioHCITransportDriver.h"
|
||||
#include "drivers/DigitalInOut.h"
|
||||
|
||||
|
||||
namespace ble {
|
||||
namespace vendor {
|
||||
namespace cypress_ble {
|
||||
|
@ -41,12 +40,14 @@ public:
|
|||
* Initialize the transport driver.
|
||||
*
|
||||
*/
|
||||
CyH4TransportDriver(PinName tx, PinName rx, PinName cts, PinName rts, int baud, PinName bt_host_wake_name, PinName bt_device_wake_name);
|
||||
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 = 0, uint8_t dev_wake_irq = 0);
|
||||
CyH4TransportDriver(PinName tx, PinName rx, PinName cts, PinName rts, int baud);
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
virtual ~CyH4TransportDriver() { }
|
||||
virtual ~CyH4TransportDriver();
|
||||
|
||||
/**
|
||||
* @see CordioHCITransportDriver::initialize
|
||||
|
@ -65,7 +66,10 @@ public:
|
|||
|
||||
void bt_host_wake_irq_handler();
|
||||
|
||||
private:
|
||||
bool get_enabled_powersave();
|
||||
uint8_t get_host_wake_irq_event();
|
||||
uint8_t get_dev_wake_irq_event();
|
||||
|
||||
private:
|
||||
void on_controller_irq();
|
||||
void assert_bt_dev_wake();
|
||||
|
@ -80,13 +84,28 @@ private:
|
|||
PinName rts;
|
||||
PinName bt_host_wake_name;
|
||||
PinName bt_device_wake_name;
|
||||
|
||||
DigitalInOut bt_host_wake;
|
||||
DigitalInOut bt_device_wake;
|
||||
|
||||
bool enabled_powersave;
|
||||
uint8_t host_wake_irq_event;
|
||||
uint8_t dev_wake_irq_event;
|
||||
|
||||
bool holding_deep_sleep_lock;
|
||||
|
||||
};
|
||||
|
||||
} // namespace cypress
|
||||
} // namespace vendor
|
||||
} // namespace ble
|
||||
|
||||
#define DEF_BT_BAUD_RATE (115200)
|
||||
|
||||
#define WAKE_EVENT_ACTIVE_HIGH ( 1 ) /* Interrupt Rising Edge */
|
||||
#define WAKE_EVENT_ACTIVE_LOW ( 0 ) /* Interrupt Falling Edge */
|
||||
|
||||
ble::vendor::cypress_ble::CyH4TransportDriver& ble_cordio_get_default_h4_transport_driver();
|
||||
ble::vendor::cypress_ble::CyH4TransportDriver& ble_cordio_get_h4_transport_driver();
|
||||
#endif
|
||||
#endif /* CY_H4TRANSPORT_DRIVER_H_ */
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
#include <stdbool.h>
|
||||
#include "hci_mbed_os_adaptation.h"
|
||||
#include "CyH4TransportDriver.h"
|
||||
#include "cycfg_pins.h"
|
||||
|
||||
extern const int brcm_patch_ram_length;
|
||||
extern const uint8_t brcm_patchram_buf[];
|
||||
|
@ -57,10 +56,16 @@ class HCIDriver : public cordio::CordioHCIDriver {
|
|||
public:
|
||||
HCIDriver(
|
||||
cordio::CordioHCITransportDriver& transport_driver,
|
||||
PinName bt_power_name
|
||||
PinName bt_power_name,
|
||||
bool ps_enabled,
|
||||
uint8_t host_wake_irq,
|
||||
uint8_t dev_wake_irq
|
||||
) : cordio::CordioHCIDriver(transport_driver),
|
||||
bt_power_name(bt_power_name),
|
||||
bt_power(bt_power_name, PIN_OUTPUT, PullUp, 0),
|
||||
is_powersave_enabled(ps_enabled),
|
||||
host_wake_irq(host_wake_irq),
|
||||
dev_wake_irq(dev_wake_irq),
|
||||
service_pack_index(0),
|
||||
service_pack_ptr(0),
|
||||
service_pack_length(0),
|
||||
|
@ -343,11 +348,23 @@ private:
|
|||
uint8_t *pBuf;
|
||||
if ((pBuf = hciCmdAlloc(HCI_VS_CMD_SET_SLEEP_MODE, 12)) != NULL)
|
||||
{
|
||||
if (is_powersave_on()) {
|
||||
pBuf[HCI_CMD_HDR_LEN] = 0x01; // sleep
|
||||
} else {
|
||||
pBuf[HCI_CMD_HDR_LEN] = 0x00; // no sleep
|
||||
}
|
||||
pBuf[HCI_CMD_HDR_LEN + 1] = 0x00; // no idle threshold host (N/A)
|
||||
pBuf[HCI_CMD_HDR_LEN + 2] = 0x00; // no idle threshold HC (N/A)
|
||||
if (is_powersave_on()) {
|
||||
pBuf[HCI_CMD_HDR_LEN + 3] = dev_wake_irq; // BT WAKE
|
||||
} else {
|
||||
pBuf[HCI_CMD_HDR_LEN + 3] = 0x00; // BT WAKE
|
||||
pBuf[HCI_CMD_HDR_LEN + 4] = 0x00; // HOST WAKE
|
||||
}
|
||||
if (is_powersave_on()) {
|
||||
pBuf[HCI_CMD_HDR_LEN + 4] = host_wake_irq; // HOST WAKE
|
||||
} else {
|
||||
pBuf[HCI_CMD_HDR_LEN + 3] = 0x00; // BT WAKE
|
||||
}
|
||||
pBuf[HCI_CMD_HDR_LEN + 5] = 0x00; // Sleep during SCO
|
||||
pBuf[HCI_CMD_HDR_LEN + 6] = 0x00; // Combining sleep mode and SCM
|
||||
pBuf[HCI_CMD_HDR_LEN + 7] = 0x00; // Tristate TX
|
||||
|
@ -406,8 +423,18 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
bool is_powersave_on(void)
|
||||
{
|
||||
return (is_powersave_enabled);
|
||||
}
|
||||
|
||||
PinName bt_power_name;
|
||||
DigitalInOut bt_power;
|
||||
|
||||
bool is_powersave_enabled;
|
||||
uint8_t host_wake_irq;
|
||||
uint8_t dev_wake_irq;
|
||||
|
||||
size_t service_pack_index;
|
||||
const uint8_t* service_pack_ptr;
|
||||
int service_pack_length;
|
||||
|
@ -420,15 +447,16 @@ private:
|
|||
} // namespace vendor
|
||||
} // namespace ble
|
||||
|
||||
ble::vendor::cordio::CordioHCIDriver& ble_cordio_get_hci_driver() {
|
||||
static ble::vendor::cypress_ble::CyH4TransportDriver transport_driver(
|
||||
/* TX */ CYBSP_BT_UART_TX, /* RX */ CYBSP_BT_UART_RX,
|
||||
/* cts */ CYBSP_BT_UART_CTS, /* rts */ CYBSP_BT_UART_RTS, 115200,
|
||||
CYBSP_BT_HOST_WAKE, CYBSP_BT_DEVICE_WAKE
|
||||
);
|
||||
ble::vendor::cordio::CordioHCIDriver& ble_cordio_get_hci_driver()
|
||||
{
|
||||
static ble::vendor::cypress_ble::CyH4TransportDriver& transport_driver =
|
||||
ble_cordio_get_h4_transport_driver();
|
||||
static ble::vendor::cypress::HCIDriver hci_driver(
|
||||
transport_driver,
|
||||
/* bt_power */ CYBSP_BT_POWER
|
||||
/* bt_power */ CYBSP_BT_POWER,
|
||||
transport_driver.get_enabled_powersave(),
|
||||
transport_driver.get_host_wake_irq_event(),
|
||||
transport_driver.get_dev_wake_irq_event()
|
||||
);
|
||||
return hci_driver;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,125 @@
|
|||
/*******************************************************************************
|
||||
* \file cy_bt_cordio_cfg.cpp
|
||||
* \version 1.0
|
||||
*
|
||||
*
|
||||
* Low Power Assist BT Pin configuration implementation.
|
||||
*
|
||||
********************************************************************************
|
||||
* \copyright
|
||||
* Copyright 2019 Cypress Semiconductor Corporation
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*******************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "CordioBLE.h"
|
||||
#include "CordioHCIDriver.h"
|
||||
#include "hci_api.h"
|
||||
#include "hci_cmd.h"
|
||||
#include "hci_core.h"
|
||||
#include "bstream.h"
|
||||
#include "assert.h"
|
||||
#include <stdbool.h>
|
||||
#include "hci_mbed_os_adaptation.h"
|
||||
#include "CyH4TransportDriver.h"
|
||||
#include "cycfg.h"
|
||||
|
||||
/* Sanity Checks for Pin Configuration. Fail compilation if Sanity Check is enabled
|
||||
* and configuration is incorrect
|
||||
*/
|
||||
|
||||
#if (defined(MBED_TICKLESS) && DEVICE_SLEEP && DEVICE_LPTICKER)
|
||||
|
||||
#if ((defined(CYCFG_BT_LP_ENABLED)) && (CYCFG_BT_LP_ENABLED != 0))
|
||||
|
||||
#if (!defined(CY_BT_SKIP_CONFIGURATION_CHECKS))
|
||||
#if ((!defined(CYCFG_BT_HOST_WAKE_GPIO)) || (!defined(CYCFG_BT_DEV_WAKE_GPIO)))
|
||||
#error "configurator host-wake and dev-wake pins must be configured when deep-sleep is enabled"
|
||||
#endif
|
||||
static_assert(((CYCFG_BT_HOST_WAKE_GPIO != NC) && (CYCFG_BT_DEV_WAKE_GPIO != NC)), \
|
||||
"configurator host-wake and dev-wake pins must not be NC (no connect) when deep-sleep is enabled");
|
||||
#endif /* (!defined(CY_BT_SKIP_CONFIGURATION_CHECKS)) */
|
||||
|
||||
#else /* ((defined(CYCFG_BT_LP_ENABLED)) && (CYCFG_BT_LP_ENABLED != 0)) */
|
||||
|
||||
#if (!defined(CY_BT_SKIP_CONFIGURATION_CHECKS))
|
||||
#if ((!defined(CYBSP_BT_HOST_WAKE)) || (!defined(CYBSP_BT_DEVICE_WAKE)))
|
||||
#error "BSP configuration host-wake and dev-wake pin must be configured when deep-sleep is enabled"
|
||||
#endif
|
||||
static_assert(((CYBSP_BT_HOST_WAKE != NC) && (CYBSP_BT_DEVICE_WAKE != NC)), \
|
||||
"BSP configuration host-wake and dev-wake pin must not be NC (no connect) when deep-sleep is enabled");
|
||||
#endif /* (!defined(CY_BT_SKIP_CONFIGURATION_CHECKS)) */
|
||||
|
||||
#endif /* ((defined(CYCFG_BT_LP_ENABLED)) && (CYCFG_BT_LP_ENABLED != 0)) */
|
||||
|
||||
#endif /* (defined(MBED_TICKLESS) && DEVICE_SLEEP && DEVICE_LPTICKER) */
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name: ble_cordio_get_h4_transport_driver
|
||||
********************************************************************************
|
||||
*
|
||||
* Strong implementation of function which calls CyH4TransportDriver constructor and return it
|
||||
*
|
||||
* \param none
|
||||
*
|
||||
* \return
|
||||
* Returns the transport driver object
|
||||
*******************************************************************************/
|
||||
ble::vendor::cypress_ble::CyH4TransportDriver& ble_cordio_get_h4_transport_driver()
|
||||
{
|
||||
#if (defined(MBED_TICKLESS) && DEVICE_SLEEP && DEVICE_LPTICKER)
|
||||
|
||||
#if (defined(CYCFG_BT_LP_ENABLED))
|
||||
if (CYCFG_BT_LP_ENABLED) {
|
||||
static ble::vendor::cypress_ble::CyH4TransportDriver s_transport_driver(
|
||||
/* TX */ cyhal_gpio_to_rtos(CYBSP_BT_UART_TX),
|
||||
/* RX */ cyhal_gpio_to_rtos(CYBSP_BT_UART_RX),
|
||||
/* cts */ cyhal_gpio_to_rtos(CYBSP_BT_UART_CTS),
|
||||
/* rts */ cyhal_gpio_to_rtos(CYBSP_BT_UART_RTS), DEF_BT_BAUD_RATE,
|
||||
cyhal_gpio_to_rtos(CYCFG_BT_HOST_WAKE_GPIO),
|
||||
cyhal_gpio_to_rtos(CYCFG_BT_DEV_WAKE_GPIO),
|
||||
CYCFG_BT_HOST_WAKE_IRQ_EVENT,
|
||||
CYCFG_BT_DEV_WAKE_POLARITY
|
||||
);
|
||||
return s_transport_driver;
|
||||
} else { /* CYCFG_BT_LP_ENABLED */
|
||||
static ble::vendor::cypress_ble::CyH4TransportDriver s_transport_driver(
|
||||
/* TX */ cyhal_gpio_to_rtos(CYBSP_BT_UART_TX),
|
||||
/* RX */ cyhal_gpio_to_rtos(CYBSP_BT_UART_RX),
|
||||
/* cts */ cyhal_gpio_to_rtos(CYBSP_BT_UART_CTS),
|
||||
/* rts */ cyhal_gpio_to_rtos(CYBSP_BT_UART_RTS), DEF_BT_BAUD_RATE);
|
||||
return s_transport_driver;
|
||||
}
|
||||
#else /* (defined(CYCFG_BT_LP_ENABLED)) */
|
||||
static ble::vendor::cypress_ble::CyH4TransportDriver s_transport_driver(
|
||||
/* TX */ cyhal_gpio_to_rtos(CYBSP_BT_UART_TX),
|
||||
/* RX */ cyhal_gpio_to_rtos(CYBSP_BT_UART_RX),
|
||||
/* cts */ cyhal_gpio_to_rtos(CYBSP_BT_UART_CTS),
|
||||
/* rts */ cyhal_gpio_to_rtos(CYBSP_BT_UART_RTS), DEF_BT_BAUD_RATE,
|
||||
cyhal_gpio_to_rtos(CYBSP_BT_HOST_WAKE), cyhal_gpio_to_rtos(CYBSP_BT_DEVICE_WAKE)
|
||||
);
|
||||
return s_transport_driver;
|
||||
#endif /* (defined(CYCFG_BT_LP_ENABLED)) */
|
||||
|
||||
#else /* (defined(MBED_TICKLESS) && DEVICE_SLEEP && DEVICE_LPTICKER) */
|
||||
static ble::vendor::cypress_ble::CyH4TransportDriver s_transport_driver(
|
||||
/* TX */ cyhal_gpio_to_rtos(CYBSP_BT_UART_TX),
|
||||
/* RX */ cyhal_gpio_to_rtos(CYBSP_BT_UART_RX),
|
||||
/* cts */ cyhal_gpio_to_rtos(CYBSP_BT_UART_CTS),
|
||||
/* rts */ cyhal_gpio_to_rtos(CYBSP_BT_UART_RTS), DEF_BT_BAUD_RATE);
|
||||
return s_transport_driver;
|
||||
#endif /* (defined(MBED_TICKLESS) && DEVICE_SLEEP && DEVICE_LPTICKER) */
|
||||
}
|
Loading…
Reference in New Issue