Add the RTOS processing. for the Network radio streaming receiver.

Fork of VS1053b by Christian Schmiljun

Committer:
ban4jp
Date:
Sun Feb 22 14:44:41 2015 +0000
Revision:
10:114ac02a3875
Parent:
8:5e4a21202223
Add support the RTOS processing.

Who changed what in which revision?

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