Difference between revisions of "Saleae Logic16/Firmware"

From sigrok
Jump to navigation Jump to search
m
(Updated to contain renumbering of variables and bits in new FPGA bitstream)
 
(7 intermediate revisions by 3 users not shown)
Line 3: Line 3:
== Interrupt handlers ==
== Interrupt handlers ==


The following interrupt handlers are installed. If the address is absent, it means the handler just returns (RETI) without performing any action.
The following interrupt handlers are installed. If the address is absent, it means the handler just returns (RETI) without performing any action.  Addresses in red is for the new firmware version (vendor software version 1.1.34).


{| border="0" style="font-size: smaller;" class="alternategrey sigroktable"
{| border="0" style="font-size: smaller;" class="alternategrey sigroktable"
Line 9: Line 9:
!Address
!Address
|-
|-
|RESET
| RESET
|0x0000
| 0x0000
|-
|-
|TF2
| TF2
|0x0e65
| 0x0e65
|-
|-
|RESUME
| RESUME
|0x002e
| 0x002e
|-
|-
|SUDAV
| SUDAV
|0x0ae8
| 0x0ae8
|-
|-
|SOF
| SOF
|0x13d2
| 0x13d2 <span style="color: red">0x13d6</span>
|-
|-
|SUTOK
| SUTOK
|0x13bf
| 0x13bf <span style="color: red">0x13c3</span>
|-
|-
|SUSPEND
| SUSPEND
|0x13aa
| 0x13aa <span style="color: red">0x13ae</span>
|-
|-
|USB_RESET
| USB_RESET
|0x130b
| 0x130b <span style="color: red">0x130f</span>
|-
|-
|HISPEED
| HISPEED
|0x12df
| 0x12df <span style="color: red">0x12e3</span>
|-
|-
|EP0ACK
| EP0ACK
|
|
|-
|-
|EP0_IN
| EP0_IN
|
|
|-
|-
|EP0_OUT
| EP0_OUT
|
|
|-
|-
|EP1_IN
| EP1_IN
|
|
|-
|-
|EP1_OUT
| EP1_OUT
|0x115d
| 0x115d <span style="color: red">0x1161</span>
|-
|-
|EP2
| EP2
|0x11a2
| 0x11a2 <span style="color: red">0x11a6</span>
|-
|-
|EP4
| EP4
|
|
|-
|-
|EP6
| EP6
|
|
|-
|-
|EP8
| EP8
|
|
|-
|-
|IBN
| IBN
|
|
|-
|-
|EP0PING
| EP0PING
|
|
|-
|-
|EP1PING
| EP1PING
|
|
|-
|-
|EP2PING
| EP2PING
|
|
|-
|-
|EP4PING
| EP4PING
|
|
|-
|-
|EP6PING
| EP6PING
|
|
|-
|-
|EP8PING
| EP8PING
|
|
|-
|-
|ERRLIMIT
| ERRLIMIT
|
|
|-
|-
|EP2ISOERR
| EP2ISOERR
|
|
|-
|-
|EP4ISOERRF
| EP4ISOERRF
|
|
|-
|-
|EP6ISOERR
| EP6ISOERR
|
|
|-
|-
|EP8ISOERRF
| EP8ISOERRF
|
|
|-
|-
|EP2PF
| EP2PF
|
|
|-
|-
|EP4PF
| EP4PF
|
|
|-
|-
|EP6PF
| EP6PF
|
|
|-
|-
|EP8PF
| EP8PF
|
|
|-
|-
|EP2EF
| EP2EF
|
|
|-
|-
|EP4EF
| EP4EF
|
|
|-
|-
|EP6EF
| EP6EF
|
|
|-
|-
|EP8EF
| EP8EF
|
|
|-
|-
|EP2FF
| EP2FF
|0x11e7
| 0x11e7 <span style="color: red">0x11eb</span>
|-
|-
|EP4FF
| EP4FF
|
|
|-
|-
|EP6FF
| EP6FF
|
|
|-
|-
|EP8FF
| EP8FF
|
|
|-
|-
|GPIFDONE
| GPIFDONE
|
|
|-
|-
|GPIFWF
| GPIFWF
|
|
|}
|}
Line 147: Line 147:


