SPI refresher for PIC18F27J13

Thread Starter

spinnaker

Joined Oct 29, 2009
7,830
It is been a while since I have worked with SPI and I need a refresher.

Datasheet says:

Each MSSP module consists of a Transmit/Receive
Shift register (SSPxSR) and a Buffer register
(SSPxBUF). The SSPxSR shifts the data in and out of
the device, MSb first. The SSPxBUF holds the data that
was written to the SSPxSR until the received data is
ready. Once the 8 bits of data have been received, that
byte is moved to the SSPxBUF register. Then, the Buffer
Full (BF) detect bit (SSPxSTAT<0>) and the interrupt
flag bit, SSPxIF, are set. This double-buffering of the
received data (SSPxBUF) allows the next byte to start
reception before reading the data that was just received.

Any write to the SSPxBUF register during transmission
or reception of data will be ignored and the Write
Collision Detect bit, WCOL (SSPxCON1<7>), will be set.
User software must clear the WCOL bit so that it can be
determined if the following write(s) to the SSPxBUF
register completed successfully.

It says WCOL needs to be cleared. When? I assume this is before I transmit?
 

JohnInTX

Joined Jun 26, 2012
4,787
WCOL shouldn’t be set if you work the SPI correctly. The easiest way to.do that is check BF and read SSPxBUF before writing the next character. If you don’t and WCOL is set, clear it before you transmit again. A good SPI implementation will check the error flags after each byte anyway including WCOL. Any error flag should be taken as a failed communication.
 

JohnInTX

Joined Jun 26, 2012
4,787
Unless there is a special TX only mode, I just write a byte to SSPxBUF, wait for BF or interrupt, read SSPxBUF and discard the received value if I don’t want it. Repeat.

EDIT: a quick read of the datasheet confirms that you have to read SSPxBUF to clear BF and avoid WCOL and SSPOV errors. The procedure above should work. See Register 20-2 description and this on the next page:
Note: When the application software is expecting
to receive valid data, the SSPxBUF should
be read before the next byte of transfer
data is written to the SSPxBUF. Application
software should follow this process even
when the current contents of SSPxBUF
are not important.
 
Last edited:

Picbuster

Joined Dec 2, 2013
1,059
So I am transmitting only. Any tips there?
here a working SPI Tx
delays needed in my application due to SPI behave of connected devices

C:
//SPI settings

//  SSP1CON1 explain
//bit 7  Wcol
//bit 6  slave mode overrun
//bit 5  SSpen 1 enable spi
//bit 4  ckp clock polarity
//bit 0-3  value
//  SSPM=2;  //FOSC/64
//  SSPM=1;  //FOSC/16
//  SSPM=0;  //FOSC/4
  SPEN1=1;
   SYNC1=0;
   BRGH1=0;
  SPBRG1 =15;
  SSP1STAT= 0b1000000;
  SSP1CON1bits.CKP=0;
  SSP1CON1bits.SSPM=2;

  SSP1CON1bits.SSPEN=On;
  PIE1bits.SSP1IE=On;
  INTCONbits.GIE=On;
  INTCONbits.PEIE=On;

// data in FTDI_Msg

void Send_SPI1(int Size)
{
  Ena_B_1=Yes;
  __delay_ms(2);  // wait for ready
  for (n=0;n<Size;n++)
  {
  char temp = SSP1BUF;  // clear buffer//------
  while (SSP1CON1bits.WCOL)
  {
  SSP1CON1bits.WCOL=0;
  __delay_us(2);
  }

  SSP1BUF =  FTDI_Msg[n];  // send
  __delay_us(5);
  }
  __delay_ms(5);  // allow disconnect
  Ena_B_1=No;
}
Picbuster

Moderators note : Please use code tags for pieces of code
 
Last edited by a moderator:
Top