I'm working to send frame of 8 bytes to Micro-controller Xmega128a1 (via RS485). The frame looks like this:
{header1,header2,CMD,D1,D2,D3,D4,CRC}
For example:
{0x55,0xaa,0xFF,0x59,0xfd,0x64,0x68,0x32}
The micro-controller has to resend the frame back to the PC, if it's 'correct'. The frame received is correct if the header is {0x55,0xaa}.
I used ASF drivers for USART,TIMER,I/O,CPU and PMIC also added fifo, gpio,c lock system and IOport services.
The serial port ISR raises a flag every new byte (new_byte_resived_flag
). In the while loop I add every new byte to an array of 8 bytes Rx_buf_F0
(witch represent the received frame). When the frame received is complete, I set the a flag frame_completed_flag
to 1. Also, in the while loop I make a verification if the frame is correct or not. If it is, then I send it back to PC.
Sampling flag is raised every 50ms to assign the correct data frame received to variables such as CMD,data[i],i=3,4,5,6.
The problem is: when I send a frame to the micro-controller, sometimes it replies but not with the correct frame.
The serial port is working good but I think I have problems using buffers and fifo functions in the correct way. My code:
#include <asf.h>
#include <compiler.h>
#include <sysclk.h>
#include <board.h>
#include <gpio.h>
#include "tc.h"
uint8_t sampling_flag =0;
uint8_t i=0;
uint8_t n=0;
uint8_t CRC=0;
uint8_t flag_rx_Frame_F0=0;
uint8_t new_byte_resived_flag=0;
uint8_t frame_completed_flag=0;
uint8_t fram_recived_correct_flag=0;
fifo_desc_t rx_fifo_F0;
uint8_t Rx_buf_F0[8] = {0x48 , 0x75, 0x73, 0x73, 0x61, 0x6d, 0x59, 0x0d};
static void my_callback(void)
{
sampling_flag = 1;
}
uint8_t rx_buffer[32];
ISR(USARTF0_RXC_vect)
{
//ioport_set_pin_low(LED1_GPIO);
uint8_t received_byte;
//while(i<7){
received_byte = usart_getchar(&USARTF0);
//Rx_buf_F0[i] = usart_getchar(&USARTF0);
fifo_push_uint8(&rx_fifo_F0, received_byte);
//if(fifo_get_used_size(&fifo_desc) == 0) break;
new_byte_resived_flag=1;
//fifo_push_uint8(&rx_fifo_F0, received_byte);
usart_clear_rx_complete(&USARTF0);
}
uint8_t CMD;
uint8_t data[4] = {0x00 , 0x00, 0x00, 0x00};
int main (void)
{
/* Insert system clock initialization code here (sysclk_init()). */
board_init();
sysclk_init();
/////////////////////////////////////////////////////////////////////////////////////tIMER C0 INIT
tc_enable(&TCC0);
tc_set_overflow_interrupt_callback(&TCC0, my_callback);
tc_set_wgm(&TCC0, TC_WG_NORMAL);
tc_set_overflow_interrupt_level(&TCC0, TC_INT_LVL_LO);
tc_write_period(&TCC0, 25000);
tc_write_clock_source(&TCC0, TC_CLKSEL_DIV64_gc);
//////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////USART RS232 MODE INIT
static usart_rs232_options_t USART_SERIAL_OPTIONS = {
.baudrate = 38400,
.charlength = USART_CHSIZE_8BIT_gc,
.paritytype = USART_PMODE_DISABLED_gc,
.stopbits = true
};
/////////////////////////////////////
///////// Initialize usart driver in RS232 mode
usart_init_rs232(&USARTF0, &USART_SERIAL_OPTIONS);
sysclk_enable_module(SYSCLK_PORT_F, PR_USART0_bm);
PORTF.DIRSET = PIN3_bm;
usart_set_rx_interrupt_level(&USARTF0, USART_INT_LVL_HI);
fifo_init(&rx_fifo_F0, rx_buffer, 32);
pmic_init();
cpu_irq_enable();
while (1)
{
if(new_byte_resived_flag==1)
{
new_byte_resived_flag=0;
i++;
Rx_buf_F0[i]=fifo_pull_uint8_nocheck(&rx_fifo_F0);
if(i==7)
{
frame_completed_flag=1;
i=0;
}
}
if (frame_completed_flag==1)
{
frame_completed_flag=0;
if (Rx_buf_F0[0]==0x55 && Rx_buf_F0[1]==0xaa )
{
for (int j = 0; j < 7; j++)
{
usart_putchar(&USARTF0, Rx_buf_F0[j]);
}
fram_recived_correct_flag=1;
}
}
if (sampling_flag==1)
{
sampling_flag=0;
if ( fram_recived_correct_flag==1)
{
fram_recived_correct_flag=0;
CMD=Rx_buf_F0[2];
for(int k=3;k<7;k++)
data[k]=Rx_buf_F0[k];
CRC= Rx_buf_F0[7];
for (int j = 0; j < 7; j++)
{
Rx_buf_F0[j]='\0';
}
}
}
}//end of while(1)
}//end of main