Post Go back to editing

UART tx and rx interrupt

Hi,

   I am suing SHARC 21369 processor. I want to use the UART Transmit and receive interrupt to send and receive messages. I have gone through the UART echo back example.

The echo back example uses only receive interrupt. I have gone through the hardware refrence manual and I am a bit confuse on how to enable and use both transmit and receive interrupts.

The uart receive interrupt is assigned to P13 using the following

*pPICR2 &= ~(0x3E0);  

//Sets the UART0 receive interrupt to P13

 

Do I need to assign UART0 transmit interrupt to say P14?  I will be grateful if anyone could provide me some information or example code.

 

 

         Cheers,

         RAZ.

  • Hi Raz,

    Please note the following statement at page 11-9 of the ADSP-21369 HRM:

     

     

     

    "Even though the UART has two interrupts for receive and transmit, in I/O mode, all interrupts are grouped as a single receive interrupt".

     

    You might need to read the UARTxIIR register to know whether the interrupt has occured because of "TX buffer empty" or "RX buffer full" condition. Please make sure that the required interrupt is enabled in the UARTxIER register.

    Hope this helps.

    Thanks,

    Mitesh

  • Hi Mitesh,

                        Thanks for your reply. So please verify if I need to do the following

    1) Since all interrupts are grouped as single receive interrupt we DONT have to assign UART0 transmit interrupt to say P14

    2) Need to enable tx interrupt using

          *pUART0IER   = UARTTBEIE;

    3)  Read the UARTIIR register with the receive ISR as follows:

    void UARTisr()
    {

        //Check if  Rx interrupt.

        if ((*pUART0IIR ) == 4){

              //codefor rx interrupt

         }

        //Check if  Tx interrupt.

        if ((*pUART0IIR ) == 0){

              //codefor tx interrupt

         }

    }

              RAZ

  • Hi RAZ,

    Please see my reply below:

    1)  Since all interrupts are grouped as single receive interrupt we DONT have to assign UART0 transmit interrupt to say P14

     

    >> Yes.

    2) Need to enable tx interrupt using

          *pUART0IER  = UARTTBEIE;

    >> That's correct. But in case you want to enable both THR empty and RBR full interrupts, the instruction should be something like this:

        *pUART0IER  = UARTTBEIE|UARTRBFIE;

    3)  Read the UARTIIR register with the receive ISR as follows:

    void UARTisr()
    {

        //Check if  Rx interrupt.

        if ((*pUART0IIR ) == 4){

              //codefor rx interrupt

        }

        //Check if  Tx interrupt.

        if ((*pUART0IIR ) == 0){

              //codefor tx interrupt

        }

    }

    >> Since all enabled interrupts sources are sharing the UART RX interrupt, you might need to mask the content of UART0IIR register with the bit you want to test i.e.

     

    if ((*pUART0IIR ) == 4) should be replaced by if ((*pUART0IIR&4 ) == 4)

     

    Also, the correct instruction to test whether the interrupt occured because of THR buffer empty would be


    if ((*pUART0IIR&2 ) ==2 ) instead of  if ((*pUART0IIR ) == 0)

    Hope this helps.

    Thanks,

    Mitesh

  • Hi everyone.

    I'm working on a project with the ADSP-21369 EZ-kit lite and I'm facing some problems related to the UART.

    The code I present below is very simple and it's mostly based on the "UART echo back (C)" example.

    I'm using the program "Termite" to establish communication to the UART. It's very similar to hyperterminal. I write some predefined commands and the DSP responds what I want. As you can see in the sample of my code if I write "OK?" in Termite the DSP responds "ALL IS OK" or if I write "get info" samples are acquired from an external ADC and processed. I have also other commands but to simplify they're not included here.

    The problem I'm facing is in the UART_isr function. When I write any command the program enters UART_isr, checks the condition if((*pUART0IIR&4)==4  and executes the correspondent function in the main cycle. If I want to transmit data, like a large number of acquired samples, I want them to be transmitted while other algorithms are still running.  I suppose by Mitesh's sugestion that I could activate a transmit interruption by doing if((*pUART0IIR&2)==2 condition. When I run my code the program never enters that section in UART_isr.

    What am I doing wrong? Is it any configuration register? I hope you could help.

    Best regards

    Pedro

    //-------------------------------------------------------------------------------------------//

    char uart_receive_buffer[20];

    char uart_transmit_buffer[200];

    int uart_char_receive_counter=0;    

    main(){

    *pPICR2 &= ~(0x3E0);                                    // Sets the UART0 receive interrupt to P13.
    *pPICR2 |= (0x13<<5);       // For I/O mode, both the transmit and receive interrupt can be
                                                  // programmed through the PICR register using the code select
                                                  // value for the UART receive interrupt (0x13 for UART0 interrupt).

    *pUART0LCR=0;

    *pUART0IER = UARTTBEIE | UARTRBFIE;

    interrupt(SIG_P13,UART_isr);

    Route_DPI_Signals_UART0();                // makes UART0 signal connections to DPI pins

    Init_UART0();                                             // Defining RS232 protocol (baud rate, stop bits, parity...).

    sysreg_bit_set(sysreg_MODE1,IRPTEN);     // Enable interrupts (globally)
    while(!EXIT) {
            while(!END_OF_MESSAGE){
                }
                      if((strcmp(uart_receive_buffer,"OK?")==0)){          // user check if everything is ok
                 Transmit_UART_message("ALL IS OK\n");     //  transmited message
            }
           else if if((strcmp(uart_receive_buffer,"get info")==0)){
                  Acquiredata();                               // acquire data from external ADC
                 // ...code for doing some calculations like FFT, sine-fitting and other algorithms;
           }
           else {
                 Transmit_UART_message("Unknown command: \"");
                 Transmit_UART_message(uart_receive_buffer);
                 Transmit_UART_message("\"\n\n");
           }
    }
    }
    // UART0 ISR
    void UART_isr(){
         int value,i;
      
         if((*pUART0IIR&4)==4){
              value = *pUART0RBR;                                             // UART Receive Buffer Register (RBR)
              while((*pUART0LSR & UARTTHRE) == 0){;}                                
                 uart_receive_buffer[uart_char_receive_counter]=value;
              uart_char_receive_counter++;
            
              if(value==10) {                                     // detect new line
                   uart_char_receive_counter--;
                      uart_receive_buffer[uart_char_receive_counter]='\0';
                      END_OF_MESSAGE=1;
                 }
         }
         if ((*pUART0IIR&2)==2){
               // transmit interrupt code -> never enters here
         }
    }
    // TRANSMIT UART FUNCTION
    void Transmit_UART_message(char*xmit){
         int i;
         int SIZE;
         SIZE=strlen(xmit);
         #pragma vector_for
         for (i=0; i<SIZE; i++){                                   /* loop to transmit source array in core driven mode */ 
              do {;}                                                                      // Wait for the UART transmitter to be ready.
              while ((*pUART0LSR & UARTTHRE) == 0);
      
            *pUART0THR = xmit[i];
         }
    while ((*pUART0LSR & UARTTEMT) == 0){;}
    }
  • Hi,

    Please note that the THR empty status bit in the UARTx_IIR register is cleared either by writing to THR register or by reading UARTx_IIR register. So, in your code whenever the THR empty interrupt occurs, it gets cleared by the instruction "if((*pUART0IIR&4)==4)". So the expression "if ((*pUART0IIR&2)==2)" always returns FLASE.  The recommended way is to read the UARTx_IIR register first in a temporary local variable and then use that local variable to check whether RX buffer full or TX buffer empty bit is set i.e. the modified uart ISR code should be as follows:

    void UART_isr(){

         int value,i, temp;

         temp=*pUART0IIR;

         if((temp&4)==4){

              value = *pUART0RBR;                                             // UART Receive Buffer Register (RBR)

              while((*pUART0LSR & UARTTHRE) == 0){;}                                

                 uart_receive_buffer[uart_char_receive_counter]=value;

              uart_char_receive_counter++;

              if(value==10) {                                     // detect new line

                   uart_char_receive_counter--;

                      uart_receive_buffer[uart_char_receive_counter]='\0';

                      END_OF_MESSAGE=1;

                 }

         }

         if ((temp&2)==2){

               // transmit interrupt code ->should enter here now

         }

    }

    This should work for you. Please let me know if you still face further issues.

    Thanks,

    Mitesh

  • Hi Mitesh

    Thanks for the sugestion, it worked just fine though I have another doubt.

    The condition "if ((temp&2)==2)" is true if previously a character is written to *pUART0THR. If I want to transmit a set of data with this interruption do I have to transmit something else first to activate it or there's another way around? I think there's something I'm not considering but I can't see what it is.

    Glad for your help,

    Regards,

    -Pedro

  • Hi Pedro,

    You don't essentially have to write something previously to start the THR empty interrupt. You will get a THR empty interrupt as soon as the UART transmitter is enabled provided that the respective bit is set in the UARTxIER register. Inside the interrupt, you can make write to THR to transmit something. However, the usual practice is to load the UARTxTHR buffer with the first data you want to transmit and then enable the UART transmit buffer in the UARTxTXCTL register. Once the THR buffer is emptied, you will get an interrupt and inside the ISR, you can load second data to transmit and this process continues till the complete buffer is sent out. Once, you are done with UART transmit, you can disable the tx buffer by clearing the UARTEN bit in the UARTxTXCTL register.

    Hope this answers your question.

    Thanks,

    Mitesh

  • This question has been assumed as answered either offline via email or with a multi-part answer. This question has now been closed out. If you have an inquiry related to this topic please post a new question in the applicable product forum.

    Thank you,
    EZ Admin