This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

I2C3 SensorHub with TMP006 - register always busy

Other Parts Discussed in Thread: TMP006

Hello, 

I am trying to make my own interface with the Sensorhub TMP006 sensor, using I2C. Right now I'm only trying to write to the config address in the TMP006 module.

I followed through some of the sensorhub example program, as well as the Datasheets, and I cannot understand what is wrong and why the code is not working. Here's the line of code that gives me trouble:

I'm not sure how it's best to show how I configured the I2C3 ports, with code or with the Register maps. I'll go for both. Right before I run the highlighted line, this is how the settings for the I2C3 regs are:

The SYSCTL regs seem fine, for PortD. This is the Init function (clock is confirmed 50 MHz):

void I2C_Init(){
	// Initializes I2C(3) peripheral.

	// Enable clock using RCGCI2C
	SYSCTL_RCGCI2C_R |= SYSCTL_RCGCI2C_R3; // 0x0000.0001

	// Enable the clock to the appropriate GPIO module using RCGCGPIO
	SYSCTL_RCGCGPIO_R |= SYSCTL_RCGCGPIO_R3; // 0x0000.0008

	// Alternate function GPIOAFSEL
	GPIO_PORTD_AFSEL_R |= (GPIO_PIN_1 | GPIO_PIN_0);  // pins D0 and D1

	// I2CSDA pin for open-drain operation
	GPIO_PORTD_ODR_R |= (GPIO_PIN_1 );

	// configure appropriate pins in GPIOPCTL register
	GPIO_PORTD_PCTL_R =  GPIO_PCTL_PD0_I2C3SCL | GPIO_PCTL_PD1_I2C3SDA;


	// Initialize I2CMCR by writing value of 0x0000.0010 (master mode)
	I2C3_MCR_R |= I2C_MCR_MFE;

	// Set the correct I2CMTPR register value
	/*for 100kHz, we have tbit = 10000ns. If we consider
	 * the clock speed to be 50Mhz, then t = 20ns
	 * Using the formular TPR = 500/t - 1
	 * We get TPR = 24 = 0x18*/
	I2C3_MTPR_R = 0x00000018;

}

Anyways, once I run the function, the MCS register becomes busy:

And then it gets stuck in the while loop. I am pretty sure the hardware is connected correctly, as I've run the example project with success. I cannot understand why it's staying on the busy loop, and why the write isn't happening.

EDIT: Also, the device address I'm using is 0x41, which is the same one used in the example program. 

Please let me know if there is more info I can provide, and thanks in advance,

