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

Fork of VS1053b by Christian Schmiljun

Committer:
christi_s
Date:
Tue Dec 14 18:22:54 2010 +0000
Revision:
0:7728d9c6c487
Child:
1:ced2c297cc1b
initial

Who changed what in which revision?

UserRevisionLine numberNew contents of line
christi_s 0:7728d9c6c487 1 #include "VS1053.h"
christi_s 0:7728d9c6c487 2 #include "mbed.h"
christi_s 0:7728d9c6c487 3
christi_s 0:7728d9c6c487 4 // patch binarys
christi_s 0:7728d9c6c487 5 #include "Patches/VS1053b_patch_1_5.c"
christi_s 0:7728d9c6c487 6 #include "Patches/VS1053b_patch_1_5_flac.c"
christi_s 0:7728d9c6c487 7 #include "Patches/VS1053b_patch_1_4_flac.c"
christi_s 0:7728d9c6c487 8 // spectrum analyzer binary
christi_s 0:7728d9c6c487 9 #include "Patches/VS1053b_specana.c"
christi_s 0:7728d9c6c487 10
christi_s 0:7728d9c6c487 11
christi_s 0:7728d9c6c487 12 /* ==================================================================
christi_s 0:7728d9c6c487 13 * Constructor
christi_s 0:7728d9c6c487 14 * =================================================================*/
christi_s 0:7728d9c6c487 15 VS1053::VS1053(
christi_s 0:7728d9c6c487 16 PinName mosi, PinName miso, PinName sck, PinName cs, PinName rst,
christi_s 0:7728d9c6c487 17 PinName dreq, PinName dcs)
christi_s 0:7728d9c6c487 18 :
christi_s 0:7728d9c6c487 19 _spi(mosi, miso, sck),
christi_s 0:7728d9c6c487 20 _CS(cs),
christi_s 0:7728d9c6c487 21 _RST(rst),
christi_s 0:7728d9c6c487 22 _DREQ(dreq),
christi_s 0:7728d9c6c487 23 _DCS(dcs) {
christi_s 0:7728d9c6c487 24 firstTime=-1;
christi_s 0:7728d9c6c487 25 }
christi_s 0:7728d9c6c487 26
christi_s 0:7728d9c6c487 27 /*===================================================================
christi_s 0:7728d9c6c487 28 * Functions
christi_s 0:7728d9c6c487 29 *==================================================================*/
christi_s 0:7728d9c6c487 30
christi_s 0:7728d9c6c487 31 void VS1053::cs_low(void) {
christi_s 0:7728d9c6c487 32 _CS = 0;
christi_s 0:7728d9c6c487 33 }
christi_s 0:7728d9c6c487 34 void VS1053::cs_high(void) {
christi_s 0:7728d9c6c487 35 _CS = 1;
christi_s 0:7728d9c6c487 36 }
christi_s 0:7728d9c6c487 37 void VS1053::dcs_low(void) {
christi_s 0:7728d9c6c487 38 _DCS = 0;
christi_s 0:7728d9c6c487 39
christi_s 0:7728d9c6c487 40 }
christi_s 0:7728d9c6c487 41 void VS1053::dcs_high(void) {
christi_s 0:7728d9c6c487 42 _DCS = 1;
christi_s 0:7728d9c6c487 43 }
christi_s 0:7728d9c6c487 44 void VS1053::sci_en(void) { //SCI enable
christi_s 0:7728d9c6c487 45 cs_high();
christi_s 0:7728d9c6c487 46 dcs_high();
christi_s 0:7728d9c6c487 47 cs_low();
christi_s 0:7728d9c6c487 48 }
christi_s 0:7728d9c6c487 49 void VS1053::sci_dis(void) { //SCI disable
christi_s 0:7728d9c6c487 50 cs_high();
christi_s 0:7728d9c6c487 51 }
christi_s 0:7728d9c6c487 52 void VS1053::sdi_en(void) { //SDI enable
christi_s 0:7728d9c6c487 53 dcs_high();
christi_s 0:7728d9c6c487 54 cs_high();
christi_s 0:7728d9c6c487 55 dcs_low();
christi_s 0:7728d9c6c487 56 }
christi_s 0:7728d9c6c487 57 void VS1053::sdi_dis(void) { //SDI disable
christi_s 0:7728d9c6c487 58 dcs_high();
christi_s 0:7728d9c6c487 59 }
christi_s 0:7728d9c6c487 60 void VS1053::reset(void) { //hardware reset
christi_s 0:7728d9c6c487 61 // wait(0.01);
christi_s 0:7728d9c6c487 62 wait_ms(10);
christi_s 0:7728d9c6c487 63 _RST = 0;
christi_s 0:7728d9c6c487 64 // wait(0.01);
christi_s 0:7728d9c6c487 65 wait_ms(5);
christi_s 0:7728d9c6c487 66 _RST = 1;
christi_s 0:7728d9c6c487 67 // wait(0.10);
christi_s 0:7728d9c6c487 68 wait_ms(10);
christi_s 0:7728d9c6c487 69 }
christi_s 0:7728d9c6c487 70 void VS1053::power_down(void) { //hardware and software reset
christi_s 0:7728d9c6c487 71 cs_low();
christi_s 0:7728d9c6c487 72 reset();
christi_s 0:7728d9c6c487 73 // sci_write(0x00, SM_PDOWN);
christi_s 0:7728d9c6c487 74 sci_write(0x00, 0x10); // tempo
christi_s 0:7728d9c6c487 75 wait(0.01);
christi_s 0:7728d9c6c487 76 reset();
christi_s 0:7728d9c6c487 77 }
christi_s 0:7728d9c6c487 78 void VS1053::sci_initialise(void) {
christi_s 0:7728d9c6c487 79 _RST = 1; //no reset
christi_s 0:7728d9c6c487 80 _spi.format(8,0); //spi 8bit interface, steady state low
christi_s 0:7728d9c6c487 81 // _spi.frequency(1000000); //rising edge data record, freq. 1Mhz
christi_s 0:7728d9c6c487 82 _spi.frequency(2000000); //rising edge data record, freq. 2Mhz
christi_s 0:7728d9c6c487 83
christi_s 0:7728d9c6c487 84
christi_s 0:7728d9c6c487 85 cs_low();
christi_s 0:7728d9c6c487 86 for (int i=0; i<4; i++) {
christi_s 0:7728d9c6c487 87 _spi.write(0xFF); //clock the chip a bit
christi_s 0:7728d9c6c487 88 }
christi_s 0:7728d9c6c487 89 cs_high();
christi_s 0:7728d9c6c487 90 dcs_high();
christi_s 0:7728d9c6c487 91 wait_us(5);
christi_s 0:7728d9c6c487 92 }
christi_s 0:7728d9c6c487 93 void VS1053::sdi_initialise(void) {
christi_s 0:7728d9c6c487 94 _spi.format(8,0);
christi_s 0:7728d9c6c487 95 // _spi.frequency(7000000); //set to 7MHz
christi_s 0:7728d9c6c487 96 // _spi.frequency(12000000); //set to 12MHz to make fast transfer
christi_s 0:7728d9c6c487 97 _spi.frequency(18000000); //set to 18MHz to make fast transfer
christi_s 0:7728d9c6c487 98 //NG does not work// _spi.frequency(24000000); //set to 24MHz to make fast transfer
christi_s 0:7728d9c6c487 99
christi_s 0:7728d9c6c487 100 cs_high();
christi_s 0:7728d9c6c487 101 dcs_high();
christi_s 0:7728d9c6c487 102 }
christi_s 0:7728d9c6c487 103 void VS1053::sci_write(unsigned char address, unsigned short int data) {
christi_s 0:7728d9c6c487 104 sci_en(); //enables SCI/disables SDI
christi_s 0:7728d9c6c487 105
christi_s 0:7728d9c6c487 106 while (!_DREQ); //wait unitl data request is high
christi_s 0:7728d9c6c487 107 _spi.write(0x02); //SCI write
christi_s 0:7728d9c6c487 108 _spi.write(address); //register address
christi_s 0:7728d9c6c487 109 _spi.write((data >> 8) & 0xFF); //write out first half of data word
christi_s 0:7728d9c6c487 110 _spi.write(data & 0xFF); //write out second half of data word
christi_s 0:7728d9c6c487 111
christi_s 0:7728d9c6c487 112 sci_dis(); //enables SDI/disables SCI
christi_s 0:7728d9c6c487 113 wait_us(5);
christi_s 0:7728d9c6c487 114 }
christi_s 0:7728d9c6c487 115 void VS1053::sdi_write(unsigned char datum) {
christi_s 0:7728d9c6c487 116 sdi_en();
christi_s 0:7728d9c6c487 117
christi_s 0:7728d9c6c487 118 while (!_DREQ);
christi_s 0:7728d9c6c487 119 _spi.write(datum);
christi_s 0:7728d9c6c487 120
christi_s 0:7728d9c6c487 121 //? sci_dis();
christi_s 0:7728d9c6c487 122 sdi_dis();
christi_s 0:7728d9c6c487 123 }
christi_s 0:7728d9c6c487 124 unsigned short int VS1053::sci_read(unsigned short int address) {
christi_s 0:7728d9c6c487 125 cs_low(); //enables SCI/disables SDI
christi_s 0:7728d9c6c487 126
christi_s 0:7728d9c6c487 127 while (!_DREQ); //wait unitl data request is high
christi_s 0:7728d9c6c487 128 _spi.write(0x03); //SCI write
christi_s 0:7728d9c6c487 129 _spi.write(address); //register address
christi_s 0:7728d9c6c487 130 unsigned short int received = _spi.write(0x00); //write out dummy byte
christi_s 0:7728d9c6c487 131 received <<= 8;
christi_s 0:7728d9c6c487 132 received += _spi.write(0x00); //write out dummy byte
christi_s 0:7728d9c6c487 133
christi_s 0:7728d9c6c487 134 cs_high(); //enables SDI/disables SCI
christi_s 0:7728d9c6c487 135
christi_s 0:7728d9c6c487 136 return received; //return received word
christi_s 0:7728d9c6c487 137 }
christi_s 0:7728d9c6c487 138 void VS1053::sine_test_activate(unsigned char wave) {
christi_s 0:7728d9c6c487 139 cs_high(); //enables SDI/disables SCI
christi_s 0:7728d9c6c487 140
christi_s 0:7728d9c6c487 141 while (!_DREQ); //wait unitl data request is high
christi_s 0:7728d9c6c487 142 _spi.write(0x53); //SDI write
christi_s 0:7728d9c6c487 143 _spi.write(0xEF); //SDI write
christi_s 0:7728d9c6c487 144 _spi.write(0x6E); //SDI write
christi_s 0:7728d9c6c487 145 _spi.write(wave); //SDI write
christi_s 0:7728d9c6c487 146 _spi.write(0x00); //filler byte
christi_s 0:7728d9c6c487 147 _spi.write(0x00); //filler byte
christi_s 0:7728d9c6c487 148 _spi.write(0x00); //filler byte
christi_s 0:7728d9c6c487 149 _spi.write(0x00); //filler byte
christi_s 0:7728d9c6c487 150
christi_s 0:7728d9c6c487 151 cs_low(); //enables SCI/disables SDI
christi_s 0:7728d9c6c487 152 }
christi_s 0:7728d9c6c487 153 void VS1053::sine_test_deactivate(void) {
christi_s 0:7728d9c6c487 154 cs_high();
christi_s 0:7728d9c6c487 155
christi_s 0:7728d9c6c487 156 while (!_DREQ);
christi_s 0:7728d9c6c487 157 _spi.write(0x45); //SDI write
christi_s 0:7728d9c6c487 158 _spi.write(0x78); //SDI write
christi_s 0:7728d9c6c487 159 _spi.write(0x69); //SDI write
christi_s 0:7728d9c6c487 160 _spi.write(0x74); //SDI write
christi_s 0:7728d9c6c487 161 _spi.write(0x00); //filler byte
christi_s 0:7728d9c6c487 162 _spi.write(0x00); //filler byte
christi_s 0:7728d9c6c487 163 _spi.write(0x00); //filler byte
christi_s 0:7728d9c6c487 164 _spi.write(0x00); //filler byte
christi_s 0:7728d9c6c487 165 }
christi_s 0:7728d9c6c487 166
christi_s 0:7728d9c6c487 167 void VS1053::writeStream(unsigned char *array, int size) {
christi_s 0:7728d9c6c487 168 for (int i=0; i<size; i++) {
christi_s 0:7728d9c6c487 169 sdi_write(array[i]);
christi_s 0:7728d9c6c487 170 }
christi_s 0:7728d9c6c487 171 }
christi_s 0:7728d9c6c487 172
christi_s 0:7728d9c6c487 173 #if 0
christi_s 0:7728d9c6c487 174 // this function does not work
christi_s 0:7728d9c6c487 175 // because of function call overhead
christi_s 0:7728d9c6c487 176 void VS1053::putcStream(unsigned char datum) {
christi_s 0:7728d9c6c487 177 sdi_write(datum);
christi_s 0:7728d9c6c487 178 }
christi_s 0:7728d9c6c487 179 #endif
christi_s 0:7728d9c6c487 180
christi_s 0:7728d9c6c487 181 unsigned short int VS1053::wram_read(unsigned short int address) {
christi_s 0:7728d9c6c487 182 unsigned short int tmp1,tmp2;
christi_s 0:7728d9c6c487 183 sci_write(SCI_WRAMADDR,address);
christi_s 0:7728d9c6c487 184 tmp1=sci_read(SCI_WRAM);
christi_s 0:7728d9c6c487 185 sci_write(SCI_WRAMADDR,address);
christi_s 0:7728d9c6c487 186 tmp2=sci_read(SCI_WRAM);
christi_s 0:7728d9c6c487 187 if (tmp1==tmp2) return tmp1;
christi_s 0:7728d9c6c487 188 sci_write(SCI_WRAMADDR,address);
christi_s 0:7728d9c6c487 189 tmp1=sci_read(SCI_WRAM);
christi_s 0:7728d9c6c487 190 if (tmp1==tmp2) return tmp1;
christi_s 0:7728d9c6c487 191 sci_write(SCI_WRAMADDR,address);
christi_s 0:7728d9c6c487 192 tmp1=sci_read(SCI_WRAM);
christi_s 0:7728d9c6c487 193 if (tmp1==tmp2) return tmp1;
christi_s 0:7728d9c6c487 194 return tmp1;
christi_s 0:7728d9c6c487 195 }
christi_s 0:7728d9c6c487 196
christi_s 0:7728d9c6c487 197 void VS1053::wram_write(unsigned short int address, unsigned short int data) {
christi_s 0:7728d9c6c487 198 sci_write(SCI_WRAMADDR,address);
christi_s 0:7728d9c6c487 199 sci_write(SCI_WRAM,data);
christi_s 0:7728d9c6c487 200 return;
christi_s 0:7728d9c6c487 201 }
christi_s 0:7728d9c6c487 202
christi_s 0:7728d9c6c487 203
christi_s 0:7728d9c6c487 204 void VS1053::terminateStream(void) {
christi_s 0:7728d9c6c487 205 #if 1
christi_s 0:7728d9c6c487 206 unsigned int endFillByte=wram_read(para_endFillByte);
christi_s 0:7728d9c6c487 207 // printf("endFillByte:%04X\r\n",endFillByte); // debug
christi_s 0:7728d9c6c487 208 for (int n=0; n<2052; n++) sdi_write(0xFF&endFillByte);
christi_s 0:7728d9c6c487 209 sci_write(SCI_MODE,(SM_SDINEW+SM_CANCEL));
christi_s 0:7728d9c6c487 210 for (int n=0; n<2048; n++) sdi_write(0xFF&endFillByte);
christi_s 0:7728d9c6c487 211 // don't reset if you don't want to lose the patch
christi_s 0:7728d9c6c487 212 // sci_write(SCI_MODE,(SM_SDINEW+SM_RESET)); // set mode reg.
christi_s 0:7728d9c6c487 213 // wait_ms(10);
christi_s 0:7728d9c6c487 214 #endif
christi_s 0:7728d9c6c487 215 }
christi_s 0:7728d9c6c487 216
christi_s 0:7728d9c6c487 217 void VS1053::write_plugin(const unsigned short *plugin, unsigned int len) {
christi_s 0:7728d9c6c487 218 unsigned int i;
christi_s 0:7728d9c6c487 219 unsigned short addr, n, val;
christi_s 0:7728d9c6c487 220
christi_s 0:7728d9c6c487 221 for (i=0; i<len;) {
christi_s 0:7728d9c6c487 222 addr = plugin[i++];
christi_s 0:7728d9c6c487 223 n = plugin[i++];
christi_s 0:7728d9c6c487 224 if (n & 0x8000U) { //RLE run, replicate n samples
christi_s 0:7728d9c6c487 225 n &= 0x7FFF;
christi_s 0:7728d9c6c487 226 val = plugin[i++];
christi_s 0:7728d9c6c487 227 while (n--) {
christi_s 0:7728d9c6c487 228 sci_write(addr,val);
christi_s 0:7728d9c6c487 229 }
christi_s 0:7728d9c6c487 230 } else { //copy run, copy n sample
christi_s 0:7728d9c6c487 231 while (n--) {
christi_s 0:7728d9c6c487 232 val = plugin[i++];
christi_s 0:7728d9c6c487 233 sci_write(addr,val);
christi_s 0:7728d9c6c487 234 }
christi_s 0:7728d9c6c487 235 }
christi_s 0:7728d9c6c487 236 }
christi_s 0:7728d9c6c487 237
christi_s 0:7728d9c6c487 238 return;
christi_s 0:7728d9c6c487 239 }
christi_s 0:7728d9c6c487 240
christi_s 0:7728d9c6c487 241
christi_s 0:7728d9c6c487 242 void VS1053::initialize(void) {
christi_s 0:7728d9c6c487 243 _RST = 1;
christi_s 0:7728d9c6c487 244 cs_high(); //chip disabled
christi_s 0:7728d9c6c487 245 sci_initialise(); //initialise MBED
christi_s 0:7728d9c6c487 246 sci_write(SCI_MODE,(SM_SDINEW+SM_RESET)); // set mode reg.
christi_s 0:7728d9c6c487 247 wait_ms(10);
christi_s 0:7728d9c6c487 248 #if 1
christi_s 0:7728d9c6c487 249 // debug
christi_s 0:7728d9c6c487 250 unsigned int chipID_0=wram_read(para_chipID_0);
christi_s 0:7728d9c6c487 251 if (firstTime) printf("chipID_0:%04X\r\n",chipID_0); // debug
christi_s 0:7728d9c6c487 252 unsigned int chipID_1=wram_read(para_chipID_1);
christi_s 0:7728d9c6c487 253 if (firstTime) printf("chipID_1:%04X\r\n",chipID_1); // debug
christi_s 0:7728d9c6c487 254 unsigned int struct_version=wram_read(para_version);
christi_s 0:7728d9c6c487 255 if (firstTime) printf("structure version:%04X\r\n",struct_version); // debug
christi_s 0:7728d9c6c487 256 #endif
christi_s 0:7728d9c6c487 257 //get chip version, set clock multiplier and load patch
christi_s 0:7728d9c6c487 258 int i = (sci_read(SCI_STATUS)&0xF0)>>4;
christi_s 0:7728d9c6c487 259 if (i == 4) {
christi_s 0:7728d9c6c487 260 if (firstTime) printf("Installed Chip is: VS1053\r\n");
christi_s 0:7728d9c6c487 261 sci_write(SCI_CLOCKF, (SC_MULT_XTALIx50+SC_ADD_20x));
christi_s 0:7728d9c6c487 262 #ifdef VS_PATCH
christi_s 0:7728d9c6c487 263 // loading patch
christi_s 0:7728d9c6c487 264 write_plugin(vs1053b_patch, sizeof(vs1053b_patch)/2);
christi_s 0:7728d9c6c487 265 if (firstTime) {
christi_s 0:7728d9c6c487 266 printf("VS1053b patch loaded.\r\n");
christi_s 0:7728d9c6c487 267 printf("patch size:%d bytes\r\n",sizeof(vs1053b_patch));
christi_s 0:7728d9c6c487 268 }
christi_s 0:7728d9c6c487 269 #endif
christi_s 0:7728d9c6c487 270 #ifdef VS_SPECANA
christi_s 0:7728d9c6c487 271 // loading plugin(spectrum analyzer)
christi_s 0:7728d9c6c487 272 write_plugin(vs1053b_specana, sizeof(vs1053b_specana)/2);
christi_s 0:7728d9c6c487 273 if (firstTime) printf("VS1053b specana loaded.\r\n");
christi_s 0:7728d9c6c487 274 #endif
christi_s 0:7728d9c6c487 275 } else printf("??? Not Supported Chip???\r\n");
christi_s 0:7728d9c6c487 276 sdi_initialise();
christi_s 0:7728d9c6c487 277 firstTime=0; // disable message when init after 1st time
christi_s 0:7728d9c6c487 278 }
christi_s 0:7728d9c6c487 279
christi_s 0:7728d9c6c487 280 void VS1053::setVolume(unsigned short int vol) {
christi_s 0:7728d9c6c487 281 while (!_DREQ);
christi_s 0:7728d9c6c487 282 sci_write(0x0B, vol);
christi_s 0:7728d9c6c487 283 }