The supported board list:
This quick start will set up LIN frame format transmission according to your configuration CONF_LIN_NODE_TYPE
. For LIN master, it will send LIN command after startup. For LIN salve, once received a format from LIN master with ID LIN_ID_FIELD_VALUE
, it will reply four data bytes plus a checksum.
Setup
Prerequisites
When verify data transmission between LIN master and slave, two boards are needed: one is for LIN master and the other is for LIN slave. connect LIN master LIN PIN with LIN slave LIN PIN.
Code
Add to the main application source file, outside of any functions:
static struct usart_module cdc_instance,lin_instance;
#define LIN_ID_FIELD_VALUE 0x64
#define LIN_DATA_LEN 5
static uint8_t rx_buffer[LIN_DATA_LEN]={0};
const static uint8_t tx_buffer[LIN_DATA_LEN]={0x4a,0x55,0x93,0xe5,0xe6};
Copy-paste the following setup code to your user application:
static void configure_usart_cdc(void)
{
config_cdc.baudrate = 115200;
config_cdc.mux_setting = EDBG_CDC_SERCOM_MUX_SETTING;
config_cdc.pinmux_pad0 = EDBG_CDC_SERCOM_PINMUX_PAD0;
config_cdc.pinmux_pad1 = EDBG_CDC_SERCOM_PINMUX_PAD1;
config_cdc.pinmux_pad2 = EDBG_CDC_SERCOM_PINMUX_PAD2;
config_cdc.pinmux_pad3 = EDBG_CDC_SERCOM_PINMUX_PAD3;
stdio_serial_init(&cdc_instance, EDBG_CDC_MODULE, &config_cdc);
}
static void lin_read_callback(struct usart_module *const usart_module)
{
for(i = 0; i < LIN_DATA_LEN; i++){
if(rx_buffer[i] != tx_buffer[i]) {
break;
}
}
if(i == LIN_DATA_LEN){
printf(
"Slave response: OK\r\n");
}
if(rx_buffer[0] == LIN_ID_FIELD_VALUE) {
printf(
"Receive ID field from mater: OK \r\n");
(uint8_t *)tx_buffer, LIN_DATA_LEN);
}
}
}
static void lin_read_error_callback(struct usart_module *const usart_module)
{
printf(
"Data Read error\r\n");
}
static void configure_usart_lin(void)
{
config_lin.lin_node = CONF_LIN_NODE_TYPE;
config_lin.baudrate = 115200;
config_lin.mux_setting = LIN_USART_SERCOM_MUX_SETTING;
config_lin.pinmux_pad0 = LIN_USART_SERCOM_PINMUX_PAD0;
config_lin.pinmux_pad1 = LIN_USART_SERCOM_PINMUX_PAD1;
config_lin.pinmux_pad2 = LIN_USART_SERCOM_PINMUX_PAD2;
config_lin.pinmux_pad3 = LIN_USART_SERCOM_PINMUX_PAD3;
config_lin.receiver_enable = false;
config_lin.transmitter_enable = false;
config_lin.lin_slave_enable = true;
}
LIN_USART_MODULE, &config_lin) !=
STATUS_OK) {
}
}
Add to user application initialization (typically the start of main()
):
Workflow
- Create USART CDC and LIN module software instance structure for the USART module to store the USART driver state while it is in use.
static struct usart_module cdc_instance,lin_instance;
- Define LIN ID field for header format.
#define LIN_ID_FIELD_VALUE 0x64
- Note
- The ID
LIN_ID_FIELD_VALUE
is eight bits as [P1,P0,ID5...ID0], when it's 0x64, the data field length is four bytes plus a checksum byte.
- Define LIN RX/TX buffer.
#define LIN_DATA_LEN 5
static uint8_t rx_buffer[LIN_DATA_LEN]={0};
const static uint8_t tx_buffer[LIN_DATA_LEN]={0x4a,0x55,0x93,0xe5,0xe6};
- Note
- For
tx_buffer
and rx_buffer
, the last byte is for checksum.
- Configure the USART CDC for output message.
static void configure_usart_cdc(void)
{
config_cdc.baudrate = 115200;
config_cdc.mux_setting = EDBG_CDC_SERCOM_MUX_SETTING;
config_cdc.pinmux_pad0 = EDBG_CDC_SERCOM_PINMUX_PAD0;
config_cdc.pinmux_pad1 = EDBG_CDC_SERCOM_PINMUX_PAD1;
config_cdc.pinmux_pad2 = EDBG_CDC_SERCOM_PINMUX_PAD2;
config_cdc.pinmux_pad3 = EDBG_CDC_SERCOM_PINMUX_PAD3;
stdio_serial_init(&cdc_instance, EDBG_CDC_MODULE, &config_cdc);
}
- Configure the USART LIN module.
static void lin_read_callback(struct usart_module *const usart_module)
{
uint8_t i = 0;
for(i = 0; i < LIN_DATA_LEN; i++){
if(rx_buffer[i] != tx_buffer[i]) {
break;
}
}
if(i == LIN_DATA_LEN){
printf(
"Slave response: OK\r\n");
}
if(rx_buffer[0] == LIN_ID_FIELD_VALUE) {
printf(
"Receive ID field from mater: OK \r\n");
(uint8_t *)tx_buffer, LIN_DATA_LEN);
}
}
}
static void lin_read_error_callback(struct usart_module *const usart_module)
{
printf(
"Data Read error\r\n");
}
static void configure_usart_lin(void)
{
config_lin.lin_node = CONF_LIN_NODE_TYPE;
config_lin.baudrate = 115200;
config_lin.mux_setting = LIN_USART_SERCOM_MUX_SETTING;
config_lin.pinmux_pad0 = LIN_USART_SERCOM_PINMUX_PAD0;
config_lin.pinmux_pad1 = LIN_USART_SERCOM_PINMUX_PAD1;
config_lin.pinmux_pad2 = LIN_USART_SERCOM_PINMUX_PAD2;
config_lin.pinmux_pad3 = LIN_USART_SERCOM_PINMUX_PAD3;
config_lin.receiver_enable = false;
config_lin.transmitter_enable = false;
config_lin.lin_slave_enable = true;
}
LIN_USART_MODULE, &config_lin) !=
STATUS_OK) {
}
}
- Note
- The LIN frame format can be configured as master or slave, refer to
CONF_LIN_NODE_TYPE
.
Use Case
Code
Copy-paste the following code to your user application:
configure_usart_lin();
printf(
"LIN Works in Master Mode\r\n");
while(1) {
(uint8_t *)rx_buffer, 5);
}
}
} else {
printf(
"LIN Works in Slave Mode\r\n");
while(1) {
(uint8_t *)rx_buffer, 1);
}
}
Workflow
- Set up USART LIN module.
- For LIN master, sending LIN command. For LIN slaver, start reading data .
printf(
"LIN Works in Master Mode\r\n");
while(1) {
(uint8_t *)rx_buffer, 5);
}
}
} else {
printf(
"LIN Works in Slave Mode\r\n");
while(1) {
(uint8_t *)rx_buffer, 1);
}
}