{| border="0" style="font-size: smaller;" class="alternategrey sigroktable"
{| border="0" style="font-size: smaller;" class="alternategrey sigroktable"
! Byte
!Byte
! Handler
!Handler
! Operation
!Operation
|-
|-
| 1
| 1
Line 157: Line 157:
| 2
| 2
| 0x157
| 0x157
| Abort the GPIF.
| Abort the GPIF. <span style="color: red">In the new firmware, also reconfigures the endpoints like operation 1.</span>
|-
|-
| 6
| 6
| 0x15f
| 0x15f <span style="color: red">0x162</span>
| Write data to EEPROM with I²C address 1010000 (single addressing mode). The second and third byte contain a fixed magic cookie of 0x42 0x55. The fourth byte contains the single byte address. The fifth byte contains the number of bytes to write (1-58). The rest of the packet contains the data to write.
| Write data to EEPROM with I²C address 1010000 (0x50) in single byte addressing mode. The second and third byte contain a fixed magic cookie of '''0x42 0x55'''. The fourth byte contains the single byte address. The fifth byte contains the number of bytes to write (1-58). The rest of the packet contains the data to write.
|-
|-
| 7
| 7
| 0x1b3
| 0x1b3 <span style="color: red">0x1b6</span>
| Read data from EEPROM with I²C address 1010000 (single byte addressing mode). The second and third byte contain a fixed magic cookie of 0x33 0x81. The fourth byte contains the single byte address. The fifth byte contains the number of bytes to read (1-64). The data will be available as an IN transfer.
| Read data from EEPROM with I²C address 1010000 (0x50) in single byte addressing mode. The second and third byte contain a fixed magic cookie of '''0x33 0x81'''. The fourth byte contains the single byte address. The fifth byte contains the number of bytes to read (1-64). The data will be available as an IN transfer.
|-
|-
| 0x7a
| 0x7a
| 0x309
| 0x309 <span style="color: red">0x30c</span>
| Upload the sine table for LED flashing. The second byte contains the offset to start writing at, and the third byte the number of bytes to write. A maximum of 61 bytes can be uploaded per packet, so two packets are needed to write the entire table.
| Upload the sine table for LED flashing. The second byte contains the offset to start writing at, and the third byte the number of bytes to write. A maximum of 61 bytes can be uploaded per packet, so two packets are needed to write the entire table.
|-
|-
| 0x7b
| 0x7b
| 0x346
| 0x346 <span style="color: red">0x349</span>
| Enable or disable LED flashing. The second byte of the packet is a bool indicating if LED flashing should be enabled. The following bytes are only used if LED flashing is enabled, but are always transmitted. If flashing is enabled, the LED brighness will periodically be set from the sine table. Byte 3 and 4 of the packet are the Timer 2 reload value, in little endian format. Byte 5 is a software clock divisor. The pointer in the sine table will be advanced by one every (0x10000-RELOAD)*(DIV+1)/4000000 seconds. Byte 6 is a boolean indicating whether to repeat the waveform (1) or stop at the end of the first period (0).
| Enable or disable LED flashing. The second byte of the packet is a bool indicating if LED flashing should be enabled. The following bytes are only used if LED flashing is enabled, but are always transmitted. If flashing is enabled, the LED brighness will periodically be set from the sine table. Byte 3 and 4 of the packet are the Timer 2 reload value, in little endian format. Byte 5 is a software clock divisor. The pointer in the sine table will be advanced by one every '''(0x10000 - RELOAD) * (DIV + 1) / 4000000''' seconds. Byte 6 is a boolean indicating whether to repeat the waveform (1) or stop at the end of the first period (0).
|-
|-
| 0x7c
| 0x7c
| 0x282
| 0x282 <span style="color: red">0x285</span>
| Re-renumerate; return control to the builtin bootloader.
| Re-renumerate; return control to the builtin bootloader.
|-
|-
| 0x7d
| 0x7d
| 0x2aa
| 0x2aa <span style="color: red">0x2ad</span>
| Abort the GPIF. The second byte of the packet is returned complemented in an IN transfer, as acknowledgement.
| Abort the GPIF. The second byte of the packet is returned complemented in an IN transfer, as acknowledgement.
|-
|-
| 0x7e
| 0x7e
| 0x2cf
| 0x2cf <span style="color: red">0x2d2</span>
| Disable LED flashing, configure the GPIF, and prepare the FPGA for bitstream upload by pulsing PROG_B and then waiting for INIT_B.
| Disable LED flashing, configure the GPIF, and prepare the FPGA for bitstream upload by pulsing '''PROG_B''' and then waiting for '''INIT_B'''.
|-
|-
| 0x7f
| 0x7f
| 0x2e4
| 0x2e4 <span style="color: red">0x2e7</span>
| Disable LED flashing, transmit N (1-62) bytes of bitstream on the FPGA DIN pin, clocked by CCLK. The second byte of the packet encodes N.
| Disable LED flashing, transmit N (1-62) bytes of bitstream on the FPGA '''DIN''' pin, clocked by '''CCLK'''. The second byte of the packet encodes N.
|-
|-
| 0x80
| 0x80
| 0x205
| 0x205 <span style="color: red">0x208</span>
| Transmit N (1-31) 16-bit words to the FPGA. The second byte of the packet encodes N. Data is sent on PA6, MSB first, with rising edges of PA5 to clock the bits out. During each word transfer, PA4 is held low. The most significant bit (b15) of each word must be 0.
| Transmit N (1-31) 16-bit words to the FPGA. The second byte of the packet encodes N. Data is sent on '''PA6''', MSB-first, with rising edges of '''PA5''' to clock the bits out. During each word transfer, '''PA4''' is held low. The most significant bit (b15) of each word must be 0.
|-
|-
| 0x81
| 0x81
| 0x23b
| 0x23b <span style="color: red">0x23e</span>
| Perform N (1-31) write-read transactions to the FPGA. The second byte of the packet encodes N. Each transaction consists of 8 bits (from the out packet) being transmitted on PA6, like for the 0x80 operation above, and then 8 bits being received on PA7. N bytes will be available for an IN transfer afterwards. The most significant bit (b7) of each byte to send must be 0, but is actually transmitted as a 1 (to indicate read operation). PA7 is polled immediately after the falling edge of PA5. PA4 is held low during each write-read transaction.
| Perform N (1-31) write-read transactions to the FPGA. The second byte of the packet encodes N. Each transaction consists of 8 bits (from the out packet) being transmitted on '''PA6''', like for the 0x80 operation above, and then 8 bits being received on '''PA7'''. N bytes will be available for an IN transfer afterwards. The most significant bit (b7) of each byte to send must be 0, but is actually transmitted as a 1 (to indicate read operation). '''PA7''' is polled immediately after the falling edge of '''PA5'''. '''PA4''' is held low during each write-read transaction.
|-
|-
| 0x82
| 0x82
| 0x3a3
| 0x3a3 <span style="color: red">0x3a6</span>
| Read the REVID register. 16 bits of REVID data will be available for an IN transfer.
| Read the REVID register. 16 bits of '''REVID''' data will be available for an IN transfer.
|-
|-
| others
| others
| 0x3c7
| 0x3c7 <span style="color: red">0x3ca</span>
| Do nothing
| Do nothing
|}
|}
Line 236: Line 236:
!Value
!Value
|-
|-
|0x1f00-0x1f7f
| 0x1f00-0x1f7f
|0x8d6-0x955
| 0x8d6-0x955
|
|
|WAVEDATA
| WAVEDATA
|-
|-
|0x1f80
| 0x1f80
|0x981
| 0x981
|0xe0
| 0xe0
|GPIFREADYCFG
| GPIFREADYCFG
|-
|-
|0x1f81
| 0x1f81
|0x982
| 0x982
|0x10
| 0x10
|GPIFCTLCFG
| GPIFCTLCFG
|-
|-
|0x1f82
| 0x1f82
|0x983
| 0x983
|0x00
| 0x00
|GPIFIDLECS
| GPIFIDLECS
|-
|-
|0x1f83
| 0x1f83
|0x984
| 0x984
|0x05
| 0x05
|GPIFIDLECTL
| GPIFIDLECTL
|-
|-
|0x1f84
| 0x1f84
|0x985
| 0x985
|0xee
| 0xee
|?
| ?
|-
|-
|0x1f85
| 0x1f85
|0x986
| 0x986
|0x50
| 0x50
|GPIFWFSELECT
| GPIFWFSELECT
|-
|-
|0x1f86
| 0x1f86
|0x987
| 0x987
|0x00
| 0x00
|GPIFREADYSTAT
| GPIFREADYSTAT
|-
|-
|0x1f87
| 0x1f87
|0x95a
| 0x95a
|0x00
| 0x00
|FLOWSTATE
| FLOWSTATE
|-
|-
|0x1f88
| 0x1f88
|0x95b
| 0x95b
|0x00
| 0x00
|FLOWLOGIC
| FLOWLOGIC
|-
|-
|0x1f89
| 0x1f89
|0x95c
| 0x95c
|0x00
| 0x00
|FLOWEQ0CTL
| FLOWEQ0CTL
|-
|-
|0x1f8a
| 0x1f8a
|0x95d
| 0x95d
|0x00
| 0x00
|FLOWEQ1CTL
| FLOWEQ1CTL
|-
|-
|0x1f8b
| 0x1f8b
|0x95e
| 0x95e
|0x00
| 0x00
|FLOWHOLDOFF
| FLOWHOLDOFF
|-
|-
|0x1f8c
| 0x1f8c
|0x95f
| 0x95f
|0x00
| 0x00
|FLOWSTB
| FLOWSTB
|-
|-
|0x1f8d
| 0x1f8d
|0x960
| 0x960
|0x00
| 0x00
|FLOWSTBEDGE
| FLOWSTBEDGE
|-
|-
|0x1f8e
| 0x1f8e
|0x961
| 0x961
|0x00
| 0x00
|FLOWSTBHPERIOD
| FLOWSTBHPERIOD
|-
|-
|0x1f8f-0x1faa
| 0x1f8f-0x1faa
|0x962-0x97d
| 0x962-0x97d
|0x00
| 0x00
|?
| ?
|-
|-
|0x1fab-0x1fea
| 0x1fab-0x1fea
|
|
|
|
|64 byte sine table for LED flashing
| 64 byte sine table for LED flashing
|}
|}


