Reply
Posts: 91
Registered: ‎11-07-2016

Re: I do have a problem setting registers to my device over I2C...

Sorry, I mean SECOND row in the table.

 

Also, the pin is not configured as push-pull. It is Digital Open Drain I/O

Posts: 3,153
Registered: ‎02-07-2002

Re: I do have a problem setting registers to my device over I2C...

I was talking about the INT1 or INT2 pin of your LIS2DH. I do not think you can configure these output pins to be either push-pull or open-drain. That can only be done on the input pin of the MCU.

 

And I think you have shorted this output so often by now that is unlikely it is still operational.

<a href="http://community.silabs.com/t5/Welcome-and-Announcements/Community-Ranking-System-and-Recognition-Program/m-p/140490#U140490"><font color="#000000"><font size="2">Hero</font></font> </a> jmg
Posts: 1,185
Registered: ‎04-27-2004

Re: I do have a problem setting registers to my device over I2C...


vanmierlo wrote:

 

And I think you have shorted this output so often by now that is unlikely it is still operational.


The shorts for testing are brief, so the OP may be lucky and the device may still be ok.

 

It would be a good idea to add a series resistor of maybe 470 ohms, between the sensor and MCU, so that manual-short testings cannot stress things.

 

I would also add a LED to the Sensor INT, as it seems sticky and with some handshake, and a LED proves when it goes H/L associated with code stepping.

Posts: 91
Registered: ‎11-07-2016

Re: I do have a problem setting registers to my device over I2C...

Just to test, I reconnected my accelerometer eval board to the ATTiny85 board I used to do the initial prototype. It worked flawlessly so I don't think I've hosed the accelerometer. 

Posts: 91
Registered: ‎11-07-2016

Re: I do have a problem setting registers to my device over I2C...

Great idea on the LED in series with the interrupt. I'll do that when I get back to it after turkey day. And add a 470Ω resistor.

 

I'm still trying to understand why the manual connect to gnd is triggering when removed but not when connected to VCC and why the INT from the probe is not working. It has seemingly worked in previous trials but not now with the "logical" pin configuration.

Posts: 91
Registered: ‎11-07-2016

Re: I do have a problem setting registers to my device over I2C...

@vanmierlo - yesterday you wrote:

 

Level interrupts are perfect when servicing an external device like this in the ISR. As long as the device wants service it will keep the interrupt active. If a new event arrives in the device while you're still servicing the previous the line will stay active and will not retrigger. After the ISR ends the level will retrigger the interrupt.

 

This makes more sense now with the last day's leaning behind me. I had tried this at one point and I believe I ran into a problem using I2C to read data from and clear the interrupt on the accelerometer from the ISR. Perhaps it was my misunderstanding/misinterpretation in the heat of the moment. So I'll ask explicitly before trying this again, can I call I2C read/writes from within an ISR?

<a href="http://community.silabs.com/t5/Welcome-and-Announcements/Community-Ranking-System-and-Recognition-Program/m-p/140490#U140490"><font color="#000000"><font size="2">Hero</font></font> </a> jmg
Posts: 1,185
Registered: ‎04-27-2004

Re: I do have a problem setting registers to my device over I2C...


  So I'll ask explicitly before trying this again, can I call I2C read/writes from within an ISR?


In theory, i2c inside another INT is possible, but think a little about the fish-hooks lurking here :

 

The i2c bus cannot interrupt, so you must ensure no other i2c action is occurring, which either limits the BUS connections, or forces you to use i2c only inside the reacting INT.

 

i2c code that uses an interrupt itself, now needs more care - you cannot call that directly, but you can make that a higher priority, and so have the i2c state engine properly update, but that has now restricted other interrupt choices.

 

i2c transactions are not fast, and taking that much time inside an interrupt is best avoided.

Of course, if nothing else is happening, and there is no Serial Port, or SPI or ADC etc to service, you might not care if the MCU takes 100's of us to complete.

 

Notice how all this has gotten harder to debug, and riskier to expand later ... and what has actually been gained ?

 

Generally, fewer interrupts are easier to debug, and safer to expand later, and in your system case, you can poll the IE0 flag, ( _/= edge triggered)  as it will store until read.

Posts: 91
Registered: ‎11-07-2016

Re: I do have a problem setting registers to my device over I2C...

@jmg I have not experimented with polling the IE0 flag but given that I am not getting the INT trigger now, might polling also not work as expected?

 

