SDFileSystem & K-Series PIC

General discussion relating to the library modules supplied with the compiler

Moderators: David Barker, Jerry Messina

Post Reply
User avatar
Senacharim
Posts: 139
Joined: Tue Aug 10, 2010 5:19 pm
Location: Ventura, CA

SDFileSystem & K-Series PIC

Post by Senacharim » Mon Nov 22, 2010 8:01 pm

Hey all,
Recently began attempting to get a newest-of-the-new K-Series PIC going. It features 2 USARTS and 2 MSSP hardware modules on the 28 pin PIC. The 18F25K22.

With only minor modifications to the USART2 module, I've gotten the 2 USARTS working like a charm.

My only use for the MSSP modules is to interface with an SD card. When I include the SDFileSystem module, it compiles without error... I've double-checked the hardware references in the module and they appear to be correct. Double-checked the bits set in the SSP1 control & stat registers and they appear to be accurate. I've compiled it using MSSP and SW options, and regardless of what I do, the Card-Init routine consistently fails.

For comparison, the exact same code compiled for a 18F2620 put into the same circuit board runs without error.

I'm rapidly reaching the end of my troubleshooting prowess, and would greatly appreciate suggestions/assistance in solving this difficulty.

Thanks in advance..
Surviving Member
Bermuda Triangle Battalion
from 2026 to 1992

Voted "Most likely to time travel"--Class of 2024.

User avatar
Senacharim
Posts: 139
Joined: Tue Aug 10, 2010 5:19 pm
Location: Ventura, CA

Post by Senacharim » Mon Nov 22, 2010 9:50 pm

Well, got it going.

Ended up having to make my own copy of the SDFileSystem module and modify it with a few defines specifically for my K-Series PIC. (I'm sure David would have done a better job, but I've got it going well enough for my purposes.)

So, turns out there an ANSELx register in addition to every TRISx register. The combination of bit settings between the two registers determines the function of the pin, AND whether it's analogue or digital.


For David:
Here's the only function which I modified in the SDFileSystem module to get it working with a 18F25K22 PIC.

Code: Select all

{
********************************************************************************
* Name    : InitSequence (PRIVATE)                                             *
* Purpose : Init SD or MMC card.                                               *
*         : Sets Input/Output pins and switches card to SPI mode.              *
*         : Return: 0 = Success, 1 = Fail/card not present.                    *
*         : Either software or hardware SPI can be used by selecting           *
*         : #option SD_SPI = SW or #option SD_SPI = MSSP                       *
********************************************************************************
}   
Function InitSequence() As Boolean
Dim Index As Word
Dim OCR(4) As Byte
   #if SD_SPI = MSSP                             // MSSP version
      SSPControl1 = %00000000                    // Turn off MSSP module for SW slow init
   #endif
   Disk.SlowSPI = 1                              // Set SPI to slow mode for initialisation
#if _device = 18LF25K22
    TRISA.4 = 0
    ANSELA.4 = 1
    
    TRISC.3 = 0
    ANSELC.3 = 1
    
    TRISC.4 = 1
    ANSELC.4 = 0
    
    TRISC.5 = 0
    ANSELC.5 = 1
#else
   Output(CS)                                    // Setup direction for SPI bus
   Output(DI)
   Output(CLK)
   Input(DO)
