Audible "Hello" example for VS1003B + Microcontroller

Writing software for systems that use VLSI Solution's devices as slave codecs to a host microcontroller.
almen_80
User
Posts: 8
Joined: Sat 2016-12-03 15:38

Re: Audible "Hello" example for VS1003B + Microcontroller

Post by almen_80 »

Hi Panu,

The Adafruit’s schematic shows a “XTEST” connected to 3v3. In the VS1053 Datasheet XTEST should be connected to IOVDD (4.8 Analog characteristics: IOVDD=2.8V).

Could be the XTEST the cause of the issue? Is possible to check this using registers?
Attachments
Adafruit_schematic.jpg
Adafruit_schematic.jpg (180.38 KiB) Viewed 12670 times
User avatar
Panu
VSDSP Expert
Posts: 2829
Joined: Tue 2010-06-22 13:43

Re: Audible "Hello" example for VS1003B + Microcontroller

Post by Panu »

From the "MCU Howto" link below: (please read all the topics from that link)
- Note that after reset, before you set the CLOCKF register clock doubler/multiplier, the SPI bus speed must be less than 1/6 of your crystal clock. That's 2 Mbits/s for the default crystal.
Could this be the problem? What's your SPI speed? Hmm, not very high I guess if you're using software SPI...

Can you use an oscilloscope or logic analyzer to check that your SPI bus signaling is correct?
almen_80
User
Posts: 8
Joined: Sat 2016-12-03 15:38

Re: Audible "Hello" example for VS1003B + Microcontroller

Post by almen_80 »

Hi Panu,

I’m sorry but I don’t have an oscilloscope or logic analyzer. But I’m able to mount and read the SD-Card located on the Adafruit Breakout (sharing same SPI).

I’m initializing with slow SPI having 500 kHz. “FastSPI” on current PIC configuration would be maximal 4 MHz. I’m able to read and write the registers.

I attached a record of the played “Hello”. With slower “fastSPI” I get more distortion.
Attachments
record.mp3
(92.66 KiB) Downloaded 482 times
almen_80
User
Posts: 8
Joined: Sat 2016-12-03 15:38

Re: Audible "Hello" example for VS1003B + Microcontroller

Post by almen_80 »

Hi Panu,

Sorry to ask you again for advice, but I’m going out of ideas what I’m doing wrong.

The information under the link "MCU Howto" is a little different from the one described in the datasheet. I suppose that the link describes the first or minimal steps.

I re-write the code trying to follow the datasheet and looking at the provided example “player1053.c” (without optimizations).

Now I’m unable to make the sanity check, that is, reading the register SCI_AICTRL1 returns “0xFFAD” but not the one I wrote. The second registry “SCI_AICTRL2” is read as expected: "0x7E57"

Note that I'm able to read the SDCARD. I'm running the PIC at the slowest speed having SPI mode 0.

My question is if I’m configuring the SPI-Mode on the right parameters:
- From 7.1.1-datasheet I interpret that SPI-master should be configured as having CPOL=0 and CPHA=0. Is this assumption correct?

I post my code, maybe could be for interest for someone else. I would appreciate some help on this.

PS: maybe I should start a new thread?

Code: Select all

#define FCY 4000000

#include <stdio.h>
#include <stdlib.h>
#include <libpic30.h>
#include "mcc_generated_files/mcc.h"
#include "FatFS/pff.h"

