DPPI - Distributed programmable peripheral interconnect

The distributed programmable peripheral interconnect (DPPI) enables peripherals to interact autonomously with each other, 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 of CPU involvement to implement behavior which can be predefined using the DPPI.

DPPI has the following features:

The DPPI system consists of several PPIBus modules, which are connected to a fixed number of DPPI channels and a DPPI controller (DPPIC):
Figure 1. DPPI overview
DPPI overview, block diagram

Subscribing to and publishing on channels

The PPIBus can route peripheral events onto the channels (publishing), or route events from the channels into peripheral tasks (subscribing).

All peripherals include:

  • One subscribe register per task
  • One publish register per event

Publish and subscribe registers use 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.

One event can trigger multiple tasks by subscribing different tasks to the same channel. Similarly, one task could be triggered by multiple events by publishing different events to the same channel. For advanced use cases, multiple events and multiple tasks could be connected 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 will be merged and only one event is routed through the DPPI system.

DPPI events flow shows how peripheral events are routed onto different channels based on the publish registers.

Figure 2. DPPI events flow
DPPI events flow

DPPI tasks flow shows how peripheral tasks are triggered from different channels based on the subscribe registers.

Figure 3. DPPI tasks flow
DPPI tasks flow

DPPI controller

Enabling/disabling and control of DPPI channels are handled locally at every peripheral and through the centralized DPPI controller peripheral.

There are two ways of enabling and disabling global channels using the DPPIC:

  • Enable or disable channels individually using the CHEN, CHENSET and CHENCLR registers.
  • Enable or disable channels in channel groups using the groups' ENABLE and DISABLE tasks. Prior triggering these tasks, it needs to be defined which channels belong to which channel groups.
Important: When a channel belongs to two (or more) groups, for example group m and n, and the tasks CHG[m].EN and CHG[n].DIS occur simultaneously (m and n can be equal or different), the CHG[m].EN task on that channel has priority. Meaning that enable tasks are prioritized over disable tasks.

DPPIC tasks (for example CHG[0].EN) can be triggered through the DPPI system like any other task, which means they can be hooked 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 when either subscribe register is enabled.

Connection examples

DPPI offers several connection options. Examples are given for how to create one-to-one and many-to-many connections.

One-to-one connection

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 in the DPPI controller.

          
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);

Many-to-many connection

The example shows how to create a many-to-many connection, also showcasing the use of the channel group functionality of the DPPI controller.

A channel group, including only channel 0, is set up first. Then GPIOTE and TIMER0 configure their IN0 and COMPARE0 events respectively to be published on channel 0, while SAADC configures its START task to subscribe to events on channel 0. The DPPI controller configures its CHG0 disable task to subscribe to events on channel 0. This will effectively disable channel 0 after an event is received on channel 0. Finally, channel 0 is enabled using the DPPI controller task to enable a channel group.

          
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;
        

Special considerations for system implementing TrustZone for Cortex-M® processors

In a system implementing the TrustZone for Cortex-M® technology, DPPI channels can be defined as "Secure" or "Non-Secure" using the SPU - System protection unit :
  • A peripheral configured with a non-secure security attribute will only be able to subscribe or publish to non secure DPPI channels.
  • A peripheral configured as secure will be able to access all DPPI channels
The DPPIC is implemented as a "split-security" peripheral. It is therefore accessible by both secure and non-secure accesses but the DPPIC behaves differently depending of the access type :
  • A non-secure peripheral access will only be able to configure and control DPPI channels defined as non-secure in the SPU.DPPI.PERM[] register(s).
  • A secure peripheral access can control all the DPPI channels, independently of the SPU.DPPI.PERM[] register(s).
The DPPIC allows the creation of a group of channels to be able to simultaneously enable or disable all channels within a group . The security attribute of a group of channels (secure or non-secure) is defined as follows:
  • If all the channels (enabled or not) of a group are non-secure, then the group is considered as non-secure
  • If at least one of the channels (enabled or not) of the group is secure, then the group is considered as secure
A non-secure access to a DPPIC register or a bitfield controlling a channel marked as secure in SPU.DPPI[].PERM register(s) will be ignored :
  • Write accesses will have no effect
  • Read accesses will always return a zero value
No exception is triggered when a non-secure access targets a register or bitfield 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
  • Non-secure write accesses to CHEN, CHENSET and CHENCLR registers will not be able to write to bit i of those registers
  • Non-secure write accesses to TASK_CHG[j].EN and TASK_CHG[j].DIS registers will be ignored if the channel group j contains at least a channel defined as secure (it can be the channel i itself or any channel declared as secure)
  • Non-secure read accesses to registers CHEN, CHENSET and CHENCLR will always read a 0 for the bit at position i

