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:
Thu Dec 26 09:14:07 2013 +0000
Revision:
4:ce980c240ae1
Parent:
3:59c27531f18e
fixed bug

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 }
ollie8 4:ce980c240ae1 493
ollie8 4:ce980c240ae1 494 void VS1053Codec::cancelplayback() {
ollie8 4:ce980c240ae1 495 unsigned int i = (unsigned short)readreg(VLSI_MODE);
ollie8 4:ce980c240ae1 496 writereg( VLSI_MODE, ( i | SM_CANCEL ));
ollie8 4:ce980c240ae1 497 }
ollie8 4:ce980c240ae1 498
clemente 0:e97876f96d4b 499 /****************************************************************************
clemente 0:e97876f96d4b 500 Function:
clemente 0:e97876f96d4b 501 void setvolume(unsigned char vRight, unsigned char vLeft)
clemente 0:e97876f96d4b 502
clemente 0:e97876f96d4b 503 Description:
clemente 0:e97876f96d4b 504 This function set volume for analog outputs on the VLSI codec.
clemente 0:e97876f96d4b 505
clemente 0:e97876f96d4b 506 Precondition:
clemente 0:e97876f96d4b 507 None
clemente 0:e97876f96d4b 508
clemente 0:e97876f96d4b 509 Parameters:
clemente 0:e97876f96d4b 510 unsigned char vRight - right channel attenuation from maximum volume, 0.5dB steps
clemente 0:e97876f96d4b 511 (0x00 = full volume, 0xFF = muted)
clemente 0:e97876f96d4b 512 unsigned char vLeft - left channel attenuation from maximum volume, 0.5dB steps
clemente 0:e97876f96d4b 513 (0x00 = full volume, 0xFF = muted)
clemente 0:e97876f96d4b 514
clemente 0:e97876f96d4b 515 Returns:
clemente 0:e97876f96d4b 516 None
clemente 0:e97876f96d4b 517
clemente 0:e97876f96d4b 518 Remarks:
clemente 0:e97876f96d4b 519 None
clemente 0:e97876f96d4b 520 ***************************************************************************/
clemente 0:e97876f96d4b 521 void VS1053Codec::setvolume(unsigned char vRight, unsigned char vLeft)
clemente 0:e97876f96d4b 522 {
clemente 0:e97876f96d4b 523 writereg(VLSI_VOL, ((unsigned int)vLeft)<<8 | vRight);
clemente 0:e97876f96d4b 524 }
clemente 0:e97876f96d4b 525
clemente 0:e97876f96d4b 526
clemente 0:e97876f96d4b 527 void VS1053Codec::sinetest( unsigned char pitch)
clemente 0:e97876f96d4b 528 {
clemente 0:e97876f96d4b 529 unsigned int i;
clemente 0:e97876f96d4b 530
clemente 0:e97876f96d4b 531 while(!_dreq);
clemente 0:e97876f96d4b 532
clemente 0:e97876f96d4b 533 i=(unsigned short)readreg( VLSI_MODE);
clemente 0:e97876f96d4b 534 writereg( VLSI_MODE, ( i | SM_TESTS ));
clemente 0:e97876f96d4b 535
clemente 0:e97876f96d4b 536 VS1053_XDCS_ENABLE;
clemente 0:e97876f96d4b 537
clemente 0:e97876f96d4b 538 if ( pitch) {
clemente 0:e97876f96d4b 539 // START Sine Test
clemente 0:e97876f96d4b 540 _spi.write(0x53);
clemente 0:e97876f96d4b 541 _spi.write(0xEF);
clemente 0:e97876f96d4b 542 _spi.write(0x6E);
clemente 0:e97876f96d4b 543 _spi.write( pitch);
clemente 0:e97876f96d4b 544 _spi.write(0x00);
clemente 0:e97876f96d4b 545 _spi.write(0x00);
clemente 0:e97876f96d4b 546 _spi.write(0x00);
clemente 0:e97876f96d4b 547 _spi.write(0x00);
clemente 0:e97876f96d4b 548 } else {
clemente 0:e97876f96d4b 549 // STOP Sine Test
clemente 0:e97876f96d4b 550 _spi.write(0x45);
clemente 0:e97876f96d4b 551 _spi.write(0x78);
clemente 0:e97876f96d4b 552 _spi.write(0x69);
clemente 0:e97876f96d4b 553 _spi.write(0x74);
clemente 0:e97876f96d4b 554 _spi.write(0x00);
clemente 0:e97876f96d4b 555 _spi.write(0x00);
clemente 0:e97876f96d4b 556 _spi.write(0x00);
clemente 0:e97876f96d4b 557 _spi.write(0x00);
clemente 0:e97876f96d4b 558 }
clemente 0:e97876f96d4b 559
clemente 0:e97876f96d4b 560 VS1053_XDCS_DISABLE;
clemente 0:e97876f96d4b 561
clemente 0:e97876f96d4b 562 }
clemente 0:e97876f96d4b 563
clemente 0:e97876f96d4b 564 void VS1053Codec::writedata( unsigned char data)
clemente 0:e97876f96d4b 565 /*
clemente 0:e97876f96d4b 566 * Write data to SDI.
clemente 0:e97876f96d4b 567 */
clemente 0:e97876f96d4b 568 {
clemente 0:e97876f96d4b 569 int i=0;
clemente 0:e97876f96d4b 570
clemente 0:e97876f96d4b 571 VS1053_XDCS_ENABLE;
clemente 0:e97876f96d4b 572 for( i=0; i<cVS1053_CS_DELAY; i++);
clemente 0:e97876f96d4b 573
clemente 0:e97876f96d4b 574 _spi.write( data);
clemente 0:e97876f96d4b 575
clemente 0:e97876f96d4b 576 for( i=0; i<cVS1053_CS_DELAY; i++);
clemente 0:e97876f96d4b 577 VS1053_XDCS_DISABLE;
clemente 0:e97876f96d4b 578
clemente 0:e97876f96d4b 579 }
clemente 0:e97876f96d4b 580
clemente 0:e97876f96d4b 581 //******************************************************************************
clemente 0:e97876f96d4b 582 //******************************************************************************
clemente 0:e97876f96d4b 583 //******************************************************************************
clemente 0:e97876f96d4b 584 // Section: Internal Functions
clemente 0:e97876f96d4b 585 //******************************************************************************
clemente 0:e97876f96d4b 586 //******************************************************************************
clemente 0:e97876f96d4b 587 //******************************************************************************
clemente 0:e97876f96d4b 588
clemente 0:e97876f96d4b 589
clemente 0:e97876f96d4b 590 unsigned short VS1053Codec::readreg(unsigned char vAddress)
clemente 0:e97876f96d4b 591 {
clemente 0:e97876f96d4b 592 unsigned short wValue;
clemente 0:e97876f96d4b 593 unsigned int i;
clemente 0:e97876f96d4b 594
clemente 0:e97876f96d4b 595 VS1053_CS_ENABLE;
clemente 0:e97876f96d4b 596 for ( i=0; i<cVS1053_CS_DELAY;i++);
clemente 0:e97876f96d4b 597
clemente 0:e97876f96d4b 598 _spi.write(0x03); // Read
clemente 0:e97876f96d4b 599 _spi.write(vAddress); // Register address
clemente 0:e97876f96d4b 600 ((unsigned char*)&wValue)[1] = _spi.write(0xFF); // 8 bit value high byte
clemente 0:e97876f96d4b 601 ((unsigned char*)&wValue)[0] = _spi.write(0xFF); // 8 bit value low byte
clemente 0:e97876f96d4b 602
clemente 0:e97876f96d4b 603 for ( i=0; i<cVS1053_CS_DELAY;i++);
clemente 0:e97876f96d4b 604 VS1053_CS_DISABLE;
clemente 0:e97876f96d4b 605
clemente 0:e97876f96d4b 606 return wValue;
clemente 0:e97876f96d4b 607 }
clemente 0:e97876f96d4b 608
clemente 0:e97876f96d4b 609 void VS1053Codec::writereg(unsigned char vAddress, unsigned int wValue)
clemente 0:e97876f96d4b 610 {
clemente 0:e97876f96d4b 611 int i;
clemente 0:e97876f96d4b 612
clemente 0:e97876f96d4b 613 while(!_dreq);
clemente 0:e97876f96d4b 614
clemente 0:e97876f96d4b 615 VS1053_CS_ENABLE;
clemente 0:e97876f96d4b 616 for ( i=0; i<cVS1053_CS_DELAY;i++);
clemente 0:e97876f96d4b 617
clemente 0:e97876f96d4b 618 _spi.write(0x02); // Write
clemente 0:e97876f96d4b 619 _spi.write(vAddress); // Register address
clemente 0:e97876f96d4b 620 _spi.write(((unsigned char*)&wValue)[1]); // 8 bit value to write high byte
clemente 0:e97876f96d4b 621 _spi.write(((unsigned char*)&wValue)[0]); // 8 bit value to write low byte
clemente 0:e97876f96d4b 622
clemente 0:e97876f96d4b 623 for ( i=0; i<cVS1053_CS_DELAY;i++);
clemente 0:e97876f96d4b 624 VS1053_CS_DISABLE;
clemente 0:e97876f96d4b 625
clemente 0:e97876f96d4b 626 }
clemente 0:e97876f96d4b 627
clemente 0:e97876f96d4b 628
clemente 0:e97876f96d4b 629 /* */
clemente 0:e97876f96d4b 630 void VS1053Codec::reset( void)
clemente 0:e97876f96d4b 631 {
clemente 0:e97876f96d4b 632 // Reset the vs1053
clemente 0:e97876f96d4b 633 writereg(VLSI_MODE, ( cMODEREG_SET | SM_RESET) );
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 // Configure CLOCK register.
clemente 0:e97876f96d4b 639 writereg(VLSI_CLOCKF, cCLOCK_SET);
clemente 0:e97876f96d4b 640 wait_ms( 5);
clemente 0:e97876f96d4b 641 // Wait...
clemente 0:e97876f96d4b 642 while(!_dreq);
clemente 0:e97876f96d4b 643 }
clemente 0:e97876f96d4b 644
clemente 0:e97876f96d4b 645
clemente 0:e97876f96d4b 646 void VS1053Codec::writeregnowait(unsigned char vAddress, unsigned int wValue)
clemente 0:e97876f96d4b 647 /*
clemente 0:e97876f96d4b 648 Write to SCI interface without waiting for the DREQ pin
clemente 0:e97876f96d4b 649 */
clemente 0:e97876f96d4b 650 {
clemente 0:e97876f96d4b 651 int i;
clemente 0:e97876f96d4b 652
clemente 0:e97876f96d4b 653 VS1053_CS_ENABLE;
clemente 0:e97876f96d4b 654 for ( i=0; i<cVS1053_CS_DELAY;i++);
clemente 0:e97876f96d4b 655
clemente 0:e97876f96d4b 656 _spi.write(0x02); // Write
clemente 0:e97876f96d4b 657 _spi.write(vAddress); // Register address
clemente 0:e97876f96d4b 658 _spi.write(((unsigned char*)&wValue)[1]); // 8 bit value to write high byte
clemente 0:e97876f96d4b 659 _spi.write(((unsigned char*)&wValue)[0]); // 8 bit value to write low byte
clemente 0:e97876f96d4b 660
clemente 0:e97876f96d4b 661 for ( i=0; i<cVS1053_CS_DELAY;i++);
clemente 0:e97876f96d4b 662 VS1053_CS_DISABLE;
clemente 0:e97876f96d4b 663
clemente 0:e97876f96d4b 664 }
clemente 0:e97876f96d4b 665
clemente 0:e97876f96d4b 666 #ifdef __ENCODE_OGG
clemente 0:e97876f96d4b 667 void VS1053Codec::VoggEncoding_Start( void)
clemente 0:e97876f96d4b 668 /* VorbisEncoder160c pag. 9 */
clemente 0:e97876f96d4b 669 {
clemente 0:e97876f96d4b 670 unsigned short temp;
clemente 0:e97876f96d4b 671
clemente 0:e97876f96d4b 672 /* 2. vs1053b at 55.3MHz */
clemente 0:e97876f96d4b 673 writeregnowait( VLSI_CLOCKF, 0xC000); cWAIT_DREQ_1MS;
clemente 0:e97876f96d4b 674 /* 3. SCI_BASS to 0 */
clemente 0:e97876f96d4b 675 writeregnowait( VLSI_BASS, 0x0000); cWAIT_DREQ_1MS;
clemente 0:e97876f96d4b 676 /* 4. Disable user application (no wait fot DREQ pin and no delay, as from the VLSI source file example */
clemente 0:e97876f96d4b 677 /* record.c from playercode1053-Aug2009.zip */
clemente 0:e97876f96d4b 678 writeregnowait( VLSI_AIADDR, 0x0000);
clemente 0:e97876f96d4b 679 /* 5. Disable all IRQ except the SCI IRQ */
clemente 0:e97876f96d4b 680 writeregnowait( VLSI_WRAMADDR, 0xC01A);
clemente 0:e97876f96d4b 681 writeregnowait( VLSI_WRAM, 0x0002);
clemente 0:e97876f96d4b 682 /* 6. Load the plugin code... */
clemente 0:e97876f96d4b 683 loadoggpatch();
clemente 0:e97876f96d4b 684 /* 7. Set bit SM_ADPCM to 1. */
clemente 0:e97876f96d4b 685 temp = (unsigned short)readreg( VLSI_MODE); cWAIT_DREQ_1MS;
clemente 0:e97876f96d4b 686 temp |= SM_ADPCM;
clemente 0:e97876f96d4b 687 writeregnowait( VLSI_MODE, temp); cWAIT_DREQ_1MS;
clemente 0:e97876f96d4b 688 writeregnowait( VLSI_AICTRL0, 0x0000); cWAIT_DREQ_1MS;
clemente 0:e97876f96d4b 689 /* 8. Set recording level. Value are for conservative AGC. */
clemente 0:e97876f96d4b 690 writeregnowait( VLSI_AICTRL1, 0x0000); cWAIT_DREQ_1MS;
clemente 0:e97876f96d4b 691 writeregnowait( VLSI_AICTRL2, 4096); cWAIT_DREQ_1MS;
clemente 0:e97876f96d4b 692 /* 10. Set 0 to SCI_AICTRL3. */
clemente 0:e97876f96d4b 693 writeregnowait( VLSI_AICTRL3, 0x0000); cWAIT_DREQ_1MS;
clemente 0:e97876f96d4b 694 /* 11. Active the encoder... */
clemente 0:e97876f96d4b 695 wait_ms( 5);
clemente 0:e97876f96d4b 696 writeregnowait( VLSI_AIADDR, 0x0034); wait_ms( 1);
clemente 0:e97876f96d4b 697 /* 12. wait DREQ high. */
clemente 0:e97876f96d4b 698 cWAIT_DREQ; /* Loop forever. */
clemente 0:e97876f96d4b 699
clemente 0:e97876f96d4b 700 }
clemente 0:e97876f96d4b 701
clemente 0:e97876f96d4b 702 #if 0
clemente 0:e97876f96d4b 703 void VS1053Codec::VoggEncoding_ReadStatus( RUNTIME_VOGG_VALUE *status)
clemente 0:e97876f96d4b 704 /* VorbisEncoder160c par 2.3.4, pag. 11 */
clemente 0:e97876f96d4b 705 /* see VLSICodec.h for RUNTIME_VOGG_VALUE struct data. */
clemente 0:e97876f96d4b 706 {
clemente 0:e97876f96d4b 707 unsigned short temp, temph;
clemente 0:e97876f96d4b 708
clemente 0:e97876f96d4b 709 /* Recording Time */
clemente 0:e97876f96d4b 710 writereg( VLSI_WRAMADDR, 0x0008); cWAIT_DREQ_1MS;
clemente 0:e97876f96d4b 711 temp = (unsigned short)readreg( VLSI_WRAM); /* LSB recording Time */
clemente 0:e97876f96d4b 712 temph= (unsigned short)readreg( VLSI_WRAM); /* MSB recording Time */
clemente 0:e97876f96d4b 713 status->rec_time = ((unsigned long)temph << 16) | temp;
clemente 0:e97876f96d4b 714
clemente 0:e97876f96d4b 715 /* Average bitrate */
clemente 0:e97876f96d4b 716 writereg( VLSI_WRAMADDR, 0x000C); cWAIT_DREQ_1MS;
clemente 0:e97876f96d4b 717 temp = (unsigned short)readreg( VLSI_WRAM); /* LSB Average bitrate */
clemente 0:e97876f96d4b 718 temph= (unsigned short)readreg( VLSI_WRAM); /* MSB Average bitrate */
clemente 0:e97876f96d4b 719 status->average_bitrate = ((unsigned long)temph << 16) | temp;
clemente 0:e97876f96d4b 720
clemente 0:e97876f96d4b 721 /* Sample Counter */
clemente 0:e97876f96d4b 722 writereg( VLSI_WRAMADDR, 0x1800); cWAIT_DREQ_1MS;
clemente 0:e97876f96d4b 723 temp = (unsigned short)readreg( VLSI_WRAM); /* LSB Sample Counter */
clemente 0:e97876f96d4b 724 temph= (unsigned short)readreg( VLSI_WRAM); /* MSB Average bitrate */
clemente 0:e97876f96d4b 725 status->sample_counter = ((unsigned long)temph << 16) | temp;
clemente 0:e97876f96d4b 726 }
clemente 0:e97876f96d4b 727 #endif
clemente 0:e97876f96d4b 728
clemente 0:e97876f96d4b 729
clemente 0:e97876f96d4b 730 /*
clemente 0:e97876f96d4b 731 * Questa funzione legge il registro SCI_HDAT1 per verificare la presenza di
clemente 0:e97876f96d4b 732 * sample disponibili. In caso ci siano li legge dal reg. SCI_HDAT0
clemente 0:e97876f96d4b 733 * salvandoli nel puntatore passatogli. Ritorna il numero di byte copiati.
clemente 0:e97876f96d4b 734 */
clemente 0:e97876f96d4b 735 unsigned int VS1053Codec::VoggEncoding_ReadBuffer( unsigned char *voggSample)
clemente 0:e97876f96d4b 736 /* VorbisEncoder160c pag. 10 */
clemente 0:e97876f96d4b 737 {
clemente 0:e97876f96d4b 738 unsigned int i;
clemente 0:e97876f96d4b 739 unsigned short temp, sample;
clemente 0:e97876f96d4b 740
clemente 0:e97876f96d4b 741 temp=0;
clemente 0:e97876f96d4b 742 i=0;
clemente 0:e97876f96d4b 743 sample=0;
clemente 0:e97876f96d4b 744
clemente 0:e97876f96d4b 745 // printf("readbuffer\r\n");
clemente 0:e97876f96d4b 746
clemente 0:e97876f96d4b 747 do {
clemente 0:e97876f96d4b 748 /* reading the sample counter... */
clemente 0:e97876f96d4b 749 temp = (unsigned short)readreg( VLSI_HDAT1);
clemente 0:e97876f96d4b 750 if ( temp ) {
clemente 0:e97876f96d4b 751 // printf("sample %d\r\n", temp);
clemente 0:e97876f96d4b 752 /* there are samples... */
clemente 0:e97876f96d4b 753 i=0;
clemente 0:e97876f96d4b 754 while( i < temp) {
clemente 0:e97876f96d4b 755 /* read the sample as word */
clemente 0:e97876f96d4b 756 sample=(unsigned short)readreg( VLSI_HDAT0);
clemente 0:e97876f96d4b 757 /* save it into the array as single byte. */
clemente 0:e97876f96d4b 758 *voggSample++ = (unsigned char)(sample >> 8); /* MSB */
clemente 0:e97876f96d4b 759 *voggSample++ = (unsigned char)(sample & 0x00FF); /* LSB */
clemente 0:e97876f96d4b 760 i++;
clemente 0:e97876f96d4b 761 wait_ms( 1);
clemente 0:e97876f96d4b 762 }
clemente 0:e97876f96d4b 763
clemente 0:e97876f96d4b 764 /* Exit the loop. */
clemente 0:e97876f96d4b 765 break;
clemente 0:e97876f96d4b 766 } else {
clemente 0:e97876f96d4b 767 // printf("no sample\r\n");
clemente 0:e97876f96d4b 768 /* Exit the loop. */
clemente 0:e97876f96d4b 769 break;
clemente 0:e97876f96d4b 770 }
clemente 0:e97876f96d4b 771 } while( 1);
clemente 0:e97876f96d4b 772 /* just relax... */
clemente 0:e97876f96d4b 773 wait_ms( 1);
clemente 0:e97876f96d4b 774 /* Return the number of byte saved. */
clemente 0:e97876f96d4b 775 return i*2;
clemente 0:e97876f96d4b 776 }
clemente 0:e97876f96d4b 777
clemente 0:e97876f96d4b 778 /*
clemente 0:e97876f96d4b 779 * Questa funzione esegue la procedura di fine encoding memorizzando i rimanenti sample
clemente 0:e97876f96d4b 780 * nel puntatore passatogli. Ritorna il numero di sample letti.
clemente 0:e97876f96d4b 781 */
clemente 0:e97876f96d4b 782 unsigned int VS1053Codec::VoggEncoding_Stop( unsigned char *voggSample)
clemente 0:e97876f96d4b 783 /* VorbisEncoder160c pag. 11 */
clemente 0:e97876f96d4b 784 {
clemente 0:e97876f96d4b 785 unsigned int res, i, ii;
clemente 0:e97876f96d4b 786 unsigned short temp, sample;
clemente 0:e97876f96d4b 787 res=0;
clemente 0:e97876f96d4b 788 temp=0;
clemente 0:e97876f96d4b 789 sample=0;
clemente 0:e97876f96d4b 790
clemente 0:e97876f96d4b 791 /* 1. set bit 0 to 1 */
clemente 0:e97876f96d4b 792 temp = (unsigned short)readreg( VLSI_AICTRL3);
clemente 0:e97876f96d4b 793 temp |= 0x0001;
clemente 0:e97876f96d4b 794 writereg( VLSI_AICTRL3, temp);
clemente 0:e97876f96d4b 795
clemente 0:e97876f96d4b 796 /* 2. continue reading data but checking the bit 1 of VLSI_AICTRL3 reg. */
clemente 0:e97876f96d4b 797 res=0;
clemente 0:e97876f96d4b 798 do {
clemente 0:e97876f96d4b 799 /* reading the sample counter... */
clemente 0:e97876f96d4b 800 temp = (unsigned short)readreg( VLSI_HDAT1);
clemente 0:e97876f96d4b 801 if ( temp) {
clemente 0:e97876f96d4b 802 // printf("EncStop: %d\r\n", temp);
clemente 0:e97876f96d4b 803 i=0;
clemente 0:e97876f96d4b 804 while( i < temp ) {
clemente 0:e97876f96d4b 805 /* */
clemente 0:e97876f96d4b 806 sample = (unsigned short)readreg( VLSI_HDAT0);
clemente 0:e97876f96d4b 807 *voggSample++ = (unsigned char)(sample >> 8);
clemente 0:e97876f96d4b 808 *voggSample++ = (unsigned char)sample & 0x00FF;
clemente 0:e97876f96d4b 809 i++;
clemente 0:e97876f96d4b 810 wait_ms( 1);
clemente 0:e97876f96d4b 811 }
clemente 0:e97876f96d4b 812 res+=i;
clemente 0:e97876f96d4b 813 }
clemente 0:e97876f96d4b 814 /* just relax... */
clemente 0:e97876f96d4b 815 wait_ms( 1);
clemente 0:e97876f96d4b 816 temp = (unsigned short)readreg( VLSI_AICTRL3);
clemente 0:e97876f96d4b 817 /* verify the bit 1 of VLSI_AICTRL3 reg. */
clemente 0:e97876f96d4b 818 if ( temp & 0x0002) {
clemente 0:e97876f96d4b 819 // printf("Encoding STOP\r\n");
clemente 0:e97876f96d4b 820 /* encoding has finished. */
clemente 0:e97876f96d4b 821 break;
clemente 0:e97876f96d4b 822 }
clemente 0:e97876f96d4b 823 } while( 1); /* Loop forever... */
clemente 0:e97876f96d4b 824 /* 3. write the remaining word... */
clemente 0:e97876f96d4b 825 ii=0;
clemente 0:e97876f96d4b 826 do {
clemente 0:e97876f96d4b 827 temp = (unsigned short)readreg( VLSI_HDAT1);
clemente 0:e97876f96d4b 828 if ( temp) {
clemente 0:e97876f96d4b 829 // printf("Flush %d\r\n", temp);
clemente 0:e97876f96d4b 830 /* there are samples... */
clemente 0:e97876f96d4b 831 i=0;
clemente 0:e97876f96d4b 832 while( i < temp ) { /* con il numero precedente. */
clemente 0:e97876f96d4b 833 /* */
clemente 0:e97876f96d4b 834 sample = (unsigned short)readreg( VLSI_HDAT0);
clemente 0:e97876f96d4b 835 *voggSample++ = (unsigned char)(sample >> 8);
clemente 0:e97876f96d4b 836 *voggSample++ = (unsigned char)sample & 0x00FF;
clemente 0:e97876f96d4b 837 i++;
clemente 0:e97876f96d4b 838 wait_ms( 1);
clemente 0:e97876f96d4b 839 }
clemente 0:e97876f96d4b 840 res+=i;
clemente 0:e97876f96d4b 841 } else {
clemente 0:e97876f96d4b 842 wait_ms( 1);
clemente 0:e97876f96d4b 843 ii++;
clemente 0:e97876f96d4b 844 }
clemente 0:e97876f96d4b 845 } while( ii<5); /* Loops ... */
clemente 0:e97876f96d4b 846 /* 4. read twise AICTRL3 */
clemente 0:e97876f96d4b 847 temp = (unsigned short)readreg( VLSI_AICTRL3);
clemente 0:e97876f96d4b 848 temp = (unsigned short)readreg( VLSI_AICTRL3);
clemente 0:e97876f96d4b 849 // printf("last read %d\r\n", temp);
clemente 0:e97876f96d4b 850 if ( temp & 0x0004 ) {
clemente 0:e97876f96d4b 851 /* remove last byte ( bits 7:0) from the last word. */
clemente 0:e97876f96d4b 852 voggSample--;
clemente 0:e97876f96d4b 853 *voggSample=0;
clemente 0:e97876f96d4b 854 res=(res*2)-1;
clemente 0:e97876f96d4b 855 } else {
clemente 0:e97876f96d4b 856 res=res*2;
clemente 0:e97876f96d4b 857 }
clemente 0:e97876f96d4b 858 /* 5. Reset the codec. */
clemente 0:e97876f96d4b 859
clemente 0:e97876f96d4b 860 /* Ritorno il numero di sample, in byte, letti. */
clemente 0:e97876f96d4b 861 return res;
clemente 0:e97876f96d4b 862 }
clemente 0:e97876f96d4b 863 #endif