Generic USB definitions

The file UsbDefs.fth contains generic USB defines and tools used to insulate the hardware drivers UsbHwxxxx.fth from the core layers in UsbBase.fth and UsbEP0.fth.

0 equ USBMin?   \ -- flag
If your control file sets this equate non-zero, much of the USB code is compiled without headers.

struct /USBSetupPacket  \ -- len
USB Default Control Pipe Setup Packet structure.

  byte  usp.bmRequestType       \ bit7=Dir,0=to dev, bit6:5=Type, bit4:0=Recipient
  byte  usp.bRequest
  hword usp.wValue
  hword usp.wIndex
  hword usp.wLength
end-struct

struct /UsbEpd  \ -- len
USB Standard Endpoint Descriptor

  BYTE  epd.Len
  BYTE  epd.Type
  BYTE  epd.Addr
  BYTE  epd.Attribs
  HWORD epd./MaxPacket
  BYTE  epd.Interval
end-struct

Support tools

: bitn          \ n -- 2^n
Generate bit n from n.

: lew@          \ addr -- w
16 bit unaligned little-endian fetch. USB control data is in little-endian form and may be unaligned.

: lew!          \ w addr --
16 bit unaligned little endian store. USB control data is in little-endian form and may be unaligned.

: lel@          \ addr -- x
32 bit unaligned little-endian fetch.

: lel!          \ x addr --
32 bit unaligned little endian store.

: lew@          \ addr -- w
16 bit fetch. USB control data is in little-endian form and may be unaligned.

: lew!          \ w addr --
16 bit store. USB control data is in little-endian form and may be unaligned.

: lew,          \ w --
Lay unaligned little-endian 16 bit data.

: lel@          \ addr -- x
32 bit unaligned little-endian fetch.

: lel!          \ x addr --
32 bit unaligned little endian store.

: lel,          \ x --
Lay unaligned little-endian 32 bit data.

: bew@          \ addr -- w
Unaligned big-endian 16 bit fetch.

: bew!          \ w addr --
Unaligned big-endian 16 bit store.

: bew,          \ w --
Lay unaligned big-endian 16 bit data.

: bel@          \ addr -- x
Unaligned big-endian 32 bit fetch.

: bel!          \ x addr --
Unaligned big-endian 32 bit store.

: bel,          \ x --
Lay unaligned big-endian 32 bit data.

Strings are laid as little-endian 16 bit Unicode, preceded by a count byte and a string type marker.

: resetUIFs     \ --
Start the USB interface sequence numbering at 0.

: NextUIF:      \ "<name>" --
Create an equate with the next USB interface number.

: #UIFs         \ -- u
Returns the number of interfaces defined so far.

Hardware isolation

The five VALUEs below are used to provide status information for the core layer, but are actually contained here in UsbDefs.fth to avoid forward references and to permit easy reference by the class drivers. Note that the endpoint status values are bit masks in a hardware independent form. See EP>mask below.

0 value DevAddr         \ -- x
Set to $80+u where u is the new device address. Used by low level code to set the USB device address at a time suitable for the hardware. After setting UsbDevAddr below, DevAddr is reset to 0.

0 value UsbDevAddr      \ -- u
USB device address. Set by the host.

0 value UsbConfig       \ -- x
USB Configuration set. Non-zero when the USB device has been configured.

0 value UsbEPmask       \ -- x
Endpoint mask. Bits are set when the endpoint is enabled. Used by the core layer.

0 value UsbEPhalt       \ -- x
Endpoint halt status. Bits are set when the endpoint is halted/stalled.

0 value Usb#IfSet       \ -- n
Number of interfaces set.

: EP>mask       \ ep# -- mask
Decode an endpoint number to a bit mask such that if bit 7 is clear (OUT endpoints), the bit is in the low 16 bits, and if set (IN endpoints) in the upper 16 bits.

Linked lists

Linked lists are used by the USB driver to avoid forward references to higher level code, especially various reset actions. Note that the chains are managed at compile time. The linked list uses facilities provided in Common\Kernel62.fth.

: ExecChain     \ anchor --
Execute the contents of chain with the following structure:

  link | xt | ...

Each word that is run has the stack effect

  link -- link

Where link is the address of the link field in the structure. Thus, data that follows the xt can easily be accessed.

create UsbResetChain    \ -- addr
Anchors the chain of words executed at device reset.

create UsbFrameChain    \ -- addr
Anchors the chain of words executed in the frame interrupt.

: link,         \ addr --
Extend chain anchored at addr.

: AtUSBreset    \ xt --
Add the word whose xt is given to the USB reset chain.

: AtUSBframe    \ xt --
Add the word whose xt is given to the USB frame interrupt chain. Words in this chain are mostly used to enable Bulk or Interrupt endpoint NAK interrupts. Careful use of this chain can significantly reduce USB interrupt handling overhead.