Mateusz Wójcik / Mbed 2 deprecated FRDMK64_SDCard

Dependencies:   mbed

Committer:
kudlatykaskader
Date:
Sat Nov 18 22:04:50 2017 +0000
Revision:
0:e2da1a4652f5
commit;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kudlatykaskader 0:e2da1a4652f5 1 /* mbed VLSI VS1053b library
kudlatykaskader 0:e2da1a4652f5 2 * Copyright (c) 2010 Christian Schmiljun
kudlatykaskader 0:e2da1a4652f5 3 *
kudlatykaskader 0:e2da1a4652f5 4 * Permission is hereby granted, free of charge, to any person obtaining a copy
kudlatykaskader 0:e2da1a4652f5 5 * of this software and associated documentation files (the "Software"), to deal
kudlatykaskader 0:e2da1a4652f5 6 * in the Software without restriction, including without limitation the rights
kudlatykaskader 0:e2da1a4652f5 7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
kudlatykaskader 0:e2da1a4652f5 8 * copies of the Software, and to permit persons to whom the Software is
kudlatykaskader 0:e2da1a4652f5 9 * furnished to do so, subject to the following conditions:
kudlatykaskader 0:e2da1a4652f5 10 *
kudlatykaskader 0:e2da1a4652f5 11 * The above copyright notice and this permission notice shall be included in
kudlatykaskader 0:e2da1a4652f5 12 * all copies or substantial portions of the Software.
kudlatykaskader 0:e2da1a4652f5 13 *
kudlatykaskader 0:e2da1a4652f5 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
kudlatykaskader 0:e2da1a4652f5 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
kudlatykaskader 0:e2da1a4652f5 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
kudlatykaskader 0:e2da1a4652f5 17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
kudlatykaskader 0:e2da1a4652f5 18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
kudlatykaskader 0:e2da1a4652f5 19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
kudlatykaskader 0:e2da1a4652f5 20 * THE SOFTWARE.
kudlatykaskader 0:e2da1a4652f5 21 */
kudlatykaskader 0:e2da1a4652f5 22
kudlatykaskader 0:e2da1a4652f5 23 /* This code based on:
kudlatykaskader 0:e2da1a4652f5 24 * mbeduino_MP3_Shield_MP3Player
kudlatykaskader 0:e2da1a4652f5 25 * http://mbed.org/users/xshige/programs/mbeduino_MP3_Shield_MP3Player/lgcx63
kudlatykaskader 0:e2da1a4652f5 26 * 2010-10-16
kudlatykaskader 0:e2da1a4652f5 27 */
kudlatykaskader 0:e2da1a4652f5 28
kudlatykaskader 0:e2da1a4652f5 29 #include "VS1053.h"
kudlatykaskader 0:e2da1a4652f5 30 #include "mbed.h"
kudlatykaskader 0:e2da1a4652f5 31
kudlatykaskader 0:e2da1a4652f5 32 // patch binarys
kudlatykaskader 0:e2da1a4652f5 33 #include "Patches/VS1053b_patch_1_5.c"
kudlatykaskader 0:e2da1a4652f5 34 #include "Patches/VS1053b_patch_1_5_flac.c"
kudlatykaskader 0:e2da1a4652f5 35 #include "Patches/VS1053b_patch_1_4_flac.c"
kudlatykaskader 0:e2da1a4652f5 36 #include "Patches/VS1053b_specana_0_9.c"
kudlatykaskader 0:e2da1a4652f5 37 #include "Patches/VS1053b_pcm_recorder_0_9.c"
kudlatykaskader 0:e2da1a4652f5 38
kudlatykaskader 0:e2da1a4652f5 39 const char VS1053::_sampleRateTable[4][4] = {
kudlatykaskader 0:e2da1a4652f5 40 11, 12, 8, 0,
kudlatykaskader 0:e2da1a4652f5 41 11, 12, 8, 0,
kudlatykaskader 0:e2da1a4652f5 42 22, 24, 16, 0,
kudlatykaskader 0:e2da1a4652f5 43 44, 48, 32, 0
kudlatykaskader 0:e2da1a4652f5 44 };
kudlatykaskader 0:e2da1a4652f5 45
kudlatykaskader 0:e2da1a4652f5 46 /* ==================================================================
kudlatykaskader 0:e2da1a4652f5 47 * Constructor
kudlatykaskader 0:e2da1a4652f5 48 * =================================================================*/
kudlatykaskader 0:e2da1a4652f5 49 VS1053::VS1053(
kudlatykaskader 0:e2da1a4652f5 50 PinName mosi, PinName miso, PinName sck, PinName cs, PinName rst,
kudlatykaskader 0:e2da1a4652f5 51 PinName dreq, PinName dcs, char* buffer, int buffer_size)
kudlatykaskader 0:e2da1a4652f5 52 :
kudlatykaskader 0:e2da1a4652f5 53 _spi(mosi, miso, sck),
kudlatykaskader 0:e2da1a4652f5 54 _CS(cs),
kudlatykaskader 0:e2da1a4652f5 55 _RST(rst),
kudlatykaskader 0:e2da1a4652f5 56 _DCS(dcs),
kudlatykaskader 0:e2da1a4652f5 57 _DREQ(dreq),
kudlatykaskader 0:e2da1a4652f5 58 _DREQ_INTERUPT_IN(dreq)
kudlatykaskader 0:e2da1a4652f5 59 {
kudlatykaskader 0:e2da1a4652f5 60 _volume = DEFAULT_VOLUME;
kudlatykaskader 0:e2da1a4652f5 61 _balance = DEFAULT_BALANCE_DIFERENCE_LEFT_RIGHT;
kudlatykaskader 0:e2da1a4652f5 62 _sb_amplitude = DEFAULT_BASS_AMPLITUDE;
kudlatykaskader 0:e2da1a4652f5 63 _sb_freqlimit = DEFAULT_BASS_FREQUENCY;
kudlatykaskader 0:e2da1a4652f5 64 _st_amplitude = DEFAULT_TREBLE_AMPLITUDE;
kudlatykaskader 0:e2da1a4652f5 65 _st_freqlimit = DEFAULT_TREBLE_FREQUENCY;
kudlatykaskader 0:e2da1a4652f5 66 _buffer = buffer;
kudlatykaskader 0:e2da1a4652f5 67 BUFFER_SIZE = buffer_size;
kudlatykaskader 0:e2da1a4652f5 68 _DREQ_INTERUPT_IN.mode(PullDown);
kudlatykaskader 0:e2da1a4652f5 69 INTERRUPT_HANDLER_DISABLE;
kudlatykaskader 0:e2da1a4652f5 70 bufferReset();
kudlatykaskader 0:e2da1a4652f5 71 }
kudlatykaskader 0:e2da1a4652f5 72
kudlatykaskader 0:e2da1a4652f5 73
kudlatykaskader 0:e2da1a4652f5 74 /*===================================================================
kudlatykaskader 0:e2da1a4652f5 75 * Functions
kudlatykaskader 0:e2da1a4652f5 76 *==================================================================*/
kudlatykaskader 0:e2da1a4652f5 77
kudlatykaskader 0:e2da1a4652f5 78 void VS1053::cs_low(void) {
kudlatykaskader 0:e2da1a4652f5 79 _CS = 0;
kudlatykaskader 0:e2da1a4652f5 80 }
kudlatykaskader 0:e2da1a4652f5 81 void VS1053::cs_high(void) {
kudlatykaskader 0:e2da1a4652f5 82 _CS = 1;
kudlatykaskader 0:e2da1a4652f5 83 }
kudlatykaskader 0:e2da1a4652f5 84 void VS1053::dcs_low(void) {
kudlatykaskader 0:e2da1a4652f5 85 _DCS = 0;
kudlatykaskader 0:e2da1a4652f5 86
kudlatykaskader 0:e2da1a4652f5 87 }
kudlatykaskader 0:e2da1a4652f5 88 void VS1053::dcs_high(void) {
kudlatykaskader 0:e2da1a4652f5 89 _DCS = 1;
kudlatykaskader 0:e2da1a4652f5 90 }
kudlatykaskader 0:e2da1a4652f5 91 void VS1053::sci_en(void) { //SCI enable
kudlatykaskader 0:e2da1a4652f5 92 cs_high();
kudlatykaskader 0:e2da1a4652f5 93 dcs_high();
kudlatykaskader 0:e2da1a4652f5 94 cs_low();
kudlatykaskader 0:e2da1a4652f5 95 }
kudlatykaskader 0:e2da1a4652f5 96 void VS1053::sci_dis(void) { //SCI disable
kudlatykaskader 0:e2da1a4652f5 97 cs_high();
kudlatykaskader 0:e2da1a4652f5 98 }
kudlatykaskader 0:e2da1a4652f5 99 void VS1053::sdi_en(void) { //SDI enable
kudlatykaskader 0:e2da1a4652f5 100 dcs_high();
kudlatykaskader 0:e2da1a4652f5 101 cs_high();
kudlatykaskader 0:e2da1a4652f5 102 dcs_low();
kudlatykaskader 0:e2da1a4652f5 103 }
kudlatykaskader 0:e2da1a4652f5 104 void VS1053::sdi_dis(void) { //SDI disable
kudlatykaskader 0:e2da1a4652f5 105 dcs_high();
kudlatykaskader 0:e2da1a4652f5 106 }
kudlatykaskader 0:e2da1a4652f5 107 void VS1053::reset(void) { //hardware reset
kudlatykaskader 0:e2da1a4652f5 108 INTERRUPT_HANDLER_DISABLE;
kudlatykaskader 0:e2da1a4652f5 109 wait_ms(10);
kudlatykaskader 0:e2da1a4652f5 110 _RST = 0;
kudlatykaskader 0:e2da1a4652f5 111 wait_ms(5);
kudlatykaskader 0:e2da1a4652f5 112 _RST = 1;
kudlatykaskader 0:e2da1a4652f5 113 wait_ms(10);
kudlatykaskader 0:e2da1a4652f5 114 }
kudlatykaskader 0:e2da1a4652f5 115 void VS1053::power_down(void) { //hardware and software reset
kudlatykaskader 0:e2da1a4652f5 116 cs_low();
kudlatykaskader 0:e2da1a4652f5 117 reset();
kudlatykaskader 0:e2da1a4652f5 118 // sci_write(0x00, SM_PDOWN);
kudlatykaskader 0:e2da1a4652f5 119 sci_write(0x00, 0x10); // tempo
kudlatykaskader 0:e2da1a4652f5 120 wait(0.01);
kudlatykaskader 0:e2da1a4652f5 121 reset();
kudlatykaskader 0:e2da1a4652f5 122 }
kudlatykaskader 0:e2da1a4652f5 123 void VS1053::spi_initialise(void) {
kudlatykaskader 0:e2da1a4652f5 124 _RST = 1; //no reset
kudlatykaskader 0:e2da1a4652f5 125 _spi.format(8,0); //spi 8bit interface, steady state low
kudlatykaskader 0:e2da1a4652f5 126 // _spi.frequency(1000000); //rising edge data record, freq. 1Mhz
kudlatykaskader 0:e2da1a4652f5 127 _spi.frequency(2000000); //rising edge data record, freq. 2Mhz
kudlatykaskader 0:e2da1a4652f5 128
kudlatykaskader 0:e2da1a4652f5 129
kudlatykaskader 0:e2da1a4652f5 130 cs_low();
kudlatykaskader 0:e2da1a4652f5 131 for (int i=0; i<4; i++) {
kudlatykaskader 0:e2da1a4652f5 132 _spi.write(0xFF); //clock the chip a bit
kudlatykaskader 0:e2da1a4652f5 133 }
kudlatykaskader 0:e2da1a4652f5 134 cs_high();
kudlatykaskader 0:e2da1a4652f5 135 dcs_high();
kudlatykaskader 0:e2da1a4652f5 136 wait_us(5);
kudlatykaskader 0:e2da1a4652f5 137 }
kudlatykaskader 0:e2da1a4652f5 138 void VS1053::sdi_initialise(void) {
kudlatykaskader 0:e2da1a4652f5 139 _spi.frequency(8000000); //set to 8 MHz to make fast transfer
kudlatykaskader 0:e2da1a4652f5 140 cs_high();
kudlatykaskader 0:e2da1a4652f5 141 dcs_high();
kudlatykaskader 0:e2da1a4652f5 142 }
kudlatykaskader 0:e2da1a4652f5 143 void VS1053::sci_write(unsigned char address, unsigned short int data) {
kudlatykaskader 0:e2da1a4652f5 144 // TODO disable all interrupts
kudlatykaskader 0:e2da1a4652f5 145 __disable_irq();
kudlatykaskader 0:e2da1a4652f5 146 sci_en(); //enables SCI/disables SDI
kudlatykaskader 0:e2da1a4652f5 147
kudlatykaskader 0:e2da1a4652f5 148 while (!_DREQ); //wait unitl data request is high
kudlatykaskader 0:e2da1a4652f5 149 _spi.write(0x02); //SCI write
kudlatykaskader 0:e2da1a4652f5 150 _spi.write(address); //register address
kudlatykaskader 0:e2da1a4652f5 151 _spi.write((data >> 8) & 0xFF); //write out first half of data word
kudlatykaskader 0:e2da1a4652f5 152 _spi.write(data & 0xFF); //write out second half of data word
kudlatykaskader 0:e2da1a4652f5 153
kudlatykaskader 0:e2da1a4652f5 154 sci_dis(); //enables SDI/disables SCI
kudlatykaskader 0:e2da1a4652f5 155 wait_us(5);
kudlatykaskader 0:e2da1a4652f5 156
kudlatykaskader 0:e2da1a4652f5 157 // TODO enable all interrupts
kudlatykaskader 0:e2da1a4652f5 158 __enable_irq();
kudlatykaskader 0:e2da1a4652f5 159 }
kudlatykaskader 0:e2da1a4652f5 160 void VS1053::sdi_write(unsigned char datum) {
kudlatykaskader 0:e2da1a4652f5 161
kudlatykaskader 0:e2da1a4652f5 162 sdi_en();
kudlatykaskader 0:e2da1a4652f5 163
kudlatykaskader 0:e2da1a4652f5 164 while (!_DREQ);
kudlatykaskader 0:e2da1a4652f5 165 _spi.write(datum);
kudlatykaskader 0:e2da1a4652f5 166
kudlatykaskader 0:e2da1a4652f5 167 sdi_dis();
kudlatykaskader 0:e2da1a4652f5 168 }
kudlatykaskader 0:e2da1a4652f5 169 unsigned short VS1053::sci_read(unsigned short int address) {
kudlatykaskader 0:e2da1a4652f5 170 // TODO disable all interrupts
kudlatykaskader 0:e2da1a4652f5 171 __disable_irq();
kudlatykaskader 0:e2da1a4652f5 172
kudlatykaskader 0:e2da1a4652f5 173 cs_low(); //enables SCI/disables SDI
kudlatykaskader 0:e2da1a4652f5 174
kudlatykaskader 0:e2da1a4652f5 175 while (!_DREQ); //wait unitl data request is high
kudlatykaskader 0:e2da1a4652f5 176 _spi.write(0x03); //SCI write
kudlatykaskader 0:e2da1a4652f5 177 _spi.write(address); //register address
kudlatykaskader 0:e2da1a4652f5 178 unsigned short int received = _spi.write(0x00); //write out dummy byte
kudlatykaskader 0:e2da1a4652f5 179 received <<= 8;
kudlatykaskader 0:e2da1a4652f5 180 received |= _spi.write(0x00); //write out dummy byte
kudlatykaskader 0:e2da1a4652f5 181
kudlatykaskader 0:e2da1a4652f5 182 cs_high(); //enables SDI/disables SCI
kudlatykaskader 0:e2da1a4652f5 183
kudlatykaskader 0:e2da1a4652f5 184 // TODO enable all interrupts
kudlatykaskader 0:e2da1a4652f5 185 __enable_irq();
kudlatykaskader 0:e2da1a4652f5 186 return received; //return received word
kudlatykaskader 0:e2da1a4652f5 187 }
kudlatykaskader 0:e2da1a4652f5 188 void VS1053::sine_test_activate(unsigned char wave) {
kudlatykaskader 0:e2da1a4652f5 189 cs_high(); //enables SDI/disables SCI
kudlatykaskader 0:e2da1a4652f5 190
kudlatykaskader 0:e2da1a4652f5 191 while (!_DREQ); //wait unitl data request is high
kudlatykaskader 0:e2da1a4652f5 192 _spi.write(0x53); //SDI write
kudlatykaskader 0:e2da1a4652f5 193 _spi.write(0xEF); //SDI write
kudlatykaskader 0:e2da1a4652f5 194 _spi.write(0x6E); //SDI write
kudlatykaskader 0:e2da1a4652f5 195 _spi.write(wave); //SDI write
kudlatykaskader 0:e2da1a4652f5 196 _spi.write(0x00); //filler byte
kudlatykaskader 0:e2da1a4652f5 197 _spi.write(0x00); //filler byte
kudlatykaskader 0:e2da1a4652f5 198 _spi.write(0x00); //filler byte
kudlatykaskader 0:e2da1a4652f5 199 _spi.write(0x00); //filler byte
kudlatykaskader 0:e2da1a4652f5 200
kudlatykaskader 0:e2da1a4652f5 201 cs_low(); //enables SCI/disables SDI
kudlatykaskader 0:e2da1a4652f5 202 }
kudlatykaskader 0:e2da1a4652f5 203 void VS1053::sine_test_deactivate(void) {
kudlatykaskader 0:e2da1a4652f5 204 cs_high();
kudlatykaskader 0:e2da1a4652f5 205
kudlatykaskader 0:e2da1a4652f5 206 while (!_DREQ);
kudlatykaskader 0:e2da1a4652f5 207 _spi.write(0x45); //SDI write
kudlatykaskader 0:e2da1a4652f5 208 _spi.write(0x78); //SDI write
kudlatykaskader 0:e2da1a4652f5 209 _spi.write(0x69); //SDI write
kudlatykaskader 0:e2da1a4652f5 210 _spi.write(0x74); //SDI write
kudlatykaskader 0:e2da1a4652f5 211 _spi.write(0x00); //filler byte
kudlatykaskader 0:e2da1a4652f5 212 _spi.write(0x00); //filler byte
kudlatykaskader 0:e2da1a4652f5 213 _spi.write(0x00); //filler byte
kudlatykaskader 0:e2da1a4652f5 214 _spi.write(0x00); //filler byte
kudlatykaskader 0:e2da1a4652f5 215 }
kudlatykaskader 0:e2da1a4652f5 216
kudlatykaskader 0:e2da1a4652f5 217 unsigned short int VS1053::wram_read(unsigned short int address) {
kudlatykaskader 0:e2da1a4652f5 218 unsigned short int tmp1,tmp2;
kudlatykaskader 0:e2da1a4652f5 219 sci_write(SCI_WRAMADDR,address);
kudlatykaskader 0:e2da1a4652f5 220 tmp1=sci_read(SCI_WRAM);
kudlatykaskader 0:e2da1a4652f5 221 sci_write(SCI_WRAMADDR,address);
kudlatykaskader 0:e2da1a4652f5 222 tmp2=sci_read(SCI_WRAM);
kudlatykaskader 0:e2da1a4652f5 223 if (tmp1==tmp2) return tmp1;
kudlatykaskader 0:e2da1a4652f5 224 sci_write(SCI_WRAMADDR,address);
kudlatykaskader 0:e2da1a4652f5 225 tmp1=sci_read(SCI_WRAM);
kudlatykaskader 0:e2da1a4652f5 226 if (tmp1==tmp2) return tmp1;
kudlatykaskader 0:e2da1a4652f5 227 sci_write(SCI_WRAMADDR,address);
kudlatykaskader 0:e2da1a4652f5 228 tmp1=sci_read(SCI_WRAM);
kudlatykaskader 0:e2da1a4652f5 229 if (tmp1==tmp2) return tmp1;
kudlatykaskader 0:e2da1a4652f5 230 return tmp1;
kudlatykaskader 0:e2da1a4652f5 231 }
kudlatykaskader 0:e2da1a4652f5 232
kudlatykaskader 0:e2da1a4652f5 233 void VS1053::wram_write(unsigned short int address, unsigned short int data) {
kudlatykaskader 0:e2da1a4652f5 234 sci_write(SCI_WRAMADDR,address);
kudlatykaskader 0:e2da1a4652f5 235 sci_write(SCI_WRAM,data);
kudlatykaskader 0:e2da1a4652f5 236 return;
kudlatykaskader 0:e2da1a4652f5 237 }
kudlatykaskader 0:e2da1a4652f5 238
kudlatykaskader 0:e2da1a4652f5 239 void VS1053::setPlaySpeed(unsigned short speed)
kudlatykaskader 0:e2da1a4652f5 240 {
kudlatykaskader 0:e2da1a4652f5 241 wram_write(para_playSpeed, speed);
kudlatykaskader 0:e2da1a4652f5 242 DEBUGOUT("VS1053b: Change speed. New speed: %d\r\n", speed);
kudlatykaskader 0:e2da1a4652f5 243 }
kudlatykaskader 0:e2da1a4652f5 244
kudlatykaskader 0:e2da1a4652f5 245 void VS1053::terminateStream(void) {
kudlatykaskader 0:e2da1a4652f5 246 while(bufferCount() > 0)
kudlatykaskader 0:e2da1a4652f5 247 ;
kudlatykaskader 0:e2da1a4652f5 248 DEBUGOUT("VS1053b: Song terminating..\r\n");
kudlatykaskader 0:e2da1a4652f5 249 // send at least 2052 bytes of endFillByte[7:0].
kudlatykaskader 0:e2da1a4652f5 250 // read endFillByte (0 .. 15) from wram
kudlatykaskader 0:e2da1a4652f5 251 unsigned short endFillByte=wram_read(para_endFillByte);
kudlatykaskader 0:e2da1a4652f5 252 // clear endFillByte (8 .. 15)
kudlatykaskader 0:e2da1a4652f5 253 endFillByte = endFillByte ^0x00FF;
kudlatykaskader 0:e2da1a4652f5 254 for (int n = 0; n < 2052; n++)
kudlatykaskader 0:e2da1a4652f5 255 sdi_write(endFillByte);
kudlatykaskader 0:e2da1a4652f5 256
kudlatykaskader 0:e2da1a4652f5 257 // set SCI MODE bit SM CANCEL
kudlatykaskader 0:e2da1a4652f5 258 unsigned short sciModeByte = sci_read(SCI_MODE);
kudlatykaskader 0:e2da1a4652f5 259 sciModeByte |= SM_CANCEL;
kudlatykaskader 0:e2da1a4652f5 260 sci_write(SCI_MODE, sciModeByte);
kudlatykaskader 0:e2da1a4652f5 261
kudlatykaskader 0:e2da1a4652f5 262 // send up 2048 bytes of endFillByte[7:0].
kudlatykaskader 0:e2da1a4652f5 263 for (int i = 0; i < 64; i++)
kudlatykaskader 0:e2da1a4652f5 264 {
kudlatykaskader 0:e2da1a4652f5 265 // send at least 32 bytes of endFillByte[7:0]
kudlatykaskader 0:e2da1a4652f5 266 for (int n = 0; n < 32; n++)
kudlatykaskader 0:e2da1a4652f5 267 sdi_write(endFillByte);
kudlatykaskader 0:e2da1a4652f5 268 // read SCI MODE; if SM CANCEL is still set, repeat
kudlatykaskader 0:e2da1a4652f5 269 sciModeByte = sci_read(SCI_MODE);
kudlatykaskader 0:e2da1a4652f5 270 if ((sciModeByte & SM_CANCEL) == 0x0000)
kudlatykaskader 0:e2da1a4652f5 271 {
kudlatykaskader 0:e2da1a4652f5 272 break;
kudlatykaskader 0:e2da1a4652f5 273 }
kudlatykaskader 0:e2da1a4652f5 274 }
kudlatykaskader 0:e2da1a4652f5 275
kudlatykaskader 0:e2da1a4652f5 276 if ((sciModeByte & SM_CANCEL) == 0x0000)
kudlatykaskader 0:e2da1a4652f5 277 {
kudlatykaskader 0:e2da1a4652f5 278 DEBUGOUT("VS1053b: Song sucessfully sent. Terminating OK\r\n");
kudlatykaskader 0:e2da1a4652f5 279 DEBUGOUT("VS1053b: SCI MODE = %#x, SM_CANCEL = %#x\r\n", sciModeByte, sciModeByte & SM_CANCEL);
kudlatykaskader 0:e2da1a4652f5 280 sci_write(SCI_DECODE_TIME, 0x0000);
kudlatykaskader 0:e2da1a4652f5 281 }
kudlatykaskader 0:e2da1a4652f5 282 else
kudlatykaskader 0:e2da1a4652f5 283 {
kudlatykaskader 0:e2da1a4652f5 284 DEBUGOUT("VS1053b: SM CANCEL hasn't cleared after sending 2048 bytes, do software reset\r\n");
kudlatykaskader 0:e2da1a4652f5 285 DEBUGOUT("VS1053b: SCI MODE = %#x, SM_CANCEL = %#x\r\n", sciModeByte, sciModeByte & SM_CANCEL);
kudlatykaskader 0:e2da1a4652f5 286 initialize();
kudlatykaskader 0:e2da1a4652f5 287 }
kudlatykaskader 0:e2da1a4652f5 288 }
kudlatykaskader 0:e2da1a4652f5 289
kudlatykaskader 0:e2da1a4652f5 290 void VS1053::write_plugin(const unsigned short *plugin, unsigned int len) {
kudlatykaskader 0:e2da1a4652f5 291 unsigned int i;
kudlatykaskader 0:e2da1a4652f5 292 unsigned short addr, n, val;
kudlatykaskader 0:e2da1a4652f5 293
kudlatykaskader 0:e2da1a4652f5 294 for (i=0; i<len;) {
kudlatykaskader 0:e2da1a4652f5 295 addr = plugin[i++];
kudlatykaskader 0:e2da1a4652f5 296 n = plugin[i++];
kudlatykaskader 0:e2da1a4652f5 297 if (n & 0x8000U) { //RLE run, replicate n samples
kudlatykaskader 0:e2da1a4652f5 298 n &= 0x7FFF;
kudlatykaskader 0:e2da1a4652f5 299 val = plugin[i++];
kudlatykaskader 0:e2da1a4652f5 300 while (n--) {
kudlatykaskader 0:e2da1a4652f5 301 sci_write(addr,val);
kudlatykaskader 0:e2da1a4652f5 302 }
kudlatykaskader 0:e2da1a4652f5 303 } else { //copy run, copy n sample
kudlatykaskader 0:e2da1a4652f5 304 while (n--) {
kudlatykaskader 0:e2da1a4652f5 305 val = plugin[i++];
kudlatykaskader 0:e2da1a4652f5 306 sci_write(addr,val);
kudlatykaskader 0:e2da1a4652f5 307 }
kudlatykaskader 0:e2da1a4652f5 308 }
kudlatykaskader 0:e2da1a4652f5 309 }
kudlatykaskader 0:e2da1a4652f5 310
kudlatykaskader 0:e2da1a4652f5 311 return;
kudlatykaskader 0:e2da1a4652f5 312 }
kudlatykaskader 0:e2da1a4652f5 313
kudlatykaskader 0:e2da1a4652f5 314
kudlatykaskader 0:e2da1a4652f5 315 bool VS1053::initialize(void) {
kudlatykaskader 0:e2da1a4652f5 316 _RST = 1;
kudlatykaskader 0:e2da1a4652f5 317 cs_high(); //chip disabled
kudlatykaskader 0:e2da1a4652f5 318 spi_initialise(); //initialise MBED
kudlatykaskader 0:e2da1a4652f5 319
kudlatykaskader 0:e2da1a4652f5 320 sci_write(SCI_MODE, (SM_SDINEW+SM_RESET)); // set mode reg.
kudlatykaskader 0:e2da1a4652f5 321 wait_ms(10);
kudlatykaskader 0:e2da1a4652f5 322
kudlatykaskader 0:e2da1a4652f5 323 #ifdef DEBUG
kudlatykaskader 0:e2da1a4652f5 324 unsigned int info = wram_read(para_chipID_0);
kudlatykaskader 0:e2da1a4652f5 325 DEBUGOUT("VS1053b: ChipID_0:%04X\r\n", info);
kudlatykaskader 0:e2da1a4652f5 326 info = wram_read(para_chipID_1);
kudlatykaskader 0:e2da1a4652f5 327 DEBUGOUT("VS1053b: ChipID_1:%04X\r\n", info);
kudlatykaskader 0:e2da1a4652f5 328 info = wram_read(para_version);
kudlatykaskader 0:e2da1a4652f5 329 DEBUGOUT("VS1053b: Structure version:%04X\r\n", info);
kudlatykaskader 0:e2da1a4652f5 330 #endif
kudlatykaskader 0:e2da1a4652f5 331
kudlatykaskader 0:e2da1a4652f5 332 //get chip version, set clock multiplier and load patch
kudlatykaskader 0:e2da1a4652f5 333 int i = (sci_read(SCI_STATUS) & 0xF0) >> 4;
kudlatykaskader 0:e2da1a4652f5 334 if (i == 4) {
kudlatykaskader 0:e2da1a4652f5 335
kudlatykaskader 0:e2da1a4652f5 336 DEBUGOUT("VS1053b: Installed Chip is: VS1053\r\n");
kudlatykaskader 0:e2da1a4652f5 337
kudlatykaskader 0:e2da1a4652f5 338 sci_write(SCI_CLOCKF, (SC_MULT_XTALIx50));
kudlatykaskader 0:e2da1a4652f5 339 wait_ms(10);
kudlatykaskader 0:e2da1a4652f5 340 #ifdef VS_PATCH
kudlatykaskader 0:e2da1a4652f5 341 // loading patch
kudlatykaskader 0:e2da1a4652f5 342 write_plugin(vs1053b_patch, sizeof(vs1053b_patch)/2);
kudlatykaskader 0:e2da1a4652f5 343
kudlatykaskader 0:e2da1a4652f5 344 DEBUGOUT("VS1053b: Patch is loaded.\r\n");
kudlatykaskader 0:e2da1a4652f5 345 DEBUGOUT("VS1053b: Patch size:%d bytes\r\n",sizeof(vs1053b_patch));
kudlatykaskader 0:e2da1a4652f5 346
kudlatykaskader 0:e2da1a4652f5 347 #endif // VS_PATCH
kudlatykaskader 0:e2da1a4652f5 348 }
kudlatykaskader 0:e2da1a4652f5 349 else
kudlatykaskader 0:e2da1a4652f5 350 {
kudlatykaskader 0:e2da1a4652f5 351 DEBUGOUT("VS1053b: Not Supported Chip\r\n");
kudlatykaskader 0:e2da1a4652f5 352 return false;
kudlatykaskader 0:e2da1a4652f5 353 }
kudlatykaskader 0:e2da1a4652f5 354
kudlatykaskader 0:e2da1a4652f5 355 // change spi to higher speed
kudlatykaskader 0:e2da1a4652f5 356 sdi_initialise();
kudlatykaskader 0:e2da1a4652f5 357 changeVolume();
kudlatykaskader 0:e2da1a4652f5 358 changeBass();
kudlatykaskader 0:e2da1a4652f5 359 _isIdle = true;
kudlatykaskader 0:e2da1a4652f5 360 return true;
kudlatykaskader 0:e2da1a4652f5 361 }
kudlatykaskader 0:e2da1a4652f5 362
kudlatykaskader 0:e2da1a4652f5 363 void VS1053::setVolume(float vol)
kudlatykaskader 0:e2da1a4652f5 364 {
kudlatykaskader 0:e2da1a4652f5 365 if (vol > -0.5)
kudlatykaskader 0:e2da1a4652f5 366 _volume = -0.5;
kudlatykaskader 0:e2da1a4652f5 367 else
kudlatykaskader 0:e2da1a4652f5 368 _volume = vol;
kudlatykaskader 0:e2da1a4652f5 369
kudlatykaskader 0:e2da1a4652f5 370 changeVolume();
kudlatykaskader 0:e2da1a4652f5 371 }
kudlatykaskader 0:e2da1a4652f5 372
kudlatykaskader 0:e2da1a4652f5 373 float VS1053::getVolume(void)
kudlatykaskader 0:e2da1a4652f5 374 {
kudlatykaskader 0:e2da1a4652f5 375 return _volume;
kudlatykaskader 0:e2da1a4652f5 376 }
kudlatykaskader 0:e2da1a4652f5 377
kudlatykaskader 0:e2da1a4652f5 378 void VS1053::setBalance(float balance)
kudlatykaskader 0:e2da1a4652f5 379 {
kudlatykaskader 0:e2da1a4652f5 380 _balance = balance;
kudlatykaskader 0:e2da1a4652f5 381
kudlatykaskader 0:e2da1a4652f5 382 changeVolume();
kudlatykaskader 0:e2da1a4652f5 383 }
kudlatykaskader 0:e2da1a4652f5 384
kudlatykaskader 0:e2da1a4652f5 385 float VS1053::getBalance(void)
kudlatykaskader 0:e2da1a4652f5 386 {
kudlatykaskader 0:e2da1a4652f5 387 return _balance;
kudlatykaskader 0:e2da1a4652f5 388 }
kudlatykaskader 0:e2da1a4652f5 389
kudlatykaskader 0:e2da1a4652f5 390 void VS1053::changeVolume(void)
kudlatykaskader 0:e2da1a4652f5 391 {
kudlatykaskader 0:e2da1a4652f5 392 // volume calculation
kudlatykaskader 0:e2da1a4652f5 393 unsigned short volCalced = (((char)(_volume / -0.5f)) << 8) + (char)((_volume - _balance) / -0.5f);
kudlatykaskader 0:e2da1a4652f5 394
kudlatykaskader 0:e2da1a4652f5 395 sci_write(SCI_VOL, volCalced);
kudlatykaskader 0:e2da1a4652f5 396
kudlatykaskader 0:e2da1a4652f5 397 DEBUGOUT("VS1053b: Change volume to %#x (%f, Balance = %f)\r\n", volCalced, _volume, _balance);
kudlatykaskader 0:e2da1a4652f5 398 }
kudlatykaskader 0:e2da1a4652f5 399
kudlatykaskader 0:e2da1a4652f5 400 int VS1053::getTrebleFrequency(void)
kudlatykaskader 0:e2da1a4652f5 401 {
kudlatykaskader 0:e2da1a4652f5 402 return _st_freqlimit * 1000;
kudlatykaskader 0:e2da1a4652f5 403 }
kudlatykaskader 0:e2da1a4652f5 404
kudlatykaskader 0:e2da1a4652f5 405
kudlatykaskader 0:e2da1a4652f5 406 void VS1053::setTrebleFrequency(int frequency)
kudlatykaskader 0:e2da1a4652f5 407 {
kudlatykaskader 0:e2da1a4652f5 408 frequency /= 1000;
kudlatykaskader 0:e2da1a4652f5 409
kudlatykaskader 0:e2da1a4652f5 410 if(frequency < 1)
kudlatykaskader 0:e2da1a4652f5 411 {
kudlatykaskader 0:e2da1a4652f5 412 frequency = 1;
kudlatykaskader 0:e2da1a4652f5 413 }
kudlatykaskader 0:e2da1a4652f5 414 else if(frequency > 15)
kudlatykaskader 0:e2da1a4652f5 415 {
kudlatykaskader 0:e2da1a4652f5 416 frequency = 15;
kudlatykaskader 0:e2da1a4652f5 417 }
kudlatykaskader 0:e2da1a4652f5 418 _st_freqlimit = frequency;
kudlatykaskader 0:e2da1a4652f5 419 changeBass();
kudlatykaskader 0:e2da1a4652f5 420 }
kudlatykaskader 0:e2da1a4652f5 421
kudlatykaskader 0:e2da1a4652f5 422 int VS1053::getTrebleAmplitude(void)
kudlatykaskader 0:e2da1a4652f5 423 {
kudlatykaskader 0:e2da1a4652f5 424 return _st_amplitude;
kudlatykaskader 0:e2da1a4652f5 425 }
kudlatykaskader 0:e2da1a4652f5 426
kudlatykaskader 0:e2da1a4652f5 427 void VS1053::setTrebleAmplitude(int amplitude)
kudlatykaskader 0:e2da1a4652f5 428 {
kudlatykaskader 0:e2da1a4652f5 429 if(amplitude < -8)
kudlatykaskader 0:e2da1a4652f5 430 {
kudlatykaskader 0:e2da1a4652f5 431 amplitude = -8;
kudlatykaskader 0:e2da1a4652f5 432 }
kudlatykaskader 0:e2da1a4652f5 433 else if(amplitude > 7)
kudlatykaskader 0:e2da1a4652f5 434 {
kudlatykaskader 0:e2da1a4652f5 435 amplitude = 7;
kudlatykaskader 0:e2da1a4652f5 436 }
kudlatykaskader 0:e2da1a4652f5 437 _st_amplitude = amplitude;
kudlatykaskader 0:e2da1a4652f5 438 changeBass();
kudlatykaskader 0:e2da1a4652f5 439 }
kudlatykaskader 0:e2da1a4652f5 440
kudlatykaskader 0:e2da1a4652f5 441 int VS1053::getBassFrequency(void)
kudlatykaskader 0:e2da1a4652f5 442 {
kudlatykaskader 0:e2da1a4652f5 443 return _sb_freqlimit * 10;
kudlatykaskader 0:e2da1a4652f5 444 }
kudlatykaskader 0:e2da1a4652f5 445
kudlatykaskader 0:e2da1a4652f5 446 void VS1053::setBassFrequency(int frequency)
kudlatykaskader 0:e2da1a4652f5 447 {
kudlatykaskader 0:e2da1a4652f5 448 frequency /= 10;
kudlatykaskader 0:e2da1a4652f5 449
kudlatykaskader 0:e2da1a4652f5 450 if(frequency < 2)
kudlatykaskader 0:e2da1a4652f5 451 {
kudlatykaskader 0:e2da1a4652f5 452 frequency = 2;
kudlatykaskader 0:e2da1a4652f5 453 }
kudlatykaskader 0:e2da1a4652f5 454 else if(frequency > 15)
kudlatykaskader 0:e2da1a4652f5 455 {
kudlatykaskader 0:e2da1a4652f5 456 frequency = 15;
kudlatykaskader 0:e2da1a4652f5 457 }
kudlatykaskader 0:e2da1a4652f5 458 _sb_freqlimit = frequency;
kudlatykaskader 0:e2da1a4652f5 459 changeBass();
kudlatykaskader 0:e2da1a4652f5 460 }
kudlatykaskader 0:e2da1a4652f5 461
kudlatykaskader 0:e2da1a4652f5 462 int VS1053::getBassAmplitude(void)
kudlatykaskader 0:e2da1a4652f5 463 {
kudlatykaskader 0:e2da1a4652f5 464 return _sb_amplitude;
kudlatykaskader 0:e2da1a4652f5 465 }
kudlatykaskader 0:e2da1a4652f5 466
kudlatykaskader 0:e2da1a4652f5 467 void VS1053::setBassAmplitude(int amplitude)
kudlatykaskader 0:e2da1a4652f5 468 {
kudlatykaskader 0:e2da1a4652f5 469 if(amplitude < -15)
kudlatykaskader 0:e2da1a4652f5 470 {
kudlatykaskader 0:e2da1a4652f5 471 amplitude = -15;
kudlatykaskader 0:e2da1a4652f5 472 }
kudlatykaskader 0:e2da1a4652f5 473 else if(amplitude > 0)
kudlatykaskader 0:e2da1a4652f5 474 {
kudlatykaskader 0:e2da1a4652f5 475 amplitude = 0;
kudlatykaskader 0:e2da1a4652f5 476 }
kudlatykaskader 0:e2da1a4652f5 477 _sb_amplitude = amplitude;
kudlatykaskader 0:e2da1a4652f5 478 changeBass();
kudlatykaskader 0:e2da1a4652f5 479 }
kudlatykaskader 0:e2da1a4652f5 480
kudlatykaskader 0:e2da1a4652f5 481 void VS1053::changeBass(void)
kudlatykaskader 0:e2da1a4652f5 482 {
kudlatykaskader 0:e2da1a4652f5 483 unsigned short bassCalced = ((_st_amplitude & 0x0f) << 12)
kudlatykaskader 0:e2da1a4652f5 484 | ((_st_freqlimit & 0x0f) << 8)
kudlatykaskader 0:e2da1a4652f5 485 | ((_sb_amplitude & 0x0f) << 4)
kudlatykaskader 0:e2da1a4652f5 486 | ((_sb_freqlimit & 0x0f) << 0);
kudlatykaskader 0:e2da1a4652f5 487
kudlatykaskader 0:e2da1a4652f5 488 sci_write(SCI_BASS, bassCalced);
kudlatykaskader 0:e2da1a4652f5 489
kudlatykaskader 0:e2da1a4652f5 490 DEBUGOUT("VS1053b: Change bass settings to:\r\n")
kudlatykaskader 0:e2da1a4652f5 491 DEBUGOUT("VS1053b: --Treble: Amplitude=%i, Frequency=%i\r\n", getTrebleAmplitude(), getTrebleFrequency());
kudlatykaskader 0:e2da1a4652f5 492 DEBUGOUT("VS1053b: --Bass: Amplitude=%i, Frequency=%i\r\n", getBassAmplitude(), getBassFrequency());
kudlatykaskader 0:e2da1a4652f5 493 }
kudlatykaskader 0:e2da1a4652f5 494
kudlatykaskader 0:e2da1a4652f5 495 /*===================================================================
kudlatykaskader 0:e2da1a4652f5 496 * Buffer handling
kudlatykaskader 0:e2da1a4652f5 497 *==================================================================*/
kudlatykaskader 0:e2da1a4652f5 498
kudlatykaskader 0:e2da1a4652f5 499 unsigned int VS1053::bufferLength(void)
kudlatykaskader 0:e2da1a4652f5 500 {
kudlatykaskader 0:e2da1a4652f5 501 return BUFFER_SIZE;
kudlatykaskader 0:e2da1a4652f5 502 }
kudlatykaskader 0:e2da1a4652f5 503
kudlatykaskader 0:e2da1a4652f5 504 unsigned char VS1053::bufferGetByte(void)
kudlatykaskader 0:e2da1a4652f5 505 {
kudlatykaskader 0:e2da1a4652f5 506 unsigned char retVal = 0x00;
kudlatykaskader 0:e2da1a4652f5 507 if (bufferCount() > 0x00)
kudlatykaskader 0:e2da1a4652f5 508 {
kudlatykaskader 0:e2da1a4652f5 509 retVal = *_bufferReadPointer++;
kudlatykaskader 0:e2da1a4652f5 510 if (_bufferReadPointer >= _buffer + BUFFER_SIZE)
kudlatykaskader 0:e2da1a4652f5 511 {
kudlatykaskader 0:e2da1a4652f5 512 _bufferReadPointer = _buffer;
kudlatykaskader 0:e2da1a4652f5 513 }
kudlatykaskader 0:e2da1a4652f5 514 }
kudlatykaskader 0:e2da1a4652f5 515 return retVal;
kudlatykaskader 0:e2da1a4652f5 516 }
kudlatykaskader 0:e2da1a4652f5 517
kudlatykaskader 0:e2da1a4652f5 518 bool VS1053::bufferSetByte(char c)
kudlatykaskader 0:e2da1a4652f5 519 {
kudlatykaskader 0:e2da1a4652f5 520 if (bufferFree() > 0x00)
kudlatykaskader 0:e2da1a4652f5 521 {
kudlatykaskader 0:e2da1a4652f5 522 *_bufferWritePointer++ = c;
kudlatykaskader 0:e2da1a4652f5 523 if (_bufferWritePointer >= _buffer + BUFFER_SIZE)
kudlatykaskader 0:e2da1a4652f5 524 {
kudlatykaskader 0:e2da1a4652f5 525 _bufferWritePointer = _buffer;
kudlatykaskader 0:e2da1a4652f5 526 }
kudlatykaskader 0:e2da1a4652f5 527 return true;
kudlatykaskader 0:e2da1a4652f5 528 }
kudlatykaskader 0:e2da1a4652f5 529 return false;
kudlatykaskader 0:e2da1a4652f5 530 }
kudlatykaskader 0:e2da1a4652f5 531
kudlatykaskader 0:e2da1a4652f5 532 bool VS1053::bufferPutStream(const char *s, unsigned int length)
kudlatykaskader 0:e2da1a4652f5 533 {
kudlatykaskader 0:e2da1a4652f5 534 if (bufferFree() >= length)
kudlatykaskader 0:e2da1a4652f5 535 {
kudlatykaskader 0:e2da1a4652f5 536 while (length--)
kudlatykaskader 0:e2da1a4652f5 537 {
kudlatykaskader 0:e2da1a4652f5 538 *_bufferWritePointer++ = *s++;
kudlatykaskader 0:e2da1a4652f5 539 if (_bufferWritePointer >= _buffer + BUFFER_SIZE)
kudlatykaskader 0:e2da1a4652f5 540 {
kudlatykaskader 0:e2da1a4652f5 541 _bufferWritePointer = _buffer;
kudlatykaskader 0:e2da1a4652f5 542 }
kudlatykaskader 0:e2da1a4652f5 543 }
kudlatykaskader 0:e2da1a4652f5 544 return true;
kudlatykaskader 0:e2da1a4652f5 545 }
kudlatykaskader 0:e2da1a4652f5 546 return false;
kudlatykaskader 0:e2da1a4652f5 547 }
kudlatykaskader 0:e2da1a4652f5 548
kudlatykaskader 0:e2da1a4652f5 549 unsigned int VS1053::bufferFree(void)
kudlatykaskader 0:e2da1a4652f5 550 {
kudlatykaskader 0:e2da1a4652f5 551 if(_bufferReadPointer > _bufferWritePointer)
kudlatykaskader 0:e2da1a4652f5 552 {
kudlatykaskader 0:e2da1a4652f5 553 return _bufferReadPointer - _bufferWritePointer - 1;
kudlatykaskader 0:e2da1a4652f5 554 }
kudlatykaskader 0:e2da1a4652f5 555 else if(_bufferReadPointer < _bufferWritePointer)
kudlatykaskader 0:e2da1a4652f5 556 {
kudlatykaskader 0:e2da1a4652f5 557 return BUFFER_SIZE - (_bufferWritePointer - _bufferReadPointer) - 1;
kudlatykaskader 0:e2da1a4652f5 558 }
kudlatykaskader 0:e2da1a4652f5 559 return BUFFER_SIZE - 1;
kudlatykaskader 0:e2da1a4652f5 560 }
kudlatykaskader 0:e2da1a4652f5 561
kudlatykaskader 0:e2da1a4652f5 562 unsigned int VS1053::bufferCount(void)
kudlatykaskader 0:e2da1a4652f5 563 {
kudlatykaskader 0:e2da1a4652f5 564 return BUFFER_SIZE - bufferFree() - 1;
kudlatykaskader 0:e2da1a4652f5 565 }
kudlatykaskader 0:e2da1a4652f5 566
kudlatykaskader 0:e2da1a4652f5 567 void VS1053::bufferReset(void)
kudlatykaskader 0:e2da1a4652f5 568 {
kudlatykaskader 0:e2da1a4652f5 569 _bufferReadPointer = _buffer;
kudlatykaskader 0:e2da1a4652f5 570 _bufferWritePointer = _buffer;
kudlatykaskader 0:e2da1a4652f5 571 }
kudlatykaskader 0:e2da1a4652f5 572
kudlatykaskader 0:e2da1a4652f5 573
kudlatykaskader 0:e2da1a4652f5 574 void VS1053::dataRequestHandler(void)
kudlatykaskader 0:e2da1a4652f5 575 {
kudlatykaskader 0:e2da1a4652f5 576 if (_isIdle && _DREQ)
kudlatykaskader 0:e2da1a4652f5 577 {
kudlatykaskader 0:e2da1a4652f5 578 _isIdle = false;
kudlatykaskader 0:e2da1a4652f5 579 // write buffer to vs1053b
kudlatykaskader 0:e2da1a4652f5 580 unsigned length = bufferCount();
kudlatykaskader 0:e2da1a4652f5 581 int i = 0;
kudlatykaskader 0:e2da1a4652f5 582 sdi_en();
kudlatykaskader 0:e2da1a4652f5 583
kudlatykaskader 0:e2da1a4652f5 584 while (length > 0)
kudlatykaskader 0:e2da1a4652f5 585 {
kudlatykaskader 0:e2da1a4652f5 586 int l2 = (length > 32) ? 32 : length;
kudlatykaskader 0:e2da1a4652f5 587 //DEBUGOUT("L2: %i\r\n", l2);
kudlatykaskader 0:e2da1a4652f5 588 for( ; l2 != 0; l2--)
kudlatykaskader 0:e2da1a4652f5 589 {
kudlatykaskader 0:e2da1a4652f5 590 _spi.write(bufferGetByte());
kudlatykaskader 0:e2da1a4652f5 591 }
kudlatykaskader 0:e2da1a4652f5 592
kudlatykaskader 0:e2da1a4652f5 593 length -= l2;
kudlatykaskader 0:e2da1a4652f5 594
kudlatykaskader 0:e2da1a4652f5 595 if (!_DREQ || i > 4)
kudlatykaskader 0:e2da1a4652f5 596 break;
kudlatykaskader 0:e2da1a4652f5 597 i++;
kudlatykaskader 0:e2da1a4652f5 598 }
kudlatykaskader 0:e2da1a4652f5 599
kudlatykaskader 0:e2da1a4652f5 600 sdi_dis();
kudlatykaskader 0:e2da1a4652f5 601
kudlatykaskader 0:e2da1a4652f5 602 _isIdle = true;
kudlatykaskader 0:e2da1a4652f5 603 }
kudlatykaskader 0:e2da1a4652f5 604 }
kudlatykaskader 0:e2da1a4652f5 605
kudlatykaskader 0:e2da1a4652f5 606 void VS1053::play(void)
kudlatykaskader 0:e2da1a4652f5 607 {
kudlatykaskader 0:e2da1a4652f5 608 INTERRUPT_HANDLER_ENABLE;
kudlatykaskader 0:e2da1a4652f5 609 DEBUGOUT("VS1053b: Play.\r\n");
kudlatykaskader 0:e2da1a4652f5 610 }
kudlatykaskader 0:e2da1a4652f5 611
kudlatykaskader 0:e2da1a4652f5 612 void VS1053::pause(void)
kudlatykaskader 0:e2da1a4652f5 613 {
kudlatykaskader 0:e2da1a4652f5 614 INTERRUPT_HANDLER_DISABLE;
kudlatykaskader 0:e2da1a4652f5 615 DEBUGOUT("VS1053b: Pause.\r\n");
kudlatykaskader 0:e2da1a4652f5 616 }
kudlatykaskader 0:e2da1a4652f5 617
kudlatykaskader 0:e2da1a4652f5 618 void VS1053::stop(void)
kudlatykaskader 0:e2da1a4652f5 619 {
kudlatykaskader 0:e2da1a4652f5 620 INTERRUPT_HANDLER_DISABLE;
kudlatykaskader 0:e2da1a4652f5 621 __disable_irq();
kudlatykaskader 0:e2da1a4652f5 622 DEBUGOUT("VS1053b: Song stoping..\r\n");
kudlatykaskader 0:e2da1a4652f5 623 while(!_isIdle)
kudlatykaskader 0:e2da1a4652f5 624 ;
kudlatykaskader 0:e2da1a4652f5 625
kudlatykaskader 0:e2da1a4652f5 626 // set SCI MODE bit SM CANCEL
kudlatykaskader 0:e2da1a4652f5 627 unsigned short sciModeByte = sci_read(SCI_MODE);
kudlatykaskader 0:e2da1a4652f5 628 sciModeByte |= SM_CANCEL;
kudlatykaskader 0:e2da1a4652f5 629 sci_write(SCI_MODE, sciModeByte);
kudlatykaskader 0:e2da1a4652f5 630
kudlatykaskader 0:e2da1a4652f5 631 // send up 2048 bytes of audio data.
kudlatykaskader 0:e2da1a4652f5 632 for (int i = 0; i < 64; i++)
kudlatykaskader 0:e2da1a4652f5 633 {
kudlatykaskader 0:e2da1a4652f5 634 // send at least 32 bytes of audio data
kudlatykaskader 0:e2da1a4652f5 635 int z = bufferCount();
kudlatykaskader 0:e2da1a4652f5 636 if (z > 32)
kudlatykaskader 0:e2da1a4652f5 637 z = 32;
kudlatykaskader 0:e2da1a4652f5 638 for (int n = 0; n < z; n++)
kudlatykaskader 0:e2da1a4652f5 639 {
kudlatykaskader 0:e2da1a4652f5 640 _spi.write(bufferGetByte());
kudlatykaskader 0:e2da1a4652f5 641 }
kudlatykaskader 0:e2da1a4652f5 642 // read SCI MODE; if SM CANCEL is still set, repeat
kudlatykaskader 0:e2da1a4652f5 643 sciModeByte = sci_read(SCI_MODE);
kudlatykaskader 0:e2da1a4652f5 644 if ((sciModeByte & SM_CANCEL) == 0x0000)
kudlatykaskader 0:e2da1a4652f5 645 {
kudlatykaskader 0:e2da1a4652f5 646 break;
kudlatykaskader 0:e2da1a4652f5 647 }
kudlatykaskader 0:e2da1a4652f5 648 }
kudlatykaskader 0:e2da1a4652f5 649
kudlatykaskader 0:e2da1a4652f5 650 if ((sciModeByte & SM_CANCEL) == 0x0000)
kudlatykaskader 0:e2da1a4652f5 651 {
kudlatykaskader 0:e2da1a4652f5 652 // send at least 2052 bytes of endFillByte[7:0].
kudlatykaskader 0:e2da1a4652f5 653 // read endFillByte (0 .. 15) from wram
kudlatykaskader 0:e2da1a4652f5 654 unsigned short endFillByte=wram_read(para_endFillByte);
kudlatykaskader 0:e2da1a4652f5 655 // clear endFillByte (8 .. 15)
kudlatykaskader 0:e2da1a4652f5 656 endFillByte = endFillByte ^0x00FF;
kudlatykaskader 0:e2da1a4652f5 657 for (int n = 0; n < 2052; n++)
kudlatykaskader 0:e2da1a4652f5 658 sdi_write(endFillByte);
kudlatykaskader 0:e2da1a4652f5 659 DEBUGOUT("VS1053b: Song sucessfully stopped.\r\n");
kudlatykaskader 0:e2da1a4652f5 660 DEBUGOUT("VS1053b: SCI MODE = %#x, SM_CANCEL = %#x\r\n", sciModeByte, sciModeByte & SM_CANCEL);
kudlatykaskader 0:e2da1a4652f5 661 sci_write(SCI_DECODE_TIME, 0x0000);
kudlatykaskader 0:e2da1a4652f5 662 }
kudlatykaskader 0:e2da1a4652f5 663 else
kudlatykaskader 0:e2da1a4652f5 664 {
kudlatykaskader 0:e2da1a4652f5 665 DEBUGOUT("VS1053b: SM CANCEL hasn't cleared after sending 2048 bytes, do software reset\r\n");
kudlatykaskader 0:e2da1a4652f5 666 DEBUGOUT("VS1053b: SCI MODE = %#x, SM_CANCEL = %#x\r\n", sciModeByte, sciModeByte & SM_CANCEL);
kudlatykaskader 0:e2da1a4652f5 667 initialize();
kudlatykaskader 0:e2da1a4652f5 668 }
kudlatykaskader 0:e2da1a4652f5 669
kudlatykaskader 0:e2da1a4652f5 670 bufferReset();
kudlatykaskader 0:e2da1a4652f5 671 __enable_irq();
kudlatykaskader 0:e2da1a4652f5 672 }
kudlatykaskader 0:e2da1a4652f5 673
kudlatykaskader 0:e2da1a4652f5 674 void VS1053::getAudioInfo(AudioInfo* aInfo)
kudlatykaskader 0:e2da1a4652f5 675 {
kudlatykaskader 0:e2da1a4652f5 676 // volume calculation
kudlatykaskader 0:e2da1a4652f5 677 unsigned short hdat0 = sci_read(SCI_HDAT0);
kudlatykaskader 0:e2da1a4652f5 678 unsigned short hdat1 = sci_read(SCI_HDAT1);
kudlatykaskader 0:e2da1a4652f5 679
kudlatykaskader 0:e2da1a4652f5 680 DEBUGOUT("VS1053b: Audio info\r\n");
kudlatykaskader 0:e2da1a4652f5 681
kudlatykaskader 0:e2da1a4652f5 682 AudioInfo* retVal = aInfo;
kudlatykaskader 0:e2da1a4652f5 683 retVal->type = UNKNOWN;
kudlatykaskader 0:e2da1a4652f5 684
kudlatykaskader 0:e2da1a4652f5 685 if (hdat1 == 0x7665)
kudlatykaskader 0:e2da1a4652f5 686 {
kudlatykaskader 0:e2da1a4652f5 687 // audio is WAV
kudlatykaskader 0:e2da1a4652f5 688 retVal->type = WAV;
kudlatykaskader 0:e2da1a4652f5 689 }
kudlatykaskader 0:e2da1a4652f5 690 else if (hdat1 == 0x4154 || hdat1 == 0x4144 || hdat1 == 0x4D34 )
kudlatykaskader 0:e2da1a4652f5 691 {
kudlatykaskader 0:e2da1a4652f5 692 // audio is AAC
kudlatykaskader 0:e2da1a4652f5 693 retVal->type = AAC;
kudlatykaskader 0:e2da1a4652f5 694 }
kudlatykaskader 0:e2da1a4652f5 695 else if (hdat1 == 0x574D )
kudlatykaskader 0:e2da1a4652f5 696 {
kudlatykaskader 0:e2da1a4652f5 697 // audio is WMA
kudlatykaskader 0:e2da1a4652f5 698 retVal->type = WMA;
kudlatykaskader 0:e2da1a4652f5 699 }
kudlatykaskader 0:e2da1a4652f5 700 else if (hdat1 == 0x4D54 )
kudlatykaskader 0:e2da1a4652f5 701 {
kudlatykaskader 0:e2da1a4652f5 702 // audio is MIDI
kudlatykaskader 0:e2da1a4652f5 703 retVal->type = MIDI;
kudlatykaskader 0:e2da1a4652f5 704 }
kudlatykaskader 0:e2da1a4652f5 705 else if (hdat1 == 0x4F76 )
kudlatykaskader 0:e2da1a4652f5 706 {
kudlatykaskader 0:e2da1a4652f5 707 // audio is OGG VORBIS
kudlatykaskader 0:e2da1a4652f5 708 retVal->type = OGG_VORBIS;
kudlatykaskader 0:e2da1a4652f5 709 }
kudlatykaskader 0:e2da1a4652f5 710 else if (hdat1 >= 0xFFE0 && hdat1 <= 0xFFFF)
kudlatykaskader 0:e2da1a4652f5 711 {
kudlatykaskader 0:e2da1a4652f5 712 // audio is mp3
kudlatykaskader 0:e2da1a4652f5 713 retVal->type = MP3;
kudlatykaskader 0:e2da1a4652f5 714
kudlatykaskader 0:e2da1a4652f5 715 DEBUGOUT("VS1053b: Audio is mp3\r\n");
kudlatykaskader 0:e2da1a4652f5 716 retVal->ext.mp3.id = (MP3_ID)((hdat1 >> 3) & 0x0003);
kudlatykaskader 0:e2da1a4652f5 717 switch((hdat1 >> 1) & 0x0003)
kudlatykaskader 0:e2da1a4652f5 718 {
kudlatykaskader 0:e2da1a4652f5 719 case 3:
kudlatykaskader 0:e2da1a4652f5 720 retVal->ext.mp3.layer = 1;
kudlatykaskader 0:e2da1a4652f5 721 break;
kudlatykaskader 0:e2da1a4652f5 722 case 2:
kudlatykaskader 0:e2da1a4652f5 723 retVal->ext.mp3.layer = 2;
kudlatykaskader 0:e2da1a4652f5 724 break;
kudlatykaskader 0:e2da1a4652f5 725 case 1:
kudlatykaskader 0:e2da1a4652f5 726 retVal->ext.mp3.layer = 3;
kudlatykaskader 0:e2da1a4652f5 727 break;
kudlatykaskader 0:e2da1a4652f5 728 default:
kudlatykaskader 0:e2da1a4652f5 729 retVal->ext.mp3.layer = 0;
kudlatykaskader 0:e2da1a4652f5 730 break;
kudlatykaskader 0:e2da1a4652f5 731 }
kudlatykaskader 0:e2da1a4652f5 732 retVal->ext.mp3.protrectBit = (hdat1 >> 0) & 0x0001;
kudlatykaskader 0:e2da1a4652f5 733
kudlatykaskader 0:e2da1a4652f5 734 char srate = (hdat0 >> 10) & 0x0003;
kudlatykaskader 0:e2da1a4652f5 735 retVal->ext.mp3.kSampleRate = _sampleRateTable[retVal->ext.mp3.id][srate];
kudlatykaskader 0:e2da1a4652f5 736
kudlatykaskader 0:e2da1a4652f5 737 retVal->ext.mp3.padBit = (hdat0 >> 9) & 0x0001;
kudlatykaskader 0:e2da1a4652f5 738 retVal->ext.mp3.mode =(MP3_MODE)((hdat0 >> 6) & 0x0003);
kudlatykaskader 0:e2da1a4652f5 739 retVal->ext.mp3.extension = (hdat0 >> 4) & 0x0003;
kudlatykaskader 0:e2da1a4652f5 740 retVal->ext.mp3.copyright = (hdat0 >> 3) & 0x0001;
kudlatykaskader 0:e2da1a4652f5 741 retVal->ext.mp3.original = (hdat0 >> 2) & 0x0001;
kudlatykaskader 0:e2da1a4652f5 742 retVal->ext.mp3.emphasis = (hdat0 >> 0) & 0x0003;
kudlatykaskader 0:e2da1a4652f5 743
kudlatykaskader 0:e2da1a4652f5 744 DEBUGOUT("VS1053b: ID: %i, Layer: %i, Samplerate: %i, Mode: %i\r\n", retVal->ext.mp3.id, retVal->ext.mp3.layer, retVal->ext.mp3.kSampleRate, retVal->ext.mp3.mode);
kudlatykaskader 0:e2da1a4652f5 745 }
kudlatykaskader 0:e2da1a4652f5 746
kudlatykaskader 0:e2da1a4652f5 747 // read byteRate
kudlatykaskader 0:e2da1a4652f5 748 unsigned short byteRate = wram_read(para_byteRate);
kudlatykaskader 0:e2da1a4652f5 749 retVal->kBitRate = (byteRate * 8) / 1000;
kudlatykaskader 0:e2da1a4652f5 750 DEBUGOUT("VS1053b: BitRate: %i kBit/s\r\n", retVal->kBitRate);
kudlatykaskader 0:e2da1a4652f5 751
kudlatykaskader 0:e2da1a4652f5 752 // decode time
kudlatykaskader 0:e2da1a4652f5 753 retVal->decodeTime = sci_read(SCI_DECODE_TIME);
kudlatykaskader 0:e2da1a4652f5 754 DEBUGOUT("VS1053b: Decodetime: %i s\r\n", retVal->decodeTime);
kudlatykaskader 0:e2da1a4652f5 755
kudlatykaskader 0:e2da1a4652f5 756 }