Description
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:
- Upload the ArduinoISP sample to the leonardo.
- Select ArduinoISP as programmer
- In the preferences select verbose output during uploads.
- 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).
- 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