And a second question, how would you compare polling the MCU's IE0 flag - which is connected to the probe's INT output to simply polling the probe's INT register via I2C directly? 

 

I think I answered my own question - polling the probe via I2C introduces the latency of I2C whereas poliing the MCU IEO does not. I'm willing to give this a shot, now I need to understand what this means from a pin configuration and code perspective to try.

<a href="http://community.silabs.com/t5/Welcome-and-Announcements/Community-Ranking-System-and-Recognition-Program/m-p/140490#U140490"><font color="#000000"><font size="2">Hero</font></font> </a> jmg
Posts: 1,185
Registered: ‎04-27-2004

Re: I do have a problem setting registers to my device over I2C...


I'm still trying to understand why the manual connect to gnd is triggering when removed but not when connected to VCC and why the INT from the probe is not working. 


If the GND test triggers, that proves you have a correctly active interrupt.

Proving the edge could be a little harder, as contact bounce is likely.

 

What I would do is, add test code to pulse a spare output pin (eg an LED pin) and connect that to the INT, the debug step will show which edge actives the INT.

 

Probe interrupt requires an edge, and if it goes high and stays high, you will see what you describe.

ie manual pull down triggers, but the probe does not re-trigger as expected.

If a software handshake is needed to clear the probe interrupt, then you need to focus on that.

Posts: 91
Registered: ‎11-07-2016

Re: I do have a problem setting registers to my device over I2C...

@jmg, it's late here in Boston so maybe I should mull it over but I don't understand these two statements:

 

What I would do is, add test code to pulse a spare output pin (eg an LED pin) and connect that to the INT, the debug step will show which edge actives the INT.

 

If I am not seeing the interrupt from the probe now, how does this work?

 

Probe interrupt requires an edge, and if it goes high and stays high, you will see what you describe.

ie manual pull down triggers, but the probe does not re-trigger as expected.

If a software handshake is needed to clear the probe interrupt, then you need to focus on that.

 

 

Wouldn't the MCU see the rising edge when the probe interrupt is asserted? That's the point I don't get - except for the weak pullup maybe interferring. But when I disable the weak pullups, my I2C ceases to function properly. 

 

I don't understand the last line. The probe INT does stay high until I clear it via I2C by clearing the interrupt register. What do you mean by focusing on that? Again, I am not seeing the interrupt at the MCU P0.7 that I have configured for EXT INT 0. If I poll the probe via I2C I do see the interrupt on the probe.

<a href="http://community.silabs.com/t5/Welcome-and-Announcements/Community-Ranking-System-and-Recognition-Program/m-p/140490#U140490"><font color="#000000"><font size="2">Hero</font></font> </a> jmg
Posts: 1,185
Registered: ‎04-27-2004

Re: I do have a problem setting registers to my device over I2C...


@jmg I have not experimented with polling the IE0 flag but given that I am not getting the INT trigger now, might polling also not work as expected?


You reported you do get an interrupt on manual trigger - that means the MCU side is working.

If you are not seeing a Probe INT, that is a separate issue you need to solve.

 


I think I answered my own question - polling the probe via I2C introduces the latency of I2C whereas polling the MCU IEO does not. 


Correct, there is nothing wrong with polling via i2c, if the MCU has nothing else to do, and you do not care about power consumption.

 

If you do care about power, then you might look at slowing down the MCU, and going into IDLE and that sleeps until an interrupt occurs.

 

Or, you can slow the SysCLK and poll IE0, and speed up to service it.

Does this have a Serial Port ? - Change of SysClk is more of a Pain with a UART active, so in that case usually one chooses some moderate clock speed as a compromise. In many cases, 24.5MHz is way faster than needed, and the default of /8 may be fine.

 

Posts: 91
Registered: ‎11-07-2016

Re: I do have a problem setting registers to my device over I2C...

Right, I do understand that the MCU side is working and I've actually seen the probe's interrupt signal working too but changing the P0.7 configuration to what I believe should be correct - rising edge, high - it does not trigger the MCU ISR handler. That's what I'm trying to sort out. This all worked on the ATTiny85 first try. I didn't expect to have problems at this level (I thought my biggest challenge would be the I2C interface and that's actually working great). The probe is being powered by the 2020A's 3v3 output as it is a 3V3 device. I reread the data sheet tonight and the outputs are .9 * VIN for high and .1 * VIN for low. I suspect this and/or the weak pull up is where the issue is but I have not yet figured out how to configure to resolve it. I'll attack it again after Turkey tomorrow. I really appreciate everyone's help, thank you.

