─── 見於《《派生》 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
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
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
───
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.
───
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…
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 』的哩!!!
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 withnumber = 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?