bugAVR Downloader/UploaDEr - Bugs: bug #56584, Arduino double reset before...

 
 

You are not allowed to post comments on this tracker with your current authentication level.

bug #56584: Arduino double reset before programming (TIOCM_DTR clear/set swapped)

Submitted by:  spike <spike>
Submitted on:  Sun 07 Jul 2019 03:01:17 AM UTC  
 
Category:  None Severity:  3 - Normal
Priority:  5 - Normal Item Group:  None
Status:  None Privacy:  Public
Assigned to:  None Originator Name:  spike
Open/Closed:  Open Release:  SVN snapshot
Programmer hardware:  Device type:  arduino

Sun 07 Jul 2019 08:07:14 PM UTC, comment #1: 

Pretty much the same patch was already submitted (along with a really nice explanation) back in 2011: https://savannah.nongnu.org/patch/download.php?file_id=23541

Discussion here: https://savannah.nongnu.org/patch/?7559

This should also fix https://savannah.nongnu.org/patch/?9004 which I vaguely recall hitting at some point myself:

original submission:

> There seem to be some rare intermittent timeouts on 'regular' Arduinos (pro mini, don't recall exactly) on Windows

spike <spike>
Sun 07 Jul 2019 03:01:17 AM UTC, original submission:  

Whenever I'm using the Arduino programmer (i.e. -carduino) the device to be programmed is reset twice, roughly within 250ms before the DTR pin is actually pulled low and data is pushed out the usb port. I've made some screenshots to illustrate the point:

On Linux: https://gist.githubusercontent.com/spike77453/891a1131232420a0937964cc944c3b49/raw/c2c84f56ce8b2f0c35fafec6e495f1216250ae23/DTR_Linux.png
On Windows 7: https://gist.githubusercontent.com/spike77453/891a1131232420a0937964cc944c3b49/raw/c2c84f56ce8b2f0c35fafec6e495f1216250ae23/DTR_Win7.png

Looking at the source code (arduino.c) there's a comment referring to unloading the RESET capacitor (which e.g. on the Arduino UNO R3 would be C5), which would generate a falling edge on the RESET pin and therefore resetting the microcontroller so the bootloader can do its thing:

  /* Clear DTR and RTS to unload the RESET capacitor
   * (for example in Arduino) */
  serial_set_dtr_rts(&pgm->fd, 0);
  usleep(250*1000);
  /* Set DTR and RTS back to high */
  serial_set_dtr_rts(&pgm->fd, 1);
  usleep(50*1000);

Unfortunately, the code seems to do the opposite, i.e. setting DTR high instead of low. If one looks into 'ser_posix.c' for example, the relevant function is 'ser_set_dtr_rts'. Depending on the value of 'is_on' it sets or clears the TIOCM_DTR and TIOCM_RTS bits:

  if (is_on) {
    /* Set DTR and RTS */
    ctl |= (TIOCM_DTR | TIOCM_RTS);
  }
  else {
    /* Clear DTR and RTS */
    ctl &= ~(TIOCM_DTR | TIOCM_RTS);
  }

This seems to be the wrong way around: DTR (and RTS) are active low as far as I know, so setting the TIOCM_DTR bit actually pulls the output low. And it seems to be the reason why the DTR pin is high for roughly 250ms. I would have expected it to be low for about 250ms to unload the capacitor and generate the reset edge, as was probably intended by the author/commenter of the code above.
I've swapped it around (https://gist.githubusercontent.com/spike77453/891a1131232420a0937964cc944c3b49/raw/c2c84f56ce8b2f0c35fafec6e495f1216250ae23/AVRDude_ClearDTR.patch):

  serial_set_dtr_rts(&pgm->fd, 1);
  usleep(250*1000);
  /* Set DTR and RTS back to high */
  serial_set_dtr_rts(&pgm->fd, 0);

and now the DTR pin seems to behave properly:

On Linux after patch: https://gist.githubusercontent.com/spike77453/891a1131232420a0937964cc944c3b49/raw/c2c84f56ce8b2f0c35fafec6e495f1216250ae23/DTR_PatchedAVRDude_Linux.png
On Windows 7 after patch: https://gist.githubusercontent.com/spike77453/891a1131232420a0937964cc944c3b49/raw/c2c84f56ce8b2f0c35fafec6e495f1216250ae23/DTR_PatchedAVRDude_Win7.png

I've tested a couple of devices (m1284p, m32, m328p, t13) and avrdude still works as expected. Why there are two reset pulses in the first place when clearing TIOCM_DTR while it's idling high is beyond me. It seems pure coincidence to me but then again I know very little about the I/O subsystem.
The double reset is not actually a big deal. It seems to work just fine for a lot of people after all. There seem to be some rare intermittent timeouts on 'regular' Arduinos (pro mini, don't recall exactly) on Windows which might be just timing related.
But there are a few oddball systems that implement the Arduino 'auto-reset' circuit, i.e. a series capacitor and a diode across the reset pullup resistor, but use RTS instead of DTR. That works fine on Linux (it actually generates the exact same two resets) but fails on Windows. Apparently since there's a quirk in Windows's usbser.sys which doesn't generate an edge when the pin is already high on RTS (but does so on DTR). Also: Two resets are just not necessary

spike <spike>

 

No files currently attached

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -email is unavailable- added by spike (Submitted the item)
  •  

    Do you think this task is very important?
    If so, you can add your encouragement to it.
    This task has 0 encouragements so far.

    Only logged-in users can vote.

     

     

     

    No changes have been made to this item

    Back to the top


    Powered by Savane 3.5