177 lines
6.6 KiB
C
177 lines
6.6 KiB
C
/* Include Files */
|
|
#include "KTag.h"
|
|
|
|
/* Local Definitions and Constants */
|
|
|
|
#define UART_CIRCULAR_BUFFER_SIZE 1024
|
|
#define BLE_UART_BUFFER_CHARACTERISTIC_SIZE 20
|
|
|
|
/* Public Variables */
|
|
|
|
/* Private Variables */
|
|
|
|
static uint_fast16_t UART_Tx_Notifications_Enabled = 0;
|
|
|
|
static uint8_t UART_Tx_Buffer_Storage[UART_CIRCULAR_BUFFER_SIZE];
|
|
static UTIL_CircularBuffer_T UART_Tx_Buffer;
|
|
static uint8_t BLE_UART_Tx_Buffer[BLE_UART_BUFFER_CHARACTERISTIC_SIZE];
|
|
static uint8_t Rx_Buffer[BLE_UART_BUFFER_CHARACTERISTIC_SIZE + 1];
|
|
|
|
/* Private Function Prototypes */
|
|
|
|
/* Public Functions */
|
|
|
|
void COMM_BLE_UART_Init(void)
|
|
{
|
|
UTIL_InitCircularBuffer(&UART_Tx_Buffer, UART_Tx_Buffer_Storage, UART_CIRCULAR_BUFFER_SIZE);
|
|
}
|
|
|
|
//! Sends a message over the BLE UART.
|
|
void COMM_BLE_UART_PutString(const char8 * string, uint16_t length)
|
|
{
|
|
for (uint8_t i = 0; i < length; i++)
|
|
{
|
|
(void) UTIL_PushToCircularBuffer(&UART_Tx_Buffer, *string++);
|
|
}
|
|
}
|
|
|
|
//! Sends a single character over the BLE UART.
|
|
void COMM_BLE_UART_PutChar(char8 character)
|
|
{
|
|
(void) UTIL_PushToCircularBuffer(&UART_Tx_Buffer, character);
|
|
}
|
|
|
|
void COMM_BLE_UART_MaybeSendData(void)
|
|
{
|
|
int8_t length = 0;
|
|
|
|
if (UTIL_IsCircularBufferEmpty(&UART_Tx_Buffer) == false)
|
|
{
|
|
while ((length < BLE_UART_BUFFER_CHARACTERISTIC_SIZE) && (UTIL_IsCircularBufferEmpty(&UART_Tx_Buffer) == false))
|
|
{
|
|
uint8_t value;
|
|
if (UTIL_PopFromCircularBuffer(&UART_Tx_Buffer, &value) == UTIL_CIRCULARBUFFERRESULT_SUCCESS)
|
|
{
|
|
BLE_UART_Tx_Buffer[length] = value;
|
|
length++;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (length > 0)
|
|
{
|
|
for (uint_fast8_t i = 0; i < CY_BLE_CONN_COUNT; i++)
|
|
{
|
|
if (Cy_BLE_GetConnectionState(appConnHandle[i]) >= CY_BLE_CONN_STATE_CONNECTED)
|
|
{
|
|
cy_stc_ble_gatt_handle_value_pair_t tempHandle;
|
|
|
|
tempHandle.attrHandle = CY_BLE_NORDIC_UART_SERVICE_TX_CHAR_HANDLE;
|
|
tempHandle.value.val = (uint8 *) BLE_UART_Tx_Buffer;
|
|
tempHandle.value.actualLen = length;
|
|
tempHandle.value.len = length;
|
|
|
|
Cy_BLE_GATTS_WriteAttributeValueLocal(&tempHandle);
|
|
}
|
|
}
|
|
|
|
// Send notification to each client that has TX notifications enabled.
|
|
for (uint_fast8_t i = 0; i < CY_BLE_CONN_COUNT; i++)
|
|
{
|
|
if ((Cy_BLE_GetConnectionState(appConnHandle[i]) >= CY_BLE_CONN_STATE_CONNECTED) &&
|
|
Cy_BLE_GATTS_IsNotificationEnabled(&appConnHandle[i],
|
|
CY_BLE_NORDIC_UART_SERVICE_TX_TXCCCD_DESC_HANDLE))
|
|
{
|
|
cy_stc_ble_gatt_handle_value_pair_t tempHandle;
|
|
|
|
tempHandle.attrHandle = CY_BLE_NORDIC_UART_SERVICE_TX_CHAR_HANDLE;
|
|
tempHandle.value.val = (uint8 *) BLE_UART_Tx_Buffer;
|
|
tempHandle.value.actualLen = length;
|
|
tempHandle.value.len = length;
|
|
|
|
Cy_BLE_GATTS_SendNotification(&appConnHandle[i], &tempHandle);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//! BLE event handler for the BLE UART feature.
|
|
/*!
|
|
* This function should be called *before* events are handled in the event handler passed to
|
|
* Cy_BLE_Start(). If it returns `false`, then the rest of the event handler should proceed.
|
|
*
|
|
* \param event BLE stack event code received from the BLE middleware (one of cy_en_ble_event_t).
|
|
* \param eventParam pointer to an event-specific data structure containing the relevant event information.
|
|
* \return true if this handler has completely handled the event, and no further
|
|
* handling is necessary; false otherwise.
|
|
*/
|
|
bool COMM_BLE_UART_HandleEvent(uint32 event, void * eventParam)
|
|
{
|
|
static cy_stc_ble_gatts_write_cmd_req_param_t * writeReqParameter;
|
|
bool handled = false;
|
|
|
|
/* Take an action based on the current event */
|
|
switch ((cy_en_ble_event_t)event)
|
|
{
|
|
// Handle a write request.
|
|
case CY_BLE_EVT_GATTS_WRITE_REQ:
|
|
|
|
writeReqParameter = (cy_stc_ble_gatts_write_cmd_req_param_t*)eventParam;
|
|
|
|
// Request to write the UART.
|
|
// https://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.sdk5.v15.2.0%2Fble_sdk_app_nus_eval.html&cp=5_5_0_4_1_2_24
|
|
if (writeReqParameter->handleValPair.attrHandle == CY_BLE_NORDIC_UART_SERVICE_RX_CHAR_HANDLE)
|
|
{
|
|
// Only update the value and write the response if the requested write is allowed.
|
|
if (CY_BLE_GATT_ERR_NONE == Cy_BLE_GATTS_WriteAttributeValuePeer(&writeReqParameter->connHandle, &writeReqParameter->handleValPair))
|
|
{
|
|
uint16_t i;
|
|
|
|
for (i = 0; (i < BLE_UART_BUFFER_CHARACTERISTIC_SIZE) && (i < writeReqParameter->handleValPair.value.len); i++)
|
|
{
|
|
Rx_Buffer[i] = writeReqParameter->handleValPair.value.val[i];
|
|
}
|
|
|
|
// NULL-terminate the buffer.
|
|
Rx_Buffer[i] = 0x00;
|
|
|
|
Cy_BLE_GATTS_WriteRsp(writeReqParameter->connHandle);
|
|
|
|
COMM_Console_Execute_Internal_Command(Rx_Buffer);
|
|
}
|
|
|
|
handled = true;
|
|
}
|
|
|
|
// Request for UART Tx notifications.
|
|
if (writeReqParameter->handleValPair.attrHandle == CY_BLE_NORDIC_UART_SERVICE_TX_TXCCCD_DESC_HANDLE)
|
|
{
|
|
if (CY_BLE_GATT_ERR_NONE == Cy_BLE_GATTS_WriteAttributeValuePeer(&writeReqParameter->connHandle, &writeReqParameter->handleValPair))
|
|
{
|
|
UART_Tx_Notifications_Enabled = writeReqParameter->handleValPair.value.val[0] & 0x01;
|
|
|
|
if (UART_Tx_Notifications_Enabled)
|
|
{
|
|
COMM_Console_Print_String("[BLE] UART Tx notifications enabled.\n");
|
|
}
|
|
else
|
|
{
|
|
COMM_Console_Print_String("[BLE] UART Tx notifications disabled.\n");
|
|
}
|
|
|
|
Cy_BLE_GATTS_WriteRsp(writeReqParameter->connHandle);
|
|
}
|
|
|
|
handled = true;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
// (`handled` is already set to false.)
|
|
break;
|
|
}
|
|
|
|
return handled;
|
|
}
|
|
|
|
/* Private Functions */
|