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

Tuesday, September 1, 2020

How to remove OAD feature on CC26x2/CC13x2 project_zero

 The following steps show you how to remove OAD feature on CC26x2/CC13x2 project_zero

 1. Replace C:\ti\simplelink_cc13x2_26x2_sdk_4_10_03_02_eng\examples\rtos\CC26X2R1_LAUNCHXL\ble5stack\project_zero\tirtos\ccs\cc13x2_cc26x2_app.cmd
   with C:\ti\simplelink_cc13x2_26x2_sdk_4_10_03_02_eng\examples\rtos\CC26X2R1_LAUNCHXL\ble5stack\simple_peripheral\tirtos\ccs\cc13x2_cc26x2_app.cmd
   
2. Check "Exclude from build" on project_zero OAD folder in CCS Project Explorer.

3. Remove all OAD_xxx related code from projec_zero.c and _imgHdr

4. Change project_zero_app.cfg

m3Hwi.nvicCCR.UNALIGN_TRP = 0;
//m3Hwi.nvicCCR.UNALIGN_TRP = 1;

/* Put reset vector after OAD metadata */
var compilerOpts = prog.build.target.ccOpts.prefix; // Get the target compiler options
var regex = /(?:\-\-define\=)(\w*)(?:\=*\w*\s)/g;
var compilerDefs = [];
while ((tmp = regex.exec(compilerOpts)) !== null) compilerDefs.push(tmp[1]); // Parse compiler symbols

if (compilerDefs.indexOf('SECURITY') > -1) { // Check for SECURITY compiler symbol
    m3Hwi.resetVectorAddress = 0x90; // Image B Reset Vector Address
}
else {
    m3Hwi.resetVectorAddress = 0x50; // Image A Reset Vector Address
}

/* Put interrupt vector at start of RAM so interrupts can be configured at runtime */
m3Hwi.vectorTableAddress  = 0x20000000;

To

m3Hwi.nvicCCR.UNALIGN_TRP = 0;
//m3Hwi.nvicCCR.UNALIGN_TRP = 1;

/* Put reset vector at start of Flash */
m3Hwi.resetVectorAddress  = 0x0;

/* Put interrupt vector at start of RAM so interrupts can be configured at runtime */
m3Hwi.vectorTableAddress  = 0x20000000;

Tuesday, August 25, 2020

Build OpenThread Sleepy End Device doorlock prototype to test with Rasperry Pi OpenThread Border Router

The following steps show how to build OpenThread Sleepy End Device doorlock prototype to test with Rasperry Pi OpenThread Border Router

1. Build OpenThread Sleepy End Device doorlock prototype for TI LAUNCHXL-CC26X2R1

1.1 Download/Install TI CCS 10.1 and SIMPLELINK-CC13X2-26X2-SDK v4.20.00.35.

1.2 Import thread door_lock example from C:\ti\simplelink_cc13x2_26x2_sdk_4_20_00_35\examples\rtos\CC26X2R1_LAUNCHXL\thread\door_lock

1.3 Set door_lock as Sleepy End Device from sysconfig.

 

1.4 Add the following codes in tiop_ui.c for providing API to output IPv6 address to UART console.

inline uint16_t Swap16(uint16_t v)
{
    return (((v & 0x00ffU) << 8) & 0xff00) | (((v & 0xff00U) >> 8) & 0x00ff);
}
 

inline uint16_t HostSwap16(uint16_t v)
{
    return Swap16(v);
}

void tiopCUIOutputIp6Address(otIp6Address aAddress)
{
    CUI_statusLinePrintf(
        clientHandle, nwkInfoLine1,
        "[" CUI_COLOR_GREEN "IPv6" CUI_COLOR_RESET "] %s - %x:%x:%x:%x:%x:%x:%x:%x",
        "Addr",
        HostSwap16(aAddress.mFields.m16[0]), HostSwap16(aAddress.mFields.m16[1]),
                HostSwap16(aAddress.mFields.m16[2]), HostSwap16(aAddress.mFields.m16[3]), HostSwap16(aAddress.mFields.m16[4]),
                HostSwap16(aAddress.mFields.m16[5]), HostSwap16(aAddress.mFields.m16[6]), HostSwap16(aAddress.mFields.m16[7]));
}

1.5 Add the following line to expose API tiopCUIOutputIp6Address in tiop_ui.h.

extern void tiopCUIOutputIp6Address(otIp6Address aAddress);

1.6 Add the following line in "case DoorLock_evtKeyRight:..." of processEvent (doorlock.c) to output IPv6 address when right button is pressed.

tiopCUIOutputIp6Address(*(otThreadGetRloc(OtInstance_get())));

1.7 Build and download sleepy door_lock firmware into LAUNCHXL-CC26X2R1.

 

