Enabling Direct Hardware Control of the SPI Slave Select Output

The SPI protocol allows a master device to interface one or more slave devices, all on the same bus. When more than one slave device is connected to a SPI master, each slave should have an independent Slave Select (or Chip Select) connection from the master device that is used to determine which slave is being communicated with at a given time. The master selects the slave that it will communicate with by enabling the Slave Select line for that slave on the bus. Traditionally, a GPIO would need to be dedicated to serve as the Slave Select, which required that the user set/clear the pin as needed in software, whenever a SPI communication was to occur.

The stand-alone SPI module features the ability to control the SPI Slave Select output in hardware, removing the need to enable/disable the Slave Select line in software. To enable hardware control of the SPI Slave Select output, the desired pin must be configured using PPS as the “SPIxSS”. In addition to using PPS to choose a Slave Select output, the corresponding TRISx setting must also be configured as an output. Once these configuration steps have been completed, every time that the SPI master initiates communication, the Slave Select line will be enabled and disabled, as needed in hardware. The Slave Select Input/Output Polarity Control (SSP) bit of the SPIxCON1 register can be used to select whether the Slave Select is active-high or active-low. Example 4-1 below contains a code snippet demonstrating how the PPS and TRIS settings can be configured to enable hardware control of the Slave Select output.

Pin Configuration Settings for SPI1 with Hardware Slave Select Control

void PIN_MANAGER_Initialize(void) {

    TRISE = 0x07;
    TRISA = 0xFF;
    TRISB = 0xFF;
    TRISC = 0xAF;
    TRISD = 0xEF;        //RD4 = Output (Slave Select Output)
    .
    .
    .
    SPI1SCKPPS = 0x16;    //RC6->SPI1:SCK1;    
    RC4PPS = 0x1F;        //RC4->SPI1:SDO1;    
    RC6PPS = 0x1E;        //RC6->SPI1:SCK1;   
    RD4PPS = 0x33;        //RD4->SPI1:SS1;(Refer to PPS table for this value!)
    SPI1SDIPPS = 0x15;    //RC5->SPI1:SDI1;    
}