第一次提交
This commit is contained in:
235
Bsp/bsp_lin.c
Normal file
235
Bsp/bsp_lin.c
Normal file
@@ -0,0 +1,235 @@
|
||||
#include "bsp_lin.h"
|
||||
#include "circular_buffer.h"
|
||||
|
||||
|
||||
static lin_error_enum lin_error = FIFO_VOID;
|
||||
static lin_rxstate_enum lin_rxstateget = BREAK_GET;
|
||||
static lin_msg_struct lin_msg = {0};
|
||||
static CircBuf_t lin_rx_circbuf = {0};//<2F><><EFBFBD>ջ<EFBFBD><D5BB>ζ<EFBFBD><CEB6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
|
||||
void lin_init(void)
|
||||
{
|
||||
gpio_init_type gpio_init_struct;
|
||||
|
||||
crm_periph_clock_enable(CRM_USART5_PERIPH_CLOCK, TRUE);
|
||||
crm_periph_clock_enable(CRM_GPIOB_PERIPH_CLOCK, TRUE);
|
||||
|
||||
// TX<54><58><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
gpio_default_para_init(&gpio_init_struct); // <20><><EFBFBD>սṹ<D5BD><E1B9B9>
|
||||
gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_MODERATE; // <20>е<EFBFBD><D0B5><EFBFBD><EFBFBD><EFBFBD>ǿ<EFBFBD><C7BF>
|
||||
gpio_init_struct.gpio_out_type = GPIO_OUTPUT_OPEN_DRAIN; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
gpio_init_struct.gpio_mode = GPIO_MODE_MUX; // <20><><EFBFBD>Ÿ<EFBFBD><C5B8><EFBFBD>ģʽ
|
||||
gpio_init_struct.gpio_pins = GPIO_PINS_3; // TX<54><58><EFBFBD><EFBFBD>
|
||||
gpio_init_struct.gpio_pull = GPIO_PULL_NONE; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
gpio_init(GPIOB, &gpio_init_struct); // <20><>ʼ<EFBFBD><CABC>TX<54><58><EFBFBD><EFBFBD>
|
||||
|
||||
gpio_pin_mux_config(GPIOB, GPIO_PINS_SOURCE3, GPIO_MUX_10);
|
||||
|
||||
// RX<52><58><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
gpio_init_struct.gpio_mode = GPIO_MODE_MUX; // <20><><EFBFBD><EFBFBD>ģʽ
|
||||
gpio_init_struct.gpio_pins = GPIO_PINS_4; // RX<52><58><EFBFBD><EFBFBD>
|
||||
gpio_init(GPIOB, &gpio_init_struct); // <20><>ʼ<EFBFBD><CABC>RX<52><58><EFBFBD><EFBFBD>
|
||||
|
||||
gpio_pin_mux_config(GPIOB, GPIO_PINS_SOURCE4, GPIO_MUX_10);
|
||||
|
||||
// USART<52><54><EFBFBD><EFBFBD>
|
||||
usart_init(USART5, Lin_Speed, USART_DATA_8BITS, USART_STOP_1_BIT);
|
||||
usart_transmitter_enable(USART5, TRUE); // ʹ<>ܷ<EFBFBD><DCB7><EFBFBD><EFBFBD><EFBFBD>
|
||||
usart_receiver_enable(USART5, TRUE); // ʹ<>ܽ<EFBFBD><DCBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
usart_parity_selection_config(USART5, USART_PARITY_NONE); // <20><><EFBFBD><EFBFBD>żУ<C5BC><D0A3>
|
||||
usart_break_bit_num_set(USART5, USART_BREAK_11BITS); // <20><>֡<EFBFBD><D6A1><EFBFBD><EFBFBD>
|
||||
usart_lin_mode_enable(USART5, TRUE); // <20><><EFBFBD><EFBFBD>LINģʽ
|
||||
|
||||
// <20>ж<EFBFBD><D0B6><EFBFBD><EFBFBD><EFBFBD>
|
||||
nvic_irq_enable(USART5_IRQn, 0, 0); // <20><><EFBFBD>ô<EFBFBD><C3B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȼ<EFBFBD>
|
||||
usart_enable(USART5, TRUE); // ʹ<><CAB9>USART1
|
||||
usart_interrupt_enable(USART5, USART_BF_INT, TRUE); // ʹ<><CAB9>֡<EFBFBD>ж<EFBFBD>
|
||||
usart_interrupt_enable(USART5, USART_RDBF_INT,TRUE);// ʹ<>ܴ<EFBFBD><DCB4>ڽ<EFBFBD><DABD><EFBFBD><EFBFBD>ж<EFBFBD>
|
||||
|
||||
CircBuf_Alloc(&lin_rx_circbuf, sizeof(lin_msg_struct)*2);
|
||||
}
|
||||
|
||||
uint8_t lin_getpid(uint8_t id)
|
||||
{
|
||||
uint8_t pid = 0, p0 = 0, p1 = 0;
|
||||
|
||||
p0 = (((id>>0)^(id>>1)^(id>>2)^(id>>4))&0x01)<<6;//żУ<C5BC><D0A3>λ
|
||||
p1 = ((~((id>>1)^(id>>3)^(id>>4)^(id>>5)))&0x01)<<7;//<2F><>У<EFBFBD><D0A3>λ
|
||||
pid = (id|p0|p1);
|
||||
return pid;
|
||||
}
|
||||
|
||||
uint8_t lin_getchecksum(uint8_t pid, uint8_t* p_data, uint8_t data_len, uint8_t flag)
|
||||
{
|
||||
uint16_t checksum = 0;
|
||||
if((pid != 0x3c)&&(pid != 0x7d))
|
||||
{
|
||||
checksum = pid;
|
||||
}
|
||||
for(uint8_t i = 0; i < data_len; i++)
|
||||
{
|
||||
checksum += p_data[i];
|
||||
if(checksum > 0xff)
|
||||
{
|
||||
checksum -=0xff;
|
||||
}
|
||||
}
|
||||
|
||||
if(flag == 0)
|
||||
{
|
||||
return (~checksum) & 0xff; //<2F><><EFBFBD>ͷ<EFBFBD><CDB7><EFBFBD>Ҫȡ<D2AA><C8A1>
|
||||
}
|
||||
else
|
||||
{
|
||||
return checksum & 0xff; //<2F><><EFBFBD>շ<EFBFBD><D5B7><EFBFBD><EFBFBD><EFBFBD>Ҫ
|
||||
}
|
||||
}
|
||||
|
||||
void lin_send_bytes(usart_type * usart_x, uint8_t* p_data, uint8_t data_len)
|
||||
{
|
||||
for(uint8_t i = 0; i < data_len; i++)
|
||||
{
|
||||
usart_data_transmit(usart_x, *p_data++);
|
||||
while(usart_flag_get(USART3, USART_TDBE_FLAG) == RESET);
|
||||
}
|
||||
}
|
||||
|
||||
void lin_rx_data(uint8_t pid, uint8_t* p_data, uint8_t data_len)
|
||||
{
|
||||
uint8_t lin_buffer[data_len + 1];
|
||||
uint8_t checksum = lin_getchecksum(pid, p_data, data_len, 0);
|
||||
|
||||
for(uint8_t i = 0; i < data_len; i++)
|
||||
{
|
||||
lin_buffer[i] = *(p_data + i);
|
||||
}
|
||||
|
||||
lin_buffer[data_len] = checksum;
|
||||
lin_send_bytes(USART3,lin_buffer, data_len + 1);
|
||||
}
|
||||
|
||||
|
||||
void lin_master_rxmsg(uint8_t data)
|
||||
{
|
||||
lin_msg_struct* p_lin_msg = &lin_msg;
|
||||
|
||||
switch((uint8_t)lin_rxstateget)
|
||||
{
|
||||
case BREAK_GET:
|
||||
break;
|
||||
case SYNCH_GET:
|
||||
{
|
||||
if(data != 0x55)
|
||||
{
|
||||
lin_error = SYNC_ERR;
|
||||
lin_rxstateget = BREAK_GET;
|
||||
}
|
||||
else
|
||||
{
|
||||
p_lin_msg->sync = data;
|
||||
lin_rxstateget = PID_GET;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case PID_GET:
|
||||
{
|
||||
p_lin_msg->frameid = data&0x3f;
|
||||
p_lin_msg->pid = data;
|
||||
uint8_t pid = lin_getpid(p_lin_msg->frameid);
|
||||
|
||||
if(pid == p_lin_msg->pid)
|
||||
{
|
||||
if(p_lin_msg->frameid == 0x03) //ִ<><D6B4> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
{
|
||||
lin_rxstateget = MSG_GET;
|
||||
p_lin_msg->datalen = 0;
|
||||
}
|
||||
else if(p_lin_msg->frameid == 0x32) //<2F><><EFBFBD><EFBFBD> <09><><EFBFBD><EFBFBD>lin<69><6E><EFBFBD>߷<EFBFBD><DFB7><EFBFBD><EFBFBD><EFBFBD>Ϣ
|
||||
{
|
||||
lin_rx_data(p_lin_msg->pid, &data, 1);
|
||||
lin_rxstateget = BREAK_GET;
|
||||
}
|
||||
else
|
||||
{
|
||||
lin_rxstateget = BREAK_GET;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lin_error = PID_ERR;
|
||||
lin_rxstateget = BREAK_GET;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case MSG_GET:
|
||||
{
|
||||
p_lin_msg->data[p_lin_msg->datalen++] = data;
|
||||
lin_rxstateget = (p_lin_msg->datalen >= 8) ? CHECKSUM_GET:MSG_GET;
|
||||
}
|
||||
break;
|
||||
|
||||
case CHECKSUM_GET:
|
||||
{
|
||||
p_lin_msg->checksum = data;
|
||||
uint8_t checksum = lin_getchecksum(p_lin_msg->pid, p_lin_msg->data, p_lin_msg->datalen, 1);
|
||||
if((checksum + p_lin_msg->checksum) == 0xff)
|
||||
{
|
||||
CircBuf_Push(&lin_rx_circbuf, (uint8_t *)p_lin_msg, sizeof(lin_msg_struct));
|
||||
}
|
||||
else
|
||||
{
|
||||
lin_error = FORMAT_ERR;
|
||||
}
|
||||
lin_rxstateget = BREAK_GET;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
lin_rxstateget = BREAK_GET;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t rx_ring_buffer_get_lin_msg(lin_msg_struct * p_lin_msg)
|
||||
{
|
||||
return CircBuf_Pop(&lin_rx_circbuf,(uint8_t*)p_lin_msg, sizeof(lin_msg_struct));
|
||||
}
|
||||
|
||||
void USART5_IRQHandler(void)
|
||||
{
|
||||
uint8_t receive_data = 0;
|
||||
|
||||
|
||||
if(RESET != usart_interrupt_flag_get(USART5,USART_BFF_FLAG))
|
||||
{
|
||||
usart_data_receive(USART5);
|
||||
|
||||
lin_rxstateget = SYNCH_GET;
|
||||
|
||||
usart_flag_clear(USART5,USART_FERR_FLAG);//<2F><><EFBFBD><EFBFBD>֡<EFBFBD><D6A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>־<EFBFBD><D6BE>lin<69>Ͽ<EFBFBD><CFBF><EFBFBD>Ҳ<EFBFBD><D2B2><EFBFBD><EFBFBD><EFBFBD>ݣ<EFBFBD>ֻ<EFBFBD><D6BB><EFBFBD><EFBFBD><EFBFBD>Ͽ<EFBFBD><CFBF><EFBFBD><EFBFBD>dz<EFBFBD><C7B3><EFBFBD>10λ<30><CEBB>0<EFBFBD><30><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD><CFB4>ڵ<EFBFBD>֡<EFBFBD><D6A1><EFBFBD><D7BC><EFBFBD><EFBFBD><EFBFBD>Գ<EFBFBD><D4B3><EFBFBD><EFBFBD><EFBFBD>֡<EFBFBD><D6A1><EFBFBD><EFBFBD>
|
||||
usart_flag_clear(USART5,USART_BFF_FLAG);
|
||||
usart_flag_clear(USART5,USART_RDBF_FLAG);
|
||||
return ;
|
||||
}
|
||||
|
||||
if(RESET != usart_interrupt_flag_get(USART5,USART_RDBF_FLAG))
|
||||
{
|
||||
receive_data = usart_data_receive(USART5);
|
||||
if(RESET == usart_interrupt_flag_get(USART5,USART_FERR_FLAG))
|
||||
{
|
||||
if((receive_data == 0x55)&&(lin_rxstateget == BREAK_GET))
|
||||
{
|
||||
lin_rxstateget = SYNCH_GET;
|
||||
return ;
|
||||
}
|
||||
|
||||
lin_master_rxmsg(receive_data);
|
||||
}
|
||||
|
||||
usart_flag_clear(USART5,USART_RDBF_FLAG);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user