Files
zTC1/mico-os/libraries/bluetooth/BTE_platform/mico_bt_bus.c
2025-03-11 15:54:45 +08:00

246 lines
8.1 KiB
C

/**
* UNPUBLISHED PROPRIETARY SOURCE CODE
* Copyright (c) 2016 MXCHIP Inc.
*
* The contents of this file may not be disclosed to third parties, copied or
* duplicated in any form, in whole or in part, without the prior written
* permission of MXCHIP Corporation.
*
*/
/*******************************************************************************
** Name: userial_bby.c
**
** Description:
**
** This file contains the universal driver wrapper for the BTE-QC serial
** drivers
*******************************************************************************/
#include "mico.h"
#include "mico_bt_types.h"
#include "platform_bluetooth.h"
#include "platform_config.h"
/* Macro for checking of bus is initialised */
#define IS_BUS_INITIALISED( ) \
do \
{ \
if ( bus_initialised == false ) \
{ \
printf( "bus uninitialised" ); \
return -1; \
} \
}while ( 0 )
/* Macro for checking if bus is ready */
#define BT_BUS_IS_READY( ) \
do \
{ \
if ( bt_bus_is_ready( ) == false ) \
{ \
printf( "bus not ready" ) \
return kGeneralErr; \
} \
}while ( 0 )
/* Macro for waiting until bus is ready */
#define BT_BUS_WAIT_UNTIL_READY( ) \
do \
{ \
while ( bt_bus_is_ready( ) == false ) \
{ \
mico_thread_msleep( 10 ); \
} \
} while ( 0 )
/* TODO: bring in bt_bus code to remove BTE dependency on MiCO bluetooth library */
extern int bt_bus_init( void );
extern int bt_bus_deinit( void );
extern int bt_bus_transmit( const uint8_t* data_out, uint32_t size );
extern int bt_bus_receive( uint8_t* data_in, uint32_t size, uint32_t timeout_ms );
extern int bt_bus_uart_reset( void );
extern int bt_bus_uart_reconifig_baud(uint32_t baud);
extern bool bt_bus_is_ready( void );
extern OSStatus platform_uart_reconfig( platform_uart_driver_t* driver, const platform_uart_config_t* config );
/******************************************************
* Enumerations
******************************************************/
/*****************************************************************************
* Platform UART interface, taken from
* ../Library/bluetooth/internal/bus/UART/bt_bus.c
* (audio/2.4.x-bluetooth branch)
*****************************************************************************/
#ifndef USERIAL_RX_FIFO_SIZE
#define USERIAL_RX_FIFO_SIZE (3000)
#endif
static volatile bool bus_initialised = false;
static volatile bool device_powered = false;
/* RX ring buffer. Bluetooth chip UART receive can be asynchronous, therefore a ring buffer is required */
static ring_buffer_t rx_ring_buffer;
static uint8_t rx_data[USERIAL_RX_FIFO_SIZE];
int bt_bus_init( void )
{
//USART_OverSampling8Cmd(USART1, ENABLE);
if ( bus_initialised == false )
{
if( mico_bt_control_pins[MICO_BT_PIN_HOST_WAKE] != NULL)
require_noerr( platform_gpio_init( mico_bt_control_pins[MICO_BT_PIN_HOST_WAKE], INPUT_HIGH_IMPEDANCE ), exit );
if( mico_bt_control_pins[MICO_BT_PIN_DEVICE_WAKE] != NULL)
{
require_noerr( platform_gpio_init( mico_bt_control_pins[MICO_BT_PIN_DEVICE_WAKE], OUTPUT_OPEN_DRAIN_PULL_UP ), exit );
require_noerr( platform_gpio_output_high( mico_bt_control_pins[MICO_BT_PIN_DEVICE_WAKE] ), exit );
mico_thread_msleep( 100 );
}
/* Configure Reg Enable pin to output. Set to HIGH */
if( mico_bt_control_pins[MICO_BT_PIN_POWER] != NULL)
{
require_noerr( platform_gpio_init( mico_bt_control_pins[MICO_BT_PIN_POWER], OUTPUT_OPEN_DRAIN_PULL_UP ), exit );
require_noerr( platform_gpio_output_high( mico_bt_control_pins[MICO_BT_PIN_POWER] ), exit );
}
device_powered = true;
if ( mico_bt_uart_config.flow_control == FLOW_CONTROL_DISABLED )
{
/* Configure RTS pin to output. Set to HIGH */
require_noerr( platform_gpio_init( mico_bt_uart_pins[MICO_BT_PIN_UART_RTS], OUTPUT_OPEN_DRAIN_PULL_UP ), exit );
require_noerr( platform_gpio_output_high( mico_bt_uart_pins[MICO_BT_PIN_UART_RTS] ), exit ); //William, working wrong if set high, so donot use FLOW_CONTROL_DISABLED in 43438A1
/* Configure CTS pin to input pull-up */
require_noerr( platform_gpio_init( mico_bt_uart_pins[MICO_BT_PIN_UART_CTS], INPUT_PULL_UP ), exit );
}
/* Configure Reset pin to output. Set to HIGH */
if( mico_bt_control_pins[MICO_BT_PIN_RESET] != NULL)
{
require_noerr( platform_gpio_init( mico_bt_control_pins[MICO_BT_PIN_RESET], OUTPUT_OPEN_DRAIN_PULL_UP ), exit );
require_noerr( platform_gpio_output_high( mico_bt_control_pins[MICO_BT_PIN_RESET] ), exit );
}
/* Initialise RX ring buffer */
ring_buffer_init( &rx_ring_buffer, (uint8_t*) rx_data, sizeof( rx_data ) );
/* Configure USART comms */
require_noerr( platform_uart_init( mico_bt_uart_driver, mico_bt_uart_peripheral, &mico_bt_uart_config, &rx_ring_buffer ), exit );
#ifdef MICO_USE_BT_RESET_PIN
/* Reset bluetooth chip. Delay momentarily. */
require_noerr( platform_gpio_output_low( &bt_control_pins[BT_PIN_RESET] ), exit );
mico_thread_msleep( 10 );
require_noerr( platform_gpio_output_high( &bt_control_pins[BT_PIN_RESET] ), exit );
#endif
/* Wait until the Bluetooth chip stabilizes. */
mico_thread_msleep( 100 );
/* Bluetooth chip is ready. Pull host's RTS low */
if ( mico_bt_uart_config.flow_control == FLOW_CONTROL_DISABLED )
{
/* Bluetooth chip is ready. Pull host's RTS low */
require_noerr( platform_gpio_output_low( mico_bt_uart_pins[MICO_BT_PIN_UART_RTS] ), exit );
}
bus_initialised = true;
/* Wait for bluetooth chip to pull its RTS (host's CTS) low. From observation using CRO, it takes the bluetooth chip > 170ms to pull its RTS low after CTS low */
BT_BUS_WAIT_UNTIL_READY();
}
exit:
return kNoErr;
}
int bt_bus_deinit( void )
{
require( bus_initialised, exit);
if( mico_bt_control_pins[MICO_BT_PIN_RESET] != NULL)
require_noerr( platform_gpio_output_low( mico_bt_control_pins[MICO_BT_PIN_RESET] ), exit );
require_noerr( platform_gpio_output_high( mico_bt_uart_pins[MICO_BT_PIN_UART_RTS] ), exit ); // RTS deasserted
if( mico_bt_control_pins[MICO_BT_PIN_POWER] != NULL)
require_noerr( platform_gpio_output_low ( mico_bt_control_pins[MICO_BT_PIN_POWER] ), exit ); // Bluetooth chip regulator off
device_powered = false;
/* Deinitialise UART */
require_noerr( platform_uart_deinit( mico_bt_uart_driver ), exit );
bus_initialised = false;
return kNoErr;
exit:
return kGeneralErr;
}
int bt_bus_transmit( const uint8_t* data_out, uint32_t size )
{
IS_BUS_INITIALISED();
BT_BUS_WAIT_UNTIL_READY();
require_noerr( platform_uart_transmit_bytes( mico_bt_uart_driver, data_out, size ), exit );
exit:
return kNoErr;
}
int bt_bus_receive( uint8_t* data_in, uint32_t size, uint32_t timeout_ms )
{
IS_BUS_INITIALISED();
return platform_uart_receive_bytes( mico_bt_uart_driver, (void*)data_in, size, timeout_ms );
}
bool bt_bus_is_ready( void )
{
return ( bus_initialised == false ) ? false : ( ( platform_gpio_input_get( mico_bt_uart_pins[MICO_BT_PIN_UART_CTS] ) == true ) ? false : true );
}
int bt_bus_uart_reconifig_baud(uint32_t newBaudRate)
{
platform_uart_config_t bt_uart_config;
uint32_t last_rx_size = mico_bt_uart_driver->rx_size;
memcpy( &bt_uart_config, &mico_bt_uart_config, sizeof( mico_bt_uart_config ) );
if ( bus_initialised == true )
{
bt_uart_config.baud_rate = newBaudRate;
/* Initialise RX ring buffer */
ring_buffer_init( &rx_ring_buffer, (uint8_t*) rx_data, sizeof( rx_data ) );
/* Configure USART comms */
platform_uart_init( mico_bt_uart_driver, mico_bt_uart_peripheral, &bt_uart_config, &rx_ring_buffer );
/* UART receive function may on the pending, but init will clear the rx size, recover here */
mico_bt_uart_driver->rx_size = last_rx_size;
return kNoErr;
}
else
{
return kGeneralErr;
}
}