HostMot2 Register map in offsets from 32 bit memory base address Note the following addresses are standard but driver should use IDROM info instead of this table. Also, number of special functions (counters, PWMGens etc) is determined by configuration. Additional registers are always at increasing doubleword boundaries with the exception of UART data FIFOs. (this difference with UARTS make be fixed by using byte enables later) First ID stuff 0x0100 Config cookie = 0x55AACAFE 0x0104 First 4 characters of configuration name 0x0108 Last 4 characters of configuration name 0x010C Offset to IDROM location (normally 0x00000400) 0x0400 Normal IDROM location 0x400 IDROMType 2 for this type 0x404 OffsetToModules 64 for this type 0x408 OffsetToPindesc 512 for this type 0x40C BoardNameLow 0x410 BoardNameHigh 0x414 FPGA size 0x418 FPGA pins 0x41C IOPorts 0x420 IOWidth 0x424 PortWidth Normally 24 0x428 ClockLow In Hz (note:on 5I20/4I65 = PCI clock -- guessed as 33.33 MHz) 0x42C ClockHigh In Hz 0x430 InstanceStride0 0x434 InstanceStride1 0x438 RegisterStride0 0x43C RegisterStride1 0x440.. Module descriptions 0 through 31 Each module descriptor is three doublewords with the following record structure: 0x440: (from least to most significant order) GTag(0 (byte) = General function tag Version(0) (byte) = module version ClockTag(0) (byte) = Whether module uses ClockHigh or ClockLow Instances(0) (byte) = Number of instances of module in configuration BaseAddress(0) (word) = offset to module. This is also specific register = Tag Registers(0) (byte) = Number of registers per module MPBitmap(0) (Double) = bit map of which registers are multiple '1' = multiple, LSb = reg(0) 0x44C: (from least to most significant order) GTag(1) (byte) = General function tag Version(1) (byte) = module version ClockTag(1) (byte) = Whether module uses ClockHigh or ClockLow Instances(1) (byte) = Number of instances of module in configuration BaseAddress(1) (word) = offset to module. This is also specific register = Tag Registers(1) (byte) = Number of registers per module MPBitmap(1) (Double) = bit map of which registers are multiple '1' = multiple, LSb = reg(0) 0 GTag marks end of module descriptors 0x600 Pin descriptors 0 through 127. There is one Pin Descriptor for each I/O pin. Each pin descriptor is a doubleword with the following record structure: 0x600 SecPin(0) (byte) = Which pin of secondary function connects here eg: A,B,IDX. Output pins have bit 7 = '1' SecTag(0) (byte) = Secondary function type (PWM,QCTR etc). Same as module GTag SecUnit(0) (byte) = Which secondary unit or channel connects here PrimaryTag(0) (byte) = Primary function tag (normally I/O port) 0x604 SecPin(1) (byte) = Which pin of secondary function connects here eg: A,B,IDX. Output pins have bit 7 = '1' SecTag(1) (byte) = Secondary function type (PWM,QCTR etc). Same as module GTag SecUnit(1) (byte) = Which secondary unit or channel connects here PrimaryTag(1) (byte) = Primary function tag (normally I/O port) ... 0 primary function tag marks end of pins 0x0800 1 bit IDROM write enable bit: high=Enable writes 0x0900 IRQDiv 16 bit divider of selected PWMreference output bit. Divides by n+2. 0x0A00 IRQStatus Bit 2..4 Select which PWM reference counter bit is used as IRQ divider source: 000 = PWMRefcount(MSB-7) 001 = PWMRefcount(MSB-6) 010 = PWMRefcount(MSB-5) 011 = PWMRefcount(MSB-4) 100 = PWMRefcount(MSB-3) 101 = PWMRefcount(MSB-2) 110 = PWMRefcount(MSB-1) 111 = PWMRefcount(MSB) Bit 1 = Irq mask: 0 = masked Bit 0 = IRQ status (R/W) 0x0B00 ClearIRQ: Writes here clear IRQ 0x0C00 WatchdogTimer (R/W 32 bit watchdog timer.If MSB is set, watchdog is disabled. Timeout is WatchdogTimer+1/CLKLOW. Currently all watchdog does is clear GPIO DDR, and OpenDrain registers setting all GPIO to inputs (high with pullups) 0x0D00 WatchDogStatus Bit 0 = Watchdog has bitten status (1 = you been bit) 0x0E00 Watchdog Cookie location 0x5A written to 8 MSbs will reset watchdog to previously written timeout value. 0x1000 I/O port 0..23 0x1004 I/O port 24..47 0x1008 I/O port 48..71 0x100C I/O port 72..95 0x1010 I/O port 96..127 Writes write to output register, reads read pin status 0x1100 DDR for I/O port 0..23 0x1104 DDR for I/O port 24..47 0x1108 DDR for I/O port 48..71 0x110C DDR for I/O port 72..95 '1' bit in DDR register makes corresponding GPIO bit an output 0x1200 AltSourceReg for I/O port 0..23 0x1204 AltSourceReg for I/O port 24..47 0x1208 AltSourceReg for I/O port 48..71 0x120C AltSourceReg for I/O port 72..95 '1' bit in AltSource register makes corresponding GPIO bit data source come from Alternate source for that bit instead of output register. 0x1300 OpenDrainSelect for I/O port 0..23 0x1304 OpenDrainSelect for I/O port 24..47 0x1308 OpenDrainSelect for I/O port 48..71 0x130C OpenDrainSelect for I/O port 72..95 '1' bit in OpenDrainSelect register makes corresponding GPIO an open drain output. If OpenDrain is selected for an I/O bit , the DDR register is ignored. 0x1400 OutputInvert for I/O port 0..23 0x1404 OutputInvert for I/O port 24..47 0x1408 OutputInvert for I/O port 48..71 0x140C OutputInvert for I/O port 72..95 A '1' bit in the OutputInv register inverts the cooresponding output bit. This may be the output register bit or alternate source. The input is not inverted. ************************************************** Step/dir generators currently 48 bit accum = 16 bits full step, 32 fractional step/rate Step rate registers : Write only 0x2000 32 bit rate register for StepGen 0 0x2004 32 bit rate register for StepGen 1 0x2008 32 bit rate register for StepGen 2 0x200C 32 bit rate register for StepGen 3 0x2010 32 bit rate register for StepGen 4 0x2014 32 bit rate register for StepGen 5 0x2018 32 bit rate register for StepGen 6 0x201C 32 bit rate register for StepGen 7 ... 32 bit top of accumulator = 16.16 fullstep.fractionalstep : Read/write 0x2100 32 bit full.fractional accum for StepGen 0 0x2104 32 bit full.fractional accum for StepGen 1 0x2108 32 bit full.fractional accum for StepGen 2 0x210C 32 bit full.fractional accum for StepGen 3 0x2110 32 bit full.fractional accum for StepGen 4 0x2114 32 bit full.fractional accum for StepGen 5 0x2118 32 bit full.fractional accum for StepGen 6 0x211C 32 bit full.fractional accum for StepGen 7 ... Mode registers (2 bits Write only) 00 = Step/Dir 01 = Up/Down 10 = Quadrature 11 = Table Driven 0x2200 2 bit mode register for StepGen 0 0x2204 2 bit mode register for StepGen 1 0x2208 2 bit mode register for StepGen 2 0x220C 2 bit mode register for StepGen 3 0x2210 2 bit mode register for StepGen 4 0x2214 2 bit mode register for StepGen 5 0x2218 2 bit mode register for StepGen 6 0x221C 2 bit mode register for StepGen 7 ... DIR Setup time = how long DIR must be valid before step pulses may be issued Max time for 14 bits at ClockLow = 33 MHz = ~480 uS. At ClockLow = 50 MHz = ~320 uS Write only 0x2300 14 bit DIR setup time register for StepGen 0 0x2304 14 bit DIR setup time register for StepGen 1 0x2308 14 bit DIR setup time register for StepGen 2 0x230C 14 bit DIR setup time register for StepGen 3 0x2310 14 bit DIR setup time register for StepGen 4 0x2314 14 bit DIR setup time register for StepGen 5 0x2318 14 bit DIR setup time register for StepGen 6 0x231C 14 bit DIR setup time register for StepGen 7 ... DIR Hold time = how long DIR most remain valid after a step pulse has been issued Max time for 14 bits at ClockLow = 33 MHz = ~480 mS. At ClockLow = 50 MHz = ~320 mS Write only 0x2400 14 bit DIR hold time register for StepGen 0 0x2404 14 bit DIR hold time register for StepGen 1 0x2408 14 bit DIR hold time register for StepGen 2 0x240C 14 bit DIR hold time register for StepGen 3 0x2410 14 bit DIR hold time register for StepGen 4 0x2414 14 bit DIR hold time register for StepGen 5 0x2418 14 bit DIR hold time register for StepGen 6 0x241C 14 bit DIR hold time register for StepGen 7 ... Pulse length = Active time of output pulse. Max time for 14 bits at ClockLow = 33 MHz = ~480 uS. At ClockLow = 50 MHz = ~320 uS Write only 0x2500 14 bit pulse width register for StepGen 0 0x2504 14 bit pulse width register for StepGen 1 0x2508 14 bit pulse width register for StepGen 2 0x250C 14 bit pulse width register for StepGen 3 0x2510 14 bit pulse width register for StepGen 4 0x2514 14 bit pulse width register for StepGen 5 0x2518 14 bit pulse width register for StepGen 6 0x251C 14 bit pulse width register for StepGen 7 ... Pulse Idle = Inactive time of output pulse. Max time for 14 bits at ClockLow = 33 MHz = ~480 uS. At ClockLow = 50 MHz = ~320 uS Write only 0x2600 14 bit pulse idle width register for StepGen 0 0x2604 14 bit pulse idle width register for StepGen 1 0x2608 14 bit pulse idle width register for StepGen 2 0x260C 14 bit pulse idle width register for StepGen 3 0x2610 14 bit pulse idle width register for StepGen 4 0x2614 14 bit pulse idle width register for StepGen 5 0x2618 14 bit pulse idle width register for StepGen 6 0x261C 14 bit pulse idle width register for StepGen 7 ... Output sequence table. This is a single write location where the table sequence data for table driven step generator output is stored. Data is written sequentially here from last to first data word in the sequence. Default table width is 6 bits. Table data is in LSBs of written word. 0x2700 Table sequence data setup register for StepGen 0 0x2704 Table sequence data setup register for StepGen 1 0x2708 Table sequence data setup register for StepGen 2 0x270C Table sequence data setup register for StepGen 3 0x2710 Table sequence data setup register for StepGen 4 0x2714 Table sequence data setup register for StepGen 5 0x2718 Table sequence data setup register for StepGen 6 0x271c Table sequence data setup register for StepGen 7 ... TableLength register: 4 bit register that determines table sequence length. Sequence length is TableLength+1, Maximum length is 16 steps 0x2800 Table sequence length register for StepGen 0 0x2804 Table sequence length register for StepGen 1 0x2808 Table sequence length register for StepGen 2 0x280C Table sequence length register for StepGen 3 0x2810 Table sequence length register for StepGen 4 0x2814 Table sequence length register for StepGen 5 0x2818 Table sequence length register for StepGen 6 x281c Table sequence length register for StepGen 7 ... 0x2900 32 bit master DDS for all stepgens (compile time option, may be disabled) Step generator addition rate is (ClockLow*MasterDDSVal/2^32) Probably just set to 0xffffffff for playing with QuadratureCounter Type 2 (with timestamp) 32 bit register: bottom 16 bits are count, top 16 bits are timestamp of last change Writes to counter register clear the counter. 0x3000 quad counter 0 0x3004 quad counter 1 0x3008 quad counter 2 0x300C quad counter 3 0x3010 quad counter 4 0x3014 quad counter 5 0x3018 quad counter 6 0x301c quad counter 7 ... The time stamp allows reciprocal time (DeltaCount/DeltaTime) velocity calculation for better estimation of motor velocity at low counts/sample interval QuadratureCounter latch/Control register 32 bit register: top 16 bits are latched (by index) count, bottom 16 bits is control register 0x3100 quad counter latch/CCR 0 0x3104 quad counter latch/CCR 1 0x3108 quad counter latch/CCR 2 0x310C quad counter latch/CCR 3 0x3110 quad counter latch/CCR 4 0x3114 quad counter latch/CCR 5 0x3118 quad counter latch/CCR 6 0x311c quad counter latch/CCR 7 ... Bit 31..16 = Latched count (Latch on index) Bit15 Quad Error: set if quadrature sequence error Bit14 AB mask polarity: A*B must be high for index gate Bit13 xx Bit12 xx Bit11 Quad filter (0=3 clocks 1=15 clocks) Bit10 CounterMode 0 = Quadrature, 1 = up/down Bit9 UseIndexMask 1= use mask Bit8 IndexMask Polarity 1=active high Bit7 ABgateIndex 1=gate index signal with A,B Bit6 JustOnce 1= ClearOnIndex or LatchOnIndex happen only once Bit5 ClearOnIndex 1=Clear count on index Bit4 LatchOnIndex 1=Latch count on index Bit3 IndexPol 1 = active high Bit2 read = realtime index signal Bit1 read only realtime B signal Bit0 read only realtime A signal 0x3200 TSSDiv 16 bit time stamp programmable divider (in LSBs) (R\W) Sets quadrature counter reference clock for timestamp. Timestamp count rate is ClockLow/(TSDiv+2). Any divisor with MSB set = divide by 1 0x3300 TSCount 16 bit time stamp counter (read only) 0x3400 QfilterRate 12 bit Quadrature counter filter rate count rate is ClockLow/(QFilterRate+2). Any divisor with MSB set = divide by 1 Notes about quadrature filter rate: QFilterRate sets the sampling rate for all quadrature counters input filters. Input filtering should be set with as long a time constant as possible, especially when using TTL encoders. The time constant chosen should give a fair (say 30%) margin of quadrature counter maximum count rate above the hardwares maximum possible count rate. For example with a 33MHz ClockLow and QfilterRate = 0xFFF (divide by one): With the filter bit off, the the input filter requires 3 clocks to recognize an input change = ~90 nS. This gives a maximum input frequency of 1/180 nS = ~5MHz or a maximum quadrature (4X) count rate of ~ 20MHz With the filter bit on, the the input filter requires 15 clocks to recognize an input change = ~450 nS. This gives a maximum input frequency of 1/900 nS = ~1.1MHz or a maximum quadrature (4X) count rate of ~ 4.4 MHz This is still much faster than needed for most applications so the QFilterRate register allows lowering the filter sample rate. For example with the Qfilterrate register set to divide by 10 (QFilterRate loaded with 8), the input filter sample rate at 33 MHz ClockLow would be 3.3 MHz: With the filter bit off, the the input filter requires 3 clocks to recognize an input change = ~900 nS. This gives a maximum input frequency of 1/1800 nS = ~500 KHz or a maximum quadrature (4X) count rate of ~ 2MHz With the filter bit on, the the input filter requires 15 clocks to recognize an input change = ~4500 nS. This gives a maximum input frequency of 1/9000 nS = ~110 KHz or a maximum quadrature (4X) count rate of ~ 440 KHz 440 KHz is adequate for most normal applications = 13200 RPM with a 500 line (2000 count) encoder, and has the benefit that noise rejection is very good, input noise pulses less than 4500 nS will be ignored. Most PWM generated noise pulses tend to be short, determined by the PWM voltage and the time constant of the PWM to encoder wire capacitance and the encoder output resistance. This output resistance is often quite high in low cost TTL encoders, with outputs that are just open collector comparators with pullup resistors. These encoders are very susceptible to low going noise pulses, and benefit greatly by maximizing the filter time constant. PWM generators (With FPGA compile time constant PWM width = 13) 0x4000 PWMVal 0 Right justified 9..12 bit PWM in bits 27..16 DIR is bit 31 0x4004 PWMVal 1 Right justified 9..12 bit PWM in bits 27..16 DIR is bit 31 0x4008 PWMVal 2 Right justified 9..12 bit PWM in bits 27..16 DIR is bit 31 0x400C PWMVal 3 Right justified 9..12 bit PWM in bits 27..16 DIR is bit 31 0x4010 PWMVal 4 Right justified 9..12 bit PWM in bits 27..16 DIR is bit 31 0x4014 PWMVal 5 Right justified 9..12 bit PWM in bits 27..16 DIR is bit 31 0x4018 PWMVal 6 Right justified 9..12 bit PWM in bits 27..16 DIR is bit 31 0x401C PWMVal 7 Right justified 9..12 bit PWM in bits 27..16 DIR is bit 31 ... PWM mode registers 6 bits Bit 1,0 = width select (With FPGA compile time constant PWM width = 13) 00 = 9 bit PWM 01 = 10 bit PWM 10 = 11 bit PWM 11 = 12 bit PWM Bit 2 = PWM mode select 0 = Straight (Sawtooth) PWM 1 = Symmetrical (Triangle) PWM Bit 4,3 = PWM output mode select 00 = Normal Sign Magnitude PWM&DIR outputs normal 01 = Normal Sign Magnitude PWM&DIR outputs swapped (for locked antiphase) 10 = Up/down mode 11 = PDM mode (12 bits) Bit 5 = Double Buffered mode When bit 5 is set, the PWMval register is not updated until the beginning of a PWM cycle, avoiding extra transitions in the output PWM waveform. This adds an extra delay of 0 to PWMWidth/PWMClock (normal mode) or PWMWidth*2/PWMClock (Symmetrical mode) between when the host writes the PWMVal register and the PWM output is updated. 0x4100 PWM mode select register 0 0x4104 PWM mode select register 1 0x4108 PWM mode select register 2 0x410C PWM mode select register 3 0x4110 PWM mode select register 4 0x4114 PWM mode select register 5 0x4118 PWM mode select register 6 0x411C PWM mode select register 7 ... 0x4200 16 bit PWM gen master rate DDS (PWMCLOCK = CLKHIGH*Rate/65536) PWM rate will be PWMCLOCK/(2^PWMBITS) for normal PWM and PWMCLOCK/(2^(PWMBITS+1)) for symmetrical mode PWM. 0x4300 16 bit PDM gen master rate DDS (PDMCLOCK = CLKHIGH*Rate/65536) PDM rate will be PDMCLOCK/(4096). 0x4400 Enable register for PWM. Doesn't actually change PWM but is used for enabling PWM driven devices (the ENA pin). 1 bit per PWM channel. Active high --> '1' means enabled = '0' output pin level. Bit 0 PWM channel 0 enable Bit 1 PWM channel 1 enable Bit 2 PWM channel 2 enable PWM/PDM Notes: 1. For 7I33 and 7I33T that filter the PWM to generate analog voltages, PDM mode should be used. Optimum PDM rate for best trade-off between ripple and linearity for 7I33 and 7I33T is about 6 MHz (PDM rate register approx 0x0fff) 2. Double buffering should be used where the PWM directly drives an HBridge. Double buffering prevents extra transitions on the PWM output which waste power in switching losses. Double buffering should _not_ be used with PDM output! UART TX data register Different offsets push different numbers of bytes on xmit FIFO Didn't use byte enables for compatibility with other (non PCI) 32 bit interfaces 0x4500 UART TXdata 0 (push 1 byte) 0x4504 UART TXData 0 (push 2 bytes) 0x4508 UART TXData 0 (push 3 bytes) 0x450C UART TXData 0 (push 4 bytes) 0x4510 UART TXdata 1 (push 1 byte) 0x4514 UART TXData 1 (push 2 bytes) 0x4518 UART TXData 1 (push 3 bytes) 0x451C UART TXData 1 (push 4 bytes) 0x4520 UART TXdata 2 (push 1 byte) 0x4524 UART TXData 2 (push 2 bytes) 0x4528 UART TXData 2 (push 3 bytes) 0x452C UART TXData 2 (push 4 bytes) 0x4530 UART TXdata 3 (push 1 byte) 0x4534 UART TXData 3 (push 2 bytes) 0x4538 UART TXData 3 (push 3 bytes) 0x453C UART TXData 3 (push 4 bytes) ... UART TX FIFO count register = number slots used in FIFO, pushes less than one 32 bit word use a hole word slot, in other words, TX FIFO is 16 32 bit words deep, but 16 one byte pushes will fill, so TX FIFO capacity is 16 Bytes for byte pushes, but 64 bytes with 16 doubleword pushes. Writes to the FIFO count register clear the FIFO. 0x4600 UART TXFIFO Count 0 0x4604 UART TXFIFO Count 1 0x4608 UART TXFIFO Count 2 0x460C UART TXFIFO Count 3 ... TX Bitrate select register. TX bitrate is generated by a 16 bit phase accumulator. Bitrate is: TXBitrate/65536*ClockLow 0x4700 UART TX Bitrate Register 0 0x4704 UART TX Bitrate Register 1 0x4708 UART TX Bitrate Register 2 0x470C UART TX Bitrate Register 3 ... UART TX mode register controls TXEnable and TXEnable timing (for half duplex) Bit 0..3 are TXEnable delay. TXEnable delay specifies the transmit data holdoff time from the TXenable signal valid state. This is used for RS-485 (half duplex) operaton, to delay transmit data until the driver is enabled, allowing for driver enable delays, isolation barrier delays etc. Delay is in units of ClockLow period. Bit 4 is DriveEnableAuto, When set, enables Drive when any data is in FIFO or Xmit Shift register,removes drive when FIFO and Xmit shift register are empty. Bit 5 is DriveEnableBit, If DriveEnableAuto is 0, controls Drive ( for software control of Xmit drive) 0x4800 UART TX Mode register 0 0x4804 UART TX Mode register 1 0x4808 UART TX Mode register 2 0x480c UART TX Mode register 3 ... UART RX Data register, Different offsets pop different numbers of bytes from RX FIFO, data is always right justified. FIFO depth is 16 bytes. I may eventually change this to use byte enables. 0x4900 UART RX Data 0 (POP 1 byte) 0x4904 UART RX Data 0 (POP 2 bytes) 0x4908 UART RX Data 0 (POP 3 bytes) 0x490C UART RX Data 0 (POP 4 bytes) 0x4910 UART RX Data 1 (POP 1 byte) 0x4914 UART RX Data 1 (POP 2 bytes) 0x4918 UART RX Data 1 (POP 3 bytes) 0x491C UART RX Data 1 (POP 4 bytes) 0x4910 UART RX Data 2 (POP 1 byte) 0x4914 UART RX Data 2 (POP 2 bytes) 0x4918 UART RX Data 2 (POP 3 bytes) 0x491C UART RX Data 2 (POP 4 bytes) 0x4910 UART RX Data 3 (POP 1 byte) 0x4914 UART RX Data 3 (POP 2 bytes) 0x4918 UART RX Data 3 (POP 3 bytes) 0x491C UART RX Data 4 (POP 4 bytes) ... UART RX FIFO count register = number of bytes in RX FIFO Writes to the RX FIFO count register clear RX FIFO 0x4A00 UART RXFIFO Count 0 0x4A04 UART RXFIFO Count 1 0x4A08 UART RXFIFO Count 2 0x4A0C UART RXFIFO Count 3 ... UART RX Bitrate select register. RX bitrate is generated by a 16 bit phase accumulator. Bitrate is RXBitrate/65536*ClockLow 0x4B00 UART RX Bitrate Register 0 0x4B04 UART RX Bitrate Register 0 0x4B08 UART RX Bitrate Register 0 0x4B0C UART RX Bitrate Register 0 ... RX MODE/STATUS Register Bit 0 = FalseStart bit Status, 1 = false start bit detected Bit 1 = OverRun Status, 1 = overun condition detected Bit 2 = RXMaskEnable, 1= enable RXMask for half duplex operation, 0 = ignore RXMask Bit 6 = RXMask, RO RXMASK status Bit 7 = FIFO Has Data 0x4C00 UART RX Mode/Status register 0 0x4C04 UART RX Mode/Status register 1 0x4C08 UART RX Mode/Status register 2 0x4C0C UART RX Mode/Status register 3 ... Notes: 1. RXMaskEnable uses the transmitters TXEN as a mask to the character receive logic. This is so that when 2 wire RS-485 type interfaces are used, the transmit data ia not echoed back to the receiver SPI SREG 32 bits Writes here load shift register and start frame transmission 0x5000 SPI SREG 0 0x5004 SPI SREG 1 0x5008 SPI SREG 2 0x500C SPI SREG 3 0x5010 SPI SREG 4 0x5014 SPI SREG 5 ... SPI bit count register Bits 0..5 = bits per SPI frame (bits = N+1) ie 0x1f = 32 bit frame Bit 6 = CPOL = Clock polarity ( FreeScale SPI spec compatible definitions) Bit 7 = CPHA = Clock Phase Bit 31 = DAV = data ready Bit 30 = Busy 0x5100 SPI bit count register 0 0x5104 SPI bit count register 1 0x5108 SPI bit count register 2 0x510C SPI bit count register 3 0x5110 SPI bit count register 4 0x5114 SPI bit count register 5 ... SPI bit rate register Bits 0..7 = programmable divider, SPI bit rate is (N+1)*2 Maximum rate (N=0) is 24 MHz (5I22 with 48 MHz clock) or 16.66 (5I20 with 33 MHz clock Minmum rate (N=255) is 93.75 KHz (48 MHz clock) or ~65 KHz (33 MHz clock) 0x5200 SPI bit rate register 0 0x5204 SPI bit rate register 1 0x5208 SPI bit rate register 2 0x520C SPI bit rate register 3 0x5210 SPI bit rate register 4 0x5214 SPI bit rate register 5 ... Address Translation RAM (8/16 bit interfaces only = EPP, USB and PC/104) The address translation RAM is used to eliminate expensive address cycles when addressing hardwired sequences of non-contiguous bytes. The address RAM give indirect access to all internal registers. Translation RAM, 256 deep by 16 bit wide address translation RAM 0x7800 Translation RAM byte address 0 0x7804 Translation RAM byte address 1 ... 0x7BFC Translation RAM byte address 255 Data in translation RAM is LS 16 bits (MS 16 bits are unused) of 32 bit word. Bit 15 is StrobeBit. For read sequences, the StrobeBit must be OR'ed with the first translation RAM address entry of a read sequence, for write sequences, the StrobeBit must be OR'ed with the last translation RAM address of the write sequence. To use address translation, there is a 256 byte window where addresses are translated: 7C00 Translation region byte 0 (controlled by Translation RAM address @ 0x7800 7C01 Translation region byte 1 (controlled by Translation RAM address @ 0x7804 ... 7CFF Translation region byte 255 (controlled by Translation RAM address @ 0x7BFC Here is an example of using address translation (With EPP) to write one 24 bit I/O port, read the next 24 bit I/O port and read and 4 quadrature counters, skipping the timestamp, and update 4 PWM generators. First initialize the translation RAM (Only done once at program startup) write32 0x7800 0x1000 First byte of port write write32 0x7804 0x1001 Second byte of port write write32 0x7808 0x9002 Third byte of port write (Note: OR'ed with StrobeBit) write32 0x780C 0x9004 First byte of read (Note OR'ed with StrobeBit) write32 0x7810 0x1005 Second byte of read write32 0x7814 0x1006 Third byte of read write32 0x7818 0xB000 First byte of Qcounter0 (Note: OR'ed with StrobeBit) write32 0x781C 0x3001 Second byte of Qcounter0 write32 0x7820 0xB004 First byte of Qcounter1 (Note: OR'ed with StrobeBit) write32 0x7824 0x3005 Second byte of Qcounter1 write32 0x7828 0xB008 First byte of Qcounter2 (Note: OR'ed with StrobeBit) write32 0x782C 0x3009 Second byte of Qcounter2 write32 0x7830 0xB00C First byte of Qcounter3 (Note: OR'ed with StrobeBit) write32 0x7834 0x300D Second byte of Qcounter3 write32 0x7838 0x4002 First byte of PWMGen0 (in MS word) write32 0x783C 0xC003 Second byte of PWMGen0 (in MS word) (Note: OR'ed with StrobeBit) write32 0x7838 0x4004 First byte of PWMGen1 (in MS word) write32 0x783C 0xC005 Second byte of PWMGen1 (in MS word) (Note: OR'ed with StrobeBit) write32 0x7838 0x4008 First byte of PWMGen2 (in MS word) write32 0x783C 0xC009 Second byte of PWMGen2 (in MS word) (Note: OR'ed with StrobeBit) write32 0x7838 0x400C First byte of PWMGen3 (in MS word) write32 0x783C 0xC00D Second byte of PWMGen3 (in MS word) (Note: OR'ed with StrobeBit) Once these 22 address translation table entries are initialized, the following sequence of EPP operations will do all the data transfers: writeaddr 0x00 writeaddr 0xFC This sets up the 16 bit EPP address as 0xFC00 = translation region (0x7C00) with auto-inc (0x8000) writedata write port 0 Byte 0 writedata write port 0 Byte 1 writedata write port 0 Byte 2 readdata read Port 1 byte 0 readdata read Port 1 byte 1 readdata read Port 1 byte 2 readdata read Qcounter 0 byte 0 readdata read Qcounter 0 byte 1 readdata read Qcounter 1 byte 0 readdata read Qcounter 1 byte 1 readdata read Qcounter 2 byte 0 readdata read Qcounter 2 byte 1 readdata read Qcounter 3 byte 0 readdata read Qcounter 3 byte 1 writedata write PWMVal 0 byte 0 writedata write PWMVal 0 byte 1 writedata write PWMVal 1 byte 0 writedata write PWMVal 1 byte 1 writedata write PWMVal 2 byte 0 writedata write PWMVal 2 byte 1 writedata write PWMVal 3 byte 0 writedata write PWMVal 3 byte 1 Notes: For compatibility reasons, basic register access is still 32 bits even with address translation so a 32 bit write is always done even if only a single byte is written. This is usually not important, but does have some subtle side effects. For example if a 24 bit wide I/O port is defined with 16 input bits and 8 output bits (say to interface with a 7I37), the 8 output bits can be updated in a single byte write thats part of a sequence in the translation RAM. The side effect of this is that the 16 unused output bits that coorespond to the input bits on the port _will_ be written with random data.