Need help to port this library for ATmega32M1
Opened this issue · 0 comments
hugovw1976 commented
I am not an expert programmer, and I need a lin bus library for the atmega32M1, could anyone help me to modify it? I made some changes in lin_stack.cpp to change the Tx and Rx ports for the atmega32M1 but it does't work.
Link to atmega32m1 datasheet: http://www.atmel.com/Images/Atmel-7647-Automotive-Microcontrollers-ATmega16M1-32M1-64M1-32C1-64C1_datasheet.pdf
This is the code that I modify:
#include <lin_stack.h>
const unsigned long bound_rate = 10417;
// CONSTRUCTORS
lin_stack::lin_stack(byte Ch){
sleep_config(Ch); // Configurating Sleep pin for transceiver
}
lin_stack::lin_stack(byte Ch, byte ident){
sleep_config(Ch); // Configuration of Sleep pin for transceiver
identByte = ident; // saving idet to private variable
sleep(1); // Transceiver is always in Normal Mode
}
// PUBLIC METHODS
// WRITE methods
// Creates a LIN packet and then send it via USART(Serial) interface.
int lin_stack::write(byte ident, byte data[], byte data_size){
// Calculate checksum
byte suma = 0;
for(int i=0;i<data_size;i++) suma = suma + data[i];
suma = suma + 1;
byte checksum = 255 - suma;
// Start interface
sleep(1); // Go to Normal mode
// Synch Break
serial_pause(13);
// Send data via Serial interface
if(ch==1){ // For LIN1 or Serial
Serial.begin(bound_rate); // config Serial
Serial.write(0x55); // write Synch Byte to serial
Serial.write(ident); // write Identification Byte to serial
for(int i=0;i<data_size;i++) Serial.write(data[i]); // write data to serial
Serial.write(checksum); // write Checksum Byte to serial
Serial.end(); // clear Serial config
}
sleep(0); // Go to Sleep mode
return 1;
}
int lin_stack::writeRequest(byte ident){
// Create Header
byte header[2]= {0x55, ident};
// Start interface
sleep(1); // Go to Normal mode
// Synch Break
serial_pause(13);
// Send data via Serial interface
if(ch==1){ // For LIN1 or Serial
Serial.begin(bound_rate); // config Serial
Serial.write(header,2); // write data to serial
Serial.end(); // clear Serial config
}
sleep(0); // Go to Sleep mode
return 1;
}
int lin_stack::writeResponse(byte data[], byte data_size){
// Calculate checksum
byte suma = 0;
for(int i=0;i<data_size;i++) suma = suma + data[i];
suma = suma + 1;
byte checksum = 255 - suma;
// Start interface
sleep(1); // Go to Normal mode
// Send data via Serial interface
if(ch==1){ // For LIN1 or Serial
Serial.begin(bound_rate); // config Serial
Serial.write(data, data_size); // write data to serial
Serial.write(checksum); // write data to serial
Serial.end(); // clear Serial config
}
sleep(0); // Go to Sleep mode
return 1;
}
int lin_stack::writeStream(byte data[], byte data_size){
// Start interface
sleep(1); // Go to Normal mode
// Synch Break
serial_pause(13);
// Send data via Serial interface
if(ch==1){ // For LIN1 or Serial
Serial.begin(bound_rate); // config Serial
for(int i=0;i<data_size;i++) Serial.write(data[i]);
Serial.end(); // clear Serial config
}
sleep(0); // Go to Sleep mode
return 1;
}
// READ methods
// Read LIN traffic and then proces it.
int lin_stack::setSerial(){ // Only needed when receiving signals
if(ch==1){ // For LIN1 (Channel 1)
Serial.begin(10417); // Configure Serial
PORTD|= _BV(PD4); // We need software Pull-Up because there is no hardware Pull-Up resistor
}
}
int lin_stack::read(byte data[], byte data_size){
byte rec[data_size+3];
if(ch==1){ // For LIN1 or Serial
if(Serial.read() != -1){ // Check if there is an event on LIN bus
Serial.readBytes(rec,data_size+3);
if((validateParity(rec[1]))&(validateChecksum(rec,data_size+3))){
for(int j=0;j<data_size;j++){
data[j] = rec[j+2];
}
return 1;
}else{
return -1;
}
}
}
return 0;
}
int lin_stack::readStream(byte data[],byte data_size){
byte rec[data_size];
if(ch==1){ // For LIN1 or Serial
if(Serial.read() != -1){ // Check if there is an event on LIN bus
Serial.readBytes(rec,data_size);
for(int j=0;j<data_size;j++){
data[j] = rec[j];
}
return 1;
}
}
return 0;
}
// PRIVATE METHODS
int lin_stack::serial_pause(int no_bits){
// Calculate delay needed for 13 bits, depends on bound rate
unsigned int del = period*no_bits; // delay for number of bits (no-bits) in microseconds, depends on period
if(ch=1){
DDRD = (1<<PD3);
PORTD&= ~_BV(PD3); // clear PD3
delayMicroseconds(del); // delay
PORTD|= _BV(PD3); // set pin high
//PIOD->PIO_PDR = PIO_PD3; // clear configuration for PIO, needs to be done because Serial wont work with it
}
return 1;
}
int lin_stack::sleep(byte sleep_state){
if(sleep_state==1){ // Go to Normal mode
if(ch==1) PORTB|= _BV(PB1); // Set PB1, high state, normal mode
}else if(sleep_state==0){ // Go to Sleep mode
if(ch==1) PORTB&= ~_BV(PB1); // Clear PB1, low state, sleep mode
}
delayMicroseconds(20); // According to TJA1021 datasheet this is needed for propper working
return 1;
}
int lin_stack::sleep_config(byte serial_No){
if(serial_No==1){ // When using LIN1 channel - usign Serial and pin PB4 for Sleep
DDRB = (1<<PB1); // enable PIO register on pin PB1
//PIOB->PIO_OER = PIO_PB1; // set PB1 as output
PORTB&= ~_BV(PB1); // disable pull-up
ch=1; // saved as private variable, used for determening Serial port
}
return 1;
}
boolean lin_stack::validateParity(byte ident) {
if(ident == identByte)
return true;
else
return false;
}
boolean lin_stack::validateChecksum(unsigned char data[], byte data_size){
byte checksum = data[data_size-1];
byte suma = 0;
for(int i=2;i<data_size-1;i++) suma = suma + data[i];
byte v_checksum = 255 - suma - 1;
if(checksum==v_checksum)
return true;
else
return false;
}