Pico Mounting SD Card

RP2040 based microcontroller boards running MicroPython.
Target audience: MicroPython users with an RP2040 boards.
This does not include conventional Linux-based Raspberry Pi boards.
FeK9
Posts: 33
Joined: Sun Jan 20, 2019 8:19 am

Re: Pico Mounting SD Card

Post by FeK9 » Mon Dec 20, 2021 3:48 pm

Sorry No, thats beyond my pay grade... :D

User avatar
SchroedersKater
Posts: 11
Joined: Sun Dec 19, 2021 4:09 pm
Location: Near Bonn & Cologne, Germany

Re: Pico Mounting SD Card

Post by SchroedersKater » Mon Dec 20, 2021 3:50 pm

OK, I invalidated the code that determines the type of card and made the driver think, the card is a version 1 type and it works. The card is accessible now.

Now I have to find out how this card identifies itself as a version 1 card to differentiate between the different versions. There must be a second indicator that tells me this, because otherwise the readers at my other computers could not determine these cards correctly.

User avatar
SchroedersKater
Posts: 11
Joined: Sun Dec 19, 2021 4:09 pm
Location: Near Bonn & Cologne, Germany

Re: Pico Mounting SD Card

Post by SchroedersKater » Mon Dec 20, 2021 3:52 pm

Your post and mine became overlapped. Hope you don't get paid too bad. :lol:

Thank you very much anyway! Your help was very much appreciated.

User avatar
SchroedersKater
Posts: 11
Joined: Sun Dec 19, 2021 4:09 pm
Location: Near Bonn & Cologne, Germany

Re: Pico Mounting SD Card

Post by SchroedersKater » Tue Dec 21, 2021 9:00 am

Well, I found out that there are SD cards that say they are version 2 cards, but in fact they are not. To get around this lie I modified sdcard.py like this. I hope someone profits from this.

The timeout code looks different for version 1 and 2, so I modified this as well.

Code: Select all

_CMD_TIMEOUT = const(10) #oth a 0.5 second delay should be enough for any card to become ready
And here is the modified code for both versions.

Code: Select all

    def init_card_v1(self):
        for i in range(_CMD_TIMEOUT):
            self.cmd(55, 0, 0)
            if self.cmd(41, 0, 0) == 0:
                self.cdv = 512
                # print("[SDCard] v1 card")
                return
            time.sleep_ms(50) #oth
        raise OSError("timeout waiting for v1 card")

    def init_card_v2(self):
        #oth check if it eventually works like a v1 card
        for i in range(_CMD_TIMEOUT):
            self.cmd(55, 0, 0)
            if self.cmd(41, 0, 0) == 0:
                self.cdv = 512
                print("[SDCard] v1a card")
                return
            time.sleep_ms(50)

        # current state is undefined, so try again from beginning

        # clock card at least 100 cycles with cs high
        for i in range(16):
            self.spi.write(b"\xff")

        # CMD0: init card; should return _R1_IDLE_STATE (allow 5 attempts)
        for _ in range(5):
            if self.cmd(0, 0, 0x95) == _R1_IDLE_STATE:
                break
        else:
            raise OSError("no SD card")

        # CMD8: determine card version, but ignore in this case
        r = self.cmd(8, 0x01AA, 0x87, 4)
        #oth

        for i in range(_CMD_TIMEOUT):
            self.cmd(58, 0, 0, 4)
            self.cmd(55, 0, 0)
            if self.cmd(41, 0x40000000, 0) == 0:
                self.cmd(58, 0, 0, 4)
                self.cdv = 1
                print("[SDCard] v2 card")
                return
            time.sleep_ms(50) #oth
        raise OSError("timeout waiting for v2 card")
I marked the modifications with "#oth".

Hope, this helps someone.

PM-TPI
Posts: 75
Joined: Fri Jun 28, 2019 3:09 pm

Re: Pico Mounting SD Card

Post by PM-TPI » Tue Apr 05, 2022 6:50 pm

using a...
MicroPython v1.17-805-g7b1d10d69-dirty on 2022-04-05; 4MB/OTA/SPIram module with ESP32

Now getting [Errno 5] EIO errors, never had with a v2 8GB card.
Been logging, reading for months no issue.
Needed your fix for production units already received with 2GB v2 (not realy) cards.
You fix does correct the initializing of cards !!!
Have not tested 2GB cards with fix but went back to my dev unit to now have [Errno 5] EIO errors.
The error is hit or miss, I have changed _CMD_TIMEOUT = const(), for your 10,
but have also tried 20, 50, and back to orginal 100, still get random errors.