For the channel configuration registers (DPPIC.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 DPPIC.CHG[g] register included one or more secure channel, then the group g is considered as secure and only a secure transfer can read or write DPPIC.CHG[g]. A non-secure write access will be ignored and a non-secure read access will return 0.

The DPPIC can subscribe to both secure or non-secure channel through the SUBSCRIBE_CHG[] registers in order to trigger task for enabling or disabling groups of channels. But an event from a non-secure channel will be ignored if the group subscribing to this channel is secure. A event from a secure channel can trigger both secure and non-secure tasks.

Registers

Table 1. Instances
Base address Peripheral Instance Secure mapping DMA security Description Configuration

0x50017000
0x40017000

DPPIC

DPPIC : S
DPPIC : NS

SPLIT

NA

DPPI controller

   
Table 2. Register overview
Register Offset Security Description
TASKS_CHG[0].EN 0x000  

Enable channel group 0

 
TASKS_CHG[0].DIS 0x004  

Disable channel group 0

 
TASKS_CHG[1].EN 0x008  

Enable channel group 1

 
TASKS_CHG[1].DIS 0x00C  

Disable channel group 1

 
TASKS_CHG[2].EN 0x010  

Enable channel group 2

 
TASKS_CHG[2].DIS 0x014  

Disable channel group 2

 
TASKS_CHG[3].EN 0x018  

Enable channel group 3

 
TASKS_CHG[3].DIS 0x01C  

Disable channel group 3

 
TASKS_CHG[4].EN 0x020  

Enable channel group 4

 
TASKS_CHG[4].DIS 0x024  

Disable channel group 4

 
TASKS_CHG[5].EN 0x028  

Enable channel group 5

 
TASKS_CHG[5].DIS 0x02C  

Disable channel group 5

 
SUBSCRIBE_CHG[0].EN 0x080  

Subscribe configuration for task CHG[0].EN

 
SUBSCRIBE_CHG[0].DIS 0x084  

Subscribe configuration for task CHG[0].DIS

 
SUBSCRIBE_CHG[1].EN 0x088  

Subscribe configuration for task CHG[1].EN

 
SUBSCRIBE_CHG[1].DIS 0x08C  

Subscribe configuration for task CHG[1].DIS

 
SUBSCRIBE_CHG[2].EN 0x090  

Subscribe configuration for task CHG[2].EN

 
SUBSCRIBE_CHG[2].DIS 0x094  

Subscribe configuration for task CHG[2].DIS

 
SUBSCRIBE_CHG[3].EN 0x098  

Subscribe configuration for task CHG[3].EN

 
SUBSCRIBE_CHG[3].DIS 0x09C  

Subscribe configuration for task CHG[3].DIS

 
SUBSCRIBE_CHG[4].EN 0x0A0  

Subscribe configuration for task CHG[4].EN

 
SUBSCRIBE_CHG[4].DIS 0x0A4  

Subscribe configuration for task CHG[4].DIS

 
SUBSCRIBE_CHG[5].EN 0x0A8  

Subscribe configuration for task CHG[5].EN

 
SUBSCRIBE_CHG[5].DIS 0x0AC  

Subscribe configuration for task CHG[5].DIS

 
CHEN 0x500  

Channel enable register

 
CHENSET 0x504  

Channel enable set register

 
CHENCLR 0x508  

Channel enable clear register

 
CHG[0] 0x800  

Channel group 0

Note: Writes to this register is ignored if either SUBSCRIBE_CHG[0].EN/DIS are enabled.

 
CHG[1] 0x804  

Channel group 1

Note: Writes to this register is ignored if either SUBSCRIBE_CHG[1].EN/DIS are enabled.

 
CHG[2] 0x808  

Channel group 2

Note: Writes to this register is ignored if either SUBSCRIBE_CHG[2].EN/DIS are enabled.

 
CHG[3] 0x80C  

Channel group 3

Note: Writes to this register is ignored if either SUBSCRIBE_CHG[3].EN/DIS are enabled.

 
CHG[4] 0x810  

Channel group 4

Note: Writes to this register is ignored if either SUBSCRIBE_CHG[4].EN/DIS are enabled.

 
CHG[5] 0x814  

Channel group 5

Note: Writes to this register is ignored if either SUBSCRIBE_CHG[5].EN/DIS are enabled.

 

TASKS_CHG[n].EN (n=0..5)

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 Access Field Value ID Value Description
A W

EN

   

Enable channel group n

     

Trigger

1

Trigger task

TASKS_CHG[n].DIS (n=0..5)

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 Access Field Value ID Value Description
A W

DIS

   

Disable channel group n

     

Trigger

1

Trigger task

SUBSCRIBE_CHG[n].EN (n=0..5)

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
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 Access Field Value ID Value Description
A RW

CHIDX

 

[15..0]

Channel that task CHG[n].EN will subscribe to

B RW

EN

     

     

Disabled

0

Disable subscription

     

Enabled

1

Enable subscription

SUBSCRIBE_CHG[n].DIS (n=0..5)

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
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 Access Field Value ID Value Description
A RW

CHIDX

 

[15..0]

Channel that task CHG[n].DIS will subscribe to

B RW

EN

     

     

Disabled

0

Disable subscription

     

Enabled

1

Enable subscription

CHEN

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                                 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 Access Field Value ID Value Description
A-P RW

CH[i] (i=0..15)

   

Enable or disable channel i

     

Disabled

0

Disable channel

     

Enabled

1

Enable channel

CHENSET

Address offset: 0x504

Channel enable set register

Read: reads value of CH{i} field in CHEN 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                                 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 Access Field Value ID Value Description
A-P RW

CH[i] (i=0..15)

   

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

CHENCLR

Address offset: 0x508

Channel enable clear register

Read: reads value of CH{i} field in CHEN 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                                 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 Access Field Value ID Value Description
A-P RW

CH[i] (i=0..15)

   

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

CHG[n] (n=0..5)

Address offset: 0x800 + (n × 0x4)

Channel group n

Note: Writes to this register is ignored if either SUBSCRIBE_CHG[n].EN/DIS are 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                                 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 Access Field Value ID Value Description
A-P RW

CH[i] (i=0..15)

   

Include or exclude channel i

     

Excluded

0

Exclude

     

Included

1

Include