Skip to content

Commit 263d3af

Browse files
Added files missing from the last commit
1 parent 1af98fe commit 263d3af

4 files changed

Lines changed: 528 additions & 0 deletions

File tree

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#######################################
2+
# Syntax Coloring Map For VS1003
3+
#######################################
4+
5+
#######################################
6+
# Datatypes (KEYWORD1)
7+
#######################################
8+
9+
VS1003 KEYWORD1
10+
11+
#######################################
12+
# Methods and Functions (KEYWORD2)
13+
#######################################
14+
15+
begin KEYWORD2
16+
startSong KEYWORD2
17+
playChunk KEYWORD2
18+
stopSong KEYWORD2
19+
printDetails KEYWORD2
20+
modeSwitch KEYWORD2
21+
setVolume KEYWORD2
22+
23+
#######################################
24+
# Instances (KEYWORD2)
25+
#######################################
26+
27+
28+
#######################################
29+
# Constants (LITERAL1)
30+
#######################################
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
name=Serasidis_VS1003B_STM
2+
version=1.0
3+
author=Andy Karpov - ported to STM by Vasillis Serasidis. Updated by Roger Clark
4+
email=
5+
sentence=VS1003 and VS1053 MP3, MP3 player and recorder
6+
paragraph=VS1003 and VS1053 MP3, MP3 player and recorder
7+
url=
8+
architectures=STM32F1
Lines changed: 345 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,345 @@
1+
/*
2+
Copyright (C) 2012 Andy Karpov <andy.karpov@gmail.com>
3+
4+
This program is free software; you can redistribute it and/or
5+
modify it under the terms of the GNU General Public License
6+
version 2 as published by the Free Software Foundation.
7+
8+
Ported to STM32F103 by Vassilis Serasidis on 21 May 2015
9+
Home: http://www.serasidis.gr
10+
email: avrsite@yahoo.gr
11+
29 May 2015 - Added a fix for booting the VS1053B boards into
12+
mp3 decoding instead of booting into MID (modeSwitch function).
13+
*/
14+
15+
//#include <my_SPI.h>
16+
#include <VS1003_STM.h>
17+
18+
#define vs1003_chunk_size 32
19+
/****************************************************************************/
20+
21+
// VS1003 SCI Write Command byte is 0x02
22+
#define VS_WRITE_COMMAND 0x02
23+
24+
// VS1003 SCI Read COmmand byte is 0x03
25+
#define VS_READ_COMMAND 0x03
26+
27+
// SCI Registers
28+
29+
const uint8_t SCI_MODE = 0x0;
30+
const uint8_t SCI_STATUS = 0x1;
31+
const uint8_t SCI_BASS = 0x2;
32+
const uint8_t SCI_CLOCKF = 0x3;
33+
const uint8_t SCI_DECODE_TIME = 0x4;
34+
const uint8_t SCI_AUDATA = 0x5;
35+
const uint8_t SCI_WRAM = 0x6;
36+
const uint8_t SCI_WRAMADDR = 0x7;
37+
const uint8_t SCI_HDAT0 = 0x8;
38+
const uint8_t SCI_HDAT1 = 0x9;
39+
const uint8_t SCI_AIADDR = 0xa;
40+
const uint8_t SCI_VOL = 0xb;
41+
const uint8_t SCI_AICTRL0 = 0xc;
42+
const uint8_t SCI_AICTRL1 = 0xd;
43+
const uint8_t SCI_AICTRL2 = 0xe;
44+
const uint8_t SCI_AICTRL3 = 0xf;
45+
const uint8_t SCI_num_registers = 0xf;
46+
47+
// SCI_MODE bits
48+
49+
const uint8_t SM_DIFF = 0;
50+
const uint8_t SM_LAYER12 = 1;
51+
const uint8_t SM_RESET = 2;
52+
const uint8_t SM_OUTOFWAV = 3;
53+
const uint8_t SM_EARSPEAKER_LO = 4;
54+
const uint8_t SM_TESTS = 5;
55+
const uint8_t SM_STREAM = 6;
56+
const uint8_t SM_EARSPEAKER_HI = 7;
57+
const uint8_t SM_DACT = 8;
58+
const uint8_t SM_SDIORD = 9;
59+
const uint8_t SM_SDISHARE = 10;
60+
const uint8_t SM_SDINEW = 11;
61+
const uint8_t SM_ADPCM = 12;
62+
const uint8_t SM_ADCPM_HP = 13;
63+
const uint8_t SM_LINE_IN = 14;
64+
65+
// Register names
66+
67+
const char reg_name_MODE[] = "MODE";
68+
const char reg_name_STATUS[] = "STATUS";
69+
const char reg_name_BASS[] = "BASS";
70+
const char reg_name_CLOCKF[] = "CLOCKF";
71+
const char reg_name_DECODE_TIME[] = "DECODE_TIME";
72+
const char reg_name_AUDATA[] = "AUDATA";
73+
const char reg_name_WRAM[] = "WRAM";
74+
const char reg_name_WRAMADDR[] = "WRAMADDR";
75+
const char reg_name_HDAT0[] = "HDAT0";
76+
const char reg_name_HDAT1[] = "HDAT1";
77+
const char reg_name_AIADDR[] = "AIADDR";
78+
const char reg_name_VOL[] = "VOL";
79+
const char reg_name_AICTRL0[] = "AICTRL0";
80+
const char reg_name_AICTRL1[] = "AICTRL1";
81+
const char reg_name_AICTRL2[] = "AICTRL2";
82+
const char reg_name_AICTRL3[] = "AICTRL3";
83+
84+
static PGM_P const register_names[] =
85+
{
86+
reg_name_MODE,
87+
reg_name_STATUS,
88+
reg_name_BASS,
89+
reg_name_CLOCKF,
90+
reg_name_DECODE_TIME,
91+
reg_name_AUDATA,
92+
reg_name_WRAM,
93+
reg_name_WRAMADDR,
94+
reg_name_HDAT0,
95+
reg_name_HDAT1,
96+
reg_name_AIADDR,
97+
reg_name_VOL,
98+
reg_name_AICTRL0,
99+
reg_name_AICTRL1,
100+
reg_name_AICTRL2,
101+
reg_name_AICTRL3,
102+
};
103+
104+
/****************************************************************************/
105+
106+
inline void DMA1_CH3_Event() {
107+
dma1_ch3_Active = 0;
108+
dma_disable(DMA1, DMA_CH3);
109+
}
110+
111+
/****************************************************************************/
112+
113+
uint16_t VS1003::read_register(uint8_t _reg) const
114+
{
115+
uint16_t result;
116+
control_mode_on();
117+
delayMicroseconds(1); // tXCSS
118+
my_SPI.transfer(VS_READ_COMMAND); // Read operation
119+
my_SPI.transfer(_reg); // Which register
120+
result = my_SPI.transfer(0xff) << 8; // read high byte
121+
result |= my_SPI.transfer(0xff); // read low byte
122+
delayMicroseconds(1); // tXCSH
123+
await_data_request();
124+
control_mode_off();
125+
return result;
126+
}
127+
128+
/****************************************************************************/
129+
130+
void VS1003::write_register(uint8_t _reg,uint16_t _value) const
131+
{
132+
control_mode_on();
133+
delayMicroseconds(1); // tXCSS
134+
my_SPI.transfer(VS_WRITE_COMMAND); // Write operation
135+
my_SPI.transfer(_reg); // Which register
136+
my_SPI.transfer(_value >> 8); // Send hi byte
137+
my_SPI.transfer(_value & 0xff); // Send lo byte
138+
delayMicroseconds(1); // tXCSH
139+
await_data_request();
140+
control_mode_off();
141+
}
142+
143+
/****************************************************************************/
144+
145+
void VS1003::sdi_send_buffer(const uint8_t* data, size_t len)
146+
{
147+
data_mode_on();
148+
while ( len )
149+
{
150+
await_data_request();
151+
delayMicroseconds(3);
152+
153+
size_t chunk_length = min(len,vs1003_chunk_size);
154+
len -= chunk_length;
155+
while ( chunk_length-- )
156+
my_SPI.transfer(*data++);
157+
}
158+
data_mode_off();
159+
}
160+
161+
/****************************************************************************/
162+
163+
void VS1003::sdi_send_zeroes(size_t len)
164+
{
165+
data_mode_on();
166+
while ( len )
167+
{
168+
await_data_request();
169+
170+
size_t chunk_length = min(len,vs1003_chunk_size);
171+
len -= chunk_length;
172+
while ( chunk_length-- )
173+
my_SPI.transfer(0);
174+
}
175+
data_mode_off();
176+
}
177+
178+
/****************************************************************************/
179+
180+
VS1003::VS1003( uint8_t _cs_pin, uint8_t _dcs_pin, uint8_t _dreq_pin, uint8_t _reset_pin, SPIClass _spiChan):
181+
cs_pin(_cs_pin), dcs_pin(_dcs_pin), dreq_pin(_dreq_pin), reset_pin(_reset_pin), my_SPI(_spiChan)
182+
{
183+
}
184+
185+
/****************************************************************************/
186+
187+
void VS1003::begin(void)
188+
{
189+
190+
// Keep the chip in reset until we are ready
191+
pinMode(reset_pin,OUTPUT);
192+
digitalWrite(reset_pin,LOW);
193+
194+
// The SCI and SDI will start deselected
195+
pinMode(cs_pin,OUTPUT);
196+
digitalWrite(cs_pin,HIGH);
197+
pinMode(dcs_pin,OUTPUT);
198+
digitalWrite(dcs_pin,HIGH);
199+
200+
// DREQ is an input
201+
pinMode(dreq_pin,INPUT);
202+
203+
204+
// Boot VS1003
205+
//printf(("Booting VS1003...\r\n"));
206+
207+
delay(1);
208+
209+
my_SPI.begin();
210+
my_SPI.setBitOrder(MSBFIRST);
211+
my_SPI.setDataMode(SPI_MODE0);
212+
// init SPI slow mode
213+
214+
my_SPI.setClockDivider(SPI_CLOCK_DIV64); // Slow!
215+
216+
// release from reset
217+
digitalWrite(reset_pin,HIGH);
218+
219+
// Declick: Immediately switch analog off
220+
write_register(SCI_VOL,0xffff); // VOL
221+
222+
/* Declick: Slow sample rate for slow analog part startup */
223+
write_register(SCI_AUDATA,10);
224+
225+
delay(100);
226+
227+
/* Switch on the analog parts */
228+
write_register(SCI_VOL,0xfefe); // VOL
229+
230+
//printf(("VS1003 still booting\r\n"));
231+
232+
write_register(SCI_AUDATA,44101); // 44.1kHz stereo
233+
234+
write_register(SCI_VOL,0x2020); // VOL
235+
236+
// soft reset
237+
write_register(SCI_MODE, (1<<SM_SDINEW) | (1<<SM_RESET));
238+
delay(1);
239+
await_data_request();
240+
//write_register(SCI_CLOCKF,0xB800); // Experimenting with higher clock settings
241+
write_register(SCI_CLOCKF,0x6000);
242+
delay(1);
243+
await_data_request();
244+
245+
// Now you can set high speed SPI clock
246+
// 72 MHz / 16 = 4.5 MHz max is practically allowed by VS1003 SPI interface.
247+
my_SPI.setClockDivider(SPI_CLOCK_DIV16);
248+
249+
//printf(("VS1003 Set\r\n"));
250+
//printDetails();
251+
//printf(("VS1003 OK\r\n"));
252+
253+
}
254+
255+
/****************************************************************************/
256+
257+
void VS1003::setVolume(uint8_t vol) const
258+
{
259+
uint16_t value = vol;
260+
value <<= 8;
261+
value |= vol;
262+
263+
write_register(SCI_VOL,value); // VOL
264+
}
265+
266+
/****************************************************************************/
267+
268+
void VS1003::startSong(void)
269+
{
270+
sdi_send_zeroes(10);
271+
}
272+
273+
/****************************************************************************/
274+
275+
void VS1003::playChunk(const uint8_t* data, size_t len)
276+
{
277+
sdi_send_buffer(data,len);
278+
}
279+
280+
/****************************************************************************/
281+
282+
void VS1003::stopSong(void)
283+
{
284+
sdi_send_zeroes(2048);
285+
}
286+
287+
/****************************************************************************/
288+
289+
void VS1003::print_byte_register(uint8_t reg) const
290+
{
291+
const char *name = reinterpret_cast<const char*>(pgm_read_word( register_names + reg ));
292+
char extra_tab = strlen_P(name) < 5 ? '\t' : 0;
293+
//printf(("%02x %S\t%c = 0x%02x\r\n"),reg,name,extra_tab,read_register(reg));
294+
}
295+
296+
/****************************************************************************/
297+
298+
void VS1003::printDetails(void) const
299+
{
300+
//printf(("VS1003 Configuration:\r\n"));
301+
int i = 0;
302+
while ( i <= SCI_num_registers )
303+
print_byte_register(i++);
304+
}
305+
306+
/****************************************************************************/
307+
void VS1003::modeSwitch(void)
308+
{
309+
//GPIO_DDR
310+
write_register(SCI_WRAMADDR, 0xc017);
311+
write_register(SCI_WRAM, 0x0003);
312+
//GPIO_ODATA
313+
write_register(SCI_WRAMADDR, 0xc019);
314+
write_register(SCI_WRAM, 0x0000);
315+
316+
delay(100);
317+
write_register(SCI_MODE, (1<<SM_SDINEW) | (1<<SM_RESET));
318+
delay(100);
319+
}
320+
/****************************************************************************/
321+
322+
void VS1003::loadUserCode(const uint16_t* buf, size_t len) const
323+
{
324+
while (len)
325+
{
326+
uint16_t addr = pgm_read_word(buf++); len--;
327+
uint16_t n = pgm_read_word(buf++); len--;
328+
if (n & 0x8000U) { /* RLE run, replicate n samples */
329+
n &= 0x7FFF;
330+
uint16_t val = pgm_read_word(buf++); len--;
331+
while (n--) {
332+
//printf(("W %02x: %04x\r\n"),addr,val);
333+
write_register(addr, val);
334+
}
335+
} else { /* Copy run, copy n samples */
336+
while (n--) {
337+
uint16_t val = pgm_read_word(buf++); len--;
338+
//printf(("W %02x: %04x\r\n"),addr,val);
339+
write_register(addr, val);
340+
}
341+
}
342+
}
343+
}
344+
345+
/****************************************************************************/

0 commit comments

Comments
 (0)