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.

Periodic (microseconds) transmission CC3200

Other Parts Discussed in Thread: SYSBIOS, CC3200

Hi,

I need to send a packet periodically with resolution of microseconds in the stack bypass mode. I have the following code:

...

Clock_Params clkParams;

/* Create a periodic Clock Instance with period = 5 system time units */
Clock_Params_init(&clkParams);
clkParams.period = 5; //80000000; // at 80MHz, 80 tics are supposed to be 1us?
clkParams.startFlag = TRUE;
clk2 = Clock_create(clk0Fxn, 5, &clkParams, NULL); //(clk0Fxn, 80000000, &clkParams, NULL); // at 80MHz, 80 tics are supposed to be 1us?

Clock_start(clk2);

BIOS_start(); /* does not return */

...

Void clk0Fxn(UArg arg0)
{
UART_PRINT("Transmiting triggered by clock.\r\n");

Status= sl_Send(socket_descriptor,RawData,sizeof(RawData),0);
Report("sl_Send_Status = %d. Data sent: %s. sizeof(RawData):%d.\n\r",Status,RawData,sizeof(RawData));

if(Status < 0)
{
UART_PRINT("Transmition Failed!\r\n");
sl_Close(socket_descriptor);
//ASSERT_ON_ERROR(__LINE__, lRetVal);
}
}

The transmitting part is working properly on its own, but the action is not being triggered by the clock. There are no errors, but the clock does not seem to start, or trigger the action. Please let me know what am I missing or if there is a better way to transmit periodically a frame in the stack bypass mode.

