Or rather: The SPI That Fooled Me ---------------------- I just posted this message on the Microchip Forums, but I thought I'd share this with all of you on the PICList as well. If my mistake can help others, heck, it will be worth it (I'm sure it's not new to many of you, but for some people it may not be): Alright, sorry, this is not about James Bond, but now that I have your attention, let me wipe the egg from my face, get serious, and share some information about the MSSP (Master Synchronous Serial Port) module that recently caught me off guard. The intention of this post is to prevent others from making the same mistake that I did, and also to prevent them from wasting time troubleshooting what's wrong with SPI (Serial Peripheral Interface) reception in their SPI application. A lot of people already know about the information in this post (very old news), but I think it's a good idea to bring this subject up especially for people who are not aware of it. I don't recall seeing this discussed very much. In a lot (but not all) of Microchip data sheets and reference manuals that describe the MSSP module in SPI mode, you'll sometimes see the following line under the ENABLING SPI I/O heading title: SDI is automatically controlled by the SPI module This is how some older MSSP modules used to work (the PIC16F877-20/P B3 silicon for example), but the statement above describes MSSP silicon errata which has been long since corrected, and therefore makes that statement false for current devices. So if the SDI pin was automatically controlled by the SPI module, why was this considered MSSP errata? My best guess is for the simple fact that by having the MSSP module override the SDI's TRIS setting, the user was prevented from making the SDI a general-purpose output pin if he/she so desired. For example, if a user was going to use the MSSP module to only transmit information over the SPI bus, only the SDO pin would be needed and thus the SDI pin would obviously not be needed for SPI communication in a master transmit-only application. Since free I/O pins are hard to come by in most microcontroller designs, it would make sense that a user should be able to use the SDI pin as a general-purpose output, for example. This would be one of the reasons for the following statement (also under the ENABLING SPI I/O heading title): Any serial port function that is not desired may be overridden by programming the corresponding data direction (TRIS) register to the opposite value. Unfortunately, this is not possible for the SDI pin due to how the early MSSP modules worked in SPI mode. As soon as you would enable the module by setting SSPEN, the SDI pin would automatically and unconditionally become an input -- regardless of the setting of the TRIS bit associated with that SDI pin. If I have my PICmicro history correct, the PIC16F877 microcontroller was the first Microchip microcontroller with a MSSP module (please note that I'm using the term MSSP, not SPP which was the precursor to the MSSP module). At some point in time the MSSP module was changed (the MSSP errata was fixed) with regard to how the SDI pin is configured. In the newer MSSP modules, the statement "SDI is automatically controlled by the SPI module" is no longer true. Whether the SDI pin is an input or an output is not controlled by the SPI module, by rather by the TRIS bit setting that is associated with the SDI pin. Therefore, if the user does not need to use the SDI pin in a SPI application, the user can use the SDI pin as a general-purpose output. This means that the user has two options for configuring the TRIS bit associated with the SDI pin: 1) If the user needs to receive information from the SPI bus, the TRIS bit associated with the SDI pin MUST be set ( = 1). 2) If the user does not need to receive information from the SPI bus, he/she can use that pin as a general-purpose output, and the TRIS bit associated with the SDI pin MUST be cleared ( = 0). Please keep this information in mind when working with the MSSP module's SPI mode on PIC microcontrollers. The good news is that you'll some data sheets that have the correction in place under the ENABLING SPI I/O title (the PIC18F2220/2320/4220/4320 for example): SDI must have TRISC<4> bit set However, as I have stated above, there are many instances in data sheets and reference manuals where it still states that "SDI is automatically controlled by the SPI module" and fails to state that the TRIS bit associated with SDI must be set. I would imagine that it was just wording that was carried over from the original PIC16F877 data sheet and was never changed after the MSSP errata fix was made. I don't believe the statement, "SDI is automatically controlled by the SPI module", is true for any PICmicros that are currently in production or in the distribution channels. Therefore, you always want to make sure you explicitly make the SDI pin an input if you need to use it in your SPI application. In any event, it is very easy to test the behavior with a few lines of code. So what was the driving force in posting this message at all? Well, I recently developed a project with some very old PIC16F877 microcontrollers that I had on hand -- ones that exhibited the aforementioned MSSP silicon errata (since the date codes were before 9925). I had explicitly set the SDI as an output (TRISC<4> = 0) knowing that once the MSSP module was enabled for SPI mode the SDI pin would turn into an input (which it did). Everything worked perfectly -- including SPI reception. But then I used the same code and compiled it for a PIC16F877A microcontroller. The latest PIC16F877A data sheet included the same "SDI is automatically controlled by the SPI module" reference as the early PIC16F877 data sheets, so there was no reason for me to think the MSSP module of the new PIC16F877A would act any differently than its elderly counterpart. Boy, how wrong I was as I've explained above! Had I tested the PIC16F877A properly and extensively, I would have caught the discrepancy. In addition I failed in carefully researching the errata documentation which I usually do. This was an awesome and humbling learning experience, but 100% entirely my fault! Experiences like these are good because they teach you not to be complacent and that you must always test and pay attention. My aim in this post is not to be misleading in any way, and I'd tried my best to be as accurate as possible in explaining things in the spirit of helping others (and poking fun at myself in the process), but if anyone sees any errors in this post, please correct me where I'm wrong or post any constructive criticism. Humans make mistakes and these mistakes can sometimes seep into code (which I hate when it happens), but through forums like these, there is great potential that coding errors can be minimized by the sharing of knowledge and past mistakes and "battle scars". Many times it's the little and simple things that screw us up. I hope this post helps someone. Thank you and best regards, Ken Pergola -- http://www.piclist.com hint: The PICList is archived three different ways. See http://www.piclist.com/#archives for details.