Showing posts with label LAUNCHXL-CC2640R2. Show all posts
Showing posts with label LAUNCHXL-CC2640R2. Show all posts

Friday, October 22, 2021

Add write capability to Characteristics 5 in TI CC26xx BLE simple_peripheral example

The following steps show you how to add write capability to Characteristics 5 in TI CC26xx BLE simple_peripheral example. In simple_gatt_profile.c

1. Revise "static uint8 simpleProfileChar5Props = GATT_PROP_READ;" to "static uint8 simpleProfileChar5Props = GATT_PROP_READ | GATT_PROP_WRITE;"

2. Revise the following code in simpleProfileAttrTbl

      // Characteristic Value 5
      {
        { ATT_BT_UUID_SIZE, simpleProfilechar5UUID },
        GATT_PERMIT_AUTHEN_READ,
        0,
        simpleProfileChar5
      },

to

      // Characteristic Value 5
      {
        { ATT_BT_UUID_SIZE, simpleProfilechar5UUID },
        GATT_PERMIT_AUTHEN_READ | GATT_PERMIT_WRITE,
        0,
        simpleProfileChar5
      },

3. Add the following code into simpleProfile_WriteAttrCB

      case SIMPLEPROFILE_CHAR5_UUID:

      //Validate the value
      // Make sure it's not a blob oper
      if ( offset == 0 )
      {
        if ( len > SIMPLEPROFILE_CHAR5_LEN )
        {
          status = ATT_ERR_INVALID_VALUE_SIZE;
        }
      }
      else
      {
        status = ATT_ERR_ATTR_NOT_LONG;
      }

      //Write the value
      if ( status == SUCCESS )
      {
        uint8 *pCurValue = (uint8 *)pAttr->pValue;
        memcpy(pCurValue,pValue,len);
        if( pAttr->pValue == &simpleProfileChar5 )
        {
          notifyApp = SIMPLEPROFILE_CHAR5;
        }
      }

      break;

Build the project and you can use TI SimpleLink Starter App or LightBlue App to test Characteristics 5 with write capability.

Thursday, June 4, 2020

How to add you own custom board files to CC26xx BLE stack


The following steps show you how to add you own custom board files to CC26xx BLE stack using CC2650 BLE stack 2.2.04.06 version

1. Create CC2650_YK folder under C:\ti\simplelink\ble_sdk_2_02_04_06\src\boards\

2.
   2.1 Copy Board.h/CC2650_LAUNCHXL.h/CC2650_LAUNCHXL.c from C:\ti\simplelink\ble_sdk_2_02_04_06\src\boards\CC2650_LAUNCHXL to C:\ti\simplelink\ble_sdk_2_02_04_06\src\boards\CC2650_YK
  
   2.2 Rename CC2650_LAUNCHXL.h/CC2650_LAUNCHXL.c to CC2650_YK.h/CC2650_YK.c
  
   2.3 Revise #include "CC2650_LAUNCHXL.h" in Board.h to #include "CC2650_YK.h"

3. Create cc2650yk folder under C:\ti\simplelink\ble_sdk_2_02_04_06\src\target

4
   4.1 Copy cc2650lp_board.h/cc2650lp_board.c from C:\ti\simplelink\ble_sdk_2_02_04_06\src\target\cc2650lp to C:\ti\simplelink\ble_sdk_2_02_04_06\src\target\cc2650yk

   4.2 Rename cc2650lp_board.h/cc2650lp_board.c to cc2650yk_board.h/cc2650yk_board.c

   4.3 Add the following codes in cc2650yk_board.h
      
       #elif defined(CC2650_YK)
       #include <../../boards/CC2650_YK/Board.h>

   4.4 Add the following codes in cc2650yk_board.c

       #elif defined(CC2650_YK)
       #include <../../boards/CC2650_YK/Board.h>
       #include <../../boards/CC2650_YK/CC2650_YK.c>

5.
   5.1 Add the following codes in board.h
  
       #elif defined(CC2650_YK)
       #include "./cc2650yk/cc2650yk_board.h"

   5.2 Add the following codes in board.c
  
       #elif defined(CC2650_YK)
       #include "./cc2650yk/cc2650yk_board.c"

6. Change CC2650_LAUNCHXL in Predefined Symbols to CC2650_YK

7. Now you can build the code with your own custom board.

Wednesday, December 18, 2019

How to change CC26xx/CC13xx UART baudrate dynamically in your application.

The following steps show you how to change CC26xx/CC13xx UART baudrate dynamically in your application.

1. In port pininterrupt example into your CCS.

2. Add the following header files for UART and task related stuffs.

    #include <ti/sysbios/knl/Task.h>
    #include <ti/drivers/UART.h>
    #include <stdint.h>

