TSK3000A Special Function Registers
Special Function Registers (SFRs) in the TSK3000A are implemented as COP0 registers (Coprocessor 0). They can be read and written (where possible) in a single instruction cycle using the MFC0 and MTC0 instructions, respectively.
Table 1 summarizes the special function registers for the TSK3000A.
Register | Name | Description | Read | Write | Index |
---|---|---|---|---|---|
Control/Status | Status | Individual Control and Status bits | Yes | Yes | $0 |
Interrupt Enable | IEnable | Enable/Disable individual interrupts | Yes | Yes | $1 |
Interrupts Pending | IPending | View of the interrupt values after individual enable gating (i.e. interrupts that are pending or yet to be handled) | Yes | Yes | $2 |
Time Base Low | TBLO | Least significant 32-bits of the 64-bit time base | Yes | No | $3 |
Time Base High | TBHI | Most significant 32-bits of the 64-bit time base | Yes | No | $4 |
Programmable Interval Timer Limit | PIT | Interval length (in clock cycles) of the interval timer | Yes | Yes | $5 |
Debug Data | Debug | Register for OCDS to exchange data with the processor | Yes | Yes | $6 |
Exception Return | ER | Register in which to store the return address for interrupts and exceptions | Yes | Yes | $7 |
Exception Base | EB | Specifies base address for the interrupt vector table | Yes | Yes | $8 |
Interrupt Mode | IMode | Configures interrupt input pins to operate as either level-sensitive or edge-triggered | Yes | Yes | $9 |
Control/Status Register (Status)
This 32-bit register (COP0-$0) is used to control aspects of the processor's operation and to determine the current state of the processor. Only bits 0..15 are currently used. All other bits are reserved for future use.
After a reset, this register is initialized to 0000_0000h
.
MSB LSB | ||||||||||||
31 16 | 15 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
- | Interrupt Priority | ACK | VIE | ITE | ITR | 0 | UMo | IEo | UMp | IEp | UMc | IEc |
Bit | Symbol | Function |
---|---|---|
Status.31..Status.16 | - | Reserved for future use |
Status.15..Status.11 | Interrupt Priority | Shows the value for the current priority vector based on the current interrupt inputs |
Status.10 | ACK | Acknowledgment flag – used to indicate whether a time-out has occurred on one of the processor's Wishbone interfaces: |
Status.9 | VIE | Vectored Interrupt Enable. Use this bit to determine the current interrupt mode: |
Status.8 | ITE | Interval Timer Enable. This bit serves effectively as both an enable and a reset. When this bit is zero, the Interval Timer is held at zero. When set to one, the Timer is enabled and starts to count up |
Status.7 | ITR | Interval Timer (interrupt) Reset. When this bit is set High it clears the interrupt flag for the Interval Timer. Holding this bit High will prevent interrupts by breaking the link between the Interval Timer and the interval limit stored in the PIT register. Therefore if the Interval Timer is enabled (ITE = 1), the Interval Timer will just keep counting up, overflow, wrap-around and so on. |
Status.6 | 0 | Reserved – always set to zero |
Status.5 | UMo | User Mode – Old. Indicates the user mode from two exceptions ago |
Status.4 | IEo | Interrupt Enable – Old. Indicates the interrupt mode from two exceptions ago |
Status.3 | UMp | User Mode – Previous. Indicates the user mode prior to the last exception |
Status.2 | IEp | Interrupt Enable – Previous. Indicates the interrupt mode prior to the last exception |
Status.1 | UMc | User Mode – Current. Controls whether the Processor is in user mode or not. |
Status.0 | IEc | Interrupt Enable – Current. Controls whether interrupts are globally enabled or not. This bit is saved and then set by any interrupt or trap (SYSCALL) and restored to its previous state by the RFE (restore from exception) instruction. |
Interrupt Enable Register (IEnable)
This 32-bit register (COP0-$1) allows individual interrupts to be enabled or disabled. Each bit corresponds to a single interrupt. Setting a bit High will enable interrupts on the correspondingly numbered interrupt input.
After a reset, this register is initialized to 0000_0000h
, effectively disabling all interrupts.
Interrupts Pending Register (IPending)
This 32-bit register (COP0-$2) provides a view of the interrupt values after individual interrupt enable gating. The corresponding bit for an interrupt in this register will therefore only be High if both an interrupt is present at that interrupt input AND the corresponding bit for that interrupt in the IEnable register is also High.
When an interrupt input is configured to operate as edge-triggered, then once an edge has occurred it must be cleared, to allow the detection of another edge. This is accomplished by writing a '1' to the corresponding bit in the IPending register.
An activated edge-triggered interrupt will appear as pending in the IPending register until it is cleared using this method.
After a reset, this register is initialized to 0000_0000h
.
Time Base (TBLO & TBHI)
The time base is a 64-bit counter that increments once every clock cycle. As the counter cannot be written to, it always maintains the cycle count since the last reset.
The time base is implemented as a pair of 32-bit Read-only registers:
- TBLO (COP0-$3) – least significant 32 bits of the counter
- TBHI (COP0-$4) – most significant 32 bits of the counter.
At 50MHz, the time base will roll over once every 11,699 years, making it suitable for long term time management purposes.
The time base never generates any interrupts.
After a reset, the time base registers are initialized to 0000_0000h
.
Reading the Time Base
As the 64-bit time base can only be read using two separate instructions, special precautions need to be taken in order to read it. This is due to the fact that it is possible for the low 32-bits to roll over (thereby incrementing the TBHI register) as the value in TBHI is being read. This will happen when the TBLO register rolls over from FFFF_FFFFh
to 0000_0000h
.
To avoid this problem, read the value in the TBHI register before and after reading the value in the TBLO register, and compare the two to check for rollover. If rollover has occurred, simply provide looping in the code to re-read the register values. An example of such coding is shown below:
Loop:
mfc0 $2,TBHI ; Read TBHI
mfc0 $3,TBLO ; Read TBLO
mfc0 $4,TBHI ; Read TBHI again
bne $2,$4,Loop ; Check for TBU rollover by comparing old and new
; Read again if a rollover occurred
Programmable Interval Timer Limit Register (PIT)
This 32-bit register (COP0-$5) is used to control how high the interval timer will count before being reset to zero and (optionally) generating an interrupt.
Programming a value into this register will cause the timer to be reset to zero and to generate an interrupt (if enabled) every time the specified count is reached. For example, if the system clock is running at 50MHz, programming this register with decimal 50,000 will generate an interrupt once every millisecond.
The value written to this register will remain unchanged until either a system reset (RST_I High) or the register is written with a new value by the application software.
After a system reset, this register is initialized to FFFF_FFFFh
.
Reading the Programmable Interval Limit
The current value for the Programmable Interval Limit can be read from the PIT register using the MFC0 command and storing the value in an appropriate general purpose register, as illustrated by the example code below:
mfc0 $2,PIT ; Read PIT to GPR 2
Writing the Programmable Interval Limit
Writing a value for the Programmable Interval Limit to the PIT register is a two-instruction process. Firstly, you need to write the required interval value to a general purpose register and then write the contents of that register to the PIT register, using the MTC0 instruction, as illustrated by the example code below:
li $2,50000 ; Load GPR 2 with 50,000 for 1 ms interval at 50 MHz
mtc0 $2,PIT ; Write contents of GPR 2 to the PIT register
Debug Data Register (Debug)
This 32-bit register (COP0-$6) is used by the debug system to exchange data between the debugger and the processor. This is the only register that is both a JTAG register and a processor register and is therefore visible and writeable to by both. However, there should be no need to access this register.
After a reset, this register is initialized to 0000_0000h
.
Exception Return Register (ER)
This 32-bit register (COP0-$7) is used by the processor to store the return address for interrupts and exceptions.
After a reset, this register is initialized to 0000_0000h
.
Exception Base Register (EB)
This 16-bit register (COP0-$8) specifies the address, within the first 64K of memory, for the base of the interrupt vector table. When using interrupts in standard mode, this specifies the common vector for all interrupts and exceptions.
The default value for this register is 0000_0100h
and is initialized to this value after a reset.
Interrupt Mode Register (IMode)
This 32-bit register (COP0-$9) is used to configure each of the individual interrupt inputs to operate either as edge-sensitive or level-sensitive:
- Set IMode.n High for edge-triggered operation (active on rising edge)
- Set IMode.n Low for level-sensitive operation (active High)
Level-sensitive operation is the default (i.e. all bits of the register set to 0).
After a reset, this register is initialized to 0000_0000h
.