Did I implemented correctly below...

Code: Select all

    def init_card_v1(self):
        for i in range(_CMD_TIMEOUT):
            self.cmd(55, 0, 0)
            if self.cmd(41, 0, 0) == 0:
                self.cdv = 512
                print("[SDCard] v1 card")
                return
        raise OSError("timeout waiting for v1 card")

    ## ORIGINAL
    # def init_card_v2(self):
    #     for i in range(_CMD_TIMEOUT):
    #         time.sleep_ms(50)
    #         self.cmd(58, 0, 0, 4)
    #         self.cmd(55, 0, 0)
    #         if self.cmd(41, 0x40000000, 0) == 0:
    #             self.cmd(58, 0, 0, 4)
    #             self.cdv = 1
    #             print("[SDCard] v2 card")
    #             return
    #     raise OSError("timeout waiting for v2 card")

    ## UPDATED
    def init_card_v2(self):
        #oth check if it eventually works like a v1 card
        for i in range(_CMD_TIMEOUT):
            self.cmd(55, 0, 0)
            if self.cmd(41, 0, 0) == 0:
                self.cdv = 512
                print("[SDCard] v1a card")
                return
            time.sleep_ms(50)

        # current state is undefined, so try again from beginning
        # clock card at least 100 cycles with cs high
        for i in range(16):
            self.spi.write(b"\xff")

        # CMD0: init card; should return _R1_IDLE_STATE (allow 5 attempts)
        for _ in range(5):
            if self.cmd(0, 0, 0x95) == _R1_IDLE_STATE:
                break
        else:
            raise OSError("no SD card")

        # CMD8: determine card version, but ignore in this case
        r = self.cmd(8, 0x01AA, 0x87, 4)
        #oth

        for i in range(_CMD_TIMEOUT):
            self.cmd(58, 0, 0, 4)
            self.cmd(55, 0, 0)
            if self.cmd(41, 0x40000000, 0) == 0:
                self.cmd(58, 0, 0, 4)
                self.cdv = 1
                print("[SDCard] v2 card")
                return
            time.sleep_ms(50) #oth
        raise OSError("timeout waiting for v2 card")
I feel this is a timming issue of some sorts.
Do not know where to start realy
Could you also explain briefly how you are filtering out the cards.

Are read and write to sd, going thru this section of code??

PM-TPI
Posts: 75
Joined: Fri Jun 28, 2019 3:09 pm

Re: Pico Mounting SD Card

Post by PM-TPI » Tue Apr 05, 2022 7:24 pm

I used a new sdcard.py file that did not have Peter Hinch fix of...
self.spi.write(b"\xff")
after
def readblocks(self, block_num, buf):
def writeblocks(self, block_num, buf):

All appears to be fine !!!

User avatar
jcf
Posts: 60
Joined: Wed Mar 03, 2021 11:14 am

Re: Pico Mounting SD Card

Post by jcf » Mon Sep 26, 2022 1:19 pm

Because I always got confused with the different SDcard adaptors and the wiring, I wrote a document on the subject:
http://staff.ltam.lu/feljc/electronics/ ... SDcard.pdf
Maybe it can help someone.

User avatar
jcf
Posts: 60
Joined: Wed Mar 03, 2021 11:14 am

Re: Pico Mounting SD Card

Post by jcf » Mon Sep 26, 2022 1:31 pm

When writing this document I noticed some things that are still not clear to me:
  • I mount the card like this:

    Code: Select all

    vfs = os.VfsFat(sd)
    os.mount(vfs, "/SD")
    and also tried this:

    Code: Select all

    vfs = os.VfsFat(sd)
    os.mount(vfs, "/")
    there seemed to be no difference, I could access and write files on the card.

    In the first case, sometimes the /SD folder showed in the Thonny file window, sometimes it did not.
  • Somewhere (in the German Make magazine) I read that the flush function should be used when writing a file:

    Code: Select all

    f = open ("test.txt", "w")
    f.write("Hello world\n")
    f.flush()
    f.close()
    I never used it and there was no problem. Should I flush, yes or no?

User avatar
Roberthh
Posts: 3667
Joined: Sat May 09, 2015 4:13 pm
Location: Rhineland, Europe

Re: Pico Mounting SD Card

Post by Roberthh » Mon Sep 26, 2022 1:34 pm

close() implies flush().

User avatar
jcf
Posts: 60
Joined: Wed Mar 03, 2021 11:14 am

Re: Pico Mounting SD Card

Post by jcf » Mon Sep 26, 2022 1:41 pm

That's what I thought. So it is not needed.

Post Reply