10 years, 2 months ago.

Serial txd irq can't work in KL05/KL25?

I found serial irq will not work. I try printf demo first, it works. When I try to use serial irq function, I found it work. MCU will goto dead loop in function 'txisr'. I try KL05z and KL25Z, same result.

include the mbed library with this snippet

#include "mbed.h"

DigitalOut led1(LED_GREEN);
DigitalOut led2(LED_BLUE);

Ticker tick;

Serial pc(USBTX, USBRX);

char dat = '>';

void flip()
{
  pc.putc(dat);
}
    
void txisr()
{
  led1 = !led1;
}

void rxisr()
{
  led2 = !led2;
  dat = pc.getc();
}
    
int main()
{
    pc.baud(9600);
    pc.attach(&rxisr, Serial::RxIrq);
    pc.attach(&txisr, Serial::TxIrq);

    tick.attach(&flip, 1.0f);
    
    while (true) {
    }
}

Thank Erik Olieman, let me know it is the porblem of the KL05/KL25. I make some change of in the test code, it may work now.

modify

#include "mbed.h"

DigitalOut led1(LED_GREEN);
DigitalOut led2(LED_BLUE);

Ticker tick;

Serial pc(USBTX, USBRX);

char dat = '>';

void txisr()
{
  led1 = !led1;
  pc.attach(0, Serial::TxIrq);
}

void rxisr()
{
  led2 = !led2;
  dat = pc.getc();
}
    
void flip()
{
  pc.putc(dat);
  pc.attach(&txisr, Serial::TxIrq);
}
    
int main()
{

  pc.attach(&rxisr, Serial::RxIrq);
  pc.attach(&txisr, Serial::TxIrq);

  tick.attach(&flip, 1.0f);
    
  while (true) {
    wait(1.0f);
    led2 = !led2;
  }
}
posted by shao ziyang 21 Sep 2014

1 Answer

10 years, 2 months ago.

From what I remember from a previous similar question: On the KL25z and KL05z (and similar ones), the TX irq is not called when a char is sent, such as for the LPC1768 it is, but when there is space in the transmit buffer.

For most applications this ends up to the same thing: If a char is sent, there is also space in the transmit buffer. The difference is that the char is sent only once, while if no other char is sent there is still space in the transmit buffer, so it will keep calling this interrupt constantly.

I found that, problem is not sent char, when call pc.attach(&txisr, Serial::TxIrq), it will jump to txisr function immediately, and run it constantly, the code below will not run.

posted by shao ziyang 19 Sep 2014

That is because what I described: The tx irq is not called when something is sent, it is called on the KL25Z when there is space in the transmit buffer, and that is immediatly the case, so it will always keep executing that interrupt routine.

This is different then for example the LPC1768, which is not very handy. But that is simply the way they KL25Z is made.

posted by Erik - 19 Sep 2014

That means we must modify KL25Z platform souce file to solve the problem?

posted by shao ziyang 19 Sep 2014

It simply has no interrupt which is called when a TX transfer happens, if that existed it would have been used in the first place. The question is mainly why is it a problem for you? How do you want to use the TX interrupt? Generally it is used to make interrupt driver Serial, which already exists in the form of BufferedSerial, and for that the current TX interrupt is fine.

posted by Erik - 19 Sep 2014

I may not descript the problem clearly. My problem is not how to use txd interrupt, when I set txd isr, it will goto dead loop. such as below, led2 will not blank, mcu will goto txisr continues after call "pc.attach(&txisr, Serial::TxIrq);". But it is not send any byte.

#include "mbed.h"

DigitalOut led1(LED_GREEN);
DigitalOut led2(LED_BLUE);

Serial pc(USBTX, USBRX);
   
void txisr()
{
  led1 = !led1;
}

int main()
{

    pc.attach(&txisr, Serial::TxIrq);
    
    while (true) {
	wait(1.0f);
	led2 = !led2;
    }
}

I use txisr before in other platform, it works fine. But in mbed, it's usage seemed not like befor.

posted by shao ziyang 20 Sep 2014

Again (sorry but this is last time I am going to tell it). Yes this happens on the KL25. Yes this is different than on other platforms. No we cannot do anything about it, because this is how the KL25 is made.

The TX IRQ on the KL25 is called when there is space in the transmit buffer. If you don't send anything, there is ALWAYS space in the transmit buffer, so it will always continiously call txisr().

posted by Erik - 20 Sep 2014