Hello Syed,
I will try to explain how wireless_uart is structured. In function BleApp_StateMachineHandler function, different event states are handled, at the begining, mAppIdle_c state is handled, in this function a software timer is started:
TMR_StartLowPowerTimer(mUartStreamFlushTimerId,
gTmrLowPowerIntervalMillisTimer_c,
15,
UartStreamFlushTimerCallback, NULL);
This timer is configured to call UartStreamFlushTimerCallback callback every 15 milliseconds (and this callback is used to read from console and send it back to cellphone). Once timer is running, application continues with its logic (Find art stream characteristics and store service handles) until it is in mAppRunning_c state.
As callback is called every 15 millisenconds, UartStreamFlushTimerCAllback will be polling for data in serial port just after application is in mAppRunning_c state. So this UartStreamFlushTimerCallback is called periodically.
If you want to send data to Wireless Uart application only once you have to consider:
- Buetooth state machine is in mAppRunning_c state in order to call BleApp_SendUartStream function.
- Data to be send must terminate in '0x0D'.
I added a short workaround that prints a message in th terminal:
#if WORKAROUND_TO_SEND_DATA_ONCE
static uint8_t message_was_sent = FALSE;
uint8_t data_buffer[] = {"This is my test\r"};
#endif
static void UartStreamFlushTimerCallback(void *pData)
{
uint16_t bytesRead = 0;
uint16_t byteCount = 0;
if (mPeerInformation.appState != mAppRunning_c)
{
return;
}
#if WORKAROUND_TO_SEND_DATA_ONCE
if (!message_was_sent) {
message_was_sent = TRUE;
/* Send data to app, buffer size is decreased by one in order to eliminate NULL character at the buffer's end and last byte could be 0x0D*/
BleApp_SendUartStream(mPeerInformation.deviceId, &data_buffer[0], sizeof(data_buffer) - 1);
} else {
#endif
if ( Serial_Read( gAppSerMgrIf, recvStream, mAppUartBufferSize_c, &bytesRead) == gSerial_Success_c )
{
while (byteCount < bytesRead)
{
BleApp_SendUartStream(mPeerInformation.deviceId, &recvStream[byteCount], MIN(mUartStreamMaxSize_c, bytesRead - byteCount));
byteCount += MIN(mUartStreamMaxSize_c, bytesRead - byteCount);
}
}
#if WORKAROUND_TO_SEND_DATA_ONCE
}
#endif
}
In this workaround, message will be printed only once due message_was_sent boolean variable, so, although this UartStreamFlushTimerCallback function is called periodically, it will only send data_buffer the first time.
Another possible solution could be to start an One shot timer and use the callback to send this data to application, this way you do not need to use a boolean variable to control if message has been sent. This solution would look like:
static tmrTimerID_t mOneShotTimerId;
In BleApp_Config function, add the last line:
/* Allocate application timer */
mAppTimerId = TMR_AllocateTimer();
mUartStreamFlushTimerId = TMR_AllocateTimer();
mBatteryMeasurementTimerId = TMR_AllocateTimer();
mOneShotTimerId = TMR_AllocateTimer();
And start this timer just before application reaches mAppRunning_c state:
case mAppCharServiceDisc_c:
{
if (event == mAppEvt_GattProcComplete_c)
{
/* Moving to Running State*/
mPeerInformation.appState = mAppRunning_c;
mpServiceDiscoveryBuffer->aCharacteristics = mpCharDiscoveryBuffer;
BleApp_StoreServiceHandles(mpServiceDiscoveryBuffer);
BleApp_ServiceDiscoveryReset();
TMR_StartLowPowerTimer(mOneShotTimerId,
gTmrLowPowerSingleShotMillisTimer_c,
500,
myCallbackToSendDataOnce, NULL);
}
So 500 milliseconds after mAppRunning_c state is reached, myCallbackToSendDataOnce function will be called and in this callback you can send data to cellphone, just remember to end this buffer by using 0x0D.
Does it make sense to you?
Hope this helps,
Regards,
Isaac