Problem reading from SPI bus with a dsPIC33FJ256MC710A using code from AN1069

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Problem reading from SPI bus with a dsPIC33FJ256MC710A using code from AN1069

Patrick Moody
Hi Piclist,

I've been a subscriber to this list for about 9 months now but I'm
pretty sure this is my first ever post, so I hope it's ok.  As per
subject I'm struggling to get SPI working properly on a dsPIC33F with
code borrowed from the microchip application note AN1069.  I've
searched through my collection of PIClist emails, googled, read all
the relevant data sheets I could find several times and posted the
following message in microchip's forum to try to resolve my problem
without finding anything useful yet.  I haven't had any response as
yet from the microchip forum but I only posted the message yesterday
so it may still be on its way.  I hope someone here can help.

If anyone can help me with the following problem I'd be very grateful.
 I've tried searching for previous posts and found nothing.  I do
wonder if it's at all related to the Silicon Errata (80484D) section
on SPI, though that appears to only relate to sending rather than
receiving:

When attempting to read from the SPI bus, SPIRBF goes high immediately
after the bus cycle is initiated causing 0xFF to be returned after
every attempt to read.  As this causes read function to finish
prematurely, it subsequently causes the CS line to go high prematurely
as well (5 cycles before the end of the byte I'm trying to read)

My hardware is:
A dsPIC33FJ256MC710A PIM on an explorer16 board, being debugged via an
ICD2 using MPLAB.
I also have an Intronix Logicport running via a separate laptop which
is hooked up to the relevant pins on the explorer16 EEPROM.

My software is taken from the microchip application note AN1069 "using
C30 compiler and SPI module to interface EEPROMs...."

The problem seems to appear within the following section of the code
(please let me know if it would help to include any more of the
source):
[code]
/******************************************************************************
*     Function Name :   ReadSPI2                                              *
*     Description   :   This function will read single byte/ word  from SPI   *
*                       bus. If SPI is configured for byte  communication     *
*                       then upper byte of SPIBUF is masked.
       *
*     Parameters    :   None                                                  *
*     Return Value  :   contents of SPIBUF register                           *
******************************************************************************/

unsigned int ReadSPI2()
{
  SPI2STATbits.SPIROV = 0;
  SPI2BUF = 0b10101010;                  // initiate bus cycle
   while(!SPI2STATbits.SPIRBF);    //suspect problem with this test!!!
   /* Check for Receive buffer full status bit of status register*/
  if (SPI2STATbits.SPIRBF)
  {
      SPI2STATbits.SPIROV = 0;
  //    while(SPI2BUF == 0xFF);    //wait for sensible value in buffer
- Really nasty bodge!!
      if (SPI2CON1bits.MODE16)
          return (SPI2BUF);           /* return word read */
      else
          return (SPI2BUF & 0xff);    /* return byte read */
  }
  return -1;                          /* RBF bit is not set return error*/
}
[/code]

Adding a breakpoint to the line if (SPI2STATbits.SPIRBF).... so as to
stop immediately after SPIRBF is seen to change to a 1, and looking at
SPI2BUF in the watch window, I see 0xFF.  When the code is left
running normally the same result is observed.  Having managed to write
a byte to the EEPROM in earlier tests I would expect to see the value
0x54 at this point.  According to the logic analyser, if indeed the
transfer had completed, I would see the correct value.  I also observe
via logic analyser that the CS line goes high approx 5 SCK cycles
before the transmission would be complete(when testing without a
breakpoint).  Again this appears to be a consequence of the premature
change of SPI2STATbits.SPIRBF which causes the entire read function to
return early, and move on to the next line of code which raises CS.

The really nasty bodge you see in my code works for reads, but only if
the value being read is not 0xFF, of course.  As this function is also
called in the process of writes, and it appears that this value is
returned in that process it causes the code to hang at this point.
That's why I had to comment it back out.  I'm desperately seeking
another way to get past this problem.
Any and all advice appreciated!

Thanks

Patrick
--
http://www.piclist.com PIC/SX FAQ & list archive
View/change your membership options at
http://mailman.mit.edu/mailman/listinfo/piclist
Reply | Threaded
Open this post in threaded view
|

Re: Problem reading from SPI bus

Olin Lathrop
Patrick Moody wrote:
> I do
> wonder if it's at all related to the Silicon Errata (80484D) section
> on SPI, though that appears to only relate to sending rather than
> receiving:

Every SPI transfer does both a read and write, so whatever the errata is
might still be relevant.

>   SPI2STATbits.SPIROV = 0;
>   SPI2BUF = 0b10101010;                  // initiate bus cycle

It would be a good idea to clear the SPIRBF bit right before each transfer.

>    while(!SPI2STATbits.SPIRBF);    //suspect problem with this test!!!
>    /* Check for Receive buffer full status bit of status register*/
>   if (SPI2STATbits.SPIRBF)

This makes no sense.  How can this IF ever fail?


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.
--
http://www.piclist.com PIC/SX FAQ & list archive
View/change your membership options at
http://mailman.mit.edu/mailman/listinfo/piclist
Reply | Threaded
Open this post in threaded view
|

Re: Problem reading from SPI bus

Patrick Moody
On 13 October 2010 13:06, Olin Lathrop <[hidden email]> wrote:

> It would be a good idea to clear the SPIRBF bit right before each transfer.
>
>>    while(!SPI2STATbits.SPIRBF);    //suspect problem with this test!!!
>>    /* Check for Receive buffer full status bit of status register*/
>>   if (SPI2STATbits.SPIRBF)
>
> This makes no sense.  How can this IF ever fail?

According to the datasheet, SPIRBF is read-only, else I would like to
have done as you suggest and clear it first.

I don't see how it's possible for the IF to fail either, but that's
how it's written in the application note I mentioned, which I (perhaps
wrongly) assume is a reasonable place to start from when trying to
write code to operate on the SPI bus.  I'll have another read through
the errata document and see if there's some way that is affecting
things.
Thanks

Patrick

--
http://www.piclist.com PIC/SX FAQ & list archive
View/change your membership options at
http://mailman.mit.edu/mailman/listinfo/piclist
Reply | Threaded
Open this post in threaded view
|

Re: Problem reading from SPI bus

Olin Lathrop
Patrick Moody wrote:
> According to the datasheet, SPIRBF is read-only, else I would like to
> have done as you suggest and clear it first.

According to the datasheet the bit itself if read only, but it is cleared by
reading the data register.

> I don't see how it's possible for the IF to fail either, but that's
> how it's written in the application note I mentioned, which I (perhaps
> wrongly) assume is a reasonable place to start from when trying to
> write code to operate on the SPI bus.

A reasonable assumption, but wrong.  Microchip example code generally sucks.
Read the datasheet, or in this case the family reference manual, and use
your own brain to write the code.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.
--
http://www.piclist.com PIC/SX FAQ & list archive
View/change your membership options at
http://mailman.mit.edu/mailman/listinfo/piclist
Reply | Threaded
Open this post in threaded view
|

Re: Problem reading from SPI bus with a dsPIC33FJ256MC710A using code from AN1069

thfktsc
This post has NOT been accepted by the mailing list yet.
In reply to this post by Patrick Moody
This is an old topic but i just see what the problem is and may others also need help.  Before read cycle initialization (SPIxBUF = ............ ) a read comment "SPIxBUF;" is required to empty SPIxRXB which is fulled by previous writes on MOSI for EEPROM chip commands.