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.

Enabling interrupt when interrupt condition already met wont trigger the interrupt?



Hi,

Im just starting a project using the 28027 piccolo.

Is the SCI TX interrupt edge triggered on the SCICTL2.TXRDY bit? Just enabling the interrupt with SCICTL2.TXRDY bit == 1 does not fire the interrupt as far as I can see.

The documentation in SPRUGH1C states that "When set, this flag asserts a transmitter interrupt request if the interrupt-enable bit, TX INT ENA (SCICTL2.0), is also set.". It is not clearly stated that the interrupt wont fire if the TX INT ENA is set while TXRDY is already set.

In this particular case I solved it by making sure to start a transmission (TXRDY is cleared) before enabling the interrupt. But -  since I've never used the TMS320 before a question arises:Is this a general rule that applies to all interrupts? That the interrupt wont fire if the interrupt enable flag is set while the interrupt condition is true?

My usual coding style is to enable interrupts, let them fire and then do stuff in the interrupt handler. With edge triggered interrupts you always have to do some sort of special case when enabling them the first time. In my example with the SCI I have to start transmitting the 1st char of a serial port buffer before enabling the interrupt instead of just letting the ISR pull all bytes, including the first one, from the buffer. However - this coding style might not be optimal for the 320?

---

For the interested engineer, this is what Im talking about. If the TX interrupt fires when the TX INT ENA is set while TXRDY is set, a simple buffered transmit function would look like this:

/**
 * @brief Put a character in the transmit buffer. Transmission will start immediately if the buffer is empty.
 * @param \p c The char to transmit.
 */
void Sci_BufPut_not_working_as_expected(char c)
{
    DINT;
    m_txbuf[m_tx_insert_index] = c; // Put in buffer
    m_tx_insert_index = (m_tx_insert_index + 1) & CONFIG_SCI_TXBUFMASK; // Increase buffer pointer
    SciaRegs.SCICTL2.bit.TXINTENA = 1; // Enable TX interrupt (tx will start in ISR - however the ISR doesnt fire)
    EINT;
}

/**
 * @brief Transmit interrupt handler. Sends all bytes in the transmit buffer.
 * When transmit buffer is empty, the interrupt disabled.
 */
interrupt void Sci_TxInterrupt_as_it_would_look(void)
{
    // Are there more bytes to transmit?
    if(m_tx_insert_index == m_tx_extract_index)
    {
        // No more bytes, disable transmit interrupt
        SciaRegs.SCICTL2.bit.TXINTENA = 0;
    }
    else
    {
        // Transmit next byte
        SciaRegs.SCITXBUF = m_txbuf[m_tx_extract_index];
        m_tx_extract_index = (m_tx_extract_index + 1) & CONFIG_SCI_TXBUFMASK;
       
    }
    // Issue PIE ack to clear interrupt
    PieCtrlRegs.PIEACK.all|=0x100;      
}

However, since the ISR wont fire, the Sci_BufPut() function has to be something like this:

/**
 * @brief Put a character in the transmit buffer. Transmission will start immediately if the buffer is empty.
 * @param \p c The char to transmit.
 */
void Sci_BufPut(char c)
{
    DINT;
    if(m_txIdle)
    {
        // Transmitter is idle, put byte directly to SCI and enable tx interrupt
        SciaRegs.SCICTL2.bit.TXINTENA = 1;
        SciaRegs.SCITXBUF = c;
        m_txIdle = false;
    }
    else
    {
        // Transmission in progress, put byte in buffer
        m_txbuf[m_tx_insert_index] = c;
        m_tx_insert_index = (m_tx_insert_index + 1) & CONFIG_SCI_TXBUFMASK;
    }
    EINT;
}

And... the corresponding ISR function is left out as this post is already a huge wall of text.

Best regards,

Mikael