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.

SM470R1B1M-HT: SCI Interrupts

Part Number: SM470R1B1M-HT

Hello,

I am writing an application for the SM470R1B1M microcontroller and having problems with triggering the SCI TX interrupt. The RX interrupt works w/o problems. Here is the code:

void INIT_SCI(void)
{
  //init for eval board SCI1
  SCI1CTL3 &= ~SW_NRESET;                 // Reset SCI state machine
  SCI1CCR = TIMING_MODE_ASYNC + CHAR_8;   // Async, 8-bit Char
  SCI1CTL1 |= RXENA;                      // RX enabled
  SCI1CTL2 |= TXENA;                      // TX enabled
  SCI1CTL3 |= CLOCK + RX_ACTION_ENA;      // Internal clock. RX TX interrrupt
  SCI1LBAUD = 0xC2;                       // 30MHz/(8*19200)-1
  SCI1PC2 |= RX_FUNC;                     // SCIRX is the SCI receive pin
  SCI1PC3 |= TX_FUNC;                     // SCITX is the SCI transmit pin  
  SCI1CTL2 &= ~TX_DMA_ENA;  //From the datasheet: To use transmit interrupt functionality, the TX DMA ENA bit (SCICTL2.5) must be cleared
  REQMASK |= (1 << CIM_SCI1RX);            // Enable interrupt SCI1RX channel
  REQMASK |= (1 << CIM_SCI1TX);            // Enable interrupt SCI1TX channel
  SCI1CTL3 |= SW_NRESET;                  // Configure SCI1 state machine
}//end of INIT_SCI

...

 // enable SCI1 receive interrupt
  REQMASK |= 0x00000400;
  // enable SCI1 transmit interrupt
  REQMASK |= 1<<CIM_SCI1TX;

...

__irq __arm void IRQ_Handler(void)
{
  switch((0xFF & FIQIVEC)-1)
  {
    case CIM_COMP1:
     COMP1_irq_handler();
    break;
    case CIM_SCI1RX:    // uart1 rx interrupt
      SCI1RX_irq_handler();
      //LED_BLINK;
    break;
    case CIM_SCI1TX:    // uart1 tx interrupt
      SCI1TX_irq_handler();
      //LED_BLINK;
    break;
  }
}//end of FIQ_Handler()

.....

__fiq __arm void FIQ_Handler(void) //used the same function as IRQ_Handler to be sure...
{
  switch((0xFF & FIQIVEC)-1)
  {
    case CIM_COMP1:
     COMP1_irq_handler();
    break;
    case CIM_SCI1RX:    // uart1 rx interrupt
      SCI1RX_irq_handler();
      //LED_BLINK;
    break;
    case CIM_SCI1TX:    // uart1 tx interrupt
      SCI1TX_irq_handler();
      //LED_BLINK;
    break;
  }
}//end of FIQ_Handler()

....

void Write_Serial_Port_One(unsigned char byte)
{
    while(Tx_1_Queue_Full);
    Tx_1_Queue[Tx_1_Queue_Write_Index] = byte;
    // increment the queue byte count
    Tx_1_Queue_Byte_Count++;
    // increment the write pointer
    Tx_1_Queue_Write_Index++;
    Tx_1_Queue_Write_Index &= TX_1_QUEUE_INDEX_MASK;
    SCI1CTL3 &= ~TX_ACTION_ENA; //SCICTL3.3
    if(Tx_1_Queue_Read_Index == Tx_1_Queue_Write_Index)
    {
        Tx_1_Queue_Full = TRUE;
    }
    SCI1CTL3 |= TX_ACTION_ENA; //SCICTL3.3
    Tx_1_Queue_Empty = FALSE;
}

This line above should trigger the SCI TX interrupt:  SCI1CTL3 |= TX_ACTION_ENA; //SCICTL3.3 - but it doesn't.

I implemented the same code for many other microcontrollers w/o problems.

Thanks,

