 |
The following is a description of
the TS-XDIO port. This core is designed
to implement common controller tasks
that are difficult, costly (CPU intensive),
or impossible to accomplish in software
with regular DIO / GPIO hardware and
the facilities of the 200Mhz ARM processor.
The TS-XDIO core is a GPIO core with "eXtended Digital I/O" functionality
including pulse-width modulation, quadrature
and edge counting, and pulse timing with
IRQ/DRQ support. Each core uses around
231 FPGA logic cells on Altera architectures.
There are two TS-XDIO cores in the TS-7300
SBC and one in the TS-7260 SBC. TS-XDIO
programming is done via eight-bit accesses
starting at the BASE physical memory
address listed for each respective core
below. There are four memory locations
for each core, corresponding to BASE+0,
BASE+1, BASE+2, and BASE+3.
|
Core 1
BASE
Address |
Core 2
BASE
Address |
IRQ |
FAST Clock |
SLOW Clock |
| TS-7260 |
0x12C00000 |
N/A |
32 |
68ns / 14.7456 Mhz |
30518ns / 32.7680 Khz |
| TS-7300 |
0x72000040 |
0x72000044 |
40 |
13ns / 75.0000 Mhz |
26667ns / 37.5000 Khz |
TS- XDIO port features:
- 8-pins, individually programmable
as schmitt-trigger inputs, outputs,
or special functions (3.3V levels)
- glitch-detector (all pins) to catch
edges/pulses as short as one fast clock
period without continuous software
polling
- edge-counter/frequency meter (pin
7) max incoming clock period of one-half
the core clock frequency
- quadrature counter (pins 6,7) with
max increment / decrement rate of one-half
the maximum edge-counter frequency
- Pin 5 can optionally be used as an
index pulse for resetting the edge
counter or quadrature counter to 0
- PWM (pulse width modulation) output
on pin 4 with period between two fast
clock periods and 8190 slow clock periods,
with 0.02% duty cycle precision
- One-shot programmable high or low
output pulse (pin 5) of duration between
one fast clock period and 4095 slow
clock periods
- pulse / period timer (any pin) can
measure high/low pulse time or full
period lengths at fast clock period
resolution
Register Map:
Base Address Register
| Bits |
Description |
Function |
| bits 7-6 |
MODE |
selects what registers 1-3 are |
| bits 5-4 |
PTMODE |
select pulse timer mode and polarity |
| bit 3 |
PTRST |
pulse timer reset (W)
or waiting for trailing edge (R) |
| bit 2 |
QUADEN |
quadrature enable /
edge counter disable |
| bit 1 |
START |
PWM enable / pulse start |
| bit 0 |
CLKRATE |
clock select (0 - fast,
1 - slow) |
Base Address Register Bits 7-6
| Value |
Mode |
| 0 |
pin direction, data register, and
IRQ / DRQ control |
| 1 |
edge / quadrature counter and glitch
monitor |
| 2 |
input pulse timer and pin select |
| 3 |
PWM / pulse high / low-time set |
Base Address Register Bits 5-4
| Value |
Mode |
| 0 |
negedge to posedge (low pulse time) |
| 1 |
posedge to negedge (high pulse time) |
| 2 |
negedge to negedge (period time) |
| 3 |
posedge to posedge (period time) |
Registers 1-3 Depend on Mode:
Mode 0
| Address |
Bits |
Description |
Function |
| Base+1 |
7-0 |
DIR |
DIO direction register
(1 - output, 0 - input) |
| Base+2 |
7-0 |
DATA |
DIO data register |
| Base+3 |
7 |
DRQ |
drq select (1 - drq, 0 -
irq) |
| 6 |
|
reserved (may be used in customer
specific TS-XDIO cores) |
| 5 |
IRQ_IP |
irq/drq on quadrature
/ edge counter index pulse (if enabled) |
| 4 |
IRQ_PT |
irq/drq on pulse timer
trailing edge |
| 3 |
IRQ_GLITCH_4_7 |
irq/drq on pin
glitch (pins 4-7) |
| 2 |
IRQ_GLITCH_0_3 |
irq/drq on pin
glitch (pins 0-3) |
| 1 |
IRQ_OF |
irq/drq on quadrature
/ edge overflow / underflow |
| 0 |
IRQ_CD |
irq/drq on quadrature
change direction |
Mode 1
| Address |
Bits |
Description |
Function |
Base+1
(glitch monitor) |
7 |
IP_EN_5 |
enable index pulse on
pin 5 (1 - reset counter on edge) |
| 6-0 |
GLITCH |
1 - glitch detected
on pin, 0 - inactive since last read
(cleared on read or write) |
| Base+2 |
7-0 |
QCTR_LO |
bits 7-0 of edge
/ quadrature counter |
| Base+3 |
7-0 |
QCTR_HI |
bits 15-8 of edge
/ quadrature counter |
Mode 2
| Address |
Bits |
Description |
Function |
Base+1
(pin select / timer) |
7 |
PT_ACC |
pulse time accumulate
- keeps on running adding pulse times |
| 6-4 |
INPNO |
input pin number (0-7) |
| 3-0 |
PT_EX |
bits 19-16 of pulse
timer |
| Base+2 |
7-0 |
PT_LO |
bits 7-0 of pulse
timer |
| Base+3 |
7-0 |
PT_HI |
bits 15-8 of pulse
timer |
Mode 3
| Address |
Bits |
Description |
Function |
| Base+1 |
7-4 |
THI_HI |
bits 11-8 of high
time |
| 3-0 |
TLO_HI |
bits 11-8 of low time |
| Base+2 |
7-0 |
THI_LO |
bits 7-0 of high
time |
| Base+3 |
7-0 |
TLO_LO |
bits 7-0 of low
time, oneshot mode enabled if all zeros
(In one-shot mode, pulse polarity is
inversion of DATA bit 4 In either case,
actual high time and/or low time is one
clock longer then specified by these
registers) |
Programming Notes
- If quadrature index pulse is enabled,
counter is reset on positive edge of
index pulse if DIO data register bit
5 is set 0, negative edge if set 1
- Pulse width modulation (PWM) time
is 2 + high / low time clock periods
of 14.7456Mhz or 32Khz
- If using pulse width modulation (PWM)
in oneshot mode (single pulse) type
is high pulse (low-high-low) if DIO
data register bit 4 is set 0, low pulse
(high-low-high) if set 1.
- Can use 20-bit pulse timer as free-running
timer by setting accumulate bit and
setting pin select to PWM (pulse width
modulation) output (pin 5). 14.7456Mhz
counter can be enabled by watching
periods, slower free running counters
can be had by clever use of high-time
and low-time PWM and accumulating pulse
times. (e.g. high-time 1, low-time
224 creates a 65.536Khz free-running
timer that overflows once every 16
seconds)
- Edge counter counts *both* edges
of waveform, divide by 2 for number
of periods / frequency. To count X
edges and then interrupt, preload counter
value with 2^16 - X and enable IRQ
on overflow.
- Max / min quadrature count can be
gotten by enabling IRQ / DRQ on quadrature
change of direction. Max / Min is value
-/+ 1 as long as IRQ / DRQ latency
is less than 1 quadrature cycle time.
- Core does not reset-- registers and
state remain if board undergoes reset.
On power-up DIO data direction register
is all 0's (inputs), but other register
contents are undefined.
C API for TS-XDIO
struct xdio;
Contains information and state for an
initialized XDIO core.
open_xdio(struct xdio *x,int
num);
Pass this function a pointer to an uninitialized
xdio structure. Returns true on success.
The "num" parameter is the zero-index
core number to open.
void close_xdio(struct xdio
*x);
Call this function to release the resources
associated with an XDIO core.
int setClockSpeed(xdio *x,int
fast);
Each XDIO core can be set to one of two
clock speeds: SLOW and FAST. The actual
clock period of each of these speeds
depends on the model; this function returns
the clock period in nanoseconds for the
speed selected.
void setPinDirection(xdio *x,int
pin,enum PIN_DIRECTION dir);
Each XDIO pin can be configured as either
an input or as an output. Input pins
are pulled high when nothing else is
connected. Use this function to set the
zero-indexed pin number to either INPUT
or OUTPUT. Be aware that some functions
automatically set certain pins to a specific
direction.
void setPin(xdio *x,int pin,enum
PIN_VALUE val);
Call this function to set the output
value of the given pin to either LOW
or HIGH. In some cases this call will
not make sense, such as when the pin
is an input, or under the control of
another function.
int getPin(xdio *x,int pin);
This function returns the current state
of the specified pin, as either LOW
(0) or HIGH (1).
void initPulseTimer(xdio *x,int
pin,int acc,enum PULSE_TYPE ptype);
Prepare the pulse timer to begin sampling
pulses on the specified pin. It is not
required that the specified pin be an
input. Pass a true value for the "acc" parameter
if you wish pulse times to be accumulated
across each pulse, instead of only timing
the last pulse. The acceptable pulse
types are:
PULSE_LOW_TIME (same as NEGEDGE_TO_POSEDGE)
PULSE_HIGH_TIME (same as POSEDGE_TO_NEGEDGE)
PULSE_PERIOD_LOW (same as NEGEDGE_TO_NEGEDGE)
PULSE_PERIOD_HIGH (same as POSEDGE_TO_POSEDGE)
long long getPulseTimer(xdio
*x,int sync,int reset);
Get the current value of the pulse type,
optionally waiting for the end of the
current pulse (may wait indefinitely)
and optionally resetting the value of
the pulse timer after it is read. The
value returned is the number of nano-seconds
(rounded to the previous clock period)
the pulse timer measured for the latest
pulse, or, if "acc" was set, the sum
of all pulse times since last reset.
int pinLevelChanged(xdio *x,int
pin);
Returns true if the specified pin has
changed state since the last time this
function was called for the given pin,
and false otherwise.
void generatePulse(xdio *x,long
long forNs);
Generate a single pulse on pin 4. The
current state of the pin will be inverted
for the specified number of nano-seconds,
rounded to the clock period, after which
the pin's state will be returned to its
original value.
int startPWM(xdio *x,int freq,int
microDutyCycle);
Generates a square wave on pin 4 with
the given frequency in Hz (rounded to
the nearest frequency attainable with
the current clock speed) and duty cycle
expression as 10,000ths of a percent.
This pulse-wave modulation occurs continuously
until stopped. This function will return
true on success, or false if an invalid
parameter value was passed, such as a
frequency outside of the range of the
current clock speed, or no duty cycle.
void pausePWM(xdio *x);
Stop generating PWM output on pin 4.
The characteristics of the waveform
are retained.
void resumePWM(xdio *x);
Resume generating PWM output on pin 4
using the current waveform characteristics.
You should not call this function until
the function startPWM has been called.
void initCounter(xdio *x,enum
COUNTER_TYPE type,enum INDEX_TYPE index);
Configure the counter type to either
EDGE_COUNTER (counts edges on pin 7)
or QUADRATURE (counts up/down based on
pin 6/7 quadrature input). The index
types are either NO_RESET (do not reset
the counter implicitly) or NEGEDGE_RESET
or POSEDGE_RESET (reset the counter on
the respective edge on pin 5).
int getQCTR(xdio *x);
Returns the current count of the edge/quadrature
counter.
void setQCTR(xdio *x,int v);
Sets the edge/quadrature counter to the
specified value. |