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: enable RX interrupt for SCI3

Other Parts Discussed in Thread: HALCOGEN

Tool/software: Code Composer Studio

i could enable TX interrupts and that way successfully receive data by using this function:

uint32_t thcp_hw_read_hercules(uint8_t* buffer, const uint32_t length)
{
    uint32 bytes_read = 0;
    uint32 bytes_to_read = length;

    while (sciIsRxReady(thcp_hw_sci_base) && (bytes_to_read > 0))
    {
        buffer[bytes_read] = sciReceiveByte(thcp_hw_sci_base);
        bytes_to_read--;
        bytes_read++;
    }
    return bytes_read;
}
but enabling rx-interrupts did not work. I enabled SCI3 RX INT in HalCoGen and enabled the corresponding VIM channels.
this method worked out for TX interrupts, but not for RX interrupts. What am I missing?
  • Hello,

    sciReceiveByte function is used for receiving data in polling mode.

    To receive data when interrupts are enabled you can use sciReceive function.

    For example:

    sciInit();
        while ((scilinREG->FLR & 0x4) == 4);
    
        _enable_IRQ();
    
        sciEnableNotification(scilinREG, SCI_RX_INT);
    
        sciReceive(scilinREG, TSIZE1, (uint8 *)&RX_Text[0]);
    
        while(1);

    void sciNotification(sciBASE_t *sci, uint32 flags)
    {
    
        sciReceive(sci, TSIZE1, (uint8 *)&RX_Text[0]);
    
        return;
    }




    In main, sciReceive is called to set the receive. After transfer is completed, in sciNotification SCI is prepared for next receive.
    You can read more about sciReceive in function declaration or in HALCoGen Help->Files->Source->sci.c.

    Best regards,
    Miro
  • my problem is, that although within sci->SETINT, SCI_RX_INT is set, i do not get any RX interrupts in
    void sciNotification(sciBASE_t *sci, uint32 flags) (HL_notification.c)
  • Hello,
    Take a look at this thread: e2e.ti.com/.../2788772
    You can find both HALCoGen and CCS project in attached files.

    Best regards,
    Miro
  • I found out that i enter the ISR sci3HighLevelInterrupt on receiving from SCI3.

    The triggerered interrupt is a recieve-Interrrupt (vec == 11) as expeccted.

    But rx_lenght within g_sciTransfer_t structure is zero. How can this happen?

    void sci3HighLevelInterrupt(void)
    {
    uint32 vec = sciREG3->INTVECT0;
    uint8 byte;
    /* USER CODE BEGIN (37) */
    /* USER CODE END */

    switch (vec)
    {
    case 1U:
    sciNotification(sciREG3, (uint32)SCI_WAKE_INT);
    break;
    case 3U:
    sciNotification(sciREG3, (uint32)SCI_PE_INT);
    break;
    case 6U:
    sciNotification(sciREG3, (uint32)SCI_FE_INT);
    break;
    case 7U:
    sciNotification(sciREG3, (uint32)SCI_BREAK_INT);
    break;
    case 9U:
    sciNotification(sciREG3, (uint32)SCI_OE_INT);
    break;

    case 11U:
    /* receive */
    byte = (uint8)(sciREG3->RD & 0x000000FFU);

    if (g_sciTransfer_t[2U].rx_length > 0U)  // rx_length is zero!!!??
    {
    *g_sciTransfer_t[2U].rx_data = byte;
    g_sciTransfer_t[2U].rx_data++;
    g_sciTransfer_t[2U].rx_length--;
    if (g_sciTransfer_t[2U].rx_length == 0U)
    {
    sciNotification(sciREG3, (uint32)SCI_RX_INT);
    }
    }

  • Hello,
    sciReceive, when interrupt mode is used, sets up rx.length and pointer to data and returns immediately. When transfer is complete then length needs to be set for the next receive. Usually this is done in sciNotification.

    Best regards,
    Miro
  • thanks, Miro,
    I would like to read out data by using sciReceeive() within sciNotification(), but my problem is, that sciNotification() is not called because rx_length == 0
    from HL_sci.c, sci3HighLevelInterrupt():

    case 11U:
    /* receive */
    byte = (uint8)(sciREG3->RD & 0x000000FFU);

    if (g_sciTransfer_t[2U].rx_length > 0U)
    {
    ///////////////////////////WE DO NOT ENTER HERE/////////////////////////////
    *g_sciTransfer_t[2U].rx_data = byte;
    g_sciTransfer_t[2U].rx_data++;
    g_sciTransfer_t[2U].rx_length--;
    if (g_sciTransfer_t[2U].rx_length == 0U)
    {
    sciNotification(sciREG3, (uint32)SCI_RX_INT);
    }
    }
  • Hello Matthias,
    In interrupt mode sciReceive has to be called before receiving data.

    When you call void sciReceive(sciBASE_t *sci, uint32 length, uint8 * data), the function sets:
    g_sciTransfer_t[index].rx_length = length;
    and
    g_sciTransfer_t[index].rx_data = data;
    then immediately returns.

    After g_sciTransfer_t[index].rx_length and g_sciTransfer_t[index].rx_data are set then sci is ready for receiving data in interrupt mode.
    When new data is received in sci buffer then interrupt will be generated and
    if (g_sciTransfer_t[2U].rx_length > 0U) will be true. ISR will move data from sci buffer to memory (here is actually where data is "received"):

    *g_sciTransfer_t[2U].rx_data = byte;
    g_sciTransfer_t[2U].rx_data++;
    g_sciTransfer_t[2U].rx_length--;

    After all data is received, length will be 0 and sciNotification is called.

    if (g_sciTransfer_t[2U].rx_length == 0U)
    {
    sciNotification(sciREG3, (uint32)SCI_RX_INT);
    }

    Then in sciNotification you should call again sciReceive to set
    g_sciTransfer_t[index].rx_length = length;
    and
    g_sciTransfer_t[index].rx_data = data;

    The routine again will return immediately and sci will be prepared for next receive in interrupt mode (as length pointer are set)

    Best regards,
    Miro

  • am i right, there is only one byte read per triggered interrupt (decremented by one in sci3HighLevelInterrupt)?
    Where can I find documentation on the semantic of sciReceive?
  • Hello,
    Yes, you are right.
    The receive ready (RXRDY) flag is set when the SCI transfers newly received data from SCIRXSHF to SCIRD. The RXRDY flag therefore indicates that the SCI has new data to be read. If the SET RX INT is set when the SCI sets the RXRDY flag, then a receive interrupt is generated. The received data can be read in the Interrupt Service routine.
    Description of sciReceive could be found where function is declared or in HALCoGen Help->Help topics->Files->File list->source->sci.c

    Best regards,
    Miro
  • Instead of interrupt mode, now I tried polling mode instead.

    my read function looks like

    uint32_t thcp_hw_read_hercules(uint8_t* buffer, const uint32_t max_length)
    {
    uint32_t bytes_read = 0;
    uint32_t bytes_to_read = max_length;

    while ((sciIsRxReady(thcp_hw_sci_base) != 0) && (bytes_to_read >0)) // within here, SCI_RX_INT is set in sci->FLR
    {

    uint32_t my_byte = sciReceiveByte(thcp_hw_sci_base); // within here, SCI_RX_INT is not set anymore and it loops endlessly!

    buffer[bytes_read] = (uint8_t)(my_byte & 0xFF);
    bytes_read++;
    bytes_to_read--;

    }


    return bytes_read;
    }

  • Hello Matthias,
    You can use sciReceive to receive data in polling mode as well.
    This part of code check whether SCI RX interrupt is enabled:
    if ((sci->SETINT & (uint32)SCI_RX_INT) == (uint32)SCI_RX_INT)

    If SCI RX interrupt is not enabled then polling method is used (code after else).

    In polling method RX RDY flag is polled. When data is transferred from SCIRXSHF to SCIRD RX RDY flag is set to 1.
    sciReceiveByte is doing this here:
    while ((sci->FLR & (uint32)SCI_RX_INT) == 0U)
    When RX RDY flag is set ( data is transferred from SCIRXSHF to SCIRD) then sciReceibeByte returns received data.

    sciIsRxReady checks RX RDY flag and returns TRUE when RX RDY flag is 1.
    This is checked in sciReceiveByte as well.

    sciReceiveByte will loop if data is not received.

    Best regards,
    Miro