94 lines
5.2 KiB
Plaintext
94 lines
5.2 KiB
Plaintext
<<<
|
|
:sectnums:
|
|
==== General Purpose Timer (GPTMR)
|
|
|
|
[cols="<3,<3,<4"]
|
|
[frame="topbot",grid="none"]
|
|
|=======================
|
|
| Hardware source file(s): | neorv32_gptmr.vhd |
|
|
| Software driver file(s): | neorv32_gptmr.c |
|
|
| | neorv32_gptmr.h |
|
|
| Top entity port: | `gptmr_trig_i` | timer capture input
|
|
| Configuration generics: | `IO_GPTMR_EN` | implement general purpose timer when `true`
|
|
| CPU interrupts: | fast IRQ channel 12 | timer interrupt (see <<_processor_interrupts>>)
|
|
|=======================
|
|
|
|
|
|
**Overview**
|
|
|
|
The general purpose timer module implements a simple yet universal 32-bit timer. It is implemented if the processor's
|
|
`IO_GPTMR_EN` top generic is set `true`. The timer provides a pre-scaled counter register that can trigger an interrupt
|
|
when reaching a programmable threshold value. Additionally, a timer-capture feature is implemented that copies the current
|
|
counter value to a dedicated register if a programmable edge occurs at the `gptmr_trig_i` input signal.
|
|
|
|
Four interface registers are available: a control register (`CTRL`), a 32-bit counter register (`COUNT`), a 32-bit
|
|
threshold register (`THRES`) and a 32-bit read-only capture register (`CAPTURE`). The timer is globally enabled by setting the
|
|
`GPTMR_CTRL_EN` bit in the device's control register `CTRL`. When the timer is enable the `COUNT` register will start
|
|
incrementing at a programmable rate, which scales the main processor clock. The pre-scaler value is configured via the
|
|
three `GPTMR_CTRL_PRSCx` control register bits:
|
|
|
|
.GPTMR prescaler configuration
|
|
[cols="<4,^1,^1,^1,^1,^1,^1,^1,^1"]
|
|
[options="header",grid="rows"]
|
|
|=======================
|
|
| **`GPTMR_CTRL_PRSCx`** | `0b000` | `0b001` | `0b010` | `0b011` | `0b100` | `0b101` | `0b110` | `0b111`
|
|
| Resulting `clock_prescaler` | 2 | 4 | 8 | 64 | 128 | 1024 | 2048 | 4096
|
|
|=======================
|
|
|
|
[NOTE]
|
|
Disabling the timer will not clear the `COUNT` register. However, it can be manually reset at any time by
|
|
writing zero to it.
|
|
|
|
|
|
**Interval Timer**
|
|
|
|
Whenever the counter register `COUNT` reaches the programmable threshold value `THRES` the counter register
|
|
is reset to zero and the _timer-match_ flag `GPTMR_CTRL_TRIGM` gets set. This flag has to be cleared manually
|
|
by writing zero to it. Optionally, an interrupt can be triggered if the `GPTMR_CTRL_IRQM` bit is set.
|
|
|
|
|
|
**Timer Capture**
|
|
|
|
In addition to the the internal timer, the GPTMR provides a timer-capture feature. Whenever an edge is detected
|
|
at the `gptmr_trig_i` input signal the current `COUNT` value is copied to the read-only `CAPTURE` register and the
|
|
_capture-trigger_ flag `GPTMR_CTRL_TRIGC` gets set. This flag has to be cleared manually by writing zero to it.
|
|
Optionally, an interrupt can be triggered if the `GPTMR_CTRL_IRQC` bit is set.
|
|
|
|
The triggering edge can be a rising-edge (if `GPTMR_CTRL_RISE` is set), a falling-edge (if `GPTMR_CTRL_FALL` is
|
|
set) or even both. By default, the `gptmr_trig_i` is sampled two times at the processor clock for checking for
|
|
edges. This simple edge detection is sufficient for trigger signals that are generated by (on-chip) digital logic.
|
|
|
|
For sampling chip-external signals an optional filtering mode is available that can be enabled by the
|
|
`GPTMR_CTRL_FILTER` bit. If this bit is set, the `gptmr_trig_i` is sampled at a reduced clock speed (1/4 of the
|
|
processor clock) and the signal has to be stable for at lest 4 sample clock in order to be considered high or low.
|
|
This stabilized signal is then fed to the edge detection logic.
|
|
|
|
|
|
.Timer Interrupt
|
|
[NOTE]
|
|
Once triggered, the timer interrupt remains pending within the CPU until it explicitly cleared by writing zero
|
|
to the according <<_mip>> CSR bit.
|
|
|
|
|
|
**Register Map**
|
|
|
|
.GPTMR register map (`struct NEORV32_GPTMR`)
|
|
[cols="<4,<2,<4,^1,<7"]
|
|
[options="header",grid="all"]
|
|
|=======================
|
|
| Address | Name [C] | Bit(s), Name [C] | R/W | Function
|
|
.10+<| `0xfffff100` .10+<| `CTRL` <|`0` `GPTMR_CTRL_EN` ^| r/w <| Timer enable flag
|
|
<|`3:1` `GPTMR_CTRL_PRSC2 : GPTMR_CTRL_PRSC0` ^| r/w <| 3-bit clock prescaler select
|
|
<|`4` `GPTMR_CTRL_IRQM` ^| r/w <| Enable interrupt on timer-match
|
|
<|`5` `GPTMR_CTRL_IRQC` ^| r/w <| Enable interrupt on capture-trigger
|
|
<|`6` `GPTMR_CTRL_RISE` ^| r/w <| Capture on rising edge
|
|
<|`7` `GPTMR_CTRL_FALL` ^| r/w <| Capture on falling edge
|
|
<|`8` `GPTMR_CTRL_FILTER` ^| r/w <| Filter capture input
|
|
<|`29:9` - ^| r/- <| _reserved_, read as zero
|
|
<|`30` `GPTMR_CTRL_TRIGM` ^| r/c <| Timer-match has fired, cleared by writing 0
|
|
<|`31` `GPTMR_CTRL_TRIGC` ^| r/c <| Capture-trigger has fired, cleared by writing 0
|
|
| `0xfffff104` | `THRES` |`31:0` | r/w | Threshold value register
|
|
| `0xfffff108` | `COUNT` |`31:0` | r/w | Counter register
|
|
| `0xfffff10C` | `CAPTURE` |`31:0` | r/- | Capture register
|
|
|=======================
|