SdSpiAvr.h 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. /**
  2. * Copyright (c) 2011-2020 Bill Greiman
  3. * This file is part of the SdFat library for SD memory cards.
  4. *
  5. * MIT License
  6. *
  7. * Permission is hereby granted, free of charge, to any person obtaining a
  8. * copy of this software and associated documentation files (the "Software"),
  9. * to deal in the Software without restriction, including without limitation
  10. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  11. * and/or sell copies of the Software, and to permit persons to whom the
  12. * Software is furnished to do so, subject to the following conditions:
  13. *
  14. * The above copyright notice and this permission notice shall be included
  15. * in all copies or substantial portions of the Software.
  16. *
  17. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  18. * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  20. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  22. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  23. * DEALINGS IN THE SOFTWARE.
  24. */
  25. #ifndef SdSpiAvr_h
  26. #define SdSpiAvr_h
  27. // Use of in-line for AVR to save flash.
  28. #define nop asm volatile ("nop\n\t")
  29. //------------------------------------------------------------------------------
  30. inline void SdSpiArduinoDriver::begin(SdSpiConfig spiConfig) {
  31. (void)spiConfig;
  32. SPI.begin();
  33. }
  34. //------------------------------------------------------------------------------
  35. inline void SdSpiArduinoDriver::activate() {
  36. SPI.beginTransaction(m_spiSettings);
  37. }
  38. //------------------------------------------------------------------------------
  39. inline void SdSpiArduinoDriver::deactivate() {
  40. SPI.endTransaction();
  41. }
  42. //------------------------------------------------------------------------------
  43. inline uint8_t SdSpiArduinoDriver::receive() {
  44. return SPI.transfer(0XFF);
  45. }
  46. //------------------------------------------------------------------------------
  47. inline uint8_t SdSpiArduinoDriver::receive(uint8_t* buf, size_t count) {
  48. if (count == 0) {
  49. return 0;
  50. }
  51. #ifdef SPSR
  52. SPDR = 0XFF;
  53. while (--count) {
  54. // nops optimize loop for 16MHz CPU 8 MHz SPI
  55. nop;
  56. nop;
  57. while (!(SPSR & _BV(SPIF))) {}
  58. uint8_t in = SPDR;
  59. SPDR = 0XFF;
  60. *buf++ = in;
  61. }
  62. while (!(SPSR & _BV(SPIF))) {}
  63. *buf = SPDR;
  64. #elif defined(SPI_RXCIF_bm)
  65. SPI0.DATA = 0XFF;
  66. while (--count) {
  67. // nops optimize loop for ATmega4809 16MHz CPU 8 MHz SPI
  68. nop;
  69. nop;
  70. nop;
  71. nop;
  72. while (!(SPI0.INTFLAGS & SPI_RXCIF_bm)) {}
  73. uint8_t in = SPI0.DATA;
  74. SPI0.DATA = 0XFF;
  75. *buf++ = in;
  76. }
  77. while (!(SPI0.INTFLAGS & SPI_RXCIF_bm)) {}
  78. *buf = SPI0.DATA;
  79. #else // SPSR
  80. #error Unsupported AVR CPU - edit SdFatConfig.h to use standard SPI library.
  81. #endif // SPSR
  82. return 0;
  83. }
  84. //------------------------------------------------------------------------------
  85. inline void SdSpiArduinoDriver::send(uint8_t data) {
  86. SPI.transfer(data);
  87. }
  88. //------------------------------------------------------------------------------
  89. inline void SdSpiArduinoDriver::send(const uint8_t* buf , size_t count) {
  90. if (count == 0) {
  91. return;
  92. }
  93. #ifdef SPSR
  94. SPDR = *buf++;
  95. while (--count) {
  96. uint8_t b = *buf++;
  97. // nops optimize loop for 16MHz CPU 8 MHz SPI
  98. nop;
  99. nop;
  100. while (!(SPSR & (1 << SPIF))) {}
  101. SPDR = b;
  102. }
  103. while (!(SPSR & (1 << SPIF))) {}
  104. #elif defined(SPI_RXCIF_bm)
  105. SPI0.DATA = *buf++;
  106. while (--count) {
  107. uint8_t b = *buf++;
  108. // nops optimize loop for ATmega4809 16MHz CPU 8 MHz SPI
  109. nop;
  110. nop;
  111. nop;
  112. while (!(SPI0.INTFLAGS & SPI_RXCIF_bm)) {}
  113. SPI0.DATA = b;
  114. }
  115. while (!(SPI0.INTFLAGS & SPI_RXCIF_bm)) {}
  116. #else // SPSR
  117. #error Unsupported AVR CPU - edit SdFatConfig.h to use standard SPI library.
  118. #endif // SPSR
  119. }
  120. #endif // SdSpiAvr_h