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.

UART read interrupt

Other Parts Discussed in Thread: CC2650

I can set up my UART to transmit on a CC2650/using TIRTOS, but I want to set it up to trigger an interrupt and read whenever a new message comes in on the RX line.

If I try to use PIN_Register IntCb though, it breaks my UART. How can I set up RTOS to run a callback event when a UART message comes in without losing UART functionality?

  • Hi Harsha,

    You should be able to set up the up the UART read mode to UART_MODE_CALLBACK like so:

        ...
        UART_Handle uart;
        UART_Params uartParams;
        ...
        UART_Params_init(&uartParams);
        ...
        uartParams.readMode = UART_MODE_CALLBACK; // sets up RX for callback mode
        uartParams.readCallback = myUART_readCallBack; // your callback function
        ...
        uart = UART_open(Board_UART0, &uartParams);
        ...

    Your callback function prototype should look similar to this:

    void myUART_readCallback(UART_Handle handle, void *ptr, size_t size);

    The second argument should be the read buffer, and the third argument is the amount read.

    Fair warning: in this mode, UART_read() will return immediately. Once it has completed, your callback function will be called. To kill a read in progress, you must call UART_readCancel(). Be careful with parallel reads as it will reset the UART status back to OK. Hope this helps.

    Gilbert

  • So to be clear, when does this trigger? I want the UART to start a read when it detects a rising edge on the RX pin, but that doesn't seem to be occurring. I'm not executing a read when I try to send a message to my CC2650 with the settings you recommended.
  • I may have misinterpreted your original question, but what I showed you in my first post may still work. The callback is called upon the completion of UART_read(), so a call to UART_read() must be made first. Here is a small example that you can find in the TI Drivers API guide. This case will configure the UART to receive continously in UART_MODE_CALLBACK, 16 bytes at the time and transmit them back via UART TX. Note that UART_reads() inside the read callback are safe to perform.

    #define MAX_NUM_RX_BYTES    1000   // Maximum RX bytes to receive in one go
    #define MAX_NUM_TX_BYTES    1000   // Maximum TX bytes to send in one go
    uint32_t wantedRxBytes;            // Number of bytes received so far
    uint8_t rxBuf[MAX_NUM_RX_BYTES];   // Receive buffer
    uint8_t txBuf[MAX_NUM_TX_BYTES];   // Transmit buffer
    // Callback function
    static void readCallback(UART_Handle handle, void *rxBuf, size_t size)
    {
        // Copy bytes from RX buffer to TX buffer
        for(size_t i = 0; i < size; i++)
            txBuf[i] = ((uint8_t*)rxBuf)[i];
        // Echo the bytes received back to transmitter
        UART_write(handle, txBuf, size);
        // Start another read, with size the same as it was during first call to
        // UART_read()
        UART_read(handle, rxBuf, wantedRxBytes);
    }
    static void taskFxn(UArg a0, UArg a1)
    {
        UART_Handle handle;
        UART_Params params;
        // Init UART and specify non-default parameters
        UART_Params_init(&params);
        params.baudRate      = 9600;
        params.writeDataMode = UART_DATA_BINARY;
        params.readMode      = UART_MODE_CALLBACK;
        params.readDataMode  = UART_DATA_BINARY;
        params.readCallback  = readCallback;
        // Open the UART and initiate the first read
        handle = UART_open(Board_UART, &params);
        wantedRxBytes = 16;
        int rxBytes = UART_read(handle, rxBuf, wantedRxBytes);
        while(true); // Wait forever
    }

    How are you interfacing with the CC2650? Are you using a different board or serial communication over USB?

    Gilbert

  • That's OK I guess, but what I was hoping for was for a read to trigger when a rising edge is detected, nit continuously polling. Is there a way to do this?
  • How are you interfacing with the CC2650? Are you using a different board or serial communication over USB? You might look into enabling the CC2650's UART flow control if it is appropriate for your application, but otherwise, I don't think that functionality is available in our UART drivers.
  • The UART communication is coming in through a differential 485 line from an external device, which is converted to 3.3V by the board circuitry.
  • Hm. I don't think flow control would be appropriate for your application. Having the UART read continuously is going to be your best alternative to what you are looking for.
  • So how does that work exactly? If a message transmits half way through a read to the device, wont the UART cut the message in half?

    Is this a possibility: I Set up a pin handle for the RX pin, set it to a GPIO, and register a callback to trigger on a rising edge. Then in the callback, I close the pin, and open the uart, and recieve the message. Then I close the uart and open back up the GPIO pin to wait for the next incoming message. Would that possibly work?
  • On the CC2650, RX and TX operate independently, so transmitting a message should not interfere with reading.

    I have two concerns with your scenario: I'm not sure opening the UART on the rising edge will give you a valid message since you would have already missed the first bit, and depending how long your read is, it could cause some complications since you would be doing all this in an interrupt context, which could cause some missed deadlines and clock ticks. You are welcome to try it, but I'd suggest keeping the reads short in the interrupt context, and interrupt on the falling edge instead, but I think even that might be too late.