Due to the U.S. Thanksgiving holiday, please expect delayed responses during the week of 11/22.

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.

LAUNCHXL-CC1350-4: Multi tasking / interrupts

Part Number: LAUNCHXL-CC1350-4
Other Parts Discussed in Thread: CC1350

Hello TI community,

I am working with cc1350 and my application involves use of multi-tasking (threads/interrupts/timers) in Code Composer (in particular, run adcbufcontinuous example code along with controlling a servo motor simultaneously). Unfortunately I did not find example codes for this. It will be great if I could get some guidance here. 

Thanks for your time. 

  • The examples in the SDK is typically written to show how to use one driver or one feature. The examples are made as simple as possible to make them as easy to read as possible. We therefore don't have too many examples on how to do more  than one thing at the time. Both due to the complexity makes it harder to read/ understand. I different aspect is which 2 or 3 driver examples/ feature should be combined since it's  lot of options. 

    Could you describe a bit more on a high level what you need the code to do and hopefully it will be easier to point you to different examples you may find useful for the different things you need to implement in your code. 

  • Thanks for your reply. 

    In particular I want two applications with cc1350 (using only one microcontroller) - 1. adc values to be read and display to UART (for which I used adcbufcontinous sampling example code, works well) 

    2. control 5V dc servo motor clockwise and anticlock wise direction (0 to 180 degree should be good),  continuously (independant of adc values). I cannot find example code for this. 

    Please let me know if this is possible. 

  • Not clear if you have a full working code for 1:

    ADC - UART: you can look into the .zip in this post: https://e2e.ti.com/support/wireless-connectivity/sub-1-ghz-group/sub-1-ghz/f/sub-1-ghz-forum/647411/cc1310-uart_write-block-in-the-callback-of-rxpacket

    In your case you can post a semaphore in the ADC callback that notify that data can be sent on the UART.

    2: What exactly has to be sent to the motor? I assume that it's a driver between the CC1350 and the motor? Do you in effect need to send a signal to the motor every x ms? 

  •  

    #include <stdint.h>
    #include <stdio.h>
    /* For sleep() */
    #include <unistd.h>
    
    /* Driver Header files */
    #include <ti/drivers/ADCBuf.h>
    #include <ti/drivers/UART.h>
    
    /* Example/Board Header files */
    #include "Board.h"
    
    #define ADCBUFFERSIZE    (50)
    #define UARTBUFFERSIZE   ((20 * ADCBUFFERSIZE) + 24)
    
    uint16_t sampleBufferOne[ADCBUFFERSIZE];
    uint16_t sampleBufferTwo[ADCBUFFERSIZE];
    uint32_t microVoltBuffer[ADCBUFFERSIZE];
    uint32_t buffersCompletedCounter = 0;
    char uartTxBuffer[UARTBUFFERSIZE];
    
    /* Driver handle shared between the task and the callback function */
    UART_Handle uart;
    
    /*
     * This function is called whenever an ADC buffer is full.
     * The content of the buffer is then converted into human-readable format and
     * sent to the PC via UART.
     */
    void adcBufCallback(ADCBuf_Handle handle, ADCBuf_Conversion *conversion,
        void *completedADCBuffer, uint32_t completedChannel)
    {
        uint_fast16_t i;
        uint_fast16_t uartTxBufferOffset = 0;
    
        /* Adjust raw ADC values and convert them to microvolts */
        ADCBuf_adjustRawValues(handle, completedADCBuffer, ADCBUFFERSIZE,
            completedChannel);
        ADCBuf_convertAdjustedToMicroVolts(handle, completedChannel,
            completedADCBuffer, microVoltBuffer, ADCBUFFERSIZE);
    
        /* Start with a header message.
        uartTxBufferOffset = snprintf(uartTxBuffer,
            UARTBUFFERSIZE - uartTxBufferOffset, "\r\nBuffer %u finished.",
            (unsigned int)buffersCompletedCounter++);*/
    
        /* Write raw adjusted values to the UART buffer if there is room.
        uartTxBufferOffset += snprintf(uartTxBuffer + uartTxBufferOffset,
            UARTBUFFERSIZE - uartTxBufferOffset, "\r\nRaw Buffer: ");
    
        for (i = 0; i < ADCBUFFERSIZE && uartTxBufferOffset < UARTBUFFERSIZE; i++) {
            uartTxBufferOffset += snprintf(uartTxBuffer + uartTxBufferOffset,
                UARTBUFFERSIZE - uartTxBufferOffset, "%u,",
            *(((uint16_t *)completedADCBuffer) + i));
        }*/
    
    
        /* Write microvolt values to the UART buffer if there is room. */
        if (uartTxBufferOffset < UARTBUFFERSIZE) {
            uartTxBufferOffset += snprintf(uartTxBuffer + uartTxBufferOffset,
                UARTBUFFERSIZE - uartTxBufferOffset, "");
    
            for (i = 0; i < ADCBUFFERSIZE && uartTxBufferOffset < UARTBUFFERSIZE; i++) {
                uartTxBufferOffset += snprintf(uartTxBuffer + uartTxBufferOffset,
                    UARTBUFFERSIZE - uartTxBufferOffset, "%u\r\n",
                    (unsigned int)microVoltBuffer[i]);
            }
        }
    
    /*
         * Ensure we don't write outside the buffer.
         * Append a newline after the data.
    
        if (uartTxBufferOffset < UARTBUFFERSIZE) {
            uartTxBuffer[uartTxBufferOffset++] = '\n';
        }
        else {
            uartTxBuffer[UARTBUFFERSIZE-1] = '\n';
        }
    */
        /* Display the data via UART */
        UART_write(uart, uartTxBuffer, uartTxBufferOffset) ;
    }
    
    /*
     * Callback function to use the UART in callback mode. It does nothing.
     */
    void uartCallback(UART_Handle handle, void *buf, size_t count) {
       return;
    }
    
    /*
     *  ======== mainThread ========
     */
    void *mainThread(void *arg0)
    {
        UART_Params uartParams;
        ADCBuf_Handle adcBuf;
        ADCBuf_Params adcBufParams;
        ADCBuf_Conversion continuousConversion;
    
        /* Call driver init functions */
        ADCBuf_init();
        UART_init();
    
        /* Create a UART with data processing off. */
        UART_Params_init(&uartParams);
        uartParams.writeDataMode = UART_DATA_BINARY;
        uartParams.writeMode = UART_MODE_CALLBACK;
        uartParams.writeCallback = uartCallback;
        uartParams.baudRate = 115200;
        uart = UART_open(Board_UART0, &uartParams);
    
        /* Set up an ADCBuf peripheral in ADCBuf_RECURRENCE_MODE_CONTINUOUS */
        ADCBuf_Params_init(&adcBufParams);
        adcBufParams.callbackFxn = adcBufCallback;
        adcBufParams.recurrenceMode = ADCBuf_RECURRENCE_MODE_CONTINUOUS;
        adcBufParams.returnMode = ADCBuf_RETURN_MODE_CALLBACK;
        adcBufParams.samplingFrequency = 200;
        adcBuf = ADCBuf_open(Board_ADCBUF0, &adcBufParams);
    
        /* Configure the conversion struct */
        continuousConversion.arg = NULL;
        continuousConversion.adcChannel = Board_ADCBUF0CHANNEL0;
        continuousConversion.sampleBuffer = sampleBufferOne;
        continuousConversion.sampleBufferTwo = sampleBufferTwo;
        continuousConversion.samplesRequestedCount = ADCBUFFERSIZE;
    
        if (adcBuf == NULL){
            /* ADCBuf failed to open. */
            while(1);
        }
    
        /* Start converting. */
        if (ADCBuf_convert(adcBuf, &continuousConversion, 1) !=
            ADCBuf_STATUS_SUCCESS) {
            /* Did not start conversion process correctly. */
            while(1);
        }
    
        /*
         * Go to sleep in the foreground thread forever. The ADC hardware will
         * perform conversions and invoke the callback function when a buffer is
         * full.
         */
        while(1) {
            sleep(1000);
        }
    }
    

    This is the code I am using for 1.

    I am not using motor driver. I just want a PWM signal to be sent to the motor continously so that it rotates. 

  • For 2: you should be able to use the PWNM driver (example here: https://dev.ti.com/tirex/explore/node?node=AETjgZm7r0T61L2IeMRevg__eCfARaV__LATEST) in a separate task. 

    A callback is in effect an interrupt handling meaning that the code in the callback should be lightweight. Move the UART write to a different task and use a semaphore to get better control over the timing since the UART write is fairly time consuming. 

  • Thank you for the link, but unfortunately I get an error that the resource does not exist in dev ti. 

  • Sorry, an extra = had snuck into the link. Try dev.ti.com/.../node