unsigned char HelloMP3[] = {
    0xFF, 0xF2, 0x40, 0xC0, 0x19, 0xB7, 0x00, 0x14, 0x02, 0xE6, 0x5C, /* ..@.......\ */
    0x01, 0x92, 0x68, 0x01, 0xF1, 0x5E, 0x03, 0x08, 0xF0, 0x24, 0x80, /* ..h..^...$. */
    0x05, 0x9E, 0x20, 0xC6, 0xFC, 0x12, 0x32, 0x5C, 0xBF, 0xF9, 0xB9, /* .. ...2\... */
    0x20, 0x4A, 0x7F, 0x85, 0xEC, 0x4C, 0xCD, 0xC7, 0x27, 0xFE, 0x5C, /*  J...L..'.\ */
    0x34, 0x25, 0xCB, 0xE6, 0xFF, 0xFF, 0x8E, 0x42, 0xE1, 0xA0, 0x5E, /* 4%.....B..^ */
    0xCA, 0x6E, 0x30, 0x9F, 0xFF, 0xF8, 0xC2, 0x12, 0x84, 0xB9, 0x7C, /* .n0.......| */
    0xDC, 0x61, 0x09, 0x4A, 0x7F, 0xFF, 0xFF, 0xF9, 0x7D, 0x32, 0x51, /* .a.J....}2Q */
    0x09, 0x7C, 0xE1, 0xA5, 0x6E, 0xB4, 0xFF, 0xFF, 0xFF, 0xFF, 0xD3, /* .|..n...... */
    0x34, 0x41, 0x91, 0xF0, 0x11, 0x8F, 0x00, 0x0F, 0x81, 0x9C, 0x10, /* 4A......... */
    0xEE, 0x59, 0xCE, 0x56, 0x67, 0xFF, 0xF2, 0x42, 0xC0, 0xEC, 0x53, /* .Y.Vg..B..S */
    0x09, 0x15, 0xF9, 0xAA, 0xA8, 0x0D, 0xD9, 0x40, 0x00, 0xCA, 0x34, /* .......@..4 */
    0x53, 0xD9, 0x18, 0xAB, 0x7D, 0xF7, 0x89, 0x3F, 0x11, 0x38, 0x94, /* S...}..?.8. */
    0x82, 0x59, 0x93, 0x20, 0x6A, 0x0C, 0xEE, 0x8E, 0x58, 0xFA, 0x38, /* .Y. j...X.8 */
    0x82, 0xCA, 0xF0, 0x58, 0xBB, 0xDA, 0x0C, 0x50, 0x56, 0x1F, 0xBB, /* ...X...PV.. */
    0x18, 0x5D, 0x8B, 0x9F, 0xDA, 0x71, 0x4F, 0xFF, 0xBD, 0xFE, 0xEF, /* .]...qO.... */
    0x69, 0x36, 0x86, 0x3C, 0x50, 0xBB, 0x0A, 0x07, 0x89, 0x54, 0xF0, /* i6.<P....T. */
    0x88, 0x9F, 0x90, 0x95, 0x30, 0x94, 0x2E, 0x7E, 0xF0, 0x64, 0x96, /* ....0..~.d. */
    0x79, 0x08, 0x3E, 0x20, 0x97, 0x28, 0x34, 0x9C, 0x09, 0x7F, 0xD2, /* y.> .(4.... */
    0xC0, 0x01, 0x75, 0xF8, 0x05, 0x6B, 0x5F, 0x41, 0x17, 0x0B, 0xE7, /* ..u..k_A... */
    0xFF, 0xF2, 0x40, 0xC0, 0x61, 0xE5, 0x0B, 0x16, 0x09, 0xC6, 0xC5, /* ..@.a...... */
    0x74, 0x7B, 0xCC, 0x94, 0x7A, 0xF7, 0x80, 0x76, 0xB2, 0xD2, 0xF8, /* t{..z..v... */
    0x39, 0x06, 0x38, 0xFD, 0x71, 0xC5, 0xDE, 0x3A, 0x38, 0xBF, 0xD5, /* 9.8.q..:8.. */
    0xF7, 0x12, 0x37, 0xCB, 0xF5, 0x63, 0x0C, 0x9B, 0xCE, 0x77, 0x25, /* ..7..c...w% */
    0xED, 0xFB, 0x3D, 0x6B, 0x35, 0xF9, 0x6D, 0xD7, 0xF9, 0x2C, 0xD1, /* ..=k5.m..,. */
    0x97, 0x15, 0x87, 0x93, 0xA4, 0x49, 0x4A, 0x18, 0x16, 0x07, 0xA1, /* .....IJ.... */
    0x60, 0xF7, 0x52, 0x94, 0xDB, 0x02, 0x16, 0x70, 0xB2, 0xD8, 0x80, /* `.R....p... */
    0x30, 0xC2, 0x94, 0x40, 0x81, 0x74, 0x5A, 0x19, 0x7A, 0x80, 0x60, /* 0..@.tZ.z.` */
    0x41, 0x21, 0x46, 0x95, 0xD5, 0xC4, 0x40, 0xD2, 0x01, 0xC0, 0x01, /* A!F...@.... */
    0xDA, 0xD9, 0xA0, 0xB1, 0x01, 0xFF, 0xF2, 0x42, 0xC0, 0x82, 0x10, /* .......B... */
    0x0B, 0x12, 0xF9, 0x9E, 0xC9, 0x7E, 0x7A, 0xC6, 0x95, 0x55, 0x09, /* .....~z..U. */
    0x8B, 0x19, 0x5E, 0x8B, 0x26, 0xCA, 0xEB, 0x68, 0x8A, 0x05, 0x8F, /* ..^.&..h... */
    0x36, 0xA5, 0xA5, 0x03, 0xB8, 0x9C, 0xED, 0x24, 0x51, 0x59, 0x90, /* 6......$QY. */
    0xF6, 0xC5, 0x7D, 0xB5, 0xAD, 0xAF, 0xF6, 0x3B, 0x18, 0xEF, 0x3F, /* ..}....;..? */
    0xFF, 0xFF, 0x4E, 0xDE, 0x16, 0x66, 0x0B, 0xAA, 0x33, 0x23, 0xDD, /* ..N..f..3#. */
    0x9C, 0x4E, 0x6E, 0x55, 0x22, 0x9D, 0xA2, 0x40, 0xA6, 0x36, 0x31, /* .NnU"..@.61 */
    0x69, 0xA5, 0xE1, 0xD9, 0x7F, 0xF7, 0xC6, 0xCC, 0x48, 0x00, 0x0E, /* i.......H.. */
    0x90, 0x16, 0x00, 0x0F, 0xDE, 0x6E, 0x80, 0x11, 0x0C, 0x9A, 0x4F, /* .....n....O */
    0x56, 0xDB, 0x88, 0xD3, 0xB2, 0x1C, 0x00, 0xE0, 0x2E, 0x3E, 0xAC, /* V........>. */
    0xFF, 0xF2, 0x40, 0xC0, 0x1C, 0xE5, 0x19, 0x13, 0x31, 0x4E, 0xCD, /* ..@.....1N. */
    0x9E, 0xC3, 0x06, 0x71, 0x03, 0x85, 0xE5, 0xB5, 0x6D, 0x88, 0x50, /* ...q....m.P */
    0x8E, 0x0E, 0x17, 0x3B, 0x19, 0xFB, 0x4E, 0x3B, 0x99, 0xEF, 0x4C, /* ...;..N;..L */
    0x9E, 0xF7, 0x7B, 0x31, 0x7C, 0x3C, 0x5F, 0xFF, 0xF4, 0xF8, 0xE3, /* ..{1|<_.... */
    0x92, 0x42, 0x07, 0x8E, 0x83, 0x8E, 0x0F, 0x05, 0x08, 0x91, 0xA3, /* .B......... */
    0x16, 0xE2, 0xDF, 0xB7, 0x62, 0x60, 0x48, 0x31, 0x3C, 0xFF, 0xD4, /* ....b`H1<.. */
    0x9E, 0x0C, 0x68, 0x00, 0x77, 0x54, 0xE3, 0x1E, 0x05, 0xC5, 0xF8, /* ..h.wT..... */
    0xEA, 0x8D, 0x82, 0x9D, 0x08, 0xA9, 0x06, 0x8D, 0x1E, 0x5D, 0x7C, /* .........]| */
    0x7F, 0x08, 0xC0, 0x50, 0x45, 0x42, 0xD0, 0x36, 0xF8, 0xB2, 0x4D, /* ...PEB.6..M */
    0x53, 0x0C, 0x80, 0x3B, 0x4D, 0xFF, 0xF2, 0x42, 0xC0, 0x2F, 0x3C, /* S..;M..B./< */
    0x25, 0x19, 0x29, 0xFE, 0xBC, 0x2E, 0xC4, 0xD0, 0x99, 0x4C, 0x48, /* %.)......LH */
    0xB0, 0x9C, 0x49, 0xD2, 0x1A, 0x2D, 0x02, 0xC2, 0x79, 0x69, 0x16, /* ..I..-..yi. */
    0x92, 0xA8, 0xC5, 0xAB, 0x45, 0x5A, 0x68, 0xE8, 0x75, 0x57, 0xCD, /* ....EZh.uW. */
    0xF1, 0xB9, 0xAA, 0x13, 0x88, 0xE4, 0x87, 0x42, 0x15, 0xB3, 0x58, /* .......B..X */
    0xF5, 0xA3, 0x46, 0xB1, 0xCF, 0xD3, 0x59, 0x7E, 0xBA, 0xB5, 0xA7, /* ..F...Y~... */
    0x6B, 0x0B, 0x17, 0x57, 0x6B, 0x5C, 0x4A, 0xCD, 0x53, 0x76, 0x2A, /* k..Wk\J.Sv* */
    0x1D, 0x28, 0xC5, 0x1C, 0x76, 0x5C, 0xDD, 0x0A, 0x00, 0x4B, 0xC0, /* .(..v\...K. */
    0x1B, 0xCA, 0xA8, 0xE9, 0x81, 0x5B, 0xA6, 0xDC, 0xA4, 0x59, 0x13, /* .....[...Y. */
    0xFC, 0xBA, 0x8F, 0x98, 0x79, 0x44, 0x25, 0xC9, 0x35, 0x38, 0xCA, /* ....yD%.58. */
    0xFF, 0xF2, 0x40, 0xC0, 0xB9, 0x7D, 0x1A, 0x13, 0x79, 0x6A, 0xC8, /* ..@..}..yj. */
    0x3E, 0xC4, 0x46, 0x94, 0x8D, 0x3C, 0x67, 0x85, 0xB1, 0xA8, 0x89, /* >.F..<g.... */
    0xC0, 0xF2, 0xE6, 0x2F, 0x9D, 0x7C, 0xC9, 0xB4, 0xBE, 0xCF, 0xE1, /* .../.|..... */
    0x7D, 0xFE, 0x1F, 0x03, 0x00, 0x12, 0x84, 0x72, 0x8C, 0xE7, 0xD8, /* }......r... */
    0x5E, 0xC9, 0xA9, 0x01, 0xBA, 0x9B, 0xC4, 0x10, 0x5C, 0x70, 0x2E, /* ^.......\p. */
    0x6C, 0x48, 0xE7, 0x8C, 0x15, 0x0B, 0x06, 0x01, 0xE5, 0xFF, 0xFF, /* lH......... */
    0xD4, 0x0D, 0x00, 0x0F, 0xCE, 0x58, 0x95, 0x61, 0xA8, 0x9E, 0x7B, /* .....X.a..{ */
    0x19, 0x98, 0xB0, 0xF0, 0xC6, 0x72, 0x82, 0xD5, 0x27, 0x06, 0x47, /* .....r..'.G */
    0x41, 0x22, 0x0F, 0x65, 0x93, 0xC9, 0x8A, 0x09, 0x19, 0x48, 0x1B, /* A".e.....H. */
    0xBD, 0xD6, 0x64, 0x1A, 0xAC, 0xFF, 0xF2, 0x42, 0xC0, 0xF1, 0x11, /* ..d....B... */
    0x25, 0x14, 0x22, 0x06, 0xBC, 0x0E, 0xD4, 0x4E, 0x99, 0x90, 0xA8, /* %."....N... */
    0xD8, 0xB7, 0xAD, 0x5D, 0x3E, 0xAF, 0x6E, 0xBE, 0x66, 0x83, 0xA4, /* ...]>.n.f.. */
    0xE3, 0xC2, 0xE0, 0x29, 0x43, 0x87, 0x5F, 0x4F, 0x27, 0x9C, 0x2C, /* ...)C._O'., */
    0xD0, 0x91, 0xF3, 0x87, 0x9B, 0x54, 0xED, 0xD1, 0xB4, 0xF3, 0x39, /* .....T....9 */
    0x87, 0x22, 0x06, 0x86, 0x0D, 0x71, 0xE4, 0x6F, 0x2A, 0x08, 0x04, /* ."...q.o*.. */
    0xC0, 0x03, 0x2A, 0xB1, 0xE2, 0x05, 0x4D, 0x64, 0xA1, 0x9C, 0xA6, /* ..*...Md... */
    0x0D, 0x41, 0xA6, 0xF2, 0x7A, 0xC1, 0x30, 0xC3, 0x38, 0x26, 0x09, /* .A..z.0.8&. */
    0x50, 0x08, 0xC4, 0xF6, 0x30, 0x0C, 0xA6, 0xA9, 0x17, 0x00, 0x13, /* P...0...... */
    0x0C, 0xDC, 0xC4, 0x2F, 0x28, 0xEB, 0x3F, 0xCD, 0x7A, 0x3D, 0x2F, /* .../(.?.z=/ */
    0xFF, 0xF2, 0x40, 0xC0, 0x18, 0x6F, 0x2E, 0x13, 0xA1, 0xF2, 0xBC, /* ..@..o..... */
    0x36, 0xCB, 0x4E, 0x99, 0x6E, 0xFC, 0xEE, 0xC5, 0xF0, 0xA0, 0xB7, /* 6.N.n...... */
    0x92, 0xD4, 0xEE, 0x79, 0x7C, 0x50, 0x5D, 0xE5, 0x04, 0x94, 0xA9, /* ...y|P].... */
    0x76, 0xCF, 0x6C, 0x70, 0xDD, 0x0D, 0xD4, 0xEE, 0xED, 0x98, 0xE8, /* v.lp....... */
    0xC8, 0x35, 0x36, 0x7A, 0x0C, 0x05, 0x80, 0x03, 0xBC, 0xBE, 0x91, /* .56z....... */
    0x00, 0x7C, 0xAE, 0x65, 0xB8, 0x91, 0xA3, 0x33, 0xBA, 0x68, 0x60, /* .|.e...3.h` */
    0xD4, 0x1A, 0x66, 0xF8, 0x43, 0xA0, 0x20, 0x89, 0xE7, 0x80, 0xD8, /* ..f.C. .... */
    0x1E, 0x4F, 0xA0, 0x04, 0x60, 0x06, 0x0A, 0xA4, 0x91, 0x24, 0xFA, /* .O..`....$. */
    0x9F, 0x57, 0x53, 0xF4, 0x7A, 0xDB, 0x5F, 0x56, 0xE3, 0x6E, 0x0B, /* .WS.z._V.n. */
    0x8B, 0x3A, 0x1C, 0xF9, 0x5E, 0xFF, 0xF2, 0x42, 0xC0, 0xB1, 0x00, /* .:..^..B... */
    0x38, 0x14, 0x09, 0xEE, 0xB4, 0x36, 0xD3, 0x4E, 0x99, 0xA4, 0x78, /* 8....6.N..x */
    0x94, 0x73, 0xC4, 0x66, 0x30, 0xF5, 0xEA, 0xDB, 0xBA, 0x67, 0x67, /* .s.f0....gg */
    0x95, 0x6B, 0xAB, 0x68, 0x5D, 0x08, 0xA1, 0x39, 0x56, 0xAB, 0x1E, /* .k.h]..9V.. */
    0xD5, 0x03, 0xE8, 0x01, 0x70, 0x00, 0xB3, 0x93, 0x33, 0x19, 0x8C, /* ....p...3.. */
    0x61, 0x8F, 0xBB, 0x5D, 0x24, 0x12, 0x63, 0xD3, 0x4B, 0x5D, 0x91, /* a..]$.c.K]. */
    0x08, 0x43, 0x22, 0x56, 0x1A, 0xC5, 0x10, 0x21, 0x84, 0xA8, 0xEA, /* .C"V...!... */
    0x80, 0xBF, 0x16, 0x8E, 0x3D, 0x46, 0x18, 0x9C, 0x6E, 0x9A, 0x91, /* ....=F..n.. */
    0xE6, 0xC9, 0x6F, 0xD2, 0x7D, 0x27, 0xD7, 0xE9, 0x6B, 0xFF, 0x0A, /* ..o.}'..k.. */
    0x03, 0x43, 0x89, 0xD5, 0xBF, 0x52, 0x97, 0x0A, 0x25, 0x95, 0x0D, /* .C...R..%.. */
    0xFF, 0xF2, 0x40, 0xC0, 0xF5, 0xC3, 0x41, 0x13, 0x81, 0xEE, 0xA8, /* ..@...A.... */
    0x5E, 0xD3, 0x44, 0x98, 0xFC, 0xCF, 0x97, 0xF9, 0x58, 0xB5, 0x33, /* ^.D.....X.3 */
    0xB1, 0x85, 0x47, 0x86, 0xD7, 0x98, 0x01, 0x3B, 0xA3, 0x4F, 0x7E, /* ..G....;.O~ */
    0x04, 0xA6, 0xC3, 0x39, 0x21, 0x70, 0x27, 0x62, 0xB5, 0x18, 0x10, /* ...9!p'b... */
    0x09, 0x99, 0x00, 0x8B, 0x7E, 0xF2, 0xBF, 0x52, 0x18, 0x26, 0x30, /* ....~..R.&0 */
    0x1C, 0xB0, 0x01, 0x49, 0x30, 0xE0, 0xC3, 0x11, 0x46, 0x05, 0xCC, /* ...I0...F.. */
    0x49, 0x14, 0x28, 0xB2, 0xED, 0x4B, 0x57, 0x5A, 0x2F, 0xB7, 0x46, /* I.(..KWZ/.F */
    0x63, 0x34, 0xD2, 0xDA, 0x9F, 0x56, 0x32, 0xB7, 0xA2, 0x25, 0xFF, /* c4...V2..%. */
    0x94, 0x28, 0x33, 0x7F, 0x3B, 0xC4, 0x50, 0xEC, 0xB1, 0xE2, 0x26, /* .(3.;.P...& */
    0xA1, 0xB7, 0x07, 0x7F, 0xFB, 0xFF, 0xF2, 0x42, 0xC0, 0x67, 0x6A, /* .......B.gj */
    0x4C, 0x13, 0xF9, 0x6A, 0x90, 0x7E, 0xDB, 0x44, 0x94, 0x3F, 0xFF, /* L..j.~.D.?. */
    0x14, 0xD6, 0x2A, 0xFF, 0xFF, 0xC1, 0x34, 0x8C, 0x48, 0x22, 0x00, /* ..*...4.H". */
    0x06, 0x8F, 0x21, 0xFD, 0x64, 0x60, 0x04, 0x92, 0x42, 0xEA, 0x74, /* ..!.d`..B.t */
    0x32, 0x37, 0xAA, 0x5A, 0x9F, 0x67, 0x01, 0x8B, 0x3F, 0x37, 0x31, /* 27.Z.g..?71 */
    0xDD, 0x06, 0x3C, 0x01, 0x34, 0x30, 0xE0, 0x5C, 0x78, 0x78, 0xCB, /* ..<.40.\xx. */
    0xD6, 0xF1, 0x31, 0x8A, 0x69, 0x61, 0x93, 0x92, 0x42, 0xCE, 0x4B, /* ..1.ia..B.K */
    0xC5, 0x02, 0x4E, 0x73, 0xC6, 0x24, 0x30, 0xCD, 0x08, 0x66, 0xC6, /* ..Ns.$0..f. */
    0x35, 0xAB, 0xA2, 0x3D, 0x2F, 0xB3, 0xBD, 0x34, 0x87, 0x13, 0xEE, /* 5..=/..4... */
    0x71, 0x45, 0x68, 0xFA, 0xEA, 0x05, 0x84, 0x41, 0x36, 0x4C, 0x9A, /* qEh....A6L. */
    0xFF, 0xF2, 0x40, 0xC0, 0xC9, 0x92, 0x56, 0x13, 0xD0, 0x6E, 0x70, /* ..@...V..np */
    0x54, 0xD3, 0xCC, 0x28, 0x06, 0xD7, 0x0E, 0xA4, 0x1D, 0x9C, 0x9D, /* T..(....... */
    0xD9, 0xA9, 0x88, 0x7B, 0xB5, 0xA3, 0x56, 0xB7, 0x4B, 0x4B, 0x5A, /* ...{..V.KKZ */
    0x9B, 0x2C, 0xA9, 0xAD, 0x6F, 0x99, 0x6C, 0xC0, 0x4C, 0x14, 0x14, /* .,..o.l.L.. */
    0xEF, 0xB4, 0x20, 0x91, 0x5F, 0xBC, 0x81, 0x41, 0x41, 0x5D, 0xD4, /* .. ._..AA]. */
    0x20, 0xBD, 0x05, 0x1A, 0x6F, 0xE2, 0x68, 0x56, 0x41, 0x41, 0x57, /*  ...o.hVAAW */
    0xF9, 0xBF, 0x89, 0x82, 0x8E, 0xC7, 0x8F, 0x0A, 0x0A, 0x09, 0x37, /* ..........7 */
    0xF1, 0x05, 0x0A, 0x0A, 0x0A, 0x0A, 0x09, 0x05, 0x37, 0xFF, 0x10, /* ........7.. */
    0x50, 0x50, 0x53, 0x65, 0xFF, 0xFF, 0xFD, 0x75, 0xDF, 0xFF, 0xFF, /* PPSe...u... */
    0x68, 0x4F, 0xFF, 0x84, 0x70, 0xFF, 0xF2, 0x42, 0xC0, 0x27, 0x50, /* hO..p..B.'P */
    0x5F, 0x17, 0xE8, 0x82, 0x3C, 0x11, 0x58, 0x18, 0x01, 0x55, 0x48, /* _...<.X..UH */
    0xBC, 0x52, 0xFC, 0x4A, 0x4C, 0x3C, 0xD5, 0xF6, 0x11, 0x2D, 0xBF, /* .R.JL<...-. */
    0xEA, 0x03, 0x5C, 0x57, 0x29, 0xBF, 0xC3, 0x75, 0x1C, 0xE6, 0xDD, /* ..\W)..u... */
    0xBF, 0xED, 0xEF, 0xD0, 0x98, 0x77, 0x71, 0x95, 0x73, 0xFF, 0xED, /* .....wq.s.. */
    0x54, 0xBE, 0xD5, 0xEE, 0xAE, 0xC2, 0xD5, 0x0B, 0xFF, 0xF1, 0x97, /* T.......... */
    0x8A, 0xE4, 0x42, 0x09, 0x99, 0xB1, 0xEA, 0x94, 0xDC, 0x78, 0xB5, /* ..B......x. */
    0x34, 0x0F, 0xF1, 0x8F, 0xFC, 0x15, 0xF6, 0xFA, 0xB1, 0x47, 0xA9, /* 4........G. */
    0x6C, 0x67, 0x43, 0x8B, 0xF2, 0x76, 0x22, 0xED, 0xDA, 0x85, 0xBA, /* lgC..v".... */
    0x2F, 0xC7, 0xF9, 0xCF, 0xFC, 0xDB, 0x46, 0x2E, 0x50, 0x0A, 0x84, /* /.....F.P.. */
    0xFF, 0xF2, 0x40, 0xC0, 0xC6, 0x4A, 0x59, 0x28, 0x2B, 0x19, 0xE0, /* ..@..JY(+.. */
    0x01, 0x89, 0x78, 0x00, 0x52, 0x85, 0x3C, 0x8E, 0x54, 0x9A, 0x48, /* ..x.R.<.T.H */
    0x5A, 0x72, 0x32, 0x94, 0xBF, 0x43, 0x4F, 0x24, 0x53, 0x4B, 0xEC, /* Zr2..CO$SK. */
    0x4B, 0x99, 0x0E, 0x66, 0x1F, 0xFF, 0xCE, 0x7F, 0xFF, 0x3F, 0x10, /* K..f.....?. */
    0xAE, 0x82, 0x62, 0x71, 0x34, 0x18, 0x59, 0x9B, 0x51, 0xC7, 0x59, /* ..bq4.Y.Q.Y */
    0xCE, 0xEE, 0xA5, 0xFE, 0x02, 0xBB, 0x30, 0x91, 0x49, 0xD5, 0x4B, /* ......0.I.K */
    0xF3, 0xDC, 0x9A, 0xA9, 0x57, 0x8E, 0x72, 0x10, 0xC0, 0x5D, 0x60, /* ....W.r..]` */
    0x67, 0xFC, 0x7D, 0xD6, 0xBA, 0xDD, 0xB3, 0x8B, 0x5A, 0x0A, 0x4C, /* g.}.....Z.L */
    0x41, 0x4D, 0x45, 0x33, 0x2E, 0x39, 0x33, 0xAA, 0xAA, 0xAA, 0xAA, /* AME3.93.... */
    0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x54, 0x41, 0x47, 0x48, 0x65, 0x6C, /* .....TAGHel */
    0x6C, 0x6F, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, /* lo          */
    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, /*             */
    0x20, 0x20, 0x20, 0x20, 0x20, 0x50, 0x61, 0x6E, 0x75, 0x2D, 0x4B, /*      Panu-K */
    0x72, 0x69, 0x73, 0x74, 0x69, 0x61, 0x6E, 0x20, 0x50, 0x6F, 0x69, /* ristian Poi */
    0x6B, 0x73, 0x61, 0x6C, 0x6F, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, /* ksalo       */
    0x20, 0x20, 0x56, 0x53, 0x44, 0x53, 0x50, 0x20, 0x54, 0x65, 0x73, /*   VSDSP Tes */
    0x74, 0x69, 0x6E, 0x67, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, /* ting        */
    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, /*             */
    0x20, 0x20, 0x20, 0x4D, 0x50, 0x33, 0x20, 0x48, 0x65, 0x6C, 0x6C, /*    MP3 Hell */
    0x6F, 0x2C, 0x20, 0x57, 0x6F, 0x72, 0x6C, 0x64, 0x21, 0x20, 0x20, /* o, World!   */
    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, /*             */
    0x00, /* . */
};

