[[firmware]]
== icE1usb Firmware

The icE1usb _firmware_ is a small amount of bare-iron software running
on the picoRISCV soft-core of the _gateware_.

It mainly consists of drivers for the no2e1 E1 Framer IP core and the
no2usb USB Device IP core which are part of the gateware described in
<<gateware>>.

=== Firmware Upgrade (DFU)

icE1usb contains support for the USB DFU (Device Firmware Upgrade)
standard.

As such, you can use any USB DFU compliant utility to upgrade the
firmware of the icE1usb device.

DFU mode can be entered in two ways:

1. by performing a DFU detach from the normal application firmware
   (obviously that requires a [still] working firmware present on the
   device).  To do so, please use `dfu-util -e`

2. by pushing the push-button (see <<hw-pushbutton>>) during power-up.
   Simply disconnect the USB cable, then push that button and keep it
   pushed while re-attaching the USB cable.

The icE1usb boot loader enumerates as VID:PID `1d50:6144`, while the
normal application firmware enumerates as `1d50:6145`,

You can for example use `lsusb` to check the VID:PID:

----
$ lsusb -d 1d50:
Bus 001 Device 042: ID 1d50:6145<1> OpenMoko, Inc. icE1usb
$ sudo dfu-util -d 1d50:6145 -e <2>
...
$ lsusb -d 1d50:
Bus 001 Device 043: ID 1d50:6144<3> OpenMoko, Inc. icE1usb (DFU)
----
<1> initially the device is in normal runtime mode
<2> we use `dfu-util -e` to switch to DFU mode
<3> we can see, the device is now in DFU mode

==== Obtaining firmware upgrades

The latest firmware can be found at
https://ftp.osmocom.org/binaries/icE1usb/firmware/latest/
a backlog of earlier builds can be found at
https://ftp.osmocom.org/binaries/icE1usb/firmware/all/

The latest gateware can currently only be found at the personal developer
directory of tnt at https://people.osmocom.org/tnt/ice1usb/icE1usb-202010-bd399e96.bin
A more official download location for the gateware will be provided shortly.

==== Upgrading the FPGA gateware

Gateware files are called `icE1usb-*.bin`. (without 'fw' in the name)

The gateware can be upgraded by accessing the DFU _altsetting 0_ using `dfu-util` *`-a 0`*

Assuming you already are in DFU mode, you would typically use a command
like `dfu-util -d 1d50:6144 -a 0 -D icE1usb-202010-bd3999e96.bin -R` to perform the upgrade.

NOTE: The `-R` will switch the device back to runtime mode after the
upgrade.   If you want to upgrade the firmware in the same session, skip
the `-R` in the above command.

==== Upgrading the picoRISCV firmware

Firmware files are called `icE1usb-fw*.bin`.

The firmware can be upgraded by accessing the DFU _altsetting 1_ using `dfu-util` *`-a 1`*

Assuming you already are in DFU mode, you would typically use a command
like `dfu-util -d 1d50:6144 -a 1 -D fw_app-202011-4d9a04e2.bin -R` to perform the upgrade.

.Typical output during upgrade of the firmware
----
$ sudo dfu-util -d 1d50:6144 -a 1 -D ./fw_app.bin -R
dfu-util 0.9

Copyright 2005-2009 Weston Schmidt, Harald Welte and OpenMoko Inc.
Copyright 2010-2016 Tormod Volden and Stefan Schmidt
This program is Free Software and has ABSOLUTELY NO WARRANTY
Please report bugs to http://sourceforge.net/p/dfu-util/tickets/

dfu-util: Invalid DFU suffix signature
dfu-util: A valid DFU suffix will be required in a future dfu-util release!!!
Opening DFU capable USB device...
ID 1d50:6144
Run-time device DFU version 0101
Claiming USB DFU Interface...
Setting Alternate Setting #1 ...
Determining device status: state = dfuIDLE, status = 0
dfuIDLE, continuing
DFU mode device DFU version 0101
Device returned transfer size 4096
Copying data from PC to DFU device
Download        [=========================] 100%        11256 bytes
Download done.
state(2) = dfuIDLE, status(0) = No error condition is present
Done!
Resetting USB to switch back to runtime mode
----

