mirror of https://github.com/ARMmbed/mbed-os.git
commit
d9a141e50a
|
@ -29,7 +29,7 @@ CyH4TransportDriver::CyH4TransportDriver(PinName tx, PinName rx, PinName cts, Pi
|
|||
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, PullNone, 1),
|
||||
host_wake_irq_event(host_wake_irq),
|
||||
dev_wake_irq_event(dev_wake_irq)
|
||||
{
|
||||
|
@ -61,9 +61,10 @@ CyH4TransportDriver::~CyH4TransportDriver()
|
|||
|
||||
void CyH4TransportDriver::bt_host_wake_irq_handler(void)
|
||||
{
|
||||
sleep_manager_lock_deep_sleep();
|
||||
CyH4TransportDriver::on_controller_irq();
|
||||
sleep_manager_unlock_deep_sleep();
|
||||
uart.attach(
|
||||
callback(this, &CyH4TransportDriver::on_controller_irq),
|
||||
SerialBase::RxIrq
|
||||
);
|
||||
}
|
||||
|
||||
void CyH4TransportDriver::initialize()
|
||||
|
@ -72,6 +73,8 @@ void CyH4TransportDriver::initialize()
|
|||
InterruptIn *host_wake_pin;
|
||||
#endif
|
||||
|
||||
sleep_manager_lock_deep_sleep();
|
||||
|
||||
uart.format(
|
||||
/* bits */ 8,
|
||||
/* parity */ SerialBase::None,
|
||||
|
@ -90,12 +93,14 @@ 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));
|
||||
if (bt_host_wake_name != NC) {
|
||||
//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
|
||||
|
@ -106,6 +111,7 @@ void CyH4TransportDriver::initialize()
|
|||
if (bt_device_wake_name != NC)
|
||||
bt_device_wake = WAKE_EVENT_ACTIVE_HIGH;
|
||||
}
|
||||
sleep_manager_unlock_deep_sleep();
|
||||
rtos::ThisThread::sleep_for(500);
|
||||
}
|
||||
|
||||
|
@ -115,6 +121,7 @@ uint16_t CyH4TransportDriver::write(uint8_t type, uint16_t len, uint8_t *pData)
|
|||
{
|
||||
uint16_t i = 0;
|
||||
|
||||
sleep_manager_lock_deep_sleep();
|
||||
assert_bt_dev_wake();
|
||||
|
||||
while (i < len + 1) {
|
||||
|
@ -125,28 +132,42 @@ uint16_t CyH4TransportDriver::write(uint8_t type, uint16_t len, uint8_t *pData)
|
|||
}
|
||||
|
||||
deassert_bt_dev_wake();
|
||||
sleep_manager_unlock_deep_sleep();
|
||||
return len;
|
||||
}
|
||||
|
||||
#if (defined(MBED_TICKLESS) && DEVICE_SLEEP && DEVICE_LPTICKER)
|
||||
void CyH4TransportDriver::on_host_stack_inactivity()
|
||||
{
|
||||
if (enabled_powersave) {
|
||||
uart.attach(NULL, SerialBase::RxIrq);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void CyH4TransportDriver::on_controller_irq()
|
||||
{
|
||||
assert_bt_dev_wake();
|
||||
sleep_manager_lock_deep_sleep();
|
||||
assert_bt_dev_wake();
|
||||
|
||||
while (uart.readable()) {
|
||||
while (uart.readable()) {
|
||||
uint8_t char_received = uart.getc();
|
||||
on_data_received(&char_received, 1);
|
||||
}
|
||||
|
||||
deassert_bt_dev_wake();
|
||||
deassert_bt_dev_wake();
|
||||
sleep_manager_unlock_deep_sleep();
|
||||
}
|
||||
|
||||
void CyH4TransportDriver::assert_bt_dev_wake()
|
||||
{
|
||||
#if (defined(MBED_TICKLESS) && DEVICE_SLEEP && DEVICE_LPTICKER)
|
||||
if (dev_wake_irq_event == WAKE_EVENT_ACTIVE_LOW) {
|
||||
bt_device_wake = WAKE_EVENT_ACTIVE_LOW;
|
||||
} else {
|
||||
bt_device_wake = WAKE_EVENT_ACTIVE_HIGH;
|
||||
if (enabled_powersave) {
|
||||
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
|
||||
}
|
||||
|
@ -154,15 +175,24 @@ void CyH4TransportDriver::assert_bt_dev_wake()
|
|||
void CyH4TransportDriver::deassert_bt_dev_wake()
|
||||
{
|
||||
#if (defined(MBED_TICKLESS) && DEVICE_SLEEP && DEVICE_LPTICKER)
|
||||
//De-assert bt_device_wake
|
||||
if (dev_wake_irq_event == WAKE_EVENT_ACTIVE_LOW) {
|
||||
bt_device_wake = WAKE_EVENT_ACTIVE_HIGH;
|
||||
} else {
|
||||
bt_device_wake = WAKE_EVENT_ACTIVE_LOW;
|
||||
if (enabled_powersave) {
|
||||
wait_us(5000); /* remove and replace when uart tx transmit complete api is available */
|
||||
//De-assert bt_device_wake
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
void CyH4TransportDriver::update_uart_baud_rate(int baud)
|
||||
{
|
||||
uart.baud(baud);
|
||||
}
|
||||
|
||||
bool CyH4TransportDriver::get_enabled_powersave()
|
||||
{
|
||||
return (enabled_powersave);
|
||||
|
|
|
@ -66,6 +66,12 @@ public:
|
|||
|
||||
void bt_host_wake_irq_handler();
|
||||
|
||||
#if (defined(MBED_TICKLESS) && DEVICE_SLEEP && DEVICE_LPTICKER)
|
||||
void on_host_stack_inactivity();
|
||||
#endif
|
||||
|
||||
void update_uart_baud_rate(int baud);
|
||||
|
||||
bool get_enabled_powersave();
|
||||
uint8_t get_host_wake_irq_event();
|
||||
uint8_t get_dev_wake_irq_event();
|
||||
|
@ -101,10 +107,15 @@ private:
|
|||
} // namespace ble
|
||||
|
||||
#define DEF_BT_BAUD_RATE (115200)
|
||||
#define DEF_BT_3M_BAUD_RATE (3000000) /* Both Host and BT device have to be adapt to this */
|
||||
|
||||
#define WAKE_EVENT_ACTIVE_HIGH ( 1 ) /* Interrupt Rising Edge */
|
||||
#define WAKE_EVENT_ACTIVE_LOW ( 0 ) /* Interrupt Falling Edge */
|
||||
|
||||
#if (defined(TARGET_CY8CPROTO_062_4343W))
|
||||
#define BT_UART_NO_3M_SUPPORT ( 1 )
|
||||
#endif
|
||||
|
||||
ble::vendor::cypress_ble::CyH4TransportDriver& ble_cordio_get_default_h4_transport_driver();
|
||||
ble::vendor::cypress_ble::CyH4TransportDriver& ble_cordio_get_h4_transport_driver();
|
||||
#endif
|
||||
|
|
|
@ -29,20 +29,35 @@
|
|||
extern const int brcm_patch_ram_length;
|
||||
extern const uint8_t brcm_patchram_buf[];
|
||||
|
||||
#ifndef BT_UART_NO_3M_SUPPORT
|
||||
static const uint8_t pre_brcm_patchram_buf[] = {
|
||||
// RESET followed by download mini driver cmd
|
||||
// RESET followed by update uart baudrate
|
||||
0x03, 0x0C, 0x00,
|
||||
0x18, 0xFC, 0x06, 0x00, 0x00, 0xC0, 0xC6, 0x2D, 0x00, //update uart baudrate 3 mbp
|
||||
};
|
||||
#else /* BT_UART_NO_3M_SUPPORT */
|
||||
static const uint8_t pre_brcm_patchram_buf[] = {
|
||||
// RESET cmd
|
||||
0x03, 0x0C, 0x00,
|
||||
};
|
||||
#endif /* BT_UART_NO_3M_SUPPORT */
|
||||
|
||||
static const uint8_t pre_brcm_patchram_buf2[] = {
|
||||
//download mini driver
|
||||
0x2E, 0xFC, 0x00,
|
||||
};
|
||||
|
||||
static const uint8_t post_brcm_patchram_buf[] = {
|
||||
// RESET cmd
|
||||
0x03, 0x0C, 0x00,
|
||||
};
|
||||
|
||||
static const int pre_brcm_patch_ram_length = sizeof(pre_brcm_patchram_buf);
|
||||
static const int pre_brcm_patch_ram_length2 = sizeof(pre_brcm_patchram_buf2);
|
||||
static const int post_brcm_patch_ram_length = sizeof(post_brcm_patchram_buf);
|
||||
|
||||
#define HCI_RESET_RAND_CNT 4
|
||||
#define HCI_VS_CMD_UPDATE_UART_BAUD_RATE 0xFC18
|
||||
#define HCI_VS_CMD_SET_SLEEP_MODE 0xFC27
|
||||
|
||||
|
||||
|
@ -55,7 +70,7 @@ namespace cypress {
|
|||
class HCIDriver : public cordio::CordioHCIDriver {
|
||||
public:
|
||||
HCIDriver(
|
||||
cordio::CordioHCITransportDriver& transport_driver,
|
||||
ble::vendor::cypress_ble::CyH4TransportDriver& transport_driver,
|
||||
PinName bt_power_name,
|
||||
bool ps_enabled,
|
||||
uint8_t host_wake_irq,
|
||||
|
@ -70,7 +85,8 @@ public:
|
|||
service_pack_ptr(0),
|
||||
service_pack_length(0),
|
||||
service_pack_next(),
|
||||
service_pack_transfered(false) {
|
||||
service_pack_transfered(false),
|
||||
cy_transport_driver(transport_driver) {
|
||||
}
|
||||
|
||||
virtual cordio::buf_pool_desc_t get_buffer_pool_description()
|
||||
|
@ -81,6 +97,9 @@ public:
|
|||
|
||||
virtual void do_initialize()
|
||||
{
|
||||
//Prevent PSoC6 to enter deep-sleep till BT initialization is complete
|
||||
sleep_manager_lock_deep_sleep();
|
||||
rtos::ThisThread::sleep_for(500);
|
||||
bt_power = 1;
|
||||
rtos::ThisThread::sleep_for(500);
|
||||
}
|
||||
|
@ -113,6 +132,42 @@ public:
|
|||
|
||||
/* decode opcode */
|
||||
switch (opcode) {
|
||||
case HCI_VS_CMD_UPDATE_UART_BAUD_RATE:
|
||||
#ifndef BT_UART_NO_3M_SUPPORT
|
||||
cy_transport_driver.update_uart_baud_rate(DEF_BT_3M_BAUD_RATE);
|
||||
#endif /* BT_UART_NO_3M_SUPPORT */
|
||||
#ifdef CY_DEBUG
|
||||
HciReadLocalVerInfoCmd();
|
||||
#else
|
||||
set_sleep_mode();
|
||||
#endif
|
||||
break;
|
||||
|
||||
#ifdef CY_DEBUG
|
||||
case HCI_OPCODE_READ_LOCAL_VER_INFO:
|
||||
uint8_t hci_version;
|
||||
uint8_t hci_revision;
|
||||
uint8_t lmp_revision;
|
||||
uint16_t manufacturer_name;
|
||||
|
||||
BSTREAM_TO_UINT8(hci_version, pMsg);
|
||||
BSTREAM_TO_UINT8(hci_revision, pMsg);
|
||||
BSTREAM_TO_UINT8(lmp_revision, pMsg);
|
||||
BSTREAM_TO_UINT16(manufacturer_name, pMsg);
|
||||
|
||||
if(hci_revision == 0 || manufacturer_name == 0xF)
|
||||
{
|
||||
printf("bt firmware download failed, rom code is being used\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("bt firmware download success\n");
|
||||
}
|
||||
|
||||
set_sleep_mode();
|
||||
break;
|
||||
#endif
|
||||
|
||||
// Note: Reset is handled by ack_service_pack.
|
||||
case HCI_VS_CMD_SET_SLEEP_MODE:
|
||||
HciWriteLeHostSupport();
|
||||
|
@ -263,20 +318,42 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
#if (defined(MBED_TICKLESS) && DEVICE_SLEEP && DEVICE_LPTICKER)
|
||||
virtual void on_host_stack_inactivity(void)
|
||||
{
|
||||
cy_transport_driver.on_host_stack_inactivity();
|
||||
}
|
||||
#endif
|
||||
|
||||
private:
|
||||
|
||||
// send pre_brcm_patchram_buf
|
||||
// send pre_brcm_patchram_buf issue hci reset and update baud rate on 43012
|
||||
void prepare_service_pack_transfert(void)
|
||||
{
|
||||
service_pack_ptr = pre_brcm_patchram_buf;
|
||||
service_pack_length = pre_brcm_patch_ram_length;
|
||||
service_pack_next = &HCIDriver::prepare_service_pack_transfert2;
|
||||
service_pack_index = 0;
|
||||
service_pack_transfered = false;
|
||||
send_service_pack_command();
|
||||
}
|
||||
|
||||
// Called one pre_brcm_patchram_buf has been transferred; send pre_brcm_patchram_buf2 update uart baudrate
|
||||
// on PSoC6 to send hci download minidriver
|
||||
void prepare_service_pack_transfert2(void)
|
||||
{
|
||||
#ifndef BT_UART_NO_3M_SUPPORT
|
||||
cy_transport_driver.update_uart_baud_rate(DEF_BT_3M_BAUD_RATE);
|
||||
#endif /* BT_UART_NO_3M_SUPPORT */
|
||||
service_pack_ptr = pre_brcm_patchram_buf2;
|
||||
service_pack_length = pre_brcm_patch_ram_length2;
|
||||
service_pack_next = &HCIDriver::start_service_pack_transfert;
|
||||
service_pack_index = 0;
|
||||
service_pack_transfered = false;
|
||||
send_service_pack_command();
|
||||
}
|
||||
|
||||
// Called once pre_brcm_patchram_buf has been transferred; send brcm_patchram_buf
|
||||
// Called once pre_brcm_patchram_buf2 has been transferred; send brcm_patchram_buf
|
||||
void start_service_pack_transfert(void)
|
||||
{
|
||||
service_pack_ptr = brcm_patchram_buf;
|
||||
|
@ -290,6 +367,7 @@ private:
|
|||
// Called once brcm_patchram_buf has been transferred; send post_brcm_patchram_buf
|
||||
void post_service_pack_transfert(void)
|
||||
{
|
||||
cy_transport_driver.update_uart_baud_rate(DEF_BT_BAUD_RATE);
|
||||
service_pack_ptr = post_brcm_patchram_buf;
|
||||
service_pack_length = post_brcm_patch_ram_length;
|
||||
service_pack_next = &HCIDriver::terminate_service_pack_transfert;;
|
||||
|
@ -307,7 +385,12 @@ private:
|
|||
service_pack_next = NULL;
|
||||
service_pack_index = 0;
|
||||
service_pack_transfered = true;
|
||||
#ifndef BT_UART_NO_3M_SUPPORT
|
||||
HciUpdateUartBaudRate();
|
||||
#else /* BT_UART_NO_3M_SUPPORT */
|
||||
set_sleep_mode();
|
||||
#endif /* BT_UART_NO_3M_SUPPORT */
|
||||
sleep_manager_unlock_deep_sleep();
|
||||
}
|
||||
|
||||
void send_service_pack_command(void)
|
||||
|
@ -354,7 +437,11 @@ private:
|
|||
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 + 2] = 0x05; // no idle threshold HC (N/A)
|
||||
} else {
|
||||
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 {
|
||||
|
@ -363,7 +450,7 @@ private:
|
|||
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 + 4] = 0x00; // HOST WAKE
|
||||
}
|
||||
pBuf[HCI_CMD_HDR_LEN + 5] = 0x00; // Sleep during SCO
|
||||
pBuf[HCI_CMD_HDR_LEN + 6] = 0x00; // Combining sleep mode and SCM
|
||||
|
@ -371,7 +458,23 @@ private:
|
|||
pBuf[HCI_CMD_HDR_LEN + 8] = 0x00; // Active connection handling on suspend
|
||||
pBuf[HCI_CMD_HDR_LEN + 9] = 0x00; // resume timeout
|
||||
pBuf[HCI_CMD_HDR_LEN + 10] = 0x00; // break to host
|
||||
pBuf[HCI_CMD_HDR_LEN + 10] = 0x00; // Pulsed host wake
|
||||
pBuf[HCI_CMD_HDR_LEN + 11] = 0x00; // Pulsed host wake
|
||||
hciCmdSend(pBuf);
|
||||
}
|
||||
}
|
||||
|
||||
// 0x18, 0xFC, 0x06, 0x00, 0x00, 0xC0, 0xC6, 0x2D, 0x00, //update uart baudrate 3 mbp
|
||||
void HciUpdateUartBaudRate()
|
||||
{
|
||||
uint8_t *pBuf;
|
||||
if ((pBuf = hciCmdAlloc(HCI_VS_CMD_UPDATE_UART_BAUD_RATE, 6)) != NULL)
|
||||
{
|
||||
pBuf[HCI_CMD_HDR_LEN] = 0x00; // encoded_baud_rate
|
||||
pBuf[HCI_CMD_HDR_LEN + 1] = 0x00; // use_encoded_form
|
||||
pBuf[HCI_CMD_HDR_LEN + 2] = 0xC0; // explicit baud rate bit 0-7
|
||||
pBuf[HCI_CMD_HDR_LEN + 3] = 0xC6; // explicit baud rate bit 8-15
|
||||
pBuf[HCI_CMD_HDR_LEN + 4] = 0x2D; // explicit baud rate bit 16-23
|
||||
pBuf[HCI_CMD_HDR_LEN + 5] = 0x00; // explicit baud rate bit 24-31
|
||||
hciCmdSend(pBuf);
|
||||
}
|
||||
}
|
||||
|
@ -440,6 +543,7 @@ private:
|
|||
int service_pack_length;
|
||||
void (HCIDriver::*service_pack_next)();
|
||||
bool service_pack_transfered;
|
||||
ble::vendor::cypress_ble::CyH4TransportDriver& cy_transport_driver;
|
||||
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue