PSOC6 deep-sleep changes

- Enable add MBED_TICKLESS in targets/targets.json
 - BLE : deep-sleep aware HCI transport driver
 - WIFI: deep-sleep aware driver
 - Rebuild WICED libraries with Low Power changes
pull/10067/head
Vivek Pallantla 2019-02-28 12:57:01 -08:00 committed by Cruz Monrreal II
parent 42f9c86327
commit 69e8b735b0
21 changed files with 258 additions and 42 deletions

View File

@ -0,0 +1,124 @@
/* mbed Microcontroller Library
* Copyright (c) 2017-2017 ARM Limited
* 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.
*/
#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) :
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)
{
}
void CyH4TransportDriver::bt_host_wake_irq_handler(void)
{
sleep_manager_lock_deep_sleep();
CyH4TransportDriver::on_controller_irq();
sleep_manager_unlock_deep_sleep();
}
void CyH4TransportDriver::initialize()
{
InterruptIn *host_wake_pin;
uart.format(
/* bits */ 8,
/* parity */ SerialBase::None,
/* stop bit */ 1
);
uart.set_flow_control(
/* flow */ SerialBase::RTSCTS,
/* rts */ rts,
/* cts */ cts
);
uart.attach(
callback(this, &CyH4TransportDriver::on_controller_irq),
SerialBase::RxIrq
);
#if (defined(MBED_TICKLESS) && DEVICE_SLEEP && DEVICE_LPTICKER)
//Register IRQ for Host WAKE
host_wake_pin = new InterruptIn(bt_host_wake_name);
host_wake_pin->fall(callback(this, &CyH4TransportDriver::bt_host_wake_irq_handler));
#endif
bt_device_wake = 0;
wait_ms(500);
}
void CyH4TransportDriver::terminate() { }
uint16_t CyH4TransportDriver::write(uint8_t type, uint16_t len, uint8_t *pData)
{
uint16_t i = 0;
assert_bt_dev_wake();
while (i < len + 1) {
uint8_t to_write = i == 0 ? type : pData[i - 1];
while (uart.writeable() == 0);
uart.putc(to_write);
++i;
}
deassert_bt_dev_wake();
return len;
}
void CyH4TransportDriver::on_controller_irq()
{
assert_bt_dev_wake();
while (uart.readable()) {
uint8_t char_received = uart.getc();
on_data_received(&char_received, 1);
}
deassert_bt_dev_wake();
}
void CyH4TransportDriver::assert_bt_dev_wake()
{
#if (defined(MBED_TICKLESS) && DEVICE_SLEEP && DEVICE_LPTICKER)
bt_device_wake = 0;
#endif
}
void CyH4TransportDriver::deassert_bt_dev_wake()
{
#if (defined(MBED_TICKLESS) && DEVICE_SLEEP && DEVICE_LPTICKER)
//De-assert bt_device_wake
bt_device_wake = 1;
#endif
}
} // namespace cypress_ble
} // namespace vendor
} // namespace ble
#endif

View File

@ -0,0 +1,92 @@
/* mbed Microcontroller Library
* Copyright (c) 2017-2017 ARM Limited
* 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.
*/
#ifndef CY_H4TRANSPORT_DRIVER_H_
#define CY_H4TRANSPORT_DRIVER_H_
#if (DEVICE_SERIAL && DEVICE_SERIAL_FC) || defined(DOXYGEN_ONLY)
#include <stdint.h>
#include "mbed.h"
#include "CordioHCITransportDriver.h"
#include "drivers/DigitalInOut.h"
namespace ble {
namespace vendor {
namespace cypress_ble {
using namespace ble::vendor;
/**
* Implementation of the H4 driver over Cypress based chips.
*/
class CyH4TransportDriver : public cordio::CordioHCITransportDriver {
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);
/**
* Destructor
*/
virtual ~CyH4TransportDriver() { }
/**
* @see CordioHCITransportDriver::initialize
*/
virtual void initialize();
/**
* @see CordioHCITransportDriver::terminate
*/
virtual void terminate();
/**
* @see CordioHCITransportDriver::write
*/
virtual uint16_t write(uint8_t type, uint16_t len, uint8_t *pData);
void bt_host_wake_irq_handler();
private:
private:
void on_controller_irq();
void assert_bt_dev_wake();
void deassert_bt_dev_wake();
// Use RawSerial as opposed to Serial as we don't require the locking primitives
// provided by the Serial class (access to the UART should be exclusive to this driver)
// Furthermore, we access the peripheral in interrupt context which would clash
// with Serial's locking facilities
RawSerial uart;
PinName cts;
PinName rts;
PinName bt_host_wake_name;
PinName bt_device_wake_name;
DigitalInOut bt_host_wake;
DigitalInOut bt_device_wake;
};
} // namespace cypress
} // namespace vendor
} // namespace ble
#endif
#endif /* CY_H4TRANSPORT_DRIVER_H_ */

