User Tools

Site Tools


digix:tutorials:programming

Understanding the Arduino DUE and DigiX programming modes

As there are many problems around programming anc connectivity reported, here the first draft of an complete overview over all things, which are related to connectivity and programming.

At the very first point, we have a look at the SAM3X8E, which is the CPU used on both boards. That CPU has -in contrast to the AVR based Arduinos- an builtin boot-loader, which runs from EPROM and cannot be changed. This boot-loader is called SAM-BA (SAM Boot Assistent), which is running on all Atmel SAM CPUs. There is an special bit in the GPNVM (General Purpose Non Volatile Memory), telling the CPU, if it should start SAM-BA or from certain positions in the flash memory (depending on the SAM-CPU). When that bit (bit 1) is zero, the CPU boots SAM-BA from ROM. Therefore the CPU will boot SAM-BA after the ERASE-button is pressed, because GPNVM is erased too.

When the CPU starts SAM-BA, SAM-BA first checks is USB is connected and initialized by an host system (USB enumeration). If that is the case, it starts an listening daemon on USB. If that check is unsuccesful, it checks if there is any character received over serial1. When that is succesful, it starts the listening daemon on serial1. That loop runs endless, till one of those two listening daemons are up, or the cpu is switched off.

As SAM-BA is such a basic component for the whole SAM-family there are also many programs out there, to access an SAM CPU while in SAM-BA mode. There is the official SAM-BA software from Atmel, which is somewhat complicated, as they have built in support for all their stuff. So Arduino decided to use an reduced open source software, called BOSSA (Basic Open Source SAM-BA Application ; http://www.shumatech.com/web/products/bossa).

When SAM-BA runs on USB, the device is known to the host with the VID/PID: 03EB/6124. 03EB is the code from ATMEL, 6124 identifies SAM-BA. For that pair are many drivers out there, as a bunch of devices work with that ID for uploading their firmware. One of the well known devices is e.g. the LEGO NXT brick, which identifies itself with that ID, when in firmware update mode. Some of those drivers are compatible, because they are just derivates from the ATMEL package with changed names, others may cause some problems. The author of this text has no problems, flushing an DUE/DigiX with the LEGO NXT driver and vice versa.

The USB-Port of the SAM3X8E is called the DUE native port, and the only available option on the DigiX. As soon, as an Arduino-sketch is running on the DUE or DigiX, there is an function in CDC.cpp, which is triggering an reset, as soon, as the virtual COM-Port is opened and closed with 1200 baud. While the DUE or DigiX is running, the USB port is know to the host with the VID/PID 2341/003E. 2341 is Arduino, 003E identifies the native port.

This behaviour, that the DUE/DigiX changes the VID/PID depending on the software running on the device is the main cause for several problems. The change of the VID/PID looks for the operating system on the connected host, like an change of the connected device. It just looks like, that one device was disconnected and another device was connected to the same USB-connector.

The different operating systems (Windows, Linux, OS X) are reacting in a different way to this change: Windows causes the biggest troubles, as Windows assignes for each VID/PID an own device name (COMn) also depending on which USP port, that device is connected. That means, that the DUE or DigiX appears on one USB port for example as COM10, when in SAM-BA mode and COM11, when in Arduino mode. Connected to another port it appears perhaps as COM9 and COM13.

That makes it complicated for the IDE, to program the device. The configured COM-Port is that, which is used for triggering the reset. Immediately after that, all COM-Ports are scanned, if there is an COM-Port where the SAM-BA daemon is listening. That port is than used for uploading the script. After the reset, which follows the uploading process (and setting GPNVM bit 1 active), the device reappears as Arduino. That is the reason, why you hear under Windows so many USB beeps, when you are programming the board.

Linux is little bit different. Depending on the kernel the board appears as /dev/ttyACMn or /dev/ttyUSBn (older kernels). However the devicename does not necessarly change between those reconnects, as always the lowest free number is choosen, when a new device appears to the kernel. You can however overwrite that behaviour by assigning special devicenames with udev-rules depending on VID/PID and USB-port, if you like. However, you also cannot be shure, that e.g. the DUE/DigiX comes back as /dev/ttyACM2 aftewr reset, because if in the meantime /dev/ttyACM1 was disconnected, that deviceID will be used.

There is another restriction: As reset to SAM-BA is part of the running firmware/sketch it will only work, when the code is not stuck. When the code can't react on the speed-change of the virtual COM port, there is no reset, and you have to press ERASE/RESET yourself.

To overcome some of those problems, Arduino invented the programming port. As we remember, the SAM3X8E can be also programmed over the UART, if no USB enumeration happended before. To access this UART, the DUE has another 8-bit AVR CPU on board, an Atmega 16U2, which has as well an USB interface. If that interface is connected to an host, it appears with the VID/PID 2341/003D. 2341 is Arduino, 003D identifies the programming port. On the 16U2 there is an own firmware running, which acts like an proxy, between the virtual USB based COM port and the TTL-based UART of that chip, which is connected to the UART of the SAM3X8E.

When the virtual COM-Port on that USB connection is triggered with the 1200 baud connect/disconnect, the program running on the 16U2 triggers the physical erase/reset pins of the SAM3X8E, so the reset to SAM-BA happens also in situations, when the firmware is crashed. Furthermore the USB-connection between Host and 16U2 stays stable during all states of programming, as the reset appears on the serial-connection between the two UARTs.

As the DigiX doesn't have a programming port, accessing the second way is little bit more complicated. You can connect an simple USB to TTL-UART cable to the Serial ports of the DigiX, however you need to erase/reset the DigiX before by hand.

Another possibility, which will give you much more other possibilities, is using the JTAG-pins, which are much better available on the DigiX (Pins 110-113). See here the following project in the forum: http://digistump.com/board/index.php/topic,1275.0.html

digix/tutorials/programming.txt · Last modified: 2014/02/02 03:13 by digistump