Line 346: Line 346:
!CTL0
!CTL0
|-
|-
|0
| 0
|0x81
| 0x81
|0x01   
| 0x01   
|0x05   
| 0x05   
|0x70
| 0x70
|if FF or RDY0 then 0 (ReExec) else 1
| if FF or RDY0 then 0 (ReExec) else 1
|0
| 0
|0
| 0
|1
| 1
|0
| 0
|1
| 1
|-
|-
|1
| 1
|0xB8   
| 0xB8   
|0x07   
| 0x07   
|0x04   
| 0x04   
|0x2D
| 0x2D
|if TC expired then 7 else 0
| if TC expired then 7 else 0
|1
| 1
|1
| 1
|1
| 1
|0
| 0
|0
| 0
|-
|-
|2
| 2
|0x01   
| 0x01   
|0x02   
| 0x02   
|0x04   
| 0x04   
|0x00   
| 0x00   
|Delay 1
| Delay 1
|0
| 0
|1
| 1
|1
| 1
|0
| 0
|0
| 0
|-
|-
|3
| 3
|0x01   
| 0x01   
|0x02   
| 0x02   
|0x04   
| 0x04   
|0x00   
| 0x00   
|Delay 1
| Delay 1
|0
| 0
|1
| 1
|1
| 1
|0
| 0
|0
| 0
|-
|-
|4
| 4
|0x01   
| 0x01   
|0x02   
| 0x02   
|0x04   
| 0x04   
|0x00   
| 0x00   
|Delay 1
| Delay 1
|0
| 0
|1
| 1
|1
| 1
|0
| 0
|0
| 0
|-
|-
|5
| 5
|0x01   
| 0x01   
|0x02   
| 0x02   
|0x04   
| 0x04   
|0x00   
| 0x00   
|Delay 1
| Delay 1
|0
| 0
|1
| 1
|1
| 1
|0
| 0
|0
| 0
|-
|-
|6
| 6
|0x01   
| 0x01   
|0x02   
| 0x02   
|0x04   
| 0x04   
|0x00   
| 0x00   
|Delay 1
| Delay 1
|0
| 0
|1
| 1
|1
| 1
|0
| 0
|0
| 0
|}
|}


