Library for VS1053 chip with non blocking call to check dreq and cancel playback function

Dependents:   VS1053Player MP3_test MP3_final_S4P_ANDRIAMARO_RAKOTO_1

Fork of VS1053lib by clemente di caprio

Committer:
ollie8
Date:
Tue Jun 11 16:24:39 2013 +0000
Revision:
3:59c27531f18e
Parent:
2:59076bd8a066
Child:
4:ce980c240ae1
Added a function to clear the playtime string.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
clemente 1:399afe8151de 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 1:399afe8151de 130 /** VS1053Codec
clemente 1:399afe8151de 131 */
clemente 0:e97876f96d4b 132 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 133 // defaults params
clemente 0:e97876f96d4b 134 VS1053_CS_DISABLE;
clemente 0:e97876f96d4b 135 VS1053_XDCS_DISABLE;
clemente 0:e97876f96d4b 136 }
clemente 0:e97876f96d4b 137
clemente 1:399afe8151de 138 /** Wait untile the dreq is released
clemente 1:399afe8151de 139 * @param none
clemente 1:399afe8151de 140 * @retval none
clemente 1:399afe8151de 141 */
clemente 0:e97876f96d4b 142 void VS1053Codec::testdreq( void){
clemente 0:e97876f96d4b 143 while( !_dreq);
clemente 0:e97876f96d4b 144 }
ollie8 2:59076bd8a066 145
ollie8 2:59076bd8a066 146 bool VS1053Codec::checkdreq(void) {
ollie8 2:59076bd8a066 147 return _dreq;
ollie8 2:59076bd8a066 148 }
clemente 1:399afe8151de 149
clemente 1:399afe8151de 150 /** Put the VS1053 in low power mode (RESET)
clemente 1:399afe8151de 151 *
clemente 1:399afe8151de 152 * @param none
clemente 1:399afe8151de 153 * @retval none
clemente 1:399afe8151de 154 */
clemente 0:e97876f96d4b 155 void VS1053Codec::lowpower( void)
clemente 0:e97876f96d4b 156 {
clemente 0:e97876f96d4b 157 VS1053_RST_ENABLE;
clemente 0:e97876f96d4b 158 wait_ms( 10);
clemente 0:e97876f96d4b 159 }
clemente 0:e97876f96d4b 160
clemente 1:399afe8151de 161 /** Initialize the VS1053
clemente 1:399afe8151de 162 */
clemente 0:e97876f96d4b 163 void VS1053Codec::init(void)
clemente 0:e97876f96d4b 164 {
clemente 0:e97876f96d4b 165 //
clemente 0:e97876f96d4b 166 VS1053_RST_DISABLE;
clemente 0:e97876f96d4b 167 VS1053_CS_DISABLE;
clemente 0:e97876f96d4b 168 VS1053_XDCS_DISABLE;
clemente 0:e97876f96d4b 169 //
clemente 0:e97876f96d4b 170 _spi.format( 8, 0);
clemente 0:e97876f96d4b 171 _spi.frequency( MP3_INIT_SPEED);
clemente 0:e97876f96d4b 172
clemente 0:e97876f96d4b 173 // Assert RESET
clemente 0:e97876f96d4b 174 VS1053_RST_ENABLE;
clemente 0:e97876f96d4b 175 wait_ms( 100);
clemente 0:e97876f96d4b 176
clemente 0:e97876f96d4b 177 // Deassert RESET (active low)
clemente 0:e97876f96d4b 178 VS1053_RST_DISABLE;
clemente 0:e97876f96d4b 179 VS1053_CS_DISABLE;
clemente 0:e97876f96d4b 180 VS1053_XDCS_DISABLE;
clemente 0:e97876f96d4b 181 wait_ms( 100);
clemente 0:e97876f96d4b 182
clemente 0:e97876f96d4b 183 // Wait
clemente 0:e97876f96d4b 184 while(!_dreq);
clemente 0:e97876f96d4b 185
clemente 0:e97876f96d4b 186 // Reset the vs1053
clemente 0:e97876f96d4b 187 writereg( VLSI_MODE, ( cMODEREG_SET | SM_RESET) );
clemente 0:e97876f96d4b 188 wait_ms( 10);
clemente 0:e97876f96d4b 189
clemente 0:e97876f96d4b 190 // Wait...
clemente 0:e97876f96d4b 191 while(!_dreq);
clemente 0:e97876f96d4b 192
clemente 0:e97876f96d4b 193 /*
clemente 0:e97876f96d4b 194 * Write configuration MODE register in a loop to verify that the chip is
clemente 0:e97876f96d4b 195 * connected and running correctly
clemente 0:e97876f96d4b 196 */
clemente 0:e97876f96d4b 197 do
clemente 0:e97876f96d4b 198 {
clemente 0:e97876f96d4b 199 writereg( VLSI_MODE, ( cMODEREG_SET ));
clemente 0:e97876f96d4b 200 wait_ms( 1);
clemente 0:e97876f96d4b 201 }while( readreg( VLSI_MODE) != ( cMODEREG_SET ));
clemente 0:e97876f96d4b 202
clemente 0:e97876f96d4b 203 //
clemente 0:e97876f96d4b 204 if((readreg( VLSI_STATUS) & VLSI_STATUS_VER) == VER_VS1053)
clemente 0:e97876f96d4b 205 {
clemente 0:e97876f96d4b 206 // Set the clock to maximum speed (VS1053 only) to allow all audio formats
clemente 0:e97876f96d4b 207 // to be decoded without glitching. Note that this increases power
clemente 0:e97876f96d4b 208 // consumption.
clemente 0:e97876f96d4b 209 // SC_MULT = XTALI*4.5, SC_ADD = noMod, SC_FREQ = 0 (12.288MHz)
clemente 0:e97876f96d4b 210 // VLSIWriteReg(VLSI_CLOCKF, SC_MULT_4_5 | SC_ADD_X1 | SC_FREQ);
clemente 0:e97876f96d4b 211
clemente 0:e97876f96d4b 212 writereg(VLSI_CLOCKF, cCLOCK_SET);
clemente 0:e97876f96d4b 213
clemente 0:e97876f96d4b 214 /* */
clemente 0:e97876f96d4b 215 wait_ms( 2);
clemente 0:e97876f96d4b 216 while(!_dreq);
clemente 0:e97876f96d4b 217 }
clemente 0:e97876f96d4b 218 else if ((readreg( VLSI_STATUS) & VLSI_STATUS_VER) == VER_VS1011E)
clemente 0:e97876f96d4b 219 {
clemente 0:e97876f96d4b 220 // Nothing special to do
clemente 0:e97876f96d4b 221 ;
clemente 0:e97876f96d4b 222 }
clemente 0:e97876f96d4b 223 else
clemente 0:e97876f96d4b 224 {
clemente 0:e97876f96d4b 225 // VLSI Chip version not tested, not supported, halt program execution.
clemente 0:e97876f96d4b 226 // This trap should be caught during the design phase.
clemente 0:e97876f96d4b 227 while(1);
clemente 0:e97876f96d4b 228 }
clemente 0:e97876f96d4b 229
clemente 0:e97876f96d4b 230 _spi.frequency( MP3_RUN_SPEED);
clemente 0:e97876f96d4b 231 }
clemente 0:e97876f96d4b 232
clemente 0:e97876f96d4b 233 void VS1053Codec::loadpatch(void)
clemente 0:e97876f96d4b 234 /* Questa funzione carica una patch al firmware del codec */
clemente 0:e97876f96d4b 235 {
clemente 0:e97876f96d4b 236 int i = 0, plgin_len;
clemente 0:e97876f96d4b 237 unsigned int addr, n, val;
clemente 0:e97876f96d4b 238
clemente 0:e97876f96d4b 239 plgin_len=sizeof( plugin)/sizeof(plugin[0]);
clemente 0:e97876f96d4b 240 while (i<plgin_len) {
clemente 0:e97876f96d4b 241
clemente 0:e97876f96d4b 242 addr = plugin[i++];
clemente 0:e97876f96d4b 243 n = plugin[i++];
clemente 0:e97876f96d4b 244 if (n & 0x8000U) { /* RLE run, replicate n samples */
clemente 0:e97876f96d4b 245 n &= 0x7FFF;
clemente 0:e97876f96d4b 246 val = plugin[i++];
clemente 0:e97876f96d4b 247 while (n--) {
clemente 0:e97876f96d4b 248 writeregnowait(addr, val);
clemente 0:e97876f96d4b 249 while(!_dreq);
clemente 0:e97876f96d4b 250 }
clemente 0:e97876f96d4b 251 } else { /* Copy run, copy n samples */
clemente 0:e97876f96d4b 252 while (n--) {
clemente 0:e97876f96d4b 253 val = plugin[i++];
clemente 0:e97876f96d4b 254 writeregnowait(addr, val);
clemente 0:e97876f96d4b 255 while(!_dreq);
clemente 0:e97876f96d4b 256 }
clemente 0:e97876f96d4b 257 }
clemente 0:e97876f96d4b 258 }
clemente 0:e97876f96d4b 259 //
clemente 0:e97876f96d4b 260 wait_ms( 1);
clemente 0:e97876f96d4b 261 while(!_dreq);
clemente 0:e97876f96d4b 262 }
clemente 0:e97876f96d4b 263
clemente 0:e97876f96d4b 264 #ifdef __PLUGINGA
clemente 0:e97876f96d4b 265 void VS1053Codec::loadgapatch(void)
clemente 0:e97876f96d4b 266 /* Questa funzione carica un plugin nel codec */
clemente 0:e97876f96d4b 267 {
clemente 0:e97876f96d4b 268 int i = 0, plgin_len;
clemente 0:e97876f96d4b 269 unsigned int addr, n, val;
clemente 0:e97876f96d4b 270
clemente 0:e97876f96d4b 271 plgin_len=sizeof( gaplugin)/sizeof(gaplugin[0]);
clemente 0:e97876f96d4b 272 while (i<plgin_len) {
clemente 0:e97876f96d4b 273
clemente 0:e97876f96d4b 274 addr = gaplugin[i++];
clemente 0:e97876f96d4b 275 n = gaplugin[i++];
clemente 0:e97876f96d4b 276 if (n & 0x8000U) { /* RLE run, replicate n samples */
clemente 0:e97876f96d4b 277 n &= 0x7FFF;
clemente 0:e97876f96d4b 278 val = gaplugin[i++];
clemente 0:e97876f96d4b 279 while (n--) {
clemente 0:e97876f96d4b 280 writeregnowait(addr, val);
clemente 0:e97876f96d4b 281 while(!_dreq);
clemente 0:e97876f96d4b 282 }
clemente 0:e97876f96d4b 283 } else { /* Copy run, copy n samples */
clemente 0:e97876f96d4b 284 while (n--) {
clemente 0:e97876f96d4b 285 val = gaplugin[i++];
clemente 0:e97876f96d4b 286 writeregnowait(addr, val);
clemente 0:e97876f96d4b 287 while(!_dreq);
clemente 0:e97876f96d4b 288 }
clemente 0:e97876f96d4b 289 }
clemente 0:e97876f96d4b 290 }
clemente 0:e97876f96d4b 291 //
clemente 0:e97876f96d4b 292 wait_ms( 1);
clemente 0:e97876f96d4b 293 while(!_dreq);
clemente 0:e97876f96d4b 294 }
clemente 0:e97876f96d4b 295 #endif
clemente 0:e97876f96d4b 296
clemente 0:e97876f96d4b 297 #ifdef __ENCODE_OGG
clemente 0:e97876f96d4b 298 void VS1053Codec::loadoggpatch(void)
clemente 0:e97876f96d4b 299 /* Questa funzione carica una patch per gestire l'encoder OGG */
clemente 0:e97876f96d4b 300 {
clemente 0:e97876f96d4b 301 int i = 0, plgin_len;
clemente 0:e97876f96d4b 302 unsigned int addr, n, val;
clemente 0:e97876f96d4b 303
clemente 0:e97876f96d4b 304 plgin_len=sizeof( ogg_enc)/sizeof(ogg_enc[0]);
clemente 0:e97876f96d4b 305 while (i<plgin_len) {
clemente 0:e97876f96d4b 306
clemente 0:e97876f96d4b 307 addr = ogg_enc[i++];
clemente 0:e97876f96d4b 308 n = ogg_enc[i++];
clemente 0:e97876f96d4b 309 if (n & 0x8000U) { /* RLE run, replicate n samples */
clemente 0:e97876f96d4b 310 n &= 0x7FFF;
clemente 0:e97876f96d4b 311 val = ogg_enc[i++];
clemente 0:e97876f96d4b 312 while (n--) {
clemente 0:e97876f96d4b 313 writeregnowait(addr, val);
clemente 0:e97876f96d4b 314 while(!_dreq);
clemente 0:e97876f96d4b 315 }
clemente 0:e97876f96d4b 316 } else { /* Copy run, copy n samples */
clemente 0:e97876f96d4b 317 while (n--) {
clemente 0:e97876f96d4b 318 val = ogg_enc[i++];
clemente 0:e97876f96d4b 319 writeregnowait(addr, val);
clemente 0:e97876f96d4b 320 while(!_dreq);
clemente 0:e97876f96d4b 321 }
clemente 0:e97876f96d4b 322 }
clemente 0:e97876f96d4b 323 }
clemente 0:e97876f96d4b 324 //
clemente 0:e97876f96d4b 325 wait_ms( 1);
clemente 0:e97876f96d4b 326 while(!_dreq);
clemente 0:e97876f96d4b 327 }
clemente 0:e97876f96d4b 328 #endif
clemente 0:e97876f96d4b 329
clemente 0:e97876f96d4b 330 #ifdef __PLUGINGA
clemente 0:e97876f96d4b 331 void VS1053Codec::readgavalue( unsigned char *currval, unsigned char *peak)
clemente 0:e97876f96d4b 332 {
clemente 1:399afe8151de 333 writereg( VLSI_WRAMADDR, cBASE+2);
clemente 1:399afe8151de 334 unsigned short bands = (unsigned short)readreg( VLSI_WRAM);
clemente 1:399afe8151de 335 //
clemente 1:399afe8151de 336 writereg( VLSI_WRAMADDR, cBASE+4);
clemente 1:399afe8151de 337 //
clemente 1:399afe8151de 338 for (int i=0;i<bands;i++) {
clemente 1:399afe8151de 339 short pv = readreg( VLSI_WRAM);
clemente 1:399afe8151de 340 /* current value in bits 5..0, normally 0..31
clemente 1:399afe8151de 341 peak value in bits 11..6, normally 0..31 */
clemente 1:399afe8151de 342 currval[i]=(unsigned char)(pv&0x003F);
clemente 1:399afe8151de 343 peak[i]=(unsigned char)( (pv>>6)&0x003F);
clemente 1:399afe8151de 344 }
clemente 0:e97876f96d4b 345 }
clemente 0:e97876f96d4b 346
clemente 0:e97876f96d4b 347 unsigned short VS1053Codec::readgabands( void)
clemente 0:e97876f96d4b 348 {
clemente 1:399afe8151de 349 writereg( VLSI_WRAMADDR, cBASE+2);
clemente 1:399afe8151de 350 unsigned short bands = (unsigned short)readreg( VLSI_WRAM);
clemente 1:399afe8151de 351 /* */
clemente 1:399afe8151de 352 return bands;
clemente 0:e97876f96d4b 353 }
clemente 0:e97876f96d4b 354
clemente 0:e97876f96d4b 355 #endif
clemente 0:e97876f96d4b 356
clemente 0:e97876f96d4b 357 void VS1053Codec::setvmeter( void)
clemente 0:e97876f96d4b 358 {
clemente 0:e97876f96d4b 359 unsigned short tmp;
clemente 0:e97876f96d4b 360
clemente 0:e97876f96d4b 361 tmp=(unsigned short)readreg( VLSI_STATUS);
clemente 0:e97876f96d4b 362 tmp|=(1<<9);
clemente 0:e97876f96d4b 363 writereg( VLSI_STATUS, tmp);
clemente 0:e97876f96d4b 364 }
clemente 0:e97876f96d4b 365
clemente 0:e97876f96d4b 366 void VS1053Codec::getvmeterval( unsigned char* left, unsigned char* right)
clemente 0:e97876f96d4b 367 {
clemente 0:e97876f96d4b 368 unsigned short tmp;
clemente 0:e97876f96d4b 369
clemente 0:e97876f96d4b 370 tmp=(unsigned short)readreg( VLSI_AICTRL3);
clemente 0:e97876f96d4b 371
clemente 0:e97876f96d4b 372 *right=(unsigned char)tmp&0x00FF;
clemente 0:e97876f96d4b 373 *left=(unsigned char)(tmp>>8);
clemente 0:e97876f96d4b 374 }
clemente 0:e97876f96d4b 375
clemente 0:e97876f96d4b 376 /****************************************************************************
clemente 0:e97876f96d4b 377 Function:
clemente 0:e97876f96d4b 378 void VS1053Codec::setbassboost(BYTE bass, BYTE gfreq)
clemente 0:e97876f96d4b 379
clemente 0:e97876f96d4b 380 Description:
clemente 0:e97876f96d4b 381 This function sets the bass boost.
clemente 0:e97876f96d4b 382
clemente 0:e97876f96d4b 383 Precondition:
clemente 0:e97876f96d4b 384 None
clemente 0:e97876f96d4b 385
clemente 0:e97876f96d4b 386 Parameters:
clemente 0:e97876f96d4b 387 BYTE bass - Bass gain in dB, range from 0 to 15 (MSB nibble)
clemente 0:e97876f96d4b 388 BYTE gfreq - Limit frequency for bass boost, 10 Hz steps (range from
clemente 0:e97876f96d4b 389 20 to 150) (LSB nibble)
clemente 0:e97876f96d4b 390
clemente 0:e97876f96d4b 391 Returns:
clemente 0:e97876f96d4b 392 None
clemente 0:e97876f96d4b 393
clemente 0:e97876f96d4b 394 Remarks:
clemente 0:e97876f96d4b 395 None
clemente 0:e97876f96d4b 396 ***************************************************************************/
clemente 0:e97876f96d4b 397 void VS1053Codec::setbassboost( unsigned char bass, unsigned char gfreq)
clemente 0:e97876f96d4b 398 {
clemente 0:e97876f96d4b 399 unsigned char templ;
clemente 0:e97876f96d4b 400 unsigned short tmp;
clemente 0:e97876f96d4b 401
clemente 0:e97876f96d4b 402 //
clemente 0:e97876f96d4b 403 if(bass > 15u)
clemente 0:e97876f96d4b 404 bass = 15;
clemente 0:e97876f96d4b 405 if(gfreq > 150u)
clemente 0:e97876f96d4b 406 gfreq = 150;
clemente 0:e97876f96d4b 407 if ( gfreq < 20)
clemente 0:e97876f96d4b 408 gfreq = 20;
clemente 0:e97876f96d4b 409
clemente 0:e97876f96d4b 410
clemente 0:e97876f96d4b 411 //
clemente 0:e97876f96d4b 412 templ = (unsigned char)gfreq/10;
clemente 0:e97876f96d4b 413
clemente 0:e97876f96d4b 414 // put bass boost value into the upper 4 bit
clemente 0:e97876f96d4b 415 templ |= (bass << 4);
clemente 0:e97876f96d4b 416 //
clemente 0:e97876f96d4b 417 tmp=(unsigned short)readreg( VLSI_BASS);
clemente 0:e97876f96d4b 418 tmp &= 0xFF00;
clemente 0:e97876f96d4b 419 tmp |= templ;
clemente 0:e97876f96d4b 420 //
clemente 0:e97876f96d4b 421 writereg( VLSI_BASS, tmp);
clemente 0:e97876f96d4b 422 }
clemente 0:e97876f96d4b 423
clemente 0:e97876f96d4b 424 /****************************************************************************
clemente 0:e97876f96d4b 425 Function:
clemente 0:e97876f96d4b 426 void VS1053Codec::settrebleboost(BYTE bass, WORD gfreq)
clemente 0:e97876f96d4b 427
clemente 0:e97876f96d4b 428 Description:
clemente 0:e97876f96d4b 429 This function sets the bass boost.
clemente 0:e97876f96d4b 430
clemente 0:e97876f96d4b 431 Precondition:
clemente 0:e97876f96d4b 432 None
clemente 0:e97876f96d4b 433
clemente 0:e97876f96d4b 434 Parameters:
clemente 0:e97876f96d4b 435 BYTE treble - Bass gain in dB, range from -8 to 7 (MSB nibble)
clemente 0:e97876f96d4b 436 WORD gfreq - Limit frequency for bass boost, 1000 Hz steps (range from
clemente 0:e97876f96d4b 437 1000 to 15000) (LSB nibble)
clemente 0:e97876f96d4b 438
clemente 0:e97876f96d4b 439 Returns:
clemente 0:e97876f96d4b 440 None
clemente 0:e97876f96d4b 441
clemente 0:e97876f96d4b 442 Remarks:
clemente 0:e97876f96d4b 443 None
clemente 0:e97876f96d4b 444 ***************************************************************************/
clemente 0:e97876f96d4b 445 void VS1053Codec::settrebleboost( char treble, unsigned int gfreq)
clemente 0:e97876f96d4b 446 {
clemente 0:e97876f96d4b 447 unsigned char templ;
clemente 0:e97876f96d4b 448 unsigned short tmp;
clemente 0:e97876f96d4b 449
clemente 0:e97876f96d4b 450 //
clemente 0:e97876f96d4b 451 if(treble > 7)
clemente 0:e97876f96d4b 452 treble = 7;
clemente 0:e97876f96d4b 453 if ( treble < (char)-8)
clemente 0:e97876f96d4b 454 treble = (char)-8;
clemente 0:e97876f96d4b 455
clemente 0:e97876f96d4b 456 if(gfreq > 15000u)
clemente 0:e97876f96d4b 457 gfreq = 15000;
clemente 0:e97876f96d4b 458 if(gfreq < 1000)
clemente 0:e97876f96d4b 459 gfreq = 1000;
clemente 0:e97876f96d4b 460
clemente 0:e97876f96d4b 461 //
clemente 0:e97876f96d4b 462 templ = (unsigned char)gfreq/1000;
clemente 0:e97876f96d4b 463
clemente 0:e97876f96d4b 464 // put treble boost value into the upper 4 bit
clemente 0:e97876f96d4b 465 templ |= (treble << 4);
clemente 0:e97876f96d4b 466 //
clemente 0:e97876f96d4b 467 tmp=(unsigned short)readreg( VLSI_BASS);
clemente 0:e97876f96d4b 468 tmp &= 0x00FF;
clemente 0:e97876f96d4b 469 tmp |= (templ << 8);
clemente 0:e97876f96d4b 470 //
clemente 0:e97876f96d4b 471 writereg( VLSI_BASS, tmp);
clemente 0:e97876f96d4b 472 }
clemente 0:e97876f96d4b 473
clemente 0:e97876f96d4b 474 void VS1053Codec::getplaytime(char *playtime)
clemente 0:e97876f96d4b 475 {
clemente 0:e97876f96d4b 476 unsigned short playTime;
clemente 0:e97876f96d4b 477 unsigned char minutes, seconds;
clemente 0:e97876f96d4b 478
clemente 0:e97876f96d4b 479 playTime = (unsigned short)readreg(VLSI_DECODE_TIME);
clemente 0:e97876f96d4b 480 minutes = playTime/60;
clemente 0:e97876f96d4b 481 seconds = playTime%60;
clemente 0:e97876f96d4b 482 *playtime++=('0'+minutes/10);
clemente 0:e97876f96d4b 483 *playtime++=('0'+minutes%10);
clemente 0:e97876f96d4b 484 *playtime++=(':');
clemente 0:e97876f96d4b 485 *playtime++=('0'+seconds/10);
clemente 0:e97876f96d4b 486 *playtime++=('0'+seconds%10);
clemente 0:e97876f96d4b 487 }
clemente 0:e97876f96d4b 488
ollie8 3:59c27531f18e 489 void VS1053Codec::resetplaytime() {
ollie8 3:59c27531f18e 490 writereg(VLSI_DECODE_TIME, 0);
ollie8 3:59c27531f18e 491 writereg(VLSI_DECODE_TIME, 0);
ollie8 3:59c27531f18e 492 }
clemente 0:e97876f96d4b 493 /****************************************************************************
clemente 0:e97876f96d4b 494 Function:
clemente 0:e97876f96d4b 495 void setvolume(unsigned char vRight, unsigned char vLeft)
clemente 0:e97876f96d4b 496
clemente 0:e97876f96d4b 497 Description:
clemente 0:e97876f96d4b 498 This function set volume for analog outputs on the VLSI codec.
clemente 0:e97876f96d4b 499
clemente 0:e97876f96d4b 500 Precondition:
clemente 0:e97876f96d4b 501 None
clemente 0:e97876f96d4b 502
clemente 0:e97876f96d4b 503 Parameters:
clemente 0:e97876f96d4b 504 unsigned char vRight - right channel attenuation from maximum volume, 0.5dB steps
clemente 0:e97876f96d4b 505 (0x00 = full volume, 0xFF = muted)
clemente 0:e97876f96d4b 506 unsigned char vLeft - left channel attenuation from maximum volume, 0.5dB steps
clemente 0:e97876f96d4b 507 (0x00 = full volume, 0xFF = muted)
clemente 0:e97876f96d4b 508
clemente 0:e97876f96d4b 509 Returns:
clemente 0:e97876f96d4b 510 None
clemente 0:e97876f96d4b 511
clemente 0:e97876f96d4b 512 Remarks:
clemente 0:e97876f96d4b 513 None
clemente 0:e97876f96d4b 514 ***************************************************************************/
clemente 0:e97876f96d4b 515 void VS1053Codec::setvolume(unsigned char vRight, unsigned char vLeft)
clemente 0:e97876f96d4b 516 {
clemente 0:e97876f96d4b 517 writereg(VLSI_VOL, ((unsigned int)vLeft)<<8 | vRight);
clemente 0:e97876f96d4b 518 }
clemente 0:e97876f96d4b 519
clemente 0:e97876f96d4b 520
clemente 0:e97876f96d4b 521 void VS1053Codec::sinetest( unsigned char pitch)
clemente 0:e97876f96d4b 522 {
clemente 0:e97876f96d4b 523 unsigned int i;
clemente 0:e97876f96d4b 524
clemente 0:e97876f96d4b 525 while(!_dreq);
clemente 0:e97876f96d4b 526
clemente 0:e97876f96d4b 527 i=(unsigned short)readreg( VLSI_MODE);
clemente 0:e97876f96d4b 528 writereg( VLSI_MODE, ( i | SM_TESTS ));
clemente 0:e97876f96d4b 529
clemente 0:e97876f96d4b 530 VS1053_XDCS_ENABLE;
clemente 0:e97876f96d4b 531
clemente 0:e97876f96d4b 532 if ( pitch) {
clemente 0:e97876f96d4b 533 // START Sine Test
clemente 0:e97876f96d4b 534 _spi.write(0x53);
clemente 0:e97876f96d4b 535 _spi.write(0xEF);
clemente 0:e97876f96d4b 536 _spi.write(0x6E);
clemente 0:e97876f96d4b 537 _spi.write( pitch);
clemente 0:e97876f96d4b 538 _spi.write(0x00);
clemente 0:e97876f96d4b 539 _spi.write(0x00);
clemente 0:e97876f96d4b 540 _spi.write(0x00);
clemente 0:e97876f96d4b 541 _spi.write(0x00);
clemente 0:e97876f96d4b 542 } else {
clemente 0:e97876f96d4b 543 // STOP Sine Test
clemente 0:e97876f96d4b 544 _spi.write(0x45);
clemente 0:e97876f96d4b 545 _spi.write(0x78);
clemente 0:e97876f96d4b 546 _spi.write(0x69);
clemente 0:e97876f96d4b 547 _spi.write(0x74);
clemente 0:e97876f96d4b 548 _spi.write(0x00);
clemente 0:e97876f96d4b 549 _spi.write(0x00);
clemente 0:e97876f96d4b 550 _spi.write(0x00);
clemente 0:e97876f96d4b 551 _spi.write(0x00);
clemente 0:e97876f96d4b 552 }
clemente 0:e97876f96d4b 553
clemente 0:e97876f96d4b 554 VS1053_XDCS_DISABLE;
clemente 0:e97876f96d4b 555
clemente 0:e97876f96d4b 556 }
clemente 0:e97876f96d4b 557
clemente 0:e97876f96d4b 558 void VS1053Codec::writedata( unsigned char data)
clemente 0:e97876f96d4b 559 /*
clemente 0:e97876f96d4b 560 * Write data to SDI.
clemente 0:e97876f96d4b 561 */
clemente 0:e97876f96d4b 562 {
clemente 0:e97876f96d4b 563 int i=0;
clemente 0:e97876f96d4b 564
clemente 0:e97876f96d4b 565 VS1053_XDCS_ENABLE;
clemente 0:e97876f96d4b 566 for( i=0; i<cVS1053_CS_DELAY; i++);
clemente 0:e97876f96d4b 567
clemente 0:e97876f96d4b 568 _spi.write( data);
clemente 0:e97876f96d4b 569
clemente 0:e97876f96d4b 570 for( i=0; i<cVS1053_CS_DELAY; i++);
clemente 0:e97876f96d4b 571 VS1053_XDCS_DISABLE;
clemente 0:e97876f96d4b 572
clemente 0:e97876f96d4b 573 }
clemente 0:e97876f96d4b 574
clemente 0:e97876f96d4b 575 //******************************************************************************
clemente 0:e97876f96d4b 576 //******************************************************************************
clemente 0:e97876f96d4b 577 //******************************************************************************
clemente 0:e97876f96d4b 578 // Section: Internal Functions
clemente 0:e97876f96d4b 579 //******************************************************************************
clemente 0:e97876f96d4b 580 //******************************************************************************
clemente 0:e97876f96d4b 581 //******************************************************************************
clemente 0:e97876f96d4b 582
clemente 0:e97876f96d4b 583
clemente 0:e97876f96d4b 584 unsigned short VS1053Codec::readreg(unsigned char vAddress)
clemente 0:e97876f96d4b 585 {
clemente 0:e97876f96d4b 586 unsigned short wValue;
clemente 0:e97876f96d4b 587 unsigned int i;
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(0x03); // Read
clemente 0:e97876f96d4b 593 _spi.write(vAddress); // Register address
clemente 0:e97876f96d4b 594 ((unsigned char*)&wValue)[1] = _spi.write(0xFF); // 8 bit value high byte
clemente 0:e97876f96d4b 595 ((unsigned char*)&wValue)[0] = _spi.write(0xFF); // 8 bit value 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 return wValue;
clemente 0:e97876f96d4b 601 }
clemente 0:e97876f96d4b 602
clemente 0:e97876f96d4b 603 void VS1053Codec::writereg(unsigned char vAddress, unsigned int wValue)
clemente 0:e97876f96d4b 604 {
clemente 0:e97876f96d4b 605 int i;
clemente 0:e97876f96d4b 606
clemente 0:e97876f96d4b 607 while(!_dreq);
clemente 0:e97876f96d4b 608
clemente 0:e97876f96d4b 609 VS1053_CS_ENABLE;
clemente 0:e97876f96d4b 610 for ( i=0; i<cVS1053_CS_DELAY;i++);
clemente 0:e97876f96d4b 611
clemente 0:e97876f96d4b 612 _spi.write(0x02); // Write
clemente 0:e97876f96d4b 613 _spi.write(vAddress); // Register address
clemente 0:e97876f96d4b 614 _spi.write(((unsigned char*)&wValue)[1]); // 8 bit value to write high byte
clemente 0:e97876f96d4b 615 _spi.write(((unsigned char*)&wValue)[0]); // 8 bit value to write low byte
clemente 0:e97876f96d4b 616
clemente 0:e97876f96d4b 617 for ( i=0; i<cVS1053_CS_DELAY;i++);
clemente 0:e97876f96d4b 618 VS1053_CS_DISABLE;
clemente 0:e97876f96d4b 619
clemente 0:e97876f96d4b 620 }
clemente 0:e97876f96d4b 621
clemente 0:e97876f96d4b 622
clemente 0:e97876f96d4b 623 /* */
clemente 0:e97876f96d4b 624 void VS1053Codec::reset( void)
clemente 0:e97876f96d4b 625 {
clemente 0:e97876f96d4b 626 // Reset the vs1053
clemente 0:e97876f96d4b 627 writereg(VLSI_MODE, ( cMODEREG_SET | SM_RESET) );
clemente 0:e97876f96d4b 628 wait_ms( 5);
clemente 0:e97876f96d4b 629 // Wait...
clemente 0:e97876f96d4b 630 while(!_dreq);
clemente 0:e97876f96d4b 631
clemente 0:e97876f96d4b 632 // Configure CLOCK register.
clemente 0:e97876f96d4b 633 writereg(VLSI_CLOCKF, cCLOCK_SET);
clemente 0:e97876f96d4b 634 wait_ms( 5);
clemente 0:e97876f96d4b 635 // Wait...
clemente 0:e97876f96d4b 636 while(!_dreq);
clemente 0:e97876f96d4b 637 }
clemente 0:e97876f96d4b 638
clemente 0:e97876f96d4b 639
clemente 0:e97876f96d4b 640 void VS1053Codec::writeregnowait(unsigned char vAddress, unsigned int wValue)
clemente 0:e97876f96d4b 641 /*
clemente 0:e97876f96d4b 642 Write to SCI interface without waiting for the DREQ pin
clemente 0:e97876f96d4b 643 */
clemente 0:e97876f96d4b 644 {
clemente 0:e97876f96d4b 645 int i;
clemente 0:e97876f96d4b 646
clemente 0:e97876f96d4b 647 VS1053_CS_ENABLE;
clemente 0:e97876f96d4b 648 for ( i=0; i<cVS1053_CS_DELAY;i++);
clemente 0:e97876f96d4b 649
clemente 0:e97876f96d4b 650 _spi.write(0x02); // Write
clemente 0:e97876f96d4b 651 _spi.write(vAddress); // Register address
clemente 0:e97876f96d4b 652 _spi.write(((unsigned char*)&wValue)[1]); // 8 bit value to write high byte
clemente 0:e97876f96d4b 653 _spi.write(((unsigned char*)&wValue)[0]); // 8 bit value to write low byte
clemente 0:e97876f96d4b 654
clemente 0:e97876f96d4b 655 for ( i=0; i<cVS1053_CS_DELAY;i++);
clemente 0:e97876f96d4b 656 VS1053_CS_DISABLE;
clemente 0:e97876f96d4b 657
clemente 0:e97876f96d4b 658 }
clemente 0:e97876f96d4b 659
clemente 0:e97876f96d4b 660 #ifdef __ENCODE_OGG
clemente 0:e97876f96d4b 661 void VS1053Codec::VoggEncoding_Start( void)
clemente 0:e97876f96d4b 662 /* VorbisEncoder160c pag. 9 */
clemente 0:e97876f96d4b 663 {
clemente 0:e97876f96d4b 664 unsigned short temp;
clemente 0:e97876f96d4b 665
clemente 0:e97876f96d4b 666 /* 2. vs1053b at 55.3MHz */
clemente 0:e97876f96d4b 667 writeregnowait( VLSI_CLOCKF, 0xC000); cWAIT_DREQ_1MS;
clemente 0:e97876f96d4b 668 /* 3. SCI_BASS to 0 */
clemente 0:e97876f96d4b 669 writeregnowait( VLSI_BASS, 0x0000); cWAIT_DREQ_1MS;
clemente 0:e97876f96d4b 670 /* 4. Disable user application (no wait fot DREQ pin and no delay, as from the VLSI source file example */
clemente 0:e97876f96d4b 671 /* record.c from playercode1053-Aug2009.zip */
clemente 0:e97876f96d4b 672 writeregnowait( VLSI_AIADDR, 0x0000);
clemente 0:e97876f96d4b 673 /* 5. Disable all IRQ except the SCI IRQ */
clemente 0:e97876f96d4b 674 writeregnowait( VLSI_WRAMADDR, 0xC01A);
clemente 0:e97876f96d4b 675 writeregnowait( VLSI_WRAM, 0x0002);
clemente 0:e97876f96d4b 676 /* 6. Load the plugin code... */
clemente 0:e97876f96d4b 677 loadoggpatch();
clemente 0:e97876f96d4b 678 /* 7. Set bit SM_ADPCM to 1. */
clemente 0:e97876f96d4b 679 temp = (unsigned short)readreg( VLSI_MODE); cWAIT_DREQ_1MS;
clemente 0:e97876f96d4b 680 temp |= SM_ADPCM;
clemente 0:e97876f96d4b 681 writeregnowait( VLSI_MODE, temp); cWAIT_DREQ_1MS;
clemente 0:e97876f96d4b 682 writeregnowait( VLSI_AICTRL0, 0x0000); cWAIT_DREQ_1MS;
clemente 0:e97876f96d4b 683 /* 8. Set recording level. Value are for conservative AGC. */
clemente 0:e97876f96d4b 684 writeregnowait( VLSI_AICTRL1, 0x0000); cWAIT_DREQ_1MS;
clemente 0:e97876f96d4b 685 writeregnowait( VLSI_AICTRL2, 4096); cWAIT_DREQ_1MS;
clemente 0:e97876f96d4b 686 /* 10. Set 0 to SCI_AICTRL3. */
clemente 0:e97876f96d4b 687 writeregnowait( VLSI_AICTRL3, 0x0000); cWAIT_DREQ_1MS;
clemente 0:e97876f96d4b 688 /* 11. Active the encoder... */
clemente 0:e97876f96d4b 689 wait_ms( 5);
clemente 0:e97876f96d4b 690 writeregnowait( VLSI_AIADDR, 0x0034); wait_ms( 1);
clemente 0:e97876f96d4b 691 /* 12. wait DREQ high. */
clemente 0:e97876f96d4b 692 cWAIT_DREQ; /* Loop forever. */
clemente 0:e97876f96d4b 693
clemente 0:e97876f96d4b 694 }
clemente 0:e97876f96d4b 695
clemente 0:e97876f96d4b 696 #if 0
clemente 0:e97876f96d4b 697 void VS1053Codec::VoggEncoding_ReadStatus( RUNTIME_VOGG_VALUE *status)
clemente 0:e97876f96d4b 698 /* VorbisEncoder160c par 2.3.4, pag. 11 */
clemente 0:e97876f96d4b 699 /* see VLSICodec.h for RUNTIME_VOGG_VALUE struct data. */
clemente 0:e97876f96d4b 700 {
clemente 0:e97876f96d4b 701 unsigned short temp, temph;
clemente 0:e97876f96d4b 702
clemente 0:e97876f96d4b 703 /* Recording Time */
clemente 0:e97876f96d4b 704 writereg( VLSI_WRAMADDR, 0x0008); cWAIT_DREQ_1MS;
clemente 0:e97876f96d4b 705 temp = (unsigned short)readreg( VLSI_WRAM); /* LSB recording Time */
clemente 0:e97876f96d4b 706 temph= (unsigned short)readreg( VLSI_WRAM); /* MSB recording Time */
clemente 0:e97876f96d4b 707 status->rec_time = ((unsigned long)temph << 16) | temp;
clemente 0:e97876f96d4b 708
clemente 0:e97876f96d4b 709 /* Average bitrate */
clemente 0:e97876f96d4b 710 writereg( VLSI_WRAMADDR, 0x000C); cWAIT_DREQ_1MS;
clemente 0:e97876f96d4b 711 temp = (unsigned short)readreg( VLSI_WRAM); /* LSB Average bitrate */
clemente 0:e97876f96d4b 712 temph= (unsigned short)readreg( VLSI_WRAM); /* MSB Average bitrate */
clemente 0:e97876f96d4b 713 status->average_bitrate = ((unsigned long)temph << 16) | temp;
clemente 0:e97876f96d4b 714
clemente 0:e97876f96d4b 715 /* Sample Counter */
clemente 0:e97876f96d4b 716 writereg( VLSI_WRAMADDR, 0x1800); cWAIT_DREQ_1MS;
clemente 0:e97876f96d4b 717 temp = (unsigned short)readreg( VLSI_WRAM); /* LSB Sample Counter */
clemente 0:e97876f96d4b 718 temph= (unsigned short)readreg( VLSI_WRAM); /* MSB Average bitrate */
clemente 0:e97876f96d4b 719 status->sample_counter = ((unsigned long)temph << 16) | temp;
clemente 0:e97876f96d4b 720 }
clemente 0:e97876f96d4b 721 #endif
clemente 0:e97876f96d4b 722
clemente 0:e97876f96d4b 723
clemente 0:e97876f96d4b 724 /*
clemente 0:e97876f96d4b 725 * Questa funzione legge il registro SCI_HDAT1 per verificare la presenza di
clemente 0:e97876f96d4b 726 * sample disponibili. In caso ci siano li legge dal reg. SCI_HDAT0
clemente 0:e97876f96d4b 727 * salvandoli nel puntatore passatogli. Ritorna il numero di byte copiati.
clemente 0:e97876f96d4b 728 */
clemente 0:e97876f96d4b 729 unsigned int VS1053Codec::VoggEncoding_ReadBuffer( unsigned char *voggSample)
clemente 0:e97876f96d4b 730 /* VorbisEncoder160c pag. 10 */
clemente 0:e97876f96d4b 731 {
clemente 0:e97876f96d4b 732 unsigned int i;
clemente 0:e97876f96d4b 733 unsigned short temp, sample;
clemente 0:e97876f96d4b 734
clemente 0:e97876f96d4b 735 temp=0;
clemente 0:e97876f96d4b 736 i=0;
clemente 0:e97876f96d4b 737 sample=0;
clemente 0:e97876f96d4b 738
clemente 0:e97876f96d4b 739 // printf("readbuffer\r\n");
clemente 0:e97876f96d4b 740
clemente 0:e97876f96d4b 741 do {
clemente 0:e97876f96d4b 742 /* reading the sample counter... */
clemente 0:e97876f96d4b 743 temp = (unsigned short)readreg( VLSI_HDAT1);
clemente 0:e97876f96d4b 744 if ( temp ) {
clemente 0:e97876f96d4b 745 // printf("sample %d\r\n", temp);
clemente 0:e97876f96d4b 746 /* there are samples... */
clemente 0:e97876f96d4b 747 i=0;
clemente 0:e97876f96d4b 748 while( i < temp) {
clemente 0:e97876f96d4b 749 /* read the sample as word */
clemente 0:e97876f96d4b 750 sample=(unsigned short)readreg( VLSI_HDAT0);
clemente 0:e97876f96d4b 751 /* save it into the array as single byte. */
clemente 0:e97876f96d4b 752 *voggSample++ = (unsigned char)(sample >> 8); /* MSB */
clemente 0:e97876f96d4b 753 *voggSample++ = (unsigned char)(sample & 0x00FF); /* LSB */
clemente 0:e97876f96d4b 754 i++;
clemente 0:e97876f96d4b 755 wait_ms( 1);
clemente 0:e97876f96d4b 756 }
clemente 0:e97876f96d4b 757
clemente 0:e97876f96d4b 758 /* Exit the loop. */
clemente 0:e97876f96d4b 759 break;
clemente 0:e97876f96d4b 760 } else {
clemente 0:e97876f96d4b 761 // printf("no sample\r\n");
clemente 0:e97876f96d4b 762 /* Exit the loop. */
clemente 0:e97876f96d4b 763 break;
clemente 0:e97876f96d4b 764 }
clemente 0:e97876f96d4b 765 } while( 1);
clemente 0:e97876f96d4b 766 /* just relax... */
clemente 0:e97876f96d4b 767 wait_ms( 1);
clemente 0:e97876f96d4b 768 /* Return the number of byte saved. */
clemente 0:e97876f96d4b 769 return i*2;
clemente 0:e97876f96d4b 770 }
clemente 0:e97876f96d4b 771
clemente 0:e97876f96d4b 772 /*
clemente 0:e97876f96d4b 773 * Questa funzione esegue la procedura di fine encoding memorizzando i rimanenti sample
clemente 0:e97876f96d4b 774 * nel puntatore passatogli. Ritorna il numero di sample letti.
clemente 0:e97876f96d4b 775 */
clemente 0:e97876f96d4b 776 unsigned int VS1053Codec::VoggEncoding_Stop( unsigned char *voggSample)
clemente 0:e97876f96d4b 777 /* VorbisEncoder160c pag. 11 */
clemente 0:e97876f96d4b 778 {
clemente 0:e97876f96d4b 779 unsigned int res, i, ii;
clemente 0:e97876f96d4b 780 unsigned short temp, sample;
clemente 0:e97876f96d4b 781 res=0;
clemente 0:e97876f96d4b 782 temp=0;
clemente 0:e97876f96d4b 783 sample=0;
clemente 0:e97876f96d4b 784
clemente 0:e97876f96d4b 785 /* 1. set bit 0 to 1 */
clemente 0:e97876f96d4b 786 temp = (unsigned short)readreg( VLSI_AICTRL3);
clemente 0:e97876f96d4b 787 temp |= 0x0001;
clemente 0:e97876f96d4b 788 writereg( VLSI_AICTRL3, temp);
clemente 0:e97876f96d4b 789
clemente 0:e97876f96d4b 790 /* 2. continue reading data but checking the bit 1 of VLSI_AICTRL3 reg. */
clemente 0:e97876f96d4b 791 res=0;
clemente 0:e97876f96d4b 792 do {
clemente 0:e97876f96d4b 793 /* reading the sample counter... */
clemente 0:e97876f96d4b 794 temp = (unsigned short)readreg( VLSI_HDAT1);
clemente 0:e97876f96d4b 795 if ( temp) {
clemente 0:e97876f96d4b 796 // printf("EncStop: %d\r\n", temp);
clemente 0:e97876f96d4b 797 i=0;
clemente 0:e97876f96d4b 798 while( i < temp ) {
clemente 0:e97876f96d4b 799 /* */
clemente 0:e97876f96d4b 800 sample = (unsigned short)readreg( VLSI_HDAT0);
clemente 0:e97876f96d4b 801 *voggSample++ = (unsigned char)(sample >> 8);
clemente 0:e97876f96d4b 802 *voggSample++ = (unsigned char)sample & 0x00FF;
clemente 0:e97876f96d4b 803 i++;
clemente 0:e97876f96d4b 804 wait_ms( 1);
clemente 0:e97876f96d4b 805 }
clemente 0:e97876f96d4b 806 res+=i;
clemente 0:e97876f96d4b 807 }
clemente 0:e97876f96d4b 808 /* just relax... */
clemente 0:e97876f96d4b 809 wait_ms( 1);
clemente 0:e97876f96d4b 810 temp = (unsigned short)readreg( VLSI_AICTRL3);
clemente 0:e97876f96d4b 811 /* verify the bit 1 of VLSI_AICTRL3 reg. */
clemente 0:e97876f96d4b 812 if ( temp & 0x0002) {
clemente 0:e97876f96d4b 813 // printf("Encoding STOP\r\n");
clemente 0:e97876f96d4b 814 /* encoding has finished. */
clemente 0:e97876f96d4b 815 break;
clemente 0:e97876f96d4b 816 }
clemente 0:e97876f96d4b 817 } while( 1); /* Loop forever... */
clemente 0:e97876f96d4b 818 /* 3. write the remaining word... */
clemente 0:e97876f96d4b 819 ii=0;
clemente 0:e97876f96d4b 820 do {
clemente 0:e97876f96d4b 821 temp = (unsigned short)readreg( VLSI_HDAT1);
clemente 0:e97876f96d4b 822 if ( temp) {
clemente 0:e97876f96d4b 823 // printf("Flush %d\r\n", temp);
clemente 0:e97876f96d4b 824 /* there are samples... */
clemente 0:e97876f96d4b 825 i=0;
clemente 0:e97876f96d4b 826 while( i < temp ) { /* con il numero precedente. */
clemente 0:e97876f96d4b 827 /* */
clemente 0:e97876f96d4b 828 sample = (unsigned short)readreg( VLSI_HDAT0);
clemente 0:e97876f96d4b 829 *voggSample++ = (unsigned char)(sample >> 8);
clemente 0:e97876f96d4b 830 *voggSample++ = (unsigned char)sample & 0x00FF;
clemente 0:e97876f96d4b 831 i++;
clemente 0:e97876f96d4b 832 wait_ms( 1);
clemente 0:e97876f96d4b 833 }
clemente 0:e97876f96d4b 834 res+=i;
clemente 0:e97876f96d4b 835 } else {
clemente 0:e97876f96d4b 836 wait_ms( 1);
clemente 0:e97876f96d4b 837 ii++;
clemente 0:e97876f96d4b 838 }
clemente 0:e97876f96d4b 839 } while( ii<5); /* Loops ... */
clemente 0:e97876f96d4b 840 /* 4. read twise AICTRL3 */
clemente 0:e97876f96d4b 841 temp = (unsigned short)readreg( VLSI_AICTRL3);
clemente 0:e97876f96d4b 842 temp = (unsigned short)readreg( VLSI_AICTRL3);
clemente 0:e97876f96d4b 843 // printf("last read %d\r\n", temp);
clemente 0:e97876f96d4b 844 if ( temp & 0x0004 ) {
clemente 0:e97876f96d4b 845 /* remove last byte ( bits 7:0) from the last word. */
clemente 0:e97876f96d4b 846 voggSample--;
clemente 0:e97876f96d4b 847 *voggSample=0;
clemente 0:e97876f96d4b 848 res=(res*2)-1;
clemente 0:e97876f96d4b 849 } else {
clemente 0:e97876f96d4b 850 res=res*2;
clemente 0:e97876f96d4b 851 }
clemente 0:e97876f96d4b 852 /* 5. Reset the codec. */
clemente 0:e97876f96d4b 853
clemente 0:e97876f96d4b 854 /* Ritorno il numero di sample, in byte, letti. */
clemente 0:e97876f96d4b 855 return res;
clemente 0:e97876f96d4b 856 }
clemente 0:e97876f96d4b 857 #endif