// VS10XX Operations //
#define VS_WRITE_COMMAND 0x02 /** VS10xx SCI Write Command byte is 0x02 */
#define VS_READ_COMMAND 0x03 /** VS10xx SCI Read Command byte is 0x03 */

/* SCI registers */

#define SCI_MODE        0x00
#define SCI_STATUS      0x01
#define SCI_CLOCKF      0x03
#define SCI_WRAM        0x06
#define SCI_WRAMADDR    0x07
#define SCI_HDAT0       0x08 /* VS1063, VS1053, VS1033, VS1003, VS1011 */
#define SCI_HDAT1       0x09 /* VS1063, VS1053, VS1033, VS1003, VS1011 */
#define SCI_VOL         0x0B
#define SCI_AICTRL1     0x0D /* VS1063, VS1053, VS1033, VS1003, VS1011 */
#define SCI_AICTRL2     0x0E

#define SM_RESET          (1<< 2)
#define SM_CANCEL         (1<< 3) /* VS1063, VS1053 */
#define SM_TESTS          (1<< 5)
#define SM_SDINEW         (1<<11)


/* Following are for VS1053 and VS1063 */
#define SC_MULT_53_35X 0x8000

/* Following are for VS1053 and VS1063 */
#define SC_ADD_53_10X 0x0800

