sd_card_spi.cpp 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. // Driver and interface for accessing SD card in SPI mode
  2. // Normally this is only used for saving crash log in interrupt mode
  3. #include "ZuluSCSI_platform.h"
  4. #include "ZuluSCSI_log.h"
  5. #include <hardware/spi.h>
  6. #include <SdFat.h>
  7. class RP2040SPIDriver : public SdSpiBaseClass
  8. {
  9. public:
  10. void begin(SdSpiConfig config) {
  11. // Make sure pins are routed to SPI
  12. gpio_set_function(SD_SPI_SCK, GPIO_FUNC_SPI);
  13. gpio_set_function(SD_SPI_MOSI, GPIO_FUNC_SPI);
  14. gpio_set_function(SD_SPI_MISO, GPIO_FUNC_SPI);
  15. gpio_set_function(SD_SPI_CS, GPIO_FUNC_SIO);
  16. }
  17. void activate() {
  18. _spi_init(SD_SPI, m_sckfreq);
  19. spi_set_format(SD_SPI, 8, SPI_CPOL_0, SPI_CPHA_0, SPI_MSB_FIRST);
  20. }
  21. void deactivate() {
  22. }
  23. void wait_idle() {
  24. while (!(spi_get_hw(SD_SPI)->sr & SPI_SSPSR_TFE_BITS));
  25. while (spi_get_hw(SD_SPI)->sr & SPI_SSPSR_BSY_BITS);
  26. }
  27. // Single byte receive
  28. uint8_t receive() {
  29. uint8_t tx = 0xFF;
  30. uint8_t rx;
  31. spi_write_read_blocking(SD_SPI, &tx, &rx, 1);
  32. return rx;
  33. }
  34. // Single byte send
  35. void send(uint8_t data) {
  36. spi_write_blocking(SD_SPI, &data, 1);
  37. wait_idle();
  38. }
  39. // Multiple byte receive
  40. uint8_t receive(uint8_t* buf, size_t count)
  41. {
  42. spi_read_blocking(SD_SPI, 0xFF, buf, count);
  43. if (m_stream_callback && buf == m_stream_buffer + m_stream_count)
  44. {
  45. m_stream_count += count;
  46. m_stream_callback(m_stream_count);
  47. }
  48. return 0;
  49. }
  50. // Multiple byte send
  51. void send(const uint8_t* buf, size_t count) {
  52. spi_write_blocking(SD_SPI, buf, count);
  53. if (m_stream_callback && buf == m_stream_buffer + m_stream_count)
  54. {
  55. m_stream_count += count;
  56. m_stream_callback(m_stream_count);
  57. }
  58. }
  59. void setSckSpeed(uint32_t maxSck) {
  60. m_sckfreq = maxSck;
  61. }
  62. void set_sd_callback(sd_callback_t func, const uint8_t *buffer)
  63. {
  64. m_stream_buffer = buffer;
  65. m_stream_count = 0;
  66. m_stream_callback = func;
  67. }
  68. private:
  69. uint32_t m_sckfreq;
  70. const uint8_t *m_stream_buffer;
  71. uint32_t m_stream_count;
  72. sd_callback_t m_stream_callback;
  73. };
  74. void sdCsInit(SdCsPin_t pin)
  75. {
  76. }
  77. void sdCsWrite(SdCsPin_t pin, bool level)
  78. {
  79. if (level)
  80. sio_hw->gpio_set = (1 << SD_SPI_CS);
  81. else
  82. sio_hw->gpio_clr = (1 << SD_SPI_CS);
  83. }
  84. RP2040SPIDriver g_sd_spi_port;
  85. SdSpiConfig g_sd_spi_config(0, DEDICATED_SPI, SD_SCK_MHZ(25), &g_sd_spi_port);
  86. void azplatform_set_sd_callback(sd_callback_t func, const uint8_t *buffer)
  87. {
  88. g_sd_spi_port.set_sd_callback(func, buffer);
  89. }