Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pinoccio resets when unplugging USB #5

Open
matthijskooijman opened this issue Sep 19, 2014 · 15 comments
Open

Pinoccio resets when unplugging USB #5

matthijskooijman opened this issue Sep 19, 2014 · 15 comments

Comments

@matthijskooijman
Copy link
Collaborator

I don't think this is intentional and we should probably try to fix this in a future revision.

Initially, I thought the transistor that switches from USB power to battery power wasn't switching fast enough, causing an interruption in the power supply and a brown-out reset.

However, upon closer inspection, it seems that this is because when the 16u2 is powered down, the DTR pin (PD7 on the 16u2, which was idling at high) is disconnected. This causes the voltage on the 16u2 side of capacitor on the reset line (C19) to switch from high (through DTR) to low (through pulldown R17). Since the capacitor is discharged at that time, the RESET pin on the 256rfr is also pulled low. This lasts until the capacitor is charged, through the internal pullup on the RESET pin of the 256rfr2 and the RESET pin is high again. This is essentially the same thing that happens when DTR is made low when the serial port is opened.

@amcjen
Copy link
Member

amcjen commented Sep 19, 2014

I believe this functionality is required in order for the Arduino IDE/avrdude to be able to successfully flash the 256RFR2, no? If we disabled this, wouldn't reflashing the board then require an external reset button to be pressed at precisely the correct time?

@matthijskooijman
Copy link
Collaborator Author

For flashing, you need a reset when the serial port is opened (rather, when DTR is asseted). This issue describes a reset when USB is unplugged.

@matthijskooijman
Copy link
Collaborator Author

Note that both things are caused by the same capacitor, so we should find some other setup that works better. For other Arduinos, there is no battery so this issue never shows up there.

@matthijskooijman
Copy link
Collaborator Author

An easy fix for this is probably to just remove the capacitor altogether. Instead of tying DTR directly to the 16u2 output, just generate a spike on the output in software when DTR is asserted (e.g. in the 16u2 firmware, make the output low for a short while and high again). This saves components and makes things easer. This was originally suggested on the arduino developers list

@amcjen
Copy link
Member

amcjen commented Nov 8, 2014

If I'm understanding this correctly, we'd want to make C19 to a 0 ohm resistor, R17 a do-not-include (DNI), and a usb-to-serial firmware change for the 16U2 to handle the reset pin when DTR occurs?

Also, C19 should probably have a diode instead, to protect the 16U2 pin from the reset pin state change feeding into an unpowered 16U2.

@matthijskooijman
Copy link
Collaborator Author

