0
votes

I want two PIC18 to communicate by SPI. The slave has the new SPI module with FIFOs and separate RX and TX registers. For some reason I cannot receive data. I guess I misconfigure the module. I also use the SS interrupt to prepare the transfer. Upon chip select I swap buffers and initalize counters. This part works. I also see the clock and data signal of the master on the oscilloscope. However, the interrupts for TX and RX are not fired.

Here is the configuration:

void spiInit() { spiTransferComplete=0;

// Chip not ready
CR=1;

// clear EN 
SPI1CON0bits.EN=0;
// Set PPS     
SPI1SSPPS=0b00000110; // SS  RA6 > Chip select input            
SPI1SCKPPS=0b00001010; // SCK > RB2
SPI1SDIPPS=0b00001011; // SDI > RB3
RB4PPS=0x32; // SDO > RB4 
TRISB2=1;
TRISB3=1;    

SPI1CON0=0b00000000; // EN=0, LSBF=0, MST=0, BMODE=0
SPI1CON1=0b00000100; // SMP=0, CKE=0, CKP=0, SSP=1, SDI=0, SDO=0
SPI1CON2=0b00000011; // SSET=0, TXR=1, RXR=1

// Interrupts
SPI1INTEbits.SOSIE=1;
SPI1INTEbits.EOSIE=1;
SPI1INTEbits.SPI1EOSIE=1;
SPI1INTEbits.SPI1SOSIE=1;
SPI1INTEbits.RXOIE=1;

PIE3bits.SPI1IE=1;
PIE3bits.SPI1RXIE=1;
PIE3bits.SPI1TXIE=1;

// enable EN 
SPI1CON0bits.EN=1;

}

and this is the interrupt routine:

void spiInterruptHandler() {

// Start SS
if (SPI1INTEbits.SPI1SOSIE==1 && SPI1INTFbits.SPI1SOSIF==1) {
    switchSpiBuffer(); // prepare sending
    
    spiSendCsr=1;
    spiRecvCsr=0; 
    
    spiRecv.pck.U1len=0;
    spiRecv.pck.U2len=0;
    spiRecv.pck.U3len=0;
    spiRecv.pck.U4len=0;        
    
    SPI1TXB=spiSend->cBuf[spiSendCsr]; // preload first byte
    CR=0;   // ready to send
    SPI1INTFbits.SPI1SOSIF=0;
}

// end of SS
if (SPI1INTEbits.SPI1EOSIE==1 && SPI1INTFbits.SPI1EOSIF==1) {
    CR=1;
    if (spiTransferComplete)
        spiTransferComplete(&(spiRecv.pck));
    SPI1INTFbits.SPI1EOSIF=0;
}

// byte received
if (PIR3bits.SPI1RXIF==1) {
    spiRecv.cBuf[spiRecvCsr++]=SPI1RXB;
}

// byte sent
if (PIR3bits.SPI1TXIF==1) {
    SPI1TXB=spiSend->cBuf[spiSendCsr++];
}    

}

1

1 Answers

0
votes

It was a classic. To use a digital IO properly you have to clear the according ANSEL bits for the multiplexed analog inputs. I expected MCC to do this for me but in this case it did not happen. So: always double check if TRIS and ANSEL are set correctly.