1.2 Variable Transfer Size Mode (BMODE = 1)

In Variable Transfer Size mode, the SPIxTWIDTH register is used to determine the width of each data transfer and the SPIxTCNTH/L register pair specifies the number of transfers of that bit-length that will occur. If SPIxTWIDTH is equal to zero, each data transfer will be a full byte of data, otherwise the length of the data transfer is whatever value was written to the SPIxTWIDTH register. The following example shows how the SPI module can be configured to transfer data that is five bits wide (SPIxTWIDTH = 0x05) a total of 12 times demonstrating Variable Transfer Size mode.

Variable Transfer Size Configuration

uint8_t SPI_Exchange8bit(uint8_t data) {

    SPIxCON1 = 0x00;
    SPIxCON2 = 0x03;            // Full-Duplex Mode (TXR = RXR = 1)
    SPIxBAUD = 0x00;
    SPIxCLK = 0x00;
    SPIxINTEbits.TCZIE = 1;     // Transfer Counter is Zero Interrupt Enabled
    SPIxTCNTL = 0x0C;           // SPI1TCNT
    SPIxTCNTH = 0x00;
    SPIxTWIDTH = 0x05;          // SPI1TWIDTH
    SPIxCON0 = 0x83;            // EN = 1, LSBF = 0, MST = 1, BMODE = 0

    SS1_SetHigh();
    while (SPIxINTFbits.TCZIF == 0x0) {
        SPIxTXB = data;
        while (PIR2bits.SPIxRXIF == SPI_RX_IN_PROGRESS) {
        }
        data_RX = SPIxRXB;
    }
    SS1_SetLow();
    SPIxINTFbits.TCZIF = 0;
}