Library for VS1053 chip

Committer:
clemente
Date:
Thu May 24 12:48:19 2012 +0000
Revision:
1:399afe8151de
Parent:
0:e97876f96d4b

        

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