DPPI - Distributed programmable peripheral interconnect

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.

Note: Read Peripheral interface to get familiarized with tasks, events, publish/subscribe, interrupts and other concepts.

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 configuration (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 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.

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 figure below.

Figure 2. DPPI events flow
DPPI events flow

How peripheral tasks are triggered from different channels based on subscribe registers is illustrated in the figure below.

Figure 3. DPPI tasks flow
DPPI tasks flow

DPPI configuration (DPPIC)

Enabling and disabling of channels globally is handled through the DPPI configuration (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 the DPPI configuration:

  • Enable or disable channels individually using registers CHEN, CHENSET, and CHENCLR
  • Enable or disable channels in channel groups using the groups' tasks ENABLE and DISABLE. It needs to be defined which channels belong to which channel groups before these tasks are triggered.
Note: ENABLE tasks are prioritized over DISABLE tasks. 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 is prioritized.

The DPPI configuration 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.

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

Many-to-many connection

The example shows how to create a many-to-many connection, showcasing the DPPIC's channel group functionality.

A channel group that includes only channel 0 is set up first. Then the GPIOTE and TIMER0 configure their IN0 and COMPARE0 events respectively to be published on channel 0, while the SAADC configures its START task to subscribe to events on channel 0. Through DPPIC, the CHG0 DISABLE task is configured to subscribe to events on channel 0. After an event is received on channel 0 it will be disabled. Finally, channel 0 is enabled using the DPPIC 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 a system implementing TrustZone® for Cortex®-M processors

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 non-secure peripheral access can only configure and control the 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)

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:

  • If all channels (enabled or not) within a group are non-secure, then the group is considered non-secure
  • If at least one of the channels (enabled or not) within the group is secure, then the group is considered secure

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:

  • Non-secure write accesses to registers CHEN, CHENSET, and CHENCLR cannot write bit i of these registers
  • Non-secure write accesses to TASK_CHG[j].EN and TASK_CHG[j].DIS registers are ignored if the channel group j contains at least one 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 always read 0 for the bit at position 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 non-secure channel will be ignored if the group subscribing to this channel is secure. An 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 configuration

   
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 are ignored if either SUBSCRIBE_CHG[0].EN or SUBSCRIBE_CHG[0].DIS is enabled

 
CHG[1] 0x804  

Channel group 1

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

 
CHG[2] 0x808  

Channel group 2

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

 
CHG[3] 0x80C  

Channel group 3

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

 
CHG[4] 0x810  

Channel group 4

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

 
CHG[5] 0x814  

Channel group 5

Note: Writes to this register are ignored if either SUBSCRIBE_CHG[5].EN or SUBSCRIBE_CHG[5].DIS is 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 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                                 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