I think that C19 should become a (small?) resistor, in order to prevent short circuits (I imagine the 16u2 pulls the pin high during normal operation - we don't want to short-circuit when someone manually resets by pulling the reset pin low). Looking more closely, I see R6 is between the actual 256rfr2 reset pin and the reset pin in the header, so that already achieves this. However, that resistor would prevent a manual reset from working when the 16u2 is driving high, so perhaps the 16u2 should not drive high, just switch between high-impedance (for normal operation) and drive low (for reset).

Good call on the 16u2 powerdown thing, though I think a diode will not work here - that will prevent the 16u2 from pulling the reset low for resetting the 256rfr2 (unless you point the diode at the 16u2, but then it doesn't serve any purpose). I guess something else should be inserted here, then, just like for the TX/RX lines? Essentially the current cap is providing protection from the 16u2 being powered down by acting as a high-pass...

@eeintech
Copy link

What if R17 is moved from pull-down to pull-up to VCC?

Essentially that would sandwich the capacitor between VCC on 16u2 side (through R17) and VCC on the 256rfr2 side (internal pull-up to VCC) and should prevent reset when USB power is unplugged (16u2 DTR line goes from high to tri-state, causing no change in the capacitor C19).

Now when 16u2 is unpowered, no current feed into 16u2 still thanks to the cap. And when the 16u2 generates a pulse (tri-state to low), it will still serve the same function as the RESET line goes from high to low on the 256rfr2 side for a short instant (until C19 is charged back up to VCC).

The only concern left is that C19 voltage would rise back up to 2xVCC once the 16u2 DTR pin goes back to tri-state (pulled-up to VCC through R17). To protect against over-voltage, a diode to VCC on the RESET line should do it. It could also protect from repetitive driving of the RESET_EN line to 5V.
BUT that's an extra part to the BoM...

@matthijskooijman
Copy link
Collaborator Author

It seemed elegant to get rid of the cap, but if that pulls in a dozen other components, it might not be worth it.

As for your suggestion - current will still leak through R17 into the 16u2. It's not much, but if it offsets our 12uA sleep current by a few more uA, that would be a pity :-)

As for the 2xVcc voltage - that is already present now, see #6. The extra diode needed is another reason to get rid of the cap ;-p

@eeintech
Copy link

I don't know what simpler circuit can replace the cap but I understand the leakage concern.

Throwing out a new idea: replace pull-down R17 with a 1uF cap (or slightly higher value).

Basically this cap would hold the voltage on C19 16u2 side long enough so that C19 does not see a drastic change in the voltage across its terminal and prevent the RESET line to go under 0.3*VCC.
When the 16u2 is powered-down: no leakage.
When the 16u2 pull the DTR line low, 1uF cap will discharge into DTR and cause the DTR voltage to go low causing RESET line to go low.

Good precaution for the diode :)

@amcjen
Copy link
Member

amcjen commented Dec 11, 2014

@cisco25 @matthijskooijman Revisiting all the hardware bugs today, with my goal of getting solid updates on what changes to be made for the next run of boards we're about to make.

What approach do we want to land on? François's last comment above looks to be a good approach. I don't like not having the diode on there, but honestly don't think we have the room for one.

So change R17 to a 1µF or 2.2µF cap? Leave C19 at 0.1µF and R6 as a 470Ω?

@amcjen
Copy link
Member

amcjen commented Dec 11, 2014

N/m, added the diode per the Uno rev3 schematic found here: http://arduino.cc/en/uploads/Main/Arduino_Uno_Rev3-schematic.pdf

@eeintech
Copy link

I would leave C19 and R6 as is.

I've made some quick spice simulations of USB power toggle and reset condition on the DTR line:
http://tinyurl.com/ntwuptu

It seems like 1uF capacitor should work just fine for all conditions (assuming 2.5mA current discharge during reset and weak 100k tri-state pull-down resistor during USB power toggle).

@eeintech
Copy link

I added scope capture of the RESET line after replacing R17 with a 1uF capacitor on one of my scouts: http://tinyurl.com/ntwuptu
It looks very good overall and also works as intended: no more reset upon unplugging the USB and sketches are loading very well (reset is effective).

You can note also that the RESET line does not exceed 3.8V with that change.
I would consider dropping the 10k and diode to VCC to just use that cap instead.

@matthijskooijman
Copy link
Collaborator Author

@cisco25 Ah, now I understand what you were trying to do. Somehow I thought you were trying to solve the voltage spike issue, but that's a different ticket :-)

However, the new plan is to keep the 16u2 powered on when USB is unplugged, which allows doing the reset pulse timing in software as I proposed before. This only needs two resistors - a 10k from 16u2 to the rfr2 RESET and the current 470R from RESET to the RST pin on the header. As an added advantage, this allows disabling autoreset by just connecting RST to 3V3 and it should make it easier to bypass the 16u2 with e.g. an FTDI breakout.

@cisco25, how does this sound?

@eeintech
Copy link

Yeah, that'd work too! 👍

penguin359 pushed a commit to HexRC/pinoccio-hardware-reference that referenced this issue Mar 25, 2015
The protocol is now more explicit about how to handle errors. In
particular:
 - When a slave sends a nack, it should be followed by another byte
   containing an error code.
 - The meaning of this error code can change depending on the current
   command.
 - After the error code, the slave drops off the bus and the master ends
   the transaction.
 - Trying to change a read-only EEPROM byte will now return a nack.

References Pinoccio#5
penguin359 pushed a commit to HexRC/pinoccio-hardware-reference that referenced this issue Mar 25, 2015
This commit updates to the recent changes made to the protocol spec:
 - Changes the behaviour after a NACK to always send an error code, ack
   it and then drop off the bus
 - Returns an error when an invalid EEPROM address was given
 - Returns an error when reading or writing ends up beyond the end of
   the EEPROM (implemented in slightly different way than specified,
   spec will be updated)
 - Skips the EEPROM write when the value would remain unchanged
 - Return an error when a read-only byte would be changed
 - Update the test sketch to test for all of the above

References Pinoccio#5
penguin359 pushed a commit to HexRC/pinoccio-hardware-reference that referenced this issue Mar 25, 2015
penguin359 pushed a commit to HexRC/pinoccio-hardware-reference that referenced this issue Mar 25, 2015
Previously, the last succesful byte would be nacked, but this was
confusing. The implementation already used the alternative, to send a
dummy byte after the last byte which is then acked. This is slightly
more complicated to implement, but makes a lot more sense.

Additionally, there is no longer a separate error code for end of
EEPROM, just one "Invalid address" error code should be enough.

Closes Pinoccio#5
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants