This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

fail to generate a TXDRDY Interrupt

Hi,

I'm unable to configure the UART so, that it will generate the TXDRDY event. I have an UART that should send periodicaly 4 Byte sequences without hardware handshake. I'm able to send the very first byte, but I'm unable to generate the interrupts that I need to send the next consecutive bytes.

The end of the configuration looks like this:

    reg( STARTTX )  = 1;
    sd_nvic_EnableIRQ( UART0_IRQn );
    reg( TXDRDY )   = 0;
    reg( INTENSET ) = 0x80;

I send the first byte by calling a function send_byte() (and the first byte is received correctly):

void send_byte()
{
    reg( TXDRDY )   = 0;
    reg( INTENSET ) = 0x80;
    std::uint8_t next_byte = *write_ptr_;
    ++write_ptr_;
    reg( TXD ) = next_byte;
}

I expect this to cause an interrupt, when the byte was send. But my interrupt service function is never been called (veryfied by setting a brakepoint). Any idea, what I'm doing wrong here?

Edit: Now I found a working solution (by accident / experimenting):

void interrupt_serivce()
{
    reg( INTENCLR ) = 0x80;

    if ( write_ptr_ != write_buffer_.end() )
    {
        send_byte();
    }
}

template < class SystemVector >
void update( const SystemVector& v )
{
    reg( INTENCLR ) = 0x80;

    if ( write_ptr_ == write_buffer_.end() )
    {
        ***::pack_data< typename Configuration::consumed_signal_list_type >::pack( &write_buffer_[ 2 ], v );

        write_ptr_ = write_buffer_.begin();
        send_byte();
    }
}

void send_byte()
{
    reg( TXDRDY )   = 0;
    reg( TXD )      = *write_ptr_;
    ++write_ptr_;
    reg( INTENSET ) = 0x80;
}

update() is the function that will be called periodically, fills a buffer and directly sends the first byte of the buffer. interrupt_serivce() is the interrupt service handler and is called, when a byte was transmitted.

What puzzles me is, why do I have to disable interups inbetween? If I do not reset the TXDRDY event, interrupts will not be generated. Why is this?

Thanks in advance

  • Hi Torsten

    Thank you for your question. Is you platform the nRF51822 mBed kit? For those questions, the mbed forum is perhaps better suited for your question.

    Update 28.1.2015 When the TXDRDY flag is set, an interrupt is generated. So it is needed to clear the TXDRDY flag in order to get a second interrupt.

    I guess disabling the interrupts is required in order for the interrupt_service() and update() functions not conflicting with each other, since they are accessing the same memory addresses. That could be the case if the two processes have different priorities, then one process could interrupt the other.

  • Hi Stefan, thank you for replying. No, my plattform is a bare metal nrf51422 with s210 or s310 (depends on the device in a system with multiple nrf51422).

  • Hi Stefan, thanks for the explanation. With my question, there comes a more general question: where was I supposed to get that information? I spend hours to figure out how this UART is working and read every single letter in that chapter at least twice. In 10.1.4 of the reference, I read: „Events can be generated by the peripheral even when the event register is set to ‚1‘.“ and in 10.1.6 „An interrupt is an exception that is generated by an event …“; so to me it sounds like it’s not necessary to reset the event register. There should be at least some explanation in the UART documentation, that one have to reset the event.

    Anyway: Thank your for taking the time for your answer :-)

    Cheers Torsten

Related