VS1003.cpp 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. /* Copyright (C) 2012 Andy Karpov <andy.karpov@gmail.com>
  2. * This program is free software; you can redistribute it and/or
  3. * modify it under the terms of the GNU General Public License
  4. * version 2 as published by the Free Software Foundation.
  5. */
  6. #include <avr/pgmspace.h>
  7. #include <SPI.h>
  8. #include "VS1003.h"
  9. /****************************************************************************/
  10. // Audio FIFO is 8kB (2048 stereo samples)
  11. // SM_STREAM should be doable..
  12. #define VS_WRITE_COMMAND 0b00000010 // VS1003 SCI Write
  13. #define VS_READ_COMMAND 0b00000011 // VS1003 SCI Read
  14. const uint8_t vs1003_chunk_size = 32;
  15. // SCI Registers
  16. const uint8_t SCI_MODE = 0x0;
  17. const uint8_t SCI_STATUS = 0x1;
  18. const uint8_t SCI_BASS = 0x2;
  19. const uint8_t SCI_CLOCKF = 0x3;
  20. const uint8_t SCI_DECODE_TIME = 0x4;
  21. const uint8_t SCI_AUDATA = 0x5;
  22. const uint8_t SCI_WRAM = 0x6;
  23. const uint8_t SCI_WRAMADDR = 0x7;
  24. const uint8_t SCI_HDAT0 = 0x8;
  25. const uint8_t SCI_HDAT1 = 0x9;
  26. const uint8_t SCI_AIADDR = 0xa;
  27. const uint8_t SCI_VOL = 0xb;
  28. const uint8_t SCI_AICTRL0 = 0xc;
  29. const uint8_t SCI_AICTRL1 = 0xd;
  30. const uint8_t SCI_AICTRL2 = 0xe;
  31. const uint8_t SCI_AICTRL3 = 0xf;
  32. const uint8_t SCI_num_registers = 0xf;
  33. // SCI_MODE bits
  34. const uint8_t SM_DIFF = 0;
  35. const uint8_t SM_LAYER12 = 1;
  36. const uint8_t SM_RESET = 2;
  37. const uint8_t SM_OUTOFWAV = 3;
  38. const uint8_t SM_EARSPEAKER_LO = 4;
  39. const uint8_t SM_TESTS = 5;
  40. const uint8_t SM_STREAM = 6;
  41. const uint8_t SM_EARSPEAKER_HI = 7;
  42. const uint8_t SM_DACT = 8;
  43. const uint8_t SM_SDIORD = 9;
  44. const uint8_t SM_SDISHARE = 10;
  45. const uint8_t SM_SDINEW = 11;
  46. const uint8_t SM_ADPCM = 12;
  47. const uint8_t SM_ADPCM_HP = 13;
  48. const uint8_t SM_LINE_IN = 14;
  49. // Support RIFF WAv formats
  50. const uint8_t FMT_PCM = 0x01; // 8 & 16 bit, <= 48kHz
  51. const uint8_t FMT_IMA_ADPCM = 0x11; // <= 48kHz
  52. const uint8_t FMT_MPEGL3 = 0x55; // ..
  53. /****************************************************************************/
  54. struct spi_saver_t
  55. {
  56. uint8_t saved_SPCR;
  57. uint8_t saved_SPSR;
  58. spi_saver_t(void) { saved_SPCR = SPCR; saved_SPSR = SPSR; }
  59. ~spi_saver_t() { SPCR = saved_SPCR; SPSR = saved_SPSR; }
  60. };
  61. /****************************************************************************/
  62. uint16_t VS1003::read_register(uint8_t _reg) const
  63. {
  64. uint16_t result;
  65. control_mode_on();
  66. delayMicroseconds(1); // tXCSS
  67. SPI.transfer(VS_READ_COMMAND); // Read operation
  68. SPI.transfer(_reg); // Which register
  69. result = SPI.transfer(0xff) << 8; // read high byte
  70. result |= SPI.transfer(0xff); // read low byte
  71. delayMicroseconds(1); // tXCSH
  72. await_data_request();
  73. control_mode_off();
  74. return result;
  75. }
  76. /****************************************************************************/
  77. void VS1003::write_register(uint8_t _reg,uint16_t _value) const
  78. {
  79. control_mode_on();
  80. delayMicroseconds(1); // tXCSS
  81. SPI.transfer(VS_WRITE_COMMAND); // Write operation
  82. SPI.transfer(_reg); // Which register
  83. SPI.transfer(_value >> 8); // Send hi byte
  84. SPI.transfer(_value & 0xff); // Send lo byte
  85. delayMicroseconds(1); // tXCSH
  86. await_data_request();
  87. control_mode_off();
  88. }
  89. /****************************************************************************/
  90. void VS1003::sdi_send_buffer(const uint8_t* data, size_t len)
  91. {
  92. data_mode_on();
  93. while (len)
  94. {
  95. await_data_request();
  96. delayMicroseconds(3);
  97. size_t chunk_length = min(len,vs1003_chunk_size);
  98. len -= chunk_length;
  99. while (chunk_length--) SPI.transfer(*data++);
  100. }
  101. data_mode_off();
  102. }
  103. /****************************************************************************/
  104. void VS1003::sdi_send_zeroes(size_t len)
  105. {
  106. data_mode_on();
  107. while (len)
  108. {
  109. await_data_request();
  110. size_t chunk_length = min(len,vs1003_chunk_size);
  111. len -= chunk_length;
  112. while (chunk_length--) SPI.transfer(0);
  113. }
  114. data_mode_off();
  115. }
  116. /****************************************************************************/
  117. VS1003::VS1003(uint8_t _cs_pin,
  118. uint8_t _dcs_pin,
  119. uint8_t _dreq_pin,
  120. uint8_t _reset_pin):
  121. cs_pin(_cs_pin),
  122. dcs_pin(_dcs_pin),
  123. dreq_pin(_dreq_pin),
  124. reset_pin(_reset_pin)
  125. {
  126. }
  127. /****************************************************************************/
  128. void VS1003::begin(void)
  129. {
  130. spi_saver_t spi_saver;
  131. pinMode(reset_pin,OUTPUT); // Keep the chip in reset until we are ready
  132. digitalWrite(reset_pin,LOW);
  133. pinMode(cs_pin,OUTPUT); // The SCI and SDI will start deselected
  134. digitalWrite(cs_pin,HIGH);
  135. pinMode(dcs_pin,OUTPUT);
  136. digitalWrite(dcs_pin,HIGH);
  137. pinMode(dreq_pin,INPUT); // DREQ is an input
  138. delay(1);
  139. SPI.setClockDivider(SPI_CLOCK_DIV64); // init SPI slow mode
  140. digitalWrite(reset_pin,HIGH); // release from reset
  141. write_register(SCI_VOL,0xffff); // Declick: Immediately switch analog off
  142. write_register(SCI_AUDATA,10); // & Slow sample rate for analog part startup */
  143. delay(100);
  144. write_register(SCI_VOL,0xfefe); // switch on the analog parts
  145. write_register(SCI_AUDATA,8000); // 8kHz mono
  146. write_register(SCI_VOL,0x2020); // VOL
  147. write_register(SCI_MODE,_BV(SM_SDINEW)|_BV(SM_RESET)); // soft reset
  148. delay(1);
  149. await_data_request();
  150. write_register(SCI_CLOCKF,0xB800); // Experimenting with higher clock settings
  151. delay(1);
  152. await_data_request();
  153. SPI.setClockDivider(SPI_CLOCK_DIV4); // Fastest available SPI clock
  154. save_our_spi();
  155. }
  156. /****************************************************************************/
  157. void VS1003::setVolume(uint8_t vol) const
  158. {
  159. uint16_t value = vol;
  160. value <<= 8;
  161. value |= vol;
  162. write_register(SCI_VOL,value);
  163. }
  164. /****************************************************************************/
  165. void VS1003::playChunk(const uint8_t* data, size_t len)
  166. {
  167. spi_saver_t spi_saver;
  168. set_our_spi();
  169. sdi_send_buffer(data,len);
  170. }
  171. /****************************************************************************/