<a href="http://community.silabs.com/t5/Welcome-and-Announcements/Community-Ranking-System-and-Recognition-Program/m-p/140490#U140490"><font color="#000000"><font size="2">Hero</font></font> </a> jmg
Posts: 1,185
Registered: ‎04-27-2004

Re: I do have a problem setting registers to my device over I2C...


mhackney wrote:

@jmg, it's late here in Boston so maybe I should mull it over but I don't understand these two statements:

 

What I would do is, add test code to pulse a spare output pin (eg an LED pin) and connect that to the INT, the debug step will show which edge actives the INT.

 

If I am not seeing the interrupt from the probe now, how does this work?


This splits the problem into two parts - a classic divide and conquer.

Your simple manual short to gnd can/has confirm INT is enabled in the MCU, but it is less useful to prove which edge you have active.

The self-test-code approach lets you exercise your code, with no probe connected at all.

It is always good to prove what you hoped is happening in code, actually is true Robot Happy 

ie you want an INT on _/=, and only one INT, on the edge.

 


 

The probe INT does stay high until I clear it via I2C by clearing the interrupt register. What do you mean by focusing on that? Again, I am not seeing the interrupt at the MCU P0.7 that I have configured for EXT INT 0. If I poll the probe via I2C I do see the interrupt on the probe.


If you can manually trigger an interrupt, (or do so with self-test-code + jumper) and you can meter/led prove the probe is going L/H/L/H as expected, then not much is left - maybe a bad connection ?

 

From a quick look at the data, that part seems to have many mapping choices for events -> INT pins, so I can imagine it is not an easy thing to nail down...

i2c polling is simpler, and may be more reliable, as it avoids mapping configs.

Is the speed/power tolerable when polled via i2c ?

<a href="http://community.silabs.com/t5/Welcome-and-Announcements/Community-Ranking-System-and-Recognition-Program/m-p/140490#U140490"><font color="#000000"><font size="2">Hero</font></font> </a> jmg
Posts: 1,185
Registered: ‎04-27-2004

Re: I do have a problem setting registers to my device over I2C...


mhackney wrote:

Right, I do understand that the MCU side is working and I've actually seen the probe's interrupt signal working too but changing the P0.7 configuration to what I believe should be correct - rising edge, high - it does not trigger the MCU ISR handler. That's what I'm trying to sort out. ..... I reread the data sheet tonight and the outputs are .9 * VIN for high and .1 * VIN for low. I suspect this and/or the weak pull up is where the issue is but I have not yet figured out how to configure to resolve it. 


If the Probe has CMOS drive then you can leave weak pullup as default = on.

Things are easier without pins floating.

Connect a meter or scope to P0.7 and confirm the LOW and HI voltages for your manual and probe cases. Poor Power supply connections can give funny outcomes...

 

Posts: 91
Registered: ‎11-07-2016

Re: I do have a problem setting registers to my device over I2C...

Some more experimentation - although I am not quite sure how to do a few of the recommendations.

 

1) If I disable weak pullups, I2C no longer functions correctly. This setting applies to all pins apparently. On my ATTiny85 prototype, I could disable the pullup on only the pin I was using and thats exactly how I did it. So the issue here is I can't do that on this MCU and the weak pullup is apparently causing a problem (keeping the pin high even when the accelerometer's INT has been cleared and it should be low. 

 

2) putting a meter between the MCU P0.7 and the accelerometer's output pin shows a constant 3.24 volts. 

 

3) if I disconnect the probe and put the meter between the GND pin and P0.7 I see the MCU interrupt trigger as soon as I touch GND and the meter displays 3.24 volts. So it seems like it is correctly triggering on the rising edge. If I disconnect from the meter and touch GND, it triggers when disconnecting from GND. I'm not sure I understand why the behavior is apparently opposite when inserting a meter in series

 

4) and this is the really odd one...

 

