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.

CC2640R2F: OAD operation with error

Part Number: CC2640R2F
Other Parts Discussed in Thread: CC2640

Hello everyone,

I want to implement the OAD off-chip into my project. For this, I am using the sample simple_peripheral_oad_offchip. I also use the android https://git.ti.com/simplelink-ble-oad-android sample for performing the update.
The update happens with NO error when the sample project is with no changes. However, when I change the simple_gatt_profile the update fails.

In terminal the following message is showed: 

GAPRole Initialized
FC Violated: 16

In simple_gatt_profile, I remove all characteristics from sample and adding 33 new characteristics. The SIMPLEPROFILE_SERV_UUID is changed from 0xFFF0 to 0xFED0.

Anyone can help me?

Thanks in advance. 

  • Hi,
    How did you update simple_gatt_profile?

    Did you follow the methodology described in dev.ti.com/.../ble_01_custom_profile.html
  • Yes, I followed the methodology described in the link.

    I see all the 33 characteristics in BLE Scanner and them worked normally in my project when it was with no OAD operation.

    Regards.

  • I see. Some follow up questions;

    So you mean that if you flash your project onto the device, it operates as intended?
    How do you download the new image? (What tool)
    Where in the process does it fail?
  • Yes, it operates as expected. I see all characteristics in BLE Scanner.
    I download the new image with Android App Demo. The process fails when in message "TI EOAD Client waiting for MTU update". After this message the app show me "TI EOAD Client disconnected after successful programming" but the image was not uploaded to server.

    I think can be something related with simpleProfileAttrTbl, because when I decrease the size of it to 53 for example, the OAD process works successful, but when I increase the simpleProfileAttrTbl to 103 ( My 33 characteristics need from this size) the OAD process fail as described above.

    Regards, Arubu
  • Hi Arubu,
    Are you able to sniff the connection and see if any data is sent? The OAD transfer should not be impacted by the content of the binary image unless it's related to size constraints.
  • Hi..

    Well, I never sniff the connection before. Have you a tutorial? Can the sniffer be performed with CC2640R2F launchpad?

    Do not matter the content of the binary image which will be transfer by distributor. The problem like described in previous message is in the program running on target.

    Regards.
  • Hi Aruba,
    What exactly is running on the target? Could you please provide full details?

    We have a packet sniffer (www.ti.com/.../PACKET-SNIFFER-2 for CC2640R2, although we have not added BLE support just yet.

  • Hi 

    On target is running the simple_peripheral_oad_offchip sample with update in simple_profile.

    The link to packet is off. However it is not useful for me. 

  • Hi Aruba,

    I fixed the link (for future reference once the BLE support is available).

    Just to make sure I understand the case now;

    1. You flash the device with simple_peripheral_oad_offchip sample with update in simple_profile
    2. You can successfully OAD an image with reduced set of charecteristics (53)
    3. You cannot successfully OAD an image with a larger set of charecteristics (103)

    If this is the case, whats the image size of the different images. Have you follow the OAD guide

  • No, there are two differents cases.

    1. I flash the device with simple_peripheral_oad_offchip sample with update in simple_profile. The simple_profile has reduced set of charecteristics (53).
    2. I can successfully OAD any image.

    ----------------
    1. I flash the device with simple_peripheral_oad_offchip sample with update in simple_profile. The simple_profile has a larger set of charecteristics (103).
    2. I cannot successfully OAD any image.

    Thank you for your support.
    Best regards.
  • Hi Arubu,
    Thanks for the clarification. Sounds like there is either something wrong with how you add the characteristics. Some follow-up questions to narrow down further;

    1. Are you able to perform the service discovery correctly?
    2. Do you have characteristics larger than 20 Bytes.
    3. Have you tried running the OAD Distribution from an CC2640R2 Launchpad instead? I would like to know if the issue might be related to the Android App.

    Feel free to post your custom service here for review.

    Also, I have some great news. The latest version of the packet sniffer actually supports Bluetooth low energy on CC2640R2;

    http://www.ti.com/tool/download/PACKET-SNIFFER-2

  • Hi Joakim,

    1. Yes, I see all service with BLE Scanner app.

    2. No, the larger characteristic has 19 bytes.

    3. Yes, with the image host_test in CC2640 Launchpad. Please, see the log in attached file.

    ---------------------------------------------------------------

    [26] : <Info> - 08:45:41.586
    Device Connected
    Handle = 0x0000
    Addr Type = 0x00 (ADDRTYPE_PUBLIC)
    BDAddr = B0:91:22:69:F1:79
    --------------------------------------------------------------------
    [27] : <Info> - 08:46:06.558
    OAD - Update Connection Settings
    --------------------------------------------------------------------
    [28] : <Info> - 08:46:06.628
    Start OAD Download
    --------------------------------------------------------------------
    [29] : <Info> - 08:46:06.641
    StartReset Service Discovery
    --------------------------------------------------------------------
    [30] : <Info> - 08:46:06.645
    OAD Send UUID Discovery
    --------------------------------------------------------------------
    [31] : <Tx> - 08:46:06.564
    -Type           : 0x01 (Command)
    -OpCode         : 0x2016 (HCI_LEReadRemoteUsedFeatures)
    -Data Length    : 0x02 (2) byte(s)
     Handle         : 0x0000 (0)
    Dump(Tx):
    0000:01 16 20 02 00 00                               .. ...
    --------------------------------------------------------------------
    [32] : <Tx> - 08:46:06.651
    -Type           : 0x01 (Command)
    -OpCode         : 0xFD86 (GATT_DiscPrimaryServiceByUUID)
    -Data Length    : 0x12 (18) byte(s)
     ConnHandle     : 0x0000 (0)
     Value          : 00:00:00:00:00:00:00:B0:00:40:51:04:D0:FF:00:F0
    Dump(Tx):
    0000:01 86 FD 12 00 00 00 00 00 00 00 00 00 B0 00 40 ...............@
    0010:51 04 D0 FF 00 F0                               Q.....
    --------------------------------------------------------------------
    [33] : <Rx> - 08:46:06.699
    -Type           : 0x04 (Event)
    -EventCode      : 0x00FF (HCI_LE_ExtEvent)
    -Data Length    : 0x06 (6) bytes(s)
     Event          : 0x067F (1663) (GAP_HCI_ExtentionCommandStatus)
     Status         : 0x00 (0) (SUCCESS)
     OpCode         : 0xFD86 (GATT_DiscPrimaryServiceByUUID)
     DataLength     : 0x00 (0)
    Dump(Rx):
    0000:04 FF 06 7F 06 00 86 FD 00                      .........
    --------------------------------------------------------------------
    [34] : <Rx> - 08:46:06.925
    -Type           : 0x04 (Event)
    -EventCode      : 0x003E (HCI_LE_GenericReportEvent)
    -Data Length    : 0x0C (12) bytes(s)
     LE Event Code  : 0x04 (4) (HCI_LE_ReadRemoteUsedFeaturesCompleteEvent)
     LE Event Code  : 0x04 (4) (HCI_LE_ReadRemoteUsedFeaturesCompleteEvent)
     Status         : 0x00 (0) (SUCCESS)
     ConnectionId   : 0x0000 (0)
     Features       : 0x00000000000000FD (253) (
                      Encryption
                      Reject_Extended_Indication
                      Slave_Features_Exchange
                      Ping
                      Data_Packet_Length_Extension
                      Privacy
                      Extended_Scanner_Filter_Policies)
    Dump(Rx):
    0000:04 3E 0C 04 00 00 00 FD 00 00 00 00 00 00 00    .>.............
    --------------------------------------------------------------------
    [35] : <Rx> - 08:46:36.687
    -Type           : 0x04 (Event)
    -EventCode      : 0x00FF (HCI_LE_ExtEvent)
    -Data Length    : 0x06 (6) bytes(s)
     Event          : 0x0507 (1287) (ATT_FindByTypeValueRsp)
     Status         : 0x17 (23) (bleTimeout)
     ConnHandle     : 0x0000 (0)
     PduLen         : 0x00 (0)
    Dump(Rx):
    0000:04 FF 06 07 05 17 00 00 00                      .........
    --------------------------------------------------------------------
    [36] : <Info> - 08:46:36.696
    OAD - Restore Connection Settings
    --------------------------------------------------------------------
    [37] : <Error> - 08:46:36.696
    OAD Download Not Successful
    

    I noticed another problem. When I add other task with Event_pend the problem occurs again. The new task has priority 1 and the SimplePeripheral_task has priority 2.
    Can be memory boundary problem?

    Thank you.

  • In order to test the new task, I keep just one characteristic in simple_profile.
    The MTU is updated but the transfer fails with ERROR - > DEFAULT SPINLOCK!
  • I am using the CC2640 LaunchPad as distribuitor and the error above stop, but when I try to perform a OAD transfer it fails.

    OAD Send Start OAD To ImageControl
    After message above the distribuitor tries to send the first package but it does not receive the notification for sending the second package.

    This problem happens just when a larger image is flashed into device.
  • Hi Joakim,

    Sorry my messages abuse. You can simulate the problem of the my last post with the steps below:

    1. Import  the simple_peripheral_oad_offchip sample.

    2. Update the simple_gatt_profile.c and simple_gatt_profile.h with the following files

    /******************************************************************************
    
     @file  simple_gatt_profile.c
    
     @brief This file contains the Simple GATT profile sample GATT service profile
            for use with the BLE sample application.
    
     Group: WCS, BTS
     Target Device: cc2640r2
    
     ******************************************************************************
     
     Copyright (c) 2010-2019, Texas Instruments Incorporated
     All rights reserved.
    
     Redistribution and use in source and binary forms, with or without
     modification, are permitted provided that the following conditions
     are met:
    
     *  Redistributions of source code must retain the above copyright
        notice, this list of conditions and the following disclaimer.
    
     *  Redistributions in binary form must reproduce the above copyright
        notice, this list of conditions and the following disclaimer in the
        documentation and/or other materials provided with the distribution.
    
     *  Neither the name of Texas Instruments Incorporated nor the names of
        its contributors may be used to endorse or promote products derived
        from this software without specific prior written permission.
    
     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    
     ******************************************************************************
     
     
     *****************************************************************************/
    
    /*********************************************************************
     * INCLUDES
     */
    #include <string.h>
    #include <icall.h>
    #include "util.h"
    /* This Header file contains all BLE API and icall structure definition */
    #include "icall_ble_api.h"
    
    #include "simple_gatt_profile.h"
    
    /*********************************************************************
     * MACROS
     */
    
    /*********************************************************************
     * CONSTANTS
     */
    
    #define SERVAPP_NUM_ATTR_SUPPORTED        47
    
    /*********************************************************************
     * TYPEDEFS
     */
    
    /*********************************************************************
     * GLOBAL VARIABLES
     */
    // Simple GATT Profile Service UUID: 0xFFF0
    CONST uint8 simpleProfileServUUID[ATT_BT_UUID_SIZE] =
    {
      LO_UINT16(SIMPLEPROFILE_SERV_UUID), HI_UINT16(SIMPLEPROFILE_SERV_UUID)
    };
    
    // Characteristic 1 UUID: 0xFFF1
    CONST uint8 simpleProfilechar1UUID[ATT_BT_UUID_SIZE] =
    {
      LO_UINT16(SIMPLEPROFILE_CHAR1_UUID), HI_UINT16(SIMPLEPROFILE_CHAR1_UUID)
    };
    
    // Characteristic 2 UUID: 0xFFF2
    CONST uint8 simpleProfilechar2UUID[ATT_BT_UUID_SIZE] =
    {
      LO_UINT16(SIMPLEPROFILE_CHAR2_UUID), HI_UINT16(SIMPLEPROFILE_CHAR2_UUID)
    };
    
    // Characteristic 3 UUID: 0xFFF3
    CONST uint8 simpleProfilechar3UUID[ATT_BT_UUID_SIZE] =
    {
      LO_UINT16(SIMPLEPROFILE_CHAR3_UUID), HI_UINT16(SIMPLEPROFILE_CHAR3_UUID)
    };
    
    // Characteristic 4 UUID: 0xFFF4
    CONST uint8 simpleProfilechar4UUID[ATT_BT_UUID_SIZE] =
    {
      LO_UINT16(SIMPLEPROFILE_CHAR4_UUID), HI_UINT16(SIMPLEPROFILE_CHAR4_UUID)
    };
    
    // Characteristic 5 UUID: 0xFFF5
    CONST uint8 simpleProfilechar5UUID[ATT_BT_UUID_SIZE] =
    {
      LO_UINT16(SIMPLEPROFILE_CHAR5_UUID), HI_UINT16(SIMPLEPROFILE_CHAR5_UUID)
    };
    
    CONST uint8 simpleProfilechar6UUID[ATT_BT_UUID_SIZE] =
    {
      LO_UINT16(SIMPLEPROFILE_CHAR6_UUID), HI_UINT16(SIMPLEPROFILE_CHAR6_UUID)
    };
    
    CONST uint8 simpleProfilechar7UUID[ATT_BT_UUID_SIZE] =
    {
      LO_UINT16(SIMPLEPROFILE_CHAR7_UUID), HI_UINT16(SIMPLEPROFILE_CHAR7_UUID)
    };
    
    CONST uint8 simpleProfilechar8UUID[ATT_BT_UUID_SIZE] =
    {
      LO_UINT16(SIMPLEPROFILE_CHAR8_UUID), HI_UINT16(SIMPLEPROFILE_CHAR8_UUID)
    };
    
    CONST uint8 simpleProfilechar9UUID[ATT_BT_UUID_SIZE] =
    {
      LO_UINT16(SIMPLEPROFILE_CHAR9_UUID), HI_UINT16(SIMPLEPROFILE_CHAR9_UUID)
    };
    
    CONST uint8 simpleProfilecharAUUID[ATT_BT_UUID_SIZE] =
    {
      LO_UINT16(SIMPLEPROFILE_CHARA_UUID), HI_UINT16(SIMPLEPROFILE_CHARA_UUID)
    };
    
    CONST uint8 simpleProfilecharBUUID[ATT_BT_UUID_SIZE] =
    {
      LO_UINT16(SIMPLEPROFILE_CHARB_UUID), HI_UINT16(SIMPLEPROFILE_CHARB_UUID)
    };
    
    CONST uint8 simpleProfilecharCUUID[ATT_BT_UUID_SIZE] =
    {
      LO_UINT16(SIMPLEPROFILE_CHARC_UUID), HI_UINT16(SIMPLEPROFILE_CHARC_UUID)
    };
    
    CONST uint8 simpleProfilecharDUUID[ATT_BT_UUID_SIZE] =
    {
      LO_UINT16(SIMPLEPROFILE_CHARD_UUID), HI_UINT16(SIMPLEPROFILE_CHARD_UUID)
    };
    
    CONST uint8 simpleProfilecharEUUID[ATT_BT_UUID_SIZE] =
    {
      LO_UINT16(SIMPLEPROFILE_CHARE_UUID), HI_UINT16(SIMPLEPROFILE_CHARE_UUID)
    };
    
    CONST uint8 simpleProfilecharFUUID[ATT_BT_UUID_SIZE] =
    {
      LO_UINT16(SIMPLEPROFILE_CHARF_UUID), HI_UINT16(SIMPLEPROFILE_CHARF_UUID)
    };
    
    /*********************************************************************
     * EXTERNAL VARIABLES
     */
    
    /*********************************************************************
     * EXTERNAL FUNCTIONS
     */
    
    /*********************************************************************
     * LOCAL VARIABLES
     */
    
    static simpleProfileCBs_t *simpleProfile_AppCBs = NULL;
    
    /*********************************************************************
     * Profile Attributes - variables
     */
    
    // Simple Profile Service attribute
    static CONST gattAttrType_t simpleProfileService = { ATT_BT_UUID_SIZE, simpleProfileServUUID };
    
    
    // Simple Profile Characteristic 1 Properties
    static uint8 simpleProfileChar1Props = GATT_PROP_READ | GATT_PROP_WRITE;
    
    // Characteristic 1 Value
    static uint8 simpleProfileChar1 = 0;
    
    // Simple Profile Characteristic 1 User Description
    static uint8 simpleProfileChar1UserDesp[17] = "Characteristic 1";
    
    
    // Simple Profile Characteristic 2 Properties
    static uint8 simpleProfileChar2Props = GATT_PROP_READ;
    
    // Characteristic 2 Value
    static uint8 simpleProfileChar2 = 0;
    
    // Simple Profile Characteristic 2 User Description
    static uint8 simpleProfileChar2UserDesp[17] = "Characteristic 2";
    
    
    // Simple Profile Characteristic 3 Properties
    static uint8 simpleProfileChar3Props = GATT_PROP_WRITE;
    
    // Characteristic 3 Value
    static uint8 simpleProfileChar3 = 0;
    
    // Simple Profile Characteristic 3 User Description
    static uint8 simpleProfileChar3UserDesp[17] = "Characteristic 3";
    
    
    // Simple Profile Characteristic 4 Properties
    static uint8 simpleProfileChar4Props = GATT_PROP_NOTIFY;
    
    // Characteristic 4 Value
    static uint8 simpleProfileChar4 = 0;
    
    // Simple Profile Characteristic 4 Configuration Each client has its own
    // instantiation of the Client Characteristic Configuration. Reads of the
    // Client Characteristic Configuration only shows the configuration for
    // that client and writes only affect the configuration of that client.
    static gattCharCfg_t *simpleProfileChar4Config;
    
    // Simple Profile Characteristic 4 User Description
    static uint8 simpleProfileChar4UserDesp[17] = "Characteristic 4";
    
    
    // Simple Profile Characteristic 5 Properties
    static uint8 simpleProfileChar5Props = GATT_PROP_READ;
    
    // Characteristic 5 Value
    static uint8 simpleProfileChar5[SIMPLEPROFILE_CHAR5_LEN] = { 0, 0, 0, 0, 0 };
    
    // Simple Profile Characteristic 5 User Description
    static uint8 simpleProfileChar5UserDesp[17] = "Characteristic 5";
    
    
    static uint8 simpleProfileChar6Props = GATT_PROP_READ;
    static uint8 simpleProfileChar6[SIMPLEPROFILE_CHAR_CUSTOM_LEN] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
    static uint8 simpleProfileChar6UserDesp[17] = "Characteristic 6";
    
    static uint8 simpleProfileChar7Props = GATT_PROP_READ;
    static uint8 simpleProfileChar7[SIMPLEPROFILE_CHAR_CUSTOM_LEN] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
    static uint8 simpleProfileChar7UserDesp[17] = "Characteristic 7";
    
    static uint8 simpleProfileChar8Props = GATT_PROP_READ;
    static uint8 simpleProfileChar8[SIMPLEPROFILE_CHAR_CUSTOM_LEN] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
    static uint8 simpleProfileChar8UserDesp[17] = "Characteristic 8";
    
    static uint8 simpleProfileChar9Props = GATT_PROP_READ;
    static uint8 simpleProfileChar9[SIMPLEPROFILE_CHAR_CUSTOM_LEN] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
    static uint8 simpleProfileChar9UserDesp[17] = "Characteristic 9";
    
    static uint8 simpleProfileCharAProps = GATT_PROP_READ;
    static uint8 simpleProfileCharA[SIMPLEPROFILE_CHAR_CUSTOM_LEN] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
    static uint8 simpleProfileCharAUserDesp[17] = "Characteristic A";
    
    static uint8 simpleProfileCharBProps = GATT_PROP_READ;
    static uint8 simpleProfileCharB[SIMPLEPROFILE_CHAR_CUSTOM_LEN] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
    static uint8 simpleProfileCharBUserDesp[17] = "Characteristic B";
    
    static uint8 simpleProfileCharCProps = GATT_PROP_READ;
    static uint8 simpleProfileCharC[SIMPLEPROFILE_CHAR_CUSTOM_LEN] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
    static uint8 simpleProfileCharCUserDesp[17] = "Characteristic C";
    
    static uint8 simpleProfileCharDProps = GATT_PROP_READ;
    static uint8 simpleProfileCharD[SIMPLEPROFILE_CHAR_CUSTOM_LEN] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
    static uint8 simpleProfileCharDUserDesp[17] = "Characteristic D";
    
    static uint8 simpleProfileCharEProps = GATT_PROP_READ;
    static uint8 simpleProfileCharE[SIMPLEPROFILE_CHAR_CUSTOM_LEN] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
    static uint8 simpleProfileCharEUserDesp[17] = "Characteristic E";
    
    static uint8 simpleProfileCharFProps = GATT_PROP_READ;
    static uint8 simpleProfileCharF[SIMPLEPROFILE_CHAR_CUSTOM_LEN] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
    static uint8 simpleProfileCharFUserDesp[17] = "Characteristic F";
    
    /*********************************************************************
     * Profile Attributes - Table
     */
    
    static gattAttribute_t simpleProfileAttrTbl[SERVAPP_NUM_ATTR_SUPPORTED] =
    {
      // Simple Profile Service
      {
        { ATT_BT_UUID_SIZE, primaryServiceUUID }, /* type */
        GATT_PERMIT_READ,                         /* permissions */
        0,                                        /* handle */
        (uint8 *)&simpleProfileService            /* pValue */
      },
    
        // Characteristic 1 Declaration
        {
          { ATT_BT_UUID_SIZE, characterUUID },
          GATT_PERMIT_READ,
          0,
          &simpleProfileChar1Props
        },
    
          // Characteristic Value 1
          {
            { ATT_BT_UUID_SIZE, simpleProfilechar1UUID },
            GATT_PERMIT_READ | GATT_PERMIT_WRITE,
            0,
            &simpleProfileChar1
          },
    
          // Characteristic 1 User Description
          {
            { ATT_BT_UUID_SIZE, charUserDescUUID },
            GATT_PERMIT_READ,
            0,
            simpleProfileChar1UserDesp
          },
    
        // Characteristic 2 Declaration
        {
          { ATT_BT_UUID_SIZE, characterUUID },
          GATT_PERMIT_READ,
          0,
          &simpleProfileChar2Props
        },
    
          // Characteristic Value 2
          {
            { ATT_BT_UUID_SIZE, simpleProfilechar2UUID },
            GATT_PERMIT_READ,
            0,
            &simpleProfileChar2
          },
    
          // Characteristic 2 User Description
          {
            { ATT_BT_UUID_SIZE, charUserDescUUID },
            GATT_PERMIT_READ,
            0,
            simpleProfileChar2UserDesp
          },
    
        // Characteristic 3 Declaration
        {
          { ATT_BT_UUID_SIZE, characterUUID },
          GATT_PERMIT_READ,
          0,
          &simpleProfileChar3Props
        },
    
          // Characteristic Value 3
          {
            { ATT_BT_UUID_SIZE, simpleProfilechar3UUID },
            GATT_PERMIT_WRITE,
            0,
            &simpleProfileChar3
          },
    
          // Characteristic 3 User Description
          {
            { ATT_BT_UUID_SIZE, charUserDescUUID },
            GATT_PERMIT_READ,
            0,
            simpleProfileChar3UserDesp
          },
    
        // Characteristic 4 Declaration
        {
          { ATT_BT_UUID_SIZE, characterUUID },
          GATT_PERMIT_READ,
          0,
          &simpleProfileChar4Props
        },
    
          // Characteristic Value 4
          {
            { ATT_BT_UUID_SIZE, simpleProfilechar4UUID },
            0,
            0,
            &simpleProfileChar4
          },
    
          // Characteristic 4 configuration
          {
            { ATT_BT_UUID_SIZE, clientCharCfgUUID },
            GATT_PERMIT_READ | GATT_PERMIT_WRITE,
            0,
            (uint8 *)&simpleProfileChar4Config
          },
    
          // Characteristic 4 User Description
          {
            { ATT_BT_UUID_SIZE, charUserDescUUID },
            GATT_PERMIT_READ,
            0,
            simpleProfileChar4UserDesp
          },
    
        // Characteristic 5 Declaration
        {
          { ATT_BT_UUID_SIZE, characterUUID },
          GATT_PERMIT_READ,
          0,
          &simpleProfileChar5Props
        },
    
          // Characteristic Value 5
          {
            { ATT_BT_UUID_SIZE, simpleProfilechar5UUID },
            GATT_PERMIT_AUTHEN_READ,
            0,
            simpleProfileChar5
          },
    
          // Characteristic 5 User Description
          {
            { ATT_BT_UUID_SIZE, charUserDescUUID },
            GATT_PERMIT_READ,
            0,
            simpleProfileChar5UserDesp
          },
    
      //////////////////////////////////////////////////////////////
      {
        { ATT_BT_UUID_SIZE, characterUUID },
        GATT_PERMIT_READ,
        0,
        &simpleProfileChar6Props
      },
    
        {
          { ATT_BT_UUID_SIZE, simpleProfilechar6UUID },
          GATT_PERMIT_AUTHEN_READ,
          0,
          simpleProfileChar6
        },
    
        {
          { ATT_BT_UUID_SIZE, charUserDescUUID },
          GATT_PERMIT_READ,
          0,
          simpleProfileChar6UserDesp
        },
    
        //////////////////////////////////////////////////////////////
        {
          { ATT_BT_UUID_SIZE, characterUUID },
          GATT_PERMIT_READ,
          0,
          &simpleProfileChar7Props
        },
    
          {
            { ATT_BT_UUID_SIZE, simpleProfilechar7UUID },
            GATT_PERMIT_AUTHEN_READ,
            0,
            simpleProfileChar7
          },
    
          {
            { ATT_BT_UUID_SIZE, charUserDescUUID },
            GATT_PERMIT_READ,
            0,
            simpleProfileChar7UserDesp
          },
    
      //////////////////////////////////////////////////////////////
      {
        { ATT_BT_UUID_SIZE, characterUUID },
        GATT_PERMIT_READ,
        0,
        &simpleProfileChar8Props
      },
    
        {
          { ATT_BT_UUID_SIZE, simpleProfilechar8UUID },
          GATT_PERMIT_AUTHEN_READ,
          0,
          simpleProfileChar8
        },
    
        {
          { ATT_BT_UUID_SIZE, charUserDescUUID },
          GATT_PERMIT_READ,
          0,
          simpleProfileChar8UserDesp
        },
    
        //////////////////////////////////////////////////////////////
        {
          { ATT_BT_UUID_SIZE, characterUUID },
          GATT_PERMIT_READ,
          0,
          &simpleProfileChar9Props
        },
    
          {
            { ATT_BT_UUID_SIZE, simpleProfilechar9UUID },
            GATT_PERMIT_AUTHEN_READ,
            0,
            simpleProfileChar9
          },
    
          {
            { ATT_BT_UUID_SIZE, charUserDescUUID },
            GATT_PERMIT_READ,
            0,
            simpleProfileChar9UserDesp
          },
    
          //////////////////////////////////////////////////////////////
          {
            { ATT_BT_UUID_SIZE, characterUUID },
            GATT_PERMIT_READ,
            0,
            &simpleProfileCharAProps
          },
    
            {
              { ATT_BT_UUID_SIZE, simpleProfilecharAUUID },
              GATT_PERMIT_AUTHEN_READ,
              0,
              simpleProfileCharA
            },
    
            {
              { ATT_BT_UUID_SIZE, charUserDescUUID },
              GATT_PERMIT_READ,
              0,
              simpleProfileCharAUserDesp
            },
    
        //////////////////////////////////////////////////////////////
        {
          { ATT_BT_UUID_SIZE, characterUUID },
          GATT_PERMIT_READ,
          0,
          &simpleProfileCharBProps
        },
    
          {
            { ATT_BT_UUID_SIZE, simpleProfilecharBUUID },
            GATT_PERMIT_AUTHEN_READ,
            0,
            simpleProfileCharB
          },
    
          {
            { ATT_BT_UUID_SIZE, charUserDescUUID },
            GATT_PERMIT_READ,
            0,
            simpleProfileCharBUserDesp
          },
    
          //////////////////////////////////////////////////////////////
          {
            { ATT_BT_UUID_SIZE, characterUUID },
            GATT_PERMIT_READ,
            0,
            &simpleProfileCharCProps
          },
    
            {
              { ATT_BT_UUID_SIZE, simpleProfilecharCUUID },
              GATT_PERMIT_AUTHEN_READ,
              0,
              simpleProfileCharC
            },
    
            {
              { ATT_BT_UUID_SIZE, charUserDescUUID },
              GATT_PERMIT_READ,
              0,
              simpleProfileCharCUserDesp
            },
    
        //////////////////////////////////////////////////////////////
        {
          { ATT_BT_UUID_SIZE, characterUUID },
          GATT_PERMIT_READ,
          0,
          &simpleProfileCharDProps
        },
    
          {
            { ATT_BT_UUID_SIZE, simpleProfilecharDUUID },
            GATT_PERMIT_AUTHEN_READ,
            0,
            simpleProfileCharD
          },
    
          {
            { ATT_BT_UUID_SIZE, charUserDescUUID },
            GATT_PERMIT_READ,
            0,
            simpleProfileCharDUserDesp
          },
    
          //////////////////////////////////////////////////////////////
          {
            { ATT_BT_UUID_SIZE, characterUUID },
            GATT_PERMIT_READ,
            0,
            &simpleProfileCharEProps
          },
    
            {
              { ATT_BT_UUID_SIZE, simpleProfilecharEUUID },
              GATT_PERMIT_AUTHEN_READ,
              0,
              simpleProfileCharE
            },
    
            {
              { ATT_BT_UUID_SIZE, charUserDescUUID },
              GATT_PERMIT_READ,
              0,
              simpleProfileCharEUserDesp
            },
    
        //////////////////////////////////////////////////////////////
        {
          { ATT_BT_UUID_SIZE, characterUUID },
          GATT_PERMIT_READ,
          0,
          &simpleProfileCharFProps
        },
    
          {
            { ATT_BT_UUID_SIZE, simpleProfilecharFUUID },
            GATT_PERMIT_AUTHEN_READ,
            0,
            simpleProfileCharF
          },
    
          {
            { ATT_BT_UUID_SIZE, charUserDescUUID },
            GATT_PERMIT_READ,
            0,
            simpleProfileCharFUserDesp
          },
    
    };
    
    /*********************************************************************
     * LOCAL FUNCTIONS
     */
    static bStatus_t simpleProfile_ReadAttrCB(uint16_t connHandle,
                                              gattAttribute_t *pAttr,
                                              uint8_t *pValue, uint16_t *pLen,
                                              uint16_t offset, uint16_t maxLen,
                                              uint8_t method);
    static bStatus_t simpleProfile_WriteAttrCB(uint16_t connHandle,
                                               gattAttribute_t *pAttr,
                                               uint8_t *pValue, uint16_t len,
                                               uint16_t offset, uint8_t method);
    
    /*********************************************************************
     * PROFILE CALLBACKS
     */
    
    // Simple Profile Service Callbacks
    // Note: When an operation on a characteristic requires authorization and
    // pfnAuthorizeAttrCB is not defined for that characteristic's service, the
    // Stack will report a status of ATT_ERR_UNLIKELY to the client.  When an
    // operation on a characteristic requires authorization the Stack will call
    // pfnAuthorizeAttrCB to check a client's authorization prior to calling
    // pfnReadAttrCB or pfnWriteAttrCB, so no checks for authorization need to be
    // made within these functions.
    CONST gattServiceCBs_t simpleProfileCBs =
    {
      simpleProfile_ReadAttrCB,  // Read callback function pointer
      simpleProfile_WriteAttrCB, // Write callback function pointer
      NULL                       // Authorization callback function pointer
    };
    
    /*********************************************************************
     * PUBLIC FUNCTIONS
     */
    
    /*********************************************************************
     * @fn      SimpleProfile_AddService
     *
     * @brief   Initializes the Simple Profile service by registering
     *          GATT attributes with the GATT server.
     *
     * @param   services - services to add. This is a bit map and can
     *                     contain more than one service.
     *
     * @return  Success or Failure
     */
    bStatus_t SimpleProfile_AddService( uint32 services )
    {
      uint8 status;
    
      // Allocate Client Characteristic Configuration table
      simpleProfileChar4Config = (gattCharCfg_t *)ICall_malloc( sizeof(gattCharCfg_t) *
                                                                linkDBNumConns );
      if ( simpleProfileChar4Config == NULL )
      {
        return ( bleMemAllocError );
      }
    
      // Initialize Client Characteristic Configuration attributes
      GATTServApp_InitCharCfg( INVALID_CONNHANDLE, simpleProfileChar4Config );
    
      if ( services & SIMPLEPROFILE_SERVICE )
      {
        // Register GATT attribute list and CBs with GATT Server App
        status = GATTServApp_RegisterService( simpleProfileAttrTbl,
                                              GATT_NUM_ATTRS( simpleProfileAttrTbl ),
                                              GATT_MAX_ENCRYPT_KEY_SIZE,
                                              &simpleProfileCBs );
      }
      else
      {
        status = SUCCESS;
      }
    
      return ( status );
    }
    
    /*********************************************************************
     * @fn      SimpleProfile_RegisterAppCBs
     *
     * @brief   Registers the application callback function. Only call
     *          this function once.
     *
     * @param   callbacks - pointer to application callbacks.
     *
     * @return  SUCCESS or bleAlreadyInRequestedMode
     */
    bStatus_t SimpleProfile_RegisterAppCBs( simpleProfileCBs_t *appCallbacks )
    {
      if ( appCallbacks )
      {
        simpleProfile_AppCBs = appCallbacks;
    
        return ( SUCCESS );
      }
      else
      {
        return ( bleAlreadyInRequestedMode );
      }
    }
    
    /*********************************************************************
     * @fn      SimpleProfile_SetParameter
     *
     * @brief   Set a Simple Profile parameter.
     *
     * @param   param - Profile parameter ID
     * @param   len - length of data to write
     * @param   value - pointer to data to write.  This is dependent on
     *          the parameter ID and WILL be cast to the appropriate
     *          data type (example: data type of uint16 will be cast to
     *          uint16 pointer).
     *
     * @return  bStatus_t
     */
    bStatus_t SimpleProfile_SetParameter( uint8 param, uint8 len, void *value )
    {
      bStatus_t ret = SUCCESS;
      switch ( param )
      {
        case SIMPLEPROFILE_CHAR1:
          if ( len == sizeof ( uint8 ) )
          {
            simpleProfileChar1 = *((uint8*)value);
          }
          else
          {
            ret = bleInvalidRange;
          }
          break;
    
        case SIMPLEPROFILE_CHAR2:
          if ( len == sizeof ( uint8 ) )
          {
            simpleProfileChar2 = *((uint8*)value);
          }
          else
          {
            ret = bleInvalidRange;
          }
          break;
    
        case SIMPLEPROFILE_CHAR3:
          if ( len == sizeof ( uint8 ) )
          {
            simpleProfileChar3 = *((uint8*)value);
          }
          else
          {
            ret = bleInvalidRange;
          }
          break;
    
        case SIMPLEPROFILE_CHAR4:
          if ( len == sizeof ( uint8 ) )
          {
            simpleProfileChar4 = *((uint8*)value);
    
            // See if Notification has been enabled
            GATTServApp_ProcessCharCfg( simpleProfileChar4Config, &simpleProfileChar4, FALSE,
                                        simpleProfileAttrTbl, GATT_NUM_ATTRS( simpleProfileAttrTbl ),
                                        INVALID_TASK_ID, simpleProfile_ReadAttrCB );
          }
          else
          {
            ret = bleInvalidRange;
          }
          break;
    
        case SIMPLEPROFILE_CHAR5:
          if ( len == SIMPLEPROFILE_CHAR5_LEN )
          {
            VOID memcpy( simpleProfileChar5, value, SIMPLEPROFILE_CHAR5_LEN );
          }
          else
          {
            ret = bleInvalidRange;
          }
          break;
    
        default:
          ret = INVALIDPARAMETER;
          break;
      }
    
      return ( ret );
    }
    
    /*********************************************************************
     * @fn      SimpleProfile_GetParameter
     *
     * @brief   Get a Simple Profile parameter.
     *
     * @param   param - Profile parameter ID
     * @param   value - pointer to data to put.  This is dependent on
     *          the parameter ID and WILL be cast to the appropriate
     *          data type (example: data type of uint16 will be cast to
     *          uint16 pointer).
     *
     * @return  bStatus_t
     */
    bStatus_t SimpleProfile_GetParameter( uint8 param, void *value )
    {
      bStatus_t ret = SUCCESS;
      switch ( param )
      {
        case SIMPLEPROFILE_CHAR1:
          *((uint8*)value) = simpleProfileChar1;
          break;
    
        case SIMPLEPROFILE_CHAR2:
          *((uint8*)value) = simpleProfileChar2;
          break;
    
        case SIMPLEPROFILE_CHAR3:
          *((uint8*)value) = simpleProfileChar3;
          break;
    
        case SIMPLEPROFILE_CHAR4:
          *((uint8*)value) = simpleProfileChar4;
          break;
    
        case SIMPLEPROFILE_CHAR5:
          VOID memcpy( value, simpleProfileChar5, SIMPLEPROFILE_CHAR5_LEN );
          break;
    
        default:
          ret = INVALIDPARAMETER;
          break;
      }
    
      return ( ret );
    }
    
    /*********************************************************************
     * @fn          simpleProfile_ReadAttrCB
     *
     * @brief       Read an attribute.
     *
     * @param       connHandle - connection message was received on
     * @param       pAttr - pointer to attribute
     * @param       pValue - pointer to data to be read
     * @param       pLen - length of data to be read
     * @param       offset - offset of the first octet to be read
     * @param       maxLen - maximum length of data to be read
     * @param       method - type of read message
     *
     * @return      SUCCESS, blePending or Failure
     */
    static bStatus_t simpleProfile_ReadAttrCB(uint16_t connHandle,
                                              gattAttribute_t *pAttr,
                                              uint8_t *pValue, uint16_t *pLen,
                                              uint16_t offset, uint16_t maxLen,
                                              uint8_t method)
    {
      bStatus_t status = SUCCESS;
    
      // Make sure it's not a blob operation (no attributes in the profile are long)
      if ( offset > 0 )
      {
        return ( ATT_ERR_ATTR_NOT_LONG );
      }
    
      if ( pAttr->type.len == ATT_BT_UUID_SIZE )
      {
        // 16-bit UUID
        uint16 uuid = BUILD_UINT16( pAttr->type.uuid[0], pAttr->type.uuid[1]);
        switch ( uuid )
        {
          // No need for "GATT_SERVICE_UUID" or "GATT_CLIENT_CHAR_CFG_UUID" cases;
          // gattserverapp handles those reads
    
          // characteristics 1 and 2 have read permissions
          // characteritisc 3 does not have read permissions; therefore it is not
          //   included here
          // characteristic 4 does not have read permissions, but because it
          //   can be sent as a notification, it is included here
          case SIMPLEPROFILE_CHAR1_UUID:
          case SIMPLEPROFILE_CHAR2_UUID:
          case SIMPLEPROFILE_CHAR4_UUID:
            *pLen = 1;
            pValue[0] = *pAttr->pValue;
            break;
    
          case SIMPLEPROFILE_CHAR5_UUID:
            *pLen = SIMPLEPROFILE_CHAR5_LEN;
            VOID memcpy( pValue, pAttr->pValue, SIMPLEPROFILE_CHAR5_LEN );
            break;
    
          default:
            // Should never get here! (characteristics 3 and 4 do not have read permissions)
            *pLen = 0;
            status = ATT_ERR_ATTR_NOT_FOUND;
            break;
        }
      }
      else
      {
        // 128-bit UUID
        *pLen = 0;
        status = ATT_ERR_INVALID_HANDLE;
      }
    
      return ( status );
    }
    
    /*********************************************************************
     * @fn      simpleProfile_WriteAttrCB
     *
     * @brief   Validate attribute data prior to a write operation
     *
     * @param   connHandle - connection message was received on
     * @param   pAttr - pointer to attribute
     * @param   pValue - pointer to data to be written
     * @param   len - length of data
     * @param   offset - offset of the first octet to be written
     * @param   method - type of write message
     *
     * @return  SUCCESS, blePending or Failure
     */
    static bStatus_t simpleProfile_WriteAttrCB(uint16_t connHandle,
                                               gattAttribute_t *pAttr,
                                               uint8_t *pValue, uint16_t len,
                                               uint16_t offset, uint8_t method)
    {
      bStatus_t status = SUCCESS;
      uint8 notifyApp = 0xFF;
    
      if ( pAttr->type.len == ATT_BT_UUID_SIZE )
      {
        // 16-bit UUID
        uint16 uuid = BUILD_UINT16( pAttr->type.uuid[0], pAttr->type.uuid[1]);
        switch ( uuid )
        {
          case SIMPLEPROFILE_CHAR1_UUID:
          case SIMPLEPROFILE_CHAR3_UUID:
    
            //Validate the value
            // Make sure it's not a blob oper
            if ( offset == 0 )
            {
              if ( len != 1 )
              {
                status = ATT_ERR_INVALID_VALUE_SIZE;
              }
            }
            else
            {
              status = ATT_ERR_ATTR_NOT_LONG;
            }
    
            //Write the value
            if ( status == SUCCESS )
            {
              uint8 *pCurValue = (uint8 *)pAttr->pValue;
              *pCurValue = pValue[0];
    
              if( pAttr->pValue == &simpleProfileChar1 )
              {
                notifyApp = SIMPLEPROFILE_CHAR1;
              }
              else
              {
                notifyApp = SIMPLEPROFILE_CHAR3;
              }
            }
    
            break;
    
          case GATT_CLIENT_CHAR_CFG_UUID:
            status = GATTServApp_ProcessCCCWriteReq( connHandle, pAttr, pValue, len,
                                                     offset, GATT_CLIENT_CFG_NOTIFY );
            break;
    
          default:
            // Should never get here! (characteristics 2 and 4 do not have write permissions)
            status = ATT_ERR_ATTR_NOT_FOUND;
            break;
        }
      }
      else
      {
        // 128-bit UUID
        status = ATT_ERR_INVALID_HANDLE;
      }
    
      // If a characteristic value changed then callback function to notify application of change
      if ( (notifyApp != 0xFF ) && simpleProfile_AppCBs && simpleProfile_AppCBs->pfnSimpleProfileChange )
      {
        simpleProfile_AppCBs->pfnSimpleProfileChange( notifyApp );
      }
    
      return ( status );
    }
    
    /*********************************************************************
    *********************************************************************/
    

    5543.simple_gatt_profile.h

    3. Build and flash BIM project.

    4. Build and flash stack project.

    5. Build and flash the application.

    6. Flash the host_test in a second CC2640R2F Launchxl.

    7. Try to do  a OAD transfer. You see the message

    OAD Operation Timed Out

    Operation Name = GATT_WriteNoRsp_ImageBlockWrite

    Thank you.

    Best regards.

  • Hi,
    In the step "Try to do a OAD transfer", what image are you trying to transfer and how do you build that?
  • Hi,
    The image is equal, but with SOFTWARE_VERSION updated. I build it normally with IDE generating the *oad.bin file which is read into btool.
  • Hi,
    I can reproduce the issue with the extended simple service. I will engage with some of the experts and get back to you asap.
  • Hi,

    By using HEAPMGR_METRICS I was able to observe the reason for fail, you are running out of RAM.

    One way of freeing up more RAM, would be to use CACHE_AS_RAM, as described in the users guide. With that enabled, I was able to perform successful OAD.

    You can also consider migrating to CC26x2, our next generation platform.

  • Hi Joakim,

    Thank you for your support.

    How can I use the HEAPMGR_METRICS for identify the running out of RAM? I think the total RAM usage is showed in SRAM Memory Allocation view from CCS.

    I am going to add the CACHE_AS_RAM as you tell me before.

    Best regards.

  • Hi,

    The debugging chapter of the users guide describe it well, specifically this part.

  • Ok, thank you so far by your support.