Lower baudrate

This commit is contained in:
Carsten Schmiemann 2024-06-30 18:24:27 +02:00
parent 0e174ca570
commit 74ced478e0
23 changed files with 2576 additions and 2118 deletions

View file

@ -55,7 +55,7 @@ class SnifferBREDR:
# Constructor
def __init__(self,
serial_port=None,
serial_baud=921600,
serial_baud=460800,
show_summary=True,
start_wireshark=False,
save_pcap=True,
@ -187,7 +187,7 @@ class SnifferBREDR:
# Defaults
serial_port = '/dev/ttyUSB0'
serial_baud = 921600
serial_baud = 460800
@click.command()

View file

@ -1,4 +1,9 @@
# *BrakTooth* ESP32 BR/EDR Active Sniffer/Injector
# Fork informations
This is a 1:1 fork of the following project.
My version has a lowered baudrate for host communication because of cheap ESP DevBoards.
## *BrakTooth* ESP32 BR/EDR Active Sniffer/Injector
> Simple "Monitor mode" for Bluetooth Classic. Sniff or inject BR/EDR Baseband packets in ESP32 BT connections.

View file

@ -65,15 +65,13 @@
* @param bd_addr
*/
const hci_cmd_t hci_vendor_em_set_public_address = {
0xFC02, "B"
};
0xFC02, "B"};
/**
* @param baud_rate_index
*/
const hci_cmd_t hci_vendor_em_set_uart_baudrate = {
0xFC07, "1"
};
0xFC07, "1"};
/**
* @param transmitter_test_mode
@ -82,36 +80,31 @@ const hci_cmd_t hci_vendor_em_set_uart_baudrate = {
* @param packet_payload_type
*/
const hci_cmd_t hci_vendor_em_transmitter_test = {
0xFC11, "1111"
};
0xFC11, "1111"};
/**
*/
const hci_cmd_t hci_vendor_em_transmitter_test_end = {
0xFC12, ""
};
0xFC12, ""};
/**
* @param patch_index
*/
const hci_cmd_t hci_vendor_em_patch_query = {
0xFC34, "2"
};
0xFC34, "2"};
/**
* Change the state of the selected memory.
* @param memory_attribute
*/
const hci_cmd_t hci_vendor_em_set_memory_mode = {
0xFC2B, "1"
};
0xFC2B, "1"};
/**
* @param sleep_option_settings
*/
const hci_cmd_t hci_vendor_em_set_sleep_options = {
0xFC2D, "1"
};
0xFC2D, "1"};
// baudrate to index for hci_vendor_em_set_uart_baudrate
static const uint32_t baudrates[] = {
@ -128,7 +121,7 @@ static const uint32_t baudrates[] = {
115200,
230400,
460800,
921600,
460800,
1843200,
};
@ -147,18 +140,18 @@ static enum {
UPLOAD_ACTIVE,
} upload_state;
// CRC32 implementation using 4-bit lookup table created by pycrc v0.9.1, https://pycrc.org
// ./pycrc.py --model crc-32 --algorithm table-driven --table-idx-width=4 --generate c
static const uint32_t crc32_table[16] = {
0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac, 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c, 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c
};
0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c, 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c};
static uint32_t btstack_crc32(const uint8_t *buf, uint16_t size){
static uint32_t btstack_crc32(const uint8_t *buf, uint16_t size)
{
uint16_t pos;
uint32_t crc = 0xffffffff;
for (pos=0 ; pos<size ; pos++){
for (pos = 0; pos < size; pos++)
{
int tbl_idx = crc ^ buf[pos];
crc = crc32_table[tbl_idx & 0x0f] ^ (crc >> 4);
tbl_idx = crc ^ (buf[pos] >> 4);
@ -169,23 +162,28 @@ static uint32_t btstack_crc32(const uint8_t *buf, uint16_t size){
#endif
static void chipset_set_bd_addr_command(bd_addr_t addr, uint8_t *hci_cmd_buffer){
static void chipset_set_bd_addr_command(bd_addr_t addr, uint8_t *hci_cmd_buffer)
{
little_endian_store_16(hci_cmd_buffer, 0, OPCODE(OGF_VENDOR, 0x02));
hci_cmd_buffer[2] = 0x06;
reverse_bd_addr(addr, &hci_cmd_buffer[3]);
}
static void chipset_set_baudrate_command(uint32_t baudrate, uint8_t *hci_cmd_buffer){
static void chipset_set_baudrate_command(uint32_t baudrate, uint8_t *hci_cmd_buffer)
{
// lookup baudrates
int i;
int found = 0;
for (i=0 ; i < sizeof(baudrates)/sizeof(uint32_t) ; i++){
if (baudrates[i] == baudrate){
for (i = 0; i < sizeof(baudrates) / sizeof(uint32_t); i++)
{
if (baudrates[i] == baudrate)
{
found = i;
break;
}
}
if (!found){
if (!found)
{
log_error("Baudrate %u not found in table", baudrate);
return;
}
@ -195,24 +193,30 @@ static void chipset_set_baudrate_command(uint32_t baudrate, uint8_t *hci_cmd_buf
}
#ifdef HAVE_EM9304_PATCH_CONTAINER
static void chipset_init(const void * config){
static void chipset_init(const void *config)
{
UNUSED(config);
container_blob_offset = 0;
em_cpu_reset_sent = 0;
upload_state = UPLOAD_IDLE;
}
static btstack_chipset_result_t chipset_next_command(uint8_t * hci_cmd_buffer){
static btstack_chipset_result_t chipset_next_command(uint8_t *hci_cmd_buffer)
{
log_info("pos %u, container end %u, blob size %u", container_blob_offset, container_end, container_blob_size);
if (container_blob_offset >= container_blob_size) {
if (0 == em_cpu_reset_sent){
if (container_blob_offset >= container_blob_size)
{
if (0 == em_cpu_reset_sent)
{
// send EM CPU Reset
little_endian_store_16(hci_cmd_buffer, 0, HCI_OPCODE_EM_CPU_RESET);
hci_cmd_buffer[2] = 0;
em_cpu_reset_sent = 1;
return BTSTACK_CHIPSET_VALID_COMMAND;
} else {
}
else
{
return BTSTACK_CHIPSET_DONE;
}
}
@ -222,11 +226,13 @@ static btstack_chipset_result_t chipset_next_command(uint8_t * hci_cmd_buffer){
uint32_t crc;
uint32_t container_size;
switch (upload_state){
switch (upload_state)
{
case UPLOAD_IDLE:
// check for 'em93' tag
tag = little_endian_read_32(container_blob_data, container_blob_offset);
if (0x656d3933 != tag) {
if (0x656d3933 != tag)
{
log_error("Expected 0x656d3933 ('em934') but got %08x", (int)tag);
return BTSTACK_CHIPSET_DONE;
}
@ -250,7 +256,8 @@ static btstack_chipset_result_t chipset_next_command(uint8_t * hci_cmd_buffer){
little_endian_store_32(hci_cmd_buffer, 4, crc);
memcpy(&hci_cmd_buffer[8], &container_blob_data[container_blob_offset], bytes_to_upload);
container_blob_offset += bytes_to_upload;
if (container_blob_offset < container_end){
if (container_blob_offset < container_end)
{
upload_state = UPLOAD_ACTIVE;
}
return BTSTACK_CHIPSET_VALID_COMMAND;
@ -265,7 +272,8 @@ static btstack_chipset_result_t chipset_next_command(uint8_t * hci_cmd_buffer){
little_endian_store_32(hci_cmd_buffer, 5, crc);
memcpy(&hci_cmd_buffer[9], &container_blob_data[container_blob_offset], bytes_to_upload);
container_blob_offset += bytes_to_upload;
if (container_blob_offset >= container_end){
if (container_blob_offset >= container_end)
{
log_info("container done maybe another one");
upload_state = UPLOAD_IDLE;
}
@ -292,6 +300,7 @@ static const btstack_chipset_t btstack_chipset_em9301 = {
};
// MARK: public API
const btstack_chipset_t * btstack_chipset_em9301_instance(void){
const btstack_chipset_t *btstack_chipset_em9301_instance(void)
{
return &btstack_chipset_em9301;
}

View file

@ -56,10 +56,12 @@
// should go to some common place
#define OPCODE(ogf, ocf) (ocf | ogf << 10)
static void chipset_set_baudrate_command(uint32_t baudrate, uint8_t *hci_cmd_buffer){
static void chipset_set_baudrate_command(uint32_t baudrate, uint8_t *hci_cmd_buffer)
{
// map baud rate to predefined settings
int preset = 0;
switch (baudrate){
switch (baudrate)
{
case 57600:
preset = 0x0e;
break;
@ -72,7 +74,7 @@ static void chipset_set_baudrate_command(uint32_t baudrate, uint8_t *hci_cmd_buf
case 460800:
preset = 0x13;
break;
case 921600:
case 460800:
preset = 0x14;
break;
case 1843200:
@ -96,7 +98,8 @@ static void chipset_set_baudrate_command(uint32_t baudrate, uint8_t *hci_cmd_buf
hci_cmd_buffer[3] = preset;
}
static void chipset_set_bd_addr_command(bd_addr_t addr, uint8_t *hci_cmd_buffer){
static void chipset_set_bd_addr_command(bd_addr_t addr, uint8_t *hci_cmd_buffer)
{
little_endian_store_16(hci_cmd_buffer, 0, OPCODE(OGF_VENDOR, 0x22));
hci_cmd_buffer[2] = 0x08;
hci_cmd_buffer[3] = 254;
@ -113,6 +116,7 @@ static const btstack_chipset_t btstack_chipset_stlc2500d = {
};
// MARK: public API
const btstack_chipset_t * btstack_chipset_stlc2500d_instance(void){
const btstack_chipset_t *btstack_chipset_stlc2500d_instance(void)
{
return &btstack_chipset_stlc2500d;
}

View file

@ -61,10 +61,12 @@
static const uint8_t baudrate_command[] = {0x08, 0xfc, 0x11, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x14, 0x42, 0xff, 0x10, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
static void chipset_set_baudrate_command(uint32_t baudrate, uint8_t *hci_cmd_buffer){
static void chipset_set_baudrate_command(uint32_t baudrate, uint8_t *hci_cmd_buffer)
{
uint16_t div1 = 0;
uint8_t div2 = 0;
switch (baudrate) {
switch (baudrate)
{
case 115200:
div1 = 0x001A;
div2 = 0x60;
@ -77,7 +79,7 @@ static void chipset_set_baudrate_command(uint32_t baudrate, uint8_t *hci_cmd_buf
div1 = 0x0005;
div2 = 0xA0;
break;
case 921600:
case 460800:
div1 = 0x0003;
div2 = 0x70;
break;
@ -91,7 +93,8 @@ static void chipset_set_baudrate_command(uint32_t baudrate, uint8_t *hci_cmd_buf
hci_cmd_buffer[15] = div2;
}
static void chipset_set_bd_addr_command(bd_addr_t addr, uint8_t *hci_cmd_buffer){
static void chipset_set_bd_addr_command(bd_addr_t addr, uint8_t *hci_cmd_buffer)
{
// OGF 0x04 - Informational Parameters, OCF 0x10
hci_cmd_buffer[0] = 0x13;
hci_cmd_buffer[1] = 0x10;
@ -108,6 +111,7 @@ static const btstack_chipset_t btstack_chipset_tc3566x = {
};
// MARK: public API
const btstack_chipset_t * btstack_chipset_tc3566x_instance(void){
const btstack_chipset_t *btstack_chipset_tc3566x_instance(void)
{
return &btstack_chipset_tc3566x;
}

View file

@ -51,8 +51,6 @@
*/
// *****************************************************************************
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
@ -81,12 +79,12 @@ static bd_addr_t device_addr;
* To send and receive an audio signal, ENABLE_SCO_OVER_HCI has to be defined.
*
* Tested working setups:
* - Ubuntu 14 64-bit, CC2564B connected via FTDI USB-2-UART adapter, 921600 baud
* - Ubuntu 14 64-bit, CC2564B connected via FTDI USB-2-UART adapter, 460800 baud
* - Ubuntu 14 64-bit, CSR USB dongle
* - OS X 10.11, CSR USB dongle
*
* Broken setups:
* - OS X 10.11, CC2564B connected via FDTI USB-2-UART adapter, 921600 baud
* - OS X 10.11, CC2564B connected via FDTI USB-2-UART adapter, 460800 baud
* - select(..) blocks > 400 ms -> num completed is received to late -> gaps between audio
* - looks like bug in select->FTDI driver as it works correct on Linux
*
@ -98,10 +96,9 @@ static bd_addr_t device_addr;
*
*/
#ifdef HAVE_BTSTACK_STDIN
static void show_usage(void){
static void show_usage(void)
{
bd_addr_t iut_address;
gap_local_bd_addr(iut_address);
@ -123,8 +120,10 @@ static void show_usage(void){
printf("\n");
}
static void stdin_process(char c){
switch (c){
static void stdin_process(char c)
{
switch (c)
{
case 'a':
printf("Establish audio connection\n");
hsp_ag_establish_audio_connection();
@ -180,21 +179,26 @@ static void stdin_process(char c){
}
#endif
static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t * event, uint16_t event_size){
static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *event, uint16_t event_size)
{
UNUSED(channel);
uint8_t status;
switch (packet_type){
switch (packet_type)
{
case HCI_SCO_DATA_PACKET:
if (READ_SCO_CONNECTION_HANDLE(event) != sco_handle) break;
if (READ_SCO_CONNECTION_HANDLE(event) != sco_handle)
break;
sco_demo_receive(event, event_size);
break;
case HCI_EVENT_PACKET:
switch (hci_event_packet_get_type(event)) {
switch (hci_event_packet_get_type(event))
{
#ifndef HAVE_BTSTACK_STDIN
case BTSTACK_EVENT_STATE:
if (btstack_event_state_get_state(event) != HCI_STATE_WORKING) break;
if (btstack_event_state_get_state(event) != HCI_STATE_WORKING)
break;
printf("Establish HSP AG service to %s...\n", device_addr_string);
hsp_ag_connect(device_addr);
break;
@ -203,10 +207,12 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t * even
sco_demo_send(sco_handle);
break;
case HCI_EVENT_HSP_META:
switch (hci_event_hsp_meta_get_subevent_code(event)) {
switch (hci_event_hsp_meta_get_subevent_code(event))
{
case HSP_SUBEVENT_RFCOMM_CONNECTION_COMPLETE:
status = hsp_subevent_rfcomm_connection_complete_get_status(event);
if (status != ERROR_CODE_SUCCESS){
if (status != ERROR_CODE_SUCCESS)
{
printf("RFCOMM connection establishement failed with status %u\n", status);
break;
}
@ -218,17 +224,23 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t * even
break;
case HSP_SUBEVENT_RFCOMM_DISCONNECTION_COMPLETE:
status = hsp_subevent_rfcomm_disconnection_complete_get_status(event);
if (status != ERROR_CODE_SUCCESS){
if (status != ERROR_CODE_SUCCESS)
{
printf("RFCOMM disconnection failed with status %u.\n", status);
} else {
}
else
{
printf("RFCOMM disconnected.\n");
}
break;
case HSP_SUBEVENT_AUDIO_CONNECTION_COMPLETE:
status = hsp_subevent_audio_connection_complete_get_status(event);
if (status != ERROR_CODE_SUCCESS){
if (status != ERROR_CODE_SUCCESS)
{
printf("Audio connection establishment failed with status %u\n", status);
} else {
}
else
{
sco_handle = hsp_subevent_audio_connection_complete_get_handle(event);
printf("Audio connection established with SCO handle 0x%04x.\n", sco_handle);
hci_request_sco_can_send_now_event();
@ -244,7 +256,8 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t * even
case HSP_SUBEVENT_SPEAKER_GAIN_CHANGED:
printf("Received speaker gain change %d\n", hsp_subevent_speaker_gain_changed_get_gain(event));
break;
case HSP_SUBEVENT_HS_COMMAND:{
case HSP_SUBEVENT_HS_COMMAND:
{
memset(hs_cmd_buffer, 0, sizeof(hs_cmd_buffer));
unsigned int cmd_length = hsp_subevent_hs_command_get_value_length(event);
unsigned int size = cmd_length <= sizeof(hs_cmd_buffer) ? cmd_length : sizeof(hs_cmd_buffer);
@ -253,10 +266,13 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t * even
break;
}
case HSP_SUBEVENT_BUTTON_PRESSED:
if (sco_handle == HCI_CON_HANDLE_INVALID){
if (sco_handle == HCI_CON_HANDLE_INVALID)
{
printf("Button event -> establish audio\n");
hsp_ag_establish_audio_connection();
} else {
}
else
{
printf("Button event -> release audio\n");
hsp_ag_release_audio_connection();
}
@ -291,7 +307,8 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t * even
/* LISTING_START(MainConfiguration): Setup HSP Audio Gateway */
int btstack_main(int argc, const char *argv[]);
int btstack_main(int argc, const char * argv[]){
int btstack_main(int argc, const char *argv[])
{
(void)argc;
(void)argv;

View file

@ -82,12 +82,12 @@ static bd_addr_t device_addr;
* To send and receive an audio signal, ENABLE_SCO_OVER_HCI has to be defined.
*
* Tested working setups:
* - Ubuntu 14 64-bit, CC2564B connected via FTDI USB-2-UART adapter, 921600 baud
* - Ubuntu 14 64-bit, CC2564B connected via FTDI USB-2-UART adapter, 460800 baud
* - Ubuntu 14 64-bit, CSR USB dongle
* - OS X 10.11, CSR USB dongle
*
* Broken setups:
* - OS X 10.11, CC2564B connected via FDTI USB-2-UART adapter, 921600 baud
* - OS X 10.11, CC2564B connected via FDTI USB-2-UART adapter, 460800 baud
* - select(..) blocks > 400 ms -> num completed is received to late -> gaps between audio
* - looks like bug in select->FTDI driver as it works correct on Linux
*
@ -99,8 +99,8 @@ static bd_addr_t device_addr;
*
*/
static void show_usage(void){
static void show_usage(void)
{
bd_addr_t iut_address;
gap_local_bd_addr(iut_address);
@ -121,8 +121,10 @@ static void show_usage(void){
}
#ifdef HAVE_BTSTACK_STDIN
static void stdin_process(char c){
switch (c){
static void stdin_process(char c)
{
switch (c)
{
case 'c':
printf("Connect to %s\n", bd_addr_to_str(device_addr));
hsp_hs_connect(device_addr);
@ -175,47 +177,62 @@ static void stdin_process(char c){
}
#endif
static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t * event, uint16_t event_size){
static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *event, uint16_t event_size)
{
UNUSED(channel);
uint8_t status;
switch (packet_type){
switch (packet_type)
{
case HCI_SCO_DATA_PACKET:
sco_demo_receive(event, event_size);
break;
case HCI_EVENT_PACKET:
switch (hci_event_packet_get_type(event)) {
switch (hci_event_packet_get_type(event))
{
case BTSTACK_EVENT_STATE:
if (btstack_event_state_get_state(event) != HCI_STATE_WORKING) break;
if (btstack_event_state_get_state(event) != HCI_STATE_WORKING)
break;
show_usage();
break;
case HCI_EVENT_SCO_CAN_SEND_NOW:
if (READ_SCO_CONNECTION_HANDLE(event) != sco_handle) break;
if (READ_SCO_CONNECTION_HANDLE(event) != sco_handle)
break;
sco_demo_send(sco_handle);
break;
case HCI_EVENT_HSP_META:
switch (hci_event_hsp_meta_get_subevent_code(event)) {
switch (hci_event_hsp_meta_get_subevent_code(event))
{
case HSP_SUBEVENT_RFCOMM_CONNECTION_COMPLETE:
status = hsp_subevent_rfcomm_connection_complete_get_status(event);
if (status != ERROR_CODE_SUCCESS){
if (status != ERROR_CODE_SUCCESS)
{
printf("RFCOMM connection establishement failed with status %u\n", status);
} else {
}
else
{
printf("RFCOMM connection established.\n");
}
break;
case HSP_SUBEVENT_RFCOMM_DISCONNECTION_COMPLETE:
status = hsp_subevent_rfcomm_disconnection_complete_get_status(event);
if (status != ERROR_CODE_SUCCESS){
if (status != ERROR_CODE_SUCCESS)
{
printf("RFCOMM disconnection failed with status %u.\n", status);
} else {
}
else
{
printf("RFCOMM disconnected.\n");
}
break;
case HSP_SUBEVENT_AUDIO_CONNECTION_COMPLETE:
status = hsp_subevent_audio_connection_complete_get_status(event);
if (status != ERROR_CODE_SUCCESS){
if (status != ERROR_CODE_SUCCESS)
{
printf("Audio connection establishment failed with status %u\n", status);
} else {
}
else
{
sco_handle = hsp_subevent_audio_connection_complete_get_handle(event);
printf("Audio connection established with SCO handle 0x%04x.\n", sco_handle);
hci_request_sco_can_send_now_event();
@ -234,10 +251,12 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t * even
case HSP_SUBEVENT_RING:
printf("HS: RING RING!\n");
break;
case HSP_SUBEVENT_AG_INDICATION: {
case HSP_SUBEVENT_AG_INDICATION:
{
memset(hs_cmd_buffer, 0, sizeof(hs_cmd_buffer));
unsigned int size = hsp_subevent_ag_indication_get_value_length(event);
if (size >= sizeof(hs_cmd_buffer)-1){
if (size >= sizeof(hs_cmd_buffer) - 1)
{
size = sizeof(hs_cmd_buffer) - 1;
}
memcpy(hs_cmd_buffer, hsp_subevent_ag_indication_get_value(event), size);
@ -273,7 +292,8 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t * even
/* LISTING_START(MainConfiguration): Setup HSP Headset */
int btstack_main(int argc, const char *argv[]);
int btstack_main(int argc, const char * argv[]){
int btstack_main(int argc, const char *argv[])
{
(void)argc;
(void)argv;

View file

@ -86,16 +86,19 @@ static uint16_t sco_tx_counter;
static void (*posix_i2s_test_bridge_packet_handler)(uint8_t packet_type, uint8_t *packet, uint16_t size);
static void posix_i2s_test_bridge_process_write(btstack_data_source_t *ds) {
static void posix_i2s_test_bridge_process_write(btstack_data_source_t *ds)
{
ssize_t bytes_to_write = BRIDGE_BLOCK_SIZE_BYTES - sco_tx_packet_pos;
ssize_t bytes_written = write(ds->source.fd, &sco_tx_packet[sco_tx_packet_pos], bytes_to_write);
if (bytes_written < 0) {
if (bytes_written < 0)
{
log_error("write returned error");
return;
}
sco_tx_packet_pos += bytes_written;
if (sco_tx_packet_pos < BRIDGE_BLOCK_SIZE_BYTES) {
if (sco_tx_packet_pos < BRIDGE_BLOCK_SIZE_BYTES)
{
return;
}
@ -103,20 +106,24 @@ static void posix_i2s_test_bridge_process_write(btstack_data_source_t *ds) {
btstack_run_loop_disable_data_source_callbacks(ds, DATA_SOURCE_CALLBACK_WRITE);
}
static void posix_i2s_test_bride_send_packet(const uint8_t *packet, uint16_t length){
static void posix_i2s_test_bride_send_packet(const uint8_t *packet, uint16_t length)
{
// ignore con handle
btstack_assert((packet[2] + 3) == length);
uint16_t i;
switch (sco_format){
switch (sco_format)
{
case SCO_FORMAT_8_BIT:
btstack_assert(length == 63);
for (i=0;i<60;i++){
for (i = 0; i < 60; i++)
{
big_endian_store_16(sco_tx_packet, i * 2, packet[3 + i]);
}
break;
case SCO_FORMAT_16_BIT:
btstack_assert(length == 123);
for (i=0;i<60;i++){
for (i = 0; i < 60; i++)
{
sco_tx_packet[i * 2] = packet[4 + i * 2];
sco_tx_packet[i * 2 + 1] = packet[3 + i * 2];
}
@ -131,21 +138,25 @@ static void posix_i2s_test_bride_send_packet(const uint8_t *packet, uint16_t len
btstack_run_loop_enable_data_source_callbacks(&sco_data_source, DATA_SOURCE_CALLBACK_WRITE);
}
static void posix_i2s_test_bridge_process_read(btstack_data_source_t *ds) {
static void posix_i2s_test_bridge_process_read(btstack_data_source_t *ds)
{
// read up to bytes_to_read data in
ssize_t bytes_to_read = BRIDGE_BLOCK_SIZE_BYTES - sco_rx_bytes_read;
ssize_t bytes_read = read(ds->source.fd, &sco_rx_buffer[sco_rx_bytes_read], bytes_to_read);
if (bytes_read == 0){
if (bytes_read == 0)
{
log_error("read zero bytes of %d bytes", (int)bytes_to_read);
return;
}
if (bytes_read < 0) {
if (bytes_read < 0)
{
log_error("read returned error");
return;
}
sco_rx_bytes_read += bytes_read;
if (sco_rx_bytes_read < BRIDGE_BLOCK_SIZE_BYTES) {
if (sco_rx_bytes_read < BRIDGE_BLOCK_SIZE_BYTES)
{
return;
}
@ -153,13 +164,15 @@ static void posix_i2s_test_bridge_process_read(btstack_data_source_t *ds) {
sco_rx_bytes_read = 0;
// already active
if (sco_handle == HCI_CON_HANDLE_INVALID) {
if (sco_handle == HCI_CON_HANDLE_INVALID)
{
log_info("drop SCO packet, no con Handle yet");
return;
}
// drop first packets
if (sco_rx_counter < BRIDGE_RX_BLOCKS_DROP) {
if (sco_rx_counter < BRIDGE_RX_BLOCKS_DROP)
{
sco_rx_counter++;
log_info("drop packet %u/%u\n", sco_rx_counter, BRIDGE_RX_BLOCKS_DROP);
return;
@ -169,18 +182,21 @@ static void posix_i2s_test_bridge_process_read(btstack_data_source_t *ds) {
uint8_t packet[BRIDGE_BLOCK_SIZE_BYTES + 3];
little_endian_store_16(packet, 0, sco_handle);
uint16_t index;
switch (sco_format) {
switch (sco_format)
{
case SCO_FORMAT_8_BIT:
// data is received big endian and transparent data is in lower byte
packet[2] = BRIDGE_BLOCK_SIZE_BYTES / 2;
for (index= 0 ; index < (BRIDGE_BLOCK_SIZE_BYTES / 2) ; index++) {
for (index = 0; index < (BRIDGE_BLOCK_SIZE_BYTES / 2); index++)
{
packet[3 + index] = sco_rx_buffer[2 * index + 1];
}
break;
case SCO_FORMAT_16_BIT:
// data is received big endian but sco packet contains little endian data -> swap bytes
packet[2] = BRIDGE_BLOCK_SIZE_BYTES;
for (index = 0 ; index < (BRIDGE_BLOCK_SIZE_BYTES / 2) ; index++) {
for (index = 0; index < (BRIDGE_BLOCK_SIZE_BYTES / 2); index++)
{
packet[3 + 2 * index] = sco_rx_buffer[2 * index + 1];
packet[4 + 2 * index] = sco_rx_buffer[2 * index];
}
@ -192,9 +208,12 @@ static void posix_i2s_test_bridge_process_read(btstack_data_source_t *ds) {
(*posix_i2s_test_bridge_packet_handler)(HCI_SCO_DATA_PACKET, packet, 3 + packet[2]);
}
static void hci_uart_posix_process(btstack_data_source_t *ds, btstack_data_source_callback_type_t callback_type) {
if (ds->source.fd < 0) return;
switch (callback_type){
static void hci_uart_posix_process(btstack_data_source_t *ds, btstack_data_source_callback_type_t callback_type)
{
if (ds->source.fd < 0)
return;
switch (callback_type)
{
case DATA_SOURCE_CALLBACK_READ:
posix_i2s_test_bridge_process_read(ds);
break;
@ -206,7 +225,8 @@ static void hci_uart_posix_process(btstack_data_source_t *ds, btstack_data_sourc
}
}
static int posix_i2s_test_bridge_set_baudrate(int fd, uint32_t baudrate){
static int posix_i2s_test_bridge_set_baudrate(int fd, uint32_t baudrate)
{
#ifdef __APPLE__
@ -218,7 +238,8 @@ static int posix_i2s_test_bridge_set_baudrate(int fd, uint32_t baudrate){
// and output speed.
speed_t speed = baudrate;
if (ioctl(fd, IOSSIOSPEED, &speed) == -1) {
if (ioctl(fd, IOSSIOSPEED, &speed) == -1)
{
log_error("set baud: error calling ioctl(..., IOSSIOSPEED, %u) - %s(%d).\n", baudrate, strerror(errno), errno);
return -1;
}
@ -226,56 +247,94 @@ static int posix_i2s_test_bridge_set_baudrate(int fd, uint32_t baudrate){
#else
struct termios toptions;
if (tcgetattr(fd, &toptions) < 0) {
if (tcgetattr(fd, &toptions) < 0)
{
log_error("set baud: Couldn't get term attributes");
return -1;
}
speed_t brate = baudrate; // let you override switch below if needed
switch(baudrate) {
case 9600: brate=B9600; break;
case 19200: brate=B19200; break;
case 38400: brate=B38400; break;
case 57600: brate=B57600; break;
case 115200: brate=B115200; break;
switch (baudrate)
{
case 9600:
brate = B9600;
break;
case 19200:
brate = B19200;
break;
case 38400:
brate = B38400;
break;
case 57600:
brate = B57600;
break;
case 115200:
brate = B115200;
break;
#ifdef B230400
case 230400: brate=B230400; break;
case 230400:
brate = B230400;
break;
#endif
#ifdef B460800
case 460800: brate=B460800; break;
case 460800:
brate = B460800;
break;
#endif
#ifdef B500000
case 500000: brate=B500000; break;
case 500000:
brate = B500000;
break;
#endif
#ifdef B576000
case 576000: brate=B576000; break;
case 576000:
brate = B576000;
break;
#endif
#ifdef B921600
case 921600: brate=B921600; break;
#ifdef B460800
case 460800:
brate = B460800;
break;
#endif
#ifdef B1000000
case 1000000: brate=B1000000; break;
case 1000000:
brate = B1000000;
break;
#endif
#ifdef B1152000
case 1152000: brate=B1152000; break;
case 1152000:
brate = B1152000;
break;
#endif
#ifdef B1500000
case 1500000: brate=B1500000; break;
case 1500000:
brate = B1500000;
break;
#endif
#ifdef B2000000
case 2000000: brate=B2000000; break;
case 2000000:
brate = B2000000;
break;
#endif
#ifdef B2500000
case 2500000: brate=B2500000; break;
case 2500000:
brate = B2500000;
break;
#endif
#ifdef B3000000
case 3000000: brate=B3000000; break;
case 3000000:
brate = B3000000;
break;
#endif
#ifdef B3500000
case 3500000: brate=B3500000; break;
case 3500000:
brate = B3500000;
break;
#endif
#ifdef B400000
case 4000000: brate=B4000000; break;
case 4000000:
brate = B4000000;
break;
#endif
default:
log_error("can't set baudrate %dn", baudrate);
@ -284,7 +343,8 @@ static int posix_i2s_test_bridge_set_baudrate(int fd, uint32_t baudrate){
cfsetospeed(&toptions, brate);
cfsetispeed(&toptions, brate);
if( tcsetattr(fd, TCSANOW, &toptions) < 0) {
if (tcsetattr(fd, TCSANOW, &toptions) < 0)
{
log_error("Couldn't set term attributes");
return -1;
}
@ -293,19 +353,22 @@ static int posix_i2s_test_bridge_set_baudrate(int fd, uint32_t baudrate){
return 0;
}
static int posix_i2s_test_bridge_init(const char * device_path){
static int posix_i2s_test_bridge_init(const char *device_path)
{
const uint32_t baudrate = 230400;
struct termios toptions;
int flags = O_RDWR | O_NOCTTY | O_NONBLOCK;
int fd = open(device_path, flags);
if (fd == -1) {
if (fd == -1)
{
log_error("Unable to open port %s", device_path);
return -1;
}
if (tcgetattr(fd, &toptions) < 0) {
if (tcgetattr(fd, &toptions) < 0)
{
log_error("Couldn't get term attributes");
return -1;
}
@ -323,13 +386,15 @@ static int posix_i2s_test_bridge_init(const char * device_path){
toptions.c_cc[VMIN] = 1;
toptions.c_cc[VTIME] = 0;
if(tcsetattr(fd, TCSANOW, &toptions) < 0) {
if (tcsetattr(fd, TCSANOW, &toptions) < 0)
{
log_error("Couldn't set term attributes");
return -1;
}
// also set baudrate
if (posix_i2s_test_bridge_set_baudrate(fd, baudrate) < 0){
if (posix_i2s_test_bridge_set_baudrate(fd, baudrate) < 0)
{
return -1;
}
@ -350,7 +415,8 @@ static int posix_i2s_test_bridge_init(const char * device_path){
return 0;
}
static void posix_i2s_test_bridge_open(hci_con_handle_t con_handle, sco_format_t format){
static void posix_i2s_test_bridge_open(hci_con_handle_t con_handle, sco_format_t format)
{
log_info("open: handle 0x%04x, format %s", con_handle, (format == SCO_FORMAT_16_BIT) ? "16 bit" : "8 bit");
// store config
sco_format = format;
@ -361,16 +427,19 @@ static void posix_i2s_test_bridge_open(hci_con_handle_t con_handle, sco_format_t
sco_tx_counter = 0;
}
static void posix_i2s_test_bridge_close(hci_con_handle_t con_handle){
static void posix_i2s_test_bridge_close(hci_con_handle_t con_handle)
{
log_info("close: handle 0x%04x", con_handle);
sco_handle = HCI_CON_HANDLE_INVALID;
}
static void posix_i2s_test_bridge_register_packet_handler(void (*handler)(uint8_t packet_type, uint8_t *packet, uint16_t size)){
static void posix_i2s_test_bridge_register_packet_handler(void (*handler)(uint8_t packet_type, uint8_t *packet, uint16_t size))
{
posix_i2s_test_bridge_packet_handler = handler;
}
const btstack_sco_transport_t * btstack_sco_transport_posix_i2s_test_bridge_init_instance(const char * device_path){
const btstack_sco_transport_t *btstack_sco_transport_posix_i2s_test_bridge_init_instance(const char *device_path)
{
static const btstack_sco_transport_t transport = {
.open = posix_i2s_test_bridge_open,
.close = posix_i2s_test_bridge_close,
@ -378,7 +447,8 @@ const btstack_sco_transport_t * btstack_sco_transport_posix_i2s_test_bridge_init
.send_packet = posix_i2s_test_bride_send_packet,
};
int err = posix_i2s_test_bridge_init(device_path);
if (err > 0) {
if (err > 0)
{
return NULL;
}
sco_format = SCO_FORMAT_8_BIT;

View file

@ -76,31 +76,36 @@ static uint8_t * btstack_uart_block_read_bytes_data;
static void (*block_sent)(void);
static void (*block_received)(void);
static int btstack_uart_posix_init(const btstack_uart_config_t * config){
static int btstack_uart_posix_init(const btstack_uart_config_t *config)
{
uart_config = config;
return 0;
}
static void hci_uart_posix_process(btstack_data_source_t *ds, btstack_data_source_callback_type_t callback_type);
static void btstack_uart_block_posix_process_write(btstack_data_source_t *ds) {
static void btstack_uart_block_posix_process_write(btstack_data_source_t *ds)
{
if (btstack_uart_block_write_bytes_len == 0) return;
if (btstack_uart_block_write_bytes_len == 0)
return;
uint32_t start = btstack_run_loop_get_time_ms();
// write up to write_bytes_len to fd
int bytes_written = (int)write(ds->source.fd, btstack_uart_block_write_bytes_data, btstack_uart_block_write_bytes_len);
uint32_t end = btstack_run_loop_get_time_ms();
if (end - start > 10){
if (end - start > 10)
{
// log_info("write took %u ms", end - start);
}
if (bytes_written == 0){
if (bytes_written == 0)
{
// log_error("wrote zero bytes\n");
return;
}
if (bytes_written < 0) {
if (bytes_written < 0)
{
// log_error("write returned error\n");
btstack_run_loop_enable_data_source_callbacks(ds, DATA_SOURCE_CALLBACK_WRITE);
return;
@ -109,7 +114,8 @@ static void btstack_uart_block_posix_process_write(btstack_data_source_t *ds) {
btstack_uart_block_write_bytes_data += bytes_written;
btstack_uart_block_write_bytes_len -= bytes_written;
if (btstack_uart_block_write_bytes_len){
if (btstack_uart_block_write_bytes_len)
{
btstack_run_loop_enable_data_source_callbacks(ds, DATA_SOURCE_CALLBACK_WRITE);
return;
}
@ -117,14 +123,17 @@ static void btstack_uart_block_posix_process_write(btstack_data_source_t *ds) {
btstack_run_loop_disable_data_source_callbacks(ds, DATA_SOURCE_CALLBACK_WRITE);
// notify done
if (block_sent){
if (block_sent)
{
block_sent();
}
}
static void btstack_uart_block_posix_process_read(btstack_data_source_t *ds) {
static void btstack_uart_block_posix_process_read(btstack_data_source_t *ds)
{
if (btstack_uart_block_read_bytes_len == 0) {
if (btstack_uart_block_read_bytes_len == 0)
{
log_info("called but no read pending");
btstack_run_loop_disable_data_source_callbacks(ds, DATA_SOURCE_CALLBACK_READ);
}
@ -135,30 +144,36 @@ static void btstack_uart_block_posix_process_read(btstack_data_source_t *ds) {
ssize_t bytes_read = read(ds->source.fd, btstack_uart_block_read_bytes_data, btstack_uart_block_read_bytes_len);
// log_info("read need %u bytes, got %d", btstack_uart_block_read_bytes_len, (int) bytes_read);
uint32_t end = btstack_run_loop_get_time_ms();
if (end - start > 10){
if (end - start > 10)
{
// log_info("read took %u ms", end - start);
}
if (bytes_read == 0){
if (bytes_read == 0)
{
// log_error("read zero bytes\n");
return;
}
if (bytes_read < 0) {
if (bytes_read < 0)
{
// log_error("read returned error\n");
return;
}
btstack_uart_block_read_bytes_len -= bytes_read;
btstack_uart_block_read_bytes_data += bytes_read;
if (btstack_uart_block_read_bytes_len > 0) return;
if (btstack_uart_block_read_bytes_len > 0)
return;
btstack_run_loop_disable_data_source_callbacks(ds, DATA_SOURCE_CALLBACK_READ);
if (block_received){
if (block_received)
{
block_received();
}
}
static int btstack_uart_posix_set_baudrate(uint32_t baudrate){
static int btstack_uart_posix_set_baudrate(uint32_t baudrate)
{
int fd = transport_data_source.source.fd;
@ -166,7 +181,8 @@ static int btstack_uart_posix_set_baudrate(uint32_t baudrate){
struct termios toptions;
if (tcgetattr(fd, &toptions) < 0) {
if (tcgetattr(fd, &toptions) < 0)
{
// log_error("btstack_uart_posix_set_baudrate: Couldn't get term attributes");
return -1;
}
@ -174,50 +190,87 @@ static int btstack_uart_posix_set_baudrate(uint32_t baudrate){
#ifndef __APPLE__
speed_t brate = baudrate; // let you override switch below if needed
switch(baudrate) {
case 9600: brate=B9600; break;
case 19200: brate=B19200; break;
case 38400: brate=B38400; break;
case 57600: brate=B57600; break;
case 115200: brate=B115200; break;
switch (baudrate)
{
case 9600:
brate = B9600;
break;
case 19200:
brate = B19200;
break;
case 38400:
brate = B38400;
break;
case 57600:
brate = B57600;
break;
case 115200:
brate = B115200;
break;
#ifdef B230400
case 230400: brate=B230400; break;
case 230400:
brate = B230400;
break;
#endif
#ifdef B460800
case 460800: brate=B460800; break;
case 460800:
brate = B460800;
break;
#endif
#ifdef B500000
case 500000: brate=B500000; break;
case 500000:
brate = B500000;
break;
#endif
#ifdef B576000
case 576000: brate=B576000; break;
case 576000:
brate = B576000;
break;
#endif
#ifdef B921600
case 921600: brate=B921600; break;
#ifdef B460800
case 460800:
brate = B460800;
break;
#endif
#ifdef B1000000
case 1000000: brate=B1000000; break;
case 1000000:
brate = B1000000;
break;
#endif
#ifdef B1152000
case 1152000: brate=B1152000; break;
case 1152000:
brate = B1152000;
break;
#endif
#ifdef B1500000
case 1500000: brate=B1500000; break;
case 1500000:
brate = B1500000;
break;
#endif
#ifdef B2000000
case 2000000: brate=B2000000; break;
case 2000000:
brate = B2000000;
break;
#endif
#ifdef B2500000
case 2500000: brate=B2500000; break;
case 2500000:
brate = B2500000;
break;
#endif
#ifdef B3000000
case 3000000: brate=B3000000; break;
case 3000000:
brate = B3000000;
break;
#endif
#ifdef B3500000
case 3500000: brate=B3500000; break;
case 3500000:
brate = B3500000;
break;
#endif
#ifdef B400000
case 4000000: brate=B4000000; break;
case 4000000:
brate = B4000000;
break;
#endif
default:
log_error("can't set baudrate %dn", baudrate);
@ -230,7 +283,8 @@ static int btstack_uart_posix_set_baudrate(uint32_t baudrate){
// also set options for __APPLE__ to enforce write drain
// Mac OS Mojave: tcsdrain did not work as expected
if( tcsetattr(fd, TCSADRAIN, &toptions) < 0) {
if (tcsetattr(fd, TCSADRAIN, &toptions) < 0)
{
log_error("Couldn't set term attributes");
return -1;
}
@ -244,7 +298,8 @@ static int btstack_uart_posix_set_baudrate(uint32_t baudrate){
// and output speed.
speed_t speed = baudrate;
if (ioctl(fd, IOSSIOSPEED, &speed) == -1) {
if (ioctl(fd, IOSSIOSPEED, &speed) == -1)
{
log_error("btstack_uart_posix_set_baudrate: error calling ioctl(..., IOSSIOSPEED, %u) - %s(%d).\n", baudrate, strerror(errno), errno);
return -1;
}
@ -253,8 +308,10 @@ static int btstack_uart_posix_set_baudrate(uint32_t baudrate){
return 0;
}
static void btstack_uart_posix_set_parity_option(struct termios * toptions, int parity){
switch (parity){
static void btstack_uart_posix_set_parity_option(struct termios *toptions, int parity)
{
switch (parity)
{
case BTSTACK_UART_PARITY_OFF:
toptions->c_cflag &= ~PARENB;
toptions->c_cflag &= ~PARODD;
@ -271,48 +328,58 @@ static void btstack_uart_posix_set_parity_option(struct termios * toptions, int
}
}
static void btstack_uart_posix_set_flowcontrol_option(struct termios * toptions, int flowcontrol){
if (flowcontrol) {
static void btstack_uart_posix_set_flowcontrol_option(struct termios *toptions, int flowcontrol)
{
if (flowcontrol)
{
// with flow control
toptions->c_cflag |= CRTSCTS;
} else {
}
else
{
// no flow control
toptions->c_cflag &= ~CRTSCTS;
}
}
static int btstack_uart_posix_set_parity(int parity){
static int btstack_uart_posix_set_parity(int parity)
{
int fd = transport_data_source.source.fd;
struct termios toptions;
if (tcgetattr(fd, &toptions) < 0) {
if (tcgetattr(fd, &toptions) < 0)
{
log_error("Couldn't get term attributes");
return -1;
}
btstack_uart_posix_set_parity_option(&toptions, parity);
if(tcsetattr(fd, TCSANOW, &toptions) < 0) {
if (tcsetattr(fd, TCSANOW, &toptions) < 0)
{
log_error("Couldn't set term attributes");
return -1;
}
return 0;
}
static int btstack_uart_posix_set_flowcontrol(int flowcontrol){
static int btstack_uart_posix_set_flowcontrol(int flowcontrol)
{
int fd = transport_data_source.source.fd;
struct termios toptions;
if (tcgetattr(fd, &toptions) < 0) {
if (tcgetattr(fd, &toptions) < 0)
{
log_error("Couldn't get term attributes");
return -1;
}
btstack_uart_posix_set_flowcontrol_option(&toptions, flowcontrol);
if(tcsetattr(fd, TCSANOW, &toptions) < 0) {
if (tcsetattr(fd, TCSANOW, &toptions) < 0)
{
log_error("Couldn't set term attributes");
return -1;
}
return 0;
}
static int btstack_uart_posix_open(void){
static int btstack_uart_posix_open(void)
{
const char *device_name = uart_config->device_name;
const uint32_t baudrate = uart_config->baudrate;
@ -322,12 +389,14 @@ static int btstack_uart_posix_open(void){
struct termios toptions;
int flags = O_RDWR | O_NOCTTY | O_NONBLOCK;
int fd = open(device_name, flags);
if (fd == -1) {
if (fd == -1)
{
log_error("Unable to open port %s", device_name);
return -1;
}
if (tcgetattr(fd, &toptions) < 0) {
if (tcgetattr(fd, &toptions) < 0)
{
log_error("Couldn't get term attributes");
return -1;
}
@ -351,7 +420,8 @@ static int btstack_uart_posix_open(void){
// flowcontrol
btstack_uart_posix_set_flowcontrol_option(&toptions, flowcontrol);
if(tcsetattr(fd, TCSANOW, &toptions) < 0) {
if (tcsetattr(fd, TCSANOW, &toptions) < 0)
{
log_error("Couldn't set term attributes");
return -1;
}
@ -360,7 +430,8 @@ static int btstack_uart_posix_open(void){
transport_data_source.source.fd = fd;
// also set baudrate
if (btstack_uart_posix_set_baudrate(baudrate) < 0){
if (btstack_uart_posix_set_baudrate(baudrate) < 0)
{
return -1;
}
@ -375,7 +446,8 @@ static int btstack_uart_posix_open(void){
return 0;
}
static int btstack_uart_posix_close_new(void){
static int btstack_uart_posix_close_new(void)
{
// first remove run loop handler
btstack_run_loop_remove_data_source(&transport_data_source);
@ -386,22 +458,26 @@ static int btstack_uart_posix_close_new(void){
return 0;
}
static void btstack_uart_posix_set_block_received( void (*block_handler)(void)){
static void btstack_uart_posix_set_block_received(void (*block_handler)(void))
{
block_received = block_handler;
}
static void btstack_uart_posix_set_block_sent( void (*block_handler)(void)){
static void btstack_uart_posix_set_block_sent(void (*block_handler)(void))
{
block_sent = block_handler;
}
static void btstack_uart_posix_send_block(const uint8_t *data, uint16_t size){
static void btstack_uart_posix_send_block(const uint8_t *data, uint16_t size)
{
// setup async write
btstack_uart_block_write_bytes_data = data;
btstack_uart_block_write_bytes_len = size;
btstack_run_loop_enable_data_source_callbacks(&transport_data_source, DATA_SOURCE_CALLBACK_WRITE);
}
static void btstack_uart_posix_receive_block(uint8_t *buffer, uint16_t len){
static void btstack_uart_posix_receive_block(uint8_t *buffer, uint16_t len)
{
btstack_uart_block_read_bytes_data = buffer;
btstack_uart_block_read_bytes_len = len;
btstack_run_loop_enable_data_source_callbacks(&transport_data_source, DATA_SOURCE_CALLBACK_READ);
@ -439,28 +515,33 @@ static void (*frame_received)(uint16_t frame_size);
static void btstack_uart_slip_posix_block_sent(void);
static void btstack_uart_slip_posix_process_write(btstack_data_source_t *ds) {
static void btstack_uart_slip_posix_process_write(btstack_data_source_t *ds)
{
if (btstack_uart_slip_write_bytes_len == 0) return;
if (btstack_uart_slip_write_bytes_len == 0)
return;
uint32_t start = btstack_run_loop_get_time_ms();
// write up to btstack_uart_slip_write_bytes_len to fd
int bytes_written = (int)write(ds->source.fd, btstack_uart_slip_write_bytes_data, btstack_uart_slip_write_bytes_len);
if (bytes_written < 0) {
if (bytes_written < 0)
{
btstack_run_loop_enable_data_source_callbacks(ds, DATA_SOURCE_CALLBACK_WRITE);
return;
}
uint32_t end = btstack_run_loop_get_time_ms();
if (end - start > 10){
if (end - start > 10)
{
log_info("write took %u ms", end - start);
}
btstack_uart_slip_write_bytes_data += bytes_written;
btstack_uart_slip_write_bytes_len -= bytes_written;
if (btstack_uart_slip_write_bytes_len){
if (btstack_uart_slip_write_bytes_len)
{
btstack_run_loop_enable_data_source_callbacks(ds, DATA_SOURCE_CALLBACK_WRITE);
return;
}
@ -472,29 +553,34 @@ static void btstack_uart_slip_posix_process_write(btstack_data_source_t *ds) {
}
// @returns frame size if complete frame decoded and delivered
static uint16_t btstack_uart_slip_posix_process_buffer(void){
static uint16_t btstack_uart_slip_posix_process_buffer(void)
{
log_debug("process buffer: pos %u, len %u", btstack_uart_slip_receive_pos, btstack_uart_slip_receive_len);
uint16_t frame_size = 0;
while (btstack_uart_slip_receive_pos < btstack_uart_slip_receive_len && frame_size == 0){
while (btstack_uart_slip_receive_pos < btstack_uart_slip_receive_len && frame_size == 0)
{
btstack_slip_decoder_process(btstack_uart_slip_receive_buffer[btstack_uart_slip_receive_pos++]);
frame_size = btstack_slip_decoder_frame_size();
}
// reset buffer if fully processed
if (btstack_uart_slip_receive_pos == btstack_uart_slip_receive_len ){
if (btstack_uart_slip_receive_pos == btstack_uart_slip_receive_len)
{
btstack_uart_slip_receive_len = 0;
btstack_uart_slip_receive_pos = 0;
}
// deliver frame if frame complete
if (frame_size) {
if (frame_size)
{
// receive done
btstack_uart_slip_receive_active = 0;
// only print if read was involved
if (btstack_uart_slip_receive_track_start == 0){
if (btstack_uart_slip_receive_track_start == 0)
{
log_info("frame receive time %u ms", btstack_run_loop_get_time_ms() - btstack_uart_slip_receive_start_time);
btstack_uart_slip_receive_start_time = 0;
}
@ -505,11 +591,13 @@ static uint16_t btstack_uart_slip_posix_process_buffer(void){
return frame_size;
}
static void btstack_uart_slip_posix_process_read(btstack_data_source_t *ds) {
static void btstack_uart_slip_posix_process_read(btstack_data_source_t *ds)
{
uint32_t start = btstack_run_loop_get_time_ms();
if (btstack_uart_slip_receive_track_start){
if (btstack_uart_slip_receive_track_start)
{
btstack_uart_slip_receive_track_start = 0;
btstack_uart_slip_receive_start_time = start;
}
@ -519,10 +607,12 @@ static void btstack_uart_slip_posix_process_read(btstack_data_source_t *ds) {
log_debug("requested %u bytes, got %d", SLIP_RECEIVE_BUFFER_SIZE, (int)bytes_read);
uint32_t end = btstack_run_loop_get_time_ms();
if (end - start > 10){
if (end - start > 10)
{
log_info("read took %u ms", end - start);
}
if (bytes_read < 0) return;
if (bytes_read < 0)
return;
btstack_uart_slip_receive_pos = 0;
btstack_uart_slip_receive_len = (uint16_t)bytes_read;
@ -533,9 +623,11 @@ static void btstack_uart_slip_posix_process_read(btstack_data_source_t *ds) {
// -----------------------------
// SLIP ENCODING
static void btstack_uart_slip_posix_encode_chunk_and_send(void){
static void btstack_uart_slip_posix_encode_chunk_and_send(void)
{
uint16_t pos = 0;
while (btstack_slip_encoder_has_data() & (pos < SLIP_TX_CHUNK_LEN)) {
while (btstack_slip_encoder_has_data() & (pos < SLIP_TX_CHUNK_LEN))
{
btstack_uart_slip_outgoing_buffer[pos++] = btstack_slip_encoder_get_byte();
}
@ -546,9 +638,11 @@ static void btstack_uart_slip_posix_encode_chunk_and_send(void){
btstack_run_loop_enable_data_source_callbacks(&transport_data_source, DATA_SOURCE_CALLBACK_WRITE);
}
static void btstack_uart_slip_posix_block_sent(void){
static void btstack_uart_slip_posix_block_sent(void)
{
// check if more data to send
if (btstack_slip_encoder_has_data()){
if (btstack_slip_encoder_has_data())
{
btstack_uart_slip_posix_encode_chunk_and_send();
return;
}
@ -557,12 +651,14 @@ static void btstack_uart_slip_posix_block_sent(void){
btstack_uart_slip_write_active = 0;
// notify done
if (frame_sent){
if (frame_sent)
{
frame_sent();
}
}
static void btstack_uart_slip_posix_send_frame(const uint8_t * frame, uint16_t frame_size){
static void btstack_uart_slip_posix_send_frame(const uint8_t *frame, uint16_t frame_size)
{
// write started
btstack_uart_slip_write_active = 1;
@ -577,7 +673,8 @@ static void btstack_uart_slip_posix_send_frame(const uint8_t * frame, uint16_t f
// SLIP ENCODING
// -----------------------------
static void btstack_uart_slip_posix_receive_frame(uint8_t *buffer, uint16_t len){
static void btstack_uart_slip_posix_receive_frame(uint8_t *buffer, uint16_t len)
{
// receive started
btstack_uart_slip_receive_active = 1;
@ -590,22 +687,24 @@ static void btstack_uart_slip_posix_receive_frame(uint8_t *buffer, uint16_t len)
// process bytes received in earlier read. might deliver packet, which in turn will call us again.
// just make sure to exit right away
if (btstack_uart_slip_receive_len){
if (btstack_uart_slip_receive_len)
{
int frame_found = btstack_uart_slip_posix_process_buffer();
if (frame_found) return;
if (frame_found)
return;
}
// no frame delivered, enable posix read
btstack_run_loop_enable_data_source_callbacks(&transport_data_source, DATA_SOURCE_CALLBACK_READ);
}
static void btstack_uart_slip_posix_set_frame_received( void (*block_handler)(uint16_t frame_size)){
static void btstack_uart_slip_posix_set_frame_received(void (*block_handler)(uint16_t frame_size))
{
frame_received = block_handler;
}
static void btstack_uart_slip_posix_set_frame_sent( void (*block_handler)(void)){
static void btstack_uart_slip_posix_set_frame_sent(void (*block_handler)(void))
{
frame_sent = block_handler;
}
@ -613,14 +712,19 @@ static void btstack_uart_slip_posix_set_frame_sent( void (*block_handler)(void))
#endif
// dispatch into block or SLIP code
static void hci_uart_posix_process(btstack_data_source_t *ds, btstack_data_source_callback_type_t callback_type) {
if (ds->source.fd < 0) return;
switch (callback_type){
static void hci_uart_posix_process(btstack_data_source_t *ds, btstack_data_source_callback_type_t callback_type)
{
if (ds->source.fd < 0)
return;
switch (callback_type)
{
case DATA_SOURCE_CALLBACK_READ:
#ifdef ENABLE_H5
if (btstack_uart_slip_receive_active){
if (btstack_uart_slip_receive_active)
{
btstack_uart_slip_posix_process_read(ds);
} else
}
else
#endif
{
btstack_uart_block_posix_process_read(ds);
@ -628,9 +732,11 @@ static void hci_uart_posix_process(btstack_data_source_t *ds, btstack_data_sourc
break;
case DATA_SOURCE_CALLBACK_WRITE:
#ifdef ENABLE_H5
if (btstack_uart_slip_write_active){
if (btstack_uart_slip_write_active)
{
btstack_uart_slip_posix_process_write(ds);
} else
}
else
#endif
{
btstack_uart_block_posix_process_write(ds);
@ -662,10 +768,14 @@ static const btstack_uart_t btstack_uart_posix = {
/* void (*receive_frame)(uint8_t *buffer, uint16_t len); */ &btstack_uart_slip_posix_receive_frame,
/* void (*send_frame)(const uint8_t *buffer, uint16_t length); */ &btstack_uart_slip_posix_send_frame,
#else
NULL, NULL, NULL, NULL,
NULL,
NULL,
NULL,
NULL,
#endif
};
const btstack_uart_t * btstack_uart_posix_instance(void){
const btstack_uart_t *btstack_uart_posix_instance(void)
{
return &btstack_uart_posix;
}

View file

@ -130,7 +130,7 @@ void hal_uart_dma_init(void)
16000000 / 576000 = 277.77
16000000 / 115200 = 138.88
16000000 / 921600 = 17.36
16000000 / 460800 = 17.36
16000000 / 1000000 = 16.00
16000000 / 2000000 = 8.00
16000000 / 2400000 = 6.66
@ -138,13 +138,15 @@ void hal_uart_dma_init(void)
16000000 / 4000000 = 2.00
*/
int hal_uart_dma_set_baud(uint32_t baud){
int hal_uart_dma_set_baud(uint32_t baud)
{
int result = 0;
UCA2CTL1 |= UCSWRST; // Reset State
switch (baud){
switch (baud)
{
case 4000000:
UCA2BR0 = 2;
@ -176,7 +178,7 @@ int hal_uart_dma_set_baud(uint32_t baud){
UCA2MCTL = 0 << 1; // + 0.000
break;
case 921600:
case 460800:
UCA2BR0 = 17;
UCA2BR1 = 0;
UCA2MCTL = 7 << 1; // 3 << 1; // + 0.375
@ -204,16 +206,20 @@ int hal_uart_dma_set_baud(uint32_t baud){
return result;
}
void hal_uart_dma_set_block_received( void (*the_block_handler)(void)){
void hal_uart_dma_set_block_received(void (*the_block_handler)(void))
{
rx_done_handler = the_block_handler;
}
void hal_uart_dma_set_block_sent( void (*the_block_handler)(void)){
void hal_uart_dma_set_block_sent(void (*the_block_handler)(void))
{
tx_done_handler = the_block_handler;
}
void hal_uart_dma_set_csr_irq_handler( void (*the_irq_handler)(void)){
if (the_irq_handler){
void hal_uart_dma_set_csr_irq_handler(void (*the_irq_handler)(void))
{
if (the_irq_handler)
{
P1IFG = 0; // no IRQ pending
P1IV = 0; // no IRQ pending
P1IES &= ~BIT4; // IRQ on 0->1 transition
@ -235,7 +241,8 @@ void hal_uart_dma_set_csr_irq_handler( void (*the_irq_handler)(void)){
*
* @return none
**************************************************************************/
void hal_uart_dma_shutdown(void) {
void hal_uart_dma_shutdown(void)
{
UCA2IE &= ~(UCRXIE | UCTXIE);
UCA2CTL1 = UCSWRST; // Reset State
@ -245,7 +252,8 @@ void hal_uart_dma_shutdown(void) {
BT_PORT_OUT &= ~(BT_PIN_TXD + BT_PIN_RXD);
}
void hal_uart_dma_send_block(const uint8_t * data, uint16_t len){
void hal_uart_dma_send_block(const uint8_t *data, uint16_t len)
{
// printf("hal_uart_dma_send_block, size %u\n\r", len);
@ -257,15 +265,18 @@ void hal_uart_dma_send_block(const uint8_t * data, uint16_t len){
UCA2IE |= UCTXIE; // enable TX interrupts
}
static inline void hal_uart_dma_enable_rx(void){
static inline void hal_uart_dma_enable_rx(void)
{
P1OUT &= ~BIT3; // = 0 - RTS low -> ok
}
static inline void hal_uart_dma_disable_rx(void){
static inline void hal_uart_dma_disable_rx(void)
{
P1OUT |= BIT3; // = 1 - RTS high -> stop
}
void hal_uart_dma_receive_block(uint8_t *buffer, uint16_t len){
void hal_uart_dma_receive_block(uint8_t *buffer, uint16_t len)
{
// disable RX interrupts
UCA2IE &= ~UCRXIE;
@ -279,12 +290,14 @@ void hal_uart_dma_receive_block(uint8_t *buffer, uint16_t len){
UCA2IE |= UCRXIE;
// if byte was pending, ISR controls RTS
if (!pending) {
if (!pending)
{
hal_uart_dma_enable_rx();
}
}
void hal_uart_dma_set_sleep(uint8_t sleep){
void hal_uart_dma_set_sleep(uint8_t sleep)
{
hal_cpu_set_uart_needed_during_sleep(!sleep);
}
@ -296,13 +309,17 @@ __attribute__((interrupt(USCI_A2_VECTOR)))
#pragma vector = USCI_A2_VECTOR
__interrupt
#endif
void usbRxTxISR(void){
void
usbRxTxISR(void)
{
// find reason
switch (UCA2IV){
switch (UCA2IV)
{
case 2: // RXIFG
if (bytes_to_read == 0) {
if (bytes_to_read == 0)
{
hal_uart_dma_disable_rx();
UCA2IE &= ~UCRXIE; // disable RX interrupts
return;
@ -310,7 +327,8 @@ void usbRxTxISR(void){
*rx_buffer_ptr = UCA2RXBUF;
++rx_buffer_ptr;
--bytes_to_read;
if (bytes_to_read > 0) {
if (bytes_to_read > 0)
{
hal_uart_dma_enable_rx();
return;
}
@ -325,7 +343,8 @@ void usbRxTxISR(void){
break;
case 4: // TXIFG
if (bytes_to_write == 0){
if (bytes_to_write == 0)
{
UCA2IE &= ~UCTXIE; // disable TX interrupts
return;
}
@ -333,7 +352,8 @@ void usbRxTxISR(void){
++tx_buffer_ptr;
--bytes_to_write;
if (bytes_to_write > 0) {
if (bytes_to_write > 0)
{
return;
}
@ -351,7 +371,6 @@ void usbRxTxISR(void){
}
}
// CTS ISR
extern void ehcill_handle(uint8_t action);
@ -364,7 +383,9 @@ __attribute__((interrupt(PORT1_VECTOR)))
#pragma vector = PORT1_VECTOR
__interrupt
#endif
void ctsISR(void){
void
ctsISR(void)
{
P1IV = 0;
(*cts_irq_handler)();
}

View file

@ -130,7 +130,7 @@ void hal_uart_dma_init(void)
16000000 / 576000 = 277.77
16000000 / 115200 = 138.88
16000000 / 921600 = 17.36
16000000 / 460800 = 17.36
16000000 / 1000000 = 16.00
16000000 / 2000000 = 8.00
16000000 / 2400000 = 6.66
@ -138,13 +138,15 @@ void hal_uart_dma_init(void)
16000000 / 4000000 = 2.00
*/
int hal_uart_dma_set_baud(uint32_t baud){
int hal_uart_dma_set_baud(uint32_t baud)
{
int result = 0;
UCA2CTL1 |= UCSWRST; // Reset State
switch (baud){
switch (baud)
{
case 4000000:
UCA2BR0 = 2;
@ -176,7 +178,7 @@ int hal_uart_dma_set_baud(uint32_t baud){
UCA2MCTL = 0 << 1; // + 0.000
break;
case 921600:
case 460800:
UCA2BR0 = 17;
UCA2BR1 = 0;
UCA2MCTL = 7 << 1; // 3 << 1; // + 0.375
@ -204,16 +206,20 @@ int hal_uart_dma_set_baud(uint32_t baud){
return result;
}
void hal_uart_dma_set_block_received( void (*the_block_handler)(void)){
void hal_uart_dma_set_block_received(void (*the_block_handler)(void))
{
rx_done_handler = the_block_handler;
}
void hal_uart_dma_set_block_sent( void (*the_block_handler)(void)){
void hal_uart_dma_set_block_sent(void (*the_block_handler)(void))
{
tx_done_handler = the_block_handler;
}
void hal_uart_dma_set_csr_irq_handler( void (*the_irq_handler)(void)){
if (the_irq_handler){
void hal_uart_dma_set_csr_irq_handler(void (*the_irq_handler)(void))
{
if (the_irq_handler)
{
P1IFG = 0; // no IRQ pending
P1IV = 0; // no IRQ pending
P1IES &= ~BIT3; // IRQ on 0->1 transition
@ -235,7 +241,8 @@ void hal_uart_dma_set_csr_irq_handler( void (*the_irq_handler)(void)){
*
* @return none
**************************************************************************/
void hal_uart_dma_shutdown(void) {
void hal_uart_dma_shutdown(void)
{
UCA2IE &= ~(UCRXIE | UCTXIE);
UCA2CTL1 = UCSWRST; // Reset State
@ -245,7 +252,8 @@ void hal_uart_dma_shutdown(void) {
BT_PORT_OUT &= ~(BT_PIN_TXD + BT_PIN_RXD);
}
void hal_uart_dma_send_block(const uint8_t * data, uint16_t len){
void hal_uart_dma_send_block(const uint8_t *data, uint16_t len)
{
// printf("hal_uart_dma_send_block, size %u\n\r", len);
@ -257,15 +265,18 @@ void hal_uart_dma_send_block(const uint8_t * data, uint16_t len){
UCA2IE |= UCTXIE; // enable TX interrupts
}
static inline void hal_uart_dma_enable_rx(void){
static inline void hal_uart_dma_enable_rx(void)
{
P1OUT &= ~BIT4; // = 0 - RTS low -> ok
}
static inline void hal_uart_dma_disable_rx(void){
static inline void hal_uart_dma_disable_rx(void)
{
P1OUT |= BIT4; // = 1 - RTS high -> stop
}
void hal_uart_dma_receive_block(uint8_t *buffer, uint16_t len){
void hal_uart_dma_receive_block(uint8_t *buffer, uint16_t len)
{
// disable RX interrupts
UCA2IE &= ~UCRXIE;
@ -279,12 +290,14 @@ void hal_uart_dma_receive_block(uint8_t *buffer, uint16_t len){
UCA2IE |= UCRXIE;
// if byte was pending, ISR controls RTS
if (!pending) {
if (!pending)
{
hal_uart_dma_enable_rx();
}
}
void hal_uart_dma_set_sleep(uint8_t sleep){
void hal_uart_dma_set_sleep(uint8_t sleep)
{
hal_cpu_set_uart_needed_during_sleep(!sleep);
}
@ -296,13 +309,17 @@ __attribute__((interrupt(USCI_A2_VECTOR)))
#pragma vector = USCI_A2_VECTOR
__interrupt
#endif
void usbRxTxISR(void){
void
usbRxTxISR(void)
{
// find reason
switch (UCA2IV){
switch (UCA2IV)
{
case 2: // RXIFG
if (bytes_to_read == 0) {
if (bytes_to_read == 0)
{
hal_uart_dma_disable_rx();
UCA2IE &= ~UCRXIE; // disable RX interrupts
return;
@ -310,7 +327,8 @@ void usbRxTxISR(void){
*rx_buffer_ptr = UCA2RXBUF;
++rx_buffer_ptr;
--bytes_to_read;
if (bytes_to_read > 0) {
if (bytes_to_read > 0)
{
hal_uart_dma_enable_rx();
return;
}
@ -325,7 +343,8 @@ void usbRxTxISR(void){
break;
case 4: // TXIFG
if (bytes_to_write == 0){
if (bytes_to_write == 0)
{
UCA2IE &= ~UCTXIE; // disable TX interrupts
return;
}
@ -333,7 +352,8 @@ void usbRxTxISR(void){
++tx_buffer_ptr;
--bytes_to_write;
if (bytes_to_write > 0) {
if (bytes_to_write > 0)
{
return;
}
@ -351,7 +371,6 @@ void usbRxTxISR(void){
}
}
// CTS ISR
extern void ehcill_handle(uint8_t action);
@ -364,7 +383,9 @@ __attribute__((interrupt(PORT1_VECTOR)))
#pragma vector = PORT1_VECTOR
__interrupt
#endif
void ctsISR(void){
void
ctsISR(void)
{
P1IV = 0;
(*cts_irq_handler)();
}

View file

@ -50,7 +50,6 @@ extern void hal_cpu_set_uart_needed_during_sleep(uint8_t enabled);
// debugging only
// #include <stdio.h>
// RXD 3.4
// TXD 3.3
#define BT_PORT_OUT P3OUT
@ -142,7 +141,7 @@ void hal_uart_dma_init(void)
16000000 / 576000 = 277.77
16000000 / 115200 = 138.88
16000000 / 921600 = 17.36
16000000 / 460800 = 17.36
16000000 / 1000000 = 16.00
16000000 / 2000000 = 8.00
16000000 / 2400000 = 6.66
@ -150,13 +149,15 @@ void hal_uart_dma_init(void)
16000000 / 4000000 = 2.00
*/
int hal_uart_dma_set_baud(uint32_t baud){
int hal_uart_dma_set_baud(uint32_t baud)
{
int result = 0;
UCA0CTL1 |= UCSWRST; // Reset State
switch (baud){
switch (baud)
{
case 4000000:
UCA0BR0 = 2;
@ -188,7 +189,7 @@ int hal_uart_dma_set_baud(uint32_t baud){
UCA0MCTL = 0 << 1; // + 0.000
break;
case 921600:
case 460800:
UCA0BR0 = 17;
UCA0BR1 = 0;
UCA0MCTL = 7 << 1; // 3 << 1; // + 0.375
@ -216,17 +217,21 @@ int hal_uart_dma_set_baud(uint32_t baud){
return result;
}
void hal_uart_dma_set_block_received( void (*the_block_handler)(void)){
void hal_uart_dma_set_block_received(void (*the_block_handler)(void))
{
rx_done_handler = the_block_handler;
}
void hal_uart_dma_set_block_sent( void (*the_block_handler)(void)){
void hal_uart_dma_set_block_sent(void (*the_block_handler)(void))
{
tx_done_handler = the_block_handler;
}
void hal_uart_dma_set_csr_irq_handler( void (*the_irq_handler)(void)){
void hal_uart_dma_set_csr_irq_handler(void (*the_irq_handler)(void))
{
#ifdef HAVE_CTS_IRQ
if (the_irq_handler){
if (the_irq_handler)
{
P2IFG = 0; // no IRQ pending
P2IV = 0; // no IRQ pending
P2IES &= ~CTS_PIN; // IRQ on 0->1 transition
@ -248,7 +253,8 @@ void hal_uart_dma_set_csr_irq_handler( void (*the_irq_handler)(void)){
*
* @return none
**************************************************************************/
void hal_uart_dma_shutdown(void) {
void hal_uart_dma_shutdown(void)
{
UCA0IE &= ~(UCRXIE | UCTXIE);
UCA0CTL1 = UCSWRST; // Reset State
@ -258,7 +264,8 @@ void hal_uart_dma_shutdown(void) {
BT_PORT_OUT &= ~(BT_PIN_TXD + BT_PIN_RXD);
}
void hal_uart_dma_send_block(const uint8_t * data, uint16_t len){
void hal_uart_dma_send_block(const uint8_t *data, uint16_t len)
{
// printf("hal_uart_dma_send_block, size %u\n\r", len);
@ -270,15 +277,18 @@ void hal_uart_dma_send_block(const uint8_t * data, uint16_t len){
UCA0IE |= UCTXIE; // enable TX interrupts
}
static inline void hal_uart_dma_enable_rx(void){
static inline void hal_uart_dma_enable_rx(void)
{
RTS_OUT &= ~RTS_PIN; // = 0 - RTS low -> ok
}
static inline void hal_uart_dma_disable_rx(void){
static inline void hal_uart_dma_disable_rx(void)
{
RTS_OUT |= RTS_PIN; // = 1 - RTS high -> stop
}
void hal_uart_dma_receive_block(uint8_t *buffer, uint16_t len){
void hal_uart_dma_receive_block(uint8_t *buffer, uint16_t len)
{
// disable RX interrupts
UCA0IE &= ~UCRXIE;
@ -292,12 +302,14 @@ void hal_uart_dma_receive_block(uint8_t *buffer, uint16_t len){
UCA0IE |= UCRXIE; // enable RX interrupts
// if byte was pending, ISR controls RTS
if (!pending) {
if (!pending)
{
hal_uart_dma_enable_rx();
}
}
void hal_uart_dma_set_sleep(uint8_t sleep){
void hal_uart_dma_set_sleep(uint8_t sleep)
{
hal_cpu_set_uart_needed_during_sleep(!sleep);
}
@ -309,13 +321,17 @@ __attribute__((interrupt(USCI_A0_VECTOR)))
#pragma vector = USCI_A0_VECTOR
__interrupt
#endif
void usbRxTxISR(void){
void
usbRxTxISR(void)
{
// find reason
switch (UCA0IV){
switch (UCA0IV)
{
case 2: // RXIFG
if (bytes_to_read == 0) {
if (bytes_to_read == 0)
{
hal_uart_dma_disable_rx();
UCA0IE &= ~UCRXIE; // disable RX interrupts
return;
@ -323,7 +339,8 @@ void usbRxTxISR(void){
*rx_buffer_ptr = UCA0RXBUF;
++rx_buffer_ptr;
--bytes_to_read;
if (bytes_to_read > 0) {
if (bytes_to_read > 0)
{
hal_uart_dma_enable_rx();
return;
}
@ -338,7 +355,8 @@ void usbRxTxISR(void){
break;
case 4: // TXIFG
if (bytes_to_write == 0){
if (bytes_to_write == 0)
{
UCA0IE &= ~UCTXIE; // disable TX interrupts
return;
}
@ -346,7 +364,8 @@ void usbRxTxISR(void){
++tx_buffer_ptr;
--bytes_to_write;
if (bytes_to_write > 0) {
if (bytes_to_write > 0)
{
return;
}
@ -364,7 +383,6 @@ void usbRxTxISR(void){
}
}
// CTS ISR
#ifdef HAVE_CTS_IRQ
// TODO: there's no PORT8_VECTOR, but configuration seems possible
@ -378,9 +396,10 @@ __attribute__((interrupt(PORT2_VECTOR)))
#pragma vector = PORT2_VECTOR
__interrupt
#endif
void ctsISR(void){
void
ctsISR(void)
{
P2IV = 0;
(*cts_irq_handler)();
}
#endif

View file

@ -67,7 +67,6 @@
#include "hci.h"
#include "hci_dump.h"
int btstack_main(int argc, const char *argv[]);
#define TLV_DB_PATH_PREFIX "/tmp/btstack_"
@ -79,7 +78,7 @@ static btstack_tlv_posix_t tlv_context;
static hci_transport_config_uart_t transport_config = {
HCI_TRANSPORT_CONFIG_UART,
115200,
921600, // main baudrate
460800, // main baudrate
0, // flow control
NULL,
BTSTACK_UART_PARITY_EVEN, // parity
@ -91,7 +90,8 @@ static const char ** main_argv;
static btstack_packet_callback_registration_t hci_event_callback_registration;
static void sigint_handler(int param){
static void sigint_handler(int param)
{
UNUSED(param);
printf("CTRL-C - SIGINT received, shutting down..\n");
@ -108,17 +108,22 @@ static void sigint_handler(int param){
}
static int led_state = 0;
void hal_led_toggle(void){
void hal_led_toggle(void)
{
led_state = 1 - led_state;
printf("LED State %u\n", led_state);
}
static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size)
{
bd_addr_t addr;
if (packet_type != HCI_EVENT_PACKET) return;
switch (hci_event_packet_get_type(packet)){
if (packet_type != HCI_EVENT_PACKET)
return;
switch (hci_event_packet_get_type(packet))
{
case BTSTACK_EVENT_STATE:
if (btstack_event_state_get_state(packet) != HCI_STATE_WORKING) break;
if (btstack_event_state_get_state(packet) != HCI_STATE_WORKING)
break;
gap_local_bd_addr(addr);
printf("BTstack up and running at %s\n", bd_addr_to_str(addr));
// setup TLV
@ -140,7 +145,8 @@ static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *pack
}
static void phase2(int status);
int main(int argc, const char * argv[]){
int main(int argc, const char *argv[])
{
/// GET STARTED with BTstack ///
btstack_memory_init();
@ -172,7 +178,6 @@ int main(int argc, const char * argv[]){
uart_config.device_name = transport_config.device_name;
uart_driver->init(&uart_config);
// setup HCI (to be able to use bcm chipset driver)
// init HCI
const hci_transport_t *transport = hci_transport_h5_instance(uart_driver);
@ -200,9 +205,11 @@ int main(int argc, const char * argv[]){
return 0;
}
static void phase2(int status){
static void phase2(int status)
{
if (status){
if (status)
{
printf("Download firmware failed\n");
return;
}
@ -212,4 +219,3 @@ static void phase2(int status){
// setup app
btstack_main(main_argc, main_argv);
}

View file

@ -29,7 +29,7 @@
#define ENABLE_SDP
#define HAVE_TRANSPORT_H4
#define UART_DEVICE "/dev/tty.bluetooth"
#define UART_SPEED 921600
#define UART_SPEED 460800
#define USE_LAUNCHD
#define USE_SPRINGBOARD

View file

@ -86,7 +86,7 @@ int btstack_main(int argc, const char * argv[]);
static hci_transport_config_uart_t transport_config = {
HCI_TRANSPORT_CONFIG_UART,
921600,
460800,
0, // main baudrate
1, // flow control
NULL,
@ -94,12 +94,16 @@ static hci_transport_config_uart_t transport_config = {
static btstack_packet_callback_registration_t hci_event_callback_registration;
static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size)
{
bd_addr_t addr;
if (packet_type != HCI_EVENT_PACKET) return;
switch (hci_event_packet_get_type(packet)){
if (packet_type != HCI_EVENT_PACKET)
return;
switch (hci_event_packet_get_type(packet))
{
case BTSTACK_EVENT_STATE:
if (btstack_event_state_get_state(packet) != HCI_STATE_WORKING) break;
if (btstack_event_state_get_state(packet) != HCI_STATE_WORKING)
break;
gap_local_bd_addr(addr);
printf("BTstack up and running at %s\n", bd_addr_to_str(addr));
// setup TLV
@ -117,7 +121,8 @@ static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *pack
}
}
static void sigint_handler(int param){
static void sigint_handler(int param)
{
UNUSED(param);
printf("CTRL-C - SIGINT received, shutting down..\n");
@ -134,14 +139,17 @@ static void sigint_handler(int param){
}
static int led_state = 0;
void hal_led_toggle(void){
void hal_led_toggle(void)
{
led_state = 1 - led_state;
printf("LED State %u\n", led_state);
}
static void phase2(int status){
static void phase2(int status)
{
if (status){
if (status)
{
printf("Download firmware failed\n");
return;
}
@ -164,8 +172,8 @@ static void phase2(int status){
btstack_main(main_argc, main_argv);
}
int main(int argc, const char * argv[]){
int main(int argc, const char *argv[])
{
/// GET STARTED with BTstack ///
btstack_memory_init();

View file

@ -76,7 +76,6 @@
#include "btstack_chipset_stlc2500d.h"
#include "btstack_chipset_tc3566x.h"
#define TLV_DB_PATH_PREFIX "/tmp/btstack_"
#define TLV_DB_PATH_POSTFIX ".tlv"
static char tlv_db_path[100];
@ -98,12 +97,16 @@ static hci_transport_config_uart_t config = {
static btstack_packet_callback_registration_t hci_event_callback_registration;
static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size)
{
bd_addr_t addr;
if (packet_type != HCI_EVENT_PACKET) return;
switch (hci_event_packet_get_type(packet)){
if (packet_type != HCI_EVENT_PACKET)
return;
switch (hci_event_packet_get_type(packet))
{
case BTSTACK_EVENT_STATE:
if (btstack_event_state_get_state(packet) != HCI_STATE_WORKING) break;
if (btstack_event_state_get_state(packet) != HCI_STATE_WORKING)
break;
gap_local_bd_addr(addr);
printf("BTstack up and running at %s\n", bd_addr_to_str(addr));
// setup TLV
@ -120,16 +123,20 @@ static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *pack
#endif
break;
case HCI_EVENT_COMMAND_COMPLETE:
if (HCI_EVENT_IS_COMMAND_COMPLETE(packet, hci_read_local_name)){
if (hci_event_command_complete_get_return_parameters(packet)[0]) break;
if (HCI_EVENT_IS_COMMAND_COMPLETE(packet, hci_read_local_name))
{
if (hci_event_command_complete_get_return_parameters(packet)[0])
break;
// terminate, name 248 chars
packet[6 + 248] = 0;
printf("Local name: %s\n", &packet[6]);
if (is_bcm){
if (is_bcm)
{
btstack_chipset_bcm_set_device_name((const char *)&packet[6]);
}
}
if (HCI_EVENT_IS_COMMAND_COMPLETE(packet, hci_read_local_version_information)){
if (HCI_EVENT_IS_COMMAND_COMPLETE(packet, hci_read_local_version_information))
{
local_version_information_handler(packet);
}
break;
@ -138,7 +145,8 @@ static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *pack
}
}
static void sigint_handler(int param){
static void sigint_handler(int param)
{
UNUSED(param);
printf("CTRL-C - SIGINT received, shutting down..\n");
@ -155,11 +163,13 @@ static void sigint_handler(int param){
}
static int led_state = 0;
void hal_led_toggle(void){
void hal_led_toggle(void)
{
led_state = 1 - led_state;
printf("LED State %u\n", led_state);
}
static void use_fast_uart(void){
static void use_fast_uart(void)
{
#if defined(HAVE_POSIX_B240000_MAPPED_TO_3000000) || defined(HAVE_POSIX_B600_MAPPED_TO_3000000)
printf("Using 3000000 baud.\n");
config.baudrate_main = 3000000;
@ -167,12 +177,13 @@ static void use_fast_uart(void){
printf("Using 2000000 baud.\n");
config.baudrate_main = 2000000;
#else
printf("Using 921600 baud.\n");
config.baudrate_main = 921600;
printf("Using 460800 baud.\n");
config.baudrate_main = 460800;
#endif
}
static void local_version_information_handler(uint8_t * packet){
static void local_version_information_handler(uint8_t *packet)
{
printf("Local version information:\n");
uint16_t hci_version = packet[6];
uint16_t hci_revision = little_endian_read_16(packet, 7);
@ -184,7 +195,8 @@ static void local_version_information_handler(uint8_t * packet){
printf("- LMP Version 0x%04x\n", lmp_version);
printf("- LMP Subversion 0x%04x\n", lmp_subversion);
printf("- Manufacturer 0x%04x\n", manufacturer);
switch (manufacturer){
switch (manufacturer)
{
case BLUETOOTH_COMPANY_ID_CAMBRIDGE_SILICON_RADIO:
printf("Cambridge Silicon Radio - CSR chipset, Build ID: %u.\n", hci_revision);
use_fast_uart();
@ -192,7 +204,8 @@ static void local_version_information_handler(uint8_t * packet){
break;
case BLUETOOTH_COMPANY_ID_TEXAS_INSTRUMENTS_INC:
printf("Texas Instruments - CC256x compatible chipset.\n");
if (lmp_subversion != btstack_chipset_cc256x_lmp_subversion()){
if (lmp_subversion != btstack_chipset_cc256x_lmp_subversion())
{
printf("Error: LMP Subversion does not match initscript! ");
printf("Your initscripts is for %s chipset\n", btstack_chipset_cc256x_lmp_subversion() < lmp_subversion ? "an older" : "a newer");
printf("Please update Makefile to include the appropriate bluetooth_init_cc256???.c file\n");
@ -237,7 +250,8 @@ static void local_version_information_handler(uint8_t * packet){
}
}
int main(int argc, const char * argv[]){
int main(int argc, const char *argv[])
{
/// GET STARTED with BTstack ///
btstack_memory_init();
@ -257,7 +271,8 @@ int main(int argc, const char * argv[]){
config.device_name = "/dev/tty.usbserial-A900K0VK"; // CSR8811 breakout board
// accept path from command line
if (argc >= 3 && strcmp(argv[1], "-u") == 0){
if (argc >= 3 && strcmp(argv[1], "-u") == 0)
{
config.device_name = argv[2];
argc -= 2;
memmove(&argv[1], &argv[3], (argc - 1) * sizeof(char *));

View file

@ -94,7 +94,8 @@ static hci_transport_config_uart_t config = {
static btstack_packet_callback_registration_t hci_event_callback_registration;
static void local_version_information_handler(uint8_t *packet);
static void sigint_handler(int param){
static void sigint_handler(int param)
{
UNUSED(param);
printf("CTRL-C - SIGINT received, shutting down..\n");
@ -111,16 +112,19 @@ static void sigint_handler(int param){
}
static int led_state = 0;
void hal_led_toggle(void){
void hal_led_toggle(void)
{
led_state = 1 - led_state;
printf("LED State %u\n", led_state);
}
static void use_fast_uart(void){
printf("Using 921600 baud.\n");
config.baudrate_main = 921600;
static void use_fast_uart(void)
{
printf("Using 460800 baud.\n");
config.baudrate_main = 460800;
}
static void local_version_information_handler(uint8_t * packet){
static void local_version_information_handler(uint8_t *packet)
{
printf("Local version information:\n");
uint16_t hci_version = packet[6];
uint16_t hci_revision = little_endian_read_16(packet, 7);
@ -132,7 +136,8 @@ static void local_version_information_handler(uint8_t * packet){
printf("- LMP Version 0x%04x\n", lmp_version);
printf("- LMP Revision 0x%04x\n", lmp_subversion);
printf("- Manufacturer 0x%04x\n", manufacturer);
switch (manufacturer){
switch (manufacturer)
{
case BLUETOOTH_COMPANY_ID_CAMBRIDGE_SILICON_RADIO:
printf("Cambridge Silicon Radio - CSR chipset, Build ID: %u.\n", hci_revision);
use_fast_uart();
@ -162,12 +167,16 @@ static void local_version_information_handler(uint8_t * packet){
}
}
static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size)
{
bd_addr_t addr;
if (packet_type != HCI_EVENT_PACKET) return;
switch (hci_event_packet_get_type(packet)){
if (packet_type != HCI_EVENT_PACKET)
return;
switch (hci_event_packet_get_type(packet))
{
case BTSTACK_EVENT_STATE:
if (btstack_event_state_get_state(packet) != HCI_STATE_WORKING) break;
if (btstack_event_state_get_state(packet) != HCI_STATE_WORKING)
break;
gap_local_bd_addr(addr);
printf("BTstack up and running at %s\n", bd_addr_to_str(addr));
// setup TLV
@ -184,13 +193,16 @@ static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *pack
#endif
break;
case HCI_EVENT_COMMAND_COMPLETE:
if (HCI_EVENT_IS_COMMAND_COMPLETE(packet, hci_read_local_name)){
if (hci_event_command_complete_get_return_parameters(packet)[0]) break;
if (HCI_EVENT_IS_COMMAND_COMPLETE(packet, hci_read_local_name))
{
if (hci_event_command_complete_get_return_parameters(packet)[0])
break;
// terminate, name 248 chars
packet[6 + 248] = 0;
printf("Local name: %s\n", &packet[6]);
}
if (HCI_EVENT_IS_COMMAND_COMPLETE(packet, hci_read_local_version_information)){
if (HCI_EVENT_IS_COMMAND_COMPLETE(packet, hci_read_local_version_information))
{
local_version_information_handler(packet);
}
break;
@ -199,7 +211,8 @@ static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *pack
}
}
int main(int argc, const char * argv[]){
int main(int argc, const char *argv[])
{
/// GET STARTED with BTstack ///
btstack_memory_init();
@ -219,7 +232,8 @@ int main(int argc, const char * argv[]){
config.device_name = "/dev/tty.usbserial-A900K0VK"; // CSR8811 breakout board
// accept path from command line
if (argc >= 3 && strcmp(argv[1], "-u") == 0){
if (argc >= 3 && strcmp(argv[1], "-u") == 0)
{
config.device_name = argv[2];
argc -= 2;
memmove(&argv[1], &argv[3], (argc - 1) * sizeof(char *));

View file

@ -109,12 +109,14 @@ static hci_transport_config_uart_t config = {
NULL,
};
static void use_fast_uart(void){
printf("Using 921600 baud.\n");
config.baudrate_main = 921600;
static void use_fast_uart(void)
{
printf("Using 460800 baud.\n");
config.baudrate_main = 460800;
}
static void local_version_information_handler(uint8_t * packet){
static void local_version_information_handler(uint8_t *packet)
{
printf("Local version information:\n");
uint16_t hci_version = packet[6];
uint16_t hci_revision = little_endian_read_16(packet, 7);
@ -126,7 +128,8 @@ static void local_version_information_handler(uint8_t * packet){
printf("- LMP Version 0x%04x\n", lmp_version);
printf("- LMP Subversion 0x%04x\n", lmp_subversion);
printf("- Manufacturer 0x%04x\n", manufacturer);
switch (manufacturer){
switch (manufacturer)
{
case BLUETOOTH_COMPANY_ID_CAMBRIDGE_SILICON_RADIO:
printf("Cambridge Silicon Radio - CSR chipset, Build ID: %u.\n", hci_revision);
use_fast_uart();
@ -134,7 +137,8 @@ static void local_version_information_handler(uint8_t * packet){
break;
case BLUETOOTH_COMPANY_ID_TEXAS_INSTRUMENTS_INC:
printf("Texas Instruments - CC256x compatible chipset.\n");
if (lmp_subversion != btstack_chipset_cc256x_lmp_subversion()){
if (lmp_subversion != btstack_chipset_cc256x_lmp_subversion())
{
printf("Error: LMP Subversion does not match initscript! ");
printf("Your initscripts is for %s chipset\n", btstack_chipset_cc256x_lmp_subversion() < lmp_subversion ? "an older" : "a newer");
printf("Please update CMakeLists.txt to include the appropriate bluetooth_init_cc256???.c file\n");
@ -161,16 +165,20 @@ static void local_version_information_handler(uint8_t * packet){
}
}
static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size)
{
UNUSED(channel);
UNUSED(size);
if (packet_type != HCI_EVENT_PACKET) return;
switch (hci_event_packet_get_type(packet)){
if (packet_type != HCI_EVENT_PACKET)
return;
switch (hci_event_packet_get_type(packet))
{
case BTSTACK_EVENT_STATE:
if (btstack_event_state_get_state(packet) != HCI_STATE_WORKING) return;
if (btstack_event_state_get_state(packet) != HCI_STATE_WORKING)
return;
gap_local_bd_addr(local_addr);
if (using_static_address){
if (using_static_address)
{
memcpy(local_addr, static_address, 6);
}
printf("BTstack up and running on %s.\n", bd_addr_to_str(local_addr));
@ -190,16 +198,20 @@ static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *pack
#endif
break;
case HCI_EVENT_COMMAND_COMPLETE:
if (HCI_EVENT_IS_COMMAND_COMPLETE(packet, hci_read_local_name)){
if (hci_event_command_complete_get_return_parameters(packet)[0]) break;
if (HCI_EVENT_IS_COMMAND_COMPLETE(packet, hci_read_local_name))
{
if (hci_event_command_complete_get_return_parameters(packet)[0])
break;
// terminate, name 248 chars
packet[6 + 248] = 0;
printf("Local name: %s\n", &packet[6]);
if (is_bcm){
if (is_bcm)
{
btstack_chipset_bcm_set_device_name((const char *)&packet[6]);
}
}
if (HCI_EVENT_IS_COMMAND_COMPLETE(packet, hci_read_local_version_information)){
if (HCI_EVENT_IS_COMMAND_COMPLETE(packet, hci_read_local_version_information))
{
local_version_information_handler(packet);
}
break;
@ -208,7 +220,8 @@ static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *pack
}
}
static void sigint_handler(int param){
static void sigint_handler(int param)
{
UNUSED(param);
printf("CTRL-C - SIGINT received, shutting down..\n");
@ -225,7 +238,8 @@ static void sigint_handler(int param){
}
static int led_state = 0;
void hal_led_toggle(void){
void hal_led_toggle(void)
{
led_state = 1 - led_state;
printf("LED State %u\n", led_state);
}
@ -233,7 +247,8 @@ void hal_led_toggle(void){
#define USB_MAX_PATH_LEN 7
int btstack_main(int argc, const char *argv[]);
int main(int argc, char * argv[]){
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);

View file

@ -81,12 +81,12 @@
#include "btstack_chipset_bcm_download_firmware.h"
#include "btstack_control_raspi.h"
#include "raspi_get_model.h"
int btstack_main(int argc, const char *argv[]);
typedef enum {
typedef enum
{
UART_INVALID,
UART_SOFTWARE_NO_FLOW,
UART_HARDWARE_NO_FLOW,
@ -115,10 +115,10 @@ static char tlv_db_path[100];
static const btstack_tlv_t *tlv_impl;
static btstack_tlv_posix_t tlv_context;
static int raspi_speed_to_baud(speed_t baud)
{
switch (baud) {
switch (baud)
{
case B9600:
return 9600;
case B19200:
@ -137,8 +137,8 @@ static int raspi_speed_to_baud(speed_t baud)
return 500000;
case B576000:
return 576000;
case B921600:
return 921600;
case B460800:
return 460800;
case B1000000:
return 1000000;
case B1152000:
@ -185,7 +185,8 @@ static void raspi_get_terminal_params( hci_transport_config_uart_t *tc )
}
}
static void sigint_handler(int param){
static void sigint_handler(int param)
{
UNUSED(param);
printf("CTRL-C - SIGINT received, shutting down..\n");
@ -202,17 +203,22 @@ static void sigint_handler(int param){
}
static int led_state = 0;
void hal_led_toggle(void){
void hal_led_toggle(void)
{
led_state = 1 - led_state;
printf("LED State %u\n", led_state);
}
static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size)
{
bd_addr_t addr;
if (packet_type != HCI_EVENT_PACKET) return;
switch (hci_event_packet_get_type(packet)){
if (packet_type != HCI_EVENT_PACKET)
return;
switch (hci_event_packet_get_type(packet))
{
case BTSTACK_EVENT_STATE:
if (btstack_event_state_get_state(packet) != HCI_STATE_WORKING) break;
if (btstack_event_state_get_state(packet) != HCI_STATE_WORKING)
break;
gap_local_bd_addr(addr);
printf("BTstack up and running at %s\n", bd_addr_to_str(addr));
// setup TLV
@ -229,8 +235,10 @@ static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *pack
#endif
break;
case HCI_EVENT_COMMAND_COMPLETE:
if (HCI_EVENT_IS_COMMAND_COMPLETE(packet, hci_read_local_name)){
if (hci_event_command_complete_get_return_parameters(packet)[0]) break;
if (HCI_EVENT_IS_COMMAND_COMPLETE(packet, hci_read_local_name))
{
if (hci_event_command_complete_get_return_parameters(packet)[0])
break;
// terminate, name 248 chars
packet[6 + 248] = 0;
printf("Local name: %s\n", &packet[6]);
@ -244,62 +252,82 @@ static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *pack
}
// see https://github.com/RPi-Distro/pi-bluetooth/blob/master/usr/bin/btuart
static int raspi_get_bd_addr(bd_addr_t addr){
static int raspi_get_bd_addr(bd_addr_t addr)
{
FILE *fd = fopen("/proc/device-tree/serial-number", "r");
if( fd == NULL ){
if (fd == NULL)
{
fprintf(stderr, "can't read serial number, %s\n", strerror(errno));
return -1;
}
fscanf( fd, "%*08x" "%*02x" "%02" SCNx8 "%02" SCNx8 "%02" SCNx8, &addr[3], &addr[4], &addr[5] );
fscanf(fd, "%*08x"
"%*02x"
"%02" SCNx8 "%02" SCNx8 "%02" SCNx8,
&addr[3], &addr[4], &addr[5]);
fclose(fd);
addr[0] = 0xb8; addr[1] = 0x27; addr[2] = 0xeb;
addr[3] ^= 0xaa; addr[4] ^= 0xaa; addr[5] ^= 0xaa;
addr[0] = 0xb8;
addr[1] = 0x27;
addr[2] = 0xeb;
addr[3] ^= 0xaa;
addr[4] ^= 0xaa;
addr[5] ^= 0xaa;
return 0;
}
// see https://github.com/RPi-Distro/pi-bluetooth/blob/master/usr/bin/btuart
// on UART_INVALID errno is set
static uart_type_t raspi_get_bluetooth_uart_type(void){
static uart_type_t raspi_get_bluetooth_uart_type(void)
{
uint8_t deviceUart0[21] = {0};
FILE *fd = fopen("/proc/device-tree/aliases/uart0", "r");
if( fd == NULL ) return UART_INVALID;
if (fd == NULL)
return UART_INVALID;
fscanf(fd, "%20s", deviceUart0);
fclose(fd);
uint8_t deviceSerial1[21] = {0};
fd = fopen("/proc/device-tree/aliases/serial1", "r");
if( fd == NULL ) return UART_INVALID;
if (fd == NULL)
return UART_INVALID;
fscanf(fd, "%20s", deviceSerial1);
fclose(fd);
// test if uart0 is an alias for serial1
if( strncmp( (const char *) deviceUart0, (const char *) deviceSerial1, 21 ) == 0 ){
if (strncmp((const char *)deviceUart0, (const char *)deviceSerial1, 21) == 0)
{
// HW uart
size_t count = 0;
uint8_t buf[16];
fd = fopen("/proc/device-tree/soc/gpio@7e200000/uart0_pins/brcm,pins", "r");
if( fd == NULL ) return UART_INVALID;
if (fd == NULL)
return UART_INVALID;
count = fread(buf, 1, 16, fd);
fclose(fd);
// contains assigned pins
int pins = count / 4;
if( pins == 4 ){
if (pins == 4)
{
return UART_HARDWARE_FLOW;
} else {
}
else
{
return UART_HARDWARE_NO_FLOW;
}
} else {
}
else
{
return UART_SOFTWARE_NO_FLOW;
}
}
static void phase2(int status);
int main(int argc, const char * argv[]){
int main(int argc, const char *argv[])
{
/// GET STARTED with BTstack ///
btstack_memory_init();
@ -324,7 +352,8 @@ int main(int argc, const char * argv[]){
// set UART config based on raspi Bluetooth UART type
int bt_reg_en_pin = -1;
bool power_cycle = true;
switch (raspi_get_bluetooth_uart_type()){
switch (raspi_get_bluetooth_uart_type())
{
case UART_INVALID:
fprintf(stderr, "can't verify HW uart, %s\n", strerror(errno));
return -1;
@ -339,7 +368,7 @@ int main(int argc, const char * argv[]){
// Raspberry Pi 3 B
// power up with H5 and without power cycle untested/unsupported
bt_reg_en_pin = 128;
transport_config.baudrate_main = 921600;
transport_config.baudrate_main = 460800;
transport_config.flowcontrol = 0;
break;
case UART_HARDWARE_FLOW:
@ -348,10 +377,13 @@ int main(int argc, const char * argv[]){
// Raspberry Pi 3B+ vgpio 129 but WLAN + BL
transport_config.flowcontrol = 1;
int model = raspi_get_model();
if (model == MODEL_ZERO_W){
if (model == MODEL_ZERO_W)
{
bt_reg_en_pin = 45;
transport_config.baudrate_main = 921600;
} else {
transport_config.baudrate_main = 460800;
}
else
{
bt_reg_en_pin = 129;
transport_config.baudrate_main = 3000000;
}
@ -360,7 +392,8 @@ int main(int argc, const char * argv[]){
power_cycle = false;
#else
// warn about power cycle on devices with shared reg_en pins
if (model == MODEL_3APLUS || model == MODEL_3BPLUS){
if (model == MODEL_3APLUS || model == MODEL_3BPLUS)
{
printf("Wifi and Bluetooth share a single RESET line and BTstack needs to reset Bluetooth -> SSH over Wifi will fail\n");
printf("Please add ENABLE_CONTROLLER_WARM_BOOT to btstack_config.h to enable startup without RESET\n");
}
@ -387,9 +420,12 @@ int main(int argc, const char * argv[]){
// HW with FlowControl -> we can use regular h4 mode
const hci_transport_t *transport;
if (transport_config.flowcontrol){
if (transport_config.flowcontrol)
{
transport = hci_transport_h4_instance(uart_driver);
} else {
}
else
{
transport = hci_transport_h5_instance(uart_driver);
}
@ -409,7 +445,8 @@ int main(int argc, const char * argv[]){
main_argv = argv;
// power cycle Bluetooth controller on older models without flowcontrol
if (power_cycle){
if (power_cycle)
{
btstack_control_raspi_set_bt_reg_en_pin(bt_reg_en_pin);
btstack_control_t *control = btstack_control_raspi_get_instance();
control->init(NULL);
@ -418,17 +455,20 @@ int main(int argc, const char * argv[]){
control->on();
}
if (transport_config.flowcontrol){
if (transport_config.flowcontrol)
{
// re-use current terminal speed (if there was no power cycle)
if (!power_cycle){
if (!power_cycle)
{
raspi_get_terminal_params(&transport_config);
}
// with flowcontrol, we use h4 and are done
btstack_main(main_argc, main_argv);
} else {
}
else
{
// assume BCM4343W used in Pi 3 A/B. Pi 3 A/B+ have a newer controller but support H4 with Flowcontrol
btstack_chipset_bcm_set_device_name("BCM43430A1");
@ -445,9 +485,11 @@ int main(int argc, const char * argv[]){
return 0;
}
static void phase2(int status){
static void phase2(int status)
{
if (status){
if (status)
{
printf("Download firmware failed\n");
return;
}
@ -457,4 +499,3 @@ static void phase2(int status){
// setup app
btstack_main(main_argc, main_argv);
}

View file

@ -92,12 +92,14 @@ static const btstack_tlv_t * tlv_impl;
static btstack_tlv_posix_t tlv_context;
static bd_addr_t local_addr;
void hal_led_toggle(void){
void hal_led_toggle(void)
{
led_state = 1 - led_state;
printf("LED State %u\n", led_state);
}
static void sigint_handler(int param){
static void sigint_handler(int param)
{
UNUSED(param);
printf("CTRL-C = SIGINT received, shutting down..\n");
@ -115,12 +117,16 @@ static void sigint_handler(int param){
static btstack_packet_callback_registration_t hci_event_callback_registration;
static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size)
{
bd_addr_t addr;
if (packet_type != HCI_EVENT_PACKET) return;
switch (hci_event_packet_get_type(packet)){
if (packet_type != HCI_EVENT_PACKET)
return;
switch (hci_event_packet_get_type(packet))
{
case BTSTACK_EVENT_STATE:
if (btstack_event_state_get_state(packet) != HCI_STATE_WORKING) break;
if (btstack_event_state_get_state(packet) != HCI_STATE_WORKING)
break;
gap_local_bd_addr(addr);
printf("BTstack up and running on %s.\n", bd_addr_to_str(local_addr));
strcpy(tlv_db_path, TLV_DB_PATH_PREFIX);
@ -137,16 +143,20 @@ static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *pack
printf("BTstack up and running at %s\n", bd_addr_to_str(addr));
break;
case HCI_EVENT_COMMAND_COMPLETE:
if (HCI_EVENT_IS_COMMAND_COMPLETE(packet, hci_read_local_name)){
if (hci_event_command_complete_get_return_parameters(packet)[0]) break;
if (HCI_EVENT_IS_COMMAND_COMPLETE(packet, hci_read_local_name))
{
if (hci_event_command_complete_get_return_parameters(packet)[0])
break;
// terminate, name 248 chars
packet[6 + 248] = 0;
printf("Local name: %s\n", &packet[6]);
if (is_bcm){
if (is_bcm)
{
btstack_chipset_bcm_set_device_name((const char *)&packet[6]);
}
}
if (HCI_EVENT_IS_COMMAND_COMPLETE(packet, hci_read_local_version_information)){
if (HCI_EVENT_IS_COMMAND_COMPLETE(packet, hci_read_local_version_information))
{
local_version_information_handler(packet);
}
break;
@ -154,12 +164,14 @@ static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *pack
break;
}
}
static void use_fast_uart(void){
printf("Using 921600 baud.\n");
config.baudrate_main = 921600;
static void use_fast_uart(void)
{
printf("Using 460800 baud.\n");
config.baudrate_main = 460800;
}
static void local_version_information_handler(uint8_t * packet){
static void local_version_information_handler(uint8_t *packet)
{
printf("Local version information:\n");
uint16_t hci_version = packet[6];
uint16_t hci_revision = little_endian_read_16(packet, 7);
@ -171,7 +183,8 @@ static void local_version_information_handler(uint8_t * packet){
printf("- LMP Version 0x%04x\n", lmp_version);
printf("- LMP Revision 0x%04x\n", lmp_subversion);
printf("- Manufacturer 0x%04x\n", manufacturer);
switch (manufacturer){
switch (manufacturer)
{
case BLUETOOTH_COMPANY_ID_CAMBRIDGE_SILICON_RADIO:
printf("Cambridge Silicon Radio - CSR chipset, Build ID: %u.\n", hci_revision);
use_fast_uart();
@ -179,7 +192,8 @@ static void local_version_information_handler(uint8_t * packet){
break;
case BLUETOOTH_COMPANY_ID_TEXAS_INSTRUMENTS_INC:
printf("Texas Instruments - CC256x compatible chipset.\n");
if (lmp_subversion != btstack_chipset_cc256x_lmp_subversion()){
if (lmp_subversion != btstack_chipset_cc256x_lmp_subversion())
{
printf("Error: LMP Subversion does not match initscript!");
printf("Your initscripts is for %s chipset\n", btstack_chipset_cc256x_lmp_subversion() < lmp_subversion ? "an older" : "a newer");
printf("Please update Makefile to include the appropriate bluetooth_init_cc256???.c file\n");
@ -222,7 +236,8 @@ static void local_version_information_handler(uint8_t * packet){
}
}
int main(int argc, const char * argv[]){
int main(int argc, const char *argv[])
{
printf("BTstack on windows booting up\n");
/// GET STARTED with BTstack ///
@ -240,7 +255,8 @@ int main(int argc, const char * argv[]){
config.device_name = "\\\\.\\COM7";
// accept path from command line
if (argc >= 3 && strcmp(argv[1], "-u") == 0){
if (argc >= 3 && strcmp(argv[1], "-u") == 0)
{
config.device_name = argv[2];
argc -= 2;
memmove(&argv[1], &argv[3], (argc - 1) * sizeof(char *));

View file

@ -76,34 +76,39 @@ static uint8_t * read_bytes_data;
static void (*block_sent)(void);
static void (*block_received)(void);
static int btstack_uart_posix_init(const btstack_uart_config_t * config){
static int btstack_uart_posix_init(const btstack_uart_config_t *config)
{
uart_config = config;
return 0;
}
static void btstack_uart_posix_process_write(btstack_data_source_t *ds) {
static void btstack_uart_posix_process_write(btstack_data_source_t *ds)
{
if (write_bytes_len == 0) return;
if (write_bytes_len == 0)
return;
uint32_t start = btstack_run_loop_get_time_ms();
// write up to write_bytes_len to fd
int bytes_written = (int)write(ds->source.fd, write_bytes_data, write_bytes_len);
if (bytes_written < 0) {
if (bytes_written < 0)
{
btstack_run_loop_enable_data_source_callbacks(ds, DATA_SOURCE_CALLBACK_WRITE);
return;
}
uint32_t end = btstack_run_loop_get_time_ms();
if (end - start > 10){
if (end - start > 10)
{
log_info("h4_process: write took %u ms", end - start);
}
write_bytes_data += bytes_written;
write_bytes_len -= bytes_written;
if (write_bytes_len){
if (write_bytes_len)
{
btstack_run_loop_enable_data_source_callbacks(ds, DATA_SOURCE_CALLBACK_WRITE);
return;
}
@ -111,14 +116,17 @@ static void btstack_uart_posix_process_write(btstack_data_source_t *ds) {
btstack_run_loop_disable_data_source_callbacks(ds, DATA_SOURCE_CALLBACK_WRITE);
// notify done
if (block_sent){
if (block_sent)
{
block_sent();
}
}
static void btstack_uart_posix_process_read(btstack_data_source_t *ds) {
static void btstack_uart_posix_process_read(btstack_data_source_t *ds)
{
if (read_bytes_len == 0) {
if (read_bytes_len == 0)
{
log_info("btstack_uart_posix_process_read but no read requested");
btstack_run_loop_disable_data_source_callbacks(ds, DATA_SOURCE_CALLBACK_READ);
}
@ -129,25 +137,32 @@ static void btstack_uart_posix_process_read(btstack_data_source_t *ds) {
ssize_t bytes_read = read(ds->source.fd, read_bytes_data, read_bytes_len);
// log_info("btstack_uart_posix_process_read need %u bytes, got %d", read_bytes_len, (int) bytes_read);
uint32_t end = btstack_run_loop_get_time_ms();
if (end - start > 10){
if (end - start > 10)
{
log_info("h4_process: read took %u ms", end - start);
}
if (bytes_read < 0) return;
if (bytes_read < 0)
return;
read_bytes_len -= bytes_read;
read_bytes_data += bytes_read;
if (read_bytes_len > 0) return;
if (read_bytes_len > 0)
return;
btstack_run_loop_disable_data_source_callbacks(ds, DATA_SOURCE_CALLBACK_READ);
if (block_received){
if (block_received)
{
block_received();
}
}
static void hci_transport_h5_process(btstack_data_source_t *ds, btstack_data_source_callback_type_t callback_type) {
if (ds->source.fd < 0) return;
switch (callback_type){
static void hci_transport_h5_process(btstack_data_source_t *ds, btstack_data_source_callback_type_t callback_type)
{
if (ds->source.fd < 0)
return;
switch (callback_type)
{
case DATA_SOURCE_CALLBACK_READ:
btstack_uart_posix_process_read(ds);
break;
@ -159,7 +174,8 @@ static void hci_transport_h5_process(btstack_data_source_t *ds, btstack_data_sou
}
}
static int btstack_uart_posix_set_baudrate(uint32_t baudrate){
static int btstack_uart_posix_set_baudrate(uint32_t baudrate)
{
UNUSED(baudrate);
#if 0
int fd = transport_data_source.source.fd;
@ -199,8 +215,8 @@ static int btstack_uart_posix_set_baudrate(uint32_t baudrate){
#ifdef B460800
case 460800: brate=B460800; break;
#endif
#ifdef B921600
case 921600: brate=B921600; break;
#ifdef B460800
case 460800: brate=B460800; break;
#endif
// Hacks to switch to 2/3 mbps on FTDI FT232 chipsets
@ -238,58 +254,72 @@ static int btstack_uart_posix_set_baudrate(uint32_t baudrate){
return 0;
}
static void btstack_uart_posix_set_parity_option(struct termios * toptions, int parity){
if (parity){
static void btstack_uart_posix_set_parity_option(struct termios *toptions, int parity)
{
if (parity)
{
// enable even parity
toptions->c_cflag |= PARENB;
} else {
}
else
{
// disable even parity
toptions->c_cflag &= ~PARENB;
}
}
static void btstack_uart_posix_set_flowcontrol_option(struct termios * toptions, int flowcontrol){
if (flowcontrol) {
static void btstack_uart_posix_set_flowcontrol_option(struct termios *toptions, int flowcontrol)
{
if (flowcontrol)
{
// with flow control
toptions->c_cflag |= CRTSCTS;
} else {
}
else
{
// no flow control
toptions->c_cflag &= ~CRTSCTS;
}
}
static int btstack_uart_posix_set_parity(int parity){
static int btstack_uart_posix_set_parity(int parity)
{
int fd = transport_data_source.source.fd;
struct termios toptions;
if (tcgetattr(fd, &toptions) < 0) {
if (tcgetattr(fd, &toptions) < 0)
{
log_error("btstack_uart_posix_set_parity: Couldn't get term attributes");
return -1;
}
btstack_uart_posix_set_parity_option(&toptions, parity);
if(tcsetattr(fd, TCSANOW, &toptions) < 0) {
if (tcsetattr(fd, TCSANOW, &toptions) < 0)
{
log_error("posix_set_parity: Couldn't set term attributes");
return -1;
}
return 0;
}
static int btstack_uart_posix_set_flowcontrol(int flowcontrol){
static int btstack_uart_posix_set_flowcontrol(int flowcontrol)
{
int fd = transport_data_source.source.fd;
struct termios toptions;
if (tcgetattr(fd, &toptions) < 0) {
if (tcgetattr(fd, &toptions) < 0)
{
log_error("btstack_uart_posix_set_parity: Couldn't get term attributes");
return -1;
}
btstack_uart_posix_set_flowcontrol_option(&toptions, flowcontrol);
if(tcsetattr(fd, TCSANOW, &toptions) < 0) {
if (tcsetattr(fd, TCSANOW, &toptions) < 0)
{
log_error("posix_set_flowcontrol: Couldn't set term attributes");
return -1;
}
return 0;
}
static int btstack_uart_posix_open(void){
static int btstack_uart_posix_open(void)
{
const char *device_name = uart_config->device_name;
const int flowcontrol = uart_config->flowcontrol;
@ -298,12 +328,14 @@ static int btstack_uart_posix_open(void){
struct termios toptions;
int flags = O_RDWR | O_NOCTTY | O_NONBLOCK;
int fd = open(device_name, flags);
if (fd == -1) {
if (fd == -1)
{
log_error("posix_open: Unable to open port %s", device_name);
return -1;
}
if (tcgetattr(fd, &toptions) < 0) {
if (tcgetattr(fd, &toptions) < 0)
{
log_error("posix_open: Couldn't get term attributes");
return -1;
}
@ -327,7 +359,8 @@ static int btstack_uart_posix_open(void){
// flowcontrol
btstack_uart_posix_set_flowcontrol_option(&toptions, flowcontrol);
if(tcsetattr(fd, TCSANOW, &toptions) < 0) {
if (tcsetattr(fd, TCSANOW, &toptions) < 0)
{
log_error("posix_open: Couldn't set term attributes");
return -1;
}
@ -336,7 +369,8 @@ static int btstack_uart_posix_open(void){
transport_data_source.source.fd = fd;
// also set baudrate
if (btstack_uart_posix_set_baudrate(baudrate) < 0){
if (btstack_uart_posix_set_baudrate(baudrate) < 0)
{
return -1;
}
@ -351,7 +385,8 @@ static int btstack_uart_posix_open(void){
return 0;
}
static int btstack_uart_posix_close_new(void){
static int btstack_uart_posix_close_new(void)
{
// first remove run loop handler
btstack_run_loop_remove_data_source(&transport_data_source);
@ -362,15 +397,18 @@ static int btstack_uart_posix_close_new(void){
return 0;
}
static void btstack_uart_posix_set_block_received( void (*block_handler)(void)){
static void btstack_uart_posix_set_block_received(void (*block_handler)(void))
{
block_received = block_handler;
}
static void btstack_uart_posix_set_block_sent( void (*block_handler)(void)){
static void btstack_uart_posix_set_block_sent(void (*block_handler)(void))
{
block_sent = block_handler;
}
static void btstack_uart_posix_send_block(const uint8_t *data, uint16_t size){
static void btstack_uart_posix_send_block(const uint8_t *data, uint16_t size)
{
// setup async write
write_bytes_data = data;
write_bytes_len = size;
@ -380,7 +418,8 @@ static void btstack_uart_posix_send_block(const uint8_t *data, uint16_t size){
btstack_run_loop_enable_data_source_callbacks(&transport_data_source, DATA_SOURCE_CALLBACK_WRITE);
}
static void btstack_uart_posix_receive_block(uint8_t *buffer, uint16_t len){
static void btstack_uart_posix_receive_block(uint8_t *buffer, uint16_t len)
{
read_bytes_data = buffer;
read_bytes_len = len;
btstack_run_loop_enable_data_source_callbacks(&transport_data_source, DATA_SOURCE_CALLBACK_READ);
@ -408,9 +447,13 @@ static const btstack_uart_block_t btstack_uart_posix = {
/* int (*get_supported_sleep_modes); */ NULL,
/* void (*set_sleep)(btstack_uart_sleep_mode_t sleep_mode); */ NULL,
/* void (*set_wakeup_handler)(void (*handler)(void)); */ NULL,
NULL, NULL, NULL, NULL,
NULL,
NULL,
NULL,
NULL,
};
const btstack_uart_block_t * btstack_uart_posix_instance(void){
const btstack_uart_block_t *btstack_uart_posix_instance(void)
{
return &btstack_uart_posix;
}

View file

@ -86,7 +86,7 @@ static void local_version_information_handler(uint8_t *packet);
static hci_transport_config_uart_t config = {
HCI_TRANSPORT_CONFIG_UART,
921600,
460800,
0, // main baudrate
0, // flow control
NULL,

View file

@ -67,11 +67,11 @@ class ESP32BTDriver:
serial_bridge = None
serial_bridge_name = None
serial_hci_thread = None
serial_baudrate = 921600
serial_baudrate = 460800
serial_portname = None
# Constructor ------------------------------------
def __init__(self, port_name=None, baudrate=921600, reset_board=True,
def __init__(self, port_name=None, baudrate=460800, reset_board=True,
debug=False):
self.serial_portname = port_name