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.

CCS/CC3220SF-LAUNCHXL: UART Interrupt

Part Number: CC3220SF-LAUNCHXL
Other Parts Discussed in Thread: CC3220SF

Tool/software: Code Composer Studio

Hello! I try define UART interrupt using in my application based on netwotk_terminal_CC3220SF_LAUNCHXL_tirtos_ccs. The UART drivers are not compatable with my UART protocol processing and I need have my own interrupt, that process my UART packet.

My first error was, that UART interrupt called forever, and application don't work. I fixed it by using MAP_UARTIntDisable(hwAttrs->baseAddr,0xFFFF);
Now I have problem, that interrupt generate only for even symbol, and when I can read two received symbols. After I send one character to UART, I don't get interrupt, then I send second symbol - UART interrupt generate and I can read two character. But I need get interrupt for every symbol received. UART FIFO is disabled. What error I make, when configuring UART interrupt?

P.S. I tryed use HWI instead MAP_UARTIntRegister(hwAttrs->baseAddr,UART0_Handler), but it have same effect.

Thank you!

My code:

static void UART0_Handler(uintptr_t arg)
{
  char UART_STATUS = 0;
  char byBuf;
  int i=0;

  UARTCC32XX_HWAttrsV1 const   *hwAttrs = rfidHandle->hwAttrs;

  UART_STATUS = UARTIntStatus(hwAttrs->baseAddr, true);
  MAP_UARTIntClear(hwAttrs->baseAddr,UART_STATUS);

  if((UART_STATUS & UART_INT_RX) && MAP_UARTCharsAvail(hwAttrs->baseAddr))
  {
    //clear the receive interrupt
    MAP_UARTIntClear(hwAttrs->baseAddr, UART_INT_RX);
    //receive data here
    byBuf = (unsigned char)MAP_UARTCharGetNonBlocking(hwAttrs->baseAddr);

    /* My own code process UART message */


   }

}

