BusPirate / Bus_Pirate

Community driven firmware and hardware for Bus Pirate version 3 and 4
633 stars 131 forks source link

bp_delay_us is not accurate #23

Open agatti opened 8 years ago

agatti commented 8 years ago

A more precise way to perform delays should be implemented as this might mess with timing-sensitive protocols such as 1-Wire. Unfortunately I bricked my v4 and I'm away for a week so I can't really work on this at the moment, but before the bricking I made 1-Wire work more reliably by changing the amount of time being waited, and my logic analyser all of a sudden would detect the protocol state changes.

Something that on paper should be more accurate would be this (assuming the number of milliseconds is in W0 and that it's running on a v4 board, which means it can execute 16 instructions each microsecond):

  sub #1, w0    /*  1 / 16 */ /* Compensate for first batch of NOPs */
  nop           /*  2 / 16 */
  nop           /*  3 / 16 */
  nop           /*  4 / 16 */
  nop           /*  5 / 16 */
  nop           /*  6 / 16 */
  nop           /*  7 / 16 */
  nop           /*  8 / 16 */
  nop           /*  9 / 16 */
  nop           /* 10 / 16 */
  nop           /* 11 / 16 */
  nop           /* 12 / 16 */
  nop           /* 13 / 16 */
  nop           /* 14 / 16 */
  nop           /* 15 / 16 */
  nop           /* 16 / 16 */

.loop: 

  nop           /*  1 / 16 */
  nop           /*  2 / 16 */
  nop           /*  3 / 16 */
  nop           /*  4 / 16 */
  nop           /*  5 / 16 */
  nop           /*  6 / 16 */
  nop           /*  7 / 16 */
  nop           /*  8 / 16 */
  nop           /*  9 / 16 */
  nop           /* 10 / 16 */
  nop           /* 11 / 16 */
  nop           /* 12 / 16 */
  nop           /* 13 / 16 */

  sub #1, w0    /* 14 / 16 */
  bra z, .end   /* 15 / 16 */
  bra .loop     /* 16 / 16 */

.end:

  nop           /* 16 / 16 */ /* Align to 16 cycles for when W0 is 0 */

However I can't really try this out at the moment, if somebody with a logic analyser or a PIC simulator or a PicKit and a spare board wants to get wild with this, that'd be awesome!

agatti commented 6 years ago

I added @ChristopherSamSoon's delay code to the main branch - it is currently enabled by default, but can be switched off by undefining BP_USE_HARDWARE_DELAY_TIMER in configuration.h.

USBEprom commented 6 years ago

I just built new firmwares SAFE and UNSAFE starting from this repository (https://github.com/BusPirate/Bus_Pirate/archive/master.zip) where you have merged the code provided by Christopher Sam Soon (https://github.com/ChristopherSamSoon/Bus_Pirate) and for me it works with Bus Pirate v3. Thank you sir and thanks to Christopher Sam Soon too!:

http://dangerousprototypes.com/forum/viewtopic.php?f=28&t=8498&start=120

ChristopherSamSoon commented 6 years ago

I just built new firmwares SAFE and UNSAFE starting from this repository (https://github.com/BusPirate/Bus_Pirate/archive/master.zip) where you have merged the code provided by Christopher Sam Soon (https://github.com/ChristopherSamSoon/Bus_Pirate) and for me it works with Bus Pirate v3. Thank you sir and thanks to Christopher Sam Soon too!:

http://dangerousprototypes.com/forum/viewtopic.php?f=28&t=8498&start=120

No problem, I am glad to contribute to the community.

Lest us know of your results for 1-WIRE together with the iButton. I tried to lookout for my Arduino but could not get hold on it yet.

USBEprom commented 6 years ago

@ChristopherSamSoon

Surely, I am already at work on that. Thanks again sir.

USBEprom commented 6 years ago

Ok, in the end I managed to test the functioning of the 1-WIRE protocol on the Pirate v3 Bus using the firmwares that I got from the current repository and therefore updated, concluding that everything works as expected. For the tests I have followed the suggestion of agatti and I used an Arduino MEGA 2560 card borrowed from the usual friend of mine where was running a 1-WIRE SLAVE library. Very sadly I have not in any way been able to test the 1-WIRE protocol with a real device, because despite all the attempts I made I could not read the iButton DS1990A-F5 I own. I tried hard, I also purchased a real iButton socket probe reader provided with suppressor but no joy. Maybe my DS1990A-F5 has something bad, even if it is weird because it is fully working using other than Bus Pirate, I do not know why it does not work with my Bus Pirate v3 which has the 2000ohm R20 pull-up resistor. I would have liked to verify the 1-WIRE protocol with a real and not simulated device but in the end I had to resign myself to perform tests on devices emulated with Arduino. The library that I used is here:

https://github.com/orgua/OneWireHub

It is the only one I could find that works with the Arduino MEGA 2560 board. Among the other supported devices, the above library also manages the families DS1990, DS1990A and DS2401, so in the end, although only in emulation mode, I could virtually test the 1-WIRE protocol with the iButton DS1990A, because with the real one I own I have not succeeded.

ds1990-ds1990a-ds2401 ds18b20 arduino-1wire_slave ds2431_arduino-1wire_slave

For what I could see everything works correctly, even if I noticed a weirdness and could in my opinion be introduced some improvements.

The weirdness I noticed is that while performing MACRO (1-50) which show the 8-byte ROM identifier of the device placed on the specific address chose, then the resulting final message does not match to the device on which the query was made.

So for instance while querying for device 3 on the 1-WIRE bus by performing MACRO (3):

1-WIRE>(3)

Then the response show the device numbered as n+1, or 4 rather than 3 as actually it should be in this case:

ADDRESS MACRO 4: 0x81 0x00 0xA0 0x90 0x19 0xDA 0x00 0x03

wierd

I guess this behavior could be related to the fact that the numbering does not start from 0 because that is the purpose of MACRO (0) that on the Bus Pirate show the list of available macros, do not the 8-byte ROM of the device number 0 on the 1-WIRE bus, though I can very well be wrong.

The possible improvement that I thought is tied with the item Overdrive (~160kps) into the menu as available choice. I would have liked to check this too but sadly I could not because if I have not misunderstood to enable Overdrive (~160kps) on the 1-WIRE devices that allow for it, not all 1-WIRE slaves support Overdrive (~160kps), it is need to send 0x69 (Overdrive Match ROM command) in normal speed followed by the 8-byte ROM identifier in overdrive speed or by sending 0x3c (Overdrive Skip ROM command) in normal speed. This one immediately puts all overdrive capable slaves on the bus into overdrive mode. Once a slave is in overdrive mode, all subsequent communication must take place at overdrive speed. (http://forum.arduino.cc/index.php?topic=201776.msg1486950#msg1486950) The Bus Pirate provide Overdrive (~160kps) support (https://github.com/BusPirate/Bus_Pirate/commit/07c8be981fac9cfc633195c55959ca4c968ba4e1) but actually it can not use it because in order to do so would need to go from Standard (~16.3kbps) to Overdrive (~160kps) and the other way around, keeping active pull-ups and power supply, which is not currently allowed. In fact, once one of the two items has been set, Standard (~16.3kbps) or Overdrive (~160kps), to change it it is need to return to the menu with the "m" command, thus immediately making the power supply and the pull-up resistors are deactivated, therefore there is in no way possible to initialize the slave devices that support it in the Overdrive mode (~160kps). Even using externally powered external pull-up resistors it does not improve the thing, especially when working with emulated 1-WIRE slave devices, as this could result in the risk of damaging the Arduino board and or the Bus Pirate itself, although I believe that this last should have more chance to survive than the Arduino board, however I would like to avoid experiments in that direction. In my opinion the correct and most elegant solution would be to be able to switch from Standard (~16.3kbps) to Overdrive (~160kps) and the other way around without contextually deactivating power supply and pull-up resistors on the Bus Pirate side. I do not know if this is possible or not, even if it can be recommended, it is only a thought of mine that I want to share.

USBEprom commented 6 years ago

Ok, in the end I managed to test Overdrive (~160kps) on 1-WIRE protocol with the Bus Pirate v3 despite as it is now Bus Pirate v3 can not natively switch from standard to overdrive speed without turning off power supply and pull-up resistors so that the 1-WIRE slave device is indesirably deselected (#117 and https://github.com/BusPirate/Bus_Pirate/commit/07c8be981fac9cfc633195c55959ca4c968ba4e1). In order to reach the goal I had to manually operate 3 switches and add 2 diodes type 1N4148 and one 2,2kohm resistor as in the attached picture. 1-wire _Since the above diagram is used to execute the I2C_ARDUINO_TEST procedure provided by agatti I have also kept it for the OneWireHub-2.2.1 library by simply setting to 20 the 1-WIRE pin (pinonewire {20};) that is among the valid interrupt pins for the Arduino MEGA 2560 board. In this way I can do testing on both I2C and 1-WIRE protocols with no need to change connections and by only switch from an Arduino sketch to another. This is why there are the SCL and the SDA names on the diagram although I am talking about 1-WIRE protocol.

The target 1-WIRE slave was a DS2506 64Kb Add-Only Memory simulated by an Arduino MEGA 2560 running the OneWireHub-2.2.1 library (https://github.com/orgua/OneWireHub) where in "OneWireHub_config.h" the overdrive support for the slaves was enabled #define OVERDRIVE_ENABLE 1 // support overdrive for the slaves. In order to operate safety for Bus Pirate v3 and Arduino MEGA 2560 I did as follow. First. With the connections shown above I have set up:

a) SWITCH 3 = OPEN

b) SWITCH 2 = CLOSE

c) SWITCH 1 = CLOSE

Once did so I started the Bus Pirate v3 for 1-WIRE protocol and Standard (~16.3kbps) speed, ending turning on the power supplies with command "W" and pull-up resistors with command "P". After this I queried the Arduino MEGA 2560 with macro (51) and (240) in order to be sure all was right. Having verified this, I gave the command {0x3c r: 8 from the Bus Pirate v3. As explained here in http://forum.arduino.cc/index.php?topic=201776.msg1486950#msg1486950, 0x3c (Overdrive Skip ROM command) immediately puts all overdrive capable slaves on the bus into overdrive mode. Once a slave is in overdrive mode, all subsequent communication must take place at overdrive speed, so I did this:

a) SWITCH 2 = OPEN

b) SWITCH 3 = CLOSE

c) SWITCH 1 = OPEN

Then I reset the Bus Pirate v3 with command "#" and restarted it for 1-WIRE protocol this time choosing the Overdrive (~160kps) speed and ending turning on the power supplies with command "W" and pull-up resistors with command "P". At this point I moved switches as follow:

a) SWITCH 1 = CLOSE