3. Add the following defines and global variables for UART and task related stuffs.

    #define TASKSTACKSIZE     768
    uint32_t baudrate=115200;
    bool baudrate_change=false;
    UART_Handle uart;
    UART_Params uartParams;

    Task_Struct task0Struct;
    Char task0Stack[TASKSTACKSIZE];

4. Add the following red codes into buttonCallbackFxn to change baudrate when BTN1 is pressed.

            case Board_BUTTON1:
                currVal =  PIN_getOutputValue(Board_LED1);
                PIN_setOutputValue(ledPinHandle, Board_LED1, !currVal);
                if(baudrate==115200){
                    const char echoBaudrateChange[] = "\fChange Baudrate to 9600:\r\n";
                    UART_write(uart, echoBaudrateChange, sizeof(echoBaudrateChange));
                    baudrate=9600;
                }else{
                    const char echoBaudrateChange[] = "\fChange Baudrate to 115200:\r\n";
                    UART_write(uart, echoBaudrateChange, sizeof(echoBaudrateChange));
                    baudrate=115200;
                }
                baudrate_change=true;
                break;


5. Add the following function echoFxn()

Void echoFxn(UArg arg0, UArg arg1)
{
    char input;
    const char echoPrompt[] = "\fEchoing characters:\r\n";

    /* Create a UART with data processing off. */
    UART_Params_init(&uartParams);

RESTART_UART:
    uartParams.writeDataMode = UART_DATA_BINARY;
    uartParams.readDataMode = UART_DATA_BINARY;
    uartParams.readReturnMode = UART_RETURN_FULL;
    uartParams.readEcho = UART_ECHO_OFF;
    uartParams.baudRate = baudrate;
    uart = UART_open(Board_UART0, &uartParams);

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

    UART_write(uart, echoPrompt, sizeof(echoPrompt));

    /* Loop forever echoing */
    while (1) {
        if(baudrate_change){
            UART_close(uart);
            uart=NULL;
            baudrate_change=false;
            goto RESTART_UART;
        }
        UART_read(uart, &input, 1);
        UART_write(uart, &input, 1);
    }
}


6. Add the following red codes in main function to start UART task.

int main(void)
{
    Task_Params taskParams;
    /* Call board init functions */
    Board_initGeneral();
    Board_initUART();

    /* Construct BIOS objects */
    Task_Params_init(&taskParams);
    taskParams.stackSize = TASKSTACKSIZE;
    taskParams.stack = &task0Stack;
    Task_construct(&task0Struct, (Task_FuncPtr)echoFxn, &taskParams, NULL);
...
}


7. Build and download firmware into LaunchPad to test it.

Tuesday, December 17, 2019

How to create a periodic event to toggle BLE Advertising in CC26xx simple_peripheral example

The following steps show you how to create a periodic event to toggle BLE Advertising every 10 seconds in CC26xx simple_peripheral example.

In simple_peripheral.c, add the following codes:

1. Add "#define ADV_PERIODIC_EVT Event_Id_01" for new periodic event.

2. Add "#define ADV_PERIODIC_EVT_PERIOD 10000" to define the period as 10 seconds.

3. Add ADV_PERIODIC_EVT to Bitwise OR of all events to pend on.

    #define SBP_ALL_EVENTS       (SBP_ICALL_EVT        | \
                                                         SBP_QUEUE_EVT        | \
                                                         ADV_PERIODIC_EVT     | \
                                                         SBP_PERIODIC_EVT)

4. Add "advertEnabledPeriod = TRUE;" as a global variable for toggling BLE advertising.

5. Add "static Clock_Struct periodicClockAdv;" for periodic clock.

6. In SimplePeripheral_init(), add the following lines to start periodic event for toggling BLE advertising.

    Util_constructClock(&periodicClockAdv, SimplePeripheral_clockHandler,
                      ADV_PERIODIC_EVT_PERIOD, 0, false, ADV_PERIODIC_EVT);
    Util_startClock(&periodicClockAdv);



7.  Add the following codes in SimplePeripheral_taskFxn() to toggle BLE advertising in ADV_PERIODIC_EVT event which is triggered every 10 seconds.

      if (events & ADV_PERIODIC_EVT)
      {
        Util_startClock(&periodicClockAdv);
        if(advertEnabledPeriod==TRUE){
            advertEnabledPeriod=FALSE;
        } else {
            advertEnabledPeriod=TRUE;
        }
        GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t),
                                 &advertEnabledPeriod);

      }


8. After building and download hex into your CC26xx device, you can use SimpleLink Starter APP to scan and check if BLE advertising is toggled every 10 seconds.

Monday, December 16, 2019

How to use indication in simple_peripheral example and use Btool to enable indication.

The following steps show you how to revise CC26xx simple_peripheral example to use indication in simple_peripheral example and use Btool to enable indication.