2. Setup OpenThread Border Router and libcoap on Raspberry Pi.

2.1 Refer to this link to setup OpenThread Border Router on Raspberry Pi.

2.2 Run the following command in Raspberry Pi console to setup libcoap.

      sudo apt install autoconf automake libtool
      git clone --depth 1 --recursive -b dtls https://github.com/home-assistant/libcoap.git
      cd libcoap
      ./autogen.sh
      ./configure --disable-documentation --disable-shared --without-debug CFLAGS="-D COAP_DEBUG_FD=stderr"
      make
      sudo make install

3. Use the following commands on Raspberry Pi console and start sleepy door_lock to join thread network. Then, press right button on LAUNCHXL-CC26X2R1 to print IPv6 address of sleepy door_lock.

sudo ot-ctl commissioner start
sudo ot-ctl commissioner joiner add 00124b001ca16238 DRRLCK1

4. Use the following command to request lock state of sleepy door_lock from border router.

coap-client -m get coap://[fd11:1111:1122:0:0:ff:fe00:ec08]/doorlock/lockstate

5. Use the following command to change lock state of sleepy door_lock from border router.

coap-client -m post coap://[fd11:1111:1122:0:0:ff:fe00:ec08]/doorlock/lockstate -e unlock

 


Tuesday, June 16, 2020

How to use two UARTs in CC26x2 and CC13x2.

The following steps show you how to enable second UART in CC26x2 and CC13x2 using uartecho example.

1. Add second UART CONFIG_UART_1 from syscfg with the following steps



2. Add the following red codes to use CONFIG_UART_1.

void *mainThread(void *arg0)
{
    char        input;
    const char  echoPrompt[] = "Echoing characters:\r\n";
    const char  echo1Prompt[] = "UART 2 Echoing characters:\r\n";
    UART_Handle uart;
    UART_Params uartParams;
    UART_Handle uart1;
    UART_Params uart1Params;


    /* Call driver init functions */
    GPIO_init();
    UART_init();

    /* Configure the LED pin */
    GPIO_setConfig(CONFIG_GPIO_LED_0, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);

    /* Turn on user LED */
    GPIO_write(CONFIG_GPIO_LED_0, CONFIG_GPIO_LED_ON);

    /* 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.baudRate = 115200;

    uart = UART_open(CONFIG_UART_0, &uartParams);

    if (uart == NULL) {
        /* UART_open() failed */
        while (1);
    }

    /* Create second UART with data processing off. */
    UART_Params_init(&uart1Params);
    uart1Params.writeDataMode = UART_DATA_BINARY;
    uart1Params.readDataMode = UART_DATA_BINARY;
    uart1Params.readReturnMode = UART_RETURN_FULL;
    uart1Params.baudRate = 115200;

    uart1 = UART_open(CONFIG_UART_1, &uart1Params);

    if (uart1 == NULL) {
        /* UART_open() failed */
        while (1);
    }

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

    /* Loop forever echoing */
    while (1) {
        if(UART_read(uart, &input, 1))
            UART_write(uart, &input, 1);
    }

3. Build and run uartecho and now you can see "UART 2 Echoing characters:" output from the seconds UART TX pin.

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.

Monday, April 13, 2020

How to use two endpoints in SIMPLELINK-CC13X2-26X2-SDK Z-Stack.

The following steps show you how to use two endpoints in SIMPLELINK-CC13X2-26X2-SDK Z-Stack zed_sw example.

1. Define a new SAMPLESW_ENDPOINT2 as 9 in zcl_samplesw.h.


    #define SAMPLESW_ENDPOINT2               9

2. Define a new zclSampleSwEp2Desc in zcl_samplesw.c.

 static endPointDesc_t  zclSampleSwEp2Desc = {0};

3. Clone zclSampleSwEp2_Attrs, zclSampleSwEp2_InClusterList, and zclSampleSwEp2_OutClusterList from zclSampleSw_Attrs, zclSampleSw_InClusterList, and zclSampleSw_OutClusterList in zcl_samplesw_data.c.


4. Define a new zclSampleSwEp2_SimpleDesc in zcl_samplesw_data.c.

#define ZCLSAMPLESWEp2_MAX_INCLUSTERS    ( sizeof( zclSampleSwEp2_InClusterList ) / sizeof( zclSampleSwEp2_InClusterList[0] ))

#define ZCLSAMPLESWEp2_MAX_OUTCLUSTERS   ( sizeof( zclSampleSwEp2_OutClusterList ) / sizeof( zclSampleSwEp2_OutClusterList[0] ))

