@@ -30,19 +30,27 @@ extern const int brcm_patch_ram_length;
3030extern const uint8_t brcm_patchram_buf[];
3131
3232static const uint8_t pre_brcm_patchram_buf[] = {
33- // RESET followed by download mini driver cmd
33+ // RESET followed by update uart baudrate
3434 0x03 , 0x0C , 0x00 ,
35+ 0x18 , 0xFC , 0x06 , 0x00 , 0x00 , 0xC0 , 0xC6 , 0x2D , 0x00 , // update uart baudrate 3 mbp
36+ };
37+
38+ static const uint8_t pre_brcm_patchram_buf2[] = {
39+ // download mini driver
3540 0x2E , 0xFC , 0x00 ,
3641};
42+
3743static const uint8_t post_brcm_patchram_buf[] = {
3844 // RESET cmd
3945 0x03 , 0x0C , 0x00 ,
4046};
4147
4248static const int pre_brcm_patch_ram_length = sizeof (pre_brcm_patchram_buf);
49+ static const int pre_brcm_patch_ram_length2 = sizeof (pre_brcm_patchram_buf2);
4350static const int post_brcm_patch_ram_length = sizeof (post_brcm_patchram_buf);
4451
4552#define HCI_RESET_RAND_CNT 4
53+ #define HCI_VS_CMD_UPDATE_UART_BAUD_RATE 0xFC18
4654#define HCI_VS_CMD_SET_SLEEP_MODE 0xFC27
4755
4856
@@ -55,7 +63,7 @@ namespace cypress {
5563class HCIDriver : public cordio ::CordioHCIDriver {
5664public:
5765 HCIDriver (
58- cordio::CordioHCITransportDriver & transport_driver,
66+ ble::vendor::cypress_ble::CyH4TransportDriver & transport_driver,
5967 PinName bt_power_name,
6068 bool ps_enabled,
6169 uint8_t host_wake_irq,
@@ -70,7 +78,8 @@ class HCIDriver : public cordio::CordioHCIDriver {
7078 service_pack_ptr(0 ),
7179 service_pack_length(0 ),
7280 service_pack_next(),
73- service_pack_transfered(false ) {
81+ service_pack_transfered(false ),
82+ cy_transport_driver(transport_driver) {
7483 }
7584
7685 virtual cordio::buf_pool_desc_t get_buffer_pool_description ()
@@ -81,6 +90,9 @@ class HCIDriver : public cordio::CordioHCIDriver {
8190
8291 virtual void do_initialize ()
8392 {
93+ // Prevent PSoC6 to enter deep-sleep till BT initialization is complete
94+ sleep_manager_lock_deep_sleep ();
95+ rtos::ThisThread::sleep_for (500 );
8496 bt_power = 1 ;
8597 rtos::ThisThread::sleep_for (500 );
8698 }
@@ -113,6 +125,40 @@ class HCIDriver : public cordio::CordioHCIDriver {
113125
114126 /* decode opcode */
115127 switch (opcode) {
128+ case HCI_VS_CMD_UPDATE_UART_BAUD_RATE:
129+ cy_transport_driver.update_uart_baud_rate (DEF_BT_3M_BAUD_RATE);
130+ #ifdef CY_DEBUG
131+ HciReadLocalVerInfoCmd ();
132+ #else
133+ set_sleep_mode ();
134+ #endif
135+ break ;
136+
137+ #ifdef CY_DEBUG
138+ case HCI_OPCODE_READ_LOCAL_VER_INFO:
139+ uint8_t hci_version;
140+ uint8_t hci_revision;
141+ uint8_t lmp_revision;
142+ uint16_t manufacturer_name;
143+
144+ BSTREAM_TO_UINT8 (hci_version, pMsg);
145+ BSTREAM_TO_UINT8 (hci_revision, pMsg);
146+ BSTREAM_TO_UINT8 (lmp_revision, pMsg);
147+ BSTREAM_TO_UINT16 (manufacturer_name, pMsg);
148+
149+ if (hci_revision == 0 || manufacturer_name == 0xF )
150+ {
151+ printf (" bt firmware download failed, rom code is being used\n " );
152+ }
153+ else
154+ {
155+ printf (" bt firmware download success\n " );
156+ }
157+
158+ set_sleep_mode ();
159+ break ;
160+ #endif
161+
116162 // Note: Reset is handled by ack_service_pack.
117163 case HCI_VS_CMD_SET_SLEEP_MODE:
118164 HciWriteLeHostSupport ();
@@ -263,20 +309,40 @@ class HCIDriver : public cordio::CordioHCIDriver {
263309 }
264310 }
265311
312+ #if (defined(MBED_TICKLESS) && DEVICE_SLEEP && DEVICE_LPTICKER)
313+ virtual void on_host_stack_inactivity (void )
314+ {
315+ cy_transport_driver.on_host_stack_inactivity ();
316+ }
317+ #endif
318+
266319private:
267320
268- // send pre_brcm_patchram_buf
321+ // send pre_brcm_patchram_buf issue hci reset and update baud rate on 43012
269322 void prepare_service_pack_transfert (void )
270323 {
271324 service_pack_ptr = pre_brcm_patchram_buf;
272325 service_pack_length = pre_brcm_patch_ram_length;
326+ service_pack_next = &HCIDriver::prepare_service_pack_transfert2;
327+ service_pack_index = 0 ;
328+ service_pack_transfered = false ;
329+ send_service_pack_command ();
330+ }
331+
332+ // Called one pre_brcm_patchram_buf has been transferred; send pre_brcm_patchram_buf2 update uart baudrate
333+ // on PSoC6 to send hci download minidriver
334+ void prepare_service_pack_transfert2 (void )
335+ {
336+ cy_transport_driver.update_uart_baud_rate (DEF_BT_3M_BAUD_RATE);
337+ service_pack_ptr = pre_brcm_patchram_buf2;
338+ service_pack_length = pre_brcm_patch_ram_length2;
273339 service_pack_next = &HCIDriver::start_service_pack_transfert;
274340 service_pack_index = 0 ;
275341 service_pack_transfered = false ;
276342 send_service_pack_command ();
277343 }
278344
279- // Called once pre_brcm_patchram_buf has been transferred; send brcm_patchram_buf
345+ // Called once pre_brcm_patchram_buf2 has been transferred; send brcm_patchram_buf
280346 void start_service_pack_transfert (void )
281347 {
282348 service_pack_ptr = brcm_patchram_buf;
@@ -290,6 +356,7 @@ class HCIDriver : public cordio::CordioHCIDriver {
290356 // Called once brcm_patchram_buf has been transferred; send post_brcm_patchram_buf
291357 void post_service_pack_transfert (void )
292358 {
359+ cy_transport_driver.update_uart_baud_rate (DEF_BT_BAUD_RATE);
293360 service_pack_ptr = post_brcm_patchram_buf;
294361 service_pack_length = post_brcm_patch_ram_length;
295362 service_pack_next = &HCIDriver::terminate_service_pack_transfert;;
@@ -307,7 +374,8 @@ class HCIDriver : public cordio::CordioHCIDriver {
307374 service_pack_next = NULL ;
308375 service_pack_index = 0 ;
309376 service_pack_transfered = true ;
310- set_sleep_mode ();
377+ HciUpdateUartBaudRate ();
378+ sleep_manager_unlock_deep_sleep ();
311379 }
312380
313381 void send_service_pack_command (void )
@@ -354,7 +422,11 @@ class HCIDriver : public cordio::CordioHCIDriver {
354422 pBuf[HCI_CMD_HDR_LEN] = 0x00 ; // no sleep
355423 }
356424 pBuf[HCI_CMD_HDR_LEN + 1 ] = 0x00 ; // no idle threshold host (N/A)
357- pBuf[HCI_CMD_HDR_LEN + 2 ] = 0x00 ; // no idle threshold HC (N/A)
425+ if (is_powersave_on ()) {
426+ pBuf[HCI_CMD_HDR_LEN + 2 ] = 0x05 ; // no idle threshold HC (N/A)
427+ } else {
428+ pBuf[HCI_CMD_HDR_LEN + 2 ] = 0x00 ; // no idle threshold HC (N/A)
429+ }
358430 if (is_powersave_on ()) {
359431 pBuf[HCI_CMD_HDR_LEN + 3 ] = dev_wake_irq; // BT WAKE
360432 } else {
@@ -363,15 +435,31 @@ class HCIDriver : public cordio::CordioHCIDriver {
363435 if (is_powersave_on ()) {
364436 pBuf[HCI_CMD_HDR_LEN + 4 ] = host_wake_irq; // HOST WAKE
365437 } else {
366- pBuf[HCI_CMD_HDR_LEN + 3 ] = 0x00 ; // BT WAKE
438+ pBuf[HCI_CMD_HDR_LEN + 4 ] = 0x00 ; // HOST WAKE
367439 }
368440 pBuf[HCI_CMD_HDR_LEN + 5 ] = 0x00 ; // Sleep during SCO
369441 pBuf[HCI_CMD_HDR_LEN + 6 ] = 0x00 ; // Combining sleep mode and SCM
370442 pBuf[HCI_CMD_HDR_LEN + 7 ] = 0x00 ; // Tristate TX
371443 pBuf[HCI_CMD_HDR_LEN + 8 ] = 0x00 ; // Active connection handling on suspend
372444 pBuf[HCI_CMD_HDR_LEN + 9 ] = 0x00 ; // resume timeout
373445 pBuf[HCI_CMD_HDR_LEN + 10 ] = 0x00 ; // break to host
374- pBuf[HCI_CMD_HDR_LEN + 10 ] = 0x00 ; // Pulsed host wake
446+ pBuf[HCI_CMD_HDR_LEN + 11 ] = 0x00 ; // Pulsed host wake
447+ hciCmdSend (pBuf);
448+ }
449+ }
450+
451+ // 0x18, 0xFC, 0x06, 0x00, 0x00, 0xC0, 0xC6, 0x2D, 0x00, //update uart baudrate 3 mbp
452+ void HciUpdateUartBaudRate ()
453+ {
454+ uint8_t *pBuf;
455+ if ((pBuf = hciCmdAlloc (HCI_VS_CMD_UPDATE_UART_BAUD_RATE, 6 )) != NULL )
456+ {
457+ pBuf[HCI_CMD_HDR_LEN] = 0x00 ; // encoded_baud_rate
458+ pBuf[HCI_CMD_HDR_LEN + 1 ] = 0x00 ; // use_encoded_form
459+ pBuf[HCI_CMD_HDR_LEN + 2 ] = 0xC0 ; // explicit baud rate bit 0-7
460+ pBuf[HCI_CMD_HDR_LEN + 3 ] = 0xC6 ; // explicit baud rate bit 8-15
461+ pBuf[HCI_CMD_HDR_LEN + 4 ] = 0x2D ; // explicit baud rate bit 16-23
462+ pBuf[HCI_CMD_HDR_LEN + 5 ] = 0x00 ; // explicit baud rate bit 24-31
375463 hciCmdSend (pBuf);
376464 }
377465 }
@@ -440,6 +528,7 @@ class HCIDriver : public cordio::CordioHCIDriver {
440528 int service_pack_length;
441529 void (HCIDriver::*service_pack_next)();
442530 bool service_pack_transfered;
531+ ble::vendor::cypress_ble::CyH4TransportDriver& cy_transport_driver;
443532
444533};
445534
0 commit comments