Help on SPI

Thread Starter

davidmeetsall

Joined Dec 1, 2016
24
Configuration shows FOSC= INTOSC . OSCCON = x78. SPI clock is FOSC/4. So, SPI clock must be 4 MHz. But clock on oscilloscope shows only 825Khz. I am able to trace sent data on SDO line. Trying to find the issue on SDI line. Oscilloscope shows only 1 value. Any idea on the clock and SDI issue?

--David
 

jpanhalt

Joined Jan 18, 2008
11,087
I agree. If internal oscillator is defined in the configuration word, it is perfectly OK to leave OSCCON bits <1-0> clear:

upload_2016-12-5_13-47-24.png

0x78 is 16 MHz with PLL disabled according to the datasheet.

John
 

AlbertHall

Joined Jun 4, 2014
12,625
The OSCCON value should be 0x7A or 0x7B
If you want the internal clock to run at the speed selected by the IRCF bits in OSCCON then you do need to set the SCS bits.

From the datasheet:

5.3.1 SYSTEM CLOCK SELECT (SCS)
BITSThe System Clock Select (SCS) bits of the OSCCON
register selects the system clock source that is used for
the CPU and peripherals.
• When the SCS bits of the OSCCON register = 00,
the system clock source is determined by value of
the FOSC<2:0> bits in the Configuration Word 1.
• When the SCS bits of the OSCCON register = 01,
the system clock source is the Timer1 oscillator.
• When the SCS bits of the OSCCON register = 1x,
the system clock source is chosen by the internal
oscillator frequency selected by the IRCF<3:0>
bits of the OSCCON register. After a Reset, the
SCS bits of the OSCCON register are always
cleared
 

jpanhalt

Joined Jan 18, 2008
11,087
The OSCCON value should be 0x7A or 0x7B
If you want the internal clock to run at the speed selected by the IRCF bits in OSCCON then you do need to set the SCS bits.
You have misread the datasheet. There are different ways to set the correct frequency. Posted somewhere is a working example of this code with an SPI interface to a magnetometer.
Config:
upload_2016-12-5_17-22-26.png

OSCCON:
upload_2016-12-5_17-21-6.png

The chip is the 16F1783, but for setting the internal oscillator there is no difference.

John
 

Thread Starter

davidmeetsall

Joined Dec 1, 2016
24
Hi,

I am able to capture SCK, SDO and SDI data on oscilloscope. It was more of oscilloscope setting issue than softwareissue.
SCK, SDO o/p is correct but SDI data is not as per expected. I will see this.
But I am seeing two issues. I have used MCC code. As SPI write and read happens at the same time, I send my write command of 8-bytes first. Then as per protocol give some delay and then send dummy data 8-bytes to get the response. Here is the code:
Code:
uint8_t SPI_Exchange8bitBuffer(uint8_t *dataIn, uint8_t bufLen, uint8_t *dataOut)
{
    uint8_t bytesWritten = 0;

    if(bufLen != 0)
    {
        if(dataIn != NULL)
        {
            while(bytesWritten < bufLen)
            {
                if(dataOut == NULL)
                {
                    SPI_Exchange8bit(dataIn[bytesWritten]);
                }
                else
                {
                    dataOut[bytesWritten] = SPI_Exchange8bit(dataIn[bytesWritten]);
                }
                bytesWritten++;
            }
        }
        else
        {
            if(dataOut != NULL)
            {
                while(bytesWritten < bufLen )
                {
                    dataOut[bytesWritten] = SPI_Exchange8bit(DUMMY_DATA);
                    bytesWritten++;
                }
               [B]memcpy(buf, dataOut, bytesWritten);[/B]
            }
        }
    }
    return bytesWritten;
}
As per my understanding, In above equation, For write operation, I keep sending bytes to dataIn and make dataOut as NULL. I don't care data coming from slave. After this I insert a delay.
For read operation, I make dataIn as NULL and send dummy data and keep reading. I copy the all read bytes in buf using memcpy.

Now,
Code:
main()
{
     while()
      {  
             //call below function 8-times
            SPI_Exchange8bitBuffer(dataIn, bufLen, NULL);   //Write - write from PIC
             delay;
              //call below function 8-times
             SPI_Exchange8bitBuffer(NULL, bufLen, dataOut);   // Read which is response from slave. 
       }
}
Is this correct for write and Read?
I see two main issues when I debug and keep it Running
1. buf value which is response from slave (Seen by watching the value while debugging) is different from what I see in oscilloscope. Why?
2. In oscilloscope I see the response data along with clock first and then I see the write data. Why? Is it bcoz debugging in Running state? But in main function, I call write first and then read.
Please help.

--David.
 
Top