Line 446: Line 446:
!CTL0
!CTL0
|-
|-
|0-6
| 0-6
|0x01
| 0x01
|0x00
| 0x00
|0x05
| 0x05
|0x00
| 0x00
|Delay 1
| Delay 1
|0
| 0
|0
| 0
|1
| 1
|0
| 0
|1
| 1
|}
|}


== FPGA variables ==
== FPGA variables ==


The following variables can be read and written by the host using operations 0x81 and 0x80:
The following variables can be read and written by the host using operations 0x81 and 0x80 (red numbers indicate variable and bit numbers in the new version bitstreams):


{| border="0" style="font-size: smaller;" class="alternategrey sigroktable"
{| border="0" style="font-size: smaller;" class="alternategrey sigroktable"
! Address
! style="width: 4em;" | Address
! style="width: 3em;" | Bit
! Contents
! Contents
|-
|-
|0x00
| 0x00 <span style="color: red">0x07</span>
|FPGA bitstream version (currently 0x10)
|
| '''FPGA bitstream version''' (currently 0x10 <span style="color: red">0x13</span>).
|-
| 0x01 <span style="color: red">0x0f</span>
|
| '''Status and control'''.
|-
|
| 0 <span style="color: red">5</span>
| Acquisition running
|-
|
| 1 <span style="color: red">3</span>
| Update acquisition parameters(?)
|-
|
| 2
|
|-
|
| 3 <span style="color: red">4</span>
|
|-
|-
|0x01
|
|Status and control.  Bit 0 = acquisition running.  Bit 1 = update acquisition parameters(?).  Bit 3 = ?.  Bit 6 = ?.
| 4
|
|-
|-
|0x02
|
|Channel select low.  Each 1 bit in this byte enables one of the channels 0-7 for acquisition.
| 5 <span style="color: red">0</span>
| FIFO overflow
|-
|-
|0x03
|
|Channel select high.  Each 1 bit in this byte enables one of the channels 8-15 for acquisition.
| 6 <span style="color: red">2</span>
|
|-
|-
|0x04
|
|Sampling rate divisor. Sample rate is the base clock divided by N+1, where N is the value in this register.
| 7
|
 
|-
| 0x02 <span style="color: red">0x01</span>
|
| '''Channel select low'''. Each 1 bit in this byte enables one of the channels 0-7 for acquisition.
|-
| 0x03 <span style="color: red">0x06</span>
|
| '''Channel select high'''. Each 1 bit in this byte enables one of the channels 8-15 for acquisition.
|-
| 0x04 <span style="color: red">0x0b</span>
|
| '''Sampling rate divisor'''. Sample rate is the base clock divided by N+1, where N is the value in this register.
|-
| 0x05 <span style="color: red">0x05</span>
|
| '''LED brightness'''. 0 = min (off), 0xff = max, 0x19 = dimmed.
|-
| 0x06 <span style="color: red">0x0e</span>
|
| ?
|-
| 0x07 <span style="color: red">0x02</span>
|
| ?
|-
| 0x08
|
| ? (Read on acquisition stop.)
|-
| 0x09
|
| ? (Read on acquisition stop.)
|-
| 0x0a <span style="color: red">0x04</span>
|
|
|-
|
| 0 <span style="color: red">2</span>
| Sampling base clock select: 0 = 100MHz, 1 = 160MHz
|-
|
| 1
|
|-
|
| 2
|
|-
|
| 3
|
|-
|
| 4
|
|-
|
| 5
|
|-
|
| 6 <span style="color: red">7</span>
|
|-
|
| 7 <span style="color: red">0</span>
|
 
|-
| 0x0c <span style="color: red">0x03</span>
|
| ?
|}
 
== EEPROM layout ==
 
The Saleae Logic16 has a 256-byte I2C EEPROM with the following layout:
 
<span style="background-color: orange">c0</span> <span style="background-color: lime">a9 21</span> <span style="background-color: green">01 10</span> <span style="background-color: lightgreen">00 00</span> <span style="background-color: brown">00</span> <span style="background-color: yellow">aa bb cc dd ee ff gg hh</span>
<span style="background-color: cyan">xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx</span>
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
 
Description:
 
{| border="0" style="font-size: smaller;" class="alternategrey sigroktable"
!Bytes
!Description
|-
|-
|0x05
| style="background-color: orange" | 0
|LED brightness. 0 = min (off), 0xff = max, 0x19 = dimmed.
| '''0xc0''': FX2 "c0 load" mode, i.e. VID/PID/DID are loaded from EEPROM (but not firmware).
|-
|-
|0x06
| style="background-color: lime" | 1-2
|?
| '''0x21a9''': USB vendor ID (VID).
|-
|-
|0x07
| style="background-color: green" | 3-4
|?
| '''0x1001''': USB product ID (PID).
|-
|-
|0x08
| style="background-color: lightgreen" | 5-6
|? (Read on acquisition stop.)
| '''0x0000''': USB device ID (DID).
|-
|-
|0x09
| style="background-color: brown" | 7
|? (Read on acquisition stop.)
| '''0x00''': FX2 configuration byte (see FX2 TRM for details).
|-
|-
|0x0a
| style="background-color: yellow" | 8-15
|Bit 7 = ?.  Bit 6 = ?. Bit 0 = Sampling base clock select: 0 = 100MHz, 1 = 160MHz
| A unique device identifier / serial number for this Logic16 (8 bytes).
|-
|-
|0x0c
| style="background-color: cyan" | 16-31
|?
| "Magic" values that are different for each Logic16 device (16 bytes).
|}
|}