As the `-R` option was used, the device will reset and re-enumerate in
the newly programmed firmware.

You can verify this as follows:

----
$ lsusb -d 1d50:
Bus 001 Device 042: ID 1d50:6145 OpenMoko, Inc. icE1usb
----

or alternatively:

----
$ dfu-util -l -d 1d50:
dfu-util 0.9

Copyright 2005-2009 Weston Schmidt, Harald Welte and OpenMoko Inc.
Copyright 2010-2016 Tormod Volden and Stefan Schmidt
This program is Free Software and has ABSOLUTELY NO WARRANTY
Please report bugs to http://sourceforge.net/p/dfu-util/tickets/

Found Runtime: [1d50:6145] ver=0003, devnum=44, cfg=1, intf=1, path="1-2", alt=0, name="DFU runtime", serial="dc697407e7881531"
----


=== Use of the E1 Interface LEDs

Each E1 interface has two LEDs integrated into the RJ45 connector. They
are (starting to get) used by the firmware to indicate status
information to the user.

[options="header"]
|===
| Green LED | Yellow LED | Meaning
| Off       | Off        | Loss of Signal
| Blink     | Off        | Loss of Framing
| Blink     | On         | Loss of Framing, Receiving AIS
| On        | Off        | Aligned
| On        | On         | Aligned, Receiving RAI
|===

=== Use of the Multi-Color RGB LED

The led near the USB port is used to indicate general device status.

A blinking blue led indicates that the device is in bootloader mode.

A slow breathing indicates that at least one of the two port is
active, communicating over USB. The color of the led then indicates
the E1 link status. If all links are without issues, it will be
green, but if at least one of the enabled port has an issue,
it will show up as red.

=== Firmware <-> USB Host Interface

The icE1usb firmware provides a USB 1.1 full-speed (FS) device with

* one configuration
* 5 interfaces
** E1 port 0
** E1 port 1
** CDC-ACM (control + data)
** DFU (device firmware upgrade)

The interfaces have self-explanatory string descriptors like

----
      iInterface              6 E1 port 0
      iInterface              8 E1 port 1
      iInterface              9 GPS (CDC control)
      iInterface             10 GPS (CDC data)
      iInterface             11 DFU runtime
----

==== E1 ports

There are two physical E1 ports in the icE1usb.  Each is exposed via its own USB _interface_.

Each port (USB _interface_) contains two _altsettings_:

* one altsetting with no data endpoints (E1 disabled, this is the default)
* one altsetting with isochronous IN/OUT endpoints (E1 enabled)

In order to activate one E1 port, the driver must perform a USB standard
request to activate the _enabled_ altsetting.

NOTE:: Please note that on many XHCI host controllers there seem to be
implementation flaws in the XHCI host controller firmware preventing the
activation of both icE1usb ports simultaneously.  The XHCI controller
firmware erroneously claims that there is insufficient bus bandwidth.
However, the same icE1usb hardware/firmware works perfectly fine with
OHCI, UHCI and EHCI host controllers.  See
https://osmocom.org/projects/e1-t1-adapter/wiki/Isochronous_USB_Issues for a user-maintained list of USB hosts / controllers and whether or not they work with two E1 ports.

As most modern [PC] hardware has XHCI host controllers, you need to
choose your hardware carefully if concurrent operation of both icE1usb
ports is required in your application.

==== CDC-ACM with GPS NMEA

There's a CDC-ACM (virtual com port) interface available in the icE1usb.
This will be supported by the standard `cdc_acm` driver of your
operating system, and will expose a `/dev/ttyACMx` device on Linux.

The port provides read-only access to the GPS receiver on-board the
icE1usb.  You can use this to

* determine the GPS fix (and hence 1PPS frequency reference)
  availability
* obtain the GPS position of the device

NOTE:: Write access to the GPS receiver is not permitted as the icE1usb
firmware needs to control the GPS receiver for frequency reference
purposes.

==== DFU (Device Firmware Upgrade)

There's a DFU interface available in order to update the icE1usb
gateware and firmware.  For more information, see [[firmware]] above.
