ASF4 Start - Support for LIN

Go To Last Post
2 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Hi all,

 

Is there support for LIN in ASF4/Start? I can't seem to find a LIN software stack for ASF4 anywhere.

 

I would use ASF3, but I have a separate issue with my Atmel Studio 7 crashing with ASF3 plugin installed.

 

Thanks!

YDC

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1
/* You can experiment with the following receive-only main code. First configure USART_0 in Atmel START. */

#include <atmel_start.h>

/* USART structures, variables, and defines used for Local Interconnect Network (LIN) communication */

/* Prototype for LIN checksum calculation: inverted 8-bit sum with carry */
uint8_t Calc_checksum ( uint8_t *data, uint8_t length ); /* Calculates LIN checksum */
volatile uint8_t LIN_checksum = 0; /* Global variable for calculated checksum */

/* Counters for LIN errors, total received messages, and valid messages */
volatile uint32_t LIN_errors = 0; /* Counter for receive errors as detected by checksum and data value validation */
volatile uint32_t LIN_messages = 0; /* Counter for LIN messages received */
volatile uint32_t valid_messages = 0; /* Counter for fully decoded and valid messages */
volatile uint32_t invalid_messages = 0; /* Counter for fully decoded and invalid messages */

/* LIN message elements */
#define BREAK_OFFSET 0
#define SYNC_OFFSET 1
#define FRAME_ID_OFFSET 2
#define FRAME_DATA_OFFSET 3
#define CHECKSUM_OFFSET 4

/* LIN message contents */
#define BREAK_BYTE 0x00
#define SYNC_BYTE 0x55
#define FRAME_ID 0x03
#define NULL_ENCODING 0x00

/* LIN message buffers and descriptors */
/* LIN message is Frame-ID (with parity), followed by Frame-Data (one byte), followed by Frame-Checksum (enhanced type) */
#define LIN_MESSAGE_LENGTH 3
/* LIN buffers length are long enough to contain the Break byte, Sync byte, and LIN message */
#define LIN_BUFFER_LENGTH 5
struct io_descriptor *LIN_io;
uint8_t LIN_read_buffer[LIN_BUFFER_LENGTH] = {
	0, 0, 0, 0, 0
};

int32_t result_status = 0; /* returned result of certain Atmel Software Frame Work functions */

int main(void)
{
	/* Initializes MCU, drivers and middleware */
	atmel_start_init();

	/* Replace with your application code */

	/* Set up for USART LIN Channel (struct io_descriptor *LIN_io; is declared globally) */
	usart_sync_get_io_descriptor(&USART_0, &LIN_io);
	usart_sync_enable(&USART_0);

	while (1) {

		/* LIN Command Receive and Decode */
		result_status = usart_sync_is_rx_not_empty(&USART_0); /* Check if a new command arrived */

		if (0 != result_status)
		{
			LIN_messages++; /* Count up total messages received */
			result_status = io_read(LIN_io, (uint8_t *)LIN_read_buffer, LIN_BUFFER_LENGTH); /* Read in LIN message from USART */
			LIN_checksum = Calc_checksum ( ( LIN_read_buffer + FRAME_ID_OFFSET ), LIN_MESSAGE_LENGTH ); /* Verify integrity */
			if ((LIN_read_buffer[CHECKSUM_OFFSET] == LIN_checksum) &&
				(LIN_read_buffer[BREAK_OFFSET] == BREAK_BYTE) &&
				(LIN_read_buffer[SYNC_OFFSET] == SYNC_BYTE) &&
				(LIN_read_buffer[FRAME_ID_OFFSET] == FRAME_ID) )
			{
				switch ( LIN_read_buffer[FRAME_DATA_OFFSET] )
				{
					case NULL_ENCODING : /* process NULL command */
					valid_messages++; /* Count up fully decoded and valid messages */
					break;

					default : /* nothing to do */
					invalid_messages++; /* Count up fully decoded but invalid messages */
					break;

				} /* switch ( LIN_read_buffer[FRAME_DATA_OFFSET] ) */

			} /* LIN_read_buffer contents verification */
			else
			{
				LIN_errors++; /* Count up the LIN protocol errors for diagnostic status */
			}
		} /* (0 != result_status) */

		if ((valid_messages + invalid_messages + LIN_errors) != LIN_messages)
		{
			result_status = -1; /* Set breakpoint here to detect anomalies in program logic */
		}

	}
}

uint8_t Calc_checksum ( uint8_t *data, uint8_t length ) /* Calculates LIN checksum */
{
	uint8_t ix; /* indexing variable */
	uint16_t checksum = 0; /* accumulated result */

	for ( ix = 0; ix < ( length - 1 ); ix++ ) /* for each byte of buffer */
	{
		checksum += data[ix]; /* accumulate checksum */
		if ( checksum >= 256 ) /* check for overflow */
		{
			checksum -= 255; /* adjust for overflow */
		}
	}

	return (uint8_t) ( 0xFF - checksum ); /* inverted 8-bit sum with carry */
}	/* LIN_checksum = Calc_checksum ( Buffer, sizeof (Buffer) ); */ /* example call to checksum function */

 

Dare Auto