SimpleDescriptionFormat_t zclSampleSwEp2_SimpleDesc =
{
  SAMPLESW_ENDPOINT2,                  //  int Endpoint;
  ZCL_HA_PROFILE_ID,                  //  uint16_t AppProfId[2];
  ZCL_HA_DEVICEID_ON_OFF_LIGHT_SWITCH,//  uint16_t AppDeviceId[2];
  SAMPLESW_DEVICE_VERSION,            //  int   AppDevVer:4;
  SAMPLESW_FLAGS,                     //  int   AppFlags:4;
  ZCLSAMPLESWEp2_MAX_INCLUSTERS,         //  byte  AppNumInClusters;
  (cId_t *)zclSampleSwEp2_InClusterList, //  byte *pAppInClusterList;
  ZCLSAMPLESWEp2_MAX_OUTCLUSTERS,        //  byte  AppNumInClusters;
  (cId_t *)zclSampleSwEp2_OutClusterList //  byte *pAppInClusterList;
};


5. Register the new SAMPLESW_ENDPOINT2 and zclSampleSwEp2Desc in zclSampleSw_Init().

  //Register Endpoint 2
  zclSampleSwEp2Desc.endPoint = SAMPLESW_ENDPOINT2;
  zclSampleSwEp2Desc.simpleDesc = &zclSampleSwEp2_SimpleDesc;
  zclport_registerEndpoint(appServiceTaskId, &zclSampleSwEp2Desc);

6. Clone zclSampleSwEp2_CmdCallbacks (remember to implement your own callbacks for SAMPLESW_ENDPOINT2) from zclSampleSw_CmdCallbacks in zcl_samplesw.c and register zclSampleSwEp2_CmdCallbacks using zclGeneral_RegisterCmdCallbacks().

zclGeneral_RegisterCmdCallbacks( SAMPLESW_ENDPOINT2, &zclSampleSwEp2_CmdCallbacks );

7. Define zclSampleSwEp2_NumAttributes in zcl_samplesw_data.c.

uint8_t CONST zclSampleSwEp2_NumAttributes = ( sizeof(zclSampleSwEp2_Attrs) / sizeof(zclSampleSwEp2_Attrs[0]) );

8. Register attributes for SAMPLESW_ENDPOINT2 using zcl_registerAttrList() in .

zcl_registerAttrList( SAMPLESW_ENDPOINT, zclSampleSwEp2_NumAttributes, zclSampleSwEp2_Attrs );

9. Build and test your application for two active endpoints.

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 25, 2019

How to use internal temperature reading inside CC26xx/CC13xx

The following codes show you how to use internal temperature sensor reading inside CC26xx/CC13xx.

1. Add "#include DeviceFamily_constructPath(driverlib/aon_batmon.h)"

2. Use the following codes to do internal temperature sensor reading into curr_tmp.

    int32_t curr_tmp;
    AONBatMonEnable();
    curr_tmp=AONBatMonTemperatureGetDegC();
    AONBatMonDisable();

Wednesday, August 14, 2019

How to enable hex and float value output from System_printf in TI CC13xx/CC26xxx SDK.

The following steps show you how to enable hex and float value output from System_printf in TI CC13xx/CC26xxx SDK.

1. Add "System.extendedFormats = '%x%f%$L%$S%$F';" in your application ccfg such as app.cfg
2. Add "#include <xdc/runtime/System.h> in the beginning of C file.
3. You can use System_printf and %x/%f to print hex or float value now.

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);
    }
}

Monday, May 6, 2019

How to check APS ack in TI Z-Stack

The following steps show you how to check APS ack in TI Z-Stack using ON/OFF cluster toggle command in SampleSwitch example.

