I2C ROM blocking functions "succeed" with I2C clock disabled

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 

I2C ROM blocking functions "succeed" with I2C clock disabled

2,253件の閲覧回数
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by MarcVonWindscooting on Sun Apr 06 16:02:26 MST 2014
This weekend I continued to work on my LPC812 PCB that uses power-down mode to save power. There's a DS75 temperature sensor and a 24AA01 serial EEPROM connected to the I2C interface of the LPC. Three 74LVC1G57/58 single gates and a few MOSFETs implement a software-controlled step-down converter + power LED-driver. The LPC812 is powered by a STLQ015XG33 uPower LDO.

To get into power down, the DS75 sensor has to be powered down by a special command. I chose to use the  ROM API (blocking) functions available on the LPC800 for that.

At one point, I forgot to enable the I2C clock and the result was, that the functions return without an error from writes and reads - very much to my surprise. The DS75 'output' read 0 Celsius and the 3-byte write to power it down 'succeded', only it did not consume less power and it's not really that cold in my lab ...!?

Typically I expect more dramatic failure (lockup or error code) in response to such a fundamental configuration error of mine.
I share this information just in case someone else runs into a similar problem where "everything works", except for unplausible readings...

PS: the system can be powered down to 3.7uA @ 2.2..3.6V supply, all outputs in defined state.
LPC800 is so cool! :)
ラベル(1)
0 件の賞賛
返信
10 返答(返信)

1,985件の閲覧回数
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by rw_ on Wed Apr 16 05:29:00 MST 2014
There are things happening in the 'under current' that take much explaining before they're made clear.  This isn't about a DS7505. :D