Latest revision as of 20:34, 22 April 2015

The following information is related to the vendor firmware included with the version 1.1.15 of the vendor application "Logic".

Interrupt handlers

The following interrupt handlers are installed. If the address is absent, it means the handler just returns (RETI) without performing any action. Addresses in red is for the new firmware version (vendor software version 1.1.34).

Handler Address
RESET 0x0000
TF2 0x0e65
RESUME 0x002e
SUDAV 0x0ae8
SOF 0x13d2 0x13d6
SUTOK 0x13bf 0x13c3
SUSPEND 0x13aa 0x13ae
USB_RESET 0x130b 0x130f
HISPEED 0x12df 0x12e3
EP0ACK
EP0_IN
EP0_OUT
EP1_IN
EP1_OUT 0x115d 0x1161
EP2 0x11a2 0x11a6
EP4
EP6
EP8
IBN
EP0PING
EP1PING
EP2PING
EP4PING
EP6PING
EP8PING
ERRLIMIT
EP2ISOERR
EP4ISOERRF
EP6ISOERR
EP8ISOERRF
EP2PF
EP4PF
EP6PF
EP8PF
EP2EF
EP4EF
EP6EF
EP8EF
EP2FF 0x11e7 0x11eb
EP4FF
EP6FF
EP8FF
GPIFDONE
GPIFWF