#define PAR_END_FILL_BYTE 0x1e06 /* VS1063, VS1053 */

/* The following macro is for VS1063, VS1053, VS1033, VS1003, VS1103.
   Divide hz by two when calling if SM_CLK_RANGE = 1 */
#define HZ_TO_SC_FREQ(hz) (((hz)-8000000+2000)/4000)

// on reset VS1053 needs slow SPI
unsigned int fastSpeed = 0x0004;

/*
 * 7.4.4 SCI Timing Diagram 
 * Because tWL + tWH + tH is 6×CLKI + 25 ns, the maximum speed for SCI reads is CLKI/7
 */
void setSPISlowSpeed() {
    SPI1BRGL = 0x0004;
}

void setSPIFastSpeed() {
    SPI1BRGL = fastSpeed;
}

/*
 * 7.4.2 SCI Write
 *
 * @param addressbyte
 * @param highbyte
 * @param lowbyte
 */
void writeRegister(unsigned char addressbyte, unsigned char highbyte, unsigned char lowbyte) {
    setSPIFastSpeed();
    while (!DREQ_GetValue()); //Wait for after IC is available
    XCS_SetLow(); //Select CS

    // 1. instruction byte
    // 2. address byte
    // 3. write 16-bit data word.
    SPI1_Exchange8bit(VS_WRITE_COMMAND);
    SPI1_Exchange8bit(addressbyte);
    SPI1_Exchange8bit(highbyte);
    SPI1_Exchange8bit(lowbyte);
    /*
     * Note: VS1053b sets DREQ low after each SCI operation. The duration depends 
     * on the operation. It is not allowed to finish a new SCI/SDI operation 
     * before DREQ is high again.
     */
    while (!DREQ_GetValue());

    XCS_SetHigh(); //Deselect CS
}

