9 years, 8 months ago.

Serial communication issue on FRDM-KL25Z

Hi, I recently started working on FRDM-KL25z dev. board using mbed libraries and i am currently facing a issue while simultaneously sending and receiving data via UART. The code is shown below. When i try to send data to the device, either the communication stops entirely or no data is received by the chip when tx and rx are taking place simultaneously but there is no such issue when i am only transmitting data to the device. I have tried everything i could but the problem remains.

Note: I tried modifying the code by using sprintf and putc instead of printf/puts and it works. Don't know why though!

Codet

#include "mbed.h"

Serial pc(USBTX, USBRX);

AnalogIn adc0(A0);
AnalogIn adc1(A1);
AnalogIn adc2(A2);
AnalogIn adc3(A3);
AnalogIn adc4(A4);
AnalogIn adc5(A5);

//Global variables
char  inData[10];
float pwmPeriod = 0.01; //100Hz default
int   txEnable = 0;

void setPWM(int channel, int value)
{
    float duty = 1.0 - ((float) value)/100;
    switch(channel)
    {
        case 0  :  PwmOut ch0(LED1); ch0 = duty; ch0.period(pwmPeriod);
                   break;
        case 1  :  PwmOut ch1(LED2); ch1 = duty; ch1.period(pwmPeriod);
                   break;
        case 2  :  PwmOut ch2(LED3); ch2 = duty; ch2.period(pwmPeriod);
                   break;
        default :  break;
    }
}

void switchIO(int channel, int value)
{
    int signal = 1 - value;
    
    switch(channel)
    {
        case 0  :  DigitalOut ch0(LED1); ch0 = signal;
                   break;
        case 1  :  DigitalOut ch1(LED2); ch1 = signal;
                   break;
        case 2  :  DigitalOut ch2(LED3); ch2 = signal;
                   break;
        default :  break;
    }
}

void setFreq(int channel, int value)
{
    pwmPeriod = (float) 1.0/value;
}

void setSystemIO(char inData[10])
{
    int status = 0;
    int i = 1;
    int channelID = 0;
    
    while(inData[i] != 'X')
    {
        int temp = inData[i] - '0';
        channelID = channelID*10 + temp;
        i++;
        if(i>5) { return; }
    }
        
    int j = i + 1;
        
    while(inData[j] != '\r') {
        int num = inData[j] - '0';
        status = status*10 + num;
        j++;
        if(j>10) { return; }
    }
    
    switch(inData[0]) {
        case 'p' :  setPWM(channelID, status);
                    break;
        case 's' :  switchIO(channelID, status);
                    break;
        case 'f' :  setFreq(channelID, status);
                    break;
        default  :  break;
    }
}

void Rx_interrupt() 
{
    txEnable = 0;
    pc.gets(inData, 10);
    if(inData[0] == 'A') {
        txEnable = 1;
        return;
    }
    
    else if(inData[0] == 'a') {
        txEnable = 0;
        return;
    }
    
    setSystemIO(inData);
    txEnable = 1;
}

int main() {
    pc.attach(&Rx_interrupt, Serial::RxIrq);
    
    while (1) {
        if(txEnable == 1) {
            pc.printf("%uA.%uB.%uC.%uD.%uE.%uF\n",adc0.read_u16(),adc1.read_u16(),adc2.read_u16(),adc3.read_u16(),adc4.read_u16(),adc5.read_u16());
        }
        wait(0.2);
    }
} 

2 Answers

9 years, 8 months ago.

Have you tried RawSerial pc(USBTX, USBRX); ? RawSerial behaves differently than just Serial

...kevin

Shouldn't matter when he doesn't use RTOS though.

@Poster, try starting by making it easier. Remove everything which isn't really needed to verify the problem.

posted by Erik - 27 Jun 2014

Raw Serial doesn't work either. I have noticed that if i replace pc.printf() with just pc.putc() and send some arbitrary characters, everything works!

posted by Jaspreet Singh 28 Jun 2014

I tried modifying the code by using sprintf and putc instead of printf/puts and it works. Don't know why though!

posted by Jaspreet Singh 28 Jun 2014
9 years, 8 months ago.

txEnable should be defined as volatile.

IMO you are doing too much in the interrupt. I would suggest using BufferedSerial or other library which handles buffering. Then read the input character in the main thread and do all the work there.

Get rid of the wait as well. Use us_ticker_read() instead.

posted by Jurgis Jurksta 28 Jun 2014

Assigned to Jaspreet Singh 9 years, 4 months ago.

This means that the question has been accepted and is being worked on.