86 lines
4.2 KiB
Plaintext
86 lines
4.2 KiB
Plaintext
<<<
|
|
:sectnums:
|
|
==== Pulse-Width Modulation Controller (PWM)
|
|
|
|
[cols="<3,<3,<4"]
|
|
[frame="topbot",grid="none"]
|
|
|=======================
|
|
| Hardware source file(s): | neorv32_pwm.vhd |
|
|
| Software driver file(s): | neorv32_pwm.c |
|
|
| | neorv32_pwm.h |
|
|
| Top entity port: | `pwm_o` | PWM output channels (12-bit)
|
|
| Configuration generics: | `IO_PWM_NUM_CH` | number of PWM channels to implement (0..12)
|
|
| CPU interrupts: | none |
|
|
|=======================
|
|
|
|
|
|
**Overview**
|
|
**Overview**
|
|
|
|
The PWM module implements a pulse-width modulation controller with up to 12 independent channels providing
|
|
8-bit resolution per channel. The actual number of implemented channels is defined by the `IO_PWM_NUM_CH` generic.
|
|
Setting this generic to zero will completely remove the PWM controller from the design.
|
|
|
|
[NOTE]
|
|
The `pwm_o` has a static size of 12-bit. If less than 12 PWM channels are configured, only the LSB-aligned channel
|
|
bits are used while the remaining bits are hardwired to zero.
|
|
|
|
|
|
**Theory of Operation**
|
|
|
|
The PWM controller is activated by setting the `PWM_CTRL_EN` bit in the module's control register `CTRL`. When this
|
|
bit is cleared, the unit is reset and all PWM output channels are set to zero. The module
|
|
provides three duty cycle registers `DC[0]` to `DC[2]`. Each register contains the duty cycle configuration for four
|
|
consecutive channels. For example, the duty cycle of channel 0 is defined via bits 7:0 in `DC[0]`. The duty cycle of
|
|
channel 2 is defined via bits 15:0 in `DC[0]` and so on.
|
|
|
|
[NOTE]
|
|
Regardless of the configuration of `IO_PWM_NUM_CH` all module registers can be accessed without raising an exception.
|
|
Software can discover the number of available channels by writing 0xff to all duty cycle configuration bytes and
|
|
reading those values back. The duty-cycle of channels that were not implemented always reads as zero.
|
|
|
|
Based on the configured duty cycle the according intensity of the channel can be computed by the following formula:
|
|
|
|
_**Intensity~x~**_ = `DC[y](i*8+7 downto i*8)` / (2^8^)
|
|
|
|
The base frequency of the generated PWM signals is defined by the PWM core clock. This clock is derived
|
|
from the main processor clock and divided by a prescaler via the 3-bit `PWM_CTRL_PRSCx` in the unit's control
|
|
register.
|
|
|
|
.PWM prescaler configuration
|
|
[cols="<4,^1,^1,^1,^1,^1,^1,^1,^1"]
|
|
[options="header",grid="rows"]
|
|
|=======================
|
|
| **`PWM_CTRL_PRSCx`** | `0b000` | `0b001` | `0b010` | `0b011` | `0b100` | `0b101` | `0b110` | `0b111`
|
|
| Resulting `clock_prescaler` | 2 | 4 | 8 | 64 | 128 | 1024 | 2048 | 4096
|
|
|=======================
|
|
|
|
The resulting PWM carrier frequency is defined by:
|
|
|
|
_**f~PWM~**_ = _f~main~[Hz]_ / (2^8^ * `clock_prescaler`)
|
|
|
|
|
|
**Register Map**
|
|
|
|
.PWM register map (`struct neorv32_pwm_t`)
|
|
[cols="<4,<2,<6,^2,<8"]
|
|
[options="header",grid="all"]
|
|
|=======================
|
|
| Address | Name [C] | Bit(s), Name [C] | R/W | Function
|
|
.3+<| `0xfffff000` .3+<| `CTRL` <|`0` `PWM_CTRL_EN` ^| r/w <| PWM enable
|
|
<|`3:1` `PWM_CTRL_PRSC2 : PWM_CTRL_PRSC0` ^| r/w <| 3-bit clock prescaler select
|
|
<|`31:4` - ^| r/- <| _reserved_, read as zero
|
|
.4+<| `0xfffff004` .4+<| `DC[0]` <|`7:0` ^| r/w <| 8-bit duty cycle for channel 0
|
|
<|`15:8` ^| r/w <| 8-bit duty cycle for channel 1
|
|
<|`23:16` ^| r/w <| 8-bit duty cycle for channel 2
|
|
<|`31:24` ^| r/w <| 8-bit duty cycle for channel 3
|
|
.4+<| `0xfffff008` .4+<| `DC[1]` <|`7:0` ^| r/w <| 8-bit duty cycle for channel 4
|
|
<|`15:8` ^| r/w <| 8-bit duty cycle for channel 5
|
|
<|`23:16` ^| r/w <| 8-bit duty cycle for channel 6
|
|
<|`31:24` ^| r/w <| 8-bit duty cycle for channel 7
|
|
.4+<| `0xfffff00c` .4+<| `DC[2]` <|`7:0` ^| r/w <| 8-bit duty cycle for channel 8
|
|
<|`15:8` ^| r/w <| 8-bit duty cycle for channel 9
|
|
<|`23:16` ^| r/w <| 8-bit duty cycle for channel 10
|
|
<|`31:24` ^| r/w <| 8-bit duty cycle for channel 11
|
|
|=======================
|