Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Need help to port this library for ATmega32M1 #3

Open
hugovw1976 opened this issue Jun 12, 2017 · 0 comments
Open

Need help to port this library for ATmega32M1 #3

hugovw1976 opened this issue Jun 12, 2017 · 0 comments

Comments

@hugovw1976
Copy link

hugovw1976 commented Jun 12, 2017

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;
}
@hugovw1976 hugovw1976 changed the title Can some one port this library for ATmega32M1 Need help to port this library for ATmega32M1 Jun 12, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant