UART v2.50 ISR - spontaneus data re-write

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
lock attach
Attachments are accessible only for community members.
JaHy_1300691
Level 1
Level 1
Hello,

I would like to ask for help or explanation why my data in variable "char serial_rx_iEPC_buffer[200];" are spontaneously re-written by random values.

Background:

I am using UART v2.50 and isr routine to capture data on CY8CKIT-059. When I am receiving 3rd or sometimes 2nd message from BUS (19200 bps), the data in my buffer on the first several bytes (3 ... 9) are filled with a random data (not occurred on BUS) after n-th entering ISR from UART Rx. I am writing to buffer only at one place - at line #97 (and not using pointers in my code).

Problem solved when I used the second buffer variable - the same size, writing to it same way as the first one. The first one is still filled by data, just not used in further code... But I still do not know, why the first buffer changes its data.

The same behavior observed at another device - the second CY8CKIT-059.

Attached:

On the figure there are log of BUS signal and logs of both buffer contents with red-marked wrong data

On the serial.c there is code which causes a troubles...

Thank you in advance for any comment to help find explanation to avoid it in next applications and save several days of work!

Jan

0 Likes
1 Solution
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Hi,

Although I can not test it as I don't have the project, I would try to modify the source as

(1) modify the isr as below, so that it only fills a new data to a ring buffer.

/* added for test */

   volatile uint8_t   tmp_rx_buf[ IEPC_RX_BUFFER_SIZE ] ;

   volatile int          tmp_rx_write_index = 0 ;

   int                      tmp_rx_read_index = 0 ;

/******************/

void rx_iEPC_isr_handler()  // handling data coming out-of iEPC

{

    isr_UART_iEPC_Rx_ClearPending() ;

    if (UART_iEPC_GetRxBufferSize() > 0) {

        tmp_rx_buf[tmp_rx_write_index] = UART_iEPC_GetByte() ;

        tmp_rx_write_index = (tmp_rx_write_index + 1) % IEPC_RX_BUFFER_SIZE ;

    }

}

(2) Change your isr as a processing function, so change first few lines as

void rx_iEPC_process(uint8_t data2) // this was rx_iEPC_isr_handler()

{

//    uint8_t data2=0;   

//    data2 = UART_iEPC_GetByte();   

    serial_rx_iEPC_buffer[serial_rx_iEPC_buffer_position] = data2;          // filling buffer with received data   

    serial_rx_iEPC_buffer2[serial_rx_iEPC_buffer_position2] = data2;

   

    serial_rx_iEPC_buffer_position++;                                       // prepare buffer pointer for next data

    serial_rx_iEPC_buffer_position2++; 

    // the remaining part is same

(3) In the main loop I will add following

    if (tmp_rx_read_index != tmp_rx_write_index) { // some data has been received

        data2 = tmp_rx_buf[ tmp_rx_read_index ] ;

        tmp_rx_read_index = (tmp_rx_read_idnex + 1) % IEPC_RX_BUFFER_SIZE ;

        rx_iEPC_process(data2) ;

    }

moto

View solution in original post

0 Likes
3 Replies
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Hi,

At first glance, I think

(1) You should define following variables as "volatile"

char serial_rx_iEPC_buffer[IEPC_RX_BUFFER_SIZE];

uint8 serial_rx_iEPC_buffer_position = 0;

char serial_rx_iEPC_buffer2[IEPC_RX_BUFFER_SIZE];

uint8 serial_rx_iEPC_buffer_position2 = 0;

(2) You should not call "PutChar" in an ISR,

So I recommend you to just compose a string  then print it in the foreground

They may be more issues, but at least above two are enough to cause serial communication problem(s).

moto

0 Likes
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Hi,

Although I can not test it as I don't have the project, I would try to modify the source as

(1) modify the isr as below, so that it only fills a new data to a ring buffer.

/* added for test */

   volatile uint8_t   tmp_rx_buf[ IEPC_RX_BUFFER_SIZE ] ;

   volatile int          tmp_rx_write_index = 0 ;

   int                      tmp_rx_read_index = 0 ;

/******************/

void rx_iEPC_isr_handler()  // handling data coming out-of iEPC

{

    isr_UART_iEPC_Rx_ClearPending() ;

    if (UART_iEPC_GetRxBufferSize() > 0) {

        tmp_rx_buf[tmp_rx_write_index] = UART_iEPC_GetByte() ;

        tmp_rx_write_index = (tmp_rx_write_index + 1) % IEPC_RX_BUFFER_SIZE ;

    }

}

(2) Change your isr as a processing function, so change first few lines as

void rx_iEPC_process(uint8_t data2) // this was rx_iEPC_isr_handler()

{

//    uint8_t data2=0;   

//    data2 = UART_iEPC_GetByte();   

    serial_rx_iEPC_buffer[serial_rx_iEPC_buffer_position] = data2;          // filling buffer with received data   

    serial_rx_iEPC_buffer2[serial_rx_iEPC_buffer_position2] = data2;

   

    serial_rx_iEPC_buffer_position++;                                       // prepare buffer pointer for next data

    serial_rx_iEPC_buffer_position2++; 

    // the remaining part is same

(3) In the main loop I will add following

    if (tmp_rx_read_index != tmp_rx_write_index) { // some data has been received

        data2 = tmp_rx_buf[ tmp_rx_read_index ] ;

        tmp_rx_read_index = (tmp_rx_read_idnex + 1) % IEPC_RX_BUFFER_SIZE ;

        rx_iEPC_process(data2) ;

    }

moto

0 Likes

Hi Moto,

thanks for your help and sorry for response after long time (some urgent topic in parallel) ...

The issue was hidden in the time period spent in ISR routine.

So your ring buffer is implemented and made volatile flag carrying info about new received byte. Rest of code is moved out of ISR and triggered by flag. It works like a charm

p.s. I am a little bit upset to myself because of this beginner´s mistake.

Thanks, Jan

0 Likes