Skip to content

ArduinoISP on the Leonardo does not work on windows #1182

Closed
arduino/ArduinoCore-avr
#56
@PeterVH

Description

@PeterVH

Versions:
Tried this on windows 7 SP1 and on XP SP2 (though on XP SP2, composite device stuff must be stripped to bring up leanardo all together).
The problem does not occur on linux.
Arduino 1.0.2

What steps will reproduce the problem?
From the IDE, perform following steps:

  1. Upload the ArduinoISP sample to the leonardo.
  2. Select ArduinoISP as programmer
  3. In the preferences select verbose output during uploads.
  4. Select an arbitrary board type. (no need to actually connect that target to the leonardo, we just want to see whether serial communictation between pc an leonardo works).
  5. Perform "burn bootloader".

Expected output: avrdude should send some bytes to the leonardo and the latter should send some bytes back (this should of coarse result in a failed upload because no target is attached)

Actual output: Leonardo sends nothing back, TX led never lights up. (RX led does)

Analysis: It turns out that on windows when avrdude opens the serial port, neither DTR nor RTS are asserted. Under these conditions, the leonardo does not send out data, see CDC.cpp:

size_t Serial_::write(uint8_t c)
{
        /* only try to send bytes if the high-level CDC connection itself 
         is open (not just the pipe) - the OS should set lineState when the port
         is opened and clear lineState when the port is closed.
         bytes sent before the user opens the connection or after
         the connection is closed are lost - just like with a UART. */

        // TODO - ZE - check behavior on different OSes and test what happens if an
        // open connection isn't broken cleanly (cable is yanked out, host dies
        // or locks up, or host virtual serial port hangs) */
        if (_usbLineInfo.lineState > 0) {
                int r = USB_Send(CDC_TX,&c,1);
                if (r > 0) {
                        return r;
                } else {
                        setWriteError();
                        return 0;
                }
        }
        setWriteError();
        return 0;
}

The comment in the code makes sense but unfortunately windows/avrdude do not set RTS/DTR. Note that this does work on classic arduino's: on the duemilanove the ftdi chip apparently just forwards the data received from its uart on the usb. On the uno, the (LUFA) code in the atmega8u4, does not check RTS/DTR, but instead it checks whether the device is in the usb CONFIGURED state and whether the baudrate has been set (the latter is a bit odd, but maybe it is because of this problem). Myself I tried with no checks at all ( if ( 1 /_usbLineInfo.lineState > 0/) ). It works for ArduinoISP, but this may have side effects (hanging other sketches if serial port is not opened?).

A work around has been proposed to use ArduinoISP with the arduino protocol instead of the stk500v1 protocol. This works because the the arduino protocol's autoreset code briefly drops RTS/DTR and sets it back high. After this, the leonardo can send out data. (but this is making use of a side effect)

Not 100% sure what the best solution is. But I think that (unless there is a danger to lock up things), we should not prevent the leonardo from sending out data. The perception of the leonardo would benefit from this. (In the forum it is often heard "I gave up and bought an Uno and it worked out of the box". It is a pity the leonardo is great for ArduinoISP)

See also:
http://petervanhoyweghen.wordpress.com/2012/09/16/arduinoisp-on-the-leonardo/
http://arduino.cc/forum/index.php/topic,108270.msg1013258.html#msg1013258

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions