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
VLSIcodec.cpp@3:59c27531f18e, 2013-06-11 (annotated)
- 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?
User | Revision | Line number | New 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 |