Marius Raducanu

  • Hi Marius,

      I'm not familiar with this device. But let me see if I can help here. Please see below description.

    4.1.1 Transmit Interrupt To use transmit interrupt functionality, the TX DMA ENA bit (SCICTL2.5) must be cleared. The following paragraphs describe how a CPU interrupt can be initiated by a transmit ready condition.  The transmit ready (TXRDY) flag is set when the SCI transfers the contents of SCITXBUF to the shift register, SCITXSHF. The TXRDY flag indicates that SCITXBUF is ready to be loaded with more data. In addition, the SCI sets the TX EMPTY bit if both the SCITXBUF and SCITXSHF registers are empty. Transmit interrupts are enabled by the TX ACTION ENA (SCICTL3.3) bit. If the TX ACTION ENA bit (SCICTL3.3) is set, then a transmit interrupt is generated when the TXRDY flag goes high. Writing data to the SCITXBUF register clears the TXRDY bit. When this data has been moved to the SCITXSHF register, the TXRDY bit is set again. The interrupt request can be suspended by clearing the TX ACTION ENA bit; however, when the TX ACTION ENA bit is again set to 1, the TXRDY interrupt is asserted again. The transmit interrupt request can be eliminated until the next series of values is written to SCITXBUF by disabling the transmitter via the TXENA bit (SCICTRL2.0 = 0), an SCI software reset, or by a device hardware reset.

      Can you please check:

      -  The SCICTL2.5 needs to be clear

      - What is the status of TXRDY bit before you run SCI1CTL3 |= TX_ACTION_ENA?

      - If the TXRDY is not high then can you first try write a data to the SCITXBUF so that the data will be transferred to the SCITXSHF by which time the TXRDY will be asserted?

      This below post may be also helpful.

    https://e2e.ti.com/support/legacy_forums/hirel/f/935/t/433871?tisearch=e2e-sitesearch&keymatch=SM470R1B1

  • Hi Charles,

    Thanks for your response.

    I checked the documentation and I already did what you suggested in the code. The link you sent wasn't helpful.

    In my previous implementations of SCI TX interrupt in other microcontrollers, setting the interrupt flag, triggered the interrupt (CASE 2 below). Also, after transmitting a byte, the interrupt was triggered (CASE 1 below).

    From the datasheet:

    If the TX ACTION ENA bit (SCICTL3.3) is set, then a transmit interrupt is generated when the TXRDY flag goes high.- CASE 1

    ...however, when the TX ACTION ENA bit is again set to 1, the TXRDY interrupt is asserted again. - CASE 2

    From what I've tested, CASE 1, partially works but CASE 2 doesn't work.

    I was able to transmit "123456789" using SCI TX interrupts only after I set the interrupt flag and write a byte in the SCITXBUF register (clearing the TXRDY) as in CASE 1. The last character (0) that I've tried to send, wasn't sent and the SCI stopped to work. Even if this code works, to transmit data on SCI using the TX interrupt implies to write the first byte in SCITXBUF that is not handy. I prefer to start transmitting the bytes (trigger the TX interrupt) setting the interrupt flag (TX_ACTION_ENA) - CASE 1 that doesn't work.

    I've implemented code (including printf) to transmit on serial without interrupts (blocking code) but I prefer the non blocking code (that uses the TX interrupt) because is more efficient - I am still working on this.

    Regards,

    Marius  

  • Hello,

    The way I use the TX interrupt in a microcontroller (can be TI (SM, TMS), STM, microchip, ...) firmware is:

    - set the SCI module, clear the TX interrupt flag and disable (clear) the enable interrupt (waiting to be set, to trigger the interrupt)

    - start adding bytes in a queue. The first byte added, triggers also the TX interrupt (setting the enable interrupt flag). After adding the first byte, adding bytes in queue and the TX interrupt run in "parallel" - during the time a byte is sent other bytes are added in TX queue.  

    - adding bytes in the queue is faster than sending bytes in the interrupt so after adding in the queue all the bytes, the firmware can go to the next task because the TX interrupt is transmitting the bytes in queue - non blocking task.

    The problem I have with SM470 is that it doesn't trigger the interrupt when I set the TX_ACTION_ENA flag.

    To trigger the TX interrupt I have to write SCITXBUF (when the TX_ACTION_ENA flag is set).

    Because of this, to send bytes using the interrupt, I have to put all the bytes that I want to send in a queue and after this to write the first byte in SCITXBUF. to trigger the TX interrupt - not so elegant and prone to mistakes

    Is is something that I miss?

    Can the TX interrupt be triggered ONLY by setting the TX_ACTION_ENA flag (without requiring writing in SCITXBUF)?

     

    Regards,

    Marius.

  • Hi Marius,

    Marius Raducanu said:

    Is is something that I miss?

    Can the TX interrupt be triggered ONLY by setting the TX_ACTION_ENA flag (without requiring writing in SCITXBUF)?

      I can't speak for devices from other vendors. I check another two TI devices, one is TMS570 and another is TM4C MCU. They all require data be written to the SCITXBUF (in TMS570) or meeting a certain threshold in the TXFIFO (in TM4C) before the interrupt is generated. This is the way it works in these TI devices. You will just need to work within its specification. Sorry, I understand this may not be the answer you are looking for. But there is nothing I can help on this as this is how the TI SCI/UART module works. 

    For TMS570:

    As indicated by Step 3, software should wait for the SCI to clear the TXWAKE bit. However, the SCI
    clears the TXWAKE bit at the same time it sets TXRDY (that is, transfers data from SCITD into
    SCITXSHF). Therefore, if the TX INT ENA bit is set, the transfer of data from SCITD to SCITXSHF causes
    an interrupt to be generated at the same time that the SCI clears the TXWAKE bit. If this interrupt method
    is used, software is not required to poll the TXWAKE bit waiting for the SCI to clear it.

     

    For TM4C:

    If the FIFOs are enabled and the transmit FIFO progresses through the programmed trigger
    level, the TXRIS bit is set. The transmit interrupt is based on a transition through level, therefore
    the FIFO must be written past the programmed trigger level otherwise no further transmit interrupts
    will be generated. The transmit interrupt is cleared by writing data to the transmit FIFO until it
    becomes greater than the trigger level, or by clearing the interrupt by writing a 1 to the TXIC bit.

     

  • Hi Charles,

    Thanks for your response and confirming what I suspected.

    If the TX interrupt can be triggered only by writing in SCITXBUF when TX_ACTION_ENA is set, I will change the way I send data with interrupts: put the data in a queue and then trigger the interrupt, calling directly the interrupt function that has a write in SCITXBUF.

    Regards,

    Marius