1. Import CC26xx simple_peripheral example into CCS.

2. Replace "static ICall_EntityID selfEntity;" with "ICall_EntityID selfEntity;" in simple_peripheral.c.

3. Revise the following lines in simple_gatt_profile.c.

    3.a Add "extern ICall_EntityID selfEntity;" in EXTERNAL VARIABLES section.

    3.b Change "static uint8 simpleProfileChar4Props = GATT_PROP_NOTIFY;" to "static uint8 simpleProfileChar4Props = GATT_PROP_INDICATE;".
   
    3.c Change "status = GATTServApp_ProcessCCCWriteReq( connHandle, pAttr, pValue, len,  offset, GATT_CLIENT_CFG_NOTIFY);" to "status = GATTServApp_ProcessCCCWriteReq( connHandle, pAttr, pValue, len,  offset, GATT_CLIENT_CFG_INDICATE );".

    3.d Change

          GATTServApp_ProcessCharCfg( simpleProfileChar4Config, &simpleProfileChar4, FALSE,
                                    simpleProfileAttrTbl, GATT_NUM_ATTRS( simpleProfileAttrTbl ),
                                    INVALID_TASK_ID, simpleProfile_ReadAttrCB );
        
          to

          GATTServApp_ProcessCharCfg( simpleProfileChar4Config, &simpleProfileChar4, FALSE,
                                    simpleProfileAttrTbl, GATT_NUM_ATTRS( simpleProfileAttrTbl ),
                                    selfEntity, simpleProfile_ReadAttrCB );

4. Build simple_peripheral project and download hex to your LaunchPad. Check what BLE MAC address is on Teraterm (or any other terminal tools).



5. Start Btool to do BLE scan and select matched BLE MAC address to establish connection.



6. Write indication enable (02 00 in hex) into Characteristic Value Handle 0x0028 to enable indication and you can receive characteristic 4 indication on Btool.




Thursday, October 17, 2019

How to create micro second delay on CC2652R

The following codes show you how to create micro second delay on CC2652R

1. Use the following functions to create one micro second delay function.

#pragma FUNC_ALWAYS_INLINE (CpuDelayhundredNanoSec)
#pragma FUNCTION_OPTIONS(CpuDelayhundredNanoSec, "--opt_level=0")
static void CpuDelayhundredsNanoSec(void);
static void CpuDelayhundredsNanoSec(void) {
    asm(" NOP");
    asm(" NOP");
    asm(" NOP");
    asm(" NOP");
    asm(" NOP");
}
#pragma FUNC_ALWAYS_INLINE (CpuDelayMicroSec)
#pragma FUNCTION_OPTIONS(CpuDelayMicroSec, "--opt_level=0")
static void CpuDelayMicroSec(void);
static void CpuDelayMicroSec(void) {
    CpuDelayhundredsNanoSec();
    CpuDelayhundredsNanoSec();
    CpuDelayhundredsNanoSec();
}

2. Use the following codes in CC26x2 SDK ble5stack project_zero to test it.
    2.1. Add #include in project_zero.c
    2.2. Revise the following red codes in ProjectZero_handleButtonPress of project_zero.c to do toggle red led for 3 micro seconds when button 1 is pressed.

static void ProjectZero_handleButtonPress(pzButtonState_t *pState)
{
    Log_info2("%s %s",
              (uintptr_t)(pState->pinId ==
                          CONFIG_PIN_BTN1 ? "Button 0" : "Button 1"),
              (uintptr_t)(pState->state ?
                          ANSI_COLOR(FG_GREEN)"pressed"ANSI_COLOR(ATTR_RESET) :
                          ANSI_COLOR(FG_YELLOW)"released"ANSI_COLOR(ATTR_RESET)
                         ));

    // Update the service with the new value.
    // Will automatically send notification/indication if enabled.
    switch(pState->pinId)
    {
    case CONFIG_PIN_BTN1:
#if 0
        ButtonService_SetParameter(BS_BUTTON0_ID,
                                   sizeof(pState->state),
                                   &pState->state);
#else
        {
            ICall_CSState key;
            uint32_t c;
            key=ICall_enterCriticalSection();
            PIN_setOutputValue(ledPinHandle, CONFIG_PIN_RLED, 1);
            CpuDelayMicroSec();
            CpuDelayMicroSec();
            CpuDelayMicroSec();
            PIN_setOutputValue(ledPinHandle, CONFIG_PIN_RLED, 0);
            ICall_leaveCriticalSection(key);
        }

#endif
        break;
    case CONFIG_PIN_BTN2:
        ButtonService_SetParameter(BS_BUTTON1_ID,
                                   sizeof(pState->state),
                                   &pState->state);
        break;
    }
}

