blob: 7076ad6cc5521c2dfea21ee9f5cf44ec1f2ce383 [file] [log] [blame]
/***************************************************************************//**
* @file
* @brief Board Controller Communications (BCC) definitions
* @version 4.2.1
*******************************************************************************
* @section License
* <b>(C) Copyright 2014 Silicon Labs, http://www.silabs.com</b>
*******************************************************************************
*
* This file is licensed under the Silabs License Agreement. See the file
* "Silabs_License_Agreement.txt" for details. Before using this software for
* any purpose, you must agree to the terms of that agreement.
*
******************************************************************************/
#include <string.h>
#include "em_device.h"
#include "em_cmu.h"
#include "em_gpio.h"
#include "bsp.h"
#if defined( BSP_BCC_LEUART )
#include "em_leuart.h"
#else
#include "em_usart.h"
#endif
#if defined( BSP_STK )
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
/* Module local variables */
static uint32_t rxByteCount;
static uint32_t txByteCount;
/* Module local prototypes */
static void TxByte( uint8_t data );
static uint8_t RxByte( void );
/** @endcond */
/***************************************************************************//**
* @addtogroup BSP
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup BSP_STK API for STKs and WSTKs
* @{
******************************************************************************/
/**************************************************************************//**
* @brief Deinitialize board controller communication support (BCC)
* functionality. Reverse actions performed by @ref BSP_BccInit().
*
* @return @ref BSP_STATUS_OK.
*****************************************************************************/
int BSP_BccDeInit( void )
{
/* Reset counters */
rxByteCount = 0xFFFFFFFFUL;
txByteCount = 0xFFFFFFFFUL;
BSP_BccPinsEnable( false );
#if defined( BSP_BCC_LEUART )
/* Reset LEUART */
LEUART_Reset( BSP_BCC_LEUART );
#else
/* Reset USART */
USART_Reset( BSP_BCC_USART );
#endif
/* Disable clock */
CMU_ClockEnable( BSP_BCC_CLK, false );
return BSP_STATUS_OK;
}
/**************************************************************************//**
* @brief Initialize board controller communication support (BCC)
* functionality.
*
* @return @ref BSP_STATUS_OK.
*****************************************************************************/
int BSP_BccInit( void )
{
#if defined( BSP_BCC_LEUART )
LEUART_Init_TypeDef leuartInit = LEUART_INIT_DEFAULT;
#else
USART_InitAsync_TypeDef usartInit = USART_INITASYNC_DEFAULT;
#endif
rxByteCount = 0;
txByteCount = 0;
/* Enable High Frequency Peripherals */
CMU_ClockEnable(cmuClock_HFPER, true);
/* Enable clocks to GPIO */
CMU_ClockEnable(cmuClock_GPIO, true);
/* Enable UART clock */
CMU_ClockEnable( BSP_BCC_CLK, true );
#if defined( BSP_BCC_LEUART )
/* Enable CORE LE clock in order to access LE modules */
CMU_ClockEnable(cmuClock_CORELE, true);
/* Select CORE LE clock for LE modules */
CMU_ClockSelectSet( cmuClock_LFB, cmuSelect_CORELEDIV2 );
/* Initialize LEUART */
leuartInit.baudrate = 115200;
LEUART_Init( BSP_BCC_LEUART, &leuartInit );
#else
/* Initialize USART */
USART_InitAsync( BSP_BCC_USART, &usartInit );
#endif
/* Initialize UART pins */
BSP_BccPinsEnable( true );
return BSP_STATUS_OK;
}
/**************************************************************************//**
* @brief Get a packet from the board controller.
*
* @param[in] pkt Pointer to a @ref BCP_Packet instance.
*
* @return True if packet received without errors, false otherwise.
*****************************************************************************/
bool BSP_BccPacketReceive( BCP_Packet *pkt )
{
int i;
int length;
uint8_t *bptr;
/* Setup a byte pointer to start of packet buffer */
bptr = (uint8_t *) pkt;
/* Receive packet magic */
*bptr++ = RxByte();
if (pkt->magic != BSP_BCP_MAGIC)
{
return false;
}
/* Receive packet type */
*bptr++ = RxByte();
if ( (pkt->type < BSP_BCP_FIRST) || (pkt->type > BSP_BCP_LAST) )
{
return false;
}
/* Receive packet length */
*bptr++ = RxByte();
if (pkt->payloadLength > BSP_BCP_PACKET_SIZE)
{
return false;
}
#if ( BSP_BCP_VERSION == 2 )
/* Receive reserved byte */
*bptr++ = RxByte();
#endif
/* Receive packet data length field and sanity check it */
length = pkt->payloadLength;
if (length > BSP_BCP_PACKET_SIZE)
{
length = BSP_BCP_PACKET_SIZE;
}
/* Receive packet payload */
for( i=0; i<length; i++ )
{
*bptr++ = RxByte();
}
return true;
}
/**************************************************************************//**
* @brief Send a packet to the board controller.
*
* @param[in] pkt Pointer to a @ref BCP_Packet instance.
*
* @return @ref BSP_STATUS_OK.
*****************************************************************************/
int BSP_BccPacketSend( BCP_Packet *pkt )
{
int i;
/* Apply magic */
pkt->magic = BSP_BCP_MAGIC;
/* Transmit packet magic */
TxByte( pkt->magic );
/* Transmit packet type */
TxByte( pkt->type );
/* Transmit packet length */
TxByte( pkt->payloadLength );
#if ( BSP_BCP_VERSION == 2 )
/* Transmit reserved byte */
TxByte( pkt->reserved );
#endif
/* Transmit packet payload */
for ( i=0; i<pkt->payloadLength; i++ )
{
TxByte( pkt->data[i] );
}
return BSP_STATUS_OK;
}
/**************************************************************************//**
* @brief Enable GPIO pins for the USART/LEUART used for board communication.
*
* @param[in] enable Set to true to enable pins, set to false to disable.
*****************************************************************************/
void BSP_BccPinsEnable( bool enable )
{
if (enable)
{
/* Configure GPIO pin for UART TX */
/* To avoid false start, configure output as high. */
GPIO_PinModeSet( BSP_BCC_TXPORT, BSP_BCC_TXPIN, gpioModePushPull, 1 );
/* Configure GPIO pin for UART RX */
GPIO_PinModeSet( BSP_BCC_RXPORT, BSP_BCC_RXPIN, gpioModeInput, 1 );
/* Enable the switch that enables UART communication. */
GPIO_PinModeSet( BSP_BCC_ENABLE_PORT, BSP_BCC_ENABLE_PIN, gpioModePushPull, 1 );
#if defined( BSP_BCC_LEUART )
BSP_BCC_LEUART->ROUTE |= LEUART_ROUTE_RXPEN | LEUART_ROUTE_TXPEN | BSP_BCC_LOCATION;
#else
#if defined( USART_ROUTEPEN_TXPEN )
BSP_BCC_USART->ROUTEPEN = USART_ROUTEPEN_TXPEN | USART_ROUTEPEN_RXPEN;
BSP_BCC_USART->ROUTELOC0 =
( BSP_BCC_USART->ROUTELOC0 &
~( _USART_ROUTELOC0_TXLOC_MASK | _USART_ROUTELOC0_RXLOC_MASK ) )
| ( BSP_BCC_TX_LOCATION << _USART_ROUTELOC0_TXLOC_SHIFT )
| ( BSP_BCC_RX_LOCATION << _USART_ROUTELOC0_RXLOC_SHIFT );
#else
BSP_BCC_USART->ROUTE |= USART_ROUTE_RXPEN | USART_ROUTE_TXPEN | BSP_BCC_LOCATION;
#endif
#endif
}
else
{
GPIO_PinModeSet( BSP_BCC_ENABLE_PORT, BSP_BCC_ENABLE_PIN, gpioModeDisabled, 0 );
#if defined( BSP_BCC_LEUART )
BSP_BCC_LEUART->ROUTE &= ~(LEUART_ROUTE_RXPEN | LEUART_ROUTE_TXPEN);
#else
#if defined( USART_ROUTEPEN_TXPEN )
BSP_BCC_USART->ROUTEPEN &= ~(USART_ROUTEPEN_TXPEN | USART_ROUTEPEN_RXPEN);
#else
BSP_BCC_USART->ROUTE &= ~(USART_ROUTE_RXPEN | USART_ROUTE_TXPEN);
#endif
#endif
GPIO_PinModeSet( BSP_BCC_TXPORT, BSP_BCC_TXPIN, gpioModeDisabled, 0 );
GPIO_PinModeSet( BSP_BCC_RXPORT, BSP_BCC_RXPIN, gpioModeDisabled, 0 );
}
}
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
static uint8_t RxByte( void )
{
uint8_t byte;
/* Poll RX data available flag and return a character when one is available */
#if defined( BSP_BCC_LEUART )
while (!(BSP_BCC_LEUART->IF & LEUART_IF_RXDATAV)) ;
byte = BSP_BCC_LEUART->RXDATA;
#else
while (!(BSP_BCC_USART->STATUS & USART_STATUS_RXDATAV)) ;
byte = BSP_BCC_USART->RXDATA;
#endif
rxByteCount++;
return byte;
}
static void TxByte( uint8_t data )
{
/* Check TX buffer and allow for a pending transfer to complete */
#if defined( BSP_BCC_LEUART )
while (!(BSP_BCC_LEUART->STATUS & LEUART_STATUS_TXBL)) ;
BSP_BCC_LEUART->TXDATA = (uint32_t) data;
#else
while (!(BSP_BCC_USART->STATUS & USART_STATUS_TXBL)) ;
BSP_BCC_USART->TXDATA = (uint32_t) data;
#endif
txByteCount++;
}
/** @endcond */
/** @} (end group BSP_STK) */
/** @} (end group BSP) */
#endif /* BSP_STK */