- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
Solved! Go to Solution.
- Labels:
-
ispn:39618:1:0
-
l1:314:1:0
-
PSoC5LP
- Tags:
- data rewrite
- uart isr
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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