/**
 * 
 * @param addressbyte
 * @param data
 */
void writeRegister16(unsigned char addressbyte, unsigned int data) {
    writeRegister(addressbyte, data >> 8, data & 0xFF);
}

/**
 * 
 * @param addressbyte
 * @return 
 */
unsigned int readRegister(unsigned char addressbyte) {
    setSPISlowSpeed();
    while (!DREQ_GetValue()); //Wait for after IC is available
    XCS_SetLow(); // Select CS

    // 1. instruction byte
    // 2. address byte
    // 3. read 16-bit data word.
    SPI1_Exchange8bit(VS_READ_COMMAND); //Read instruction
    SPI1_Exchange8bit(addressbyte);

    char firstByte = SPI1_Exchange8bit(0xFF); //Read the first byte
    while (!DREQ_GetValue()); //Wait after command is complete
    char secondByte = SPI1_Exchange8bit(0xFF); //Read the second byte
    while (!DREQ_GetValue()); //Wait after command is complete

    XCS_SetHigh(); //Deselect CS

    return (firstByte << 8) | secondByte;
}

/*
  Read 16-bit value from addr.
 */
unsigned int readRegister16(unsigned short addr) {
    writeRegister16(SCI_WRAMADDR, addr);
    return readRegister(SCI_WRAM);
}

