Shop OBEX P1 Docs P2 Docs Learn Events
SPI Programming in P2ASM — Parallax Forums

SPI Programming in P2ASM

Hello!

I been working with SPI code a bit and the onboard SPI flash for the P2 Edge. I stumbled upon this code for an SPI programming but ran it through FlexProp and got an error for this line:
https://forums.parallax.com/discussion/165060/spi-flash-programmer-code/p1

testin  #spi_do     wc

to this

testp   #spi_do     wc

However, it doesn't seem to blink anything. I was able to try some of the code for reading and changed a few things. When I Compile and Flash a program via FlexProp the program is stored. I can then read/run the program on flash. Not sure why the code in the thread does not seem to work for the writing though.

Comments

  • RaymanRayman Posts: 15,316

    testp looks right. Not sure why doesn't work... Maybe post full code?

  • RaymanRayman Posts: 15,316

    You can get the spreadsheet with all the P2 assembly instructions here:
    https://www.parallax.com/propeller-2/documentation/

  • Hey there @Rayman!

    Sure thing! Here is that complete code:

    ' Program SPI flash with signed OUTB blinker program
    ' - Connect SPI flash (M25P80 okay) with pull-ups on spi_cs and spi_ck
    ' - Blinks OUTB on boot-up
    
    CON
    
      spi_cs = 61
      spi_ck = 60
      spi_di = 59
      spi_do = 58
    
    DAT
    
    
            org
    '
    '
    ' Init SPI pins
    '
            outh    #spi_cs
    
            dirh    #spi_cs
            dirh    #spi_ck
            dirh    #spi_di
    '
    '
    ' Erase 1st $1000 bytes
    '
            call    #spi_wrena      'write enable
    
            mov cmd,cmd_erase       'sector erase
            call    #spi_cmd32
    
            call    #spi_wait       'wait for completion
    '
    '
    ' Program first $400 bytes
    '
            loc ptra,#\pgmdata      'point to program data
    
    .program    call    #spi_wrena      'write enable
    
            mov cmd,cmd_program     'page program
            or  cmd,adr
            call    #spi_cmd32
    
    .byte       rdbyte  cmd,ptra++      'get byte
    
            mov x,#8            'send byte
            shl cmd,#24
            call    #spi_out
    
            add adr,#1          'page done?
            test    adr,#$FF    wz
        if_nz   jmp #.byte
    
            call    #spi_wait       'wait for completion
    
            testb   adr,#10     wz  'another page?
        if_z    jmp #.program
    '
    '
    ' Read data back to outa for viewing on logic analyzer
    '
            mov dira,#$1FF
    
    .read1k     mov cmd,cmd_read        'start read
            call    #spi_cmd32
    
            outh    #8          'trigger signal
            outl    #8
    
            decod   y,#10           'read byte to outa
    .read       call    #spi_in
            setbyte outa,cmd,#0
            djnz    y,#.read
    
            jmp #.read1k        'loop
    '
    '
    ' SPI write enable
    '
    spi_wrena   mov cmd,#$06        'write enable
            call    #spi_cmd8
    
            ret
    '
    '
    ' SPI wait while busy
    '
    spi_wait    mov cmd,#$05
            call    #spi_cmd8
    
    .wait       call    #spi_in
            test    cmd,#$01    wc
        if_c    jmp #.wait
    
            ret
    '
    '
    ' SPI command
    '
    spi_cmd32   mov x,#32
            jmp #spi_cmd
    
    spi_cmd8    mov x,#8
            shl cmd,#24
    
    spi_cmd     outh    #spi_cs
            outl    #spi_cs
    '
    '
    ' SPI long/byte out (x=bits, cmd=msbdata)
    '
    spi_out     rep @.r,x
            shl cmd,#1      wc
            outc    #spi_di
            outh    #spi_ck
            outl    #spi_ck
    .r
            ret
    '
    '
    ' SPI byte in (cmd)
    '
    spi_in
        mov y, #8
        mov cmd, #0
    .rdloop
        outh    #spi_ck
        testp   #spi_do wc
        rcl cmd, #1
        outl    #spi_ck
        djnz    y, #.rdloop
        ret
    '
    '
    ' Data
    '
    cmd_erase   long    $20_00_00_00
    cmd_program long    $02_00_00_00
    cmd_read    long    $03_00_00_00
    adr     long    0
    '
    '
    ' Variables
    '
    cmd     res 1
    x       res 1
    y       res 1
    '
    '
    ' Program Data
    '
    ' first 20 bytes are blinker program:
    '
    '   not dirb
    '.lp    not outb
    '   waitx   ##20_000_000/4
    '   jmp #.lp
    '
    ' last 32 bytes are signature (key=0)
    '
        orgh
    
    pgmdata byte    $FB,$F7,$23,$F6,$FD,$FB,$23,$F6,$25,$26,$80,$FF,$28,$80,$66,$FD 'blinker program
        byte    $F0,$FF,$9F,$FD,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
        byte    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
        byte    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
        byte    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
        byte    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
        byte    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
        byte    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
        byte    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
        byte    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
        byte    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
        byte    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
        byte    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
        byte    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
        byte    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
        byte    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
        byte    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
        byte    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
        byte    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
        byte    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
        byte    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
        byte    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
        byte    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
        byte    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
        byte    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
        byte    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
        byte    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
        byte    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
        byte    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
        byte    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
        byte    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
        byte    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
        byte    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
        byte    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
        byte    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
        byte    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
        byte    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
        byte    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
        byte    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
        byte    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
        byte    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
        byte    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
        byte    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
        byte    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
        byte    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
        byte    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
        byte    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
        byte    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
        byte    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
        byte    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
        byte    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
        byte    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
        byte    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
        byte    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
        byte    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
        byte    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
        byte    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
        byte    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
        byte    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
        byte    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
        byte    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
        byte    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
        byte    $99,$AA,$44,$98,$86,$E2,$C8,$71,$C3,$1E,$60,$BF,$A3,$36,$19,$7A 'SHA-256/HMAC signature
        byte    $F5,$3D,$53,$97,$5C,$AF,$BA,$BB,$B7,$7F,$C3,$0A,$B4,$24,$02,$40
    

    I only changed that line in FlexProp. But even then it doesn't work as it should i think. I know it's writing something though since it overwrote the program i had in place previously on the spi Flash. I've been having a bit of trouble with this thing having the boot mode on/off. Very weird behavior at times. I got the read working from using the manual a bit and this code.

  • JonnyMacJonnyMac Posts: 9,340
    edited 2025-06-19 23:04

    Yes, testp is the correct instruction. This code is for PNut (FlexProp does inline assembly differently), but this code does work.

    pri shiftin(bits) : result | tix
    
      tix := ticks                                                  ' tix in 1/2 clock
    
      org
                    rep       #6, bits
                     testp    #SF_MISO                      wc      ' scan MISO
                     rcl      result, #1                            ' move new bit to result.0
                     drvh     #SF_SCLK                              ' clock next bit
                     waitx    tix
                     drvl     #SF_SCLK
                     waitx    tix
      end
    
  • Hello @JonnyMac!

    @JonnyMac said:
    Yes, testp is the correct instruction. This code is for PNut (FlexProp does inline assembly differently), but this code does work.

    Thank you. Okay I did get reading working in another program. I think i'll pick apart the writing part a bit under FlexProp and see what I come up with.

  • evanhevanh Posts: 16,533

    I recommend use of SPI clock mode 3 rather than 0. The shared SD card wiring conflicts much less when the clock idles high.

  • Howdy @evanh

    @evanh said:
    I recommend use of SPI clock mode 3 rather than 0. The shared SD card wiring conflicts much less when the clock idles high.

    I'll give this a shot as well in the future. Would this wiring conflict cause an SD card to randomly delete itself? I went through some SD card code and created a driver for writing which works based on the reading you had helped with before. I noticed if I ran the code a few times though it blew away the SD card once i tried to read. Off-topic but just curious.

  • evanhevanh Posts: 16,533
    edited 2025-06-20 13:53

    All it would take is the erasure of block zero to stop a SD card from mounting correctly. So, yes, routines built to write blocks can easily accidentally make the card look empty. There is no filesystem management by the card itself.

    As for SPI clock mode 0, I expect it would more likely cause lock-ups rather than erasures. But I have no specific evidence of what actually happens though.

  • evanhevanh Posts: 16,533

    Another problem I discovered recently is the historical FSRW SD card FAT filesystem for the Propellers has had deficiencies in its driver layer that did not wait for card busy condition. This is particularly bad thing when writing blocks. The chances of skipped blocks is high.

    If you've been using FSRW software then that would explain filesystem corruption.

  • Well, the CRC checksums are supposed to protect against such corruption, but SPI mode doesn't use them by default... On the P2 nothing should be stopping us from using CMD59 to enable them.

  • proppyproppy Posts: 35
    edited 2025-06-20 20:05

    @evanh said:
    Another problem I discovered recently is the historical FSRW SD card FAT filesystem for the Propellers has had deficiencies in its driver layer that did not wait for card busy condition. This is particularly bad thing when writing blocks. The chances of skipped blocks is high.

    If you've been using FSRW software then that would explain filesystem corruption.

    Thanks for this. That narrows things down a bit. I'm doing FAT32 cause that's what I'm most familiar with.

    I got a little further but I'm pretty sure the program never moves from hub ram to the flash.

    ' Program SPI flash with signed program
    
    CON
    
      spi_cs = 61
      spi_ck = 60
      spi_di = 59
      spi_do = 58
    
    DAT
        orgh
    
    pgmdata byte $02, $00, $00, $FF, $04, $00, $6C, $FC, $02, $00, $00, $FF, $48, $84, $4C, $FC
    byte $02, $00, $00, $FF, $49, $00, $4C, $FC, $02, $00, $00, $FF, $04, $02, $6C, $FC
    byte $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
    byte $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
    byte $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
    byte $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
    byte $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
    byte $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
    byte $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
    byte $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
    byte $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
    byte $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
    byte $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
    byte $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
    byte $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
    byte $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
    byte $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
    byte $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
    byte $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
    byte $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
    byte $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
    byte $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
    byte $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
    byte $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
    byte $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
    byte $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
    byte $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
    byte $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
    byte $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
    byte $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
    byte $99, $AA, $44, $98, $86, $E2, $C8, $71, $C3, $1E, $60, $BF, $A3, $36, $19, $7A  'SHA-256/HMAC signature
    byte $F5, $3D, $53, $97, $5C, $AF, $BA, $BB, $B7, $7F, $C3, $0A, $B4, $24, $02, $40
    
            org
            asmclk
    '
    '
    ' Init SPI pins
    '
            outh    #spi_cs
            dirh    #spi_cs
            dirh    #spi_ck
            dirh    #spi_di
    '
    '
    ' Erase 1st $1000 bytes
    '
            call    #spi_wrena      'write enable
    
            mov cmd,cmd_erase       'sector erase
            call    #spi_cmd32
    
            call    #spi_wait       'wait for completion
    '
    '
    ' Program first $400 bytes
    '
            loc ptra,#\pgmdata      'point to program data
    
    .program    call    #spi_wrena      'write enable
    
            mov cmd,cmd_program     'page program
            or  cmd,adr
            call    #spi_cmd32
    
    .byte       rdbyte  cmd,ptra++      'get byte
    
            mov x,#8            'send byte
            shl cmd,#24
            call    #spi_out
    
            add adr,#1          'page done?
            test    adr,#$FF    wz
        if_nz   jmp #.byte
    
            call    #spi_wait       'wait for completion
    
            cmp adr, ##$100 wz
            if_nz jmp #.program
    
    '
    '
    ' Read data back to outa for viewing on logic analyzer
    '
            mov dira,#$1FF
    
    .read1k     mov cmd,cmd_read        'start read
            call    #spi_cmd32
    
            outh    #8          'trigger signal
            outl    #8
    
            decod   y,#10           'read byte to outa
    .read       call    #spi_in
            setbyte outa,cmd,#0
            djnz    y,#.read
    
            jmp #.read1k        'loop
    '
    '
    ' SPI write enable
    '
    spi_wrena   mov cmd,#$06        'write enable
            call    #spi_cmd8
    
            ret
    '
    '
    ' SPI wait while busy
    '
    spi_wait    mov cmd,#$05
            call    #spi_cmd8
    
    .wait       call    #spi_in
            test    cmd,#$01    wc
        if_c    jmp #.wait
    
            ret
    '
    '
    ' SPI command
    '
    spi_cmd32   mov x,#32
            jmp #spi_cmd
    
    spi_cmd8    mov x,#8
            shl cmd,#24
    
    spi_cmd     outh    #spi_cs
            outl    #spi_cs
    '
    '
    ' SPI long/byte out (x=bits, cmd=msbdata)
    '
    spi_out     rep @.r,x
            shl cmd,#1      wc
            outc    #spi_di
            outh    #spi_ck
            outl    #spi_ck
    .r
            ret
    '
    '
    ' SPI byte in (cmd)
    '
    spi_in      rep @.r,#8
            outh    #spi_ck
            outl    #spi_ck
            testp   #spi_do     wc  'due to latencies, 'testin' is from 2 clocks before 'outh'
            rcl cmd,#1
    .r
            ret
    '
    '
    ' Data
    '
    cmd_erase   long    $20_00_00_00    ' Sector Erase command
    cmd_program long    $02_00_00_00    ' Page Program command
    cmd_read    long    $03_00_00_00    ' Read Data command
    adr         long    $00_00_00_00    ' 24-bit address, MSB aligned
    
    '
    '
    ' Variables
    '
    cmd     res 1
    x       res 1
    y       res 1
    '
    '
    ' Program Data
    '
    ' first 20 bytes are blinker program:
    '
    '   not dirb
    '.lp    not outb
    '   waitx   ##20_000_000/4
    '   jmp #.lp
    '
    ' last 32 bytes are signature (key=0)
    '
    

    I may plug away at understanding it a bit more later. Also, I think i might need to generate a new signature. I noticed i was using the one found in the example found here: https://forums.parallax.com/discussion/165060/spi-flash-programmer-code/p1. Though honestly it does work if run from hub ram. I kept in the testp but also replaced the testb with cmp

            cmp adr, ##$100 wz
            if_nz jmp #.program
    
  • ersmithersmith Posts: 6,176

    There's some sample flash programming code in spin2cpp; for example, in Chip's parallax file system (include/filesys/parallax/flash_fs.spin2) and in the littlefs file system code (include/filesys/littlefs/SpiFlash.spin2).

    If you're trying to learn how to write programs into the flash, the sources for loadp2 or propeller-loader would be useful. On the P2 booting from flash is a two step process: the ROM loads the first 256 bytes (or so, I may be misremembering the size) from flash into RAM, and then runs that. So the first part of the flash must be a small stand-alone program capable of loading the rest of the program into flash. Chip's code for this is the file "flash_stub.spin2" in the loadp2 source code (https://github.com/totalspectrum/loadp2).

  • Hiya @ersmith!

    Firstly, thank you for all your efforts on FlexProp.

    @ersmith said:
    If you're trying to learn how to write programs into the flash,

    Yes, exactly. I’ll have a look at this stuff before I continue. I would like to finish this before moving onto dual I/O.

  • pik33pik33 Posts: 2,410

    @evanh said:
    I recommend use of SPI clock mode 3 rather than 0. The shared SD card wiring conflicts much less when the clock idles high.

    +1 to this. Mode 3 or problems with SD cards

Sign In or Register to comment.