mirror of
https://github.com/oopuuu/zTC1.git
synced 2025-12-16 23:18:24 +08:00
246 lines
8.1 KiB
C
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;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|