In current implementations, we have one interface (with it's own
separate set of USB end-points) per slot. However, the USB protocol
already includes a slot-number in the header to be able to remove that
restriction in future versions.
Also, if the USB protocol is used remotely over a network, then we could
multiplex differnt slots from different USB interfaces into one stream
on the network side.
In order to prepare the data structures in the host program, let's
introduce that logical split there, too. Might seem a bit like
overkill, but I don't want to rewrite all code later...
We want to be able to use some code irrespective of the application
(emulation, tracing, ...), so let's split the transport struct out of
the cardem_instance.
The current protocol was card-emulation specific. The new protocol is
generic/flexible enough to accommodate both tracing and card emulation,
as well as modem control and other future extensions.
We now generalize the USB communiction and abandon the 'req_ctx'
structure inherited from openpcd. Instead we use the libosmocore 'msgb'
structure to handle incoming and outgoing USB tranfers. We also use
linuxlist-based msgb-queues for each endpoint.
This was introduced for interoperability with operating systems that
might prefer such setup (I heard that Windows prefers this about a
decade ago, but I don't have any personal experience with it).
However, using different VID/PID between DFU and RT breaks usability of
dfu-util, and I really think this matters much more to our users and
developers.
the default boot state should be to use the local SIM, until the user
changes it (currently only possible via entering '!' or '@' on the
serial console). The code so far had this completely inverted.
We cannoy simply use the DFU runtime descriptor of the DFU mode, but we
have to use the descriptor of the specific currently-selected runtime
configuration. Let's iterate over the descriptors of a configuration
and find the DFU runtime descriptor in it.
At power-up we need to initialize g_dfu once, to ensure a consistent
state. Afterwards we want to keep it across (software) reset, but on
power-up the memory would otherwise be filled with random data, causing
issues with detection of DFU/Runtime switching.
Rather than using the first available interface on the first available
device, we now have a "simtrace2-list" program that lists all compatible
interfaces on all configurations of all devices on the system
When we want to run multiple instances of the card-emulator (e.g. for
multi-modem/multi-card versions of the hardware), the code shouldn't be
using any global variables but have them per-instance.
This way, host code can dynamically detect which interface supports
which functionality.
The related #defines should be moved to a header file that's shared with
the host application code.
Actually, at device level we want to specify 0, so we can select
individual Class/Subclass values at Interface values.
Table 9-8 of the USB2 Specification is quite clear about this.
This software is supposed to support a SIMTRACE1 with SAM#, as well
ast the OWHW and QMOD hardware. Let's compare the GPIO/Pin assignments
of the SAM3 in one shared spreadsheet.
When initializing the TC blocks, let's only configure the GPIO pins TCLK
and TIOB, and not the unused TIOA pin. That pin is actually used for
(separate) different functions in both qmod and owhw.
The port mapping is now as follows:
* port 1: ST12
* port 2: modem 1
* port 3: modem 2
* port 4: ST34
* port 5: modem 3
* port 6: modem 4
* port 7: daisy-chaining port
Using the USBDFU_OverrideEnterDFU() function, a board/application can
define extra conditions when the system should boot in DFU mode, even if
it was not explicitly switched to DFU mode from the application.
The app/dfu/main.c uses this mechanism to boot into DFU mode if the
stack + reset vector addresses are not plausible (i.e. some random junk
appears to be flashed in the application partition) or if the user
places a jumper accross the RxD+TxD lines of the debug UART. The idea
is that the system can be recovered by placing this jumper and then
re-installing the application from DFU.
Sometimes there is some leakage current via some I/O that's sufficient
to power up the SAM3S. Use the supply monitor to make sure the CPU
will be reset (and kept in reset) if the supply voltage is below 3.0V.
This makes sure that we'll re-enumerate on the USB, as a CPU reset
apparently doesn't automatically release the pull-up and notify the hub
that we were gone?
For some strange reason my output is garbled in both the 'screen' and
'cu' teerminal programs and 'raw' terminal (stty) mode. I fail to
understand why, but let's simply adjust the code as needed for now.
It is utterly unacceptable that Atmel is shipping example code in 2011,
which doesn't support parts that are shipped still in 2016. They would
have had five years to fix their code to implement the chip errata :(
We need to refer to g_dfu as a pointer from all code. In DFU mode, it
gets assigned to the address of _g_dfu, which is placed by the linker
script at the start of RAM. In runtime mode, the pointer is statically
defined to point at the start of RAM. The linker script for the runtime
(dfu environment) is adjusted to save the first 32 bytes for the _g_dfu
structure.
* we now actually route the EP0 control requests in DFU mode to the
correct handler (weak linker symbols are tricky)
* we now actually call code to read/write data from/to RAM/FLASH
This way we can easily check with 'diff' for differences in our code and
Atmel softpack. Also, this layout is more suitable for building various
different firmware images (e.g. factory-test, dfu-loader, main
application) for a variety of different boards (simtrace, owhw, qmod).
The signals are driving an external NPN transistor, so the default state
must be low at reset to en sure that !PERST on the modem input is
de-asserted by default.