Page 4 of 5

Re: Pico Mounting SD Card

Posted: Mon Dec 20, 2021 3:48 pm
by FeK9
Sorry No, thats beyond my pay grade... :D

Re: Pico Mounting SD Card

Posted: Mon Dec 20, 2021 3:50 pm
by SchroedersKater
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.

Re: Pico Mounting SD Card

Posted: Mon Dec 20, 2021 3:52 pm
by SchroedersKater
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.

Re: Pico Mounting SD Card

Posted: Tue Dec 21, 2021 9:00 am
by SchroedersKater
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.

Re: Pico Mounting SD Card

Posted: Tue Apr 05, 2022 6:50 pm
by PM-TPI
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??

Re: Pico Mounting SD Card

Posted: Tue Apr 05, 2022 7:24 pm
by PM-TPI
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 !!!

Re: Pico Mounting SD Card

Posted: Mon Sep 26, 2022 1:19 pm
by jcf
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.

Re: Pico Mounting SD Card

Posted: Mon Sep 26, 2022 1:31 pm
by jcf
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?

Re: Pico Mounting SD Card

Posted: Mon Sep 26, 2022 1:34 pm
by Roberthh
close() implies flush().

Re: Pico Mounting SD Card

Posted: Mon Sep 26, 2022 1:41 pm
by jcf
That's what I thought. So it is not needed.