View File

@ -24,7 +24,7 @@
#include "bstream.h"
#include <stdbool.h>
#include "hci_mbed_os_adaptation.h"
#include "H4TransportDriver.h"
#include "CyH4TransportDriver.h"
#include "cycfg_pins.h"
extern const int brcm_patch_ram_length;
@ -57,15 +57,9 @@ class HCIDriver : public cordio::CordioHCIDriver {
public:
HCIDriver(
cordio::CordioHCITransportDriver& transport_driver,
PinName bt_host_wake_name,
PinName bt_device_wake_name,
PinName bt_power_name
) : cordio::CordioHCIDriver(transport_driver),
bt_host_wake_name(bt_host_wake_name),
bt_device_wake_name(bt_device_wake_name),
bt_power_name(bt_power_name),
bt_host_wake(bt_host_wake_name, PIN_INPUT, PullNone, 0),
bt_device_wake(bt_device_wake_name, PIN_OUTPUT, PullDefault, 1),
bt_power(bt_power_name, PIN_OUTPUT, PullUp, 0),
service_pack_index(0),
service_pack_ptr(0),
@ -82,9 +76,6 @@ public:
virtual void do_initialize()
{
bt_device_wake = 0;
wait_ms(500);
bt_power = 1;
wait_ms(500);
}
@ -352,7 +343,7 @@ private:
uint8_t *pBuf;
if ((pBuf = hciCmdAlloc(HCI_VS_CMD_SET_SLEEP_MODE, 12)) != NULL)
{
pBuf[HCI_CMD_HDR_LEN] = 0x00; // no sleep moode
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)
pBuf[HCI_CMD_HDR_LEN + 3] = 0x00; // BT WAKE
@ -415,11 +406,7 @@ private:
}
}
PinName bt_host_wake_name;
PinName bt_device_wake_name;
PinName bt_power_name;
DigitalInOut bt_host_wake;
DigitalInOut bt_device_wake;
DigitalInOut bt_power;
size_t service_pack_index;
const uint8_t* service_pack_ptr;
@ -434,13 +421,14 @@ private:
} // namespace ble
ble::vendor::cordio::CordioHCIDriver& ble_cordio_get_hci_driver() {
static ble::vendor::cordio::H4TransportDriver transport_driver(
static ble::vendor::cypress_ble::CyH4TransportDriver transport_driver(
/* TX */ CY_BT_UART_TX, /* RX */ CY_BT_UART_RX,
/* cts */ CY_BT_UART_CTS, /* rts */ CY_BT_UART_RTS, 115200
/* cts */ CY_BT_UART_CTS, /* rts */ CY_BT_UART_RTS, 115200,
CY_BT_PIN_HOST_WAKE, CY_BT_PIN_DEVICE_WAKE
);
static ble::vendor::cypress::HCIDriver hci_driver(
transport_driver, /* host wake */ CY_BT_PIN_HOST_WAKE,
/* device wake */ CY_BT_PIN_DEVICE_WAKE, /* bt_power */ CY_BT_PIN_POWER
transport_driver,
/* bt_power */ CY_BT_PIN_POWER
);
return hci_driver;
}

View File

@ -251,6 +251,8 @@ typedef enum {
USBTX = UART_TX,
USBRX = UART_RX,
CY_WIFI_HOST_WAKE = P2_7,
// Not connected
AOUT = (int)0xFFFFFFFF
} PinName;

View File

@ -251,6 +251,8 @@ typedef enum {
USBTX = UART_TX,
USBRX = UART_RX,
CY_WIFI_HOST_WAKE = P2_7,
AOUT = P9_6
} PinName;

View File

@ -233,6 +233,8 @@ typedef enum {
USBTX = UART_TX,
USBRX = UART_RX,
CY_WIFI_HOST_WAKE = P2_7,
// Not connected
AOUT = (int)0xFFFFFFFF
} PinName;

View File

@ -379,26 +379,26 @@ extern "C" {
#endif
#define BT_POWER_HSIOM ioss_0_port_3_pin_4_HSIOM
#define BT_POWER_IRQ ioss_interrupts_gpio_3_IRQn
#define BT_HOST_WAKE_PORT GPIO_PRT3
#define BT_HOST_WAKE_PIN 5U
#define BT_HOST_WAKE_NUM 5U
#define BT_HOST_WAKE_PORT GPIO_PRT4
#define BT_HOST_WAKE_PIN 0U
#define BT_HOST_WAKE_NUM 0U
#define BT_HOST_WAKE_DRIVEMODE CY_GPIO_DM_ANALOG
#define BT_HOST_WAKE_INIT_DRIVESTATE 0
#ifndef ioss_0_port_3_pin_5_HSIOM
#define ioss_0_port_3_pin_5_HSIOM HSIOM_SEL_GPIO
#endif
#define BT_HOST_WAKE_HSIOM ioss_0_port_3_pin_5_HSIOM
#define BT_HOST_WAKE_IRQ ioss_interrupts_gpio_3_IRQn
#define BT_DEVICE_WAKE_PORT GPIO_PRT4
#define BT_DEVICE_WAKE_PIN 0U
#define BT_DEVICE_WAKE_NUM 0U
#define BT_DEVICE_WAKE_DRIVEMODE CY_GPIO_DM_STRONG_IN_OFF
#define BT_DEVICE_WAKE_INIT_DRIVESTATE 0
#ifndef ioss_0_port_4_pin_0_HSIOM
#define ioss_0_port_4_pin_0_HSIOM HSIOM_SEL_GPIO
#endif
#define BT_DEVICE_WAKE_HSIOM ioss_0_port_4_pin_0_HSIOM
#define BT_DEVICE_WAKE_IRQ ioss_interrupts_gpio_4_IRQn
#define BT_HOST_WAKE_HSIOM ioss_0_port_4_pin_0_HSIOM
#define BT_HOST_WAKE_IRQ ioss_interrupts_gpio_4_IRQn
#define BT_DEVICE_WAKE_PORT GPIO_PRT3
#define BT_DEVICE_WAKE_PIN 5U
#define BT_DEVICE_WAKE_NUM 5U
#define BT_DEVICE_WAKE_DRIVEMODE CY_GPIO_DM_STRONG_IN_OFF
#define BT_DEVICE_WAKE_INIT_DRIVESTATE 0
#ifndef ioss_0_port_3_pin_5_HSIOM
#define ioss_0_port_3_pin_5_HSIOM HSIOM_SEL_GPIO
#endif
#define BT_DEVICE_WAKE_HSIOM ioss_0_port_3_pin_5_HSIOM
#define BT_DEVICE_WAKE_IRQ ioss_interrupts_gpio_3_IRQn
#define EZI2C_SCL_PORT GPIO_PRT6
#define EZI2C_SCL_PIN 0U
#define EZI2C_SCL_NUM 0U

View File

@ -176,8 +176,8 @@ typedef enum {
BT_UART_RTS = P3_2,
BT_PIN_POWER = P3_4,
BT_PIN_HOST_WAKE = P3_5,
BT_PIN_DEVICE_WAKE = P4_0,
BT_PIN_HOST_WAKE = P4_0,
BT_PIN_DEVICE_WAKE = P3_5,
BT_PIN_DEVICE_RESET = P4_1,
SWITCH2 = P0_4,
@ -222,6 +222,8 @@ typedef enum {
USBTX = UART_TX,
USBRX = UART_RX,
CY_WIFI_HOST_WAKE = P2_7,
// Not connected
AOUT = (int)0xFFFFFFFF
} PinName;

View File

@ -33,6 +33,7 @@
#include "cy_gpio.h"
#include "cy_scb_uart.h"
#include "cy_sysint.h"
#include "cycfg_pins.h"
#define UART_OVERSAMPLE 12
#define UART_DEFAULT_BAUDRATE 115200
@ -42,6 +43,12 @@
#define UART_RX_INTR_MASK (CY_SCB_UART_RX_TRIGGER | CY_SCB_UART_RX_OVERFLOW | \
CY_SCB_UART_RX_ERR_FRAME | CY_SCB_UART_RX_ERR_PARITY)
#ifdef MBED_TICKLESS
#define SERIAL_PM_CALLBACK_ENABLED 1
#else
#define SERIAL_PM_CALLBACK_ENABLED 0
#endif
typedef struct serial_s serial_obj_t;
#if DEVICE_SERIAL_ASYNCH
#define OBJ_P(in) (&(in->serial))
@ -382,7 +389,6 @@ static void serial_init_peripheral(serial_obj_t *obj)
Cy_SCB_UART_Enable(obj->base);
}
/*
* Callback function to handle into and out of deep sleep state transitions.
*/
@ -412,7 +418,6 @@ static cy_en_syspm_status_t serial_pm_callback(cy_stc_syspm_callback_params_t *c
}
break;
case CY_SYSPM_CHECK_FAIL:
/* Enable the UART to operate */
Cy_SCB_UART_Enable(obj->base);
@ -437,7 +442,6 @@ static cy_en_syspm_status_t serial_pm_callback(cy_stc_syspm_callback_params_t *c
}
#endif /* DEVICE_SLEEP && DEVICE_LPTICKER && SERIAL_PM_CALLBACK_ENABLED */
void serial_init(serial_t *obj_in, PinName tx, PinName rx)
{
serial_obj_t *obj = OBJ_P(obj_in);