Thanks!

  • Clock object periods and timeouts are in units of Clock.tickPeriod.

    Have you configured Clock.tickPeriod to be something other than the default of 1000us?

    If not, then the period of '5' will be 5ms.

    Beware, setting the Clock.tickPeriod below 100us results in a fairly high system interrupt processing overhead.

    Alan

  • Thanks for the info Allan! However, I still cannot trigger an action when the clock triggers, instead I am getting an error exactly when the function clk0Fxn should be called during the clock rise edge. My code is:

    Void clk0Fxn(UArg arg0);
    Void clk1Fxn(UArg arg0);

    void main()
    {

    ...

    // Configure and start clock
    Clock_Params clkParams;

    /* Create a periodic Clock Instance with period = 5000 system time units */
    Clock_Params_init(&clkParams);
    clkParams.period = 5000; //5s
    clkParams.startFlag = TRUE;
    Clock_create(clk0Fxn, 5000, &clkParams, NULL); 

    /* Create an one-shot Clock Instance with timeout = 11000 system time units */
    clkParams.period = 0;
    clkParams.startFlag = FALSE;
    clk2 = Clock_create(clk1Fxn, 11000, &clkParams, NULL);

    Clock_start(clk2);

    UART_PRINT("Clock2 initiallized \r\n");

    BIOS_start(); /* does not return */

    ...

    }

    Void clk0Fxn(UArg arg0)
    {

    UART_PRINT("Transmiting triggered by clock.\r\n");

    }

    Void clk1Fxn(UArg arg0)
    {
    UInt32 time;

    time = Clock_getTicks();
    Report("time_Clock_getTicks: %d\n\r",time);

    BIOS_exit(0);
    }

    The code is built without errors, but during execution I get the following error after 5s:

    ti.sysbios.gates.GateMutex: line 99: assertion failure: A_badContext: bad calling context. See GateMutex API doc for details.
    xdc.runtime.Error.raise: terminating execution

    Thanks!

  • The error happens during the memory allocation, in the following line:

    pcBuff = (char*)malloc(iSize);

    of the uart_if.c file

  • Report() calls malloc().

    You can not malloc memory within a Clock function (Clock functions run within a Swi context).

    Therefore, you are not allowed to call Report() from within a Clock function.

    Alan

  • Thanks for the info Alan!

    Actually, I need to modify Clock_tickPeriod to be 100us or 50us, for example.

    In my C file I see that I can access the variable Clock_tickPeriod, but it is a constant "extern const UInt32 Clock_tickPeriod;", so I cannot modify it.

    I see that the value of 0x3e8 (1000 in decimal as you said) is set with the following code:

    /* tickPeriod__C */
    #pragma DATA_SECTION(ti_sysbios_knl_Clock_tickPeriod__C, ".const:ti_sysbios_knl_Clock_tickPeriod__C");
    __FAR__ const CT__ti_sysbios_knl_Clock_tickPeriod ti_sysbios_knl_Clock_tickPeriod__C = (xdc_UInt32)0x3e8;

    in the file ti_rtos_config/Default/configPkg/package/cfg/app_pem4.c

    But I cannot modify that file, and I am affraid that modifying this variable would affect other things. So my question is: which is the proper way to set the tick period to 100us?

    Thanks!

  • To set the tick period to 50us, add this to your .cfg file:

    var Clock = xdc.useModule('ti.sysbios.knl.Clock');
    Clock.tickPeriod = 50;


    Alan

  • Be advised that 50us is a fairly high interrupt rate.

  • I need to add the following to my .cfg file as you suggested:

    var Clock = xdc.useModule('ti.sysbios.knl.Clock');
    Clock.tickPeriod = 50;

    But, exactly which file is my .cfg? How do I find the .cfg file? I can not see it in the project tree, neither in the project folder.

    I am using CCS and the CC3200 LP.

    Thanks!

  • It looks to me like the .cfg file should be named app.cfg and appear in your project folder.

    If not, can you share you CCS project so I can have a look around?

    Alan

  • Hi!

    I implemented the proposed solution with semaphores. The code is:

    void myTxTask(void)
    {
    while (TRUE) {
    Semaphore_pend(myTxSem, BIOS_WAIT_FOREVER);
    Status= sl_Send(socket_descriptor,RawData,sizeof(RawData),0);
    Report("sl_Send_Status = %d. Data sent: %s. sizeof(RawData):%d.\n\r",Status,RawData,sizeof(RawData));

    if(Status < 0)
    {
    UART_PRINT("Transmition Failed!\r\n");
    sl_Close(socket_descriptor);
    }
    }
    }

    /*
    * ======== clk0Fxn =======
    */
    Void clk0Fxn(UArg arg0)
    {
    Semaphore_post(myTxSem);
    }

    However, this implementation just allows me to transmit at most 37 packets per second. If I try to set a higher transmission rate, I only get around 37packets per second transmitted. So it seems that using semaphores is not efficient enough to have periodic transmissions in the order of microseconds.

    If I add a sl_Send line to the previous code:

    void myTxTask(void)
    {
    while (TRUE) {
    Semaphore_pend(myTxSem, BIOS_WAIT_FOREVER);
    Status= sl_Send(socket_descriptor,RawData,sizeof(RawData),0);
    Status= sl_Send(socket_descriptor,RawData,sizeof(RawData),0);

    Report("sl_Send_Status = %d. Data sent: %s. sizeof(RawData):%d.\n\r",Status,RawData,sizeof(RawData));
    if(Status < 0)
    {
    UART_PRINT("Transmition Failed!\r\n");
    sl_Close(socket_descriptor);
    }
    }
    }

    /*
    * ======== clk0Fxn =======
    */
    Void clk0Fxn(UArg arg0)
    {
    Semaphore_post(myTxSem);
    }

    The transmission rate is duplicated, but the transmissions are not periodic.

    How can I implement a periodic transmission (with period in the order of microseconds) and high resolution? Thanks!

  • Hi!

    Alternatively, I am using the function MAP_UtilsDelay(d) to generate a delay. But the argument, "d", is the number of loops, where each loop takes 3-5 clock ticks according to 

    http://e2e.ti.com/support/wireless_connectivity/f/968/t/370018.aspx

    So to generate a delay of few us, I need to modify "Clock.tickPeriod", that has a default of 1000us. Therefore I come back to the question: where do I find the .cfg file?, because I do not see it in the project tree (see the attached figure). Thanks!

  • Fernando,

    As Alan indicated, the output indicates that an “app.cfg” file is being used.  

    I don’t know where your project came from, or why you don’t see the file in your project view.  Can you search your file system directly for this file, or any references to it?

    Scott

  • The project is a modification of the "wlan_station" example. I was looking for the app.cfg file as you suggested and this is the result:

     

    You can see as well the files in the "Includes". Comparing the "Includes" with the "app.cfg" found, there are some matches, as highlighted in the figure. Mainly in the folder

    "C:\ti\tirtos_simplelink_2_01_00_03\products\bios_6_40_03_39\packages"

    But exactly which of those files should I modify? Additionally, if I try to open those files I get the error "Error in initialization of CCSConfigEditor". Is it safe to simply open the files with Notepad and include the lines suggested by Alan:

    var Clock = xdc.useModule('ti.sysbios.knl.Clock');
    Clock.tickPeriod = 50;

    ?

  • Fernando,

    OK this helps.  I think your project is using a shared TI-RTOS configuration file.  One of the CC32xx getting started wiki pages (http://processors.wiki.ti.com/index.php/CC32xx_Getting_Started_with_WLAN_Station) indicates a shared configuration project needs to be imported into your workspace.  If I zoom into the picture of your list of projects, I see a “ti_rtos_config” project.  I think the app.cfg your project is using resides in that project.

    Yes, you should be able to open the .cfg file in a text editor, edit, save, and then rebuild the project.

    Scott

  • Hi Scott,

    Thanks!

    just a clarification from my side, in case somebody else reads the previous posts: I was confusing the clock ticks for the solution that Alan proposed and the ticks of the MAP_UtilsDelay function.