Atmega64M1 some details about datasheet

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

Hi :) 

 

I m working on the Atmega64M1. I'm trying to use the CAN peripheral but it doesn't work correctly ... I am able to receive only one message ... and after I don't know what the microcontroller do. I have read the datasheet and there is some informations that I do not understand.

About the point "20.6.2.3 Rx data and remote frame " this point describe how to receive CAN message and it is written "All the parameters and datas are available in the MOb until a new initialisation " What does the datasheet mean about "new initialisation " ? 

 

There is an other point which is "20.9.2 Interrupt Behavior ". It is written " To acknowledge a MOb interrupt, the corresponding bits of CANSTMOB register must be cleared by the SW application. This application needs a read-modify-write SW routine" I would like to know what is a "read-modify write software routine" ? 

Thank you very much and have a nice day ! 

Last Edited: Sun. Jul 30, 2017 - 04:48 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Have you looked at working code examples from others? (not just 64M1 but any of the CAN AVR). What are they doing that you aren't?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The architecture of my code is not the same... But I saw something that I didn't write : Initialize all the MOBs (the datasheet tell to do it !). I will do it but I think there are other errors in my code. I don't think that this error will change my problem, Am I wrong ? 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I've never programmed CAN on an AVR so have no idea. But if I planned to I'd first be checking for Atmel produced application notes and any library code they may have. After that I would be looking for commonly used 3rd party library code (esp Arduino) and I'd build and run that to verify my prototype electronics (so any later problems can only be my software). If the Atmel /3rd party code does not deliver my entire solution immediately I'd at least study it in minute detail until I understand every last thing they are doing in case I can reuse any ideas/code.
.
With something as complex as CAN I don't think I'd just try to do it from a raw reading of the datasheet. Sure the original "pathfinder" had to but I hope she's done it so I wouldn't have to.
.
Now where is Dean Camera when you need him? ;-)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Perhaps this Thread would be better served in the Compilers and General Programming section, as there is no specific Automotive Micro section, the question is about CAN interfaces, and nothing here relates to Xmegas?

 

Alternatively, IIRC, there are at least to other CAN Threads running at the moment, perhaps place this where they are.

 

JC

Last Edited: Sun. Jul 30, 2017 - 04:49 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ah. I just moved it from "Xmega" (which it isn't) to "tiny/mega" (which it is). Perhaps I should move it again?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi, 

Thank you for your reply ! Thank you for your method and your honnesty ! 

I succeeded to do what I want but there is something that is strange in my code ... I need a delay ! And without this delay the code is not working properly. Do you know what could be the problem ? 

Here is the code where I need a delay : This function allows to send CAN messages 

uint8_t can_tx(uint16_t identifier, uint8_t *data)
{
	uint8_t mob_free, mob_status, cpt;
	uint8_t  volatile *__i_;
	//delay_ms(5000);
	mob_free = can_get_mob_free();
	if(mob_free == NO_MOB)
	{
		return(ERROR);
	}
	else
	{
		CANPAGE = ((mob_free) << 4); //Set the associate CANPAGE of the mob free
		for (__i_=&CANSTMOB; __i_<&CANSTML; __i_++) //i pointe l'adresse de CANSTMOB à CANSTML
		{
			*__i_=0x00 ; //! All MOb Registers=0
		}
		//CANSTMOB = 0x00; //clear status mob
		can_set_std_id(identifier);
		for(cpt=0; cpt < DATA_BUFFER_SIZE; cpt++)
		{
			CANMSG = *(data + cpt); //insère la valeur de la case mémoire pointé par l'adresse data+cpt (ca peut etre data[0] , data[1]...)
		}
		CANCDMOB |= (1<<DLC0);
		CANCDMOB &= (~CONMOB_MSK); //Mob is going to "Disable"
		CANCDMOB |= (1 << CONMOB0); //Mob is going to "Enable transmission"
	}
	delay_ms(10);
	mob_status = can_get_mob_status();
	while(mob_status != MOB_TX_COMPLETED); //transmission succeeded
	CANCDMOB &= (~CONMOB_MSK); //abort mob -> disable mode
	CANSTMOB = 0x00; //clear status mob
	return(SUCCEED);
}
	

Thank you very much and have a nice day ! :D 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Again I know nothing about CAN but if you ever find yourself having to insert delays into some code the chances are there is some "completion flag" somewhere that you should be reading and have over-looked.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi, 

If I understand what you said, you are telling me that I should look the state of a flag before doing an other instruction ? 

Thank you !

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm just saying that silicon designers don't usually design peripherals on the basis that you "trigger action then wait Nms for completion". Usually they design things so you trigger some action and then there is a flag that can either be polled (or maybe even trigger an interrupt?) so you get to know about completion immediately not waiting out 10 milliseconds or whatever it is when the even may actually be complete after 3 or whatever.

 

What I am saying is that somewhere in all the bits of all the registers there might be some flag you have over-looked that you could be using as a completion indicator instead of having to insert delays.

 

This is why I think it's so important to look at the pathfinding code of others. It's all very well reading about the registers and bits in a datasheet but often the "sequence of use" is not so obvious until you see some implemented code that puts the whole thing through its paces.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ok thank you :) ! I looked 2 other codes. Have a nice day !