I do not have any ATmega CAN chips with their LIN/UART hardware handy to develop this code right now. All I did was read the data sheet trying to pick out UART only operation mode without LIN operation. I have no idea if I got it right/wrong or maybe did not even get close to a working solution. This is simple polling based throwaway UART debug code to output serial data characters for AT90CAN or ATmega CAN chip programming examples. I decided to make it work on either type of CAN chip by detecting the type of processor when compiling the C code, but I have no idea if the LIN/UART debug code will really work or not (the AT90CAN USART code works).
// WinAVR C code: // This code emulates the AT90CAN USART sample rates of 16 (U2X_SINGLE) and 8 (U2X_DOUBLE) in // the ATmega CAN chips LIN/UART hardware. This is done because it is part of a conditional // compile that chooses between the AT90CAN chips or ATmega CAN chips. Using the same sample // rates means the same UART baud rate formulas work for all these CAN chips. #include//#define F_CPU 16000000UL #define U2X_SINGLE 0 #define U2X_DOUBLE 1 #define USART0_BAUDRATE 57600UL #define USART0_SPEED U2X_DOUBLE #define BAUD_PRESCALE ((((F_CPU + (USART0_BAUDRATE * 8UL)) / (USART0_BAUDRATE * 16UL))) - 1) #define BAUD_2X_PRESCALE ((((F_CPU + (USART0_BAUDRATE * 4UL)) / (USART0_BAUDRATE * 8UL))) - 1) //******************************************************* // LIN/UART hardware setup for Tx output only, 8 bits, no parity and one stop bit. // void usart0_init () { LINCR = (1 << LSWRES); // Ensure LENA is cleared so LDISR/LBT may be written. #if (USART0_SPEED == U2X_SINGLE) LINBRRH = (uint8_t) (BAUD_PRESCALE >> 8); LINBRRL = (uint8_t) BAUD_PRESCALE; #elif (USART0_SPEED == U2X_DOUBLE) LINBRRH = (uint8_t) (BAUD_2X_PRESCALE >> 8); LINBRRL = (uint8_t) BAUD_2X_PRESCALE; #endif #if (USART0_SPEED == U2X_SINGLE) LINBTR = (1 << LDISR) | (16 << LBT0); // Set sample rate to 16 (same as AT90CAN U2X_SINGLE). #elif (USART0_SPEED == U2X_DOUBLE) LINBTR = (1 << LDISR) | (8 << LBT0); // Set sample rate to 8 (same as AT90CAN U2X_DOUBLE). #endif // Enable the LIN/UART, set UART Tx byte enable, mode 00 - 8 bit no parity. LINCR = (1 << LENA) | (1 << LCMD2) | (1 << LCMD0); } //******************************************************* // A primitive polling routine to send the byte_data on the USART0 Tx. // ATmega CAN chip LIN/UART driver for UART mode Tx: // void raw_usart0_tx (unsigned char byte_data) { while (LINSIR & (1 << LBUSY)); // Wait while the UART is busy. LINDAT = byte_data; // Tx the raw byte value. }
I think I got the UART baud rate correct, but I'm not sure if this is the correct way to setup and control the LIN/UART character output UART only Tx. Any input help from someone with experience using the 8 bit AVR LIN/UART hardware would be appreciated.
It would have been nice if ATMEL had an app note on using only the UART of the LIN/UART hardware.
Thanks.