If I enable my polling code in my main loop (which reads the probe INT via I2C) with the meter set up between P0.7 and the probe INT pin I see 0.00V after initialization. Exactly the opposite from what I see if the polling code is commented out! If I then tap the probe to trigger an event, I see the meter spike voltage very quickly (I can't tell how high it goes, I just see a quick rise and settle back to 0.00V) and my test code blinks the red LED - which I see. If I set a breakpoint in the EXT INT 0 IRQ I don't break! And if I single step through my test code, I do not see P0.7 held high at all, it immediately goes back to 0v AND I do not see the MCU's IRQ get called at all. 

 

I really do not understand the behavior in 4 at all. At first I thought I might be clearing the probe's INT register too frequently but I confirmed that I only clear the register if an interrupt has occurred and more importantly the MCU's interrupt handler sets a global flag that an interrupt occurred and this is handled first in my loop. I never see the IRQ called. I'm posting my main(), perhaps a different set of eyes will help.

 

//-----------------------------------------------------------------------------
// main()
// ----------------------------------------------------------------------------
int main(void)
{
	uint8_t i;

	uint8_t outData = 0;
 	uint8_t eventTriggered;

	// Enter default mode
	enter_BusFreeMode_from_RESET();

	// These are unique to the Busy Bee board
	BSP_DISP_EN = 0;
	GREEN_LED = BSP_LED_OFF;
	BLUE_LED = BSP_LED_OFF;
	RED_LED = BSP_LED_OFF;

	// If slave is holding SDA low because of an improper SMBus reset or error
	while (!SDA)
	{
		// Provide clock pulses to allow the slave to advance out
		// of its current state. This will allow it to release SDA.
		XBR2 = XBR2_XBARE__ENABLED;       // Enable Crossbar
		SCL = 0;                          // Drive the clock low
		for (i = 0; i < 255; i++);        // Hold the clock low
		SCL = 1;                          // Release the clock
		while (!SCL);                     // Wait for open-drain
										  // clock output to rise
		for (i = 0; i < 10; i++);         // Hold the clock high
		XBR2 = XBR2_XBARE__DISABLED;      // Disable Crossbar
	}

	// Enter default mode
	enter_DefaultMode_from_BusFreeMode();

	SMB0_reset();

	// Use Timer 1 for SCL clock rate
	// Enable SCL low timeout using Timer 3
	SMB0_init(SMB0_TIMER1, true);

	//-------------------------------------------------------------------
	// First, let's make sure we can talk to the accelerometer
	numErrors = 0;

	transferInProgress = true;

	// Send out WHO_AM_I register and ask for result
	SMB_DATA_OUT[0] = WHO_AM_I;				// should be 0x33
	SMB0_transfer(IIS2DH_ADDRESS<<1, SMB_DATA_OUT, SMB_DATA_IN, 1, 1);

	// Wait until transfer complete callback is called
	while (transferInProgress);

	// Can we talk to the accelerometer?
	if (numErrors > 0)
	{
		// handle error - one way trip...
		terminalError();
	}

	//-------------------------------------------------------------------
	// initialize and enable the accelerometer
	initAccelerometer();

	// Did we get an error initializing?
	if (numErrors > 0)
	{
		// handle error - one way trip...
		terminalError();
	}
	else
	{
		// all good, blink 3 times slowly
		int i;
		for (i = 0; i <3; i++)
		{
			// slow 1/2 sec blink
			GREEN_LED = BSP_LED_ON;
			T0_Waitms(250);
			GREEN_LED = BSP_LED_OFF;
			T0_Waitms(250);
		}
	}

	enableAccelerometer();

	//-------------------------------------------------------------------
	// loop, waiting for accelerometer events to process
	while (1)
	{
		numErrors = 0;

		// the EXT INT 0 sets gotInterrupt
		if (gotInterrupt)
		{
			// do a long red LED flash
			GREEN_LED = BSP_LED_OFF;
			RED_LED = BSP_LED_ON;
			T0_Waitms(250);
			RED_LED = BSP_LED_OFF;
			GREEN_LED = BSP_LED_ON;

			// TODO: send a signal on an output pin

			// clear interrupts and wait for the next one
			enableAccelerometer();
			gotInterrupt = false;
		}

//========================================================================================
// This is test code that polls the accelerometer to check if an interrupt was generated

		// check to see if it was triggered
		transferInProgress = true;

		SMB_DATA_OUT[0] = INT1_SRC;
		SMB0_transfer(IIS2DH_ADDRESS<<1, SMB_DATA_OUT, SMB_DATA_IN, 1, 1);

		// Wait until transfer complete callback is called
		while (transferInProgress);

        eventTriggered = SMB_DATA_IN[0] & 0xC0;
        if (eventTriggered)
        {
        	// do a long red LED flash
			GREEN_LED = BSP_LED_OFF;
			RED_LED = BSP_LED_ON;
			T0_Waitms(500);
			RED_LED = BSP_LED_OFF;
			GREEN_LED = BSP_LED_ON;

            enableAccelerometer();
        }

// end of test code
//========================================================================================

		// Indicate that an error has occurred (LED changes color to blue)
		if (numErrors > 0)
		{
			GREEN_LED = BSP_LED_OFF;
			BLUE_LED = BSP_LED_ON;
		}
		else
		{
			BLUE_LED = BSP_LED_OFF;
			GREEN_LED = !GREEN_LED;
		}

		//	T0_Waitms(50);  // Wait 50 ms until the next cycle
							// so that LED blinks slow enough to see
	}

}

I have not tried the polling MCU interrupt but given the above, I don't think it would be triggered. At this point, I certainly could make this work with polling the INT state on the probe via I2C. Power is not an issue, this is a 3D printer and when it is on, the probe is powered. The probe's current draw is really not significant. On the timing front, the faster the interrupt is caught the better - this is a probe that will "slam" into the print surface in order to measure Z=0. It need to be caught quickly so as not to damage any of the mechanics. But "quickly" is relative and even the polling should be fast enough. What's more important is reproducibility on how long it takes to service the interrupt. If it takes exactly the same # of clock cycles each time a service is made, this amount of time translates to "measured distance" and can be compensated with an offset for the probe. All of the main 3D printer firmwares already have this capability built in because no probe triggers at exactly Z=0.

 

In describing this, I think the straightforward poll the accelerometer approach will work just fine for this application. I haven't found a strong argument for or against polling or IRQ for this simple application (where the IRQ really does not do any significant processing, it just sets a global "Hey, I've been called"). And with polling, I do not have to worry about the EXT INT 0 setup or pin configuration either. 

 

My hardware partner (who I've never met and is in Europe) has already designed the prototype board and I have the PCBs back from OSH Park. I know I can get the polling implementation working. I havent; scrutinized the CAD to see how he interfaced the INT pin (pull up/pull down, etc).

Posts: 8,176
Registered: ‎08-13-2003

Re: I do have a problem setting registers to my device over I2C...

[ Edited ]

Some more experimentation 

get ONE thing to work with EVERYTHING ELSE deleted/commented out, you are all over the place and will never get out by running around in the woods withot a cxompass.  Then (gradually) add the next thing, if the first breaks, then it is the addition that broke it and it is a whole lot easier to find out than the "this complete code does not work".

 

1) If I disable weak pullups, I2C no longer functions correctly. 

of course not if you do not have external pullups

 

here is another wild excursion,  getting interrupts to work is NOT done by trying polling.  what polling might show is equally easy to see in the debugger

 

what you evidently does not understand is that NOTHING, absolutely nothing generates an interrupt. certain things set a flag that makes the INTERRUPT HANDLER generate an interrupt.

 

In describing this, I think the straightforward poll the accelerometer approach will work just fine for this application. I haven't found a strong argument for or against polling or IRQ for this simple application (where the IRQ really does not do any significant processing, it just sets a global "Hey, I've been called"). And with polling, I do not have to worry about the EXT INT 0 setup or pin configuration either. 

polling is not recommended, it is rarely used by anyone that does not suffer from interruptifobia

erik
<a href="http://community.silabs.com/t5/Welcome-and-Announcements/Community-Ranking-System-and-Recognition-Program/m-p/140490#U140490"><font color="#000000"><font size="2">Hero</font></font> </a> jmg
Posts: 1,185
Registered: ‎04-27-2004

Re: I do have a problem setting registers to my device over I2C...


1) If I disable weak pullups, I2C no longer functions correctly. This setting applies to all pins apparently.