int reset() {
    fastSpeed = 0x0004;
    XCS_SetHigh(); //Deselect CS
    XDCS_SetHigh(); //Deselect DCS

    XRESET_SetLow(); // reset
    SPI1_Exchange8bit(0xFF); // dummy byte
    __delay_ms(10);
    XRESET_SetHigh(); // back from reset

    __delay_ms(10);

    // volume(20 = -10dB
    writeRegister(SCI_VOL, 20, 20);

    writeRegister16(SCI_MODE, SM_SDINEW | SM_TESTS | SM_RESET);
    __delay_ms(100);


    /* A quick sanity check: write to two registers, then test if we
     get the same results. Note that if you use a too high SPI
     speed, the MSB is the most likely to fail when read again. */
    writeRegister16(SCI_AICTRL1, 0xABAD);
    writeRegister16(SCI_AICTRL2, 0x7E57);
    unsigned int SCI_AICTRL1_V = readRegister(SCI_AICTRL1);
    unsigned int SCI_AICTRL2_V = readRegister(SCI_AICTRL2);
    if (SCI_AICTRL1_V != 0xABAD || SCI_AICTRL2_V != 0x7E57) {
        //There is something wrong with VS10xx SCI registers
        return 0;
    }
    writeRegister16(SCI_AICTRL1, 0);
    writeRegister16(SCI_AICTRL2, 0);

    //status of the VS1053 ?
    unsigned int status = readRegister(SCI_STATUS);
    // 1001, 1011, 1011, 1003, 1053, 1033, 1063, 1103
    if (((status >> 4) & 15) != 4) {
        // something wrong
        return 0;
    }

    // current clock (for debug)
    unsigned int clock = readRegister(SCI_CLOCKF);

    /* Set the clock. Until this point we need to run SPI slow so that
     we do not exceed the maximum speeds mentioned in
     Chapter SPI Timing Diagram in the Datasheet. */
    writeRegister16(SCI_CLOCKF,
            HZ_TO_SC_FREQ(12288000) | SC_MULT_53_35X | SC_ADD_53_10X);

    // new MP3 clock (for debug)
    clock = readRegister(SCI_CLOCKF);

    fastSpeed = 0x0001;

    // volume
    int volValue = readRegister(SCI_VOL);
    if ((volValue >> 8) != 20 && (volValue & 0xFF) != 20) {
        // something wrong
        return 0;
    }

    return 1;
}

