SdSpiAvr.h 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. /**
  2. * Copyright (c) 2011-2022 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::activate() {
  31. SPI.beginTransaction(m_spiSettings);
  32. }
  33. //------------------------------------------------------------------------------
  34. inline void SdSpiArduinoDriver::begin(SdSpiConfig spiConfig) {
  35. (void)spiConfig;
  36. SPI.begin();
  37. }
  38. //------------------------------------------------------------------------------
  39. inline void SdSpiArduinoDriver::deactivate() {
  40. SPI.endTransaction();
  41. }
  42. //------------------------------------------------------------------------------
  43. inline void SdSpiArduinoDriver::end() {
  44. SPI.end();
  45. }
  46. //------------------------------------------------------------------------------
  47. inline uint8_t SdSpiArduinoDriver::receive() {
  48. return SPI.transfer(0XFF);
  49. }
  50. //------------------------------------------------------------------------------
  51. inline uint8_t SdSpiArduinoDriver::receive(uint8_t* buf, size_t count) {
  52. if (count == 0) {
  53. return 0;
  54. }
  55. #ifdef SPSR
  56. SPDR = 0XFF;
  57. while (--count) {
  58. // nops optimize loop for 16MHz CPU 8 MHz SPI
  59. nop;
  60. nop;
  61. while (!(SPSR & _BV(SPIF))) {}
  62. uint8_t in = SPDR;
  63. SPDR = 0XFF;
  64. *buf++ = in;
  65. }
  66. while (!(SPSR & _BV(SPIF))) {}
  67. *buf = SPDR;
  68. #elif defined(SPI_RXCIF_bm)
  69. SPI0.DATA = 0XFF;
  70. while (--count) {
  71. // nops optimize loop for ATmega4809 16MHz CPU 8 MHz SPI
  72. nop;
  73. nop;
  74. nop;
  75. nop;
  76. while (!(SPI0.INTFLAGS & SPI_RXCIF_bm)) {}
  77. uint8_t in = SPI0.DATA;
  78. SPI0.DATA = 0XFF;
  79. *buf++ = in;
  80. }
  81. while (!(SPI0.INTFLAGS & SPI_RXCIF_bm)) {}
  82. *buf = SPI0.DATA;
  83. #else // SPSR
  84. #error Unsupported AVR CPU - edit SdFatConfig.h to use standard SPI library.
  85. #endif // SPSR
  86. return 0;
  87. }
  88. //------------------------------------------------------------------------------
  89. inline void SdSpiArduinoDriver::send(uint8_t data) {
  90. SPI.transfer(data);
  91. }
  92. //------------------------------------------------------------------------------
  93. inline void SdSpiArduinoDriver::send(const uint8_t* buf , size_t count) {
  94. if (count == 0) {
  95. return;
  96. }
  97. #ifdef SPSR
  98. SPDR = *buf++;
  99. while (--count) {
  100. uint8_t b = *buf++;
  101. // nops optimize loop for 16MHz CPU 8 MHz SPI
  102. nop;
  103. nop;
  104. while (!(SPSR & (1 << SPIF))) {}
  105. SPDR = b;
  106. }
  107. while (!(SPSR & (1 << SPIF))) {}
  108. #elif defined(SPI_RXCIF_bm)
  109. SPI0.DATA = *buf++;
  110. while (--count) {
  111. uint8_t b = *buf++;
  112. // nops optimize loop for ATmega4809 16MHz CPU 8 MHz SPI
  113. nop;
  114. nop;
  115. nop;
  116. while (!(SPI0.INTFLAGS & SPI_RXCIF_bm)) {}
  117. SPI0.DATA = b;
  118. }
  119. while (!(SPI0.INTFLAGS & SPI_RXCIF_bm)) {}
  120. #else // SPSR
  121. #error Unsupported AVR CPU - edit SdFatConfig.h to use standard SPI library.
  122. #endif // SPSR
  123. }
  124. #endif // SdSpiAvr_h