Peripheral Pin Select (PPS) enables flexible digital peripheral I/O pin mapping to a wide range of external pins. In older 8-bit devices, a peripheral was hard-wired to a specific pin (example: PWM1 output on pin RC5). PPS allows the developer to choose from a number of output and input pins to connect to the digital peripheral.
This can be extremely handy for routing circuit boards. There are cases where a change of I/O position can make a circuit board easier to route. Sometimes mistakes are found too late to fix so having the option to change a pinout mapping in software rather than creating a new printed circuit board can be very helpful.
Some Microchip customers may be familiar with PPS from the PIC24 product line. PPS for the 8-bit family differs
in that each digital peripheral input signal is connected to a pin by default. This stands in contrast to PPS for the PIC24 products, where peripherals are left unconnected by default. For 8-bit PPS, peripheral input and output signals need to be selected before the peripheral is enabled. Then the peripheral should be enabled after both input and output selections have been completed.
PPS has its limitations though. Only digital signals are included in the selections. All analog inputs and outputs remain fixed to their assigned pins due to the internal circuitry requirements.
PPS is available on a small selection of devices but that number will increase as new controllers are released. The PIC16F170x family has the PPS feature so we will use that as a reference in this training module.
A simplified block diagram of the PPS is shown here.
PPS Video Tutorial
This video will introduce the Peripheral Pin Select (PPS) for Microchip 8-bit MCU devices and show how to use it.
For iPad users, the video quality may be poor. For a higher resolution video click here:
Direct Link to YouTube
Each peripheral that can be rearranged with the PPS has a register to select the input source. The register selects which input pin to connect to the input circuitry. The register name will have a peripheral nickname followed by the letters PPS. For example, the USART Receive input uses the RXPPS register to select the input pin connection.
A generic register is shown below since all the registers share the same setup. XXX in the name represents the peripheral name. Five bits in the register select the input pin. On reset the register defaults to a value that selects the default input pin. This will vary from peripheral to peripheral. Changing the five bits to the selected input will change the input pin for that particular peripheral. (Example here is for the PIC16F1708)
xxxPPS: Peripheral xxx Input Selection Register
Here is the code in MPLAB® XC8 format for setting the USART RX input pin to RB4:
RXPPSbits.RXPPS = 0x0C; // RB4->EUSART1:RX1
In MPASM Assembly format, the External Interrupt Pin has been connected to RA3
Banksel INTPPS ; go to bank with INTPPS registers movlw 0x03 ; load value of RA3 movwf INTPPS ; to INTPPS register
Each Peripheral output can be connected to a selected I/O pin through the PPS. This is done in a similar fashion to the input selection except that selecting the output connection is opposite from the input selection. Instead of the register being named a peripheral nickname followed by PPS, the output is the pin name followed by PPS. So the pin RB0 would have a RB0PPS register to select its connection.
There are five bits in the Output Source register used to choose the connection. These five bits select the Peripheral output that the pin will be connected to. (Example here is for the PIC16F1708)
RxyPPS: Pin Rxy Output Source Selection Register
Here is the code in MPLAB® XC8 format for setting the USART TX output pin to RA0:
RA0PPSbits.RA0PPS = 0x14; // EUSART1:TX1->RA0
In MPASM Assembly format CLC1OUT Pin is connected to RA5
Banksel RA5PPS ; go to bank with RA5PPS registers movlw 0x04 ; load value for CLC1OUT movwf RA5PPS ; to RA5PPS register
The PPS includes a mode in which all input and output selections can be locked to prevent inadvertent changes. PPS selections are locked by setting the PPSLOCKED bit of the PPSLOCK register. Setting and clearing this bit requires a special sequence as an extra precaution against inadvertent changes.
Assembly Code for PPS Lock Sequence
BCF INTCON, GIE ; DisableInterrupts: BANKSEL PPSLOCK ; Bank to PPSLOCK register MOVLW 55h ; Required sequence, next 4 instructions MOVWF PPSLOCK MOVLW AAh MOVWF PPSLOCK BSF PPSLOCK, 0 ; Set PPSLOCK bit – BCF for unlock BSF INTCON, GIE ; Re-enable Interrupts
PPSLOCK: PPS Lock Register
PPS Permanent Lock
The PPS can be permanently locked by setting the PPS1WAY Configuration bit. When this bit is set, the PPSLOCKED bit can only be cleared and set one time after a device Reset. This allows for clearing the PPSLOCKED bit so that the input and output selections can be made during initialization. When the PPSLOCKED bit is set after all selections have been
made, it will remain set and cannot be cleared until after the next device Reset event.
For this reason it is recommended that all the PPS register selections be placed near the top of the project code so I/O is properly set right after reset. The Configuration register that contains the PPS1WAY bit is shown below for the PIC16F1708.
CONFIG 2 Register
During Sleep mode the PPS input and output selections are unaffected. Consequently entering sleep and returning from sleep will leave all the connection selections in place.
When power is cycled on the device and it goes through a full power on reset, all the PPS input and output selections are reset to their default values. All other types of reset leave the selections unchanged.
MPLAB Code Configurator
The MPLAB® Code Configurator (MCC) makes creating the PPS code quite easy.
In the example below, a PWM3 peripheral is setup to connect to the RA1 pin (Green Lock Symbol). The MCC will generate the PPS lock code and the register settings when the "Generate Code" button is clicked in the Composer Area of the MCC. This creates a pin_manager.c file that contains the PPS code. The PPS section of the code, generated in MPLAB® XC8 Compiler format, is also shown below.
GIE = 0; PPSLOCK = 0x55; PPSLOCK = 0xAA; PPSLOCK = 0x00; // unlock PPS RA1PPSbits.RA1PPS = 0x0E; // RA1->PWM3:PWM3OUT PPSLOCK = 0x55; PPSLOCK = 0xAA; PPSLOCK = 0x01; // lock PPS GIE = state;