void play(unsigned char* data, unsigned int len) {
    unsigned char *p;
    unsigned int readEndFillByte;
    int i, j, endFillByte;
    readEndFillByte = len / 2;
    p = &data[0]; // Point "p" to the beginning of array
    while (i < len) {
        // 10.5.1 Playing a Whole File
        //1. Send an audio file to VS1053b
        while (!DREQ_GetValue()) {
            //DREQ is low while the receive buffer is full
            //You can do something else here, the bus is free...
            //Maybe set the volume or whatever...
        }

        //Once DREQ is released (high) we can now send 32 bytes of data
        XDCS_SetLow(); //Select Data
        SPI1_Exchange8bit(*p++); // Send SPI byte
        i++;
        XDCS_SetHigh(); //Deselect Data
        if (i > readEndFillByte) {
            // 2. Read extra parameter value endFillByte (Chapter 10.11)
            endFillByte = readRegister16(PAR_END_FILL_BYTE);
            readEndFillByte = len + 1;
        }
    }
    // 3. Send at least 2052 bytes of endFillByte[7:0].
    XDCS_SetLow();
    for (i = 0; i < 2052; i++) {
        while (!DREQ_GetValue()); // wait here until DREQ is high again
        SPI1_Exchange8bit(endFillByte);
    }
    XDCS_SetHigh();

    //4. Set SCI_MODE bit SM_CANCEL.
    unsigned int sciMode_V = readRegister(SCI_MODE);
    writeRegister16(SCI_MODE, sciMode_V | SM_CANCEL);

    // 5. Send at least 32 bytes of endFillByte[7:0]
    XDCS_SetLow();
    for (j = 0; j < 32; j++) {
        while (!DREQ_GetValue()); // wait here until DREQ is high again
        SPI1_Exchange8bit(endFillByte);
    }
    XDCS_SetHigh();
    
    // 6.A) Read SCI_MODE. If SM_CANCEL is still set, go to 5. 
    i = 0;
    sciMode_V = readRegister(SCI_MODE);
    while (((sciMode_V & SM_CANCEL) == SM_CANCEL) && i < 2048) {
        XDCS_SetLow();
        for (j = 0; j < 32; j++) {
            while (!DREQ_GetValue()); // wait here until DREQ is high again
            SPI1_Exchange8bit(endFillByte);
        }
        i += 32;
        XDCS_SetHigh();
        sciMode_V = readRegister(SCI_MODE);
    }
    while (!DREQ_GetValue());

    // 6.B) If SM_CANCEL hasn't cleared after sending 2048 bytes, do a software 
    //      reset (this should be extremely rare).
    if ((readRegister(SCI_MODE) & SM_CANCEL) == SM_CANCEL) {
        if (!reset()) {
            // something wrong, loop
            while (1);
        }
    }

    // 7. The song has now been successfully sent. HDAT0 and HDAT1 should now both
    //    contain 0 to indicate that no format is being decoded. Return to 1.
    unsigned int HDAT0_V, HDAT1_V;
    HDAT0_V = readRegister(SCI_HDAT0);
    HDAT1_V = readRegister(SCI_HDAT1);
    if (HDAT0_V != 0 || HDAT1_V != 0) {
        // something wrong, loop
        while (1);
    }
    __delay_ms(50);
}