void RFIDUartInit()
{
    UART_Params         uartParams;
    pthread_t           uartmonThread;
    pthread_attr_t      attrs;
    struct sched_param  priParam;
    int                 retc;
    ClockP_FreqHz                 freq;
    uint16_t                     pin;
    uint16_t                     mode;
    long  lFIFOLvlRx;
    long  lFIFOLvlTx;

    byRecCntRfid=0;

    rfidHandle = (UART_Handle)&(UART_config[Board_UART0]);
    UARTCC32XX_Object            *object = rfidHandle->object;
    UARTCC32XX_HWAttrsV1 const   *hwAttrs = rfidHandle->hwAttrs;

    /* Get the Power resource Id from the base address */
    object->powerMgrId = getPowerMgrId(hwAttrs->baseAddr);
    if (object->powerMgrId == (unsigned int)-1) {
        DebugP_log1("UART:(%p) Failed to determine Power resource id",
                hwAttrs->baseAddr);
        return (NULL);
    }

    /*
     *  Register power dependency. Keeps the clock running in SLP
     *  and DSLP modes.
     */
    Power_setDependency(object->powerMgrId);

    pin = (hwAttrs->rxPin) & 0xff;
    mode = (hwAttrs->rxPin >> 8) & 0xff;

    MAP_PinTypeUART((unsigned long)pin, (unsigned long)mode);

    pin = (hwAttrs->txPin) & 0xff;
    mode = (hwAttrs->txPin >> 8) & 0xff;

    MAP_PinTypeUART((unsigned long)pin, (unsigned long)mode);

    MAP_UARTDisable(hwAttrs->baseAddr);
    ClockP_getCpuFreq(&freq);
    MAP_UARTConfigSetExpClk(hwAttrs->baseAddr,freq.lo,
                            RFIDUART_BAUDRATE,(UART_CONFIG_WLEN_8 |
                                            UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE));
    MAP_UARTFlowControlSet(hwAttrs->baseAddr, UART_FLOWCONTROL_NONE);
    MAP_UARTFIFODisable(hwAttrs->baseAddr); //disable fifo
    MAP_UARTFIFOLevelSet(hwAttrs->baseAddr,0,0);
    //here we will configure the UART-0 interrupt based communication
    MAP_UARTIntDisable(hwAttrs->baseAddr,0xFFFF);
    MAP_UARTIntEnable(hwAttrs->baseAddr,UART_INT_RX);
//Here I try use direct register interrupt function
//      MAP_UARTIntRegister(hwAttrs->baseAddr,UART0_Handler); //enable interrupts
//Here I use HWI    
      HwiP_Params hwiParams;
      HwiP_Params_init(&hwiParams);
      hwiParams.arg = (uintptr_t)rfidHandle;
      hwiParams.priority = hwAttrs->intPriority;
      object->hwiHandle = HwiP_create(hwAttrs->intNum, UART0_Handler,
          &hwiParams);
      if (object->hwiHandle == NULL) {
          System_printf("UART:(%p) HwiP_create() failed", hwAttrs->baseAddr);
//          UARTCC32XX_close(handle);
          return (NULL);
      }


      Swi_Params swiPar;
      Swi_Params_init(&swiPar);
      swiPar.priority=1;
      RFIDRecSWI=Swi_create(RFIDRec,&swiPar,NULL);

      MAP_UARTEnable(hwAttrs->baseAddr);


    return(rfidHandle);
}
 

  • Иван,

    Check the following function:
    MAP_UARTFIFOLevelSet(hwAttrs->baseAddr,0,0);

    The UART has two 16×8 bit FIFOs. if you set the TX FIFO level to zero, that means a interrupt with generate when the buffer is 1/8 full. 1/8 is 16 bits, so it would make sense you would get two characters before a interrupt.

    Regards,

    VR
  • Hello, Vincent!

    This function must don't have any effect, because above of it is function MAP_UARTFIFODisable(hwAttrs->baseAddr); //disable fifo
    But I tryed several combinations:

    MAP_UARTFIFODisable(hwAttrs->baseAddr); //disable fifo
    MAP_UARTFIFOLevelSet(hwAttrs->baseAddr,0,0);

    MAP_UARTFIFOEnable(hwAttrs->baseAddr); //enable fifo
    MAP_UARTFIFOLevelSet(hwAttrs->baseAddr,0,0);

    MAP_UARTFIFOEnable(hwAttrs->baseAddr); //enable fifo
    MAP_UARTFIFOLevelSet(hwAttrs->baseAddr,1,1);

    MAP_UARTFIFOEnable(hwAttrs->baseAddr); //enable fifo
    MAP_UARTFIFOLevelSet(hwAttrs->baseAddr,2,2);

    All this combinations have same effect: I get interrupt only if two character availible for read.

  • Could you elaborate on how the TI Drivers implementation of UART doesn't work for you? We have a pretty straight forward UART example you and reference and try instead of trying to use Driverlib and MAP calls to setup the UART peripheral. UART Reads can be configured to be blocking, so you can perform other tasks whlle your task waits for the UART command.

    If you wanna stick to what you have, use only HWI or UART config to setup the interrupt. Do both of these work by themselves?



    VR
  • Problem with TI Driverlib, what I must call non blocking read function with counts of symbols, what I need receive. But I don't know, how many symbols my periphiral send to me, it's information contains at UART packet, what I receive.

    I try use HWI or UART interrupt config, but they have same effect - I receive interrupt only if two symbols availible for read.

  • Hi,

    I'm thinking through your use case and I am trying to understand why the UART drivers are unsuitable for your system.

    If you don't know how much data you are getting in a single transfer from your connected peripheral, you could do blocking reads with timeout in a loop. You should be able to get all of the UART data transferred, timeout, and then have the UART_read() function return with the bytes read on the final incomplete transfer.

    If you can control the UART behavior on your peripheral, you could alternatively start every transfer from your peripheral with a short, fixed-length header. You would then start each transfer on the CC3220 by doing a UART_read() for the specific header length, and then immediately do additional UART_read() calls until you have transferred the correct amount of bytes.

    If you are using the DMA-based variant of the UART driver by enabling it in your CC3220SF_LAUNCHXL.c file, the UART FIFO is enabled and will be able to temporarily store data while you issue additional UART_read() calls, so you shouldn't encounter data loss with the second header-based approach.

    Let me know of your concerns with those two approaches, and if you have any clarifications on your use case I should know about. I think that you should definitely use the provided UART drivers instead of writing your own.

    Regards,
    Michael
  • Hi, Michael.

    If I will use blocking read, then I need create new task for it. It need some processor resource, and I don't want use it for my simple receiving UART function. In many over device I already was make interrupt suitable processing of my protocol. In protocol I have fixed header, and I everything compare it on receiver side for synchronyzation and stable receive. But I make it everything for each symbol.

    If I don't find work decision with interrupt I need use blocking read with "task", but I think it's not optimal decision for this simple task.

    Very interesting. I'm use two UART module in my project for CC3220. First module work normally for interrup processing, I get interrupt for every symbol. But initialize procedure is the same.

  • Hi Ivan,

    I wonder what is different between your two modules. Have you tried using a logic analyzer or scope and seeing what difference is there in the UART transfers?

    If blocking reads in a dedicated task are not possible due to resource constraints, you can also use non-blocking reads, but still use the UART drivers. You could have a non-blocking read for your header length, and then have that trigger another non-blocking read for the data length desired and then handle the incoming data much like you would with your interrupt handler above.

    Regards,
    Michael
  • Hi Michael.

    At logic analyzer data on two UART modules is same. One difference only is for first module I get interrupt every char, second module get interrupts only for two chars availible.

    Thank you for recomendation. I will think about all possible decision of my problem. And when I use any decision I wil post info about it here.