The distributed programmable peripheral interconnect (DPPI) enables peripherals to interact autonomously with each other by using tasks and events, without any intervention from the CPU. DPPI allows precise synchronization between peripherals when real-time application constraints exist, and eliminates the need for CPU involvement to implement behavior which can be predefined using the DPPI.
The DPPI has the following features:
The DPPI consists of several PPIBus modules, which are connected to a fixed number of DPPI channels and a DPPI controller (DPPIC).
The PPIBus can route peripheral events onto the channels (publishing), or route events from the channels into peripheral tasks (subscribing).
All peripherals include the following:
Publish and subscribe registers use a channel index field to determine the channel to which the event is published or tasks subscribed. In addition, there is an enable bit for the subscribe and publish registers that needs to be enabled before the subscription or publishing takes effect.
Writing non-existing channel index (CHIDX) numbers into a peripheral's publish or subscribe registers will yield unexpected results.
One event can trigger multiple tasks by subscribing different tasks to the same channel. Similarly, one task can be triggered by multiple events by publishing different events to the same channel. For advanced use cases, multiple events and multiple tasks can connect to the same channel forming a many-to-many connection. If multiple events are published on the same channel at the same time, the events are merged and only one event is routed through the DPPI.
How peripheral events are routed onto different channels based on publish registers is illustrated in the following figure.
The following figure illustrates how peripheral tasks are triggered from different channels based on subscribe registers.
Enabling and disabling of channels globally is handled through DPPIC. Connection (connect/disconnect) between a channel and a peripheral is handled locally by the PPIBus.
There are two ways of enabling and disabling global channels using DPPIC:
DPPIC tasks (for example CHG[0].EN) can be triggered through DPPI like any other task, which means they can be linked to a DPPI channel through the subscribe registers.
In order to write to CHG[x], the corresponding CHG[x].EN and CHG[x].DIS subscribe registers must be disabled. Writes to CHG[x] are ignored if any of the two subscribe registers are enabled.
DPPI offers several connection options. Examples are given for how to create one-to-one and many-to-many connections.
This example shows how to create a one-to-one connection between TIMER compare register and SAADC start task.
The channel configuration is set up first. TIMER0 will publish its COMPARE0 event on channel 0, and SAADC will subscribe its START task to events on the same channel. After that, the channel is enabled through the DPPIC.
NRF_TIMER0->PUBLISH_COMPARE0 = (DPPI_PUB_CHIDX_Ch0) |
(DPPI_PUB_EN_Msk);
NRF_SAADC->SUBSCRIBE_START = (DPPI_SUB_CHIDX_Ch0) |
(DPPI_SUB_EN_Msk);
NRF_DPPIC->CHENSET = (DPPI_CHENSET_CH0_Set << DPPI_CHENSET_CH0_Pos);
The example shows how to create a many-to-many connection, showcasing the DPPIC's channel group functionality.
NRF_DPPIC->CHG[0] = (DPPI_CHG_CH0_Included << PPI_CHG_CH0_Pos);
NRF_GPIOTE->PUBLISH_IN0 = (DPPI_PUB_CHIDX_Ch0) |
(DPPI_PUB_EN_Msk);
NRF_TIMER0->PUBLISH_COMPARE0 = (DPPI_PUB_CHIDX_Ch0) |
(DPPI_PUB_EN_Msk);
NRF_SAADC->SUBSCRIBE_START = (DPPI_SUB_CHIDX_Ch0) |
(DPPI_SUB_EN_Msk);
NRF_DPPIC->SUBSCRIBE_CHG[0].DIS = (DPPI_SUB_CHIDX_Ch0) |
(DPPI_SUB_EN_Msk);
NRF_DPPIC->TASK_CHG[0].EN = 1;
DPPI is implemented with split security, meaning it handles both secure and non-secure accesses. In a system implementing the TrustZone® for Cortex®-M technology, DPPI channels can be defined as secure or non-secure using the SPU.
A peripheral configured as non-secure will only be able to subscribe to or publish on non-secure DPPI channels. A peripheral configured as secure will be able to access all DPPI channels. DPPI handles both secure and non-secure accesses, but behaves differently depending on the access type:
A group of channels can be created, making it possible to simultaneously enable or disable all channels within the group. The security attribute of a group of channels (secure or non-secure) is defined as follows:
A non-secure access to a DPPI register, or a bit field, controlling a channel marked as secure in SPU.DPPI[].PERM register(s) will be ignored. Write accesses will have no effect, and read accesses will always return a zero value.
No exceptions are triggered when non-secure accesses target a register or a bit field
controlling a secure channel. For example, if the bit i
is set in the
SPU.DPPI[0].PERM register (declaring DPPI channel i as secure), then:
i
of these registersj
contains at least one channel
defined as secure (it can be the channel i itself or any channel declared as
secure)i
For the channel configuration registers (CHG[]), access from non-secure code is only
possible if the included channels are all non-secure, whether the channels are enabled
or not. If a CHG[g] register included one or more secure channel(s), then the group
g
is considered as secure, and only secure transfers can read to or
write from CHG[g]. A non-secure write access is ignored, and a non-secure read access
returns 0.
The DPPI can subscribe to secure and non-secure channels through the SUBSCRIBE_CHG[] registers, in order to trigger the task for enabling or disabling groups of channels. An event from a secure channel will be ignored if the group subscribing to this channel is non-secure. A secure group can subscribe to a non-secure channel or a secure channel.
Base address | Domain | Peripheral | Instance | Secure mapping | DMA security | Description | Configuration | |
---|---|---|---|---|---|---|---|---|
0x50017000 |
APPLICATION | DPPIC |
DPPIC : S |
SPLIT |
NA |
DPPI controller |
32 DPPI channels |
|
0x4100F000 | NETWORK | DPPIC | DPPIC | NS | NA |
DPPI controller |
32 DPPI channels |
Register | Offset | Security | Description | |
---|---|---|---|---|
TASKS_CHG[n].EN | 0x000 |
Enable channel group n |
||
TASKS_CHG[n].DIS | 0x004 |
Disable channel group n |
||
SUBSCRIBE_CHG[n].EN | 0x080 |
Subscribe configuration for task CHG[n].EN |
||
SUBSCRIBE_CHG[n].DIS | 0x084 |
Subscribe configuration for task CHG[n].DIS |
||
CHEN | 0x500 |
Channel enable register |
||
CHENSET | 0x504 |
Channel enable set register |
||
CHENCLR | 0x508 |
Channel enable clear register |
||
CHG[n] | 0x800 |
Channel group n Note: Writes to this register are ignored if either SUBSCRIBE_CHG[n].EN or SUBSCRIBE_CHG[n].DIS is enabled |
Address offset: 0x000 + (n × 0x8)
Enable channel group n
Bit number | 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | |||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
ID | A | ||||||||||||||||||||||||||||||||||
Reset 0x00000000 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | |||
ID | R/W | Field | Value ID | Value | Description | ||||||||||||||||||||||||||||||
A | W |
EN |
Enable channel group n |
||||||||||||||||||||||||||||||||
Trigger |
1 |
Trigger task |
Address offset: 0x004 + (n × 0x8)
Disable channel group n
Bit number | 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | |||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
ID | A | ||||||||||||||||||||||||||||||||||
Reset 0x00000000 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | |||
ID | R/W | Field | Value ID | Value | Description | ||||||||||||||||||||||||||||||
A | W |
DIS |
Disable channel group n |
||||||||||||||||||||||||||||||||
Trigger |
1 |
Trigger task |
Address offset: 0x080 + (n × 0x8)
Subscribe configuration for task CHG[n].EN
Bit number | 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | |||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
ID | B | A | A | A | A | A | A | A | A | ||||||||||||||||||||||||||
Reset 0x00000000 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | |||
ID | R/W | Field | Value ID | Value | Description | ||||||||||||||||||||||||||||||
A | RW |
CHIDX |
[255..0] |
DPPI channel that task CHG[n].EN will subscribe to |
|||||||||||||||||||||||||||||||
B | RW |
EN |
|||||||||||||||||||||||||||||||||
Disabled |
0 |
Disable subscription |
|||||||||||||||||||||||||||||||||
Enabled |
1 |
Enable subscription |
Address offset: 0x084 + (n × 0x8)
Subscribe configuration for task CHG[n].DIS
Bit number | 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | |||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
ID | B | A | A | A | A | A | A | A | A | ||||||||||||||||||||||||||
Reset 0x00000000 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | |||
ID | R/W | Field | Value ID | Value | Description | ||||||||||||||||||||||||||||||
A | RW |
CHIDX |
[255..0] |
DPPI channel that task CHG[n].DIS will subscribe to |
|||||||||||||||||||||||||||||||
B | RW |
EN |
|||||||||||||||||||||||||||||||||
Disabled |
0 |
Disable subscription |
|||||||||||||||||||||||||||||||||
Enabled |
1 |
Enable subscription |
Address offset: 0x500
Channel enable register
Bit number | 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | |||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
ID | f | e | d | c | b | a | Z | Y | X | W | V | U | T | S | R | Q | P | O | N | M | L | K | J | I | H | G | F | E | D | C | B | A | |||
Reset 0x00000000 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | |||
ID | R/W | Field | Value ID | Value | Description | ||||||||||||||||||||||||||||||
A-f | RW |
CH[i] (i=0..31) |
Enable or disable channel i |
||||||||||||||||||||||||||||||||
Disabled |
0 |
Disable channel |
|||||||||||||||||||||||||||||||||
Enabled |
1 |
Enable channel |
Address offset: 0x504
Channel enable set register
Bit number | 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | |||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
ID | f | e | d | c | b | a | Z | Y | X | W | V | U | T | S | R | Q | P | O | N | M | L | K | J | I | H | G | F | E | D | C | B | A | |||
Reset 0x00000000 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | |||
ID | R/W | Field | Value ID | Value | Description | ||||||||||||||||||||||||||||||
A-f | RW |
CH[i] (i=0..31) |
Channel i enable set register. Writing 0 has no effect. |
||||||||||||||||||||||||||||||||
Disabled |
0 |
Read: Channel disabled |
|||||||||||||||||||||||||||||||||
Enabled |
1 |
Read: Channel enabled |
|||||||||||||||||||||||||||||||||
Set |
1 |
Write: Enable channel |
Address offset: 0x508
Channel enable clear register
Bit number | 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | |||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
ID | f | e | d | c | b | a | Z | Y | X | W | V | U | T | S | R | Q | P | O | N | M | L | K | J | I | H | G | F | E | D | C | B | A | |||
Reset 0x00000000 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | |||
ID | R/W | Field | Value ID | Value | Description | ||||||||||||||||||||||||||||||
A-f | RW |
CH[i] (i=0..31) |
Channel i enable clear register. Writing 0 has no effect. |
||||||||||||||||||||||||||||||||
Disabled |
0 |
Read: Channel disabled |
|||||||||||||||||||||||||||||||||
Enabled |
1 |
Read: Channel enabled |
|||||||||||||||||||||||||||||||||
Clear |
1 |
Write: Disable channel |
Address offset: 0x800 + (n × 0x4)
Channel group n
Note: Writes to this register are ignored if either SUBSCRIBE_CHG[n].EN or SUBSCRIBE_CHG[n].DIS is enabled
Bit number | 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | |||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
ID | f | e | d | c | b | a | Z | Y | X | W | V | U | T | S | R | Q | P | O | N | M | L | K | J | I | H | G | F | E | D | C | B | A | |||
Reset 0x00000000 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | |||
ID | R/W | Field | Value ID | Value | Description | ||||||||||||||||||||||||||||||
A-f | RW |
CH[i] (i=0..31) |
Include or exclude channel i |
||||||||||||||||||||||||||||||||
Excluded |
0 |
Exclude |
|||||||||||||||||||||||||||||||||
Included |
1 |
Include |