0
votes

I'm struggling with, probably, a very simple problem. I have a Cypress CY8 controller acting as SPI master, which should communicate with a PIC32mx in slave mode to exchange data packets.

However i cannot even fix simple transmission of multiple bytes from the master to the slave. I've set up the cypress to transmit a char of increasing value (0-255) with a pause (and slave select toggle) in between. The pic should read the incoming byte and then print it over uart to my pc (the uart connection works). But the pic only prints the first character it receives continuously instead of it being updated. If i check my logic sniffer, the cypress does send incrementing values and the pic relays them back over the MISO line (looks like the shift buffer isn't cleared).

What could this be?

The cypress without the pic attached gives proper output: https://dl.dropboxusercontent.com/u/3264324/Schermafdruk%202015-07-28%2015.43.28.png With the pic attached it relays the data over MISO: https://dl.dropboxusercontent.com/u/3264324/Schermafdruk%202015-07-28%2015.43.45.png

And this is my (now) extremely basic code to test it:

TRISBbits.TRISB2 = 1; // make Ra2 pin input (SDI)
TRISBbits.TRISB5 = 0; // make Ra2 pin output (SDO)
TRISBbits.TRISB15 = 1; //make RB14 output (SCK)

ANSELA = 0; // all ports digital
ANSELB = 0; // all ports digital

SYSKEY = 0x00000000;
SYSKEY = 0xAA996655;
SYSKEY = 0x556699AA;
CFGCONbits.IOLOCK=0; // unlock configuration
CFGCONbits.PMDLOCK=0;


SDI2R = 0b0100; //SDI2 on pin RB2
SS2R = 0b0011; //SS2 on pin rb10
RPB5R = 0b0100; //SDO2 on pin RB5
// SCLK is connected to pin RB14 (SCK) by default
SYSKEY = 0x00000000;

   SPI2CON = 0; // Stops and resets the SPI1.
   rData=SPI2BUF; // clears the receive buffer
   SPI2BRG=207; // use FPB/4 clock frequency  <-- not important in slave mode right?
   SPI2STATCLR=0x40; // clear the Overflo
    SPI2CON=0x8180;

    unsigned char t;
    while(1){
        t = SpiChnReadC(2);
        //t = SPI2BUF; <== i've tried this also
        sendData(t); <== uart routine
    }

As i do receive a character and the spi data is relayed back to the cypress constantly i think something goed wrong with reading/clearing the spi data structure in the PIC. But i can't figure out why. As i read in the datasheet, reading from SPI2BUFF gives me the received data, and clears the read flags so new data can be received, but it looks like that doesn't happen...

Can someone shine a light on this for me?

Thanks in advance Timberleek

1
Does SpiChnReadC(2) block until a byte has been received, or does it just return SPI2BUF? - Sigve Kolbeinson
SPIChnReadC returns immediately according to the header file. So i would expect maybe a couple of double prints. However it keeps printing the same value for minutes (and probably longer) although the data on the spi bus itself does change (according to the logic sniffer). Restarting the pic results in the same situation, but with a different value being printed - tim kers
1) "pic only prints the first character it receives continuously" --> what is that value? 2) If code was while(1){ sendData(t++);}, does your receiving system report incrementing data? - chux - Reinstate Monica
That value depends on the value on the bus at startup of the pic. If i powercycle the pic, a different value gets printed. It simply looks like it reads as it should, but only the first time. After that, the spi buffer keeps returning the same character. using only sendData(t++) with t initialized at 0 before the loop, the printed data increments as expected. t = SpiChnReadC(2); sendData(t++); <== uart routine also continuously prints the same value - tim kers
Note: use stdint.h types if you require a fixed size type! Do not realy on the standard integer types. - too honest for this site

1 Answers

0
votes

You should try making you SPI handler ISR driven to keep you from constantly polling, can also help the debugging since you'll only get notifications when the SPI is actually transacting.

NOTE: I'm bringing this from my FreeRTOS impl, so my ISR definition is not XC32 exactly...

/* Open SPI */
SPI1CON = 0;
spi_flags = SPICON_MODE32 | SPICON_ON;
SpiChnOpen(1,spi_flags,BRG_VAL);
SpiChnGetRov(1,TRUE);
mSPI1ClearAllIntFlags();
mSPI1SetIntPriority(priority + 1);
mSPI1SetIntSubPriority(0);
mSPI1RXIntEnable(1);


void vSPI1InterruptHandler(void)
{
    unsigned long data;

    if (IFS0bits.SPI1EIF == 1)
    {
       mSPI1EClearIntFlag();
    }
    if (IFS0bits.SPI1RXIF == 1)
    {
        data = SPI1BUF;
        //sendData(data);
    }
    mSPI1RXClearIntFlag();
}