The reason that I 'chose' it was to test the I2C code from the LPC812.  (Note that I started with an LPC810, which is 'weird' in terms of Keil when you exceed the 4K flash size and have already switched to the 812 but 'forgot' to change the flash programmer/driver to 16K for the 812 in the project settings...but that's another story.)

I am writing a low-level driver for a different part (has nothing to do with temperature).  The eval board that I have for the IC has 10K PUs on it and is supposedly spec'd to rates at up to 3.4 MHz.  I was using the 7505 to validate that the I2C code was working as a 'simple' test before writing the relatively more complex code for the eval board IC.  I haven't looked at the I2C spec in a good while, but I don't remember seeing anything about 3.4MHz in it... :)

As for my remark, this is the code that I was referring to:

printString("\nT = ");
printSDec32(ds75ReadTemperatureBlocking_e8(h)>>8);
printString(" C\n");

...it looks like the print function discards the sign, but I don't have access to that code.  Not that the actual temp 'read' tossed it out, but the 'presentation layer' was discarding it...at least that is what came to mind.  The only reason that I mention it is that I find myself doing such things from time-to-time and 'miss' it in test because I didn't test at below 0C on my lab bench (in Florida where it is 28 or 29).

...perhaps if the 'print' function was a SDec8 ?
0 件の賞賛
返信

1,985件の閲覧回数
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by MarcVonWindscooting on Wed Apr 16 04:13:11 MST 2014
The 10k pullups are way out of spec, although it's 'common practice' to violate the spec. 1.8k would be much better.
Fine, that you solved the problem! Yeah, copy and paste. Everyone does it, everyone knows the same 'blindness' problem.

Why did you choose the DS7505? For what special feature? There are so many alternatives, even from one manufacturer...


Quote: rw_

I did take a look at your code.  The first 'issue related' thing that came to mind (without looking very closely) is that perhaps your code isn't handling negative temperatures properly?  Just a thought; not intending to be critical.



Hey thanks for the remark! No way, my code sign-extends correctly  :((

0 件の賞賛
返信

1,985件の閲覧回数
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by rw_ on Tue Apr 15 17:56:58 MST 2014
I got it working.  Yet another situation of user error that happens after staring at the same code for too long.  I wrote and tested my function named I2cMasterWrite.  Verified that the bits asserted on the I2C bus were as desired/expected, then did the heinous cut-n-paste+modify faux pas for my I2cMasterRead function.  Somewhere along the line, I did a 'rebuild all' and found that I2cMasterWrite was doubly implemented; likely due to an interruption and 'pasting again' as I returned to task.  Of course, I deleted the 'wrong' one (one would think that they'd be identical but never forget that 'modify' doesn't mean accurate).

The 'error' was in that my 'remaining' write function was 'modified' for the 'read' buffer pointer (in preparation for the 'newly implemented' read function) in the param struct making it the 'wrong' one for a 'write' and I didn't catch it until after taking a break from looking at it.  Naturally, the weirdness was from an uninitialized buffer pointer that was being stuffed down the pipe and coming out 0x23 instead of what I wanted.

Note that in my DS7505 'write' function, I do not enable the stop bit in the param structure, which seems to work fine.  I enable the stop bit in the 'read' function.

I did take a look at your code.  The first 'issue related' thing that came to mind (without looking very closely) is that perhaps your code isn't handling negative temperatures properly?  Just a thought; not intending to be critical.

I'm using 10K PUs at 100KHz.
0 件の賞賛
返信

1,985件の閲覧回数
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by MarcVonWindscooting on Mon Apr 14 13:29:00 MST 2014

Quote: rw_

As for the PLL, the ROM API has a PLL configuration feature, too.  I was simply defining USE_ROM_API "just in case" something else wanted it in the code/library, even though I grep'd it.


No. I haven't seen a single indication in the UM, so I believe, its an LPCOpen thingy.

Sorry for your trouble with SystemInit and .bss .
While I do understand the need to initialize external RAM hardware before blanking .bss,  I seriously doubt this will be done for a LPC800 ;-)


Quote: rw_

A quick look at your code looks like I need to use the "i2c_master_tx_rx_poll" function instead of the 'transmit' followed by a 'receive' call, which is what I have been doing.



There's a difference between the two approaches: yours introduces a STOP condition between transmit and receive whereas i2c_master_tx_rx_poll does not (using repeated START instead).
When looking at the DS7505 datasheet, I find no description of a 'set pointer byte' (only) instruction. The pointer byte is always used with some data following. What if the DS7505 is a bit nitpicking about that?

By the way, are the SDA, SCL pullups small enough and the SCL clock fast enough, to not run into DS7505 bus timeout?
0 件の賞賛
返信

1,985件の閲覧回数
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by rw_ on Mon Apr 14 06:05:17 MST 2014
I got it working *some* ...then, after fooling around with the code trying to get it to read two bytes (it kept reading only one byte, no matter how many bytes I told it to read in the parameter structure), it "decided" to quit addressing the bus properly.  I started seeing 0x23 instead of 0x90 as the slave address being asserted on the bus, to which, obviously, the slave would not ACK.  I have no idea why it started doing it.  I reset everything, rebooted Windoze and Keil and cycled power enough times and eventually shelved it after testing the DS7505 with an external I2C master 'pod,' which worked fine *and* read both temp sensor bytes.

As for the PLL, the ROM API has a PLL configuration feature, too.  I was simply defining USE_ROM_API "just in case" something else wanted it in the code/library, even though I grep'd it.  There are enough minor issues combined to make one wonder whether or not it works, but, to be fair, the documentation does say that the polled I2C is intended to be for trivial use whereas the interrupt-driven ROM API for I2C is intended to be (assumed) production ready.  Maybe my next step is to modify the code for interrupt use?  I can't imagine anything more trivial than reading two bytes from a 7505...

I eventually discovered my own error(s) in terms of initial usage.  I was calling the i2c_setup function from the SystemInit function, which is called before main.  Naturally, Keil was 'secretly' initializing the .bss section somewhere after SystemInit and before main and trashing my global handle.  Doh!  Slow firing synapses recalled Kevin Wells telling me to not use any global data in SystemInit...but somehow that fired too slowly until after debugging showed that as soon as I entered main, my global handle was zeroed.  I pulled the code out of SystemInit, called it from main and things got significantly better until the 'weird' addressing snafu.

A quick look at your code looks like I need to use the "i2c_master_tx_rx_poll" function instead of the 'transmit' followed by a 'receive' call, which is what I have been doing.  Of course, who knows what will happen before I figure out why 0x90 (or 0x91) somehow magically become 0x23...inducted bit flipping from local noise on my LA leads?

I'll try it and let you know...

0 件の賞賛
返信

1,985件の閲覧回数
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by MarcVonWindscooting on Sun Apr 13 04:35:39 MST 2014

Quote: rw_
Note that my call to i2c_get_firmware_version returns 0x00000201, which, interestingly, corresponds to LPCOpen version 2.01 as defined in the 'version.txt' file:



My LPC812 reports that number, too, although I do not use LPCopen.

I attached my (minimalistic) approach to the ROM-API (non-LPCopen). Perhaps, you can give it a try? The c-file will not compile in your environment - you have to replace the output functions at least. But I think it says what it does.
I have no idea, why the LPCopen I2C rom api should mess with PLL settings - my approach doesn't.
0 件の賞賛
返信

1,985件の閲覧回数
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by rw_ on Fri Apr 11 21:04:00 MST 2014
Note that my call to i2c_get_firmware_version returns 0x00000201, which, interestingly, corresponds to LPCOpen version 2.01 as defined in the 'version.txt' file:

$ cat version.txt
2_01
Fri 10/04/2013
0 件の賞賛
返信

1,985件の閲覧回数
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by rw_ on Fri Apr 11 20:40:13 MST 2014
DS7505...

Still working through it.  Hits the HF handler every time I call the 'i2c_master_transmit_poll' function.

Interestingly, I call the i2c_get_status and it returns 0x69, which is not one of the 5 (0...4) possible modes.

Also, found a 'bug' in the ROM API code in sysinit_8xx.c.  The '2nd' cmd[2] assignment should be cmd[3].

#if defined (USE_ROM_API)
/* Use ROM API for setting up PLL */
cmd[0] = Chip_Clock_GetIntOscRate() / 1000; /* in KHz */
cmd[1] = 24000000 / 1000; /* 24MHz system clock rate */
cmd[2] = CPU_FREQ_EQU;
cmd[2] = 24000000 / 10000;
LPC_PWRD_API->set_pll(cmd, resp);

/* Dead loop on fail */
while (resp[0] != PLL_CMD_SUCCESS) {}

#else

Using an external pod I2C master device, I am able to verify that I can read the DS7505 just fine.  (Putting finger on the package increases temp results.)

LPC_I2CD_API is a structure that 'maps' to the ROM and 'overlays' the ROM functions so that you can use reasonable names to access (dereference) them.

As far as blasting away under bridges on watercraft ala James Bond, I can't help you except to say it's a 'tourist industry' (meaning, check your wallet before leaving).

My suggestion for paying the ticket would be to contact the county where you received the ticket?  Not really my specialty.
0 件の賞賛
返信

1,985件の閲覧回数
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by MarcVonWindscooting on Fri Apr 11 07:24:50 MST 2014
0x48 = temperature sensor, like LM73 / LM75 / ... ?

Suggestions? Possibly a problem with the param / result arrays: memory region (ro) or mis-alignment ?
LPC_I2CD_API ist a macro, I guess? I wasn't able to derive a compile-time address for this. I had problems
dereferencing the function table at first, but that shouldn't be the problem in your case, escpecially because initialization succeeded.

Offtopic:
Are you from Florida? If so, can you tell me how/where to pay a 'speeding ticket' online? I mean a speeding ticket for riding 4mph under a bridge on a jet-ski (OMG)...
0 件の賞賛
返信

1,985件の閲覧回数
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by rw_ on Fri Apr 11 06:08:40 MST 2014
I've been trying to get the I2C ROM API driver working in Master mode.  Haven't spent much time on it yet, but was using the LPCOpen "periph_i2c_rom.c" example code as a base line, with some seemingly minor changes.  My goal is to use the 812 as a bus master and another IC as the slave.

Everything seems fine during the initialization.  Calling error_code = LPC_I2CD_API->i2c_master_transmit_poll(i2cHandleMaster, &param, &result); causes a hard fault and puts me in the HardFault_Handler.

I'm seeing nothing on the I2C bus like a start condition, address asserted, nothing.  My parameters are nearly identical to the example code even the 7 bit address is the same (0x48).

Any suggestions?
0 件の賞賛
返信