raspi: power cycle Bluetooth controller on start

This commit is contained in:
Matthias Ringwald 2018-07-26 08:48:36 +02:00
parent 70fddd7e64
commit 11e995b1e9
4 changed files with 98 additions and 9 deletions

View File

@ -4,6 +4,7 @@ BTSTACK_ROOT = ../..
CORE += \
btstack_chipset_bcm.c \
btstack_chipset_bcm_download_firmware.c \
btstack_control_raspi.c \
btstack_link_key_db_fs.c \
btstack_run_loop_posix.c \
btstack_uart_block_posix.c \

View File

@ -0,0 +1,86 @@
#include "btstack_control.h"
#include "btstack_debug.h"
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/ioctl.h>
// constansts for firmware interface
#define RPI_FIRMWARE_DEV "/dev/vcio"
#define IOCTL_RPI_FIRMWARE_PROPERTY _IOWR(100, 0, char*)
// firmware request messages
#define RPI_FIRMWARE_STATUS_REQUEST (0)
#define RPI_FIRMWARE_PROPERTY_END (0)
#define RPI_FIRMWARE_SET_GPIO_STATE (0x00038041)
// results
#define RPI_FIRMWARE_STATUS_SUCCESS (0x80000000)
#define RPI_FIRMWARE_STATUS_ERROR (0x80000001)
// BCM4343 power management pins on main CPU
#define BT_REG_ON (128)
#define WL_REG_ON (129)
// fd for firmware interface
static int fd = -1;
static void raspi_gpio_set(int gpio, int state){
uint32_t m[8];
m[0] = sizeof(m); // total len in bytes
m[1] = RPI_FIRMWARE_STATUS_REQUEST;
m[2] = RPI_FIRMWARE_SET_GPIO_STATE;
m[3] = 8; // request size in bytes
m[4] = 0; // request response size
m[5] = gpio;
m[6] = state ? 1 : 0;
m[7] = RPI_FIRMWARE_PROPERTY_END;;
int ioctl_result = ioctl(fd, IOCTL_RPI_FIRMWARE_PROPERTY, m);
if (ioctl_result == -1) {
log_error("ioctl: IOCTL_RPI_FIRMWARE_PROPERTY: %s", strerror(errno));
return;
}
uint32_t result = m[1];
if (result != RPI_FIRMWARE_STATUS_SUCCESS) {
log_error("ioctl: firmware result 0x%08x\n", result);
}
}
static void raspi_init (const void *config) {
UNUSED(config);
fd = open(RPI_FIRMWARE_DEV, O_NONBLOCK);
if (fd == -1) {
log_error("cannot open: %s: %s", RPI_FIRMWARE_DEV, strerror(errno));
return;
}
}
static int raspi_on (){
log_info("raspi_on");
raspi_gpio_set( BT_REG_ON, 1 );
return 0;
}
static int raspi_off(void){
log_info("raspi_off");
raspi_gpio_set( BT_REG_ON, 0 );
return 0;
}
static btstack_control_t control = {
raspi_init,
raspi_on,
raspi_off,
NULL,
NULL,
NULL
};
btstack_control_t *btstack_control_raspi_get_instance(){
return &control;
}

View File

@ -0,0 +1,3 @@
#include "btstack_control.h"
btstack_control_t *btstack_control_raspi_get_instance();

View File

@ -67,7 +67,7 @@
#include "btstack_chipset_bcm.h"
#include "btstack_chipset_bcm_download_firmware.h"
// #include "btstack_control_raspi.h"
#include "btstack_control_raspi.h"
int btstack_main(int argc, const char * argv[]);
@ -251,12 +251,8 @@ int main(int argc, const char * argv[]){
const btstack_link_key_db_t * link_key_db = btstack_link_key_db_fs_instance();
hci_init(transport, (void*) &transport_config);
hci_set_bd_addr( addr );
// btstack_control_t *control = btstack_control_raspi_get_instance();
// hci_set_control( control );
hci_set_link_key_db(link_key_db);
hci_set_chipset(btstack_chipset_bcm_instance());
hci_set_link_key_db(link_key_db);
// inform about BTstack state
hci_event_callback_registration.callback = &packet_handler;
@ -271,9 +267,12 @@ int main(int argc, const char * argv[]){
// phase #1 download firmware
printf("Phase 1: Download firmware\n");
// control->off();
// sleep( 1 );
// control->on();
// power cycle Bluetooth controller
btstack_control_t *control = btstack_control_raspi_get_instance();
control->init(NULL);
control->off();
sleep( 1 );
control->on();
// phase #2 start main app
btstack_chipset_bcm_download_firmware(uart_driver, transport_config.baudrate_main, &phase2);