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.

AM2634: Uart implementation in Interrupt mode

Part Number: AM2634


Tool/software:

Hi Team,

I want to use UART receive data in interrupt mode (block mode not required), but all interrupt and DMA based example in existing SDK are blocked the process by

SemaphoreP_pend(&gUartReadDoneSem, SystemP_WAIT_FOREVER) this API, 

So want to know how achieve my requirements,

1. Interrupt on every receive byte 

2. How to implement logic to receive unknown receive data length  

3. if Rx fifo threshold is set to 8 and User send 5 bytes only, then how to get these 5 bytes

  • Hi Rohal,

    1. You can do this by setting the threshold size to 1. It will then trigger an interrupt for every byte received.

    2. This is what we would call partial mode. We are working on this right now. I might be able to share a patch over existing example in the SDK which shows the working of partial mode. I would need about 2-3 days for this to test and share.

    3. If you implement the point 1, this wouldn't be an issue as you would be getting an interrupt for those 5 bytes.

    I will get back to you with the patch to implement partial mode.

    Regards,
    Shaunak

  • Hi Rohal,

    I have a piece of code that might be helpful to you. Note: The UART is configured with 12000000 Baud Rate.

    1. Added partial mode for interrupt mode in the code.

    2. The code also showcases interchange between DMA and interrupt mode at runtime.

    uart_echo_dma_interrupt_lld.zip

    Regards,
    Shaunak

  • thanks for code and support

    please let me know what the SDK version and compiler version used to compile

    please explain below attribute

    static __attribute__((target("arm"), aligned(4))) void App_UART_ISR(void);  

    Is below statement , blocked API?

     while(try_lock_mutex(gUartObject[CONFIG_UART_CONSOLE].readTransferMutex) == MUTEX_ARM_LOCKED);
    APP_UART_ASSERT_ON_FAILURE(transferOK, trans);

    please explain below statement also

    static __attribute__((noinline, naked, target("arm"), aligned(4))) void App_UART_ISR(void)

    Do we need to implement Mutex and Semaphore for our application or we can bypass ?

  • Hi Rohal, 

    please let me know what the SDK version and compiler version used to compile

    This zip is not a complete working CCS project, rather a reference code to implement partial mode. You can use this code with MCU_PLUS_SDK 09.02 (latest public SDK)

    static __attribute__((target("arm"), aligned(4))) void App_UART_ISR(void);  

    These are function attributes for App_UART_ISR function.

    target - Arm means the code will compile with A32 state (All A32 instructions are 32 bits long. Instructions are stored word-aligned, so the least significant two bits of instruction addresses are always zero in A32 state.) Read more about it here: https://developer.arm.com/documentation/101754/0622/armclang-Reference/Compiler-specific-Function--Variable--and-Type-Attributes/--attribute----target--options-----function-attribute

    aligned(4) - Alignment by a 4 Byte boundary. Basically the memory address for App_UART_ISR will be divisible by 4. This is just for efficient memory access.

    naked - This attribute tells the compiler that the function is an embedded assembly function.

    noinline - The noinline variable attribute prevents the compiler from making any use of a constant data value for optimization purposes, without affecting its placement in the object.

    Is below statement , blocked API?

     while(try_lock_mutex(gUartObject[CONFIG_UART_CONSOLE].readTransferMutex) == MUTEX_ARM_LOCKED);
    APP_UART_ASSERT_ON_FAILURE(transferOK, trans);

    To run in partial mode, you will need this while loop. FreeRTOS here tries to acquire the Mutex. Until the Mutex is locked, the UART is reading data. You don't necessarily have to implement any mutex or semaphores. FreeRTOS already has that implementation.

    Even if you somehow want to bypass the semaphore and mutex, you would still need a while loop which will constantly read the data.

    Regards,
    Shaunak

  • Dear Shaunak,

    I'm using Uart interrupt in call back example and configure rx buffer size of one , I want UART receive interrupt on every one receive byte

    but in this configuration only first byte received and after that uart didn't get interrupt,

    What i did

    In call back function uart buffer data copy and again  UART_read() api called for next byte interrupt enable.

    So please let me know how to implement byte by byte interrupt enable  

      

  • Hi Rohal,

    For byte-by-byte interrupt enable, the simplest way is to change the threshold size from 8 to 1. You can open the application syscfg file and change the highlighted section based on your Rx and Tx requirements.

    Regards,
    Shaunak

  • Sorry its not working for me.....,

    Can you try on your side and share the code, try at least 10 byte receive, one by one. 

  • Hello Rohal,

    I tried the above mentioned solution, it worked for me. Sharing the steps in detail below:

    1. Import the UART ECHO Interrupt LLD example from the 09.02 SDK to CCS. Make the above mentioned change in the syscfg file

    2. Build the example in debug mode (so we can set breakpoints and debug efficiently).

    3. Set a breakpoint at the following function: App_UART_ISR. This function will service your ISR for read/write.

    4. The example will expect you to give 8 bytes of inputs before declaring "All tests passed". You can enter a byte one by one in the console and see the ISR breakpoint being hit every single time. Enter a character, the breakpoint hits and core halts, resume the core and enter another byte in the terminal and so on until 8 bytes have been entered.

    Im also attaching my CCS project for reference

    uart_echo_interrupt_lld_am263x-cc.zip

    Regards,
    Shaunak

  • Yes, Practically its working but its very hard to understand,

     On 1 byte receive do we need to clear the rx interrupt flag? if yes how its handling in current code  

    why two call back are there , one for every interrupt and second for buffer over flow interrupt?

    Do we need mutex/semaphore for uart implementation in NonRtos application?

    Do you any supporting document to understand the work flow of UART interrupts handling.

  • Hi Rohal,

    Yes, Practically its working but its very hard to understand,

    Thanks for confirming the workflow.

    On 1 byte receive do we need to clear the rx interrupt flag? if yes how its handling in current code  

    why two call back are there , one for every interrupt and second for buffer over flow interrupt?

    The LLD driver in the SDK explains the current ISR handling:

    /*
     *  ======== UART_controllerIsr ========
     *  Hwi function that processes UART interrupts.
     *
     *  In non-DMA mode, three UART interrupts are enabled:
     *    1. transmit FIFO is below the TX FIFO trigger level (THR)
     *    2. receive FIFO is above RX FIFO trigger level (RHR)
     *    3. line status rx error
     *
     *  ISR checks the three interrupts, to ensure that all
     *  the pending interrupts are handled.
     *
     *  If line status rx error is detected, ISR clears the last read error, update
     *  the actual number of bytes transferred and transfer status in readTrans and
     *  calls back to application in the callback mode or post the read semaphone
     *  in the blocking mode. ISR
     *
     *  If RHR interrupt is received, ISR calls the in-lined function readData to
     *  read the data out from the RX FIFO. When all the data are received, ISR updates
     *  the actual number of bytes transferred and transfer status in readTrans and
     *  calls back to the application in the callback mode or post the read semaphone
     *  in the blocking mode. if RX timeout is detected, ISR will log the timeout
     *  count.
     *
     *  If THR interrupt is received, ISR calls the in-lined function writeData,
     *  to write the data to the TX FIFO. After all the data are sent, TX FIFO empty
     *  interrupt is enabled, ISR will update the actual number of bytes transferred
     *  and transfer status in writeTrans and calls back to application in the
     *  callback mode or post the read semaphone in the blocking mode.
     *
     *
     *  @param(arg)         The UARTLLD_Handle for this Hwi.
     */
    void UART_lld_controllerIsr(void* args)

    Do we need mutex/semaphore for uart implementation in NonRtos application?

    Yes. This example uses mutexes for read and write. Mutex here is used to make sure the UART read and write commands are not executed simultaneously. For example, when the UART_lld_writeIntr is called, the UART writeTransferMutex will be in a blocked state of MUTEX_ARM_LOCKED. This ensures that the write operation of UART is completed without any interruptions. Depending on the flow of your application, you can decide if you want to use mutex/semaphores.

    It is NoRTOS based example but the mutex and semaphores can be created using the DPL (driver porting layer, read more about it here: https://dev.ti.com/tirex/explore/content/am26x_academy_2_02_00_00/_build_am26x_academy_2_02_00_00/source/kernel/dpl.html#semaphores-in-am263x-microcontrollers)

    Do you any supporting document to understand the work flow of UART interrupts handling.

    I would recommend going through the C file for LLD driver called "uart_v0_lld.c" in the SDK. It has enough comments in the code to understand a top level working of the driver.

    Regards,
    Shaunak