Hackster is hosting Hackster Holidays, Ep. 7: Livestream & Giveaway Drawing. Watch previous episodes or stream live on Friday!Stream Hackster Holidays, Ep. 7 on Friday!
Ashok R
Published

Sketch Drive Car V2

An intelligent drive.

AdvancedShowcase (no instructions)Over 2 days1,244

Things used in this project

Hardware components

NXP FRDM-KW40Z
×1
General Purpose Transistor NPN
General Purpose Transistor NPN
×1
LED 1Watt
×2
Power Bank
×1

Software apps and online services

Sketch Drive Car App

Story

Read more

Schematics

FRDM-KW40Z Schematic

Code

Main.c

C/C++
Use FRDM-KW40Z SDK for Drivers
/*! *********************************************************************************
 * \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)
{    
    
}


/*! *********************************************************************************
 * @}
 ********************************************************************************** */

Credits

Ashok R
37 projects • 102 followers
Hobbyist/Engineer/Director/Animatior

Comments