Library for VS1053 chip

Committer:
clemente
Date:
Wed May 23 06:28:16 2012 +0000
Revision:
0:e97876f96d4b
Child:
1:399afe8151de

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
clemente 0:e97876f96d4b 1 /* mbed VLSIcodec library. To access VS1053 MPEG3 codec.
clemente 0:e97876f96d4b 2
clemente 0:e97876f96d4b 3 Copyright (c) 2010 NXP 3790
clemente 0:e97876f96d4b 4
clemente 0:e97876f96d4b 5 Permission is hereby granted, free of charge, to any person obtaining a copy
clemente 0:e97876f96d4b 6 of this software and associated documentation files (the "Software"), to deal
clemente 0:e97876f96d4b 7 in the Software without restriction, including without limitation the rights
clemente 0:e97876f96d4b 8 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
clemente 0:e97876f96d4b 9 copies of the Software, and to permit persons to whom the Software is
clemente 0:e97876f96d4b 10 furnished to do so, subject to the following conditions:
clemente 0:e97876f96d4b 11
clemente 0:e97876f96d4b 12 The above copyright notice and this permission notice shall be included in
clemente 0:e97876f96d4b 13 all copies or substantial portions of the Software.
clemente 0:e97876f96d4b 14
clemente 0:e97876f96d4b 15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
clemente 0:e97876f96d4b 16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
clemente 0:e97876f96d4b 17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
clemente 0:e97876f96d4b 18 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
clemente 0:e97876f96d4b 19 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
clemente 0:e97876f96d4b 20 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
clemente 0:e97876f96d4b 21 THE SOFTWARE.
clemente 0:e97876f96d4b 22 */
clemente 0:e97876f96d4b 23
clemente 0:e97876f96d4b 24 #include "mbed.h"
clemente 0:e97876f96d4b 25 #include "VLSIcodec.h"
clemente 0:e97876f96d4b 26 #include "VLSIcodec_patch.h"
clemente 0:e97876f96d4b 27
clemente 0:e97876f96d4b 28 #ifdef __ENCODE_OGG
clemente 0:e97876f96d4b 29 #include "VLSIcodec_OGG.h"
clemente 0:e97876f96d4b 30 #endif
clemente 0:e97876f96d4b 31
clemente 0:e97876f96d4b 32 #ifdef __PLUGINGA
clemente 0:e97876f96d4b 33 #include "VLSIcodec_pluginGA.h"
clemente 0:e97876f96d4b 34 #define cBASE 0x1800 /* Base address of X-RAM for a VS1053 */
clemente 0:e97876f96d4b 35 #endif
clemente 0:e97876f96d4b 36
clemente 0:e97876f96d4b 37
clemente 0:e97876f96d4b 38 //******************************************************************************
clemente 0:e97876f96d4b 39 //******************************************************************************
clemente 0:e97876f96d4b 40 // Section: Constants
clemente 0:e97876f96d4b 41 //******************************************************************************
clemente 0:e97876f96d4b 42 //******************************************************************************
clemente 0:e97876f96d4b 43
clemente 0:e97876f96d4b 44 #define VLSI_MODE 0x00
clemente 0:e97876f96d4b 45 #define VLSI_STATUS 0x01
clemente 0:e97876f96d4b 46 #define VLSI_BASS 0x02
clemente 0:e97876f96d4b 47 #define VLSI_CLOCKF 0x03
clemente 0:e97876f96d4b 48 #define VLSI_DECODE_TIME 0x04
clemente 0:e97876f96d4b 49 #define VLSI_AUDATA 0x05
clemente 0:e97876f96d4b 50 #define VLSI_WRAM 0x06
clemente 0:e97876f96d4b 51 #define VLSI_WRAMADDR 0x07
clemente 0:e97876f96d4b 52 #define VLSI_HDAT0 0x08
clemente 0:e97876f96d4b 53 #define VLSI_HDAT1 0x09
clemente 0:e97876f96d4b 54 #define VLSI_AIADDR 0x0A
clemente 0:e97876f96d4b 55 #define VLSI_VOL 0x0B
clemente 0:e97876f96d4b 56 #define VLSI_AICTRL0 0x0C
clemente 0:e97876f96d4b 57 #define VLSI_AICTRL1 0x0D
clemente 0:e97876f96d4b 58 #define VLSI_AICTRL2 0x0E
clemente 0:e97876f96d4b 59 #define VLSI_AICTRL3 0x0F
clemente 0:e97876f96d4b 60
clemente 0:e97876f96d4b 61 #define VLSI_STATUS_VER 0x00F0u
clemente 0:e97876f96d4b 62 #define VER_VS1001 (0u<<4)
clemente 0:e97876f96d4b 63 #define VER_VS1011 (1u<<4)
clemente 0:e97876f96d4b 64 #define VER_VS1002 (2u<<4)
clemente 0:e97876f96d4b 65 #define VER_VS1011E (2u<<4)
clemente 0:e97876f96d4b 66 #define VER_VS1003 (3u<<4)
clemente 0:e97876f96d4b 67 #define VER_VS1053 (4u<<4)
clemente 0:e97876f96d4b 68 #define VER_VS1033 (5u<<4)
clemente 0:e97876f96d4b 69 #define VER_VS1103 (7u<<4)
clemente 0:e97876f96d4b 70
clemente 0:e97876f96d4b 71 #define cWAIT_DREQ_1MS wait_ms( 1); while (!_dreq);
clemente 0:e97876f96d4b 72 #define cWAIT_DREQ while (!_dreq);
clemente 0:e97876f96d4b 73
clemente 0:e97876f96d4b 74 /* VLSI 1053, MODE Register bit configuration. */
clemente 0:e97876f96d4b 75 #define SM_DIFF 0x01
clemente 0:e97876f96d4b 76 #define SM_LAYER12 0x02
clemente 0:e97876f96d4b 77 #define SM_RESET 0x04
clemente 0:e97876f96d4b 78 #define SM_CANCEL 0x08
clemente 0:e97876f96d4b 79 #define SM_EARSPEAKER_LO 0x10
clemente 0:e97876f96d4b 80 #define SM_TESTS 0x20
clemente 0:e97876f96d4b 81 #define SM_STREAM 0x40
clemente 0:e97876f96d4b 82 #define SM_EARSPEAKER_HI 0x80
clemente 0:e97876f96d4b 83 #define SM_DACT 0x100
clemente 0:e97876f96d4b 84 #define SM_SDIORD 0x200
clemente 0:e97876f96d4b 85 #define SM_SDISHARE 0x400
clemente 0:e97876f96d4b 86 #define SM_SDINEW 0x800
clemente 0:e97876f96d4b 87 #define SM_ADPCM 0x1000
clemente 0:e97876f96d4b 88 #define SM_NOTUSE 0x2000
clemente 0:e97876f96d4b 89 #define SM_LINE1 0x4000
clemente 0:e97876f96d4b 90 #define SM_CLK_RANGE 0x8000
clemente 0:e97876f96d4b 91
clemente 0:e97876f96d4b 92 /* SC MULT MASK CLKI */
clemente 0:e97876f96d4b 93 #define SC_MULT_0 0x0000 /* XTALI */
clemente 0:e97876f96d4b 94 #define SC_MULT_2 0x2000 /* XTALI×2.0 */
clemente 0:e97876f96d4b 95 #define SC_MULT_2_5 0x4000 /* XTALI×2.5 */
clemente 0:e97876f96d4b 96 #define SC_MULT_3 0x6000 /* XTALI×3.0 */
clemente 0:e97876f96d4b 97 #define SC_MULT_3_5 0x8000 /* XTALI×3.5 */
clemente 0:e97876f96d4b 98 #define SC_MULT_4 0xA000 /* XTALI×4.0 */
clemente 0:e97876f96d4b 99 #define SC_MULT_4_5 0xC000 /* XTALI×4.5 */
clemente 0:e97876f96d4b 100 #define SC_MULT_5 0xE000 /* XTALI×5.0 */
clemente 0:e97876f96d4b 101
clemente 0:e97876f96d4b 102 /*
clemente 0:e97876f96d4b 103 SC ADD tells how much the decoder firmware is allowed to add to the multiplier specified by SC MULT
clemente 0:e97876f96d4b 104 if more cycles are temporarily needed to decode a WMA or AAC stream. The values are:
clemente 0:e97876f96d4b 105 SC ADD MASK Multiplier addition
clemente 0:e97876f96d4b 106 */
clemente 0:e97876f96d4b 107 #define SC_ADD_NOMOD 0x0000 /* No modification is allowed */
clemente 0:e97876f96d4b 108 #define SC_ADD_X1 0x0800 /* 1.0× */
clemente 0:e97876f96d4b 109 #define SC_ADD_X1_5 0x1000 /* 1.5× */
clemente 0:e97876f96d4b 110 #define SC_ADD_X2 0x1800 /* 2.0× */
clemente 0:e97876f96d4b 111
clemente 0:e97876f96d4b 112 #define SC_FREQ 0x0000 /* 12.288 MHz clock. */
clemente 0:e97876f96d4b 113
clemente 0:e97876f96d4b 114 /*
clemente 0:e97876f96d4b 115 */
clemente 0:e97876f96d4b 116 #define cMODEREG_SET ( SM_SDINEW )
clemente 0:e97876f96d4b 117 #define cCLOCK_SET ( SC_MULT_5 | SC_ADD_X1 | SC_FREQ)
clemente 0:e97876f96d4b 118
clemente 0:e97876f96d4b 119 #define VS1053_CS_ENABLE _cs=0;
clemente 0:e97876f96d4b 120 #define VS1053_CS_DISABLE _cs=1;
clemente 0:e97876f96d4b 121 #define VS1053_XDCS_ENABLE _xdcs=0;
clemente 0:e97876f96d4b 122 #define VS1053_XDCS_DISABLE _xdcs=1;
clemente 0:e97876f96d4b 123 #define VS1053_RST_ENABLE _rst=0;
clemente 0:e97876f96d4b 124 #define VS1053_RST_DISABLE _rst=1;
clemente 0:e97876f96d4b 125
clemente 0:e97876f96d4b 126 /*
clemente 0:e97876f96d4b 127 */
clemente 0:e97876f96d4b 128 #define cVS1053_CS_DELAY 50
clemente 0:e97876f96d4b 129
clemente 0:e97876f96d4b 130 VS1053Codec::VS1053Codec( PinName mosi, PinName miso, PinName sclk, PinName cs, PinName dreq, PinName rst, PinName xdcs) : _spi( mosi, miso, sclk), _cs( cs), _dreq( dreq), _rst( rst), _xdcs( xdcs) {
clemente 0:e97876f96d4b 131 // defaults params
clemente 0:e97876f96d4b 132 VS1053_CS_DISABLE;
clemente 0:e97876f96d4b 133 VS1053_XDCS_DISABLE;
clemente 0:e97876f96d4b 134 }
clemente 0:e97876f96d4b 135
clemente 0:e97876f96d4b 136 void VS1053Codec::testdreq( void){
clemente 0:e97876f96d4b 137 while( !_dreq);
clemente 0:e97876f96d4b 138 }
clemente 0:e97876f96d4b 139
clemente 0:e97876f96d4b 140 void VS1053Codec::lowpower( void)
clemente 0:e97876f96d4b 141 {
clemente 0:e97876f96d4b 142 VS1053_RST_ENABLE;
clemente 0:e97876f96d4b 143 wait_ms( 10);
clemente 0:e97876f96d4b 144 }
clemente 0:e97876f96d4b 145
clemente 0:e97876f96d4b 146 void VS1053Codec::init(void)
clemente 0:e97876f96d4b 147 {
clemente 0:e97876f96d4b 148 //
clemente 0:e97876f96d4b 149 VS1053_RST_DISABLE;
clemente 0:e97876f96d4b 150 VS1053_CS_DISABLE;
clemente 0:e97876f96d4b 151 VS1053_XDCS_DISABLE;
clemente 0:e97876f96d4b 152 //
clemente 0:e97876f96d4b 153 _spi.format( 8, 0);
clemente 0:e97876f96d4b 154 _spi.frequency( MP3_INIT_SPEED);
clemente 0:e97876f96d4b 155
clemente 0:e97876f96d4b 156 // Assert RESET
clemente 0:e97876f96d4b 157 VS1053_RST_ENABLE;
clemente 0:e97876f96d4b 158 wait_ms( 100);
clemente 0:e97876f96d4b 159
clemente 0:e97876f96d4b 160 // Deassert RESET (active low)
clemente 0:e97876f96d4b 161 VS1053_RST_DISABLE;
clemente 0:e97876f96d4b 162 VS1053_CS_DISABLE;
clemente 0:e97876f96d4b 163 VS1053_XDCS_DISABLE;
clemente 0:e97876f96d4b 164 wait_ms( 100);
clemente 0:e97876f96d4b 165
clemente 0:e97876f96d4b 166 // Wait
clemente 0:e97876f96d4b 167 while(!_dreq);
clemente 0:e97876f96d4b 168
clemente 0:e97876f96d4b 169 // Reset the vs1053
clemente 0:e97876f96d4b 170 writereg( VLSI_MODE, ( cMODEREG_SET | SM_RESET) );
clemente 0:e97876f96d4b 171 wait_ms( 10);
clemente 0:e97876f96d4b 172
clemente 0:e97876f96d4b 173 // Wait...
clemente 0:e97876f96d4b 174 while(!_dreq);
clemente 0:e97876f96d4b 175
clemente 0:e97876f96d4b 176 /*
clemente 0:e97876f96d4b 177 * Write configuration MODE register in a loop to verify that the chip is
clemente 0:e97876f96d4b 178 * connected and running correctly
clemente 0:e97876f96d4b 179 */
clemente 0:e97876f96d4b 180 do
clemente 0:e97876f96d4b 181 {
clemente 0:e97876f96d4b 182 writereg( VLSI_MODE, ( cMODEREG_SET ));
clemente 0:e97876f96d4b 183 wait_ms( 1);
clemente 0:e97876f96d4b 184 }while( readreg( VLSI_MODE) != ( cMODEREG_SET ));
clemente 0:e97876f96d4b 185
clemente 0:e97876f96d4b 186 //
clemente 0:e97876f96d4b 187 if((readreg( VLSI_STATUS) & VLSI_STATUS_VER) == VER_VS1053)
clemente 0:e97876f96d4b 188 {
clemente 0:e97876f96d4b 189 // Set the clock to maximum speed (VS1053 only) to allow all audio formats
clemente 0:e97876f96d4b 190 // to be decoded without glitching. Note that this increases power
clemente 0:e97876f96d4b 191 // consumption.
clemente 0:e97876f96d4b 192 // SC_MULT = XTALI*4.5, SC_ADD = noMod, SC_FREQ = 0 (12.288MHz)
clemente 0:e97876f96d4b 193 // VLSIWriteReg(VLSI_CLOCKF, SC_MULT_4_5 | SC_ADD_X1 | SC_FREQ);
clemente 0:e97876f96d4b 194
clemente 0:e97876f96d4b 195 writereg(VLSI_CLOCKF, cCLOCK_SET);
clemente 0:e97876f96d4b 196
clemente 0:e97876f96d4b 197 /* */
clemente 0:e97876f96d4b 198 wait_ms( 2);
clemente 0:e97876f96d4b 199 while(!_dreq);
clemente 0:e97876f96d4b 200 }
clemente 0:e97876f96d4b 201 else if ((readreg( VLSI_STATUS) & VLSI_STATUS_VER) == VER_VS1011E)
clemente 0:e97876f96d4b 202 {
clemente 0:e97876f96d4b 203 // Nothing special to do
clemente 0:e97876f96d4b 204 ;
clemente 0:e97876f96d4b 205 }
clemente 0:e97876f96d4b 206 else
clemente 0:e97876f96d4b 207 {
clemente 0:e97876f96d4b 208 // VLSI Chip version not tested, not supported, halt program execution.
clemente 0:e97876f96d4b 209 // This trap should be caught during the design phase.
clemente 0:e97876f96d4b 210 while(1);
clemente 0:e97876f96d4b 211 }
clemente 0:e97876f96d4b 212
clemente 0:e97876f96d4b 213 _spi.frequency( MP3_RUN_SPEED);
clemente 0:e97876f96d4b 214 }
clemente 0:e97876f96d4b 215
clemente 0:e97876f96d4b 216 void VS1053Codec::loadpatch(void)
clemente 0:e97876f96d4b 217 /* Questa funzione carica una patch al firmware del codec */
clemente 0:e97876f96d4b 218 {
clemente 0:e97876f96d4b 219 int i = 0, plgin_len;
clemente 0:e97876f96d4b 220 unsigned int addr, n, val;
clemente 0:e97876f96d4b 221
clemente 0:e97876f96d4b 222 plgin_len=sizeof( plugin)/sizeof(plugin[0]);
clemente 0:e97876f96d4b 223 while (i<plgin_len) {
clemente 0:e97876f96d4b 224
clemente 0:e97876f96d4b 225 addr = plugin[i++];
clemente 0:e97876f96d4b 226 n = plugin[i++];
clemente 0:e97876f96d4b 227 if (n & 0x8000U) { /* RLE run, replicate n samples */
clemente 0:e97876f96d4b 228 n &= 0x7FFF;
clemente 0:e97876f96d4b 229 val = plugin[i++];
clemente 0:e97876f96d4b 230 while (n--) {
clemente 0:e97876f96d4b 231 writeregnowait(addr, val);
clemente 0:e97876f96d4b 232 while(!_dreq);
clemente 0:e97876f96d4b 233 }
clemente 0:e97876f96d4b 234 } else { /* Copy run, copy n samples */
clemente 0:e97876f96d4b 235 while (n--) {
clemente 0:e97876f96d4b 236 val = plugin[i++];
clemente 0:e97876f96d4b 237 writeregnowait(addr, val);
clemente 0:e97876f96d4b 238 while(!_dreq);
clemente 0:e97876f96d4b 239 }
clemente 0:e97876f96d4b 240 }
clemente 0:e97876f96d4b 241 }
clemente 0:e97876f96d4b 242 //
clemente 0:e97876f96d4b 243 wait_ms( 1);
clemente 0:e97876f96d4b 244 while(!_dreq);
clemente 0:e97876f96d4b 245 }
clemente 0:e97876f96d4b 246
clemente 0:e97876f96d4b 247 #ifdef __PLUGINGA
clemente 0:e97876f96d4b 248 void VS1053Codec::loadgapatch(void)
clemente 0:e97876f96d4b 249 /* Questa funzione carica un plugin nel codec */
clemente 0:e97876f96d4b 250 {
clemente 0:e97876f96d4b 251 int i = 0, plgin_len;
clemente 0:e97876f96d4b 252 unsigned int addr, n, val;
clemente 0:e97876f96d4b 253
clemente 0:e97876f96d4b 254 plgin_len=sizeof( gaplugin)/sizeof(gaplugin[0]);
clemente 0:e97876f96d4b 255 while (i<plgin_len) {
clemente 0:e97876f96d4b 256
clemente 0:e97876f96d4b 257 addr = gaplugin[i++];
clemente 0:e97876f96d4b 258 n = gaplugin[i++];
clemente 0:e97876f96d4b 259 if (n & 0x8000U) { /* RLE run, replicate n samples */
clemente 0:e97876f96d4b 260 n &= 0x7FFF;
clemente 0:e97876f96d4b 261 val = gaplugin[i++];
clemente 0:e97876f96d4b 262 while (n--) {
clemente 0:e97876f96d4b 263 writeregnowait(addr, val);
clemente 0:e97876f96d4b 264 while(!_dreq);
clemente 0:e97876f96d4b 265 }
clemente 0:e97876f96d4b 266 } else { /* Copy run, copy n samples */
clemente 0:e97876f96d4b 267 while (n--) {
clemente 0:e97876f96d4b 268 val = gaplugin[i++];
clemente 0:e97876f96d4b 269 writeregnowait(addr, val);
clemente 0:e97876f96d4b 270 while(!_dreq);
clemente 0:e97876f96d4b 271 }
clemente 0:e97876f96d4b 272 }
clemente 0:e97876f96d4b 273 }
clemente 0:e97876f96d4b 274 //
clemente 0:e97876f96d4b 275 wait_ms( 1);
clemente 0:e97876f96d4b 276 while(!_dreq);
clemente 0:e97876f96d4b 277 }
clemente 0:e97876f96d4b 278 #endif
clemente 0:e97876f96d4b 279
clemente 0:e97876f96d4b 280 #ifdef __ENCODE_OGG
clemente 0:e97876f96d4b 281 void VS1053Codec::loadoggpatch(void)
clemente 0:e97876f96d4b 282 /* Questa funzione carica una patch per gestire l'encoder OGG */
clemente 0:e97876f96d4b 283 {
clemente 0:e97876f96d4b 284 int i = 0, plgin_len;
clemente 0:e97876f96d4b 285 unsigned int addr, n, val;
clemente 0:e97876f96d4b 286
clemente 0:e97876f96d4b 287 plgin_len=sizeof( ogg_enc)/sizeof(ogg_enc[0]);
clemente 0:e97876f96d4b 288 while (i<plgin_len) {
clemente 0:e97876f96d4b 289
clemente 0:e97876f96d4b 290 addr = ogg_enc[i++];
clemente 0:e97876f96d4b 291 n = ogg_enc[i++];
clemente 0:e97876f96d4b 292 if (n & 0x8000U) { /* RLE run, replicate n samples */
clemente 0:e97876f96d4b 293 n &= 0x7FFF;
clemente 0:e97876f96d4b 294 val = ogg_enc[i++];
clemente 0:e97876f96d4b 295 while (n--) {
clemente 0:e97876f96d4b 296 writeregnowait(addr, val);
clemente 0:e97876f96d4b 297 while(!_dreq);
clemente 0:e97876f96d4b 298 }
clemente 0:e97876f96d4b 299 } else { /* Copy run, copy n samples */
clemente 0:e97876f96d4b 300 while (n--) {
clemente 0:e97876f96d4b 301 val = ogg_enc[i++];
clemente 0:e97876f96d4b 302 writeregnowait(addr, val);
clemente 0:e97876f96d4b 303 while(!_dreq);
clemente 0:e97876f96d4b 304 }
clemente 0:e97876f96d4b 305 }
clemente 0:e97876f96d4b 306 }
clemente 0:e97876f96d4b 307 //
clemente 0:e97876f96d4b 308 wait_ms( 1);
clemente 0:e97876f96d4b 309 while(!_dreq);
clemente 0:e97876f96d4b 310 }
clemente 0:e97876f96d4b 311 #endif
clemente 0:e97876f96d4b 312
clemente 0:e97876f96d4b 313 #ifdef __PLUGINGA
clemente 0:e97876f96d4b 314 void VS1053Codec::readgavalue( unsigned char *currval, unsigned char *peak)
clemente 0:e97876f96d4b 315 {
clemente 0:e97876f96d4b 316 writereg( VLSI_WRAMADDR, cBASE+2);
clemente 0:e97876f96d4b 317 unsigned short bands = (unsigned short)readreg( VLSI_WRAM);
clemente 0:e97876f96d4b 318 //
clemente 0:e97876f96d4b 319 writereg( VLSI_WRAMADDR, cBASE+4);
clemente 0:e97876f96d4b 320 //
clemente 0:e97876f96d4b 321 for (int i=0;i<bands;i++) {
clemente 0:e97876f96d4b 322 short pv = readreg( VLSI_WRAM);
clemente 0:e97876f96d4b 323 /* current value in bits 5..0, normally 0..31
clemente 0:e97876f96d4b 324 peak value in bits 11..6, normally 0..31 */
clemente 0:e97876f96d4b 325 currval[i]=(unsigned char)(pv&0x003F);
clemente 0:e97876f96d4b 326 peak[i]=(unsigned char)( (pv>>6)&0x003F);
clemente 0:e97876f96d4b 327 }
clemente 0:e97876f96d4b 328 }
clemente 0:e97876f96d4b 329
clemente 0:e97876f96d4b 330 unsigned short VS1053Codec::readgabands( void)
clemente 0:e97876f96d4b 331 {
clemente 0:e97876f96d4b 332 writereg( VLSI_WRAMADDR, cBASE+2);
clemente 0:e97876f96d4b 333 unsigned short bands = (unsigned short)readreg( VLSI_WRAM);
clemente 0:e97876f96d4b 334 /* */
clemente 0:e97876f96d4b 335 return bands;
clemente 0:e97876f96d4b 336 }
clemente 0:e97876f96d4b 337
clemente 0:e97876f96d4b 338 #endif
clemente 0:e97876f96d4b 339
clemente 0:e97876f96d4b 340 void VS1053Codec::setvmeter( void)
clemente 0:e97876f96d4b 341 {
clemente 0:e97876f96d4b 342 unsigned short tmp;
clemente 0:e97876f96d4b 343
clemente 0:e97876f96d4b 344 tmp=(unsigned short)readreg( VLSI_STATUS);
clemente 0:e97876f96d4b 345 tmp|=(1<<9);
clemente 0:e97876f96d4b 346 writereg( VLSI_STATUS, tmp);
clemente 0:e97876f96d4b 347 }
clemente 0:e97876f96d4b 348
clemente 0:e97876f96d4b 349 void VS1053Codec::getvmeterval( unsigned char* left, unsigned char* right)
clemente 0:e97876f96d4b 350 {
clemente 0:e97876f96d4b 351 unsigned short tmp;
clemente 0:e97876f96d4b 352
clemente 0:e97876f96d4b 353 tmp=(unsigned short)readreg( VLSI_AICTRL3);
clemente 0:e97876f96d4b 354
clemente 0:e97876f96d4b 355 *right=(unsigned char)tmp&0x00FF;
clemente 0:e97876f96d4b 356 *left=(unsigned char)(tmp>>8);
clemente 0:e97876f96d4b 357 }
clemente 0:e97876f96d4b 358
clemente 0:e97876f96d4b 359 /****************************************************************************
clemente 0:e97876f96d4b 360 Function:
clemente 0:e97876f96d4b 361 void VS1053Codec::setbassboost(BYTE bass, BYTE gfreq)
clemente 0:e97876f96d4b 362
clemente 0:e97876f96d4b 363 Description:
clemente 0:e97876f96d4b 364 This function sets the bass boost.
clemente 0:e97876f96d4b 365
clemente 0:e97876f96d4b 366 Precondition:
clemente 0:e97876f96d4b 367 None
clemente 0:e97876f96d4b 368
clemente 0:e97876f96d4b 369 Parameters:
clemente 0:e97876f96d4b 370 BYTE bass - Bass gain in dB, range from 0 to 15 (MSB nibble)
clemente 0:e97876f96d4b 371 BYTE gfreq - Limit frequency for bass boost, 10 Hz steps (range from
clemente 0:e97876f96d4b 372 20 to 150) (LSB nibble)
clemente 0:e97876f96d4b 373
clemente 0:e97876f96d4b 374 Returns:
clemente 0:e97876f96d4b 375 None
clemente 0:e97876f96d4b 376
clemente 0:e97876f96d4b 377 Remarks:
clemente 0:e97876f96d4b 378 None
clemente 0:e97876f96d4b 379 ***************************************************************************/
clemente 0:e97876f96d4b 380 void VS1053Codec::setbassboost( unsigned char bass, unsigned char gfreq)
clemente 0:e97876f96d4b 381 {
clemente 0:e97876f96d4b 382 unsigned char templ;
clemente 0:e97876f96d4b 383 unsigned short tmp;
clemente 0:e97876f96d4b 384
clemente 0:e97876f96d4b 385 //
clemente 0:e97876f96d4b 386 if(bass > 15u)
clemente 0:e97876f96d4b 387 bass = 15;
clemente 0:e97876f96d4b 388 if(gfreq > 150u)
clemente 0:e97876f96d4b 389 gfreq = 150;
clemente 0:e97876f96d4b 390 if ( gfreq < 20)
clemente 0:e97876f96d4b 391 gfreq = 20;
clemente 0:e97876f96d4b 392
clemente 0:e97876f96d4b 393
clemente 0:e97876f96d4b 394 //
clemente 0:e97876f96d4b 395 templ = (unsigned char)gfreq/10;
clemente 0:e97876f96d4b 396
clemente 0:e97876f96d4b 397 // put bass boost value into the upper 4 bit
clemente 0:e97876f96d4b 398 templ |= (bass << 4);
clemente 0:e97876f96d4b 399 //
clemente 0:e97876f96d4b 400 tmp=(unsigned short)readreg( VLSI_BASS);
clemente 0:e97876f96d4b 401 tmp &= 0xFF00;
clemente 0:e97876f96d4b 402 tmp |= templ;
clemente 0:e97876f96d4b 403 //
clemente 0:e97876f96d4b 404 writereg( VLSI_BASS, tmp);
clemente 0:e97876f96d4b 405 }
clemente 0:e97876f96d4b 406
clemente 0:e97876f96d4b 407 /****************************************************************************
clemente 0:e97876f96d4b 408 Function:
clemente 0:e97876f96d4b 409 void VS1053Codec::settrebleboost(BYTE bass, WORD gfreq)
clemente 0:e97876f96d4b 410
clemente 0:e97876f96d4b 411 Description:
clemente 0:e97876f96d4b 412 This function sets the bass boost.
clemente 0:e97876f96d4b 413
clemente 0:e97876f96d4b 414 Precondition:
clemente 0:e97876f96d4b 415 None
clemente 0:e97876f96d4b 416
clemente 0:e97876f96d4b 417 Parameters:
clemente 0:e97876f96d4b 418 BYTE treble - Bass gain in dB, range from -8 to 7 (MSB nibble)
clemente 0:e97876f96d4b 419 WORD gfreq - Limit frequency for bass boost, 1000 Hz steps (range from
clemente 0:e97876f96d4b 420 1000 to 15000) (LSB nibble)
clemente 0:e97876f96d4b 421
clemente 0:e97876f96d4b 422 Returns:
clemente 0:e97876f96d4b 423 None
clemente 0:e97876f96d4b 424
clemente 0:e97876f96d4b 425 Remarks:
clemente 0:e97876f96d4b 426 None
clemente 0:e97876f96d4b 427 ***************************************************************************/
clemente 0:e97876f96d4b 428 void VS1053Codec::settrebleboost( char treble, unsigned int gfreq)
clemente 0:e97876f96d4b 429 {
clemente 0:e97876f96d4b 430 unsigned char templ;
clemente 0:e97876f96d4b 431 unsigned short tmp;
clemente 0:e97876f96d4b 432
clemente 0:e97876f96d4b 433 //
clemente 0:e97876f96d4b 434 if(treble > 7)
clemente 0:e97876f96d4b 435 treble = 7;
clemente 0:e97876f96d4b 436 if ( treble < (char)-8)
clemente 0:e97876f96d4b 437 treble = (char)-8;
clemente 0:e97876f96d4b 438
clemente 0:e97876f96d4b 439 if(gfreq > 15000u)
clemente 0:e97876f96d4b 440 gfreq = 15000;
clemente 0:e97876f96d4b 441 if(gfreq < 1000)
clemente 0:e97876f96d4b 442 gfreq = 1000;
clemente 0:e97876f96d4b 443
clemente 0:e97876f96d4b 444 //
clemente 0:e97876f96d4b 445 templ = (unsigned char)gfreq/1000;
clemente 0:e97876f96d4b 446
clemente 0:e97876f96d4b 447 // put treble boost value into the upper 4 bit
clemente 0:e97876f96d4b 448 templ |= (treble << 4);
clemente 0:e97876f96d4b 449 //
clemente 0:e97876f96d4b 450 tmp=(unsigned short)readreg( VLSI_BASS);
clemente 0:e97876f96d4b 451 tmp &= 0x00FF;
clemente 0:e97876f96d4b 452 tmp |= (templ << 8);
clemente 0:e97876f96d4b 453 //
clemente 0:e97876f96d4b 454 writereg( VLSI_BASS, tmp);
clemente 0:e97876f96d4b 455 }
clemente 0:e97876f96d4b 456
clemente 0:e97876f96d4b 457 void VS1053Codec::getplaytime(char *playtime)
clemente 0:e97876f96d4b 458 {
clemente 0:e97876f96d4b 459 unsigned short playTime;
clemente 0:e97876f96d4b 460 unsigned char minutes, seconds;
clemente 0:e97876f96d4b 461
clemente 0:e97876f96d4b 462 playTime = (unsigned short)readreg(VLSI_DECODE_TIME);
clemente 0:e97876f96d4b 463 minutes = playTime/60;
clemente 0:e97876f96d4b 464 seconds = playTime%60;
clemente 0:e97876f96d4b 465 *playtime++=('0'+minutes/10);
clemente 0:e97876f96d4b 466 *playtime++=('0'+minutes%10);
clemente 0:e97876f96d4b 467 *playtime++=(':');
clemente 0:e97876f96d4b 468 *playtime++=('0'+seconds/10);
clemente 0:e97876f96d4b 469 *playtime++=('0'+seconds%10);
clemente 0:e97876f96d4b 470 }
clemente 0:e97876f96d4b 471
clemente 0:e97876f96d4b 472
clemente 0:e97876f96d4b 473 /****************************************************************************
clemente 0:e97876f96d4b 474 Function:
clemente 0:e97876f96d4b 475 void setvolume(unsigned char vRight, unsigned char vLeft)
clemente 0:e97876f96d4b 476
clemente 0:e97876f96d4b 477 Description:
clemente 0:e97876f96d4b 478 This function set volume for analog outputs on the VLSI codec.
clemente 0:e97876f96d4b 479
clemente 0:e97876f96d4b 480 Precondition:
clemente 0:e97876f96d4b 481 None
clemente 0:e97876f96d4b 482
clemente 0:e97876f96d4b 483 Parameters:
clemente 0:e97876f96d4b 484 unsigned char vRight - right channel attenuation from maximum volume, 0.5dB steps
clemente 0:e97876f96d4b 485 (0x00 = full volume, 0xFF = muted)
clemente 0:e97876f96d4b 486 unsigned char vLeft - left channel attenuation from maximum volume, 0.5dB steps
clemente 0:e97876f96d4b 487 (0x00 = full volume, 0xFF = muted)
clemente 0:e97876f96d4b 488
clemente 0:e97876f96d4b 489 Returns:
clemente 0:e97876f96d4b 490 None
clemente 0:e97876f96d4b 491
clemente 0:e97876f96d4b 492 Remarks:
clemente 0:e97876f96d4b 493 None
clemente 0:e97876f96d4b 494 ***************************************************************************/
clemente 0:e97876f96d4b 495 void VS1053Codec::setvolume(unsigned char vRight, unsigned char vLeft)
clemente 0:e97876f96d4b 496 {
clemente 0:e97876f96d4b 497 writereg(VLSI_VOL, ((unsigned int)vLeft)<<8 | vRight);
clemente 0:e97876f96d4b 498 }
clemente 0:e97876f96d4b 499
clemente 0:e97876f96d4b 500
clemente 0:e97876f96d4b 501 void VS1053Codec::sinetest( unsigned char pitch)
clemente 0:e97876f96d4b 502 {
clemente 0:e97876f96d4b 503 unsigned int i;
clemente 0:e97876f96d4b 504
clemente 0:e97876f96d4b 505 while(!_dreq);
clemente 0:e97876f96d4b 506
clemente 0:e97876f96d4b 507 i=(unsigned short)readreg( VLSI_MODE);
clemente 0:e97876f96d4b 508 writereg( VLSI_MODE, ( i | SM_TESTS ));
clemente 0:e97876f96d4b 509
clemente 0:e97876f96d4b 510 VS1053_XDCS_ENABLE;
clemente 0:e97876f96d4b 511
clemente 0:e97876f96d4b 512 if ( pitch) {
clemente 0:e97876f96d4b 513 // START Sine Test
clemente 0:e97876f96d4b 514 _spi.write(0x53);
clemente 0:e97876f96d4b 515 _spi.write(0xEF);
clemente 0:e97876f96d4b 516 _spi.write(0x6E);
clemente 0:e97876f96d4b 517 _spi.write( pitch);
clemente 0:e97876f96d4b 518 _spi.write(0x00);
clemente 0:e97876f96d4b 519 _spi.write(0x00);
clemente 0:e97876f96d4b 520 _spi.write(0x00);
clemente 0:e97876f96d4b 521 _spi.write(0x00);
clemente 0:e97876f96d4b 522 } else {
clemente 0:e97876f96d4b 523 // STOP Sine Test
clemente 0:e97876f96d4b 524 _spi.write(0x45);
clemente 0:e97876f96d4b 525 _spi.write(0x78);
clemente 0:e97876f96d4b 526 _spi.write(0x69);
clemente 0:e97876f96d4b 527 _spi.write(0x74);
clemente 0:e97876f96d4b 528 _spi.write(0x00);
clemente 0:e97876f96d4b 529 _spi.write(0x00);
clemente 0:e97876f96d4b 530 _spi.write(0x00);
clemente 0:e97876f96d4b 531 _spi.write(0x00);
clemente 0:e97876f96d4b 532 }
clemente 0:e97876f96d4b 533
clemente 0:e97876f96d4b 534 VS1053_XDCS_DISABLE;
clemente 0:e97876f96d4b 535
clemente 0:e97876f96d4b 536 }
clemente 0:e97876f96d4b 537
clemente 0:e97876f96d4b 538 void VS1053Codec::writedata( unsigned char data)
clemente 0:e97876f96d4b 539 /*
clemente 0:e97876f96d4b 540 * Write data to SDI.
clemente 0:e97876f96d4b 541 */
clemente 0:e97876f96d4b 542 {
clemente 0:e97876f96d4b 543 int i=0;
clemente 0:e97876f96d4b 544
clemente 0:e97876f96d4b 545 VS1053_XDCS_ENABLE;
clemente 0:e97876f96d4b 546 for( i=0; i<cVS1053_CS_DELAY; i++);
clemente 0:e97876f96d4b 547
clemente 0:e97876f96d4b 548 _spi.write( data);
clemente 0:e97876f96d4b 549
clemente 0:e97876f96d4b 550 for( i=0; i<cVS1053_CS_DELAY; i++);
clemente 0:e97876f96d4b 551 VS1053_XDCS_DISABLE;
clemente 0:e97876f96d4b 552
clemente 0:e97876f96d4b 553 }
clemente 0:e97876f96d4b 554
clemente 0:e97876f96d4b 555 //******************************************************************************
clemente 0:e97876f96d4b 556 //******************************************************************************
clemente 0:e97876f96d4b 557 //******************************************************************************
clemente 0:e97876f96d4b 558 // Section: Internal Functions
clemente 0:e97876f96d4b 559 //******************************************************************************
clemente 0:e97876f96d4b 560 //******************************************************************************
clemente 0:e97876f96d4b 561 //******************************************************************************
clemente 0:e97876f96d4b 562
clemente 0:e97876f96d4b 563
clemente 0:e97876f96d4b 564 unsigned short VS1053Codec::readreg(unsigned char vAddress)
clemente 0:e97876f96d4b 565 {
clemente 0:e97876f96d4b 566 unsigned short wValue;
clemente 0:e97876f96d4b 567 unsigned int i;
clemente 0:e97876f96d4b 568
clemente 0:e97876f96d4b 569 VS1053_CS_ENABLE;
clemente 0:e97876f96d4b 570 for ( i=0; i<cVS1053_CS_DELAY;i++);
clemente 0:e97876f96d4b 571
clemente 0:e97876f96d4b 572 _spi.write(0x03); // Read
clemente 0:e97876f96d4b 573 _spi.write(vAddress); // Register address
clemente 0:e97876f96d4b 574 ((unsigned char*)&wValue)[1] = _spi.write(0xFF); // 8 bit value high byte
clemente 0:e97876f96d4b 575 ((unsigned char*)&wValue)[0] = _spi.write(0xFF); // 8 bit value low byte
clemente 0:e97876f96d4b 576
clemente 0:e97876f96d4b 577 for ( i=0; i<cVS1053_CS_DELAY;i++);
clemente 0:e97876f96d4b 578 VS1053_CS_DISABLE;
clemente 0:e97876f96d4b 579
clemente 0:e97876f96d4b 580 return wValue;
clemente 0:e97876f96d4b 581 }
clemente 0:e97876f96d4b 582
clemente 0:e97876f96d4b 583 void VS1053Codec::writereg(unsigned char vAddress, unsigned int wValue)
clemente 0:e97876f96d4b 584 {
clemente 0:e97876f96d4b 585 int i;
clemente 0:e97876f96d4b 586
clemente 0:e97876f96d4b 587 while(!_dreq);
clemente 0:e97876f96d4b 588
clemente 0:e97876f96d4b 589 VS1053_CS_ENABLE;
clemente 0:e97876f96d4b 590 for ( i=0; i<cVS1053_CS_DELAY;i++);
clemente 0:e97876f96d4b 591
clemente 0:e97876f96d4b 592 _spi.write(0x02); // Write
clemente 0:e97876f96d4b 593 _spi.write(vAddress); // Register address
clemente 0:e97876f96d4b 594 _spi.write(((unsigned char*)&wValue)[1]); // 8 bit value to write high byte
clemente 0:e97876f96d4b 595 _spi.write(((unsigned char*)&wValue)[0]); // 8 bit value to write low byte
clemente 0:e97876f96d4b 596
clemente 0:e97876f96d4b 597 for ( i=0; i<cVS1053_CS_DELAY;i++);
clemente 0:e97876f96d4b 598 VS1053_CS_DISABLE;
clemente 0:e97876f96d4b 599
clemente 0:e97876f96d4b 600 }
clemente 0:e97876f96d4b 601
clemente 0:e97876f96d4b 602
clemente 0:e97876f96d4b 603 /* */
clemente 0:e97876f96d4b 604 void VS1053Codec::reset( void)
clemente 0:e97876f96d4b 605 {
clemente 0:e97876f96d4b 606 // Reset the vs1053
clemente 0:e97876f96d4b 607 writereg(VLSI_MODE, ( cMODEREG_SET | SM_RESET) );
clemente 0:e97876f96d4b 608 wait_ms( 5);
clemente 0:e97876f96d4b 609 // Wait...
clemente 0:e97876f96d4b 610 while(!_dreq);
clemente 0:e97876f96d4b 611
clemente 0:e97876f96d4b 612 // Configure CLOCK register.
clemente 0:e97876f96d4b 613 writereg(VLSI_CLOCKF, cCLOCK_SET);
clemente 0:e97876f96d4b 614 wait_ms( 5);
clemente 0:e97876f96d4b 615 // Wait...
clemente 0:e97876f96d4b 616 while(!_dreq);
clemente 0:e97876f96d4b 617 }
clemente 0:e97876f96d4b 618
clemente 0:e97876f96d4b 619
clemente 0:e97876f96d4b 620 void VS1053Codec::writeregnowait(unsigned char vAddress, unsigned int wValue)
clemente 0:e97876f96d4b 621 /*
clemente 0:e97876f96d4b 622 Write to SCI interface without waiting for the DREQ pin
clemente 0:e97876f96d4b 623 */
clemente 0:e97876f96d4b 624 {
clemente 0:e97876f96d4b 625 int i;
clemente 0:e97876f96d4b 626
clemente 0:e97876f96d4b 627 VS1053_CS_ENABLE;
clemente 0:e97876f96d4b 628 for ( i=0; i<cVS1053_CS_DELAY;i++);
clemente 0:e97876f96d4b 629
clemente 0:e97876f96d4b 630 _spi.write(0x02); // Write
clemente 0:e97876f96d4b 631 _spi.write(vAddress); // Register address
clemente 0:e97876f96d4b 632 _spi.write(((unsigned char*)&wValue)[1]); // 8 bit value to write high byte
clemente 0:e97876f96d4b 633 _spi.write(((unsigned char*)&wValue)[0]); // 8 bit value to write low byte
clemente 0:e97876f96d4b 634
clemente 0:e97876f96d4b 635 for ( i=0; i<cVS1053_CS_DELAY;i++);
clemente 0:e97876f96d4b 636 VS1053_CS_DISABLE;
clemente 0:e97876f96d4b 637
clemente 0:e97876f96d4b 638 }
clemente 0:e97876f96d4b 639
clemente 0:e97876f96d4b 640 #ifdef __ENCODE_OGG
clemente 0:e97876f96d4b 641 void VS1053Codec::VoggEncoding_Start( void)
clemente 0:e97876f96d4b 642 /* VorbisEncoder160c pag. 9 */
clemente 0:e97876f96d4b 643 {
clemente 0:e97876f96d4b 644 unsigned short temp;
clemente 0:e97876f96d4b 645
clemente 0:e97876f96d4b 646 /* 2. vs1053b at 55.3MHz */
clemente 0:e97876f96d4b 647 writeregnowait( VLSI_CLOCKF, 0xC000); cWAIT_DREQ_1MS;
clemente 0:e97876f96d4b 648 /* 3. SCI_BASS to 0 */
clemente 0:e97876f96d4b 649 writeregnowait( VLSI_BASS, 0x0000); cWAIT_DREQ_1MS;
clemente 0:e97876f96d4b 650 /* 4. Disable user application (no wait fot DREQ pin and no delay, as from the VLSI source file example */
clemente 0:e97876f96d4b 651 /* record.c from playercode1053-Aug2009.zip */
clemente 0:e97876f96d4b 652 writeregnowait( VLSI_AIADDR, 0x0000);
clemente 0:e97876f96d4b 653 /* 5. Disable all IRQ except the SCI IRQ */
clemente 0:e97876f96d4b 654 writeregnowait( VLSI_WRAMADDR, 0xC01A);
clemente 0:e97876f96d4b 655 writeregnowait( VLSI_WRAM, 0x0002);
clemente 0:e97876f96d4b 656 /* 6. Load the plugin code... */
clemente 0:e97876f96d4b 657 loadoggpatch();
clemente 0:e97876f96d4b 658 /* 7. Set bit SM_ADPCM to 1. */
clemente 0:e97876f96d4b 659 temp = (unsigned short)readreg( VLSI_MODE); cWAIT_DREQ_1MS;
clemente 0:e97876f96d4b 660 temp |= SM_ADPCM;
clemente 0:e97876f96d4b 661 writeregnowait( VLSI_MODE, temp); cWAIT_DREQ_1MS;
clemente 0:e97876f96d4b 662 writeregnowait( VLSI_AICTRL0, 0x0000); cWAIT_DREQ_1MS;
clemente 0:e97876f96d4b 663 /* 8. Set recording level. Value are for conservative AGC. */
clemente 0:e97876f96d4b 664 writeregnowait( VLSI_AICTRL1, 0x0000); cWAIT_DREQ_1MS;
clemente 0:e97876f96d4b 665 writeregnowait( VLSI_AICTRL2, 4096); cWAIT_DREQ_1MS;
clemente 0:e97876f96d4b 666 /* 10. Set 0 to SCI_AICTRL3. */
clemente 0:e97876f96d4b 667 writeregnowait( VLSI_AICTRL3, 0x0000); cWAIT_DREQ_1MS;
clemente 0:e97876f96d4b 668 /* 11. Active the encoder... */
clemente 0:e97876f96d4b 669 wait_ms( 5);
clemente 0:e97876f96d4b 670 writeregnowait( VLSI_AIADDR, 0x0034); wait_ms( 1);
clemente 0:e97876f96d4b 671 /* 12. wait DREQ high. */
clemente 0:e97876f96d4b 672 cWAIT_DREQ; /* Loop forever. */
clemente 0:e97876f96d4b 673
clemente 0:e97876f96d4b 674 }
clemente 0:e97876f96d4b 675
clemente 0:e97876f96d4b 676 #if 0
clemente 0:e97876f96d4b 677 void VS1053Codec::VoggEncoding_ReadStatus( RUNTIME_VOGG_VALUE *status)
clemente 0:e97876f96d4b 678 /* VorbisEncoder160c par 2.3.4, pag. 11 */
clemente 0:e97876f96d4b 679 /* see VLSICodec.h for RUNTIME_VOGG_VALUE struct data. */
clemente 0:e97876f96d4b 680 {
clemente 0:e97876f96d4b 681 unsigned short temp, temph;
clemente 0:e97876f96d4b 682
clemente 0:e97876f96d4b 683 /* Recording Time */
clemente 0:e97876f96d4b 684 writereg( VLSI_WRAMADDR, 0x0008); cWAIT_DREQ_1MS;
clemente 0:e97876f96d4b 685 temp = (unsigned short)readreg( VLSI_WRAM); /* LSB recording Time */
clemente 0:e97876f96d4b 686 temph= (unsigned short)readreg( VLSI_WRAM); /* MSB recording Time */
clemente 0:e97876f96d4b 687 status->rec_time = ((unsigned long)temph << 16) | temp;
clemente 0:e97876f96d4b 688
clemente 0:e97876f96d4b 689 /* Average bitrate */
clemente 0:e97876f96d4b 690 writereg( VLSI_WRAMADDR, 0x000C); cWAIT_DREQ_1MS;
clemente 0:e97876f96d4b 691 temp = (unsigned short)readreg( VLSI_WRAM); /* LSB Average bitrate */
clemente 0:e97876f96d4b 692 temph= (unsigned short)readreg( VLSI_WRAM); /* MSB Average bitrate */
clemente 0:e97876f96d4b 693 status->average_bitrate = ((unsigned long)temph << 16) | temp;
clemente 0:e97876f96d4b 694
clemente 0:e97876f96d4b 695 /* Sample Counter */
clemente 0:e97876f96d4b 696 writereg( VLSI_WRAMADDR, 0x1800); cWAIT_DREQ_1MS;
clemente 0:e97876f96d4b 697 temp = (unsigned short)readreg( VLSI_WRAM); /* LSB Sample Counter */
clemente 0:e97876f96d4b 698 temph= (unsigned short)readreg( VLSI_WRAM); /* MSB Average bitrate */
clemente 0:e97876f96d4b 699 status->sample_counter = ((unsigned long)temph << 16) | temp;
clemente 0:e97876f96d4b 700 }
clemente 0:e97876f96d4b 701 #endif
clemente 0:e97876f96d4b 702
clemente 0:e97876f96d4b 703
clemente 0:e97876f96d4b 704 /*
clemente 0:e97876f96d4b 705 * Questa funzione legge il registro SCI_HDAT1 per verificare la presenza di
clemente 0:e97876f96d4b 706 * sample disponibili. In caso ci siano li legge dal reg. SCI_HDAT0
clemente 0:e97876f96d4b 707 * salvandoli nel puntatore passatogli. Ritorna il numero di byte copiati.
clemente 0:e97876f96d4b 708 */
clemente 0:e97876f96d4b 709 unsigned int VS1053Codec::VoggEncoding_ReadBuffer( unsigned char *voggSample)
clemente 0:e97876f96d4b 710 /* VorbisEncoder160c pag. 10 */
clemente 0:e97876f96d4b 711 {
clemente 0:e97876f96d4b 712 unsigned int i;
clemente 0:e97876f96d4b 713 unsigned short temp, sample;
clemente 0:e97876f96d4b 714
clemente 0:e97876f96d4b 715 temp=0;
clemente 0:e97876f96d4b 716 i=0;
clemente 0:e97876f96d4b 717 sample=0;
clemente 0:e97876f96d4b 718
clemente 0:e97876f96d4b 719 // printf("readbuffer\r\n");
clemente 0:e97876f96d4b 720
clemente 0:e97876f96d4b 721 do {
clemente 0:e97876f96d4b 722 /* reading the sample counter... */
clemente 0:e97876f96d4b 723 temp = (unsigned short)readreg( VLSI_HDAT1);
clemente 0:e97876f96d4b 724 if ( temp ) {
clemente 0:e97876f96d4b 725 // printf("sample %d\r\n", temp);
clemente 0:e97876f96d4b 726 /* there are samples... */
clemente 0:e97876f96d4b 727 i=0;
clemente 0:e97876f96d4b 728 while( i < temp) {
clemente 0:e97876f96d4b 729 /* read the sample as word */
clemente 0:e97876f96d4b 730 sample=(unsigned short)readreg( VLSI_HDAT0);
clemente 0:e97876f96d4b 731 /* save it into the array as single byte. */
clemente 0:e97876f96d4b 732 *voggSample++ = (unsigned char)(sample >> 8); /* MSB */
clemente 0:e97876f96d4b 733 *voggSample++ = (unsigned char)(sample & 0x00FF); /* LSB */
clemente 0:e97876f96d4b 734 i++;
clemente 0:e97876f96d4b 735 wait_ms( 1);
clemente 0:e97876f96d4b 736 }
clemente 0:e97876f96d4b 737
clemente 0:e97876f96d4b 738 /* Exit the loop. */
clemente 0:e97876f96d4b 739 break;
clemente 0:e97876f96d4b 740 } else {
clemente 0:e97876f96d4b 741 // printf("no sample\r\n");
clemente 0:e97876f96d4b 742 /* Exit the loop. */
clemente 0:e97876f96d4b 743 break;
clemente 0:e97876f96d4b 744 }
clemente 0:e97876f96d4b 745 } while( 1);
clemente 0:e97876f96d4b 746 /* just relax... */
clemente 0:e97876f96d4b 747 wait_ms( 1);
clemente 0:e97876f96d4b 748 /* Return the number of byte saved. */
clemente 0:e97876f96d4b 749 return i*2;
clemente 0:e97876f96d4b 750 }
clemente 0:e97876f96d4b 751
clemente 0:e97876f96d4b 752 /*
clemente 0:e97876f96d4b 753 * Questa funzione esegue la procedura di fine encoding memorizzando i rimanenti sample
clemente 0:e97876f96d4b 754 * nel puntatore passatogli. Ritorna il numero di sample letti.
clemente 0:e97876f96d4b 755 */
clemente 0:e97876f96d4b 756 unsigned int VS1053Codec::VoggEncoding_Stop( unsigned char *voggSample)
clemente 0:e97876f96d4b 757 /* VorbisEncoder160c pag. 11 */
clemente 0:e97876f96d4b 758 {
clemente 0:e97876f96d4b 759 unsigned int res, i, ii;
clemente 0:e97876f96d4b 760 unsigned short temp, sample;
clemente 0:e97876f96d4b 761 res=0;
clemente 0:e97876f96d4b 762 temp=0;
clemente 0:e97876f96d4b 763 sample=0;
clemente 0:e97876f96d4b 764
clemente 0:e97876f96d4b 765 /* 1. set bit 0 to 1 */
clemente 0:e97876f96d4b 766 temp = (unsigned short)readreg( VLSI_AICTRL3);
clemente 0:e97876f96d4b 767 temp |= 0x0001;
clemente 0:e97876f96d4b 768 writereg( VLSI_AICTRL3, temp);
clemente 0:e97876f96d4b 769
clemente 0:e97876f96d4b 770 /* 2. continue reading data but checking the bit 1 of VLSI_AICTRL3 reg. */
clemente 0:e97876f96d4b 771 res=0;
clemente 0:e97876f96d4b 772 do {
clemente 0:e97876f96d4b 773 /* reading the sample counter... */
clemente 0:e97876f96d4b 774 temp = (unsigned short)readreg( VLSI_HDAT1);
clemente 0:e97876f96d4b 775 if ( temp) {
clemente 0:e97876f96d4b 776 // printf("EncStop: %d\r\n", temp);
clemente 0:e97876f96d4b 777 i=0;
clemente 0:e97876f96d4b 778 while( i < temp ) {
clemente 0:e97876f96d4b 779 /* */
clemente 0:e97876f96d4b 780 sample = (unsigned short)readreg( VLSI_HDAT0);
clemente 0:e97876f96d4b 781 *voggSample++ = (unsigned char)(sample >> 8);
clemente 0:e97876f96d4b 782 *voggSample++ = (unsigned char)sample & 0x00FF;
clemente 0:e97876f96d4b 783 i++;
clemente 0:e97876f96d4b 784 wait_ms( 1);
clemente 0:e97876f96d4b 785 }
clemente 0:e97876f96d4b 786 res+=i;
clemente 0:e97876f96d4b 787 }
clemente 0:e97876f96d4b 788 /* just relax... */
clemente 0:e97876f96d4b 789 wait_ms( 1);
clemente 0:e97876f96d4b 790 temp = (unsigned short)readreg( VLSI_AICTRL3);
clemente 0:e97876f96d4b 791 /* verify the bit 1 of VLSI_AICTRL3 reg. */
clemente 0:e97876f96d4b 792 if ( temp & 0x0002) {
clemente 0:e97876f96d4b 793 // printf("Encoding STOP\r\n");
clemente 0:e97876f96d4b 794 /* encoding has finished. */
clemente 0:e97876f96d4b 795 break;
clemente 0:e97876f96d4b 796 }
clemente 0:e97876f96d4b 797 } while( 1); /* Loop forever... */
clemente 0:e97876f96d4b 798 /* 3. write the remaining word... */
clemente 0:e97876f96d4b 799 ii=0;
clemente 0:e97876f96d4b 800 do {
clemente 0:e97876f96d4b 801 temp = (unsigned short)readreg( VLSI_HDAT1);
clemente 0:e97876f96d4b 802 if ( temp) {
clemente 0:e97876f96d4b 803 // printf("Flush %d\r\n", temp);
clemente 0:e97876f96d4b 804 /* there are samples... */
clemente 0:e97876f96d4b 805 i=0;
clemente 0:e97876f96d4b 806 while( i < temp ) { /* con il numero precedente. */
clemente 0:e97876f96d4b 807 /* */
clemente 0:e97876f96d4b 808 sample = (unsigned short)readreg( VLSI_HDAT0);
clemente 0:e97876f96d4b 809 *voggSample++ = (unsigned char)(sample >> 8);
clemente 0:e97876f96d4b 810 *voggSample++ = (unsigned char)sample & 0x00FF;
clemente 0:e97876f96d4b 811 i++;
clemente 0:e97876f96d4b 812 wait_ms( 1);
clemente 0:e97876f96d4b 813 }
clemente 0:e97876f96d4b 814 res+=i;
clemente 0:e97876f96d4b 815 } else {
clemente 0:e97876f96d4b 816 wait_ms( 1);
clemente 0:e97876f96d4b 817 ii++;
clemente 0:e97876f96d4b 818 }
clemente 0:e97876f96d4b 819 } while( ii<5); /* Loops ... */
clemente 0:e97876f96d4b 820 /* 4. read twise AICTRL3 */
clemente 0:e97876f96d4b 821 temp = (unsigned short)readreg( VLSI_AICTRL3);
clemente 0:e97876f96d4b 822 temp = (unsigned short)readreg( VLSI_AICTRL3);
clemente 0:e97876f96d4b 823 // printf("last read %d\r\n", temp);
clemente 0:e97876f96d4b 824 if ( temp & 0x0004 ) {
clemente 0:e97876f96d4b 825 /* remove last byte ( bits 7:0) from the last word. */
clemente 0:e97876f96d4b 826 voggSample--;
clemente 0:e97876f96d4b 827 *voggSample=0;
clemente 0:e97876f96d4b 828 res=(res*2)-1;
clemente 0:e97876f96d4b 829 } else {
clemente 0:e97876f96d4b 830 res=res*2;
clemente 0:e97876f96d4b 831 }
clemente 0:e97876f96d4b 832 /* 5. Reset the codec. */
clemente 0:e97876f96d4b 833
clemente 0:e97876f96d4b 834 /* Ritorno il numero di sample, in byte, letti. */
clemente 0:e97876f96d4b 835 return res;
clemente 0:e97876f96d4b 836 }
clemente 0:e97876f96d4b 837 #endif