void sayHello() {
    play(HelloMP3, sizeof (HelloMP3));
}

FATFS fs;

int testMP3File() {
    char buffer[3];
    UINT s1;
    FRESULT res = pf_read(buffer, 3, &s1);
    if (res != FR_OK) {
        return 0;
    }
    return buffer[0] == 'I' && buffer[1] == 'D' && buffer[2] == '3';
}

int main(int argc, char** argv) {
    SYSTEM_Initialize();
    _LATB3 = 0;
    FRESULT fr = FR_NOT_READY;
    while (fr != FR_OK) {
        fr = pf_mount(&fs);
        __delay_ms(100);
    }
    fr = pf_open("01/01.mp3");
    if (fr != FR_OK || !testMP3File()) {
        while (1);
    }

    // SDCARD share SPI with VS1053
    _LATB3 = 1;
    __delay_ms(100);
    int isOK = reset();
    if (!isOK) {
        while (1);
    }
    while (1) {
        sayHello();
    }
}
User avatar
Henrik
VLSI Staff
Posts: 1294
Joined: Tue 2010-06-22 14:10

Re: Audible "Hello" example for VS1003B + Microcontroller

Post by Henrik »

For anyone reading the thread this far:
The rest of the discussion with almen_80, including the solution, is here:
viewtopic.php?f=11&t=2031

Kind regards,
- Henrik
Good signatures never die. They just fade away.
Post Reply