This project is based on another one of my earlier project called "Sketch Drive Car" (project). I could say this is a new version of that "Sketch Drive Car V2."
Here the story starts!
After seeing the hackster autonomous challenge mail and dockey kit, I decided to Sketch Drive Car project once-again with new features. I received the RC car by late due to delay in shipment so I have got 15 days to finish. Due to short time I had to cut down some features and sensors. I almost done everything but in the end hackster extended the project deadline. I got relaxed and made some improvements mostly on Android application.
What Is Sketch Drive Car?The concept is drawing routes/path on a mobile device and the car following the same track/road in real-time.
Sketch Drive Car V2In this version I have upgraded the FRDM board to KW40z which has BLE 4.1 connectivity. Also the board comes with level shifter which I used for LED lamp and driving servos.
The car received with Raspberry Pi, power bank and Donkey Car 3D modules. Unfortunately the 3d models does not fit into this type RC car anyway that's not required for my concept. After that I have done some experiments to understand the control signals and finally simulated the same from KW40z MCU and works. Next step is building android app to communicate with KW40z. I used NXP's IoTToolBox app to test initially then later I developed my own android with joystick control on it.
Here is the basic testing video of steering and speed control.
After all finally the car ready head lights.
The KW40z board has push buttons, Button S2 is used to arming the car. Button S1 is used to advertise the BLE. If BLE connection is not made the car will go to power off mode. power bank supplies the power for Freedom Board, headlights and steering servo.
Pin DetailsPTC4 - Throttle PWM, PTC5 - Steering PWM, PTC18 - LIGHT (with 2n390 Transistor)
Finally the video demo of sketch drive was shot in Goa.
Demo Video/*! *********************************************************************************
* \addtogroup Wireless UART Application
* @{
********************************************************************************** */
/*!
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
* \file app.c
* This file is the source file for the Wireless UART Application
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/************************************************************************************
*************************************************************************************
* Include
*************************************************************************************
************************************************************************************/
/* Framework / Drivers */
#include "RNG_interface.h"
#include "Keyboard.h"
#include "Led.h"
#include "TimersManager.h"
#include "FunctionLib.h"
#include "fsl_os_abstraction.h"
#include "panic.h"
#include "SerialManager.h"
#include "MemManager.h"
#include "board.h"
/* BLE Host Stack */
#include "gatt_interface.h"
#include "gatt_server_interface.h"
#include "gatt_client_interface.h"
#include "gatt_database.h"
#include "gap_interface.h"
#include "gatt_db_app_interface.h"
#include "gatt_db_handles.h"
/* Profile / Services */
#include "wireless_uart_interface.h"
#include "battery_interface.h"
#include "board.h"
#include "ApplMain.h"
#include "app.h"
#include "system_tick.h"
/************************************************************************************
*************************************************************************************
* Private macros
*************************************************************************************
************************************************************************************/
#define mUartStreamMaxSize_c gAttMaxWriteDataSize_d(gAttMaxMtu_c)
#define mAppUartBufferSize_c (mUartStreamMaxSize_c * 4)
#define mBatteryLevelReportInterval_c (10) /* battery level report interval in seconds */
/************************************************************************************
*************************************************************************************
* Private type definitions
*************************************************************************************
************************************************************************************/
typedef enum appEvent_tag
{
mAppEvt_PeerConnected_c,
mAppEvt_GattProcComplete_c,
mAppEvt_GattProcError_c
} appEvent_t;
typedef enum appState_tag
{
mAppIdle_c,
mAppPrimaryServiceDisc_c,
mAppCharServiceDisc_c,
mAppRunning_c
} appState_t;
typedef struct appPeerInfo_tag
{
deviceId_t deviceId;
wucConfig_t clientInfo;
appState_t appState;
} appPeerInfo_t;
typedef struct advState_tag
{
bool_t advOn;
} advState_t;
/************************************************************************************
*************************************************************************************
* Private memory declarations
*************************************************************************************
************************************************************************************/
/* Host Stack Data*/
static bleDeviceAddress_t maBleDeviceAddress;
static appPeerInfo_t mPeerInformation;
static gapRole_t mGapStartRole;
/* Adv Parmeters */
static advState_t mAdvState;
static bool_t mScanningOn = FALSE;
static bool_t mFoundDeviceToConnect = FALSE;
/* Buffer used for Service Discovery */
static gattService_t *mpServiceDiscoveryBuffer = NULL;
static uint8_t mcPrimaryServices = 0;
/* Buffer used for Characteristic Procedures */
static gattCharacteristic_t *mpCharDiscoveryBuffer = NULL;
static uint8_t mcCharacteristics = 0;
static uint16_t mCharMonitoredHandles[] = { value_uart_stream};
/* Service Data*/
static wusConfig_t mWuServiceConfig;
static basConfig_t mBasServiceConfig = {service_battery, 0};
static tmrTimerID_t mAppTimerId;
static tmrTimerID_t mUartStreamFlushTimerId;
static tmrTimerID_t mBatteryMeasurementTimerId;
static uint8_t gAppSerMgrIf;
static uint8_t gAppPwmCh0Value;
static uint8_t gAppPwmCh1Value;
uint8_t gAppCtrlValue;
uint8_t recvStream[mAppUartBufferSize_c];
uint16_t recvIndex = 0;
extern volatile bool gArming;
volatile uint8_t gChannel1_ONTime;
volatile uint8_t gChannel2_ONTime;
/************************************************************************************
*************************************************************************************
* Private functions prototypes
*************************************************************************************
************************************************************************************/
/* Gatt and Att callbacks */
static void BleApp_AdvertisingCallback(gapAdvertisingEvent_t* pAdvertisingEvent);
static void BleApp_ScanningCallback (gapScanningEvent_t* pScanningEvent);
static void BleApp_ConnectionCallback
(
deviceId_t peerDeviceId,
gapConnectionEvent_t* pConnectionEvent
);
static void BleApp_GattServerCallback
(
deviceId_t deviceId,
gattServerEvent_t* pServerEvent
);
static void BleApp_GattClientCallback
(
deviceId_t serverDeviceId,
gattProcedureType_t procedureType,
gattProcedureResult_t procedureResult,
bleResult_t error
);
static void BleApp_Config ();
static void BleApp_Advertise (void);
static void BleApp_ResetStateMachine (void);
static void BleApp_ServiceDiscoveryReset(void);
static void BleApp_StateMachineHandler (deviceId_t peerDeviceId, uint8_t event);
static void BleApp_StoreServiceHandles (gattService_t *pService);
static bool_t BleApp_CheckScanEvent (gapScannedDevice_t* pData);
/* Timer Callbacks */
static void ScaningTimerCallback (void *);
static void UartStreamFlushTimerCallback(void *);
static void BatteryMeasurementTimerCallback (void *);
/* Uart Rx Callback*/
static void Uart_RxCallBack(void *pData);
/************************************************************************************
*************************************************************************************
* Public functions
*************************************************************************************
************************************************************************************/
/*! *********************************************************************************
* \brief Initializes application specific functionality before the BLE stack init.
*
********************************************************************************** */
void BleApp_Init(void)
{
/* Initialize application support for drivers */
BOARD_InitAdc();
/* UI */
SerialManager_Init();
/* Register Serial Manager interface */
Serial_InitInterface(&gAppSerMgrIf, APP_SERIAL_INTERFACE_TYPE, APP_SERIAL_INTERFACE_INSTANCE);
Serial_SetBaudRate(gAppSerMgrIf, gUARTBaudRate115200_c);
/* Install Controller Events Callback handler */
Serial_SetRxCallBack(gAppSerMgrIf, Uart_RxCallBack, NULL);
}
/*! *********************************************************************************
* \brief Starts the BLE application.
*
* \param[in] mGapStartRole GAP Start Role (Central or Peripheral).
********************************************************************************** */
void BleApp_Start (gapRole_t mGapStartRole)
{
switch (mGapStartRole)
{
case gGapCentral_c:
{
App_StartScanning(&gAppScanParams, BleApp_ScanningCallback);
break;
}
case gGapPeripheral_c:
{
BleApp_Advertise();
break;
}
default:
break;
}
}
/*! *********************************************************************************
* \brief Handles keyboard events.
*
* \param[in] events Key event structure.
********************************************************************************** */
void BleApp_HandleKeys (key_event_t events)
{
switch (events)
{
case gKBD_EventPressPB1_c:
{
LED_StopFlashingAllLeds();
Led1Flashing();
gArming = true;
BleApp_Start(mGapStartRole);
break;
}
case gKBD_EventLongPB1_c:
{
if (mPeerInformation.deviceId != gInvalidDeviceId_c)
Gap_Disconnect(mPeerInformation.deviceId);
break;
}
case gKBD_EventPressPB2_c:
case gKBD_EventLongPB2_c:
break;
default:
break;
}
}
/*! *********************************************************************************
* \brief Handles BLE generic callback.
*
* \param[in] pGenericEvent Pointer to gapGenericEvent_t.
********************************************************************************** */
void BleApp_GenericCallback (gapGenericEvent_t* pGenericEvent)
{
switch (pGenericEvent->eventType)
{
case gInitializationComplete_c:
{
BleApp_Config();
}
break;
case gPublicAddressRead_c:
{
/* Use address read from the controller */
FLib_MemCpyReverseOrder(maBleDeviceAddress,
pGenericEvent->eventData.aAddress, sizeof(bleDeviceAddress_t));
}
break;
case gAdvertisingParametersSetupComplete_c:
{
App_StartAdvertising(BleApp_AdvertisingCallback,
BleApp_ConnectionCallback);
}
break;
case gInternalError_c:
{
panic(0, 0, 0, 0);
}
break;
default:
break;
}
}
/************************************************************************************
*************************************************************************************
* Private functions
*************************************************************************************
************************************************************************************/
/*! *********************************************************************************
* \brief Configures BLE Stack after initialization. Usually used for
* configuring advertising, scanning, white list, services, et al.
*
********************************************************************************** */
static void BleApp_Config (void)
{
/* Read public address from controller */
Gap_ReadPublicDeviceAddress();
/* Register for callbacks*/
App_RegisterGattServerCallback(BleApp_GattServerCallback);
App_RegisterGattClientProcedureCallback(BleApp_GattClientCallback);
GattServer_RegisterHandlesForWriteNotifications(sizeof(mCharMonitoredHandles), mCharMonitoredHandles);
/* Setup Advertising and scanning data */
Gap_SetAdvertisingData(&gAppAdvertisingData, &gAppScanRspData);
mAdvState.advOn = FALSE;
mPeerInformation.appState = mAppIdle_c;
mScanningOn = FALSE;
mFoundDeviceToConnect = FALSE;
/* By default, always start node as GAP central */
mGapStartRole = gGapCentral_c;
/* Start services */
Wus_Start(&mWuServiceConfig);
mBasServiceConfig.batteryLevel = BOARD_GetBatteryLevel();
Bas_Start(&mBasServiceConfig);
/* Allocate application timer */
mAppTimerId = TMR_AllocateTimer();
mUartStreamFlushTimerId = TMR_AllocateTimer();
mBatteryMeasurementTimerId = TMR_AllocateTimer();
}
/*! *********************************************************************************
* \brief Configures GAP Advertise parameters. Advertise will start after
* the parameters are set.
*
********************************************************************************** */
static void BleApp_Advertise (void)
{
/* Set advertising parameters*/
Gap_SetAdvertisingParameters(&gAdvParams);
}
/*! *********************************************************************************
* \brief Handles BLE Scanning callback from host stack.
*
* \param[in] pScanningEvent Pointer to gapScanningEvent_t.
********************************************************************************** */
static void BleApp_ScanningCallback (gapScanningEvent_t* pScanningEvent)
{
switch (pScanningEvent->eventType)
{
case gDeviceScanned_c:
{
mFoundDeviceToConnect = BleApp_CheckScanEvent(&pScanningEvent->eventData.scannedDevice);
if (mFoundDeviceToConnect)
{
gConnReqParams.peerAddressType = pScanningEvent->eventData.scannedDevice.addressType;
FLib_MemCpy(gConnReqParams.peerAddress,
pScanningEvent->eventData.scannedDevice.aAddress,
sizeof(bleDeviceAddress_t));
Gap_StopScanning();
}
}
break;
case gScanStateChanged_c:
{
mScanningOn = !mScanningOn;
/* Node starts scanning */
if (mScanningOn)
{
mFoundDeviceToConnect = FALSE;
/* Start advertising timer */
TMR_StartLowPowerTimer(mAppTimerId,
gTmrLowPowerSecondTimer_c,
TmrSeconds(gScanningTime_c),
ScaningTimerCallback, NULL);
Led1Flashing();
}
/* Node is not scanning */
else
{
TMR_StopTimer(mAppTimerId);
if (mFoundDeviceToConnect)
{
Gap_Connect(&gConnReqParams, BleApp_ConnectionCallback);
}
else
{
Led1Flashing();
Led2Flashing();
//Led3Flashing();
//Led4Flashing();
}
}
}
break;
case gScanCommandFailed_c:
{
panic(0, 0, 0, 0);
break;
}
default:
break;
}
}
/*! *********************************************************************************
* \brief Handles BLE Advertising callback from host stack.
*
* \param[in] pAdvertisingEvent Pointer to gapAdvertisingEvent_t.
********************************************************************************** */
static void BleApp_AdvertisingCallback (
gapAdvertisingEvent_t* pAdvertisingEvent)
{
switch (pAdvertisingEvent->eventType)
{
case gAdvertisingStateChanged_c:
{
mAdvState.advOn = !mAdvState.advOn;
LED_StopFlashingAllLeds();
Led1Flashing();
if (!mAdvState.advOn)
{
Led2Flashing();
}
}
break;
case gAdvertisingCommandFailed_c:
{
panic(0, 0, 0, 0);
}
break;
default:
break;
}
}
/*! *********************************************************************************
* \brief Handles BLE Connection callback from host stack.
*
* \param[in] peerDeviceId Peer device ID.
* \param[in] pConnectionEvent Pointer to gapConnectionEvent_t.
********************************************************************************** */
static void BleApp_ConnectionCallback (
deviceId_t peerDeviceId,
gapConnectionEvent_t* pConnectionEvent)
{
switch (pConnectionEvent->eventType)
{
case gConnEvtConnected_c:
{
mPeerInformation.deviceId = peerDeviceId;
/* Advertising stops when connected */
mAdvState.advOn = FALSE;
/* Subscribe client*/
Wus_Subscribe(peerDeviceId);
Bas_Subscribe(peerDeviceId);
/* UI */
LED_StopFlashingAllLeds();
Led1On();
/* Stop Advertising Timer*/
mAdvState.advOn = FALSE;
TMR_StopTimer(mAppTimerId);
BleApp_StateMachineHandler(mPeerInformation.deviceId,
mAppEvt_PeerConnected_c);
/* Start battery measurements */
TMR_StartLowPowerTimer(mBatteryMeasurementTimerId, gTmrLowPowerIntervalMillisTimer_c,
TmrSeconds(mBatteryLevelReportInterval_c), BatteryMeasurementTimerCallback, NULL);
}
break;
case gConnEvtDisconnected_c:
{
/* Unsubscribe client */
Wus_Unsubscribe();
Bas_Unsubscribe();
gArming = false;
/* Reset State Machine */
BleApp_ResetStateMachine();
/* UI */
LED_TurnOffAllLeds();
LED_StartFlash(LED_ALL);
BleApp_Start(mGapStartRole);
break;
}
default:
break;
}
}
/*! *********************************************************************************
* \brief Handles GATT client callback from host stack.
*
* \param[in] serverDeviceId Server peer device ID.
* \param[in] procedureType GATT procedure type.
* \param[in] procedureType GATT procedure result.
* \param[in] error Result.
********************************************************************************** */
static void BleApp_GattClientCallback (
deviceId_t serverDeviceId,
gattProcedureType_t procedureType,
gattProcedureResult_t procedureResult,
bleResult_t error)
{
if (procedureResult == gGattProcError_c)
{
BleApp_StateMachineHandler(serverDeviceId, mAppEvt_GattProcError_c);
}
else if (procedureResult == gGattProcSuccess_c)
{
BleApp_StateMachineHandler(serverDeviceId, mAppEvt_GattProcComplete_c);
}
}
static void BleApp_ParseSerialData(uint8_t *pBuf){
uint8_t digit0,digit1,digit2;
uint8_t value=0;
digit0 = pBuf[2] - '0';
digit1 = pBuf[1] - '0';
digit2 = pBuf[0] - '0';
value = digit0 + digit1*10 + digit2*100;
if(value >= 125) value=125;
gChannel1_ONTime = ONT_MIN + value;
digit0 = pBuf[5] - '0';
digit1 = pBuf[4] - '0';
digit2 = pBuf[3] - '0';
value = digit0 + digit1*10 + digit2*100;
if(value >= 120) value=120;
gChannel2_ONTime = ONT_MIN + value;
gAppCtrlValue = pBuf[6] - '0';
}
/*! *********************************************************************************
* \brief Handles GATT server callback from host stack.
*
* \param[in] deviceId Client peer device ID.
* \param[in] pServerEvent Pointer to gattServerEvent_t.
********************************************************************************** */
static void BleApp_GattServerCallback (
deviceId_t deviceId,
gattServerEvent_t* pServerEvent)
{
switch (pServerEvent->eventType)
{
case gEvtAttributeWrittenWithoutResponse_c:
{
if (pServerEvent->eventData.attributeWrittenEvent.handle == value_uart_stream)
{
Serial_SyncWrite(gAppSerMgrIf,
pServerEvent->eventData.attributeWrittenEvent.aValue,
pServerEvent->eventData.attributeWrittenEvent.cValueLength);
/* Ashok PWM Out Drive*/
BleApp_ParseSerialData(pServerEvent->eventData.attributeWrittenEvent.aValue);
}
break;
}
default:
break;
}
}
static bool_t MatchDataInAdvElementList (
gapAdStructure_t *pElement,
void *pData,
uint8_t iDataLen)
{
uint8_t i;
for (i = 0; i < pElement->length; i += iDataLen)
{
if (FLib_MemCmp(pData, &pElement->aData[i], iDataLen))
{
return TRUE;
}
}
return FALSE;
}
/*! *********************************************************************************
* \brief Checks Scan data for a device to connect.
*
* \param[in] pData Pointer to gapScannedDevice_t.
********************************************************************************** */
static bool_t BleApp_CheckScanEvent (gapScannedDevice_t* pData)
{
uint8_t index = 0;
bool_t foundMatch = FALSE;
while (index < pData->dataLength)
{
gapAdStructure_t adElement;
adElement.length = pData->data[index];
adElement.adType = (gapAdType_t) pData->data[index + 1];
adElement.aData = &pData->data[index + 2];
/* Search for Temperature Custom Service */
if ((adElement.adType == gAdIncomplete128bitServiceList_c)
|| (adElement.adType == gAdComplete128bitServiceList_c))
{
foundMatch = MatchDataInAdvElementList(&adElement,
&uuid_service_wireless_uart, 16);
}
/* Move on to the next AD elemnt type */
index += adElement.length + sizeof(uint8_t);
}
return foundMatch;
}
/*! *********************************************************************************
* \brief Stores handles used by the application.
*
* \param[in] pService Pointer to gattService_t.
********************************************************************************** */
static void BleApp_StoreServiceHandles (gattService_t *pService)
{
uint8_t i;
/* Found Wireless UART Service */
mPeerInformation.clientInfo.hService = pService->startHandle;
if (mcCharacteristics)
{
/* Found Temperature Char */
mPeerInformation.clientInfo.hUartStream =
pService->aCharacteristics[0].value.handle;
}
}
/*! *********************************************************************************
* \brief Initiates Primary Service Discovery for Wireless UART service.
*
* \param[in] deviceId Device Id.
********************************************************************************** */
static void BleApp_FindWirelessUartService (deviceId_t deviceId)
{
/* Allocate memory for Service Discovery */
mpServiceDiscoveryBuffer = MEM_BufferAlloc(
sizeof(gattService_t) * gMaxServicesCount_d);
if (!mpServiceDiscoveryBuffer)
return;
/* Start Service Discovery*/
GattClient_DiscoverPrimaryServicesByUuid(deviceId, gBleUuidType128_c,
(bleUuid_t*) &uuid_service_wireless_uart, mpServiceDiscoveryBuffer,
gMaxServicesCount_d, &mcPrimaryServices);
}
/*! *********************************************************************************
* \brief Initiates Characteristic Discovery for ASCII Char characteristic.
*
* \param[in] deviceId Device Id.
********************************************************************************** */
static void BleApp_FindUartStreamCharacteristic (deviceId_t deviceId)
{
/* Allocate memory for Char Discovery */
mpCharDiscoveryBuffer = MEM_BufferAlloc(
sizeof(gattCharacteristic_t) * gMaxCharCount_d);
if (!mpCharDiscoveryBuffer)
return;
GattClient_DiscoverCharacteristicOfServiceByUuid(deviceId,
gBleUuidType128_c, (bleUuid_t*) &uuid_uart_stream,
mpServiceDiscoveryBuffer, mpCharDiscoveryBuffer,
gMaxCharCount_d, &mcCharacteristics);
}
static void BleApp_SendUartStream(deviceId_t deviceId, uint8_t *pRecvStream, uint8_t streamSize)
{
gattCharacteristic_t characteristic;
characteristic.value.handle = mPeerInformation.clientInfo.hUartStream;
GattClient_WriteCharacteristicValue(deviceId, &characteristic,
streamSize, pRecvStream, TRUE,
FALSE, FALSE, NULL);
}
static void BleApp_StateMachineHandler (deviceId_t peerDeviceId, uint8_t event)
{
switch (mPeerInformation.appState)
{
case mAppIdle_c:
{
if (event == mAppEvt_PeerConnected_c)
{
/* Moving to Primary Service Discovery State*/
mPeerInformation.appState = mAppPrimaryServiceDisc_c;
BleApp_FindWirelessUartService(peerDeviceId);
TMR_StartLowPowerTimer(mUartStreamFlushTimerId,
gTmrLowPowerIntervalMillisTimer_c,
15,
UartStreamFlushTimerCallback, NULL);
}
break;
}
case mAppPrimaryServiceDisc_c:
{
if (event == mAppEvt_GattProcComplete_c)
{
/* Moving to Characteristic Discovery State*/
mPeerInformation.appState = mAppCharServiceDisc_c;
BleApp_FindUartStreamCharacteristic(peerDeviceId);
}
else if (event == mAppEvt_GattProcError_c)
{
/* Retry service discovery */
BleApp_FindWirelessUartService(peerDeviceId);
}
break;
}
case mAppCharServiceDisc_c:
{
if (event == mAppEvt_GattProcComplete_c)
{
/* Moving to Running State*/
mPeerInformation.appState = mAppRunning_c;
mpServiceDiscoveryBuffer->aCharacteristics = mpCharDiscoveryBuffer;
BleApp_StoreServiceHandles(mpServiceDiscoveryBuffer);
BleApp_ServiceDiscoveryReset();
}
else if (event == mAppEvt_GattProcError_c)
{
/* Retry service discovery */
BleApp_FindWirelessUartService(peerDeviceId);
}
gChannel1_ONTime = gChannel2_ONTime = 150;
break;
}
case mAppRunning_c:
{
break;
}
}
}
static void BleApp_ResetStateMachine (void)
{
mPeerInformation.appState = mAppIdle_c;
mPeerInformation.deviceId = gInvalidDeviceId_c;
}
static void BleApp_ServiceDiscoveryReset(void)
{
if (mpServiceDiscoveryBuffer != NULL)
{
MEM_BufferFree(mpServiceDiscoveryBuffer);
mpServiceDiscoveryBuffer = NULL;
}
if (mpCharDiscoveryBuffer != NULL)
{
MEM_BufferFree(mpCharDiscoveryBuffer);
mpCharDiscoveryBuffer = NULL;
}
}
/*! *********************************************************************************
* \brief Handles scanning timer callback.
*
* \param[in] pParam Calback parameters.
********************************************************************************** */
static void ScaningTimerCallback (void * pParam)
{
/* Stop scanning and start advertising */
Gap_StopScanning();
BleApp_Advertise();
}
static void UartStreamFlushTimerCallback(void *pData)
{
uint16_t bytesRead = 0;
uint16_t byteCount = 0;
if (mPeerInformation.appState != mAppRunning_c)
{
return;
}
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);
}
}
}
/*! *********************************************************************************
* \brief Handles battery measurement timer callback.
*
* \param[in] pParam Calback parameters.
********************************************************************************** */
static void BatteryMeasurementTimerCallback(void * pParam)
{
mBasServiceConfig.batteryLevel = BOARD_GetBatteryLevel();
Bas_RecordBatteryMeasurement(mBasServiceConfig.serviceHandle, mBasServiceConfig.batteryLevel);
}
static void Uart_RxCallBack(void *pData)
{
}
/*! *********************************************************************************
* @}
********************************************************************************** */
Comments