Endpoint 1 OUT (EP1_OUT) handler

After decrypting the OUT packet, processing of the packet proceeds depending on the first byte of the packet, which selects the operation. After the operation, any resulting IN packet will be encrypted before submitting it to the host.

Byte Handler Operation
1 0x14f Configure endpoints for quad-buffered bulk FIFO operation, and trigger a GPIF read on EP2.
2 0x157 Abort the GPIF. In the new firmware, also reconfigures the endpoints like operation 1.
6 0x15f 0x162 Write data to EEPROM with I²C address 1010000 (0x50) in single byte addressing mode. The second and third byte contain a fixed magic cookie of 0x42 0x55. The fourth byte contains the single byte address. The fifth byte contains the number of bytes to write (1-58). The rest of the packet contains the data to write.
7 0x1b3 0x1b6 Read data from EEPROM with I²C address 1010000 (0x50) in single byte addressing mode. The second and third byte contain a fixed magic cookie of 0x33 0x81. The fourth byte contains the single byte address. The fifth byte contains the number of bytes to read (1-64). The data will be available as an IN transfer.
0x7a 0x309 0x30c Upload the sine table for LED flashing. The second byte contains the offset to start writing at, and the third byte the number of bytes to write. A maximum of 61 bytes can be uploaded per packet, so two packets are needed to write the entire table.
0x7b 0x346 0x349 Enable or disable LED flashing. The second byte of the packet is a bool indicating if LED flashing should be enabled. The following bytes are only used if LED flashing is enabled, but are always transmitted. If flashing is enabled, the LED brighness will periodically be set from the sine table. Byte 3 and 4 of the packet are the Timer 2 reload value, in little endian format. Byte 5 is a software clock divisor. The pointer in the sine table will be advanced by one every (0x10000 - RELOAD) * (DIV + 1) / 4000000 seconds. Byte 6 is a boolean indicating whether to repeat the waveform (1) or stop at the end of the first period (0).
0x7c 0x282 0x285 Re-renumerate; return control to the builtin bootloader.
0x7d 0x2aa 0x2ad Abort the GPIF. The second byte of the packet is returned complemented in an IN transfer, as acknowledgement.
0x7e 0x2cf 0x2d2 Disable LED flashing, configure the GPIF, and prepare the FPGA for bitstream upload by pulsing PROG_B and then waiting for INIT_B.
0x7f 0x2e4 0x2e7 Disable LED flashing, transmit N (1-62) bytes of bitstream on the FPGA DIN pin, clocked by CCLK. The second byte of the packet encodes N.
0x80 0x205 0x208 Transmit N (1-31) 16-bit words to the FPGA. The second byte of the packet encodes N. Data is sent on PA6, MSB-first, with rising edges of PA5 to clock the bits out. During each word transfer, PA4 is held low. The most significant bit (b15) of each word must be 0.
0x81 0x23b 0x23e Perform N (1-31) write-read transactions to the FPGA. The second byte of the packet encodes N. Each transaction consists of 8 bits (from the out packet) being transmitted on PA6, like for the 0x80 operation above, and then 8 bits being received on PA7. N bytes will be available for an IN transfer afterwards. The most significant bit (b7) of each byte to send must be 0, but is actually transmitted as a 1 (to indicate read operation). PA7 is polled immediately after the falling edge of PA5. PA4 is held low during each write-read transaction.
0x82 0x3a3 0x3a6 Read the REVID register. 16 bits of REVID data will be available for an IN transfer.
others 0x3c7 0x3ca Do nothing