Yes, it applies to all pins.

It is probably good practice to add SCL.SDA pullups, (2k2~4k7)  as the MCU weak pullup, is quite weak and will limit the i2c speed.

 

 


If I enable my polling code in my main loop (which reads the probe INT via I2C) with the meter set up between P0.7 and the probe INT pin I see 0.00V after initialization.

That says you can drive the weak pullup fine.


I really do not understand the behavior in 4 at all. At first I thought I might be clearing the probe's INT register too frequently but I confirmed that I only clear the register if an interrupt has occurred and more importantly the MCU's interrupt handler sets a global flag that an interrupt occurred and this is handled first in my loop.

What does the debugger show for the TCON.IE0 flag, with interrupts disabled ?

This should act as a sticky-bit, for any Edge in, you can inspect at any time. (manually clear)

 

All other behaviour sounds down to the Probe, and it may be the INT pin interacts with i2c transactions.

This is why a divide and conquer approach is best, you first nail down the correct Edge-INT or Edge-Capture, then attach the Probe, which may have a mind of its own to nail down....

 

Do you have a Scope you can connect to the INT line ?

There is a minimum time for INT to be seen, but it's rather unlikely you are below that.

 


On the timing front, the faster the interrupt is caught the better - this is a probe that will "slam" into the print surface in order to measure Z=0. It need to be caught quickly so as not to damage any of the mechanics. But "quickly" is relative and even the polling should be fast enough. What's more important is reproducibility on how long it takes to service the interrupt. If it takes exactly the same # of clock cycles each time a service is made, this amount of time translates to "measured distance" and can be compensated with an offset for the probe. All of the main 3D printer firmwares already have this capability built in because no probe triggers at exactly Z=0