b) SWITCH 3 = OPEN

c) SWITCH 2 = CLOSE

And I started to query the simulated DS2506 from the Bus Pirate v3. Bingo!, that did the trick and everything worked as expected! So I could send commands and capture and decode the data traffic on the bus with the logic analyzer. In this way I was able to measure about ~90kHz for the clock speed of the data traffic. 1-wire_overdrive The whole thing was 100% functioning even because I had to set the decoder of the logic analyzer to "Overdrive" because otherwise I could not decode anything. For what I can see all is good and nothing is wrong with 1-WIRE protocol on Bus Pirate v3 with firmware v7.x. Very, very well! All this shows that the recently added and remodeled code works well without introducing any problems whatsoever.

@ChristopherSamSoon

Many, many thanks sir!

ChristopherSamSoon commented 6 years ago

@USBEprom

Thank you for providing the detailed test results for 1Wire mode.

Let us aim to close this issue by end 2018!

Best

Christopher

USBEprom commented 6 years ago

@ChristopherSamSoon

That would be really great, sir!

USBEprom commented 6 years ago

@ ALL

Maybe I am wrong, but it seems to me that also 1-WIRE protocol uses the "blocking" way described here https://github.com/BusPirate/Bus_Pirate/issues/18, especially when the clock speed is high as in the case of Overdrive (~160kps), or rather the whole thing is more evident with high speeds. This time the usual friend of mine took a few screenshots while running ols-0.9.8 from jawi (J.W. Janssen) with the Open Bench Logic Sniffer. obls_overdrive Open Bench Logic Sniffer has confirmed the results obtained with the previous logic analyzer. The client software provided by jawi is much more powerful, eclectic and versatile than that for the other logic analyzer and allows you to go into details otherwise difficult to guess

ChristopherSamSoon commented 6 years ago

@ ALL

Maybe I am wrong, but it seems to me that also 1-WIRE protocol uses the "blocking" way described here #18, especially when the clock speed is high as in the case of Overdrive (~160kps), or rather the whole thing is more evident with high speeds. This time the usual friend of mine took a few screenshots while running ols-0.9.8 from jawi (J.W. Janssen) with the Open Bench Logic Sniffer. obls_overdrive Open Bench Logic Sniffer has confirmed the results obtained with the previous logic analyzer. The client software provided by jawi is much more powerful, eclectic and versatile than that for the other logic analyzer and allows you to go into details otherwise difficult to guess

You may be correct. I would not be surprised if the root-cause of this behaviour is the same as #18. Anyways, this problem is not because of bp_delay_us() (This issue here), but because of "blocking" printout to UART during 1WIRE transmission (possibly other protocols as well)

AreYouLoco commented 3 years ago

Is there anything that can be done with this issue? I am trying to use flashrom with 7.1 community firmware and I bumped on this bug.