CC2340R5: Send a Proprietary packet after wake up from GPIO

Part Number: CC2340R5

Tool/software:

I would like to do a simple program:

Wake up from a GPIO, emit a packet, go to sleep, and so on.
Based on the example rfPacketTx and rfPacketRx it works.

void SendPacket(void)
{
    
    RCL_init();
    
    rclHandle = RCL_open(&rclClient, &LRF_config);
    rclPacketTxCmdGenericTx.rfFrequency = FREQUENCY;

    /* Start command as soon as possible */
    rclPacketTxCmdGenericTx.common.scheduling = RCL_Schedule_Now;
    rclPacketTxCmdGenericTx.common.status = RCL_CommandStatus_Idle;

    rclPacketTxCmdGenericTx.config.fsOff = FS_OFF; // Turn off FS

    /* Callback triggers on last command done */
    rclPacketTxCmdGenericTx.common.runtime.callback = defaultCallback;
    rclPacketTxCmdGenericTx.common.runtime.rclCallbackMask.value = RCL_EventLastCmdDone.value;

    /* Set RCL TX buffer packet to be packet buffer */
    txPacket = (RCL_Buffer_TxBuffer *)&packet;
    

   
    // Create packet with random payload
    uint8_t *txData;
    txData = RCL_TxBuffer_init(txPacket, NUM_PAD_BYTES, HDR_LEN, MAX_LENGTH);

    // Zero out data in header before the length field
    for (int s = 0; s < LEN_INDEX; s++)
    {
        txData[s] = 0U;
    }

    // Set the packet length
    txData[LEN_INDEX] = MAX_LENGTH;

    // Generate a random payload
    for (int i = HDR_LEN; i < MAX_LENGTH; i++)
    {
        txData[i] = rand();
    }

    // Set packet to transmit
    RCL_TxBuffer_put(&rclPacketTxCmdGenericTx.txBuffers, txPacket);

    rclPacketTxCmdGenericTx.common.status = RCL_CommandStatus_Idle;

    // Submit command
    RCL_Command_submit(rclHandle, &rclPacketTxCmdGenericTx);

    //Pend on command completion
    RCL_Command_pend(&rclPacketTxCmdGenericTx);
    
    while(!gCmdDone)
    {};
        gCmdDone = 0;
    RCL_close(rclHandle);
    
}

Now I would like to separate the program into two parts:

The following function is run once at the beginning of the program:
void Init(void)
{

    RCL_init();
    
    rclHandle = RCL_open(&rclClient, &LRF_config);
    rclPacketTxCmdGenericTx.rfFrequency = FREQUENCY;

    // Start command as soon as possible
    rclPacketTxCmdGenericTx.common.scheduling = RCL_Schedule_Now;
    rclPacketTxCmdGenericTx.common.status = RCL_CommandStatus_Idle;

    rclPacketTxCmdGenericTx.config.fsOff = FS_OFF; // Turn off FS

    // Callback triggers on last command done
    rclPacketTxCmdGenericTx.common.runtime.callback = defaultCallback;
    rclPacketTxCmdGenericTx.common.runtime.rclCallbackMask.value = RCL_EventLastCmdDone.value;
 
    // Set RCL TX buffer packet to be packet buffer
    txPacket = (RCL_Buffer_TxBuffer *)&packet;

}
The following function is run at every wake-up by the GPIO:
void SendPacket(void)
{
    
    
    // Create packet with random payload
    uint8_t *txData;
    txData = RCL_TxBuffer_init(txPacket, NUM_PAD_BYTES, HDR_LEN, MAX_LENGTH);

    // Zero out data in header before the length field
    for (int s = 0; s < LEN_INDEX; s++)
    {
        txData[s] = 0U;
    }

    // Set the packet length
    txData[LEN_INDEX] = MAX_LENGTH;

    // Generate a random payload
    for (int i = HDR_LEN; i < MAX_LENGTH; i++)
    {
        txData[i] = rand();
    }

    // Set packet to transmit
    RCL_TxBuffer_put(&rclPacketTxCmdGenericTx.txBuffers, txPacket);

    rclPacketTxCmdGenericTx.common.status = RCL_CommandStatus_Idle;

    // Submit command
    RCL_Command_submit(rclHandle, &rclPacketTxCmdGenericTx);

    //Pend on command completion
    RCL_Command_pend(&rclPacketTxCmdGenericTx);
    
    while(!gCmdDone)
    {};
        gCmdDone = 0;
        
}
The program seems to run, but it doesn't work. The packet is never received.
Is it mandatory to make an initialization of the RCL each time the processor is woke-up from sleep to emit a new packet?

Regards,