It will not take exactly the same# of clock cycles, but the variation is small, provided no other interrupt is active.

If you want to cover the case of other interrupts active, then you should set a higher priority to the INT0, and it sounds like you ideally need to capture some time-value inside that interrupt for Z=0.

( IIRC the Tiny's cannot manage priority levels ?)

 

Note the EFM8 also has Capture timers (3+ch), in the PCA, which can capture an exact time value in hardware, and that can be prescaled via Timer0, to give useful range.

This capture will also generate an interrupt, (or set a flag) but now it does not matter how long the interrupt takes, or if another interrupt is active.

 

Posts: 91
Registered: ‎11-07-2016

Re: I do have a problem setting registers to my device over I2C...

It may seem like that but actually I'm not. I change one thing at a time, test, analyze results and then determine what next to do. The list I posted are the results of many independent tests and clearly show that I got several "1 thing"s working with everything commented out. The code I posted is simply to show the entire work. Sorry if it seemed confusing.

At this point it's clear that the weak pull-up is the culprit. But I can't disable that as it affects all pins, including the I2C pins (and I2C ceases to work properly). This is unique to this MCU as contrasted with the ATTiny85 that I originally used to do a proof of concept. The reason we wanted to change the MCU is cost reduction and ultimately being able to leverage this experience for other projects.

With this prototype composed of two evaluation boards simply wired together, which was done to get the code ported, there does not appear to be a software-only pin configuration that will work. This was the ah-ha moment for this MCU. With our hardware design we can add external pull-ups to the circuit for the I2C pins. But we've already produced a handful of PCBs without the external pull-ups - which is the primary reason I was trying to find a software configuration solution. So, I'll implement an I2C polling solution for these rev 1 boards so I can test the accelerometer auto sensitivity calibration and other software features I've developed. We can then decide if we need to redesign to add the pull-ups and/or pull downs for the next rev.

In retrospect it also turns out that a lot of the unexpected/odd behavior was the result of the oddnesses I came across in the IDE (the wine Mallon issue that will actually launch into the debugger but fail) and the generated SMB IRQ that is continuously called unless deleted. Even the example code presents this problem if you simply regenerate the Configurator source and build.
<a href="http://community.silabs.com/t5/Welcome-and-Announcements/Community-Ranking-System-and-Recognition-Program/m-p/140490#U140490"><font color="#000000"><font size="2">Hero</font></font> </a> jmg
Posts: 1,185
Registered: ‎04-27-2004

Re: I do have a problem setting registers to my device over I2C...


At this point it's clear that the weak pull-up is the culprit.

 


 

I'm not sure that is true.

 


 With our hardware design we can add external pull-ups to the circuit for the I2C pins. But we've already produced a handful of PCBs without the external pull-ups - which is the primary reason I was trying to find a software configuration solution. So, I'll implement an I2C polling solution for these rev 1 boards so I can test the accelerometer auto sensitivity calibration and other software features I've developed. 

I'd suggest you add pullups during testing, and then once it is stable, check that you can remove them.

Use a scope to check the effects on the final PCB, but keep in mind using internal-pullup-only will likely lower the workable i2c clock speed simply from the slow rise times.

That in turn, will lower the poll rate...

 

Check the Probe to nail down if it is Push-pull or some combination of Push-Pull and tristate.

A change of LED load to Vcc then LED load to GND can confirm if it is driving both ways.

 

The best-fit solution for your Z=0 sense, would be to change to a PCA HW Capture, once you can get a reliable edge from the Probe.

 

You should be able to map CEX0 onto the same INT0 pin using the crossbar.

Posts: 91
Registered: ‎11-07-2016

Re: I do have a problem setting registers to my device over I2C...


At this point it's clear that the weak pull-up is the culprit.

 I'm not sure that is true.

 

I'm basing this on the observation that everything works perfectly with an ATTiny85 processor interfaced to the same accelerometer eval board. I checked again today just to make sure. Two significant differences are that the pin the accelerometer's INT pin is connected to does not pull up and the interrupt is level triggered high.

 

I just looked through our PCD schematic and we do have external pullups on SDA and SCL.

 

My motivation here the last week or so was to use the Busy Bee eval board to port my code over and then connect to the accelerometer eval board to do some preliminary testing while I waited for the PCBs to come in. And also to get familiar with Simplicity Studio and the configuration and debugging tools. I erroneously assumed it would be just as straightforward to connect the Busy Bee eval to the accelerometer eval board as it was to connect the ATTiny85 to the accelerometer eval board (I used an external interrupt on the ATTiny85 with a simple handler that set a global exactly the way I was trying to do with this MCU).

 

I now have 6 prototype PCBs and components so I can assemble one or two boards to program and test. The convenience of using the Busy Bee was good to jump start this port. I do think a good use of time and a  logical next test is to install external pull-ups on the SDA and SCL I2C pins and disable weak pull-ups on all pins, and configure P0.7 to trigger on rising edge. I do have a pocket digital oscilloscope that is satisfactory for this testing. 

<a href="http://community.silabs.com/t5/Welcome-and-Announcements/Community-Ranking-System-and-Recognition-Program/m-p/140490#U140490"><font color="#000000"><font size="2">Hero</font></font> </a> jmg
Posts: 1,185
Registered: ‎04-27-2004

Re: I do have a problem setting registers to my device over I2C...


 I do think a good use of time and a  logical next test is to install external pull-ups on the SDA and SCL I2C pins and disable weak pull-ups on all pins, and configure P0.7 to trigger on rising edge. I do have a pocket digital oscilloscope that is satisfactory for this testing. 


Sounds a good idea.

 

If you have a scope, another test for uncertain pin-states, is to place 2 resistors in series Vcc-Gnd - say 10k and 47k, and connect INT to the centre point.

That should show

 ~ 0V on CMOS drive low,

 ~ 3.4V on CMOS drive high, and

 ~ 2.7V on TriState, which MCU will read as 1

Swap the 10k/47k order, if you want a Logic-Low on Float.

 

Then you can track exactly how the probe varies INT drive, and how it reacts to Pullup/PullDowns.

Highlighted
Posts: 91
Registered: ‎11-07-2016

Re: I do have a problem setting registers to my device over I2C...

Ok, after a good night's sleep following a day of fasting with family I took a fresh look. First I hooked up the scope and with the accelerometer INT pin disconnected from the Busy Bee I verified that the pin went and stayed high when I tap the probe. But, it was not being reset to go back low. I went through the code and accelerometer data sheet carefully and discovered that with the change I made this week to my I2C code to pass the register and single byte to write, I was calling this same code to clear interrupts on a read-only register. My setRegister() was not actually reading anything. So I created a readRegister() that does the correct thing.

 

This showed the correct behavior on the scope (probe int disconnected): tap the probe, pin went high and stayed high until cleared by call to readRegister(). I then attached the probe int to P0.7 on Busy Bee expecting things to be "right" but they weren't. I would see the int go high on the scope and stay there. The interrupt handler was not called (breakpoint not triggered) and my program could not be broken at all. This triggered an ancient memory of off interrupt behavior when accessing global variables so I took a closer look at my header file and, lo, I found the volatile culprit. This was not good:

// Got interrupt from accelerometer
extern uint8_t gotInterrupt;

This is good and now my interrupt handler works exactly as expected and reliably.

// Got interrupt from accelerometer
extern volatile uint8_t gotInterrupt;

gotInterrupt is set to true inside my EXT INT 0 handler - that's all it does. My main() loop then sees this flag and handles it accordingly.