W!o+ 的《小伶鼬工坊演義》︰ 一窺全豹之系統設計‧探索‧丙

甲骨文丁一

甲骨文丁二

甲骨文丁三

説文解字》:,夏時萬物皆丁實。象形。丁承丙,象人心。凡丁之屬皆从丁。

本義︰竹木或金屬製成之頂寬足尖的契子。

─── 見於《《派生》 Python 作坊【丁】陽燧月鑑

 

話說眼尖心細的讀者,早已看出上篇『補丁』,對『 read_i2c_block 』而言,恐將不受『 index==4 』的管制︰

void loop()
{
  long dur,RangeCm;
  if(index==4)
  {
    flag=1;
    //IR reciever pin set command
    if(cmd[0]==22)
       IR.Init(cmd[1]);

…………

    if(flow_run_bk)
    {
        if(millis()-flow_read_start>2000)
        {
            Calc = (NbTopsFan * 30 / 73);
            flow_val[0]=1;
            flow_val[1]=Calc%256;
            flow_val[2]=Calc/256;
            NbTopsFan = 0;
            flow_read_start=millis();
        }
    }
}

 

。要是想『 CMD=1 』是『 Digital Read 』指令,或可『無礙』乎?由於作者尚未能深思熟慮,故而祇想以最少『修補』爾爾!更何況這也方便探究其與『 Digital Read 』之『差別』也??

【 digitalRead vs. read_i2c_block 】

>>> switch=3
>>> grovepi.pinMode(switch,"INPUT")
1
>>> grovepi.digitalRead(switch)
0
>>> grovepi.read_i2c_block(addr)
[11, 2, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]
>>> grovepi.read_i2c_block(addr)
[11, 190, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]
>>> grovepi.read_i2c_block(addr)
[11, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]
>>> grovepi.read_i2c_block(addr)
[11, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]
>>> grovepi.read_i2c_block(addr)
[11, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]
>>> grovepi.read_i2c_block(addr)
[11, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]
>>> grovepi.digitalRead(switch)
0
>>> grovepi.ultrasonicRead(ultrasonic_ranger)
0
[11, 0, 198, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]
198
>>> 

>>> grovepi.bus.write_i2c_block_data(5, 1, [3] + [0, 0, 0])
>>> grovepi.bus.read_i2c_block_data(5, 1)
[11, 2, 190, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]
>>> grovepi.bus.write_i2c_block_data(5, 1, [3] + [0, 0, 0])
>>> grovepi.read_i2c_byte(addr)
0
>>> grovepi.bus.read_i2c_block_data(5, 1)
[11, 2, 190, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]
>>>

 

CMD = 5, index =  4

CMD = 1, index =  4

DATA = 0, 2, 189

CMD = 1, index =  0

CMD = 1, index =  1

CMD = 1, index =  2

CMD = 1, index =  3

CMD = 1, index =  4

CMD = 1, index =  0

CMD = 1, index =  4

DATA = 0, 2, 189

CMD = 7, index =  4

DATA = 0, 0, 198

CMD = 7, index =  0

#
CMD = 3, index = 4

CMD = 3, index = 0

CMD = 3, index = 4

DATA = 0, 2, 190

CMD = 3, index = 0

#

 

竟然『 read_i2c_block 』不經『 read_byte() 』洗禮,不能觸動

void sendData()

機制。如是面對『問題』 issues 時,

Extraneous bus.read_byte commands? #169

In various functions in grovepi.py, there are what seem to me to be completely extraneous calls to read_byte, which can just be deleted. Or at least, deleting them doesn’t seem to break anything for me.

e.g. in analogRead it says bus.read_byte(address), then it does the actual read transaction with number = bus.read_i2c_block_data(address, 1). As far as I can tell the bus.read_byte is totally ignored, just does an extra i2c transaction for no reason and makes the code slightly slower.

Maybe I’m missing something and there is a reason for it, but as far as I can tell this is a bug?

 

When we were building the firmware initially, we found that read_block() didn’t work properly without calling the read_byte() first and this was the way we were able to make it work. It was a workaround then and we seem to have kept it till now.

 

是否足以做出『判斷』呢?到底現今還需要『 Dummy Read 』的嗎 ??或許樹莓派論壇上的一篇古老討論︰

I2C clock stretching

by stefanBA » Mon Aug 06, 2012 9:44 pm

Hello!

I’m trying to use I2C to connect an ATmega8A microcontroller as an I2C slave to the RasPi. However, I’m experiencing problems with the clock stretching feature of I2C. Whenever the microcontroller is not able to execute the I2C interrupt fast enough, it holds the clock line low to make the I2C master (RasPi) wait. This feature is supported by RasPi according to the BCM2835 ARM Peripherals data sheet (section 3.1, page 28).

However, when the I2C slave actually stretches the clock (e.g. by 4 us), the RasPi seems to ignore it and generates the next falling clock edge without any further delay (e.g. 1 us after the slave released the clock line to high). The sampling of the data line also seems to happen at the time the regular (i.e. un-stretched) positive edge of the clock would have occured.

I’m using raspbian OS and bootc’s kernel 3.2.23+. Although the I2C driver never detects a clock stretching timeout, I’ve tried to change the value of the clock stretch timeout register (CLKT) in the driver. I changed the default value of 0x40 to larger values (0x400, 0x4000) and also set it to zero to turn off clock stretch timeout detection. It did not change the behaviour.

Did anybody else experience a similar behaviour?

Does anybody know what I could be doing wrong?

Best regards,
Stefan

───

by Gert van Loo » Thu Aug 09, 2012 4:42 pm

Ok, here I am, one day late but I have most of the answers from the developers mouth.

There is a bug in the I2C master that it does not support clock stretching at arbitrary points.
It does support clock stretching during the ACK phase.

I hope this clarifies it’s behavior.

───

by Frank B » Mon Oct 08, 2012 6:34 pm
pico wrote:I’m trying to comminucate with an atmega328p (Arduino clone) as an i2c slave.

Did you see the errata in the atmega328p-datasheet ? There’s a silicon-bug in the mega328p too…(when acting as slave)

Two bugy i2c-silicons are talking to each other… :D

I would try with very low speeds to see if it works, and then slowly go higher.

Frank.
p.s. i would be interested in your results – i plan to use an arduino.

 ───

 

,說明了相關『問題』的複雜性!!也許這篇

Raspberry Pi I2C clock-stretching bug

Date: 2013-08-17

Summary

The Broadcomm BCM2835, which is used on the Raspberry Pi, has a serious bug in its I2C implementation, which can (a) prevent I2C communication with some devices and (b) lead to data corruption (both in read and write direction).

As a result, do not use I2C-devices which use clock-stretching directly with the Raspberry Pi directly or any other Broadcomm BCM2835-based device.

Fix:
None
Workarounds:
see below

………

 

文章固可以『釋疑』,卻是無法『解惑』的也耶??!!

當思活在『 buggy 』的世界裡,請隨時準備好『 work arround 』的哩!!!