Doubts on I2C in Master mode

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

Hello to all!
I have some problem to understand how work the interrupt routine of the AVR I2C peripherical.
The my problem is to communicate whit the MPU6050 sensor. I would to communicate with it using interrupt method insted of the polling.
So i have read the datasheet of my AVR (now i use a ATMEGA 328P-PU) and i saw that for most important events that occurs in the operations of the write/read, there is a status code. Also, I have read the AVR315 application note. If i have not misunderstood, in this application note, the ISR routine work like a state machine, so according whit the MPU6050 datasheet, i tryed to implement this operation as a state machine.
I have designed two state machines , one for the read operation and one for the write operation on I2C. I attached this file on this post.
In the drawing, the rectangle represents the status code of the I2C, and the arrows represent the action that permit to change the status.
Based on this state machine i wrote the code, but it doesn't work. This is the ISR routine that i have wrote:

ISR(TWI_vect){
	
	switch (TWSR){ // status code relative at MT and MR TW mode
	
		case  TWI_BUS_ERROR:// Bus error due to an illegal START or STOP condition
			//error
			break;
	
		case TWI_START:// START has been transmitted
			i2c_write((address_slave<<1) | (0<<0));
			break;
	
		case TWI_REP_START:// REPEATED START has been transmitted
			i2c_write((address_slave<<1) | (1<<0));
			break;
	
		case TWI_ARB_LOST:// Arbitration lost in SLA+W or data bytes | Arbitration lost in SLA+R or NOT ACK bit
			//error
			break;
	
		case TWI_MTX_ADR_ACK:// SLA+W has been transmitted and ACK received
			i2c_write(address_register);
			break;
	
		case TWI_MTX_ADR_NACK:// SLA+W has been transmitted and NACK received
			// error
			break;
	
		case TWI_MTX_DATA_ACK:// Data byte has been transmitted, ACK has been received
			if(read_flag){// If (read_flag) then this is a read operation
				transmit_start_condition();
			}
			else{ //otherwise this is a write operation
				if(address_register_flag){ //if I've already written the register address, then I can write data on the bus
					if(ind_data_out == (num_byte_out-1)){// if I finished writing the data, sending a stop condition
						transmit_stop_condition(); // I close the connection with the bus and I end the write operation
						ind_data_out = 0;
						address_register_flag = 0;
					}
					else{// otherwise write a byte from the buffer on the bus
						i2c_write(data_out[ind_data_out++]);
					}
				}					
				else{ //otherwise write the register address
					i2c_write(address_register);
					address_register_flag = 1;
				}
			}			
			break;
				
		case TWI_MTX_DATA_NACK:// Data byte has been transmitted, NOT ACK has been received
			//error
			break;
				
		case TWI_MRX_ADR_ACK:// SLA+R has been transmitted, ACK has been received
			data_in[ind_data_in++] = i2c_read(ACK);
			break;
					
		case TWI_MRX_ADR_NACK:// SLA+R has been transmitted, NOT ACK has been received
			//error
			break;
			
		case TWI_MRX_DATA_ACK:// Data byte has been received, ACK has been returned
			if(ind_data_in == (num_byte_in-2)){ // if I read the last data (n-2), and then send a nack
				data_in[ind_data_in++] = i2c_read(NACK);
				ind_data_in = 0;
				read_flag = 0;
			}
			else{ //otherwise I read a byte from the bus and I put it in the input buffer
				data_in[ind_data_in++] = i2c_read(ACK);
			}				
			break;
			
		case TWI_MRX_DATA_NACK:// Data byte has been received and NACK tramsmitted
			transmit_stop_condition(); // I close the connection with the bus and I end the read operation
			break;
	}

One of the my doubts is on the subroutines that i call in the ISR routine (transmit_start_condition(), i2c_write(char), etc) that in the application note there aren't. Is correct to call this routines in the ISR code or i must call this subroutines in the main code?
If my reasoning about the modelling the operations of read and write using a state machine is wrong, how i can use the interrupt to drive the I2C in the read and write operation?

Another question are on how i check the I2C connection? I have do a little test program that turn on a led when a status is changed, but the only the led associated with the start condition status turns on.

Please, someone can help me?

Attachment(s): 

Last Edited: Fri. Nov 1, 2013 - 01:35 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Just use the Fleury I2C library functions.

There is little point in using interrupts unless you are a Slave.

Once you have become familiar with a proven I2C library, you can start writing your own. Then publish it to the civilised world (if it is better than existing libraries)

David.

imfje

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

david.prentice wrote:
Just use the Fleury I2C library functions.

There is little point in using interrupts unless you are a Slave.

Once you have become familiar with a proven I2C library, you can start writing your own. Then publish it to the civilised world (if it is better than existing libraries)

David.

imfje

Hello David!
I think that for my exam isn't correct to use 3rd part library. So i can't use this library.
My objective is to pass my exam, so I will not publish anything in the civilized world.
For do this, Peter Fleury and many other, are better than me to make and publish some library.
I'm sorry for this answer, but if I write on this forum is why i need some help to solve my problem. I haven't much time to read ancestral books on microcontrollers, or study the philosophy about the usage of the interrupt.
I have some problem using AVR devices, so i ask to this forum to solve it. Stop.
If someone can help me, ok, otherwise i will find an "AVR forum for engineering students stupid" in the web, and I will write my problem on that forum.

In friendship.

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

Ask your teacher / professor. In my humble opinion, a student who finds a proven library and uses it properly would get my approval. Especially if they give appropriate credit and references.

When I did my OU degree, we were given credit for using the most appropriate Java library methods.

Yes, for a C student, it is very important that you understand how and why the library functions. But an engineer should use safe and proven tools.

Would you want your Toyota car to use proven MISRA code or to rely on a 19-year old engineering student's "original" code ?

Don't worry. I always do the same rant.
Many others here think that students should do everything from scratch. (I disagree)

David.

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

My exam is on the microcontrollers. The scope is understand and use the devices of the microcontroller. Does not make much sense to use 3rd part library. For me, is better do everything from scratch because i try to learn how resolve a problem.

In a hypothetical futuristic scenario all people have died, and there is only one group of people to survive it must arrive in a safe place located 1000 miles away. This group of people has access to a toyota which to work, requires code MISRA and I am the only student in engineering, in the group of survivors , able to use a PC and potentially capable of programming the missing code for to operate the car.

Following your advice, I would not be able to program that code , and then I would mark the end of my existence and that of other people survived.
I think that a student should be able to face and solve engineering problems during the study period because they are learning experiences and are worth more than any theoretical examination.

I wrote on the forum because I thought to find an explanation to help me solve my problem . Obvious that on Monday I go to the professor to ask for explanations.

I'm sorry to say, but come this far just do not understand the usefulness of this forum...

In friendship

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

Human civilisation has learned from Aristotle, Newton, Maxwell, Einstein ...

Do you think that each one of these men started from scratch? They made use of prior knowledge and added to it.

We all have to rely on others in the modern world. Even if you mend your Toyota, someone else would have to make the diesel (or petrol) fuel.

My advice would be to study how a proven library works. Ask questions. Understand it fully.

You want to come to a forum and somehow ask others to do your work for you. Did your maths teacher give you a blank sheet of paper and say "invent calculus" or "solve this equation"?

I bet that your teacher showed you proven methods of calculus and solving example equations. You completed exercises to solve 'similar' questions. i.e. you followed proven methods and learned how to use them for yourself.

I would be more impresed by the computer student who used a proven "quicksort" than the student who invented "bubblesort" from scratch. Or who turned the ignition key of the Toyota instead of pushing it by hand.

David.

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

David, i think that this discussion is OT.

I had simply asked in this forum some questions about my problem, i think that i have not asked to anyone to do work for me. I asked only some explanation.
There aren't a stupid questions, there are only a stupid answers.

If you are able to help me ok, otherwise there are a lot of post in this forum where your culture, intelligence and savoir faire will be appreciated.
I'm free to follow my ideas and to do things in the way I want. Your role in this story isn't my mentor. If you can to help me ok, i will thank you, otherwise i'm not need your help.

Quote:
My advice would be to study how a proven library works. Ask questions. Understand it fully.

I have studied a device datasheet and AVR datasheet. Also i have studied how to work the I2C protocol. In the AVR datasheet there are a way to implement the I2C protocol using the interrupt. I have looked for some solution and i found an AVR315 application note. This is a official way to implement this protocol using interrupt. Basing on this paper i have implemented my code. It isn't work, so i have ask in this forum where is the problem.
But in this forum there is a GOD, that in this case has taken the form of DAVID PRENTICE. So, now i'm not try to solving my problem, but now i discuss on the create with GOD...

I think that you are a little too sure of yourself, the reality is a bit different than your thinking.

Once again, if you are able to answer my questions well, otherwise I do not need your help. Indeed avoids writing because the discussion is going well and I do not want to waste time arguing with GOD...

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

My first advice would be polled TWI via Fleury.
My second advice would be interrupt TWI via Atmel's AVR315.

No, of course you don't have to follow anyone's advice.

If you do follow AVR315 example, everything should work fine. Note that the example is not very practical or convenient API to use.

Don't worry about my personal opinions of University Education. Many people hold different opinions. It is worth thinking about because eventually you will be looking for a job.

Good Luck.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
No, of course you don't have to follow anyone's advice. 

I think that you are wrong. In effect i have followed your advice that i have previously read in this forum.

My first advice would be polled TWI via Fleury. 
My second advice would be interrupt TWI via Atmel's AVR315. 

The polling method is simple, i think that isn't necessary to use the Peter Fleury lib. In this lib there are some bit variation respect all literature that i have read about this argument. I think that for a student, or for all freaks, there shouldn't to be a problem to implements that the datasheet or a book, tell about the polling method and write the relative code.
The interrupt method is a bit different. The book tell nothing, and the datasheet show only how to work the I2C protocol using the interrupt. There aren't examples.

If you do follow AVR315 example, everything should work fine. 

Everything should work fine, but the reality is a bit different.

Note that the example is not very practical or convenient API to use.

I know, so i decided to adapt it to solve my problem, but so we have returned at the fist post on this discussion...

Don't worry about my personal opinions of University Education. Many people hold different opinions.  

Your'e right, the world is also nice for this...

It is worth thinking about because eventually you will be looking for a job. 

I'm a student, now I try to learn to do as much as possible, because in the future I would like to work on my own, and to do this I need to learn to solve problems that gradually meet on the street.

Thanks!

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

I think that the usefulness of a forum is to help those in need without feeling like a god.
Evidently for someone the forum is something different , maybe they are the stars that give a little to the head.

I'm sorry to write these things, but I think that I was treated badly just because , legally , I asked a few questions on how to solve a problem. Apparently it's my fault, that I did not understand good what is a forum ...
In the future I will try to sit away from this forum leaving the various lords of the moment to vent their frustrations on the inability, apparently, of who asks questions .

Returning to this topic , I would like to say that my way of thinking, and acting , it was correct . I managed to solve my problem without the help of my prof , of God and of the various Leonardo, Galileo , Aristotle, Einstein , Gauss , Lagrange,
Newton , DAVID PRENTICE ...

I have corrected the state machine of the procedure for reading data, and using interrupts i'm able to get the value of the register " Who_I_AM " of the sensor MPU6050 . Attached is the new picture, which of course is available to anyone who needs it.

no hard feelings
Luca

Attachment(s):