This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

UART readcallback mode

Other Parts Discussed in Thread: CC2640

Hi,

I am trying to use the uart read interrupt through the uart driver. I am not able to read from the UART.

I have pasted the code added to simpleBLEPeripheral below. I am not currently using the npi patches.

In looking at this thread, am I required to manually post a semaphore?

e2e.ti.com/.../440802

I am using TI RTOS 2.13.00.06

BLE Stack 2.1 and CCS 6.1.2, CC2640 4x4 chip.

Thanks,

Priya

#include "Board.h"

static UART_Handle uart;

static void readCallback(UART_Handle handle, void *rx_buf, size_t size)
{

    UART_read(uart, &rx_buf, size);
// UART_enqueueMsg(&rx_buf);

}

static void UART_initialize(void)
{
 UART_init();
 UART_Params uartParams;
    uint8_t rx_buf;
    uint8_t size = sizeof(rx_buf);

 /* Create a UART with data processing off. */
 UART_Params_init(&uartParams);
 uartParams.writeDataMode = UART_DATA_BINARY;
 uartParams.readDataMode = UART_DATA_BINARY;
 uartParams.readReturnMode = UART_RETURN_FULL;
 uartParams.readMode = UART_MODE_CALLBACK;
 uartParams.baudRate = 9600;

 uart = UART_open(Board_UART, &uartParams);

  if (uart == NULL) {
   System_abort("Error opening the UART");
  }

 uartParams.readCallback = readCallback;

}

  • Hello. I would recommend using the UART driver included with the RTOS install. See an example of this in the SNP project.
    Also see the UART documentation included with the RTOS.
  • The code sets the readCallback after UART_open is called. That won't work because the parameters are copied into the UART object during UART_open.
  • I updated my code to do exactly what the UART doc in the RTOS directory did.

    static void readCallback(UART_Handle uart, void *rx_buf, size_t size)
    {

        tx_buf = *((uint8_t*) rx_buf);

        UART_write(uart, &tx_buf, size);
        UART_write(uart, 0x23, 1);
        UART_read(uart, &rx_buf, size);
    //    UART_enqueueMsg(&rxBytes, uart);
    }

    static void UART_initialize(void)
    {
     UART_init();
     UART_Params uartParams;

        UART_Handle uart;

     /* Create a UART with data processing off. */
     UART_Params_init(&uartParams);
     uartParams.writeDataMode = UART_DATA_BINARY;
     uartParams.readDataMode = UART_DATA_BINARY;
     uartParams.readReturnMode = UART_RETURN_FULL;
     uartParams.readMode = UART_MODE_CALLBACK;
     uartParams.baudRate = 9600;
     uartParams.readCallback = readCallback;

     uart = UART_open(Board_UART, &uartParams);

      if (uart == NULL) {
       System_abort("Error opening the UART");
      }

        rxBytes = UART_read(uart, &rx_buf, sizeof (rx_buf));

        while(true);

    }

    In sending out 2 bytes, the scope is showing a one byte delay in the UART data being written.

    The continuous receive in UART_MODE_CALLBACK is working with a one byte delay.

    What is the best place to call the UART_enqueue_msg in SBP? I am trying to trigger an UART

    event and simply write to the UART when this event triggers instead of in the readCallback function

    in order to make this an RTOS task.

    Thanks,

    Priya

      

  • I realized when I try to enqueuer the UART message, I had to be aware the uartEvt_t structure

    is different than the sbpEvt_t structure. Though I made this change, the UART event is not triggering

    and it is not getting dequeued from the list of RTOS tasks. I have attached my SBP.c code file.

    I appreciate an insight into what may be going on.

    Thanks,

    Priya

    /*******************************************************************************
      Filename:       simpleBLEPeripheral.c
      Revised:        $Date: 2016-01-07 16:59:59 -0800 (Thu, 07 Jan 2016) $
      Revision:       $Revision: 44594 $
    
      Description:    This file contains the Simple BLE Peripheral sample 
                      application for use with the CC2650 Bluetooth Low Energy 
                      Protocol Stack.
    
      Copyright 2013 - 2015 Texas Instruments Incorporated. All rights reserved.
    
      IMPORTANT: Your use of this Software is limited to those specific rights
      granted under the terms of a software license agreement between the user
      who downloaded the software, his/her employer (which must be your employer)
      and Texas Instruments Incorporated (the "License").  You may not use this
      Software unless you agree to abide by the terms of the License. The License
      limits your use, and you acknowledge, that the Software may not be modified,
      copied or distributed unless embedded on a Texas Instruments microcontroller
      or used solely and exclusively in conjunction with a Texas Instruments radio
      frequency transceiver, which is integrated into your product.  Other than for
      the foregoing purpose, you may not use, reproduce, copy, prepare derivative
      works of, modify, distribute, perform, display or sell this Software and/or
      its documentation for any purpose.
    
      YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE
      PROVIDED �AS IS� WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,
      INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE,
      NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL
      TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT,
      NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER
      LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES
      INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE
      OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT
      OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
      (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
    
      Should you have any questions regarding your right to use this Software,
      contact Texas Instruments Incorporated at www.TI.com.
    *******************************************************************************/
    
    /*********************************************************************
     * INCLUDES
     */
    #include <string.h>
    
    #include <ti/sysbios/knl/Task.h>
    #include <ti/sysbios/knl/Clock.h>
    #include <ti/sysbios/knl/Semaphore.h>
    #include <ti/sysbios/knl/Queue.h>
    #include <ti/drivers/UART.h>
    
    #include <xdc/std.h>
    #include <xdc/cfg/global.h>
    #include <xdc/runtime/System.h>
    #include <xdc/runtime/Error.h>
    
    #include "hci_tl.h"
    #include "gatt.h"
    #include "gapgattserver.h"
    #include "gattservapp.h"
    #include "devinfoservice.h"
    #include "simpleGATTprofile.h"
    
    #if defined(SENSORTAG_HW)
    #include "bsp_spi.h"
    #endif // SENSORTAG_HW
    
    #if defined(FEATURE_OAD) || defined(IMAGE_INVALIDATE)
    #include "oad_target.h"
    #include "oad.h"
    #endif //FEATURE_OAD || IMAGE_INVALIDATE
    
    #include "peripheral.h"
    #include "gapbondmgr.h"
    
    #include "osal_snv.h"
    #include "ICallBleAPIMSG.h"
    
    #include "util.h"
    #include "board_lcd.h"
    #include "board_key.h"
    #include "Board.h"
    
    #include "simpleBLEPeripheral.h"
    
    #include <ti/drivers/lcd/LCDDogm1286.h>
    
    /*********************************************************************
     * CONSTANTS
     */
    // Advertising interval when device is discoverable (units of 625us, 160=100ms)
    #define DEFAULT_ADVERTISING_INTERVAL          160
    
    // Limited discoverable mode advertises for 30.72s, and then stops
    // General discoverable mode advertises indefinitely
    #define DEFAULT_DISCOVERABLE_MODE             GAP_ADTYPE_FLAGS_GENERAL
    
    #ifndef FEATURE_OAD
    // Minimum connection interval (units of 1.25ms, 80=100ms) if automatic
    // parameter update request is enabled
    #define DEFAULT_DESIRED_MIN_CONN_INTERVAL     80
    
    // Maximum connection interval (units of 1.25ms, 800=1000ms) if automatic
    // parameter update request is enabled
    #define DEFAULT_DESIRED_MAX_CONN_INTERVAL     800
    #else
    // Minimum connection interval (units of 1.25ms, 8=10ms) if automatic
    // parameter update request is enabled
    #define DEFAULT_DESIRED_MIN_CONN_INTERVAL     8
    
    // Maximum connection interval (units of 1.25ms, 8=10ms) if automatic
    // parameter update request is enabled
    #define DEFAULT_DESIRED_MAX_CONN_INTERVAL     8
    #endif // FEATURE_OAD
    
    // Slave latency to use if automatic parameter update request is enabled
    #define DEFAULT_DESIRED_SLAVE_LATENCY         0
    
    // Supervision timeout value (units of 10ms, 1000=10s) if automatic parameter
    // update request is enabled
    #define DEFAULT_DESIRED_CONN_TIMEOUT          1000
    
    // Whether to enable automatic parameter update request when a connection is
    // formed
    #define DEFAULT_ENABLE_UPDATE_REQUEST         TRUE
    
    // Connection Pause Peripheral time value (in seconds)
    #define DEFAULT_CONN_PAUSE_PERIPHERAL         6
    
    // How often to perform periodic event (in msec)
    #define SBP_PERIODIC_EVT_PERIOD               5000
    
    #ifdef FEATURE_OAD
    // The size of an OAD packet.
    #define OAD_PACKET_SIZE                       ((OAD_BLOCK_SIZE) + 2)
    #endif // FEATURE_OAD
    
    // Task configuration
    #define SBP_TASK_PRIORITY                     1
    
    #ifndef SBP_TASK_STACK_SIZE
    #define SBP_TASK_STACK_SIZE                   644
    #endif
    
    // Internal Events for RTOS application
    #define SBP_STATE_CHANGE_EVT                  0x0001
    #define SBP_CHAR_CHANGE_EVT                   0x0002
    #define SBP_PERIODIC_EVT                      0x0004
    #define SBP_CONN_EVT_END_EVT                  0x0008
    #define UART_EVT 							  0x0010
    
    /*********************************************************************
     * TYPEDEFS
     */
    
    // App event passed from profiles.
    typedef struct
    {
      appEvtHdr_t hdr;  // event header.
    } sbpEvt_t;
    
    typedef struct
    {
    	uint8_t  event;  // Sensor Controller events
    	void *data;   // UART data
    	UART_Handle uart;
    } uartEvt_t;
    
    /*********************************************************************
     * LOCAL VARIABLES
     */
    
    // Entity ID globally used to check for source and/or destination of messages
    static ICall_EntityID selfEntity;
    
    // Semaphore globally used to post events to the application thread
    static ICall_Semaphore sem;
    
    // Clock instances for internal periodic events.
    static Clock_Struct periodicClock;
    
    // Queue object used for app messages
    static Queue_Struct appMsg;
    static Queue_Handle appMsgQueue;
    
    static uint8_t rxBytes;
    static uint8_t rx_buf;
    static uint8_t tx_buf;
    
    
    #if defined(FEATURE_OAD)
    // Event data from OAD profile.
    static Queue_Struct oadQ;
    static Queue_Handle hOadQ;
    #endif //FEATURE_OAD
    
    // events flag for internal application events.
    static uint16_t events;
    
    // Task configuration
    Task_Struct sbpTask;
    Char sbpTaskStack[SBP_TASK_STACK_SIZE];
    
    // Profile state and parameters
    //static gaprole_States_t gapProfileState = GAPROLE_INIT;
    
    // GAP - SCAN RSP data (max size = 31 bytes)
    static uint8_t scanRspData[] =
    {
      // complete name
      0x14,   // length of this data
      GAP_ADTYPE_LOCAL_NAME_COMPLETE,
      0x53,   // 'S'
      0x69,   // 'i'
      0x6d,   // 'm'
      0x70,   // 'p'
      0x6c,   // 'l'
      0x65,   // 'e'
      0x42,   // 'B'
      0x4c,   // 'L'
      0x45,   // 'E'
      0x50,   // 'P'
      0x65,   // 'e'
      0x72,   // 'r'
      0x69,   // 'i'
      0x70,   // 'p'
      0x68,   // 'h'
      0x65,   // 'e'
      0x72,   // 'r'
      0x61,   // 'a'
      0x6c,   // 'l'
    
      // connection interval range
      0x05,   // length of this data
      GAP_ADTYPE_SLAVE_CONN_INTERVAL_RANGE,
      LO_UINT16(DEFAULT_DESIRED_MIN_CONN_INTERVAL),   // 100ms
      HI_UINT16(DEFAULT_DESIRED_MIN_CONN_INTERVAL),
      LO_UINT16(DEFAULT_DESIRED_MAX_CONN_INTERVAL),   // 1s
      HI_UINT16(DEFAULT_DESIRED_MAX_CONN_INTERVAL),
    
      // Tx power level
      0x02,   // length of this data
      GAP_ADTYPE_POWER_LEVEL,
      0       // 0dBm
    };
    
    // GAP - Advertisement data (max size = 31 bytes, though this is
    // best kept short to conserve power while advertisting)
    static uint8_t advertData[] =
    {
      // Flags; this sets the device to use limited discoverable
      // mode (advertises for 30 seconds at a time) instead of general
      // discoverable mode (advertises indefinitely)
      0x02,   // length of this data
      GAP_ADTYPE_FLAGS,
      DEFAULT_DISCOVERABLE_MODE | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,
    
      // service UUID, to notify central devices what services are included
      // in this peripheral
      0x03,   // length of this data
      GAP_ADTYPE_16BIT_MORE,      // some of the UUID's, but not all
    #ifdef FEATURE_OAD
      LO_UINT16(OAD_SERVICE_UUID),
      HI_UINT16(OAD_SERVICE_UUID)
    #else
      LO_UINT16(SIMPLEPROFILE_SERV_UUID),
      HI_UINT16(SIMPLEPROFILE_SERV_UUID),
    #endif //!FEATURE_OAD
    };
    
    // GAP GATT Attributes
    static uint8_t attDeviceName[GAP_DEVICE_NAME_LEN] = "Simple BLE Peripheral";
    
    // Globals used for ATT Response retransmission
    static gattMsgEvent_t *pAttRsp = NULL;
    static uint8_t rspTxRetry = 0;
    
    /*********************************************************************
     * LOCAL FUNCTIONS
     */
    
    static void SimpleBLEPeripheral_init( void );
    static void SimpleBLEPeripheral_taskFxn(UArg a0, UArg a1);
    
    static uint8_t SimpleBLEPeripheral_processStackMsg(ICall_Hdr *pMsg);
    static uint8_t SimpleBLEPeripheral_processGATTMsg(gattMsgEvent_t *pMsg);
    static void SimpleBLEPeripheral_processAppMsg(sbpEvt_t *pMsg);
    static void SimpleBLEPeripheral_processStateChangeEvt(
                                                         gaprole_States_t newState);
    static void SimpleBLEPeripheral_processCharValueChangeEvt(uint8_t paramID);
    static void SimpleBLEPeripheral_performPeriodicTask(void);
    
    static void SimpleBLEPeripheral_sendAttRsp(void);
    static void SimpleBLEPeripheral_freeAttRsp(uint8_t status);
    
    static void SimpleBLEPeripheral_stateChangeCB(gaprole_States_t newState);
    #ifndef FEATURE_OAD
    static void SimpleBLEPeripheral_charValueChangeCB(uint8_t paramID);
    #endif //!FEATURE_OAD
    static void SimpleBLEPeripheral_enqueueMsg(uint8_t event, uint8_t state);
    
    static void UART_enqueueMsg(void *data, UART_Handle uart);
    static void readCallback (UART_Handle handle, void *rx_buf, size_t size);
    static void UART_initialize(void);
    static void SimpleBLEPeripheral_processUART(uartEvt_t *pMsg);
    
    #ifdef FEATURE_OAD
    void SimpleBLEPeripheral_processOadWriteCB(uint8_t event, uint16_t connHandle,
                                               uint8_t *pData);
    #endif //FEATURE_OAD
    
    static void SimpleBLEPeripheral_clockHandler(UArg arg);
    
    
    static void UART_enqueueMsg(void *data, UART_Handle uart)
    {
      uartEvt_t *pMsg;
    
      // Create dynamic pointer to message.
    
      if (pMsg = ICall_malloc(sizeof(uartEvt_t)))
      {
        pMsg->event = UART_EVT;
        pMsg->data = data;
        pMsg->uart = uart;
    
    
        // Enqueue the message.
        Util_enqueueMsg(appMsgQueue, sem, (uint8*)pMsg);
      }
    }
    
    static void readCallback(UART_Handle uart, void *rx_buf, size_t size)
    {
    	uint8_t byte = 0x23;
    
        tx_buf = *((uint8_t*) rx_buf);
    
        UART_write(uart, &tx_buf, size);
        UART_write(uart, &byte, 1);
        UART_read(uart, &rx_buf, size);
        UART_enqueueMsg(&rxBytes, uart);
    }
    
    static void UART_initialize(void)
    {
    	UART_init();
    	UART_Params uartParams;
    
        UART_Handle uart;
    
    	/* Create a UART with data processing off. */
    	UART_Params_init(&uartParams);
    	uartParams.writeDataMode = UART_DATA_BINARY;
    	uartParams.readDataMode = UART_DATA_BINARY;
    	uartParams.readReturnMode = UART_RETURN_FULL;
    	uartParams.readMode = UART_MODE_CALLBACK;
    	uartParams.baudRate = 9600;
    	uartParams.readCallback = readCallback;
    
    	uart = UART_open(Board_UART, &uartParams);
    
    		if (uart == NULL) {
    			System_abort("Error opening the UART");
    		}
    
        rxBytes = UART_read(uart, &rx_buf, sizeof (rx_buf));
    
        while(true);
    
    }
    
    static void SimpleBLEPeripheral_processUART(uartEvt_t *pMsg)
    {
    uint8_t byte1 = 0x92;
    uint8_t byte2 = 0x48;
    
        UART_write(pMsg->uart, &byte1, 1);
    	UART_write(pMsg->uart, &byte2, 1);
    	UART_write(pMsg->uart, &pMsg->data, 1);
    
    }
    /*********************************************************************
     * PROFILE CALLBACKS
     */
    
    // GAP Role Callbacks
    static gapRolesCBs_t SimpleBLEPeripheral_gapRoleCBs =
    {
      SimpleBLEPeripheral_stateChangeCB     // Profile State Change Callbacks
    };
    
    // GAP Bond Manager Callbacks
    static gapBondCBs_t simpleBLEPeripheral_BondMgrCBs =
    {
      NULL, // Passcode callback (not used by application)
      NULL  // Pairing / Bonding state Callback (not used by application)
    };
    
    // Simple GATT Profile Callbacks
    #ifndef FEATURE_OAD
    static simpleProfileCBs_t SimpleBLEPeripheral_simpleProfileCBs =
    {
      SimpleBLEPeripheral_charValueChangeCB // Characteristic value change callback
    };
    #endif //!FEATURE_OAD
    
    #ifdef FEATURE_OAD
    static oadTargetCBs_t simpleBLEPeripheral_oadCBs =
    {
      SimpleBLEPeripheral_processOadWriteCB // Write Callback.
    };
    #endif //FEATURE_OAD
    
    /*********************************************************************
     * PUBLIC FUNCTIONS
     */
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_createTask
     *
     * @brief   Task creation function for the Simple BLE Peripheral.
     *
     * @param   None.
     *
     * @return  None.
     */
    void SimpleBLEPeripheral_createTask(void)
    {
      Task_Params taskParams;
    
      // Configure task
      Task_Params_init(&taskParams);
      taskParams.stack = sbpTaskStack;
      taskParams.stackSize = SBP_TASK_STACK_SIZE;
      taskParams.priority = SBP_TASK_PRIORITY;
    
      Task_construct(&sbpTask, SimpleBLEPeripheral_taskFxn, &taskParams, NULL);
    }
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_init
     *
     * @brief   Called during initialization and contains application
     *          specific initialization (ie. hardware initialization/setup,
     *          table initialization, power up notification, etc), and
     *          profile initialization/setup.
     *
     * @param   None.
     *
     * @return  None.
     */
    static void SimpleBLEPeripheral_init(void)
    {
      // ******************************************************************
      // N0 STACK API CALLS CAN OCCUR BEFORE THIS CALL TO ICall_registerApp
      // ******************************************************************
      // Register the current thread as an ICall dispatcher application
      // so that the application can send and receive messages.
      ICall_registerApp(&selfEntity, &sem);
    
    
      UART_initialize();
    
    //  UART_init();
    
      // Hard code the BD Address till CC2650 board gets its own IEEE address
      //uint8 bdAddress[B_ADDR_LEN] = { 0xAD, 0xD0, 0x0A, 0xAD, 0xD0, 0x0A };
      //HCI_EXT_SetBDADDRCmd(bdAddress);
    
      // Set device's Sleep Clock Accuracy
      //HCI_EXT_SetSCACmd(500);
      
      // Create an RTOS queue for message from profile to be sent to app.
      appMsgQueue = Util_constructQueue(&appMsg);
    
      // Create one-shot clocks for internal periodic events.
      Util_constructClock(&periodicClock, SimpleBLEPeripheral_clockHandler,
                          SBP_PERIODIC_EVT_PERIOD, 0, false, SBP_PERIODIC_EVT);
      
    #ifndef SENSORTAG_HW
      Board_openLCD();
    #endif //SENSORTAG_HW
      
    #if SENSORTAG_HW
      // Setup SPI bus for serial flash and Devpack interface
      bspSpiOpen();
    #endif //SENSORTAG_HW
      
      // Setup the GAP
      GAP_SetParamValue(TGAP_CONN_PAUSE_PERIPHERAL, DEFAULT_CONN_PAUSE_PERIPHERAL);
    
      // Setup the GAP Peripheral Role Profile
      {
        // For all hardware platforms, device starts advertising upon initialization
        uint8_t initialAdvertEnable = TRUE;
    
        // By setting this to zero, the device will go into the waiting state after
        // being discoverable for 30.72 second, and will not being advertising again
        // until the enabler is set back to TRUE
        uint16_t advertOffTime = 0;
    
        uint8_t enableUpdateRequest = DEFAULT_ENABLE_UPDATE_REQUEST;
        uint16_t desiredMinInterval = DEFAULT_DESIRED_MIN_CONN_INTERVAL;
        uint16_t desiredMaxInterval = DEFAULT_DESIRED_MAX_CONN_INTERVAL;
        uint16_t desiredSlaveLatency = DEFAULT_DESIRED_SLAVE_LATENCY;
        uint16_t desiredConnTimeout = DEFAULT_DESIRED_CONN_TIMEOUT;
    
        // Set the GAP Role Parameters
        GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t),
                             &initialAdvertEnable);
        GAPRole_SetParameter(GAPROLE_ADVERT_OFF_TIME, sizeof(uint16_t),
                             &advertOffTime);
    
        GAPRole_SetParameter(GAPROLE_SCAN_RSP_DATA, sizeof(scanRspData),
                             scanRspData);
        GAPRole_SetParameter(GAPROLE_ADVERT_DATA, sizeof(advertData), advertData);
    
        GAPRole_SetParameter(GAPROLE_PARAM_UPDATE_ENABLE, sizeof(uint8_t),
                             &enableUpdateRequest);
        GAPRole_SetParameter(GAPROLE_MIN_CONN_INTERVAL, sizeof(uint16_t),
                             &desiredMinInterval);
        GAPRole_SetParameter(GAPROLE_MAX_CONN_INTERVAL, sizeof(uint16_t),
                             &desiredMaxInterval);
        GAPRole_SetParameter(GAPROLE_SLAVE_LATENCY, sizeof(uint16_t),
                             &desiredSlaveLatency);
        GAPRole_SetParameter(GAPROLE_TIMEOUT_MULTIPLIER, sizeof(uint16_t),
                             &desiredConnTimeout);
      }
    
      // Set the GAP Characteristics
      GGS_SetParameter(GGS_DEVICE_NAME_ATT, GAP_DEVICE_NAME_LEN, attDeviceName);
    
      // Set advertising interval
      {
        uint16_t advInt = DEFAULT_ADVERTISING_INTERVAL;
    
        GAP_SetParamValue(TGAP_LIM_DISC_ADV_INT_MIN, advInt);
        GAP_SetParamValue(TGAP_LIM_DISC_ADV_INT_MAX, advInt);
        GAP_SetParamValue(TGAP_GEN_DISC_ADV_INT_MIN, advInt);
        GAP_SetParamValue(TGAP_GEN_DISC_ADV_INT_MAX, advInt);
      }
    
      // Setup the GAP Bond Manager
      {
        uint32_t passkey = 0; // passkey "000000"
        uint8_t pairMode = GAPBOND_PAIRING_MODE_WAIT_FOR_REQ;
        uint8_t mitm = TRUE;
        uint8_t ioCap = GAPBOND_IO_CAP_DISPLAY_ONLY;
        uint8_t bonding = TRUE;
    
        GAPBondMgr_SetParameter(GAPBOND_DEFAULT_PASSCODE, sizeof(uint32_t),
                                &passkey);
        GAPBondMgr_SetParameter(GAPBOND_PAIRING_MODE, sizeof(uint8_t), &pairMode);
        GAPBondMgr_SetParameter(GAPBOND_MITM_PROTECTION, sizeof(uint8_t), &mitm);
        GAPBondMgr_SetParameter(GAPBOND_IO_CAPABILITIES, sizeof(uint8_t), &ioCap);
        GAPBondMgr_SetParameter(GAPBOND_BONDING_ENABLED, sizeof(uint8_t), &bonding);
      }
    
       // Initialize GATT attributes
      GGS_AddService(GATT_ALL_SERVICES);           // GAP
      GATTServApp_AddService(GATT_ALL_SERVICES);   // GATT attributes
      DevInfo_AddService();                        // Device Information Service
    
    #ifndef FEATURE_OAD
      SimpleProfile_AddService(GATT_ALL_SERVICES); // Simple GATT Profile
    #endif //!FEATURE_OAD
    
    #ifdef FEATURE_OAD
      VOID OAD_addService();                 // OAD Profile
      OAD_register((oadTargetCBs_t *)&simpleBLEPeripheral_oadCBs);
      hOadQ = Util_constructQueue(&oadQ);
    #endif
    
    #ifdef IMAGE_INVALIDATE
      Reset_addService();
    #endif //IMAGE_INVALIDATE
      
      
    #ifndef FEATURE_OAD
      // Setup the SimpleProfile Characteristic Values
      {
        uint8_t charValue1 = 1;
        uint8_t charValue2 = 2;
        uint8_t charValue3 = 3;
        uint8_t charValue4 = 4;
        uint8_t charValue5[SIMPLEPROFILE_CHAR5_LEN] = { 1, 2, 3, 4, 5 };
    
        SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR1, sizeof(uint8_t),
                                   &charValue1);
        SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR2, sizeof(uint8_t),
                                   &charValue2);
        SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR3, sizeof(uint8_t),
                                   &charValue3);
        SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR4, sizeof(uint8_t),
                                   &charValue4);
        SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR5, SIMPLEPROFILE_CHAR5_LEN,
                                   charValue5);
      }
    
      // Register callback with SimpleGATTprofile
      SimpleProfile_RegisterAppCBs(&SimpleBLEPeripheral_simpleProfileCBs);
    #endif //!FEATURE_OAD
      
      // Start the Device
      VOID GAPRole_StartDevice(&SimpleBLEPeripheral_gapRoleCBs);
      
      // Start Bond Manager
      VOID GAPBondMgr_Register(&simpleBLEPeripheral_BondMgrCBs);
    
      // Register with GAP for HCI/Host messages
      GAP_RegisterForMsgs(selfEntity);
      
      // Register for GATT local events and ATT Responses pending for transmission
      GATT_RegisterForMsgs(selfEntity);
      
    #if defined FEATURE_OAD
    #if defined (HAL_IMAGE_A)
      LCD_WRITE_STRING("BLE Peripheral A", LCD_PAGE0);
    #else
      LCD_WRITE_STRING("BLE Peripheral B", LCD_PAGE0);
    #endif // HAL_IMAGE_A
    #else
      LCD_WRITE_STRING("BLE Peripheral", LCD_PAGE0);
    #endif // FEATURE_OAD
    }       
    
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_taskFxn
     *
     * @brief   Application task entry point for the Simple BLE Peripheral.
     *
     * @param   a0, a1 - not used.
     *
     * @return  None.
     */
    static void SimpleBLEPeripheral_taskFxn(UArg a0, UArg a1)
    {
      // Initialize application
      SimpleBLEPeripheral_init();
    /*
            UART_Params uartParams;
            UART_Handle uart;
    
          	uint8_t rx_buf;
    */
      	    /* Create a UART with data processing off. */
    
    /*
      	        UART_Params_init(&uartParams);
        	    uartParams.writeDataMode = UART_DATA_BINARY;
        	    uartParams.readDataMode = UART_DATA_BINARY;
        	    uartParams.readReturnMode = UART_RETURN_FULL;
        	    uartParams.readMode = UART_MODE_CALLBACK;
    
    
        	    uartParams.baudRate = 9600;
    
        	    uart = UART_open(Board_UART, &uartParams);
    
        	    if (uart == NULL) {
        	         System_abort("Error opening the UART");
        	    }
    
    */
    
      // Application main loop
      for (;;)
      {
        // Waits for a signal to the semaphore associated with the calling thread.
        // Note that the semaphore associated with a thread is signaled when a
        // message is queued to the message receive queue of the thread or when
        // ICall_signal() function is called onto the semaphore.
        ICall_Errno errno = ICall_wait(ICALL_TIMEOUT_FOREVER);
    
        if (errno == ICALL_ERRNO_SUCCESS)
        {
    
          ICall_EntityID dest;
          ICall_ServiceEnum src;
          ICall_HciExtEvt *pMsg = NULL;
    
     //      uartParams.readCallback = readCallback;
    //      UART_read(uart, &rx_buf, 1);
    //      UART_write(uart, &tx_buf, sizeof(tx_buf));
     //      UART_write(uart, &rx_buf, 1);
    
    
          if (ICall_fetchServiceMsg(&src, &dest,
                                    (void **)&pMsg) == ICALL_ERRNO_SUCCESS)
          {
            uint8 safeToDealloc = TRUE;
            
            if ((src == ICALL_SERVICE_CLASS_BLE) && (dest == selfEntity))
            {
              ICall_Event *pEvt = (ICall_Event *)pMsg;
              
              // Check for BLE stack events first
              if (pEvt->signature == 0xffff)
              {
                if (pEvt->event_flag & SBP_CONN_EVT_END_EVT)
                {
                  // Try to retransmit pending ATT Response (if any)
                  SimpleBLEPeripheral_sendAttRsp();
                }
              }
              else
              {
                // Process inter-task message
                safeToDealloc = SimpleBLEPeripheral_processStackMsg(
                                                                 (ICall_Hdr *)pMsg);
              }
            }
    
            if (pMsg && safeToDealloc)
            {
              ICall_freeMsg(pMsg);
            }
          }
    
          // If RTOS queue is not empty, process app message.
          while (!Queue_empty(appMsgQueue))
          {
    
        	 uartEvt_t *uMsg = (uartEvt_t *)Util_dequeueMsg(appMsgQueue);
    
             if (uMsg->event)
             {
        	    SimpleBLEPeripheral_processUART( ((uartEvt_t*)pMsg)->data);
        	    ICall_free(uMsg);
             }
    
        	sbpEvt_t *pMsg = (sbpEvt_t *)Util_dequeueMsg(appMsgQueue);
    
            if (pMsg)
            {
              // Process message.
              SimpleBLEPeripheral_processAppMsg(pMsg);
              // Free the space from the message.
              ICall_free(pMsg);
    
            }
          }
        }
    
        if (events & SBP_PERIODIC_EVT)
        {
          events &= ~SBP_PERIODIC_EVT;
    
          Util_startClock(&periodicClock);
    
          // Perform periodic application task
          SimpleBLEPeripheral_performPeriodicTask();
        }
        
    #ifdef FEATURE_OAD
        while (!Queue_empty(hOadQ))
        {
          oadTargetWrite_t *oadWriteEvt = Queue_dequeue(hOadQ);
    
          // Identify new image.
          if (oadWriteEvt->event == OAD_WRITE_IDENTIFY_REQ)
          {
            OAD_imgIdentifyWrite(oadWriteEvt->connHandle, oadWriteEvt->pData);
          }
          // Write a next block request.
          else if (oadWriteEvt->event == OAD_WRITE_BLOCK_REQ)
          {
            OAD_imgBlockWrite(oadWriteEvt->connHandle, oadWriteEvt->pData);
          }
    
          // Free buffer.
          ICall_free(oadWriteEvt);
        }
    #endif //FEATURE_OAD
      }
    }
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_processStackMsg
     *
     * @brief   Process an incoming stack message.
     *
     * @param   pMsg - message to process
     *
     * @return  TRUE if safe to deallocate incoming message, FALSE otherwise.
     */
    static uint8_t SimpleBLEPeripheral_processStackMsg(ICall_Hdr *pMsg)
    {
      uint8_t safeToDealloc = TRUE;
        
      switch (pMsg->event)
      {
        case GATT_MSG_EVENT:
          // Process GATT message
          safeToDealloc = SimpleBLEPeripheral_processGATTMsg(
                                                            (gattMsgEvent_t *)pMsg);
          break;
    
        case HCI_GAP_EVENT_EVENT:
          {
            // Process HCI message
            switch(pMsg->status)
            {
              case HCI_COMMAND_COMPLETE_EVENT_CODE:
                // Process HCI Command Complete Event
                break;
                
              default:
                break;
            }
          }
          break;
          
        default:
          // do nothing
          break;
      }
      
      return (safeToDealloc);
    }
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_processGATTMsg
     *
     * @brief   Process GATT messages and events.
     *
     * @return  TRUE if safe to deallocate incoming message, FALSE otherwise.
     */
    static uint8_t SimpleBLEPeripheral_processGATTMsg(gattMsgEvent_t *pMsg)
    {
      // See if GATT server was unable to transmit an ATT response
      if (pMsg->hdr.status == blePending)
      {
        // No HCI buffer was available. Let's try to retransmit the response
        // on the next connection event.
        if (HCI_EXT_ConnEventNoticeCmd(pMsg->connHandle, selfEntity,
                                       SBP_CONN_EVT_END_EVT) == SUCCESS)
        {
          // First free any pending response
          SimpleBLEPeripheral_freeAttRsp(FAILURE);
          
          // Hold on to the response message for retransmission
          pAttRsp = pMsg;
          
          // Don't free the response message yet
          return (FALSE);
        }
      }
      else if (pMsg->method == ATT_FLOW_CTRL_VIOLATED_EVENT)
      {
        // ATT request-response or indication-confirmation flow control is
        // violated. All subsequent ATT requests or indications will be dropped.
        // The app is informed in case it wants to drop the connection.
        
        // Display the opcode of the message that caused the violation.
        LCD_WRITE_STRING_VALUE("FC Violated:", pMsg->msg.flowCtrlEvt.opcode,
                               10, LCD_PAGE5);
      }    
      else if (pMsg->method == ATT_MTU_UPDATED_EVENT)
      {
        // MTU size updated
        LCD_WRITE_STRING_VALUE("MTU Size:", pMsg->msg.mtuEvt.MTU, 10, LCD_PAGE5);
      }
      
      // Free message payload. Needed only for ATT Protocol messages
      GATT_bm_free(&pMsg->msg, pMsg->method);
      
      // It's safe to free the incoming message
      return (TRUE);
    }
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_sendAttRsp
     *
     * @brief   Send a pending ATT response message.
     *
     * @param   none
     *
     * @return  none
     */
    static void SimpleBLEPeripheral_sendAttRsp(void)
    {
      // See if there's a pending ATT Response to be transmitted
      if (pAttRsp != NULL)
      {
        uint8_t status;
        
        // Increment retransmission count
        rspTxRetry++;
        
        // Try to retransmit ATT response till either we're successful or
        // the ATT Client times out (after 30s) and drops the connection.
        status = GATT_SendRsp(pAttRsp->connHandle, pAttRsp->method, 
                              &(pAttRsp->msg));
        if ((status != blePending) && (status != MSG_BUFFER_NOT_AVAIL))
        {
          // Disable connection event end notice
          HCI_EXT_ConnEventNoticeCmd(pAttRsp->connHandle, selfEntity, 0);
          
          // We're done with the response message
          SimpleBLEPeripheral_freeAttRsp(status);
        }
        else
        {
          // Continue retrying
          LCD_WRITE_STRING_VALUE("Rsp send retry:", rspTxRetry, 10, LCD_PAGE5);
        }
      }
    }
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_freeAttRsp
     *
     * @brief   Free ATT response message.
     *
     * @param   status - response transmit status
     *
     * @return  none
     */
    static void SimpleBLEPeripheral_freeAttRsp(uint8_t status)
    {
      // See if there's a pending ATT response message
      if (pAttRsp != NULL)
      {
        // See if the response was sent out successfully
        if (status == SUCCESS)
        {
          LCD_WRITE_STRING_VALUE("Rsp sent, retry:", rspTxRetry, 10, LCD_PAGE5);
        }
        else
        {
          // Free response payload
          GATT_bm_free(&pAttRsp->msg, pAttRsp->method);
          
          LCD_WRITE_STRING_VALUE("Rsp retry failed:", rspTxRetry, 10, LCD_PAGE5);
        }
        
        // Free response message
        ICall_freeMsg(pAttRsp);
        
        // Reset our globals
        pAttRsp = NULL;
        rspTxRetry = 0;
      }
    }
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_processAppMsg
     *
     * @brief   Process an incoming callback from a profile.
     *
     * @param   pMsg - message to process
     *
     * @return  None.
     */
    static void SimpleBLEPeripheral_processAppMsg(sbpEvt_t *pMsg)
    {
      switch (pMsg->hdr.event)
      {
        case SBP_STATE_CHANGE_EVT:
          SimpleBLEPeripheral_processStateChangeEvt((gaprole_States_t)pMsg->
                                                    hdr.state);
          break;
    
        case SBP_CHAR_CHANGE_EVT:
          SimpleBLEPeripheral_processCharValueChangeEvt(pMsg->hdr.state);
          break;
    
    
        default:
          // Do nothing.
          break;
      }
    }
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_stateChangeCB
     *
     * @brief   Callback from GAP Role indicating a role state change.
     *
     * @param   newState - new state
     *
     * @return  None.
     */
    static void SimpleBLEPeripheral_stateChangeCB(gaprole_States_t newState)
    {
      SimpleBLEPeripheral_enqueueMsg(SBP_STATE_CHANGE_EVT, newState);
    }
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_processStateChangeEvt
     *
     * @brief   Process a pending GAP Role state change event.
     *
     * @param   newState - new state
     *
     * @return  None.
     */
    static void SimpleBLEPeripheral_processStateChangeEvt(gaprole_States_t newState)
    {
    #ifdef PLUS_BROADCASTER
      static bool firstConnFlag = false;
    #endif // PLUS_BROADCASTER
    
      switch ( newState )
      {
        case GAPROLE_STARTED:
          {
            uint8_t ownAddress[B_ADDR_LEN];
            uint8_t systemId[DEVINFO_SYSTEM_ID_LEN];
    
            GAPRole_GetParameter(GAPROLE_BD_ADDR, ownAddress);
    
            // use 6 bytes of device address for 8 bytes of system ID value
            systemId[0] = ownAddress[0];
            systemId[1] = ownAddress[1];
            systemId[2] = ownAddress[2];
    
            // set middle bytes to zero
            systemId[4] = 0x00;
            systemId[3] = 0x00;
    
            // shift three bytes up
            systemId[7] = ownAddress[5];
            systemId[6] = ownAddress[4];
            systemId[5] = ownAddress[3];
    
            DevInfo_SetParameter(DEVINFO_SYSTEM_ID, DEVINFO_SYSTEM_ID_LEN, 
                                 systemId);
    
            // Display device address
            LCD_WRITE_STRING(Util_convertBdAddr2Str(ownAddress), LCD_PAGE1);
            LCD_WRITE_STRING("Initialized", LCD_PAGE2);
          }
          break;
    
        case GAPROLE_ADVERTISING:
          LCD_WRITE_STRING("Advertising", LCD_PAGE2);
          break;
    
    #ifdef PLUS_BROADCASTER   
        /* After a connection is dropped a device in PLUS_BROADCASTER will continue
         * sending non-connectable advertisements and shall sending this change of 
         * state to the application.  These are then disabled here so that sending 
         * connectable advertisements can resume.
         */
        case GAPROLE_ADVERTISING_NONCONN:
          {
            uint8_t advertEnabled = FALSE;
          
            // Disable non-connectable advertising.
            GAPRole_SetParameter(GAPROLE_ADV_NONCONN_ENABLED, sizeof(uint8_t),
                               &advertEnabled);
          
            advertEnabled = TRUE;
          
            // Enabled connectable advertising.
            GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t),
                                 &advertEnabled);
            
            // Reset flag for next connection.
            firstConnFlag = false;
            
            SimpleBLEPeripheral_freeAttRsp(bleNotConnected);
          }
          break;
    #endif //PLUS_BROADCASTER   
    
        case GAPROLE_CONNECTED:
          {
            uint8_t peerAddress[B_ADDR_LEN];
    
            GAPRole_GetParameter(GAPROLE_CONN_BD_ADDR, peerAddress);
    
            Util_startClock(&periodicClock);
            
            LCD_WRITE_STRING("Connected", LCD_PAGE2);
            LCD_WRITE_STRING(Util_convertBdAddr2Str(peerAddress), LCD_PAGE3);
    
            #ifdef PLUS_BROADCASTER
              // Only turn advertising on for this state when we first connect
              // otherwise, when we go from connected_advertising back to this state
              // we will be turning advertising back on.
              if (firstConnFlag == false)
              {
                uint8_t advertEnabled = FALSE; // Turn on Advertising
    
                // Disable connectable advertising.
                GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t),
                                     &advertEnabled);
                
                // Set to true for non-connectabel advertising.
                advertEnabled = TRUE;
    
                // Enable non-connectable advertising.
                GAPRole_SetParameter(GAPROLE_ADV_NONCONN_ENABLED, sizeof(uint8_t),
                                     &advertEnabled);
                firstConnFlag = true;
              }
            #endif // PLUS_BROADCASTER
          }
          break;
    
        case GAPROLE_CONNECTED_ADV:
          LCD_WRITE_STRING("Connected Advertising", LCD_PAGE2);
          break;
    
        case GAPROLE_WAITING:
          Util_stopClock(&periodicClock);
          
          SimpleBLEPeripheral_freeAttRsp(bleNotConnected);
    
          LCD_WRITE_STRING("Disconnected", LCD_PAGE2);
    
          // Clear remaining lines
          LCD_WRITE_STRING("", LCD_PAGE3);
          LCD_WRITE_STRING("", LCD_PAGE4);
          LCD_WRITE_STRING("", LCD_PAGE5);
          break;
    
        case GAPROLE_WAITING_AFTER_TIMEOUT:
          SimpleBLEPeripheral_freeAttRsp(bleNotConnected);
          
          LCD_WRITE_STRING("Timed Out", LCD_PAGE2);
          
          // Clear remaining lines
          LCD_WRITE_STRING("", LCD_PAGE3);
          LCD_WRITE_STRING("", LCD_PAGE4);
          LCD_WRITE_STRING("", LCD_PAGE5);
    
          #ifdef PLUS_BROADCASTER
            // Reset flag for next connection.
            firstConnFlag = false;
          #endif //#ifdef (PLUS_BROADCASTER)
          break;
    
        case GAPROLE_ERROR:
          LCD_WRITE_STRING("Error", LCD_PAGE2);
          break;
    
        default:
          LCD_WRITE_STRING("", LCD_PAGE2);
          break;
      }
    
      // Update the state
      //gapProfileState = newState;
    }
    
    #ifndef FEATURE_OAD
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_charValueChangeCB
     *
     * @brief   Callback from Simple Profile indicating a characteristic
     *          value change.
     *
     * @param   paramID - parameter ID of the value that was changed.
     *
     * @return  None.
     */
    static void SimpleBLEPeripheral_charValueChangeCB(uint8_t paramID)
    {
      SimpleBLEPeripheral_enqueueMsg(SBP_CHAR_CHANGE_EVT, paramID);
    }
    #endif //!FEATURE_OAD
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_processCharValueChangeEvt
     *
     * @brief   Process a pending Simple Profile characteristic value change
     *          event.
     *
     * @param   paramID - parameter ID of the value that was changed.
     *
     * @return  None.
     */
    static void SimpleBLEPeripheral_processCharValueChangeEvt(uint8_t paramID)
    {
    #ifndef FEATURE_OAD
      uint8_t newValue;
    
      switch(paramID)
      {
        case SIMPLEPROFILE_CHAR1:
          SimpleProfile_GetParameter(SIMPLEPROFILE_CHAR1, &newValue);
    
          LCD_WRITE_STRING_VALUE("Char 1:", (uint16_t)newValue, 10, LCD_PAGE4);
          break;
    
        case SIMPLEPROFILE_CHAR3:
          SimpleProfile_GetParameter(SIMPLEPROFILE_CHAR3, &newValue);
    
          LCD_WRITE_STRING_VALUE("Char 3:", (uint16_t)newValue, 10, LCD_PAGE4);
          break;
    
        default:
          // should not reach here!
          break;
      }
    #endif //!FEATURE_OAD
    }
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_performPeriodicTask
     *
     * @brief   Perform a periodic application task. This function gets called
     *          every five seconds (SBP_PERIODIC_EVT_PERIOD). In this example,
     *          the value of the third characteristic in the SimpleGATTProfile
     *          service is retrieved from the profile, and then copied into the
     *          value of the the fourth characteristic.
     *
     * @param   None.
     *
     * @return  None.
     */
    static void SimpleBLEPeripheral_performPeriodicTask(void)
    {
    #ifndef FEATURE_OAD
      uint8_t valueToCopy;
    
      // Call to retrieve the value of the third characteristic in the profile
      if (SimpleProfile_GetParameter(SIMPLEPROFILE_CHAR3, &valueToCopy) == SUCCESS)
      {
        // Call to set that value of the fourth characteristic in the profile.
        // Note that if notifications of the fourth characteristic have been
        // enabled by a GATT client device, then a notification will be sent
        // every time this function is called.
        SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR4, sizeof(uint8_t),
                                   &valueToCopy);
      }
    #endif //!FEATURE_OAD
    }
    
    
    #if defined(FEATURE_OAD)
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_processOadWriteCB
     *
     * @brief   Process a write request to the OAD profile.
     *
     * @param   event      - event type:
     *                       OAD_WRITE_IDENTIFY_REQ
     *                       OAD_WRITE_BLOCK_REQ
     * @param   connHandle - the connection Handle this request is from.
     * @param   pData      - pointer to data for processing and/or storing.
     *
     * @return  None.
     */
    void SimpleBLEPeripheral_processOadWriteCB(uint8_t event, uint16_t connHandle,
                                               uint8_t *pData)
    {
      oadTargetWrite_t *oadWriteEvt = ICall_malloc( sizeof(oadTargetWrite_t) + \
                                                 sizeof(uint8_t) * OAD_PACKET_SIZE);
      
      if ( oadWriteEvt != NULL )
      {
        oadWriteEvt->event = event;
        oadWriteEvt->connHandle = connHandle;
        
        oadWriteEvt->pData = (uint8_t *)(&oadWriteEvt->pData + 1);
        memcpy(oadWriteEvt->pData, pData, OAD_PACKET_SIZE);
    
        Queue_enqueue(hOadQ, (Queue_Elem *)oadWriteEvt);
        
        // Post the application's semaphore.
        Semaphore_post(sem);
      }
      else
      {
        // Fail silently.
      }
    }
    #endif //FEATURE_OAD
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_clockHandler
     *
     * @brief   Handler function for clock timeouts.
     *
     * @param   arg - event type
     *
     * @return  None.
     */
    static void SimpleBLEPeripheral_clockHandler(UArg arg)
    {
      // Store the event.
      events |= arg;
    
      // Wake up the application.
      Semaphore_post(sem);
    }
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_enqueueMsg
     *
     * @brief   Creates a message and puts the message in RTOS queue.
     *
     * @param   event - message event.
     * @param   state - message state.
     *
     * @return  None.
     */
    static void SimpleBLEPeripheral_enqueueMsg(uint8_t event, uint8_t state)
    {
      sbpEvt_t *pMsg;
    
      // Create dynamic pointer to message.
      if ((pMsg = ICall_malloc(sizeof(sbpEvt_t))))
      {
        pMsg->hdr.event = event;
        pMsg->hdr.state = state;
    
        // Enqueue the message.
        Util_enqueueMsg(appMsgQueue, sem, (uint8*)pMsg);
      }
    }
    
    
    /*********************************************************************
    *********************************************************************/
    

  • Hi,

    I am trying to use the UART read in read call back mode. I am registering the read Hwi

    with the UART driver and putting the UART read byte in the RTOS task queue in SBP.

    I am finding the read callback is working as seen on the scope, and the debugger is

    putting this message in the RTOS queue in SBP. However the UART event is not

    triggering and the message is never coming out of the RTOS queue. I am setting up the

    read callback modeling from this document:

    file:///C:/ti/tirtos_simplelink_2_13_00_06/docs/doxygen/html/_u_a_r_t_c_c26_x_x_8h.html

    Can you help pinpoint why this Hwi is not triggering?

    UART_initialize is called in SBP_init.

    All the UART functions I added are in one place inside the SBP.c code. The part which

    tries to dequeuer the UART task is inside SimpleBLEPeripheral_taskFxn. I have attached

    my SimpleBLEPeripheral.c file to this message.

    Thanks,

    Priya

    /*******************************************************************************
      Filename:       simpleBLEPeripheral.c
      Revised:        $Date: 2016-01-07 16:59:59 -0800 (Thu, 07 Jan 2016) $
      Revision:       $Revision: 44594 $
    
      Description:    This file contains the Simple BLE Peripheral sample 
                      application for use with the CC2650 Bluetooth Low Energy 
                      Protocol Stack.
    
      Copyright 2013 - 2015 Texas Instruments Incorporated. All rights reserved.
    
      IMPORTANT: Your use of this Software is limited to those specific rights
      granted under the terms of a software license agreement between the user
      who downloaded the software, his/her employer (which must be your employer)
      and Texas Instruments Incorporated (the "License").  You may not use this
      Software unless you agree to abide by the terms of the License. The License
      limits your use, and you acknowledge, that the Software may not be modified,
      copied or distributed unless embedded on a Texas Instruments microcontroller
      or used solely and exclusively in conjunction with a Texas Instruments radio
      frequency transceiver, which is integrated into your product.  Other than for
      the foregoing purpose, you may not use, reproduce, copy, prepare derivative
      works of, modify, distribute, perform, display or sell this Software and/or
      its documentation for any purpose.
    
      YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE
      PROVIDED �AS IS� WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,
      INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE,
      NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL
      TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT,
      NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER
      LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES
      INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE
      OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT
      OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
      (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
    
      Should you have any questions regarding your right to use this Software,
      contact Texas Instruments Incorporated at www.TI.com.
    *******************************************************************************/
    
    /*********************************************************************
     * INCLUDES
     */
    #include <string.h>
    
    #include <ti/sysbios/knl/Task.h>
    #include <ti/sysbios/knl/Clock.h>
    #include <ti/sysbios/knl/Semaphore.h>
    #include <ti/sysbios/knl/Queue.h>
    #include <ti/drivers/UART.h>
    
    #include <xdc/std.h>
    #include <xdc/cfg/global.h>
    #include <xdc/runtime/System.h>
    #include <xdc/runtime/Error.h>
    
    #include "hci_tl.h"
    #include "gatt.h"
    #include "gapgattserver.h"
    #include "gattservapp.h"
    #include "devinfoservice.h"
    #include "simpleGATTprofile.h"
    
    #if defined(SENSORTAG_HW)
    #include "bsp_spi.h"
    #endif // SENSORTAG_HW
    
    #if defined(FEATURE_OAD) || defined(IMAGE_INVALIDATE)
    #include "oad_target.h"
    #include "oad.h"
    #endif //FEATURE_OAD || IMAGE_INVALIDATE
    
    #include "peripheral.h"
    #include "gapbondmgr.h"
    
    #include "osal_snv.h"
    #include "ICallBleAPIMSG.h"
    
    #include "util.h"
    #include "board_lcd.h"
    #include "board_key.h"
    #include "Board.h"
    
    #include "simpleBLEPeripheral.h"
    
    #include <ti/drivers/lcd/LCDDogm1286.h>
    
    /*********************************************************************
     * CONSTANTS
     */
    // Advertising interval when device is discoverable (units of 625us, 160=100ms)
    #define DEFAULT_ADVERTISING_INTERVAL          160
    
    // Limited discoverable mode advertises for 30.72s, and then stops
    // General discoverable mode advertises indefinitely
    #define DEFAULT_DISCOVERABLE_MODE             GAP_ADTYPE_FLAGS_GENERAL
    
    #ifndef FEATURE_OAD
    // Minimum connection interval (units of 1.25ms, 80=100ms) if automatic
    // parameter update request is enabled
    #define DEFAULT_DESIRED_MIN_CONN_INTERVAL     80
    
    // Maximum connection interval (units of 1.25ms, 800=1000ms) if automatic
    // parameter update request is enabled
    #define DEFAULT_DESIRED_MAX_CONN_INTERVAL     800
    #else
    // Minimum connection interval (units of 1.25ms, 8=10ms) if automatic
    // parameter update request is enabled
    #define DEFAULT_DESIRED_MIN_CONN_INTERVAL     8
    
    // Maximum connection interval (units of 1.25ms, 8=10ms) if automatic
    // parameter update request is enabled
    #define DEFAULT_DESIRED_MAX_CONN_INTERVAL     8
    #endif // FEATURE_OAD
    
    // Slave latency to use if automatic parameter update request is enabled
    #define DEFAULT_DESIRED_SLAVE_LATENCY         0
    
    // Supervision timeout value (units of 10ms, 1000=10s) if automatic parameter
    // update request is enabled
    #define DEFAULT_DESIRED_CONN_TIMEOUT          1000
    
    // Whether to enable automatic parameter update request when a connection is
    // formed
    #define DEFAULT_ENABLE_UPDATE_REQUEST         TRUE
    
    // Connection Pause Peripheral time value (in seconds)
    #define DEFAULT_CONN_PAUSE_PERIPHERAL         6
    
    // How often to perform periodic event (in msec)
    #define SBP_PERIODIC_EVT_PERIOD               5000
    
    #ifdef FEATURE_OAD
    // The size of an OAD packet.
    #define OAD_PACKET_SIZE                       ((OAD_BLOCK_SIZE) + 2)
    #endif // FEATURE_OAD
    
    // Task configuration
    #define SBP_TASK_PRIORITY                     1
    
    #ifndef SBP_TASK_STACK_SIZE
    #define SBP_TASK_STACK_SIZE                   644
    #endif
    
    // Internal Events for RTOS application
    #define SBP_STATE_CHANGE_EVT                  0x0001
    #define SBP_CHAR_CHANGE_EVT                   0x0002
    #define SBP_PERIODIC_EVT                      0x0004
    #define SBP_CONN_EVT_END_EVT                  0x0008
    #define UART_EVT 							  0x0010
    
    /*********************************************************************
     * TYPEDEFS
     */
    
    // App event passed from profiles.
    typedef struct
    {
      appEvtHdr_t hdr;  // event header.
    } sbpEvt_t;
    
    typedef struct
    {
    	uint8_t  event;  // Sensor Controller events
    	void *data;   // UART data
    	UART_Handle uart;
    } uartEvt_t;
    
    /*********************************************************************
     * LOCAL VARIABLES
     */
    
    // Entity ID globally used to check for source and/or destination of messages
    static ICall_EntityID selfEntity;
    
    // Semaphore globally used to post events to the application thread
    static ICall_Semaphore sem;
    
    // Clock instances for internal periodic events.
    static Clock_Struct periodicClock;
    
    // Queue object used for app messages
    static Queue_Struct appMsg;
    static Queue_Handle appMsgQueue;
    
    static uint8_t rxBytes;
    static uint8_t rx_buf;
    static uint8_t tx_buf;
    
    
    #if defined(FEATURE_OAD)
    // Event data from OAD profile.
    static Queue_Struct oadQ;
    static Queue_Handle hOadQ;
    #endif //FEATURE_OAD
    
    // events flag for internal application events.
    static uint16_t events;
    
    // Task configuration
    Task_Struct sbpTask;
    Char sbpTaskStack[SBP_TASK_STACK_SIZE];
    
    // Profile state and parameters
    //static gaprole_States_t gapProfileState = GAPROLE_INIT;
    
    // GAP - SCAN RSP data (max size = 31 bytes)
    static uint8_t scanRspData[] =
    {
      // complete name
      0x14,   // length of this data
      GAP_ADTYPE_LOCAL_NAME_COMPLETE,
      0x53,   // 'S'
      0x69,   // 'i'
      0x6d,   // 'm'
      0x70,   // 'p'
      0x6c,   // 'l'
      0x65,   // 'e'
      0x42,   // 'B'
      0x4c,   // 'L'
      0x45,   // 'E'
      0x50,   // 'P'
      0x65,   // 'e'
      0x72,   // 'r'
      0x69,   // 'i'
      0x70,   // 'p'
      0x68,   // 'h'
      0x65,   // 'e'
      0x72,   // 'r'
      0x61,   // 'a'
      0x6c,   // 'l'
    
      // connection interval range
      0x05,   // length of this data
      GAP_ADTYPE_SLAVE_CONN_INTERVAL_RANGE,
      LO_UINT16(DEFAULT_DESIRED_MIN_CONN_INTERVAL),   // 100ms
      HI_UINT16(DEFAULT_DESIRED_MIN_CONN_INTERVAL),
      LO_UINT16(DEFAULT_DESIRED_MAX_CONN_INTERVAL),   // 1s
      HI_UINT16(DEFAULT_DESIRED_MAX_CONN_INTERVAL),
    
      // Tx power level
      0x02,   // length of this data
      GAP_ADTYPE_POWER_LEVEL,
      0       // 0dBm
    };
    
    // GAP - Advertisement data (max size = 31 bytes, though this is
    // best kept short to conserve power while advertisting)
    static uint8_t advertData[] =
    {
      // Flags; this sets the device to use limited discoverable
      // mode (advertises for 30 seconds at a time) instead of general
      // discoverable mode (advertises indefinitely)
      0x02,   // length of this data
      GAP_ADTYPE_FLAGS,
      DEFAULT_DISCOVERABLE_MODE | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,
    
      // service UUID, to notify central devices what services are included
      // in this peripheral
      0x03,   // length of this data
      GAP_ADTYPE_16BIT_MORE,      // some of the UUID's, but not all
    #ifdef FEATURE_OAD
      LO_UINT16(OAD_SERVICE_UUID),
      HI_UINT16(OAD_SERVICE_UUID)
    #else
      LO_UINT16(SIMPLEPROFILE_SERV_UUID),
      HI_UINT16(SIMPLEPROFILE_SERV_UUID),
    #endif //!FEATURE_OAD
    };
    
    // GAP GATT Attributes
    static uint8_t attDeviceName[GAP_DEVICE_NAME_LEN] = "Simple BLE Peripheral";
    
    // Globals used for ATT Response retransmission
    static gattMsgEvent_t *pAttRsp = NULL;
    static uint8_t rspTxRetry = 0;
    
    /*********************************************************************
     * LOCAL FUNCTIONS
     */
    
    static void SimpleBLEPeripheral_init( void );
    static void SimpleBLEPeripheral_taskFxn(UArg a0, UArg a1);
    
    static uint8_t SimpleBLEPeripheral_processStackMsg(ICall_Hdr *pMsg);
    static uint8_t SimpleBLEPeripheral_processGATTMsg(gattMsgEvent_t *pMsg);
    static void SimpleBLEPeripheral_processAppMsg(sbpEvt_t *pMsg);
    static void SimpleBLEPeripheral_processStateChangeEvt(
                                                         gaprole_States_t newState);
    static void SimpleBLEPeripheral_processCharValueChangeEvt(uint8_t paramID);
    static void SimpleBLEPeripheral_performPeriodicTask(void);
    
    static void SimpleBLEPeripheral_sendAttRsp(void);
    static void SimpleBLEPeripheral_freeAttRsp(uint8_t status);
    
    static void SimpleBLEPeripheral_stateChangeCB(gaprole_States_t newState);
    #ifndef FEATURE_OAD
    static void SimpleBLEPeripheral_charValueChangeCB(uint8_t paramID);
    #endif //!FEATURE_OAD
    static void SimpleBLEPeripheral_enqueueMsg(uint8_t event, uint8_t state);
    
    static void UART_enqueueMsg(void *data, UART_Handle uart);
    static void readCallback (UART_Handle handle, void *rx_buf, size_t size);
    static void UART_initialize(void);
    static void SimpleBLEPeripheral_processUART(uartEvt_t *pMsg);
    
    #ifdef FEATURE_OAD
    void SimpleBLEPeripheral_processOadWriteCB(uint8_t event, uint16_t connHandle,
                                               uint8_t *pData);
    #endif //FEATURE_OAD
    
    static void SimpleBLEPeripheral_clockHandler(UArg arg);
    
    
    static void UART_enqueueMsg(void *data, UART_Handle uart)
    {
      uartEvt_t *pMsg;
    
      // Create dynamic pointer to message.
    
      if (pMsg = ICall_malloc(sizeof(uartEvt_t)))
      {
        pMsg->event = UART_EVT;
        pMsg->data = data;
        pMsg->uart = uart;
    
    
        // Enqueue the message.
        Util_enqueueMsg(appMsgQueue, sem, (uint8*)pMsg);
      }
    }
    
    static void readCallback(UART_Handle uart, void *rx_buf, size_t size)
    {
    	uint8_t byte = 0x23;
    
        tx_buf = *((uint8_t*) rx_buf);
    
        UART_write(uart, &tx_buf, size);
        UART_write(uart, &byte, 1);
        UART_read(uart, &rx_buf, size);
        UART_enqueueMsg(&rxBytes, uart);
    }
    
    static void UART_initialize(void)
    {
    	UART_init();
    	UART_Params uartParams;
    
        UART_Handle uart;
    
    	/* Create a UART with data processing off. */
    	UART_Params_init(&uartParams);
    	uartParams.writeDataMode = UART_DATA_BINARY;
    	uartParams.readDataMode = UART_DATA_BINARY;
    	uartParams.readReturnMode = UART_RETURN_FULL;
    	uartParams.readMode = UART_MODE_CALLBACK;
    	uartParams.baudRate = 9600;
    	uartParams.readCallback = readCallback;
    
    	uart = UART_open(Board_UART, &uartParams);
    
    		if (uart == NULL) {
    			System_abort("Error opening the UART");
    		}
    
        rxBytes = UART_read(uart, &rx_buf, sizeof (rx_buf));
    
        while(true);
    
    }
    
    static void SimpleBLEPeripheral_processUART(uartEvt_t *pMsg)
    {
    uint8_t byte1 = 0x92;
    uint8_t byte2 = 0x48;
    
        UART_write(pMsg->uart, &byte1, 1);
    	UART_write(pMsg->uart, &byte2, 1);
    	UART_write(pMsg->uart, &pMsg->data, 1);
    
    }
    /*********************************************************************
     * PROFILE CALLBACKS
     */
    
    // GAP Role Callbacks
    static gapRolesCBs_t SimpleBLEPeripheral_gapRoleCBs =
    {
      SimpleBLEPeripheral_stateChangeCB     // Profile State Change Callbacks
    };
    
    // GAP Bond Manager Callbacks
    static gapBondCBs_t simpleBLEPeripheral_BondMgrCBs =
    {
      NULL, // Passcode callback (not used by application)
      NULL  // Pairing / Bonding state Callback (not used by application)
    };
    
    // Simple GATT Profile Callbacks
    #ifndef FEATURE_OAD
    static simpleProfileCBs_t SimpleBLEPeripheral_simpleProfileCBs =
    {
      SimpleBLEPeripheral_charValueChangeCB // Characteristic value change callback
    };
    #endif //!FEATURE_OAD
    
    #ifdef FEATURE_OAD
    static oadTargetCBs_t simpleBLEPeripheral_oadCBs =
    {
      SimpleBLEPeripheral_processOadWriteCB // Write Callback.
    };
    #endif //FEATURE_OAD
    
    /*********************************************************************
     * PUBLIC FUNCTIONS
     */
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_createTask
     *
     * @brief   Task creation function for the Simple BLE Peripheral.
     *
     * @param   None.
     *
     * @return  None.
     */
    void SimpleBLEPeripheral_createTask(void)
    {
      Task_Params taskParams;
    
      // Configure task
      Task_Params_init(&taskParams);
      taskParams.stack = sbpTaskStack;
      taskParams.stackSize = SBP_TASK_STACK_SIZE;
      taskParams.priority = SBP_TASK_PRIORITY;
    
      Task_construct(&sbpTask, SimpleBLEPeripheral_taskFxn, &taskParams, NULL);
    }
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_init
     *
     * @brief   Called during initialization and contains application
     *          specific initialization (ie. hardware initialization/setup,
     *          table initialization, power up notification, etc), and
     *          profile initialization/setup.
     *
     * @param   None.
     *
     * @return  None.
     */
    static void SimpleBLEPeripheral_init(void)
    {
      // ******************************************************************
      // N0 STACK API CALLS CAN OCCUR BEFORE THIS CALL TO ICall_registerApp
      // ******************************************************************
      // Register the current thread as an ICall dispatcher application
      // so that the application can send and receive messages.
      ICall_registerApp(&selfEntity, &sem);
    
    
      UART_initialize();
    
    //  UART_init();
    
      // Hard code the BD Address till CC2650 board gets its own IEEE address
      //uint8 bdAddress[B_ADDR_LEN] = { 0xAD, 0xD0, 0x0A, 0xAD, 0xD0, 0x0A };
      //HCI_EXT_SetBDADDRCmd(bdAddress);
    
      // Set device's Sleep Clock Accuracy
      //HCI_EXT_SetSCACmd(500);
      
      // Create an RTOS queue for message from profile to be sent to app.
      appMsgQueue = Util_constructQueue(&appMsg);
    
      // Create one-shot clocks for internal periodic events.
      Util_constructClock(&periodicClock, SimpleBLEPeripheral_clockHandler,
                          SBP_PERIODIC_EVT_PERIOD, 0, false, SBP_PERIODIC_EVT);
      
    #ifndef SENSORTAG_HW
      Board_openLCD();
    #endif //SENSORTAG_HW
      
    #if SENSORTAG_HW
      // Setup SPI bus for serial flash and Devpack interface
      bspSpiOpen();
    #endif //SENSORTAG_HW
      
      // Setup the GAP
      GAP_SetParamValue(TGAP_CONN_PAUSE_PERIPHERAL, DEFAULT_CONN_PAUSE_PERIPHERAL);
    
      // Setup the GAP Peripheral Role Profile
      {
        // For all hardware platforms, device starts advertising upon initialization
        uint8_t initialAdvertEnable = TRUE;
    
        // By setting this to zero, the device will go into the waiting state after
        // being discoverable for 30.72 second, and will not being advertising again
        // until the enabler is set back to TRUE
        uint16_t advertOffTime = 0;
    
        uint8_t enableUpdateRequest = DEFAULT_ENABLE_UPDATE_REQUEST;
        uint16_t desiredMinInterval = DEFAULT_DESIRED_MIN_CONN_INTERVAL;
        uint16_t desiredMaxInterval = DEFAULT_DESIRED_MAX_CONN_INTERVAL;
        uint16_t desiredSlaveLatency = DEFAULT_DESIRED_SLAVE_LATENCY;
        uint16_t desiredConnTimeout = DEFAULT_DESIRED_CONN_TIMEOUT;
    
        // Set the GAP Role Parameters
        GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t),
                             &initialAdvertEnable);
        GAPRole_SetParameter(GAPROLE_ADVERT_OFF_TIME, sizeof(uint16_t),
                             &advertOffTime);
    
        GAPRole_SetParameter(GAPROLE_SCAN_RSP_DATA, sizeof(scanRspData),
                             scanRspData);
        GAPRole_SetParameter(GAPROLE_ADVERT_DATA, sizeof(advertData), advertData);
    
        GAPRole_SetParameter(GAPROLE_PARAM_UPDATE_ENABLE, sizeof(uint8_t),
                             &enableUpdateRequest);
        GAPRole_SetParameter(GAPROLE_MIN_CONN_INTERVAL, sizeof(uint16_t),
                             &desiredMinInterval);
        GAPRole_SetParameter(GAPROLE_MAX_CONN_INTERVAL, sizeof(uint16_t),
                             &desiredMaxInterval);
        GAPRole_SetParameter(GAPROLE_SLAVE_LATENCY, sizeof(uint16_t),
                             &desiredSlaveLatency);
        GAPRole_SetParameter(GAPROLE_TIMEOUT_MULTIPLIER, sizeof(uint16_t),
                             &desiredConnTimeout);
      }
    
      // Set the GAP Characteristics
      GGS_SetParameter(GGS_DEVICE_NAME_ATT, GAP_DEVICE_NAME_LEN, attDeviceName);
    
      // Set advertising interval
      {
        uint16_t advInt = DEFAULT_ADVERTISING_INTERVAL;
    
        GAP_SetParamValue(TGAP_LIM_DISC_ADV_INT_MIN, advInt);
        GAP_SetParamValue(TGAP_LIM_DISC_ADV_INT_MAX, advInt);
        GAP_SetParamValue(TGAP_GEN_DISC_ADV_INT_MIN, advInt);
        GAP_SetParamValue(TGAP_GEN_DISC_ADV_INT_MAX, advInt);
      }
    
      // Setup the GAP Bond Manager
      {
        uint32_t passkey = 0; // passkey "000000"
        uint8_t pairMode = GAPBOND_PAIRING_MODE_WAIT_FOR_REQ;
        uint8_t mitm = TRUE;
        uint8_t ioCap = GAPBOND_IO_CAP_DISPLAY_ONLY;
        uint8_t bonding = TRUE;
    
        GAPBondMgr_SetParameter(GAPBOND_DEFAULT_PASSCODE, sizeof(uint32_t),
                                &passkey);
        GAPBondMgr_SetParameter(GAPBOND_PAIRING_MODE, sizeof(uint8_t), &pairMode);
        GAPBondMgr_SetParameter(GAPBOND_MITM_PROTECTION, sizeof(uint8_t), &mitm);
        GAPBondMgr_SetParameter(GAPBOND_IO_CAPABILITIES, sizeof(uint8_t), &ioCap);
        GAPBondMgr_SetParameter(GAPBOND_BONDING_ENABLED, sizeof(uint8_t), &bonding);
      }
    
       // Initialize GATT attributes
      GGS_AddService(GATT_ALL_SERVICES);           // GAP
      GATTServApp_AddService(GATT_ALL_SERVICES);   // GATT attributes
      DevInfo_AddService();                        // Device Information Service
    
    #ifndef FEATURE_OAD
      SimpleProfile_AddService(GATT_ALL_SERVICES); // Simple GATT Profile
    #endif //!FEATURE_OAD
    
    #ifdef FEATURE_OAD
      VOID OAD_addService();                 // OAD Profile
      OAD_register((oadTargetCBs_t *)&simpleBLEPeripheral_oadCBs);
      hOadQ = Util_constructQueue(&oadQ);
    #endif
    
    #ifdef IMAGE_INVALIDATE
      Reset_addService();
    #endif //IMAGE_INVALIDATE
      
      
    #ifndef FEATURE_OAD
      // Setup the SimpleProfile Characteristic Values
      {
        uint8_t charValue1 = 1;
        uint8_t charValue2 = 2;
        uint8_t charValue3 = 3;
        uint8_t charValue4 = 4;
        uint8_t charValue5[SIMPLEPROFILE_CHAR5_LEN] = { 1, 2, 3, 4, 5 };
    
        SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR1, sizeof(uint8_t),
                                   &charValue1);
        SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR2, sizeof(uint8_t),
                                   &charValue2);
        SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR3, sizeof(uint8_t),
                                   &charValue3);
        SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR4, sizeof(uint8_t),
                                   &charValue4);
        SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR5, SIMPLEPROFILE_CHAR5_LEN,
                                   charValue5);
      }
    
      // Register callback with SimpleGATTprofile
      SimpleProfile_RegisterAppCBs(&SimpleBLEPeripheral_simpleProfileCBs);
    #endif //!FEATURE_OAD
      
      // Start the Device
      VOID GAPRole_StartDevice(&SimpleBLEPeripheral_gapRoleCBs);
      
      // Start Bond Manager
      VOID GAPBondMgr_Register(&simpleBLEPeripheral_BondMgrCBs);
    
      // Register with GAP for HCI/Host messages
      GAP_RegisterForMsgs(selfEntity);
      
      // Register for GATT local events and ATT Responses pending for transmission
      GATT_RegisterForMsgs(selfEntity);
      
    #if defined FEATURE_OAD
    #if defined (HAL_IMAGE_A)
      LCD_WRITE_STRING("BLE Peripheral A", LCD_PAGE0);
    #else
      LCD_WRITE_STRING("BLE Peripheral B", LCD_PAGE0);
    #endif // HAL_IMAGE_A
    #else
      LCD_WRITE_STRING("BLE Peripheral", LCD_PAGE0);
    #endif // FEATURE_OAD
    }       
    
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_taskFxn
     *
     * @brief   Application task entry point for the Simple BLE Peripheral.
     *
     * @param   a0, a1 - not used.
     *
     * @return  None.
     */
    static void SimpleBLEPeripheral_taskFxn(UArg a0, UArg a1)
    {
      // Initialize application
      SimpleBLEPeripheral_init();
    /*
            UART_Params uartParams;
            UART_Handle uart;
    
          	uint8_t rx_buf;
    */
      	    /* Create a UART with data processing off. */
    
    /*
      	        UART_Params_init(&uartParams);
        	    uartParams.writeDataMode = UART_DATA_BINARY;
        	    uartParams.readDataMode = UART_DATA_BINARY;
        	    uartParams.readReturnMode = UART_RETURN_FULL;
        	    uartParams.readMode = UART_MODE_CALLBACK;
    
    
        	    uartParams.baudRate = 9600;
    
        	    uart = UART_open(Board_UART, &uartParams);
    
        	    if (uart == NULL) {
        	         System_abort("Error opening the UART");
        	    }
    
    */
    
      // Application main loop
      for (;;)
      {
        // Waits for a signal to the semaphore associated with the calling thread.
        // Note that the semaphore associated with a thread is signaled when a
        // message is queued to the message receive queue of the thread or when
        // ICall_signal() function is called onto the semaphore.
        ICall_Errno errno = ICall_wait(ICALL_TIMEOUT_FOREVER);
    
        if (errno == ICALL_ERRNO_SUCCESS)
        {
    
          ICall_EntityID dest;
          ICall_ServiceEnum src;
          ICall_HciExtEvt *pMsg = NULL;
    
    
          if (ICall_fetchServiceMsg(&src, &dest,
                                    (void **)&pMsg) == ICALL_ERRNO_SUCCESS)
          {
            uint8 safeToDealloc = TRUE;
            
            if ((src == ICALL_SERVICE_CLASS_BLE) && (dest == selfEntity))
            {
              ICall_Event *pEvt = (ICall_Event *)pMsg;
              
              // Check for BLE stack events first
              if (pEvt->signature == 0xffff)
              {
                if (pEvt->event_flag & SBP_CONN_EVT_END_EVT)
                {
                  // Try to retransmit pending ATT Response (if any)
                  SimpleBLEPeripheral_sendAttRsp();
                }
              }
              else
              {
                // Process inter-task message
                safeToDealloc = SimpleBLEPeripheral_processStackMsg(
                                                                 (ICall_Hdr *)pMsg);
              }
            }
    
            if (pMsg && safeToDealloc)
            {
              ICall_freeMsg(pMsg);
            }
          }
    
          // If RTOS queue is not empty, process app message.
          while (!Queue_empty(appMsgQueue))
          {
    
        	 uartEvt_t *uMsg = (uartEvt_t *)Util_dequeueMsg(appMsgQueue);
    
             if (uMsg->event)
             {
        	    SimpleBLEPeripheral_processUART( ((uartEvt_t*)pMsg)->data);
        	    ICall_free(uMsg);
             }
    
        	sbpEvt_t *pMsg = (sbpEvt_t *)Util_dequeueMsg(appMsgQueue);
    
            if (pMsg)
            {
              // Process message.
              SimpleBLEPeripheral_processAppMsg(pMsg);
              // Free the space from the message.
              ICall_free(pMsg);
    
            }
          }
        }
    
        if (events & SBP_PERIODIC_EVT)
        {
          events &= ~SBP_PERIODIC_EVT;
    
          Util_startClock(&periodicClock);
    
          // Perform periodic application task
          SimpleBLEPeripheral_performPeriodicTask();
        }
        
    #ifdef FEATURE_OAD
        while (!Queue_empty(hOadQ))
        {
          oadTargetWrite_t *oadWriteEvt = Queue_dequeue(hOadQ);
    
          // Identify new image.
          if (oadWriteEvt->event == OAD_WRITE_IDENTIFY_REQ)
          {
            OAD_imgIdentifyWrite(oadWriteEvt->connHandle, oadWriteEvt->pData);
          }
          // Write a next block request.
          else if (oadWriteEvt->event == OAD_WRITE_BLOCK_REQ)
          {
            OAD_imgBlockWrite(oadWriteEvt->connHandle, oadWriteEvt->pData);
          }
    
          // Free buffer.
          ICall_free(oadWriteEvt);
        }
    #endif //FEATURE_OAD
      }
    }
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_processStackMsg
     *
     * @brief   Process an incoming stack message.
     *
     * @param   pMsg - message to process
     *
     * @return  TRUE if safe to deallocate incoming message, FALSE otherwise.
     */
    static uint8_t SimpleBLEPeripheral_processStackMsg(ICall_Hdr *pMsg)
    {
      uint8_t safeToDealloc = TRUE;
        
      switch (pMsg->event)
      {
        case GATT_MSG_EVENT:
          // Process GATT message
          safeToDealloc = SimpleBLEPeripheral_processGATTMsg(
                                                            (gattMsgEvent_t *)pMsg);
          break;
    
        case HCI_GAP_EVENT_EVENT:
          {
            // Process HCI message
            switch(pMsg->status)
            {
              case HCI_COMMAND_COMPLETE_EVENT_CODE:
                // Process HCI Command Complete Event
                break;
                
              default:
                break;
            }
          }
          break;
          
        default:
          // do nothing
          break;
      }
      
      return (safeToDealloc);
    }
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_processGATTMsg
     *
     * @brief   Process GATT messages and events.
     *
     * @return  TRUE if safe to deallocate incoming message, FALSE otherwise.
     */
    static uint8_t SimpleBLEPeripheral_processGATTMsg(gattMsgEvent_t *pMsg)
    {
      // See if GATT server was unable to transmit an ATT response
      if (pMsg->hdr.status == blePending)
      {
        // No HCI buffer was available. Let's try to retransmit the response
        // on the next connection event.
        if (HCI_EXT_ConnEventNoticeCmd(pMsg->connHandle, selfEntity,
                                       SBP_CONN_EVT_END_EVT) == SUCCESS)
        {
          // First free any pending response
          SimpleBLEPeripheral_freeAttRsp(FAILURE);
          
          // Hold on to the response message for retransmission
          pAttRsp = pMsg;
          
          // Don't free the response message yet
          return (FALSE);
        }
      }
      else if (pMsg->method == ATT_FLOW_CTRL_VIOLATED_EVENT)
      {
        // ATT request-response or indication-confirmation flow control is
        // violated. All subsequent ATT requests or indications will be dropped.
        // The app is informed in case it wants to drop the connection.
        
        // Display the opcode of the message that caused the violation.
        LCD_WRITE_STRING_VALUE("FC Violated:", pMsg->msg.flowCtrlEvt.opcode,
                               10, LCD_PAGE5);
      }    
      else if (pMsg->method == ATT_MTU_UPDATED_EVENT)
      {
        // MTU size updated
        LCD_WRITE_STRING_VALUE("MTU Size:", pMsg->msg.mtuEvt.MTU, 10, LCD_PAGE5);
      }
      
      // Free message payload. Needed only for ATT Protocol messages
      GATT_bm_free(&pMsg->msg, pMsg->method);
      
      // It's safe to free the incoming message
      return (TRUE);
    }
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_sendAttRsp
     *
     * @brief   Send a pending ATT response message.
     *
     * @param   none
     *
     * @return  none
     */
    static void SimpleBLEPeripheral_sendAttRsp(void)
    {
      // See if there's a pending ATT Response to be transmitted
      if (pAttRsp != NULL)
      {
        uint8_t status;
        
        // Increment retransmission count
        rspTxRetry++;
        
        // Try to retransmit ATT response till either we're successful or
        // the ATT Client times out (after 30s) and drops the connection.
        status = GATT_SendRsp(pAttRsp->connHandle, pAttRsp->method, 
                              &(pAttRsp->msg));
        if ((status != blePending) && (status != MSG_BUFFER_NOT_AVAIL))
        {
          // Disable connection event end notice
          HCI_EXT_ConnEventNoticeCmd(pAttRsp->connHandle, selfEntity, 0);
          
          // We're done with the response message
          SimpleBLEPeripheral_freeAttRsp(status);
        }
        else
        {
          // Continue retrying
          LCD_WRITE_STRING_VALUE("Rsp send retry:", rspTxRetry, 10, LCD_PAGE5);
        }
      }
    }
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_freeAttRsp
     *
     * @brief   Free ATT response message.
     *
     * @param   status - response transmit status
     *
     * @return  none
     */
    static void SimpleBLEPeripheral_freeAttRsp(uint8_t status)
    {
      // See if there's a pending ATT response message
      if (pAttRsp != NULL)
      {
        // See if the response was sent out successfully
        if (status == SUCCESS)
        {
          LCD_WRITE_STRING_VALUE("Rsp sent, retry:", rspTxRetry, 10, LCD_PAGE5);
        }
        else
        {
          // Free response payload
          GATT_bm_free(&pAttRsp->msg, pAttRsp->method);
          
          LCD_WRITE_STRING_VALUE("Rsp retry failed:", rspTxRetry, 10, LCD_PAGE5);
        }
        
        // Free response message
        ICall_freeMsg(pAttRsp);
        
        // Reset our globals
        pAttRsp = NULL;
        rspTxRetry = 0;
      }
    }
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_processAppMsg
     *
     * @brief   Process an incoming callback from a profile.
     *
     * @param   pMsg - message to process
     *
     * @return  None.
     */
    static void SimpleBLEPeripheral_processAppMsg(sbpEvt_t *pMsg)
    {
      switch (pMsg->hdr.event)
      {
        case SBP_STATE_CHANGE_EVT:
          SimpleBLEPeripheral_processStateChangeEvt((gaprole_States_t)pMsg->
                                                    hdr.state);
          break;
    
        case SBP_CHAR_CHANGE_EVT:
          SimpleBLEPeripheral_processCharValueChangeEvt(pMsg->hdr.state);
          break;
    
    
        default:
          // Do nothing.
          break;
      }
    }
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_stateChangeCB
     *
     * @brief   Callback from GAP Role indicating a role state change.
     *
     * @param   newState - new state
     *
     * @return  None.
     */
    static void SimpleBLEPeripheral_stateChangeCB(gaprole_States_t newState)
    {
      SimpleBLEPeripheral_enqueueMsg(SBP_STATE_CHANGE_EVT, newState);
    }
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_processStateChangeEvt
     *
     * @brief   Process a pending GAP Role state change event.
     *
     * @param   newState - new state
     *
     * @return  None.
     */
    static void SimpleBLEPeripheral_processStateChangeEvt(gaprole_States_t newState)
    {
    #ifdef PLUS_BROADCASTER
      static bool firstConnFlag = false;
    #endif // PLUS_BROADCASTER
    
      switch ( newState )
      {
        case GAPROLE_STARTED:
          {
            uint8_t ownAddress[B_ADDR_LEN];
            uint8_t systemId[DEVINFO_SYSTEM_ID_LEN];
    
            GAPRole_GetParameter(GAPROLE_BD_ADDR, ownAddress);
    
            // use 6 bytes of device address for 8 bytes of system ID value
            systemId[0] = ownAddress[0];
            systemId[1] = ownAddress[1];
            systemId[2] = ownAddress[2];
    
            // set middle bytes to zero
            systemId[4] = 0x00;
            systemId[3] = 0x00;
    
            // shift three bytes up
            systemId[7] = ownAddress[5];
            systemId[6] = ownAddress[4];
            systemId[5] = ownAddress[3];
    
            DevInfo_SetParameter(DEVINFO_SYSTEM_ID, DEVINFO_SYSTEM_ID_LEN, 
                                 systemId);
    
            // Display device address
            LCD_WRITE_STRING(Util_convertBdAddr2Str(ownAddress), LCD_PAGE1);
            LCD_WRITE_STRING("Initialized", LCD_PAGE2);
          }
          break;
    
        case GAPROLE_ADVERTISING:
          LCD_WRITE_STRING("Advertising", LCD_PAGE2);
          break;
    
    #ifdef PLUS_BROADCASTER   
        /* After a connection is dropped a device in PLUS_BROADCASTER will continue
         * sending non-connectable advertisements and shall sending this change of 
         * state to the application.  These are then disabled here so that sending 
         * connectable advertisements can resume.
         */
        case GAPROLE_ADVERTISING_NONCONN:
          {
            uint8_t advertEnabled = FALSE;
          
            // Disable non-connectable advertising.
            GAPRole_SetParameter(GAPROLE_ADV_NONCONN_ENABLED, sizeof(uint8_t),
                               &advertEnabled);
          
            advertEnabled = TRUE;
          
            // Enabled connectable advertising.
            GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t),
                                 &advertEnabled);
            
            // Reset flag for next connection.
            firstConnFlag = false;
            
            SimpleBLEPeripheral_freeAttRsp(bleNotConnected);
          }
          break;
    #endif //PLUS_BROADCASTER   
    
        case GAPROLE_CONNECTED:
          {
            uint8_t peerAddress[B_ADDR_LEN];
    
            GAPRole_GetParameter(GAPROLE_CONN_BD_ADDR, peerAddress);
    
            Util_startClock(&periodicClock);
            
            LCD_WRITE_STRING("Connected", LCD_PAGE2);
            LCD_WRITE_STRING(Util_convertBdAddr2Str(peerAddress), LCD_PAGE3);
    
            #ifdef PLUS_BROADCASTER
              // Only turn advertising on for this state when we first connect
              // otherwise, when we go from connected_advertising back to this state
              // we will be turning advertising back on.
              if (firstConnFlag == false)
              {
                uint8_t advertEnabled = FALSE; // Turn on Advertising
    
                // Disable connectable advertising.
                GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t),
                                     &advertEnabled);
                
                // Set to true for non-connectabel advertising.
                advertEnabled = TRUE;
    
                // Enable non-connectable advertising.
                GAPRole_SetParameter(GAPROLE_ADV_NONCONN_ENABLED, sizeof(uint8_t),
                                     &advertEnabled);
                firstConnFlag = true;
              }
            #endif // PLUS_BROADCASTER
          }
          break;
    
        case GAPROLE_CONNECTED_ADV:
          LCD_WRITE_STRING("Connected Advertising", LCD_PAGE2);
          break;
    
        case GAPROLE_WAITING:
          Util_stopClock(&periodicClock);
          
          SimpleBLEPeripheral_freeAttRsp(bleNotConnected);
    
          LCD_WRITE_STRING("Disconnected", LCD_PAGE2);
    
          // Clear remaining lines
          LCD_WRITE_STRING("", LCD_PAGE3);
          LCD_WRITE_STRING("", LCD_PAGE4);
          LCD_WRITE_STRING("", LCD_PAGE5);
          break;
    
        case GAPROLE_WAITING_AFTER_TIMEOUT:
          SimpleBLEPeripheral_freeAttRsp(bleNotConnected);
          
          LCD_WRITE_STRING("Timed Out", LCD_PAGE2);
          
          // Clear remaining lines
          LCD_WRITE_STRING("", LCD_PAGE3);
          LCD_WRITE_STRING("", LCD_PAGE4);
          LCD_WRITE_STRING("", LCD_PAGE5);
    
          #ifdef PLUS_BROADCASTER
            // Reset flag for next connection.
            firstConnFlag = false;
          #endif //#ifdef (PLUS_BROADCASTER)
          break;
    
        case GAPROLE_ERROR:
          LCD_WRITE_STRING("Error", LCD_PAGE2);
          break;
    
        default:
          LCD_WRITE_STRING("", LCD_PAGE2);
          break;
      }
    
      // Update the state
      //gapProfileState = newState;
    }
    
    #ifndef FEATURE_OAD
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_charValueChangeCB
     *
     * @brief   Callback from Simple Profile indicating a characteristic
     *          value change.
     *
     * @param   paramID - parameter ID of the value that was changed.
     *
     * @return  None.
     */
    static void SimpleBLEPeripheral_charValueChangeCB(uint8_t paramID)
    {
      SimpleBLEPeripheral_enqueueMsg(SBP_CHAR_CHANGE_EVT, paramID);
    }
    #endif //!FEATURE_OAD
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_processCharValueChangeEvt
     *
     * @brief   Process a pending Simple Profile characteristic value change
     *          event.
     *
     * @param   paramID - parameter ID of the value that was changed.
     *
     * @return  None.
     */
    static void SimpleBLEPeripheral_processCharValueChangeEvt(uint8_t paramID)
    {
    #ifndef FEATURE_OAD
      uint8_t newValue;
    
      switch(paramID)
      {
        case SIMPLEPROFILE_CHAR1:
          SimpleProfile_GetParameter(SIMPLEPROFILE_CHAR1, &newValue);
    
          LCD_WRITE_STRING_VALUE("Char 1:", (uint16_t)newValue, 10, LCD_PAGE4);
          break;
    
        case SIMPLEPROFILE_CHAR3:
          SimpleProfile_GetParameter(SIMPLEPROFILE_CHAR3, &newValue);
    
          LCD_WRITE_STRING_VALUE("Char 3:", (uint16_t)newValue, 10, LCD_PAGE4);
          break;
    
        default:
          // should not reach here!
          break;
      }
    #endif //!FEATURE_OAD
    }
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_performPeriodicTask
     *
     * @brief   Perform a periodic application task. This function gets called
     *          every five seconds (SBP_PERIODIC_EVT_PERIOD). In this example,
     *          the value of the third characteristic in the SimpleGATTProfile
     *          service is retrieved from the profile, and then copied into the
     *          value of the the fourth characteristic.
     *
     * @param   None.
     *
     * @return  None.
     */
    static void SimpleBLEPeripheral_performPeriodicTask(void)
    {
    #ifndef FEATURE_OAD
      uint8_t valueToCopy;
    
      // Call to retrieve the value of the third characteristic in the profile
      if (SimpleProfile_GetParameter(SIMPLEPROFILE_CHAR3, &valueToCopy) == SUCCESS)
      {
        // Call to set that value of the fourth characteristic in the profile.
        // Note that if notifications of the fourth characteristic have been
        // enabled by a GATT client device, then a notification will be sent
        // every time this function is called.
        SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR4, sizeof(uint8_t),
                                   &valueToCopy);
      }
    #endif //!FEATURE_OAD
    }
    
    
    #if defined(FEATURE_OAD)
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_processOadWriteCB
     *
     * @brief   Process a write request to the OAD profile.
     *
     * @param   event      - event type:
     *                       OAD_WRITE_IDENTIFY_REQ
     *                       OAD_WRITE_BLOCK_REQ
     * @param   connHandle - the connection Handle this request is from.
     * @param   pData      - pointer to data for processing and/or storing.
     *
     * @return  None.
     */
    void SimpleBLEPeripheral_processOadWriteCB(uint8_t event, uint16_t connHandle,
                                               uint8_t *pData)
    {
      oadTargetWrite_t *oadWriteEvt = ICall_malloc( sizeof(oadTargetWrite_t) + \
                                                 sizeof(uint8_t) * OAD_PACKET_SIZE);
      
      if ( oadWriteEvt != NULL )
      {
        oadWriteEvt->event = event;
        oadWriteEvt->connHandle = connHandle;
        
        oadWriteEvt->pData = (uint8_t *)(&oadWriteEvt->pData + 1);
        memcpy(oadWriteEvt->pData, pData, OAD_PACKET_SIZE);
    
        Queue_enqueue(hOadQ, (Queue_Elem *)oadWriteEvt);
        
        // Post the application's semaphore.
        Semaphore_post(sem);
      }
      else
      {
        // Fail silently.
      }
    }
    #endif //FEATURE_OAD
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_clockHandler
     *
     * @brief   Handler function for clock timeouts.
     *
     * @param   arg - event type
     *
     * @return  None.
     */
    static void SimpleBLEPeripheral_clockHandler(UArg arg)
    {
      // Store the event.
      events |= arg;
    
      // Wake up the application.
      Semaphore_post(sem);
    }
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_enqueueMsg
     *
     * @brief   Creates a message and puts the message in RTOS queue.
     *
     * @param   event - message event.
     * @param   state - message state.
     *
     * @return  None.
     */
    static void SimpleBLEPeripheral_enqueueMsg(uint8_t event, uint8_t state)
    {
      sbpEvt_t *pMsg;
    
      // Create dynamic pointer to message.
      if ((pMsg = ICall_malloc(sizeof(sbpEvt_t))))
      {
        pMsg->hdr.event = event;
        pMsg->hdr.state = state;
    
        // Enqueue the message.
        Util_enqueueMsg(appMsgQueue, sem, (uint8*)pMsg);
      }
    }
    
    
    /*********************************************************************
    *********************************************************************/
    
     

  • I eliminated the custom structure for the UART and used the same structure as sbpEvt_t by using more global variables for the UART inside SimpleBLEPeripheral.c. I am able to set a breakpoint at  Util_enqueueMsg(appMsgQueue, sem, (uint8*)pMsg); inside UART_enqueueMsg function. I am not able to proceed with the program run after this point. The execution is never reaching any part of this code pasted below inside SBP.c.

    Any new ideas much appreciated.

    Priya

    /*******************************************************************************
      Filename:       simpleBLEPeripheral.c
      Revised:        $Date: 2016-01-07 16:59:59 -0800 (Thu, 07 Jan 2016) $
      Revision:       $Revision: 44594 $
    
      Description:    This file contains the Simple BLE Peripheral sample 
                      application for use with the CC2650 Bluetooth Low Energy 
                      Protocol Stack.
    
      Copyright 2013 - 2015 Texas Instruments Incorporated. All rights reserved.
    
      IMPORTANT: Your use of this Software is limited to those specific rights
      granted under the terms of a software license agreement between the user
      who downloaded the software, his/her employer (which must be your employer)
      and Texas Instruments Incorporated (the "License").  You may not use this
      Software unless you agree to abide by the terms of the License. The License
      limits your use, and you acknowledge, that the Software may not be modified,
      copied or distributed unless embedded on a Texas Instruments microcontroller
      or used solely and exclusively in conjunction with a Texas Instruments radio
      frequency transceiver, which is integrated into your product.  Other than for
      the foregoing purpose, you may not use, reproduce, copy, prepare derivative
      works of, modify, distribute, perform, display or sell this Software and/or
      its documentation for any purpose.
    
      YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE
      PROVIDED �AS IS� WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,
      INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE,
      NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL
      TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT,
      NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER
      LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES
      INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE
      OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT
      OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
      (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
    
      Should you have any questions regarding your right to use this Software,
      contact Texas Instruments Incorporated at www.TI.com.
    *******************************************************************************/
    
    /*********************************************************************
     * INCLUDES
     */
    #include <string.h>
    
    #include <ti/sysbios/knl/Task.h>
    #include <ti/sysbios/knl/Clock.h>
    #include <ti/sysbios/knl/Semaphore.h>
    #include <ti/sysbios/knl/Queue.h>
    #include <ti/drivers/UART.h>
    
    #include <xdc/std.h>
    #include <xdc/cfg/global.h>
    #include <xdc/runtime/System.h>
    #include <xdc/runtime/Error.h>
    
    #include "hci_tl.h"
    #include "gatt.h"
    #include "gapgattserver.h"
    #include "gattservapp.h"
    #include "devinfoservice.h"
    #include "simpleGATTprofile.h"
    
    #if defined(SENSORTAG_HW)
    #include "bsp_spi.h"
    #endif // SENSORTAG_HW
    
    #if defined(FEATURE_OAD) || defined(IMAGE_INVALIDATE)
    #include "oad_target.h"
    #include "oad.h"
    #endif //FEATURE_OAD || IMAGE_INVALIDATE
    
    #include "peripheral.h"
    #include "gapbondmgr.h"
    
    #include "osal_snv.h"
    #include "ICallBleAPIMSG.h"
    
    #include "util.h"
    #include "board_lcd.h"
    #include "board_key.h"
    #include "Board.h"
    
    #include "simpleBLEPeripheral.h"
    
    #include <ti/drivers/lcd/LCDDogm1286.h>
    
    /*********************************************************************
     * CONSTANTS
     */
    // Advertising interval when device is discoverable (units of 625us, 160=100ms)
    #define DEFAULT_ADVERTISING_INTERVAL          160
    
    // Limited discoverable mode advertises for 30.72s, and then stops
    // General discoverable mode advertises indefinitely
    #define DEFAULT_DISCOVERABLE_MODE             GAP_ADTYPE_FLAGS_GENERAL
    
    #ifndef FEATURE_OAD
    // Minimum connection interval (units of 1.25ms, 80=100ms) if automatic
    // parameter update request is enabled
    #define DEFAULT_DESIRED_MIN_CONN_INTERVAL     80
    
    // Maximum connection interval (units of 1.25ms, 800=1000ms) if automatic
    // parameter update request is enabled
    #define DEFAULT_DESIRED_MAX_CONN_INTERVAL     800
    #else
    // Minimum connection interval (units of 1.25ms, 8=10ms) if automatic
    // parameter update request is enabled
    #define DEFAULT_DESIRED_MIN_CONN_INTERVAL     8
    
    // Maximum connection interval (units of 1.25ms, 8=10ms) if automatic
    // parameter update request is enabled
    #define DEFAULT_DESIRED_MAX_CONN_INTERVAL     8
    #endif // FEATURE_OAD
    
    // Slave latency to use if automatic parameter update request is enabled
    #define DEFAULT_DESIRED_SLAVE_LATENCY         0
    
    // Supervision timeout value (units of 10ms, 1000=10s) if automatic parameter
    // update request is enabled
    #define DEFAULT_DESIRED_CONN_TIMEOUT          1000
    
    // Whether to enable automatic parameter update request when a connection is
    // formed
    #define DEFAULT_ENABLE_UPDATE_REQUEST         TRUE
    
    // Connection Pause Peripheral time value (in seconds)
    #define DEFAULT_CONN_PAUSE_PERIPHERAL         6
    
    // How often to perform periodic event (in msec)
    #define SBP_PERIODIC_EVT_PERIOD               5000
    
    #ifdef FEATURE_OAD
    // The size of an OAD packet.
    #define OAD_PACKET_SIZE                       ((OAD_BLOCK_SIZE) + 2)
    #endif // FEATURE_OAD
    
    // Task configuration
    #define SBP_TASK_PRIORITY                     1
    
    #ifndef SBP_TASK_STACK_SIZE
    #define SBP_TASK_STACK_SIZE                   644
    #endif
    
    // Internal Events for RTOS application
    #define SBP_STATE_CHANGE_EVT                  0x0001
    #define SBP_CHAR_CHANGE_EVT                   0x0002
    #define SBP_PERIODIC_EVT                      0x0004
    #define SBP_CONN_EVT_END_EVT                  0x0008
    #define UART_EVT 							  0x0010
    
    /*********************************************************************
     * TYPEDEFS
     */
    
    // App event passed from profiles.
    typedef struct
    {
      appEvtHdr_t hdr;  // event header.
    } sbpEvt_t;
    
    
    /*********************************************************************
     * LOCAL VARIABLES
     */
    
    // Entity ID globally used to check for source and/or destination of messages
    static ICall_EntityID selfEntity;
    
    // Semaphore globally used to post events to the application thread
    static ICall_Semaphore sem;
    
    // Clock instances for internal periodic events.
    static Clock_Struct periodicClock;
    
    // Queue object used for app messages
    static Queue_Struct appMsg;
    static Queue_Handle appMsgQueue;
    
    
    
    #if defined(FEATURE_OAD)
    // Event data from OAD profile.
    static Queue_Struct oadQ;
    static Queue_Handle hOadQ;
    #endif //FEATURE_OAD
    
    // events flag for internal application events.
    static uint16_t events;
    
    // Task configuration
    Task_Struct sbpTask;
    Char sbpTaskStack[SBP_TASK_STACK_SIZE];
    
    // Profile state and parameters
    //static gaprole_States_t gapProfileState = GAPROLE_INIT;
    
    // GAP - SCAN RSP data (max size = 31 bytes)
    static uint8_t scanRspData[] =
    {
      // complete name
      0x14,   // length of this data
      GAP_ADTYPE_LOCAL_NAME_COMPLETE,
      0x53,   // 'S'
      0x69,   // 'i'
      0x6d,   // 'm'
      0x70,   // 'p'
      0x6c,   // 'l'
      0x65,   // 'e'
      0x42,   // 'B'
      0x4c,   // 'L'
      0x45,   // 'E'
      0x50,   // 'P'
      0x65,   // 'e'
      0x72,   // 'r'
      0x69,   // 'i'
      0x70,   // 'p'
      0x68,   // 'h'
      0x65,   // 'e'
      0x72,   // 'r'
      0x61,   // 'a'
      0x6c,   // 'l'
    
      // connection interval range
      0x05,   // length of this data
      GAP_ADTYPE_SLAVE_CONN_INTERVAL_RANGE,
      LO_UINT16(DEFAULT_DESIRED_MIN_CONN_INTERVAL),   // 100ms
      HI_UINT16(DEFAULT_DESIRED_MIN_CONN_INTERVAL),
      LO_UINT16(DEFAULT_DESIRED_MAX_CONN_INTERVAL),   // 1s
      HI_UINT16(DEFAULT_DESIRED_MAX_CONN_INTERVAL),
    
      // Tx power level
      0x02,   // length of this data
      GAP_ADTYPE_POWER_LEVEL,
      0       // 0dBm
    };
    
    // GAP - Advertisement data (max size = 31 bytes, though this is
    // best kept short to conserve power while advertisting)
    static uint8_t advertData[] =
    {
      // Flags; this sets the device to use limited discoverable
      // mode (advertises for 30 seconds at a time) instead of general
      // discoverable mode (advertises indefinitely)
      0x02,   // length of this data
      GAP_ADTYPE_FLAGS,
      DEFAULT_DISCOVERABLE_MODE | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,
    
      // service UUID, to notify central devices what services are included
      // in this peripheral
      0x03,   // length of this data
      GAP_ADTYPE_16BIT_MORE,      // some of the UUID's, but not all
    #ifdef FEATURE_OAD
      LO_UINT16(OAD_SERVICE_UUID),
      HI_UINT16(OAD_SERVICE_UUID)
    #else
      LO_UINT16(SIMPLEPROFILE_SERV_UUID),
      HI_UINT16(SIMPLEPROFILE_SERV_UUID),
    #endif //!FEATURE_OAD
    };
    
    // GAP GATT Attributes
    static uint8_t attDeviceName[GAP_DEVICE_NAME_LEN] = "Simple BLE Peripheral";
    
    // Globals used for ATT Response retransmission
    static gattMsgEvent_t *pAttRsp = NULL;
    static uint8_t rspTxRetry = 0;
    
    /*********************************************************************
     * LOCAL FUNCTIONS
     */
    
    static void SimpleBLEPeripheral_init( void );
    static void SimpleBLEPeripheral_taskFxn(UArg a0, UArg a1);
    
    static uint8_t SimpleBLEPeripheral_processStackMsg(ICall_Hdr *pMsg);
    static uint8_t SimpleBLEPeripheral_processGATTMsg(gattMsgEvent_t *pMsg);
    static void SimpleBLEPeripheral_processAppMsg(sbpEvt_t *pMsg);
    static void SimpleBLEPeripheral_processStateChangeEvt(
                                                         gaprole_States_t newState);
    static void SimpleBLEPeripheral_processCharValueChangeEvt(uint8_t paramID);
    static void SimpleBLEPeripheral_performPeriodicTask(void);
    
    static void SimpleBLEPeripheral_sendAttRsp(void);
    static void SimpleBLEPeripheral_freeAttRsp(uint8_t status);
    
    static void SimpleBLEPeripheral_stateChangeCB(gaprole_States_t newState);
    #ifndef FEATURE_OAD
    static void SimpleBLEPeripheral_charValueChangeCB(uint8_t paramID);
    #endif //!FEATURE_OAD
    static void SimpleBLEPeripheral_enqueueMsg(uint8_t event, uint8_t state);
    
    static uint8_t rxBytes;
    static uint8_t rx_buf;
    static uint8_t tx_buf;
    static UART_Handle uart;
    
    static void UART_enqueueMsg(void);
    static void readCallback (UART_Handle handle, void *rx_buf, size_t size);
    static void UART_initialize(void);
    static void SimpleBLEPeripheral_processUART(uint8_t state);
    
    #ifdef FEATURE_OAD
    void SimpleBLEPeripheral_processOadWriteCB(uint8_t event, uint16_t connHandle,
                                               uint8_t *pData);
    #endif //FEATURE_OAD
    
    static void SimpleBLEPeripheral_clockHandler(UArg arg);
    
    
    static void UART_enqueueMsg(void)
    {
    	sbpEvt_t *pMsg;
    
      // Create dynamic pointer to message.
    
      if (pMsg = ICall_malloc(sizeof(sbpEvt_t)))
      {
        pMsg->hdr.event = UART_EVT;
        pMsg->hdr.state = rxBytes;
    
    
        // Enqueue the message.
        Util_enqueueMsg(appMsgQueue, sem, (uint8*)pMsg);
      }
    }
    
    static void readCallback(UART_Handle uart, void *rx_buf, size_t size)
    {
    	uint8_t byte = 0x23;
    
        tx_buf = *((uint8_t*) rx_buf);
    
        UART_write(uart, &tx_buf, size);
        UART_write(uart, &byte, 1);
        UART_read(uart, &rx_buf, size);
        UART_enqueueMsg();
    }
    
    static void UART_initialize(void)
    {
    	UART_init();
    	UART_Params uartParams;
    
        UART_Handle uart;
    
    	/* Create a UART with data processing off. */
    	UART_Params_init(&uartParams);
    	uartParams.writeDataMode = UART_DATA_BINARY;
    	uartParams.readDataMode = UART_DATA_BINARY;
    	uartParams.readReturnMode = UART_RETURN_FULL;
    	uartParams.readMode = UART_MODE_CALLBACK;
    	uartParams.baudRate = 9600;
    	uartParams.readCallback = readCallback;
    
    	uart = UART_open(Board_UART, &uartParams);
    
    		if (uart == NULL) {
    			System_abort("Error opening the UART");
    		}
    
        rxBytes = UART_read(uart, &rx_buf, sizeof (rx_buf));
    
        while(true);
    
    }
    
    static void SimpleBLEPeripheral_processUART(uint8_t state)
    {
    uint8_t byte1 = 0x92;
    uint8_t byte2 = 0x48;
    
        UART_write(uart, &byte1, 1);
    	UART_write(uart, &byte2, 1);
    	UART_write(uart, &state, 1);
    
    }
    /*********************************************************************
     * PROFILE CALLBACKS
     */
    
    // GAP Role Callbacks
    static gapRolesCBs_t SimpleBLEPeripheral_gapRoleCBs =
    {
      SimpleBLEPeripheral_stateChangeCB     // Profile State Change Callbacks
    };
    
    // GAP Bond Manager Callbacks
    static gapBondCBs_t simpleBLEPeripheral_BondMgrCBs =
    {
      NULL, // Passcode callback (not used by application)
      NULL  // Pairing / Bonding state Callback (not used by application)
    };
    
    // Simple GATT Profile Callbacks
    #ifndef FEATURE_OAD
    static simpleProfileCBs_t SimpleBLEPeripheral_simpleProfileCBs =
    {
      SimpleBLEPeripheral_charValueChangeCB // Characteristic value change callback
    };
    #endif //!FEATURE_OAD
    
    #ifdef FEATURE_OAD
    static oadTargetCBs_t simpleBLEPeripheral_oadCBs =
    {
      SimpleBLEPeripheral_processOadWriteCB // Write Callback.
    };
    #endif //FEATURE_OAD
    
    /*********************************************************************
     * PUBLIC FUNCTIONS
     */
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_createTask
     *
     * @brief   Task creation function for the Simple BLE Peripheral.
     *
     * @param   None.
     *
     * @return  None.
     */
    void SimpleBLEPeripheral_createTask(void)
    {
      Task_Params taskParams;
    
      // Configure task
      Task_Params_init(&taskParams);
      taskParams.stack = sbpTaskStack;
      taskParams.stackSize = SBP_TASK_STACK_SIZE;
      taskParams.priority = SBP_TASK_PRIORITY;
    
      Task_construct(&sbpTask, SimpleBLEPeripheral_taskFxn, &taskParams, NULL);
    }
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_init
     *
     * @brief   Called during initialization and contains application
     *          specific initialization (ie. hardware initialization/setup,
     *          table initialization, power up notification, etc), and
     *          profile initialization/setup.
     *
     * @param   None.
     *
     * @return  None.
     */
    static void SimpleBLEPeripheral_init(void)
    {
      // ******************************************************************
      // N0 STACK API CALLS CAN OCCUR BEFORE THIS CALL TO ICall_registerApp
      // ******************************************************************
      // Register the current thread as an ICall dispatcher application
      // so that the application can send and receive messages.
      ICall_registerApp(&selfEntity, &sem);
    
    
      UART_initialize();
    
    //  UART_init();
    
      // Hard code the BD Address till CC2650 board gets its own IEEE address
      //uint8 bdAddress[B_ADDR_LEN] = { 0xAD, 0xD0, 0x0A, 0xAD, 0xD0, 0x0A };
      //HCI_EXT_SetBDADDRCmd(bdAddress);
    
      // Set device's Sleep Clock Accuracy
      //HCI_EXT_SetSCACmd(500);
      
      // Create an RTOS queue for message from profile to be sent to app.
      appMsgQueue = Util_constructQueue(&appMsg);
    
      // Create one-shot clocks for internal periodic events.
      Util_constructClock(&periodicClock, SimpleBLEPeripheral_clockHandler,
                          SBP_PERIODIC_EVT_PERIOD, 0, false, SBP_PERIODIC_EVT);
      
    #ifndef SENSORTAG_HW
      Board_openLCD();
    #endif //SENSORTAG_HW
      
    #if SENSORTAG_HW
      // Setup SPI bus for serial flash and Devpack interface
      bspSpiOpen();
    #endif //SENSORTAG_HW
      
      // Setup the GAP
      GAP_SetParamValue(TGAP_CONN_PAUSE_PERIPHERAL, DEFAULT_CONN_PAUSE_PERIPHERAL);
    
      // Setup the GAP Peripheral Role Profile
      {
        // For all hardware platforms, device starts advertising upon initialization
        uint8_t initialAdvertEnable = TRUE;
    
        // By setting this to zero, the device will go into the waiting state after
        // being discoverable for 30.72 second, and will not being advertising again
        // until the enabler is set back to TRUE
        uint16_t advertOffTime = 0;
    
        uint8_t enableUpdateRequest = DEFAULT_ENABLE_UPDATE_REQUEST;
        uint16_t desiredMinInterval = DEFAULT_DESIRED_MIN_CONN_INTERVAL;
        uint16_t desiredMaxInterval = DEFAULT_DESIRED_MAX_CONN_INTERVAL;
        uint16_t desiredSlaveLatency = DEFAULT_DESIRED_SLAVE_LATENCY;
        uint16_t desiredConnTimeout = DEFAULT_DESIRED_CONN_TIMEOUT;
    
        // Set the GAP Role Parameters
        GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t),
                             &initialAdvertEnable);
        GAPRole_SetParameter(GAPROLE_ADVERT_OFF_TIME, sizeof(uint16_t),
                             &advertOffTime);
    
        GAPRole_SetParameter(GAPROLE_SCAN_RSP_DATA, sizeof(scanRspData),
                             scanRspData);
        GAPRole_SetParameter(GAPROLE_ADVERT_DATA, sizeof(advertData), advertData);
    
        GAPRole_SetParameter(GAPROLE_PARAM_UPDATE_ENABLE, sizeof(uint8_t),
                             &enableUpdateRequest);
        GAPRole_SetParameter(GAPROLE_MIN_CONN_INTERVAL, sizeof(uint16_t),
                             &desiredMinInterval);
        GAPRole_SetParameter(GAPROLE_MAX_CONN_INTERVAL, sizeof(uint16_t),
                             &desiredMaxInterval);
        GAPRole_SetParameter(GAPROLE_SLAVE_LATENCY, sizeof(uint16_t),
                             &desiredSlaveLatency);
        GAPRole_SetParameter(GAPROLE_TIMEOUT_MULTIPLIER, sizeof(uint16_t),
                             &desiredConnTimeout);
      }
    
      // Set the GAP Characteristics
      GGS_SetParameter(GGS_DEVICE_NAME_ATT, GAP_DEVICE_NAME_LEN, attDeviceName);
    
      // Set advertising interval
      {
        uint16_t advInt = DEFAULT_ADVERTISING_INTERVAL;
    
        GAP_SetParamValue(TGAP_LIM_DISC_ADV_INT_MIN, advInt);
        GAP_SetParamValue(TGAP_LIM_DISC_ADV_INT_MAX, advInt);
        GAP_SetParamValue(TGAP_GEN_DISC_ADV_INT_MIN, advInt);
        GAP_SetParamValue(TGAP_GEN_DISC_ADV_INT_MAX, advInt);
      }
    
      // Setup the GAP Bond Manager
      {
        uint32_t passkey = 0; // passkey "000000"
        uint8_t pairMode = GAPBOND_PAIRING_MODE_WAIT_FOR_REQ;
        uint8_t mitm = TRUE;
        uint8_t ioCap = GAPBOND_IO_CAP_DISPLAY_ONLY;
        uint8_t bonding = TRUE;
    
        GAPBondMgr_SetParameter(GAPBOND_DEFAULT_PASSCODE, sizeof(uint32_t),
                                &passkey);
        GAPBondMgr_SetParameter(GAPBOND_PAIRING_MODE, sizeof(uint8_t), &pairMode);
        GAPBondMgr_SetParameter(GAPBOND_MITM_PROTECTION, sizeof(uint8_t), &mitm);
        GAPBondMgr_SetParameter(GAPBOND_IO_CAPABILITIES, sizeof(uint8_t), &ioCap);
        GAPBondMgr_SetParameter(GAPBOND_BONDING_ENABLED, sizeof(uint8_t), &bonding);
      }
    
       // Initialize GATT attributes
      GGS_AddService(GATT_ALL_SERVICES);           // GAP
      GATTServApp_AddService(GATT_ALL_SERVICES);   // GATT attributes
      DevInfo_AddService();                        // Device Information Service
    
    #ifndef FEATURE_OAD
      SimpleProfile_AddService(GATT_ALL_SERVICES); // Simple GATT Profile
    #endif //!FEATURE_OAD
    
    #ifdef FEATURE_OAD
      VOID OAD_addService();                 // OAD Profile
      OAD_register((oadTargetCBs_t *)&simpleBLEPeripheral_oadCBs);
      hOadQ = Util_constructQueue(&oadQ);
    #endif
    
    #ifdef IMAGE_INVALIDATE
      Reset_addService();
    #endif //IMAGE_INVALIDATE
      
      
    #ifndef FEATURE_OAD
      // Setup the SimpleProfile Characteristic Values
      {
        uint8_t charValue1 = 1;
        uint8_t charValue2 = 2;
        uint8_t charValue3 = 3;
        uint8_t charValue4 = 4;
        uint8_t charValue5[SIMPLEPROFILE_CHAR5_LEN] = { 1, 2, 3, 4, 5 };
    
        SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR1, sizeof(uint8_t),
                                   &charValue1);
        SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR2, sizeof(uint8_t),
                                   &charValue2);
        SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR3, sizeof(uint8_t),
                                   &charValue3);
        SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR4, sizeof(uint8_t),
                                   &charValue4);
        SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR5, SIMPLEPROFILE_CHAR5_LEN,
                                   charValue5);
      }
    
      // Register callback with SimpleGATTprofile
      SimpleProfile_RegisterAppCBs(&SimpleBLEPeripheral_simpleProfileCBs);
    #endif //!FEATURE_OAD
      
      // Start the Device
      VOID GAPRole_StartDevice(&SimpleBLEPeripheral_gapRoleCBs);
      
      // Start Bond Manager
      VOID GAPBondMgr_Register(&simpleBLEPeripheral_BondMgrCBs);
    
      // Register with GAP for HCI/Host messages
      GAP_RegisterForMsgs(selfEntity);
      
      // Register for GATT local events and ATT Responses pending for transmission
      GATT_RegisterForMsgs(selfEntity);
      
    #if defined FEATURE_OAD
    #if defined (HAL_IMAGE_A)
      LCD_WRITE_STRING("BLE Peripheral A", LCD_PAGE0);
    #else
      LCD_WRITE_STRING("BLE Peripheral B", LCD_PAGE0);
    #endif // HAL_IMAGE_A
    #else
      LCD_WRITE_STRING("BLE Peripheral", LCD_PAGE0);
    #endif // FEATURE_OAD
    }       
    
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_taskFxn
     *
     * @brief   Application task entry point for the Simple BLE Peripheral.
     *
     * @param   a0, a1 - not used.
     *
     * @return  None.
     */
    static void SimpleBLEPeripheral_taskFxn(UArg a0, UArg a1)
    {
      // Initialize application
      SimpleBLEPeripheral_init();
    
    
      // Application main loop
      for (;;)
      {
        // Waits for a signal to the semaphore associated with the calling thread.
        // Note that the semaphore associated with a thread is signaled when a
        // message is queued to the message receive queue of the thread or when
        // ICall_signal() function is called onto the semaphore.
        ICall_Errno errno = ICall_wait(ICALL_TIMEOUT_FOREVER);
    
        if (errno == ICALL_ERRNO_SUCCESS)
        {
    
          ICall_EntityID dest;
          ICall_ServiceEnum src;
          ICall_HciExtEvt *pMsg = NULL;
    
    
          if (ICall_fetchServiceMsg(&src, &dest,
                                    (void **)&pMsg) == ICALL_ERRNO_SUCCESS)
          {
            uint8 safeToDealloc = TRUE;
            
            if ((src == ICALL_SERVICE_CLASS_BLE) && (dest == selfEntity))
            {
              ICall_Event *pEvt = (ICall_Event *)pMsg;
              
              // Check for BLE stack events first
              if (pEvt->signature == 0xffff)
              {
                if (pEvt->event_flag & SBP_CONN_EVT_END_EVT)
                {
                  // Try to retransmit pending ATT Response (if any)
                  SimpleBLEPeripheral_sendAttRsp();
                }
              }
              else
              {
                // Process inter-task message
                safeToDealloc = SimpleBLEPeripheral_processStackMsg(
                                                                 (ICall_Hdr *)pMsg);
              }
            }
    
            if (pMsg && safeToDealloc)
            {
              ICall_freeMsg(pMsg);
            }
          }
    
          // If RTOS queue is not empty, process app message.
          while (!Queue_empty(appMsgQueue))
          {
    
        	sbpEvt_t *pMsg = (sbpEvt_t *)Util_dequeueMsg(appMsgQueue);
    
            if (pMsg)
            {
              // Process message.
              SimpleBLEPeripheral_processAppMsg(pMsg);
              // Free the space from the message.
              ICall_free(pMsg);
    
            }
          }
        }
    
        if (events & SBP_PERIODIC_EVT)
        {
          events &= ~SBP_PERIODIC_EVT;
    
          Util_startClock(&periodicClock);
    
          // Perform periodic application task
          SimpleBLEPeripheral_performPeriodicTask();
        }
        
    #ifdef FEATURE_OAD
        while (!Queue_empty(hOadQ))
        {
          oadTargetWrite_t *oadWriteEvt = Queue_dequeue(hOadQ);
    
          // Identify new image.
          if (oadWriteEvt->event == OAD_WRITE_IDENTIFY_REQ)
          {
            OAD_imgIdentifyWrite(oadWriteEvt->connHandle, oadWriteEvt->pData);
          }
          // Write a next block request.
          else if (oadWriteEvt->event == OAD_WRITE_BLOCK_REQ)
          {
            OAD_imgBlockWrite(oadWriteEvt->connHandle, oadWriteEvt->pData);
          }
    
          // Free buffer.
          ICall_free(oadWriteEvt);
        }
    #endif //FEATURE_OAD
      }
    }
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_processStackMsg
     *
     * @brief   Process an incoming stack message.
     *
     * @param   pMsg - message to process
     *
     * @return  TRUE if safe to deallocate incoming message, FALSE otherwise.
     */
    static uint8_t SimpleBLEPeripheral_processStackMsg(ICall_Hdr *pMsg)
    {
      uint8_t safeToDealloc = TRUE;
        
      switch (pMsg->event)
      {
        case GATT_MSG_EVENT:
          // Process GATT message
          safeToDealloc = SimpleBLEPeripheral_processGATTMsg(
                                                            (gattMsgEvent_t *)pMsg);
          break;
    
        case HCI_GAP_EVENT_EVENT:
          {
            // Process HCI message
            switch(pMsg->status)
            {
              case HCI_COMMAND_COMPLETE_EVENT_CODE:
                // Process HCI Command Complete Event
                break;
                
              default:
                break;
            }
          }
          break;
          
        default:
          // do nothing
          break;
      }
      
      return (safeToDealloc);
    }
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_processGATTMsg
     *
     * @brief   Process GATT messages and events.
     *
     * @return  TRUE if safe to deallocate incoming message, FALSE otherwise.
     */
    static uint8_t SimpleBLEPeripheral_processGATTMsg(gattMsgEvent_t *pMsg)
    {
      // See if GATT server was unable to transmit an ATT response
      if (pMsg->hdr.status == blePending)
      {
        // No HCI buffer was available. Let's try to retransmit the response
        // on the next connection event.
        if (HCI_EXT_ConnEventNoticeCmd(pMsg->connHandle, selfEntity,
                                       SBP_CONN_EVT_END_EVT) == SUCCESS)
        {
          // First free any pending response
          SimpleBLEPeripheral_freeAttRsp(FAILURE);
          
          // Hold on to the response message for retransmission
          pAttRsp = pMsg;
          
          // Don't free the response message yet
          return (FALSE);
        }
      }
      else if (pMsg->method == ATT_FLOW_CTRL_VIOLATED_EVENT)
      {
        // ATT request-response or indication-confirmation flow control is
        // violated. All subsequent ATT requests or indications will be dropped.
        // The app is informed in case it wants to drop the connection.
        
        // Display the opcode of the message that caused the violation.
        LCD_WRITE_STRING_VALUE("FC Violated:", pMsg->msg.flowCtrlEvt.opcode,
                               10, LCD_PAGE5);
      }    
      else if (pMsg->method == ATT_MTU_UPDATED_EVENT)
      {
        // MTU size updated
        LCD_WRITE_STRING_VALUE("MTU Size:", pMsg->msg.mtuEvt.MTU, 10, LCD_PAGE5);
      }
      
      // Free message payload. Needed only for ATT Protocol messages
      GATT_bm_free(&pMsg->msg, pMsg->method);
      
      // It's safe to free the incoming message
      return (TRUE);
    }
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_sendAttRsp
     *
     * @brief   Send a pending ATT response message.
     *
     * @param   none
     *
     * @return  none
     */
    static void SimpleBLEPeripheral_sendAttRsp(void)
    {
      // See if there's a pending ATT Response to be transmitted
      if (pAttRsp != NULL)
      {
        uint8_t status;
        
        // Increment retransmission count
        rspTxRetry++;
        
        // Try to retransmit ATT response till either we're successful or
        // the ATT Client times out (after 30s) and drops the connection.
        status = GATT_SendRsp(pAttRsp->connHandle, pAttRsp->method, 
                              &(pAttRsp->msg));
        if ((status != blePending) && (status != MSG_BUFFER_NOT_AVAIL))
        {
          // Disable connection event end notice
          HCI_EXT_ConnEventNoticeCmd(pAttRsp->connHandle, selfEntity, 0);
          
          // We're done with the response message
          SimpleBLEPeripheral_freeAttRsp(status);
        }
        else
        {
          // Continue retrying
          LCD_WRITE_STRING_VALUE("Rsp send retry:", rspTxRetry, 10, LCD_PAGE5);
        }
      }
    }
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_freeAttRsp
     *
     * @brief   Free ATT response message.
     *
     * @param   status - response transmit status
     *
     * @return  none
     */
    static void SimpleBLEPeripheral_freeAttRsp(uint8_t status)
    {
      // See if there's a pending ATT response message
      if (pAttRsp != NULL)
      {
        // See if the response was sent out successfully
        if (status == SUCCESS)
        {
          LCD_WRITE_STRING_VALUE("Rsp sent, retry:", rspTxRetry, 10, LCD_PAGE5);
        }
        else
        {
          // Free response payload
          GATT_bm_free(&pAttRsp->msg, pAttRsp->method);
          
          LCD_WRITE_STRING_VALUE("Rsp retry failed:", rspTxRetry, 10, LCD_PAGE5);
        }
        
        // Free response message
        ICall_freeMsg(pAttRsp);
        
        // Reset our globals
        pAttRsp = NULL;
        rspTxRetry = 0;
      }
    }
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_processAppMsg
     *
     * @brief   Process an incoming callback from a profile.
     *
     * @param   pMsg - message to process
     *
     * @return  None.
     */
    static void SimpleBLEPeripheral_processAppMsg(sbpEvt_t *pMsg)
    {
      switch (pMsg->hdr.event)
      {
        case SBP_STATE_CHANGE_EVT:
          SimpleBLEPeripheral_processStateChangeEvt((gaprole_States_t)pMsg->
                                                    hdr.state);
          break;
    
        case SBP_CHAR_CHANGE_EVT:
          SimpleBLEPeripheral_processCharValueChangeEvt(pMsg->hdr.state);
          break;
    
        case UART_EVT:
        	SimpleBLEPeripheral_processUART(pMsg->hdr.state);
    
        default:
          // Do nothing.
          break;
      }
    }
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_stateChangeCB
     *
     * @brief   Callback from GAP Role indicating a role state change.
     *
     * @param   newState - new state
     *
     * @return  None.
     */
    static void SimpleBLEPeripheral_stateChangeCB(gaprole_States_t newState)
    {
      SimpleBLEPeripheral_enqueueMsg(SBP_STATE_CHANGE_EVT, newState);
    }
    
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_processStateChangeEvt
     *
     * @brief   Process a pending GAP Role state change event.
     *
     * @param   newState - new state
     *
     * @return  None.
     */
    static void SimpleBLEPeripheral_processStateChangeEvt(gaprole_States_t newState)
    {
    #ifdef PLUS_BROADCASTER
      static bool firstConnFlag = false;
    #endif // PLUS_BROADCASTER
    
      switch ( newState )
      {
        case GAPROLE_STARTED:
          {
            uint8_t ownAddress[B_ADDR_LEN];
            uint8_t systemId[DEVINFO_SYSTEM_ID_LEN];
    
            GAPRole_GetParameter(GAPROLE_BD_ADDR, ownAddress);
    
            // use 6 bytes of device address for 8 bytes of system ID value
            systemId[0] = ownAddress[0];
            systemId[1] = ownAddress[1];
            systemId[2] = ownAddress[2];
    
            // set middle bytes to zero
            systemId[4] = 0x00;
            systemId[3] = 0x00;
    
            // shift three bytes up
            systemId[7] = ownAddress[5];
            systemId[6] = ownAddress[4];
            systemId[5] = ownAddress[3];
    
            DevInfo_SetParameter(DEVINFO_SYSTEM_ID, DEVINFO_SYSTEM_ID_LEN, 
                                 systemId);
    
            // Display device address
            LCD_WRITE_STRING(Util_convertBdAddr2Str(ownAddress), LCD_PAGE1);
            LCD_WRITE_STRING("Initialized", LCD_PAGE2);
          }
          break;
    
        case GAPROLE_ADVERTISING:
          LCD_WRITE_STRING("Advertising", LCD_PAGE2);
          break;
    
    #ifdef PLUS_BROADCASTER   
        /* After a connection is dropped a device in PLUS_BROADCASTER will continue
         * sending non-connectable advertisements and shall sending this change of 
         * state to the application.  These are then disabled here so that sending 
         * connectable advertisements can resume.
         */
        case GAPROLE_ADVERTISING_NONCONN:
          {
            uint8_t advertEnabled = FALSE;
          
            // Disable non-connectable advertising.
            GAPRole_SetParameter(GAPROLE_ADV_NONCONN_ENABLED, sizeof(uint8_t),
                               &advertEnabled);
          
            advertEnabled = TRUE;
          
            // Enabled connectable advertising.
            GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t),
                                 &advertEnabled);
            
            // Reset flag for next connection.
            firstConnFlag = false;
            
            SimpleBLEPeripheral_freeAttRsp(bleNotConnected);
          }
          break;
    #endif //PLUS_BROADCASTER   
    
        case GAPROLE_CONNECTED:
          {
            uint8_t peerAddress[B_ADDR_LEN];
    
            GAPRole_GetParameter(GAPROLE_CONN_BD_ADDR, peerAddress);
    
            Util_startClock(&periodicClock);
            
            LCD_WRITE_STRING("Connected", LCD_PAGE2);
            LCD_WRITE_STRING(Util_convertBdAddr2Str(peerAddress), LCD_PAGE3);
    
            #ifdef PLUS_BROADCASTER
              // Only turn advertising on for this state when we first connect
              // otherwise, when we go from connected_advertising back to this state
              // we will be turning advertising back on.
              if (firstConnFlag == false)
              {
                uint8_t advertEnabled = FALSE; // Turn on Advertising
    
                // Disable connectable advertising.
                GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t),
                                     &advertEnabled);
                
                // Set to true for non-connectabel advertising.
                advertEnabled = TRUE;
    
                // Enable non-connectable advertising.
                GAPRole_SetParameter(GAPROLE_ADV_NONCONN_ENABLED, sizeof(uint8_t),
                                     &advertEnabled);
                firstConnFlag = true;
              }
            #endif // PLUS_BROADCASTER
          }
          break;
    
        case GAPROLE_CONNECTED_ADV:
          LCD_WRITE_STRING("Connected Advertising", LCD_PAGE2);
          break;
    
        case GAPROLE_WAITING:
          Util_stopClock(&periodicClock);
          
          SimpleBLEPeripheral_freeAttRsp(bleNotConnected);
    
          LCD_WRITE_STRING("Disconnected", LCD_PAGE2);
    
          // Clear remaining lines
          LCD_WRITE_STRING("", LCD_PAGE3);
          LCD_WRITE_STRING("", LCD_PAGE4);
          LCD_WRITE_STRING("", LCD_PAGE5);
          break;
    
        case GAPROLE_WAITING_AFTER_TIMEOUT:
          SimpleBLEPeripheral_freeAttRsp(bleNotConnected);
          
          LCD_WRITE_STRING("Timed Out", LCD_PAGE2);
          
          // Clear remaining lines
          LCD_WRITE_STRING("", LCD_PAGE3);
          LCD_WRITE_STRING("", LCD_PAGE4);
          LCD_WRITE_STRING("", LCD_PAGE5);
    
          #ifdef PLUS_BROADCASTER
            // Reset flag for next connection.
            firstConnFlag = false;
          #endif //#ifdef (PLUS_BROADCASTER)
          break;
    
        case GAPROLE_ERROR:
          LCD_WRITE_STRING("Error", LCD_PAGE2);
          break;
    
        default:
          LCD_WRITE_STRING("", LCD_PAGE2);
          break;
      }
    
      // Update the state
      //gapProfileState = newState;
    }
    
    #ifndef FEATURE_OAD
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_charValueChangeCB
     *
     * @brief   Callback from Simple Profile indicating a characteristic
     *          value change.
     *
     * @param   paramID - parameter ID of the value that was changed.
     *
     * @return  None.
     */
    static void SimpleBLEPeripheral_charValueChangeCB(uint8_t paramID)
    {
      SimpleBLEPeripheral_enqueueMsg(SBP_CHAR_CHANGE_EVT, paramID);
    }
    #endif //!FEATURE_OAD
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_processCharValueChangeEvt
     *
     * @brief   Process a pending Simple Profile characteristic value change
     *          event.
     *
     * @param   paramID - parameter ID of the value that was changed.
     *
     * @return  None.
     */
    static void SimpleBLEPeripheral_processCharValueChangeEvt(uint8_t paramID)
    {
    #ifndef FEATURE_OAD
      uint8_t newValue;
    
      switch(paramID)
      {
        case SIMPLEPROFILE_CHAR1:
          SimpleProfile_GetParameter(SIMPLEPROFILE_CHAR1, &newValue);
    
          LCD_WRITE_STRING_VALUE("Char 1:", (uint16_t)newValue, 10, LCD_PAGE4);
          break;
    
        case SIMPLEPROFILE_CHAR3:
          SimpleProfile_GetParameter(SIMPLEPROFILE_CHAR3, &newValue);
    
          LCD_WRITE_STRING_VALUE("Char 3:", (uint16_t)newValue, 10, LCD_PAGE4);
          break;
    
        default:
          // should not reach here!
          break;
      }
    #endif //!FEATURE_OAD
    }
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_performPeriodicTask
     *
     * @brief   Perform a periodic application task. This function gets called
     *          every five seconds (SBP_PERIODIC_EVT_PERIOD). In this example,
     *          the value of the third characteristic in the SimpleGATTProfile
     *          service is retrieved from the profile, and then copied into the
     *          value of the the fourth characteristic.
     *
     * @param   None.
     *
     * @return  None.
     */
    static void SimpleBLEPeripheral_performPeriodicTask(void)
    {
    #ifndef FEATURE_OAD
      uint8_t valueToCopy;
    
      // Call to retrieve the value of the third characteristic in the profile
      if (SimpleProfile_GetParameter(SIMPLEPROFILE_CHAR3, &valueToCopy) == SUCCESS)
      {
        // Call to set that value of the fourth characteristic in the profile.
        // Note that if notifications of the fourth characteristic have been
        // enabled by a GATT client device, then a notification will be sent
        // every time this function is called.
        SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR4, sizeof(uint8_t),
                                   &valueToCopy);
      }
    #endif //!FEATURE_OAD
    }
    
    
    #if defined(FEATURE_OAD)
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_processOadWriteCB
     *
     * @brief   Process a write request to the OAD profile.
     *
     * @param   event      - event type:
     *                       OAD_WRITE_IDENTIFY_REQ
     *                       OAD_WRITE_BLOCK_REQ
     * @param   connHandle - the connection Handle this request is from.
     * @param   pData      - pointer to data for processing and/or storing.
     *
     * @return  None.
     */
    void SimpleBLEPeripheral_processOadWriteCB(uint8_t event, uint16_t connHandle,
                                               uint8_t *pData)
    {
      oadTargetWrite_t *oadWriteEvt = ICall_malloc( sizeof(oadTargetWrite_t) + \
                                                 sizeof(uint8_t) * OAD_PACKET_SIZE);
      
      if ( oadWriteEvt != NULL )
      {
        oadWriteEvt->event = event;
        oadWriteEvt->connHandle = connHandle;
        
        oadWriteEvt->pData = (uint8_t *)(&oadWriteEvt->pData + 1);
        memcpy(oadWriteEvt->pData, pData, OAD_PACKET_SIZE);
    
        Queue_enqueue(hOadQ, (Queue_Elem *)oadWriteEvt);
        
        // Post the application's semaphore.
        Semaphore_post(sem);
      }
      else
      {
        // Fail silently.
      }
    }
    #endif //FEATURE_OAD
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_clockHandler
     *
     * @brief   Handler function for clock timeouts.
     *
     * @param   arg - event type
     *
     * @return  None.
     */
    static void SimpleBLEPeripheral_clockHandler(UArg arg)
    {
      // Store the event.
      events |= arg;
    
      // Wake up the application.
      Semaphore_post(sem);
    }
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_enqueueMsg
     *
     * @brief   Creates a message and puts the message in RTOS queue.
     *
     * @param   event - message event.
     * @param   state - message state.
     *
     * @return  None.
     */
    static void SimpleBLEPeripheral_enqueueMsg(uint8_t event, uint8_t state)
    {
      sbpEvt_t *pMsg;
    
      // Create dynamic pointer to message.
      if ((pMsg = ICall_malloc(sizeof(sbpEvt_t))))
      {
        pMsg->hdr.event = event;
        pMsg->hdr.state = state;
    
        // Enqueue the message.
        Util_enqueueMsg(appMsgQueue, sem, (uint8*)pMsg);
      }
    }
    
    
    /*********************************************************************
    *********************************************************************/
    

    // If RTOS queue is not empty, process app message.

         while (!Queue_empty(appMsgQueue))

         {

        sbpEvt_t *pMsg = (sbpEvt_t *)Util_dequeueMsg(appMsgQueue);

           if (pMsg)

           {

             // Process message.

             SimpleBLEPeripheral_processAppMsg(pMsg);

             // Free the space from the message.

             ICall_free(pMsg);

           }

         }

  • I am trying to add more detail to what happens when debugging.

    rx_buf is a global variable which takes on the UART_read byte value. I am not

    seeing this track the read data. The scope is displaying the first two bytes from the

    readCallback function correctly.

    The program reaches the breakpoint at Util_enqueueMsg. I put a breakpoint inside

    util.c which never gets executed.

    A screen shot is pasted from the very last point executed. The disassembly is showing

    assembly code at address 0x1001bbd6 or 0x1001bbd8.

    Thanks,

    Priya

  • Hi Priya,

    Please explain why you have while(true); within the UART_initialize() function.
  • Sean-- Thank you for your reply. I kept the while(true) there because it was part of the code that came with the UARTCC26XX.h file reference. I now realize it may have caused the RTOS to do nothing but execute this part of the code indefinitely.

    When I commented it out, the message is getting successfully put in the queue. However, the UART_EVT is still not triggering. I pruned the read call back function to simply echo what the UART read and call the enqueuer function. The rx_buf or tx_buf variables that are keeping track of the UART data aren't retaining the byte value. They are static globals in SPB.c.

    Thanks,

    Priya

    static void readCallback(UART_Handle uart, void *rx_buf, size_t size)
    {
     uint8_t byte = 0x64;

        tx_buf = *((uint8_t*) rx_buf);

        UART_write(uart, &tx_buf, size);
    //    UART_write(uart, &byte, 1);
    //    UART_read(uart, &rx_buf, size);

        UART_enqueueMsg();
    }

    static void UART_initialize(void)
    {
     UART_Params uartParams;

        UART_Handle uart;

     /* Create a UART with data processing off. */
     UART_Params_init(&uartParams);
     uartParams.writeDataMode = UART_DATA_BINARY;
     uartParams.readDataMode = UART_DATA_BINARY;
     uartParams.readReturnMode = UART_RETURN_FULL;
     uartParams.readMode = UART_MODE_CALLBACK;
     uartParams.baudRate = 9600;
     uartParams.readCallback = readCallback;

     uart = UART_open(Board_UART, &uartParams);

      if (uart == NULL) {
       System_abort("Error opening the UART");
      }

        UART_read(uart, &rx_buf, sizeof (rx_buf));


    //    while(true);

    }

  • I had UART handle declared locally and globally. The scope is showing meaningful output now.
    The process UART function is definitely being called. At the input I have only one byte message
    coming in at this time, we'll work on making that a more complex message and I will be back
    at that time. I hope unseen issues won't show up. I appreciate the ton of help, thanks!
    Priya
  • Priya,

    I am posting your latest comment from your new thread here for clarity:

    "Hi,

    I was able to read a chunk of bytes in UART read call back mode and process the message from

    the RTOS task queue inside SimpleBLEPeripheral.

    Now I want to repeat this UART read every 10 ms. I assume I need a second UART event that

    is periodic that performs a UART read every 10 ms? If defined as a unique event will this take

    care of not stepping on the timing of the rest of the tasks in SBP? If not, let me know of the

    correct way to accomplish this."


    I guess my question would be why do you need to read data every 10s? What is your planned communication scheme? Do you have a known frame format that you plan to exchange between devices? The reason I ask is because it would be best to trigger a UART read and wait on the the call back. When you remote device sends its data the UART_EVT will be triggered and SBP can process as needed.
  • Yes, there is a known format to exchange messages. Currently, each received message is 5 bytes in length. There are 5-7 different types of received messages which require different kinds of CC2640 processing. During sensor calibration, receive messages can take a while to come, they may not always happen every 100ms. The UART read periodicity can be made slower if needed.

    It was not very clear how the UART read call back works. I assume the hwi will trigger with each UART read and so there should be 5-7 UART reads. Or does the Hwi trigger whenever a new frame arrives? In this case can one UART read be enough? What happens if the rx UART buffer fills up? There was a while(true) statement in the read call back. Should this task sleep for a while and go back to executing?

    I marked this thread as answered because it answered my original question. What I am asking now is a another part. Should I mark this thread unanswered again?

    I did try a initial draft of periodic UART reads. The periodic UART event did not trigger.

    Thanks,
    Priya
  • Sean-- the UART messages arrive asynchronously. We still need to be able to read new UART messages as they arrive.
    When to do this? Currently, the first (and only) UART read triggered an Hwi and the receive message was processed
    through the RTOS queue.
    Thanks,
    Priya
  • Sean-- repeated UART reads are now working! I just had the process UART task sleep for a while and the read the uart again. This way all UART reads get processed through the RTOS queue. Thanks! Priya