Skip to content

Commit

Permalink
[docs] update GPTMR section
Browse files Browse the repository at this point in the history
  • Loading branch information
stnolting committed Jul 4, 2024
1 parent 662f8a8 commit 31d1933
Showing 1 changed file with 25 additions and 47 deletions.
72 changes: 25 additions & 47 deletions docs/datasheet/soc_gptmr.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
| Hardware source files: | neorv32_gptmr.vhd |
| Software driver files: | neorv32_gptmr.c |
| | neorv32_gptmr.h |
| Top entity ports: | `gptmr_trig_i` | timer capture input
| Top entity ports: | none |
| Configuration generics: | `IO_GPTMR_EN` | implement general purpose timer when `true`
| CPU interrupts: | fast IRQ channel 12 | timer interrupt (see <<_processor_interrupts>>)
|=======================
Expand All @@ -18,14 +18,13 @@

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.
when reaching a programmable threshold value.l.

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:
The GPTMR provides three interface registers : a control register (`CTRL`), a 32-bit counter register (`COUNT`) and a
32-bit threshold register (`THRES`). The timer is globally enabled by setting the `GPTMR_CTRL_EN` bit in the module's
control register. When the timer is enable the `COUNT` register will start incrementing from zero at a programmable
rate that scales the main processor clock. this pre-scaler is configured via the three `GPTMR_CTRL_PRSCx`
control register bits:

.GPTMR prescaler configuration
[cols="<4,^1,^1,^1,^1,^1,^1,^1,^1"]
Expand All @@ -35,40 +34,24 @@ three `GPTMR_CTRL_PRSCx` control register bits:
| 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.
Whenever the counter register `COUNT` equals the programmable threshold value `THRES` the module's interrupt
signal becomes pending (indicated by `GPTMR_CTRL_IRQ_PND` being set). Note that a pending interrupt has to be
cleared manually by writing a `1` to `GPTMR_CTRL_IRQ_CLR`.

The control register's `GPTMR_CTRL_MODE` bit defines what will happen when `COUNT == THRES`.

**Timer Capture**
* `GPTMR_CTRL_MODE = 0`: **single-shot mode** - the `COUNT` register will stop incrementing
* `GPTMR_CTRL_MODE = 1`: **continuous mode** - the `COUNT` register is automatically reset and restarts incrementing from zero
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.
.Resetting the Counter
[NOTE]
Disabling the GPTMR will also clear the `COUNT` register.


**Interrupt**

The GPTRM provides a single interrupt line that can be trigger by a timer-match event and/or by a timer-compare
event. Once triggered, the interrupt will stay active until explicitly cleared by writing zero to the according
interrupt flag (`GPTMR_CTRL_TRIGM` or `GPTMR_CTRL_TRIGC`).
The GPTRM provides a single interrupt line is triggered whenever `COUNT` equals `THRES`. Once triggered, the interrupt will
stay pending until explicitly cleared by writing a 1 to `GPTMR_CTRL_IRQ_CLR`.


**Register Map**
Expand All @@ -78,17 +61,12 @@ interrupt flag (`GPTMR_CTRL_TRIGM` or `GPTMR_CTRL_TRIGC`).
[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
.6+<| `0xfffff100` .6+<| `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_MODE` ^| r/w <| Operation mode (0=single-shot, 1=continuous)
<|`29:5` - ^| r/- <| _reserved_, read as zero
<|`30` `GPTMR_CTRL_IRQ_CLR` ^| -/w <| Write `1` to clear timer-match interrupt; auto-clears
<|`31` `GPTMR_CTRL_IRQ_PND` ^| r/- <| Timer-match interrupt pending
| `0xfffff104` | `THRES` |`31:0` | r/w | Threshold value register
| `0xfffff108` | `COUNT` |`31:0` | r/w | Counter register
| `0xfffff10C` | `CAPTURE` |`31:0` | r/- | Capture register
| `0xfffff108` | `COUNT` |`31:0` | r/- | Counter register
|=======================

0 comments on commit 31d1933

Please sign in to comment.