Command 0x7e waveform

Logic16 FW Command 0x7e Waveform.svg

Command 0x7f waveform

Logic16 FW Command 0x7f Waveform.svg

Command 0x80 waveform

Logic16 FW Command 0x80 Waveform.svg

Command 0x81 waveform

Logic16 FW Command 0x81 Waveform.svg

XDATA variables

The following variables are stored in the 8K "external" code/data memory, after the firmware code.

Address Init data in FW Contents
Address Value
0x1f00-0x1f7f 0x8d6-0x955 WAVEDATA
0x1f80 0x981 0xe0 GPIFREADYCFG
0x1f81 0x982 0x10 GPIFCTLCFG
0x1f82 0x983 0x00 GPIFIDLECS
0x1f83 0x984 0x05 GPIFIDLECTL
0x1f84 0x985 0xee ?
0x1f85 0x986 0x50 GPIFWFSELECT
0x1f86 0x987 0x00 GPIFREADYSTAT
0x1f87 0x95a 0x00 FLOWSTATE
0x1f88 0x95b 0x00 FLOWLOGIC
0x1f89 0x95c 0x00 FLOWEQ0CTL
0x1f8a 0x95d 0x00 FLOWEQ1CTL
0x1f8b 0x95e 0x00 FLOWHOLDOFF
0x1f8c 0x95f 0x00 FLOWSTB
0x1f8d 0x960 0x00 FLOWSTBEDGE
0x1f8e 0x961 0x00 FLOWSTBHPERIOD
0x1f8f-0x1faa 0x962-0x97d 0x00 ?
0x1fab-0x1fea 64 byte sine table for LED flashing

