16.8.4.1.3 Workflow

  1. 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;
    
  2. 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.
  3. 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.
  4. Configure the USART CDC for output message.
    static void configure_usart_cdc(void)
    {
    
        struct usart_config config_cdc;
        usart_get_config_defaults(&config_cdc);
        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);
        usart_enable(&cdc_instance);
    }
    
  5. Configure the USART LIN module.
    static void lin_read_callback(struct usart_module *const usart_module)
    {
    
        uint8_t i = 0;
    
        if (CONF_LIN_NODE_TYPE == LIN_MASTER_NODE) {
            for(i = 0; i < LIN_DATA_LEN; i++){
                if(rx_buffer[i] != tx_buffer[i]) {
                    printf("Data error\r\n");
                    break;
                }
            }
            if(i == LIN_DATA_LEN){
                printf("Slave response: OK\r\n");
            }
        } else if (CONF_LIN_NODE_TYPE == LIN_SLAVE_NODE) {
            if(rx_buffer[0] == LIN_ID_FIELD_VALUE) {
                usart_enable_transceiver(&lin_instance,USART_TRANSCEIVER_TX);
                printf("Receive ID field from mater: OK \r\n");
                usart_write_buffer_job(&lin_instance,
                    (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)
    {
    
        struct port_config pin_conf;
        port_get_config_defaults(&pin_conf);
        pin_conf.direction  = PORT_PIN_DIR_OUTPUT;
        port_pin_set_config(LIN_EN_PIN, &pin_conf);
    
        /* Enable LIN module*/
        port_pin_set_output_level(LIN_EN_PIN, 1);
    
        struct usart_config config_lin;
        usart_get_config_defaults(&config_lin);
    
        /* LIN frame format*/
        config_lin.lin_node = CONF_LIN_NODE_TYPE;
        config_lin.transfer_mode = USART_TRANSFER_ASYNCHRONOUSLY;
        config_lin.sample_rate = USART_SAMPLE_RATE_16X_FRACTIONAL;
    
        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;
    
        /* Disable receiver and transmitter */
        config_lin.receiver_enable  = false;
        config_lin.transmitter_enable = false;
    
        if (CONF_LIN_NODE_TYPE == LIN_SLAVE_NODE) {
            config_lin.lin_slave_enable = true;
        }
    
        while (usart_init(&lin_instance,
            LIN_USART_MODULE, &config_lin) != STATUS_OK) {
        }
    
        usart_enable(&lin_instance);
    
        usart_register_callback(&lin_instance,
            lin_read_callback, USART_CALLBACK_BUFFER_RECEIVED);
        usart_enable_callback(&lin_instance, USART_CALLBACK_BUFFER_RECEIVED);
          usart_register_callback(&lin_instance,
            lin_read_error_callback, USART_CALLBACK_ERROR);
        usart_enable_callback(&lin_instance, USART_CALLBACK_ERROR);
        system_interrupt_enable_global();
    }
    
    Note: The LIN frame format can be configured as master or slave, refer to CONF_LIN_NODE_TYPE .