Netduino home hardware projects downloads community

Jump to content


The Netduino forums have been replaced by new forums at community.wildernesslabs.co. This site has been preserved for archival purposes only and the ability to make new accounts or posts has been turned off.
Photo

SPI/I2C Conflict


  • Please log in to reply
No replies to this topic

#1 ByteMaster

ByteMaster

    Advanced Member

  • Members
  • PipPipPip
  • 76 posts

Posted 30 July 2012 - 09:04 PM

I've been fighting with an issue most of the day and I'm hoping that someone here can help me.

I have sensor board where I'm pulling I2C data from a gyro every 10ms, I'm then triggering an IRQ to the GO! board for the GO! board to pull the data via SPI. Most of the time this works great. The challenge is when GO! board is busy and doesn't get around to handling the IRQ for a while and does so when the module is pulling the next data from the gyro. When this happens it appears as if the I2C line will ignore setting the stop condition and my gryo jumps the tracks and kills the I2C bus by keeping the line low.

The SPI communication is done via an interrupt handler and the I2C is initiated by a GPIO IRQ, but just bangs out the I2C communcication sequentially (doesn't use an IRQ). I did set the GPIO IRQ priority lower so it wouldn't interfere with the SPI communcations.

Here is the offending I2C code, note that TWB_GO_GetState() is used to determine if SPI communications is occurring. If so we just spin until we go back into an idle state.

	while(_rxBytesToReceive > 0) {
		if(TWB_GO_GetState() != GO_STATE_Idle) {
			TWB_Sleep(1);
		}
		else{
			if (_rxBytesToReceive == 1){
				/* Disable Acknowledgement */
				I2C_AcknowledgeConfig(I2C_ACK_NONE);		
	
				/* Send STOP Condition */
				I2C_GenerateSTOP(ENABLE);			
	
				/* Poll on RxNE Flag */
				while ((I2C_GetFlagStatus(I2C_FLAG_RXNOTEMPTY) == RESET));
				//while (I2C_GetFlagStatus( I2C_FLAG_TRANSFERFINISHED) == RESET) {}
									
				/* Read a byte from the Slave */
				_rxBuffer[_rxBufferIdx++] = I2C_ReceiveData();					
	
				/* Decrement the read bytes counter */
				_rxBytesToReceive--;
			}				
			else if (I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_RECEIVED) ){
				/* Read a byte from the I2C Bus and stuff it in the buffer*/
				_rxBuffer[_rxBufferIdx++] = I2C_ReceiveData();
	
				/* Decrement the read bytes counter */
				_rxBytesToReceive--;
			}		
		}


I know from my logic analyzer that the code with one byte left runs, and blocks on the SPI being active (can tell by the NAK). If you look at the attached capture from the logic analyzer, you can see the I2C lines are low until the SPI communication is done, then you can see the I2C line clocks in the last byte and sends a NAK. The problem is it doesn't send the stop condition after the NAK, it looks like it want's to clock in another byte and this apparently is confusing the heck out of the gyro.

Did that make any sense at all?!?!?!?

Help!

Attached Files


Kevin D. Wolf
Windows Phone Development MVP
President Software Logistics, LLC
Tampa, FL




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

home    hardware    projects    downloads    community    where to buy    contact Copyright © 2016 Wilderness Labs Inc.  |  Legal   |   CC BY-SA
This webpage is licensed under a Creative Commons Attribution-ShareAlike License.