Wednesday, September 18, 2019

How to read TX power from CC2640R2 BLE Stack

The following steps show you how to read TX power from CC2640R2 BLE Stack. I use simple_central example for testing.

1. Call "HCI_ReadTransmitPowerLevelCmd(0, HCI_READ_CURRENT_TX_POWER_LEVEL);" in the end of SimpleCentral_init().

2. In SimpleCentral_processCmdCompleteEvt, add the following red codes to receive current TX power.

static void SimpleCentral_processCmdCompleteEvt(hciEvt_CmdComplete_t *pMsg)
{
  switch (pMsg->cmdOpcode)
  {
    case HCI_READ_TRANSMIT_POWER:
    {
        int8 get_tx_pwr = (int8)pMsg->pReturnParam[3];

        Display_print1(dispHandle, SC_ROW_SEPARATOR, 0, "TX power is %d db",get_tx_pwr);
        break;
    }

    case HCI_READ_RSSI:
    {
#ifndef Display_DISABLE_ALL
      uint16_t connHandle = BUILD_UINT16(pMsg->pReturnParam[1],
                                         pMsg->pReturnParam[2]);
      int8 rssi = (int8)pMsg->pReturnParam[3];
     
      Display_printf(dispHandle, SC_ROW_ANY_CONN, 0, "%s: RSSI %d dBm",
                   SimpleCentral_getConnAddrStr(connHandle), rssi);

#endif
      break;
    }

    default:
      break;
  }
}

Wednesday, July 31, 2019

Use PWM_PERIOD_HZ/PWM_DUTY_FRACTION to generate PWM for TI CC26xx/CC13xx devices.


You can replace the following mainThread function call in pwmled2 example to use PWM_PERIOD_HZ/PWM_DUTY_FRACTION to generate PWM for TI CC26xx/CC13xx devices.



void *mainThread(void *arg0)
{
    /* Period and duty in microseconds */
    uint16_t   pwmPeriod = 1000; //1K Hz PWM
    uint16_t   pwmDutyRatio = 0; //Init PWM Duty Ratio
    uint16_t   pwmDutyRatioInc = 5; //PWM Duty Ratio increase every time
    uint16_t   pwmDutyRatioMax= 50; //Max PWM Duty Ratio

    pwmDutyRatio = (uint32_t) (((uint64_t) PWM_DUTY_FRACTION_MAX * pwmDutyRatio) / 100);

    /* Sleep time in microseconds */
    uint32_t   time = 50000;
    PWM_Handle pwm1 = NULL;
    PWM_Handle pwm2 = NULL;
    PWM_Params params;

    /* Call driver init functions. */
    PWM_init();

    PWM_Params_init(&params);
    params.dutyUnits = PWM_DUTY_FRACTION;
    params.dutyValue = (uint32_t) (((uint64_t) PWM_DUTY_FRACTION_MAX * pwmDutyRatio) / 100);
    params.periodUnits =  PWM_PERIOD_HZ;
    params.periodValue = pwmPeriod;
    pwm1 = PWM_open(Board_PWM0, &params);
    if (pwm1 == NULL) {
        /* Board_PWM0 did not open */
        while (1);
    }

    PWM_start(pwm1);

    pwm2 = PWM_open(Board_PWM1, &params);
    if (pwm2 == NULL) {
        /* Board_PWM0 did not open */
        while (1);
    }

    PWM_start(pwm2);

    /* Loop forever incrementing the PWM duty */
    while (1) {
        PWM_setDuty(pwm1, (uint32_t) (((uint64_t) PWM_DUTY_FRACTION_MAX * pwmDutyRatio) / 100));

        PWM_setDuty(pwm2, (uint32_t) (((uint64_t) PWM_DUTY_FRACTION_MAX * pwmDutyRatio) / 100));

        pwmDutyRatio = (pwmDutyRatio + pwmDutyRatioInc);

        if (pwmDutyRatio == pwmDutyRatioMax || (!pwmDutyRatio)) {
            pwmDutyRatioInc = - pwmDutyRatioInc;
        }

        usleep(time);
    }
}

Thursday, January 17, 2019

How to output 32K crystal signal to specific pin on LAUNCHXL-CC2640R2

The following steps show you how to output 32K crystal signal to specific pin on LAUNCHXL-CC2640R2 using simple_peripheral example.

1. Add " #include  < driverlib/aon_ioc.h > " in simple_peripheral.c.

2. Add the following two lines in the end of SimplePeripheral_init() to output 32K crystal signal to DIO_10.

    IOCPortConfigureSet(IOID_10, IOC_PORT_AON_CLK32K, IOC_STD_OUTPUT);
    AONIOC32kHzOutputEnable();

3. Use scope to check wave form and frequency on DIO_10.