1. Setup OnOffOptions and use zcl_registerClusterOptionList in  zclSampleSw_Init to register receiving APS ack on ZCL_CLUSTER_ID_GEN_ON_OFF cluster command.
   
    zclOptionRec_t OnOffOptions[] =
    {
      {
         ZCL_CLUSTER_ID_GEN_ON_OFF, ( AF_EN_SECURITY | AF_ACK_REQUEST ),
      },
    };
    ZStatus_t status = zcl_registerClusterOptionList ( SAMPLESW_ENDPOINT, 1,
                                                                                    OnOffOptions );
 2.  Add "case AF_DATA_CONFIRM_CMD:..." in SYS_EVENT_MSG case of zclSampleSw_event_loop

    uint16 zclSampleSw_event_loop( uint8 task_id, uint16 events )
    {
      ...
     
      if ( events & SYS_EVENT_MSG )
      {
        while ( (MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( zclSampleSw_TaskID )) )
        {
          switch ( MSGpkt->hdr.event )
          {
            case AF_DATA_CONFIRM_CMD:
              afDataConfirm_t *SWafDataConfirm;
              SWafDataConfirm = (afDataConfirm_t *)MSGpkt;
              rcv_aps_ack_trans_id=SWafDataConfirm->transID;
              // You can use rcv_aps_ack_trans_id to check if it matches to APS_Counter when you send toggle command with zclGeneral_SendOnOff_CmdToggle
              break;
     ...

Tuesday, December 4, 2018

How to detect button hold in CC26x2, CC13x0, CC13x2 SDK.

The following steps show you how to detect button hold in CC26x2, CC13x0, CC13x2 SDK. I use zed_switch example to add related code to detect if right button (active-low) is pressed (low status) and hold for 3 seconds.

1. In board_key.c, change Board_PIN_BUTTON1 to use PIN_IRQ_BOTHEDGES

static PIN_Config keyPinTable[] = {
      Board_PIN_BUTTON0 | PIN_INPUT_EN | PIN_PULLUP | PIN_IRQ_NEGEDGE,
      Board_PIN_BUTTON1 | PIN_INPUT_EN | PIN_PULLUP | PIN_IRQ_BOTHEDGES,
      PIN_TERMINATE /* Terminate list */
    };


2. Add the following red codes in board_key.c

#include <ti/sysbios/knl/Clock.h>
...
UInt32 button_pressed_time=0;
UInt32 button_released_time=0;
static void board_key_keyFxn(PIN_Handle keyPinHandle, PIN_Id keyPinId)
{
    (void)keyPinHandle;

    if(keyPinId == keyButton0)
    {
        keysPressed |= KEY_LEFT;
    }
    else if(keyPinId == keyButton1)
    {
        if(PIN_getInputValue(keyButton1) == false){
            button_pressed_time=Clock_getTicks(); //Clock_getTicks will return counts in 10us.
            return;
         } else {
            if (PIN_getInputValue(keyButton1) == true){
                button_released_time=Clock_getTicks(); //Clock_getTicks will return counts in 10us.
            }
        }
        if ( (button_released_time-button_pressed_time)>300000 )
            keysPressed |= KEY_RIGHT_HOLD_3SEC;
        else if ( (button_released_time-button_pressed_time)>0 )
            keysPressed |= KEY_RIGHT;

    }

    if(Timer_isActive(&keyChangeClock) != true)
    {
        Timer_start(&keyChangeClock);
    }
}

3. Define KEY_RIGHT_HOLD_3SEC in board_key.h

/*! Select Key ID */
#define KEY_SELECT            0x01
/*! Up Key ID */
#define KEY_UP                0x02
/*! Down Key ID */
#define KEY_DOWN              0x04
/*! Left Key ID */
#define KEY_LEFT              0x08
/*! Right Key ID */
#define KEY_RIGHT             0x10
/*! Hold 3 seconds Right Key ID */
#define KEY_RIGHT_HOLD_3SEC   0x20


4. Add "if(keysPressed == KEY_RIGHT_HOLD_3SEC){...}" in zclSampleSw_processKey of zcl_samplesw.c to process event for right button pressing and holding for 3 seconds.

static void zclSampleSw_processKey(uint8 keysPressed)
{
    //Button 1
    if(keysPressed == KEY_LEFT)
    {
        zstack_bdbStartCommissioningReq_t zstack_bdbStartCommissioningReq;

        if(ZG_BUILD_COORDINATOR_TYPE && ZG_DEVICE_COORDINATOR_TYPE)
        {
            zstack_bdbStartCommissioningReq.commissioning_mode = BDB_COMMISSIONING_MODE_NWK_FORMATION | BDB_COMMISSIONING_MODE_NWK_STEERING | BDB_COMMISSIONING_MODE_FINDING_BINDING;
            Zstackapi_bdbStartCommissioningReq(zclSampleSw_Entity,&zstack_bdbStartCommissioningReq);
        }
        else if (ZG_BUILD_JOINING_TYPE && ZG_DEVICE_JOINING_TYPE)
        {
            zstack_bdbStartCommissioningReq.commissioning_mode = BDB_COMMISSIONING_MODE_NWK_STEERING | BDB_COMMISSIONING_MODE_FINDING_BINDING;
            Zstackapi_bdbStartCommissioningReq(zclSampleSw_Entity,&zstack_bdbStartCommissioningReq);
        }
    }
    //Button 2
    if(keysPressed == KEY_RIGHT)
    {
        zstack_bdbGetZCLFrameCounterRsp_t Rsp;

        Zstackapi_bdbGetZCLFrameCounterReq(zclSampleSw_Entity, &Rsp);
        zclGeneral_SendOnOff_CmdToggle( SAMPLESW_ENDPOINT, &zclSampleSw_DstAddr, FALSE, Rsp.zclFrameCounter );
    }
    if(keysPressed == KEY_RIGHT_HOLD_3SEC)
    {
        //Event for right button pressing and holding for 3 seconds.
    }


}