rp2040_sdio.pio 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. ; RP2040 PIO program for implementing SD card access in SDIO mode
  2. ; Run "pioasm rp2040_sdio.pio rp2040_sdio.pio.h" to regenerate the C header from this.
  3. ; The RP2040 official work-in-progress code at
  4. ; https://github.com/raspberrypi/pico-extras/tree/master/src/rp2_common/pico_sd_card
  5. ; may be useful reference, but this is independent implementation.
  6. ;
  7. ; For official SDIO specifications, refer to:
  8. ; https://www.sdcard.org/downloads/pls/
  9. ; "SDIO Physical Layer Simplified Specification Version 8.00"
  10. ; Clock settings
  11. ; For 3.3V communication the available speeds are:
  12. ; - Default speed: max. 25 MHz clock
  13. ; - High speed: max. 50 MHz clock
  14. ;
  15. ; From the default RP2040 clock speed of 125 MHz, the closest dividers
  16. ; are 3 for 41.7 MHz and 5 for 25 MHz. The CPU can apply further divider
  17. ; through state machine registers for the initial handshake.
  18. ;
  19. ; Because data is written on the falling edge and read on the rising
  20. ; edge, it is preferrable to have a long 0 state and short 1 state.
  21. ;.define CLOCK_DIVIDER 3
  22. .define CLOCK_DIVIDER 25
  23. .define D1 (CLOCK_DIVIDER/2 - 1)
  24. .define D0 ((CLOCK_DIVIDER + 1) / 2 - 1)
  25. .define SDIO_CLK_GPIO 18
  26. ; State machine 0 is used to:
  27. ; - generate continuous clock on SDIO_CLK
  28. ; - send CMD packets
  29. ; - receive response packets
  30. ;
  31. ; Pin mapping for this state machine:
  32. ; - Sideset : CLK
  33. ; - IN/OUT/SET : CMD
  34. ; - JMP_PIN : CMD
  35. ;
  36. ; The commands to send are put on TX fifo and must have two words:
  37. ; Word 0 bits 31-24: Number of bits in command minus one (usually 47)
  38. ; Word 0 bits 23-00: First 24 bits of the command packet, shifted out MSB first
  39. ; Word 1 bits 31-08: Last 24 bits of the command packet, shifted out MSB first
  40. ; Word 1 bits 07-00: Number of bits in response minus one (usually 47), or 0 if no response
  41. ;
  42. ; The response is put on RX fifo, starting with the MSB.
  43. ; Partial last word will be padded with zero bits at the top.
  44. ;
  45. ; The state machine EXECCTRL should be set so that STATUS indicates TX FIFO < 2
  46. ; and that AUTOPULL and AUTOPUSH are enabled.
  47. .program sdio_cmd_clk
  48. .side_set 1
  49. mov OSR, NULL side 1 [D1] ; Make sure OSR is full of zeros to prevent autopull
  50. wait_cmd:
  51. mov Y, !STATUS side 0 [D0] ; Check if TX FIFO has data
  52. jmp !Y wait_cmd side 1 [D1]
  53. load_cmd:
  54. out NULL, 32 side 0 [D0] ; Load first word (trigger autopull)
  55. out X, 8 side 1 [D1] ; Number of bits to send
  56. set pins, 1 side 0 [D0] ; Initial state of CMD is high
  57. set pindirs, 1 side 1 [D1] ; Set SDIO_CMD as output
  58. send_cmd:
  59. out pins, 1 side 0 [D0] ; Write output on falling edge of CLK
  60. jmp X-- send_cmd side 1 [D1]
  61. prep_resp:
  62. set pindirs, 0 side 0 [D0] ; Set SDIO_CMD as input
  63. out X, 8 side 1 [D1] ; Get number of bits in response
  64. nop side 0 [D0] ; For clock alignment
  65. jmp !X resp_done side 1 [D1] ; Check if we expect a response
  66. wait_resp:
  67. nop side 0 [D0]
  68. jmp PIN wait_resp side 1 [D1] ; Loop until SDIO_CMD = 0
  69. ; Note: input bits are read at the same time as we write CLK=0.
  70. ; Because the host controls the clock, the read happens before
  71. ; the card sees the falling clock edge. This gives maximum time
  72. ; for the data bit to settle.
  73. read_resp:
  74. in PINS, 1 side 0 [D0] ; Read input data bit
  75. jmp X-- read_resp side 1 [D1] ; Loop to receive all data bits
  76. resp_done:
  77. push side 0 [D0] ; Push the remaining part of response
  78. ; State machine 1 is used to send and receive data blocks.
  79. ; Pin mapping for this state machine:
  80. ; - IN / OUT: SDIO_D0-D3
  81. ; - GPIO defined at beginning of this file: SDIO_CLK
  82. ; Data reception program
  83. ; This program will wait for initial start of block token and then
  84. ; continuously receive data. The application can set limit of bytes
  85. ; to receive by using DMA controller, and the final checksum will
  86. ; fit in state machine RX FIFO.
  87. .program sdio_data_rx
  88. wait_start:
  89. mov Y, !PINS ; Read GPIOs (currently doesn't check for clock edge)
  90. jmp !Y wait_start ; Keep looping until we see all zeros start token
  91. .wrap_target
  92. wait 1 gpio SDIO_CLK_GPIO ; Wait for rising clock edge
  93. in PINS, 4 ; Read nibble
  94. .wrap
  95. ; Data transmission program
  96. ; This program will simply send nibbles out to pins, synchronous
  97. ; to the clock signal. The application should prepend 0xF0 to the data
  98. ; for the start of block token, and append the checksum.
  99. ; The data should be padded to full 32 bits by 0xFF bytes.
  100. .program sdio_data_tx
  101. wait 0 gpio SDIO_CLK_GPIO ; Wait for falling clock edge
  102. out PINS, 4 ; Write nibble