Laurent

  • Hi Laurent,

    Is it mandatory to make an initialization of the RCL each time the processor is woke-up from sleep to emit a new packet?

    No, you don't need to do RCL_init/open for every packet.

    From my initial look, your code should work, since your SendPacket is doing everything as shown in the while(1) loop of the rfPacketTx.c

    Is this program doing ONLY TX (similar to rfPacketTx)? Or does it also do RX?

    Maybe you can try the rfEchoTx and rfEchoRx examples?
    (Since these only call the RCL_init/open one time also).

    Thanks,
    Toby

  • Hi Toby,

    This program is only doing Tx.

    If I use rfPacketTx and rfPacketRx with no modification, it works.

    I made a modification to the rfPacketTx (see below) that goes to sleep and wakes up when you push the btn2 of the LP-EM-CC2340R5.

    You can see the LED blinking when you push the button, but nothing is received.

    I'm probably missing something with the configuration.

    Best Regards,

    Laurent

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    /*
    * Copyright (c) 2013-2022, 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,
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

  • Hi Laurent,

    Thanks for sharing more details/code, and apologies for my delay.

    The main issue I see in your code is that it explicitly calls "Power_sleep". This should not be done, as it could interfere with the automatic power management integrated with the RTOS (FreeRTOS). (More details described here: https://e2e.ti.com/support/power-management-group/power-management/f/power-management-forum/1439063/lp-em-cc2340r5-after-putting-device-in-standby-mode-code-continues-running/5542530#5542530)

    I went ahead and combined some examples/drivers together (rfPacketTx + gpioInterrupt + semaphore), and it seems to meet your initial requirements "Wake up from a GPIO, emit a packet, go to sleep".

    The zip is attached. They should run ok on a pair of LP-EM-CC2340R5.
    /cfs-file/__key/communityserver-discussions-components-files/667/example_5F00_pair.zip

    Thanks,
    Toby

  • Hello Toby,

    Thank you for your help.
    I'm going to try and I'm going to keep you updated.

    Regards,

    Laurent

  • Hello Toby,

    Your code work as expected. Thanks.

    I still have a problem : I would like to use a RTC timer to wake up the processor.

    I use the code :

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    #define RTC_PERIOD_MS 3000
    #define RTC_FREQ 31250 // 31.25 kHz
    HwiP_Struct rtcHwi;
    void rtcInterruptHandler(uintptr_t arg) {
    if (HWREG(RTC_BASE + RTC_O_RIS) & RTC_RIS_EV0) {
    HWREG(RTC_BASE + RTC_O_ICLR) |= RTC_RIS_EV0;
    GPIO_toggle(CONFIG_GPIO_LED_GREEN);
    HWREG(RTC_BASE + RTC_O_CTL) |= RTC_CTL_RST;
    }
    }
    void rtcInit(void) {
    uint32_t rtc_interval = RTC_PERIOD_MS * (RTC_FREQ / 1000);
    HWREG(RTC_BASE + RTC_O_CH0CC8U) = rtc_interval;
    HWREG(RTC_BASE + RTC_O_IMASK) |= RTC_RIS_EV0;
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    This code was found in thread : https://e2e.ti.com/support/clock-timing-group/clock-and-timing/f/clock-timing-forum/1442276/lp-em-cc2340r5-rts-timer-waking-up-from-standby-by-rtc-timer

    But no interrupt occurs.

    My low frequency clock configuration is :

    If I read register HWREG(RTC_BASE + RTC_O_TIME8U) or HWREG(RTC_BASE + RTC_O_TIME524M) I can see the value changing. It means that RTC clock is working.

    Is there anything missing from the timer configuration?

    Best regards,

    Laurent

  • Hi Laurent,

    Thanks for the update! Glad to hear it is working.

    Regarding wake on RTC, you just need to call sleep(your_sleep_time_sec) or usleep(your_sleep_time_usec).

    The RTOS layers will handle wakeup automatically, and this is based on RTC.

    Thanks,
    Toby

  • Toby,

    I'm going to try your solution with usleep, but there are some links with input interrupt.



    With the RTC if I set the bit HWREG(RTC_BASE + RTC_O_ISET) |= 1 and I read HWREG(RTC_BASE + RTC_O_RIS) the bit is set to 1.

    It means that the interrupt occurs, but the callback function is not triggered.

    Regards,

    Laurent

  • Do you plan to use an RTOS in this application?

    If yes, you can use a posix-compatible FreeRTOS timer routine implementation here: C:\ti\simplelink_lowpower_f3_sdk_8_20_00_119\source\ti\posix\freertos\timer.c

    This can call a user-specified callback upon timeout.

  • Yes, I’m going to use the RTOS. The main problem is power consumption.

    This is the reason why I need a RTC timer. I don’t know if the example uses a RTC timer.

  • RTOS does use RTC timer. For example, scheduling its next wakeup which has dependency on timer routines.