#endif
   InitSequence = False
   Disk.CardType = 0
   CS = 1                                        // Pull CS high
   Index = 10
   Repeat                                        // Clock SD for min 80 cycles
      SendByte($FF)
      Dec(Index)
   Until Index = 0
   DelayMS(100)
   CS = 0                                                // Pull CS low
   If SendCmd(CMD0, $00000000) = $01 Then                // Send Cmd 0 - enter idle state
      If SendCmd(CMD8, $000001AA) = $01 Then             // SDC Version 2+
         For Index = 0 To 3
            OCR(Index) = ReceiveByte()
         Next
         If OCR(2) = $01 And OCR(3) = $AA Then           // SD Vdd range of 2.7 - 3.6 volts
            Index = TimeOutLimit
            Repeat
               Dec(Index)               
            Until Cmd5541(True) = 0 Or Index = 0         
            If Index > 0 Then                            // Cmd 55/41 successful with HCS bit set
               If SendCmd(CMD58, $00000000) = 0 Then     // Send Cmd 58
                  For Index = 0 To 3
                     OCR(Index) = ReceiveByte()
                  Next
                  If (OCR(0) And $40) > 0 Then           // CCS[30] bit in the OCR set
                     Disk.CardType = sdSDHC              // Init successful - SDHC (3)
                  Else                 
                     Disk.CardType = sdSD                // Init successful - SD (2)
                  EndIf
               EndIf
            EndIf
         EndIf
      Else                                               // SD Version 1 or MMC
         If Cmd5541(False) <= 1 Then                     
            Disk.CardType = sdSD                         // Init successful - SD (2)
            Index = TimeOutLimit
            Repeat
               Dec(Index)               
            Until Cmd5541(True) = 0 Or Index = 0         // Wait for leaving idle state
         Else                  
            Disk.CardType = sdMMC                        // Init successful - MMC (1)
            Index = TimeOutLimit
            Repeat
               Dec(Index)               
            Until SendCmd(CMD1, $00) = 0 Or Index = 0    // Wait for leaving idle state
         EndIf
         If Index = 0 Then
            Disk.CardType = 0
         EndIf    
      EndIf
   EndIf
   CS = 1
   SendByte($FF)                                         // Clock SD/MMC to complete
   If Disk.CardType > 0 Then
      InitSequence = True
      #if SD_SPI = MSSP                                  // MSSP version
        #if _device = 18LF25K22
            TRISA.4 = 0
            ANSELA.4 = 1
            
            TRISC.3 = 0
            ANSELC.3 = 1
            
            TRISC.4 = 1
            ANSELC.4 = 0
            
            TRISC.5 = 0
            ANSELC.5 = 1
        #endif
         SSPControl1 = SPISpeed Or %00100000             // Setup MSSP module & turn on
         SSPStatus = %01000000                         
      #endif
      Disk.SlowSPI = 0                                   // Set SPI to fast mode
   EndIf
End Function
You'll note the changed portions appear between #if _device = 18LF25K22 and #endif. Also, my modification completely lacks flexibility--"by reference" pin/register assignments in Swordfish are still just a tad over my head. Works though.

Cheers.
Surviving Member
Bermuda Triangle Battalion
from 2026 to 1992

Voted "Most likely to time travel"--Class of 2024.

User avatar
Senacharim
Posts: 139
Joined: Tue Aug 10, 2010 5:19 pm
Location: Ventura, CA

Post by Senacharim » Tue Nov 23, 2010 3:42 pm

Update:
Doesn't work in MSSP mode, though works consistently in SW mode. Not sure why it's failing to engage the MSSP hardware. Hope this helps somebody out there with a similar conundrum someday.
Surviving Member
Bermuda Triangle Battalion
from 2026 to 1992

Voted "Most likely to time travel"--Class of 2024.

gramo
Registered User
Registered User
Posts: 200
Joined: Tue Mar 20, 2007 6:55 am
Location: Australia
Contact:

Post by gramo » Wed Nov 24, 2010 7:38 pm

There are a few SPI errata issues to deal with on the current silicon revisions.. Even the latest B3/B4/B5 have their fair share
digital-diy.com - Hobby microcontroller projects and tutorials. Assembly, PICBasic and C examples.

Australian distributor for the Swordfish Compiler

User avatar
ohararp
Posts: 194
Joined: Tue Oct 03, 2006 11:29 pm
Location: Dayton, OH USA
Contact:

Post by ohararp » Tue Aug 28, 2012 5:27 pm

Senachrim, I am trying to get this up and running in HW MSSP mode. Did you ever get anything working? I am using the 18F26K22 and am having a bit of trouble with the SDFileSystem.bas
Thanks Ryan
$25 SMT Stencils!!!
www.ohararp.com/Stencils.html

Jerry Messina
Swordfish Developer
Posts: 1473
Joined: Fri Jan 30, 2009 6:27 pm
Location: US

Post by Jerry Messina » Tue Aug 28, 2012 9:02 pm

The ANSELx bits that correspond to the MSSP pins you're using should be set to 0 and left that way.
Don't set them high... that will cause them to be analog and they'll always read as 0 which can cause funnies with read-modify-write operations.

Also, the 26K22 has slew-rate control on the pins, and it defaults to slow mode. Check out the SLRCON register.

User avatar
ohararp
Posts: 194
Joined: Tue Oct 03, 2006 11:29 pm
Location: Dayton, OH USA
Contact:

Post by ohararp » Tue Aug 28, 2012 9:09 pm

Jerry, thanks for the tip. I now see why your Set All Digital becomes important for these chips. I'll double check on the SLRCON stuff as well. Lots have changed on this chip!

Update 03SEP2012:

USing the SetAllDigital code and calling this SetAllDigital() command during an init sequence made my code work with the 18F26K22 no problem! Thanks Jerry!
Thanks Ryan
$25 SMT Stencils!!!
www.ohararp.com/Stencils.html

Post Reply