WAVEDATA

The following data is loaded into WAVEDATA on bootup, and whenever operation 0x7e is performed:

Waveform descriptor 0

State Length/Branch Opcode Output Logic Operation NEXT DATA CTL2 CTL1 CTL0
0 0x81 0x01 0x05 0x70 if FF or RDY0 then 0 (ReExec) else 1 0 0 1 0 1
1 0xB8 0x07 0x04 0x2D if TC expired then 7 else 0 1 1 1 0 0
2 0x01 0x02 0x04 0x00 Delay 1 0 1 1 0 0
3 0x01 0x02 0x04 0x00 Delay 1 0 1 1 0 0
4 0x01 0x02 0x04 0x00 Delay 1 0 1 1 0 0
5 0x01 0x02 0x04 0x00 Delay 1 0 1 1 0 0
6 0x01 0x02 0x04 0x00 Delay 1 0 1 1 0 0

Waveform descriptor 1-3

State Length/Branch Opcode Output Logic Operation NEXT DATA CTL2 CTL1 CTL0
0-6 0x01 0x00 0x05 0x00 Delay 1 0 0 1 0 1

FPGA variables

The following variables can be read and written by the host using operations 0x81 and 0x80 (red numbers indicate variable and bit numbers in the new version bitstreams):

Address Bit Contents
0x00 0x07 FPGA bitstream version (currently 0x10 0x13).
0x01 0x0f Status and control.
0 5 Acquisition running
1 3 Update acquisition parameters(?)
2
3 4
4
5 0 FIFO overflow
6 2
7
0x02 0x01 Channel select low. Each 1 bit in this byte enables one of the channels 0-7 for acquisition.
0x03 0x06 Channel select high. Each 1 bit in this byte enables one of the channels 8-15 for acquisition.
0x04 0x0b Sampling rate divisor. Sample rate is the base clock divided by N+1, where N is the value in this register.
0x05 0x05 LED brightness. 0 = min (off), 0xff = max, 0x19 = dimmed.
0x06 0x0e ?
0x07 0x02 ?
0x08 ? (Read on acquisition stop.)
0x09 ? (Read on acquisition stop.)
0x0a 0x04
0 2 Sampling base clock select: 0 = 100MHz, 1 = 160MHz
1
2
3
4
5
6 7
7 0
0x0c 0x03 ?

EEPROM layout

The Saleae Logic16 has a 256-byte I2C EEPROM with the following layout:

c0 a9 21 01 10 00 00 00 aa bb cc dd ee ff gg hh
xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff

Description:

Bytes Description
0 0xc0: FX2 "c0 load" mode, i.e. VID/PID/DID are loaded from EEPROM (but not firmware).
1-2 0x21a9: USB vendor ID (VID).
3-4 0x1001: USB product ID (PID).
5-6 0x0000: USB device ID (DID).
7 0x00: FX2 configuration byte (see FX2 TRM for details).
8-15 A unique device identifier / serial number for this Logic16 (8 bytes).
16-31 "Magic" values that are different for each Logic16 device (16 bytes).