chipKIT® Development Platform

Inspired by Arduino™

Polling Slave Select in SPI

Created Mon, 09 Jul 2012 02:48:33 +0000 by natashenka


natashenka

Mon, 09 Jul 2012 02:48:33 +0000

Hi,

I'm using the ChipKit Uno to simulate a SPI ROM chip, and I was wondering if anyone knows how to access the SS PIN in SPI slave mode. The chip I'm emulating supports a mass read mode, where after a read command, the chip provides output at each sequential address until SS is driven high. So I think I need to determine when this happens to stop providing data and start listening for the next command at the right time.

My code in loop is:

//get read command, and address

a = 0;
t = spiComm(0);
if(t==3){ // 3 is mass read command
      for(i = 2; i > -1; i--){
           a = a + (spiComm(0)<<(i*8));
      } 
}

...

while(I NEED HELP WITH THIS CONDITION){
     r = spiComm(v[a]); //v is an array of values for each address
     a++;  
   } 

...

uint8_t spiComm(uint8_t bVal)
{
  while ((SPI2STAT & (1 << _SPISTAT_SPITBE)) == 0) {
  }
  SPI2BUF = bVal;

  while ((SPI2STAT & (1 << _SPISTAT_SPIRBF)) == 0) {
  }

  return SPI2BUF;
}

I tried the condition r != 3, and this works sometimes, but unfortunately the master I'm using does not guarantee that MOSI will be any particular value when the slave is providing data, so sometimes I get errors if MOSI happens to be 3 when the Uno is providing data.

I've also tried digitalRead(10) == LOW as the condition, but it behaves erratically, the loop sometimes being skipped, and sometimes not terminating (but I'm fairly confident it's connected correctly, because the r != 3 condition always works, unless there's a stray 3 on the line). I suspect digitalRead doesn't work correctly on SPI pins when SPI is actively being used, but I can't find documentation on this anywhere.

Any thoughts? Is there a way you can poll SS using SPI registers?

Worst case, I can draw SS to multiple inputs, but I'd like to avoid this if possible.


nik999389

Tue, 10 Jul 2012 19:15:56 +0000

Hey! first of all Welcome to the forum! =D

The reason that the digitalRead(10) function doesnt work is because of the way the uno32 is set up. There is a jumper named JP4 that changes the output marked as pin 10 on the uno from the slave select pin to the full digital i/o pin 10. If you have JP4 in the RG9 position (which I suspect you do) then The SS pin is routed to the 9th pin of the G port.

I think you should try to read it directly from the port so like:

while(PORTG.9 == 0){
     r = spiComm(v[a]); //v is an array of values for each address
     a++; 
}

I'm not too sure on the syntax of that, you might want to double check it as I have just started working with the Chipkit and Pics in general. Let me know how it goes.


GeneApperson

Mon, 13 Aug 2012 23:29:23 +0000

The ATmega328 on the Arduino Uno has one of it's output compares on the same pin as the SPI SS signal. The PIC32 doesn't overload the pins in the same way. When I designed the Uno32, I put in jumper JP4 to allow both OC5 and SS to end up on the connector pin that corresponds to digital pin 10 on the Uno.

The more common use of that pin is for analogWrite, so the software is designed to access that connector pin as digital pin 10 with the jumper in the RD4 (port D bit 4) position.

If you want to access SS (as needed to be an SPI slave device), JP4 needs to be in the RG9 (port G, bit 9) position. With JP4 in this position, the pin on the connector is accessed as digital pin 44. So, digitalRead(44) will return the value of the "SS" signal.

Digital pin 10 is mapped to RD4, and digital pin 44 is mapped to RG9. Jumper JP4 connects one or the other of these microcontroller pins to the connector pin labeled 10 in the silk screen on the board.

Gene Apperson Digilent