Paulo

  • Hello Paulo

    1. When a MCS register operation is requested you must wait for the Busy Flag to get cleared before doing the next MCS operation. This is not the case in the code you sent. Also since there is a delay from MCS being programmed to the flag getting updated, a small delay loop of 10 would be a good line of code to have
    2. When running I2C make sure that any register or browser window are not open as some of the register bits are Clear on Read causing the main program to get stuck.
    3. Make sure that the bus is idle (Bus Idle condition in I2CMCS), before beginning any new I2C transaction. Or using the I2CMBMON register check that the SCL and SDA are 1 and there is no pull up issue.

    Regards
    Amit
  • Hi Amit,

    1. I tried adding both of these after setting the MCS bits:

    SysCtlDelay(10);
    while(I2C3_MCS_R & I2C_MCS_BUSY){};

    As well as running the code off of reset, and it still gets stuck in the while loop.

    2. I'm not sure what you mean by this, what exactly would cause the register bits to be clear.

    3. I've checked these registers, and they are 1 right before the Master enable command:

    I2C3_MCR_R |= I2C_MCR_MFE;

    And then they are always 0.


    Could this be the problem?
    Thanks,
    Paulo

  • Hello Paulo,

    Have you configured the GPIO for I2C?

    Regards
    Amit
  • Yes! It is in the code above.

    Here are my GPIO settings right before the troublesome line:

    I set up PUR as a test, but it didn't help.

    Thanks,

    Paulo

  • Hello Paulo,

    The GPIO_DEN register bits are not set for the corresponding pins: Digital function will not work without the same. This is one major setback when using DRM style of coding. This could have been easily avoided by using TivaWare and I reckon this is not going to be the last of the issues if DRM is continued further (Stong Advise: Move to TivaWare)

    Regards
    Amit
  • Hi Amit,

    This worked, thanks! I thought that DEN wasn't necessary when AFSEL is required. I now found where it explains this on the datasheet.

    I recognize that this style of coding is very non-efficient, but I'm making it a point to familiarize myself with the register workings of the microcontroller. During this extensive debugging process, I end up learning a lot of things, both specific to TM4C, and specific to the peripherals I'm trying to use.

    Thank you once again,
    Paulo
  • Paulo Costa said:
    During this extensive debugging process, I end up learning a lot of things, both specific to TM4C, and specific to the peripherals I'm trying to use.  

    And - if you'll accept an opposing viewpoint - just how "real" - and how "lasting" - do you believe such "learning" will remain?

    Amit on a daily basis - and myself as small tech biz owner - fight this, "learning vs. program completion" battle all too often.    In business - "the prize is to the swift!"    Look at any, "Market introduction vs. Profit curve" it all happens early - pity those who "learn" and sacrifice "shipments!"

    I challenge that "learning claim" as well.     Might that be extremely "short-term" - and often only a, "mirage?"    Will you (really) benefit by memorizing which bit scheme - fits with which register - in which peripheral?    Sorry but that does not make much sense.

    This vendor succeeds often due to the well crafted - extensive - and well tested/verified APIs.     Can your DRM code claim "any" of the above?  

    I direct none of this viewpoint against you - your skills - personally.     I direct it fully against what Amit, myself - and many experienced others believe to be, "fools' gold."    Should not the real goal be, "learning to employ the MCU resource in the most efficient manner - to solve real world problems?"     Is the rejection of the proven & far faster & safer (thus more efficient) API really justified?

    If you must - after the project is completed - you can "wade thru" the register intracacies.    Ideally - in that process - it may dawn that such, "low-level" analysis demands exacting attention to detail - and sensitivity to the importance of (in some cases) even the sequence of register manipulations.     Is not that the most valued lesson - and best learning?

    When experts have done the, "heavy lifting" - and thousands before you have sailed those same seas safely - how can it make sense to "discard their charts" and sail off into dark skies & high winds, chart-free?       This prolongs & endangers your voyage -  at best you'll become "almost" (but never) as "good" as the earlier, MCU "masters" and your frustrated/anxious, "clients/teachers/bosses" will (fairly) demand to know, "Why!"    

  • Hi cb1-,
    I have no doubt about the superiority of using an api, there's zero argument to that. But Im not a hobbyist, and my main goal at the moment is not to "get stuff done" as efficiently as possible.
    I like to understand how things work and how they are implemented. While I agree the skill "knowing which bits " will be useless as soon as I look at another MCU, the skills "looking at datasheets" and "debugging your code" are very handy. I read hex a lot faster thanks to this, and I know a lot more about I2C than I would if I had just used the library functions. I just bought a LA and will use it extensively to actually see the I2C in action and do further debugging on my own tmp006.c library.
    So, personally I see a lot of benefits in suffering through the registers, and I dont find it boring at all!
    on a last note, I feel this is why I am EE and not a CS student.. I absolutely hate extremely high level workspacE if I have no clue whats going on underneath
    Hope this makes sense!
    Paulo
  • Hi Paulo,  

    Indeed you make much sense - and on a (tightly) confined level - I agree. 

    That said - may I suggest that, "Starting w/the API - with the actual, individual "C" functions open/exposed - and w/the MCU manual's peripheral register pages similarly open" - accomplishes very much of your objective - yet is far more timely & efficient.    That's (precisely) our small tech firm's rule - and while there was (some) resistance - that's no longer the case.     (you may wish to adopt & experiment - the "dead ends/head-scratching" which past thrived - now have, "left the building.")  

    Recall the early days in US west - "pioneers" were (easily) identified by the number & variety of arrows - embedded their (dead) flesh.     That's not a fate I wish for you/others.    

    There "is" an alternative to "clueless" (apologies to Ms. Silverstone) - and it's been presented...

  • Hello Paulo,

    While we appreciate your approach, there are more complicated functions like SysCtlClockSet and SysCtlClocFreqSet that have a lot more room for errors, sometimes becoming nasty when the system clock frequency is locked to a frequency that may cause over clocking or underclocking and causing a pseudo-JTAG lockout.

    Regards
    Amit