Use the VS1053b chip

From F256 Foenix
Jump to navigationJump to search

How to use the VS1053b chip

This chip is only present in the F256K2 or the F256Jr2. It isn't available on the earlier F256K nor the F256Jr.

You may have to enable its audio output via manipulation of the CODEC. Check the Use the CODEC page to see how.

Using the real time midi mode

To enable the real time midi mode (ie playing notes on a keyboard and having the VS1053b react to data sent to its FIFO buffer), it first has to be enable via the SCI bus of the chip.

Register Name Address Purpose
SCI Control 0xD700 Control the flow of information
SCI Address 0xD701 Select to which VS1053b address to write to
SCI Data 1 0xD702 First byte of data
SCI Data 2 0xD703 Second byte of data
FIFO Stat 1 0xD704 First byte of status
FIFO Stat 2 0xD705 Second byte of status

Next, you have to send this plugin data from VLSI, the makers of this chip, which contains some RLE compression. Here it is in C array form:

const uint16_t plugin[28] = { /* Compressed plugin for the VS1053b to enable real time midi mode */

 0x0007, 0x0001, 0x8050, 0x0006, 0x0014, 0x0030, 0x0715, 0xb080, /*    0 */
 0x3400, 0x0007, 0x9255, 0x3d00, 0x0024, 0x0030, 0x0295, 0x6890, /*    8 */
 0x3400, 0x0030, 0x0495, 0x3d00, 0x0024, 0x2908, 0x4d40, 0x0030, /*   10 */
 0x0200, 0x000a, 0x0001, 0x0050

};

In order to properly prepare the SCI bus of the chip, this piece of code can be used with the plugin array:

void initVS1053MIDI(void) {

   uint8_t n;
   uint16_t addr, val, i=0;
 while (i<sizeof(plugin)/sizeof(plugin[0])) {
   addr = plugin[i++];
   n = plugin[i++];
   if (n & 0x8000) { /* RLE run, replicate n samples */
     n &= 0x7FFF;
     val = plugin[i++];
     while (n--) {
       //WriteVS10xxRegister(addr, val);
       POKE(VS_SCI_ADDR,addr);
       POKEW(VS_SCI_DATA,val);
       POKE(VS_SCI_CTRL,1);
       POKE(VS_SCI_CTRL,0);

while (PEEK(VS_SCI_CTRL) & 0x80);

     }
   } else {           /* Copy run, copy n samples */
     while (n--) {
       val = plugin[i++];
       //WriteVS10xxRegister(addr, val);
       POKE(VS_SCI_ADDR,addr);
       POKEW(VS_SCI_DATA,val);
       POKE(VS_SCI_CTRL,1);
       POKE(VS_SCI_CTRL,0);

while (PEEK(VS_SCI_CTRL) & 0x80);

     }
   }
 }

}

To send midi bytes to the VS1053b, use register 0xDDB1 just like you would use 0xDDA1 for the SAM2695.

huge discord note infodump that has to be cleaned and understood

normally, let's assume we begin with a playback of a MP3, you read the file and you will need to dump like a 2K in before it tells you to stop. But, the FIFO inside the FPGA is also 2K, so in theory before things get ugly, you can upload in the MP3 playback system 2K+2K bytes, which ought to be enough to get it going. Now, if you monitor the FPGA FIFO info when empty you can put more in. Normally, after the VS1053 queue is full, it only need 32 bytes at the time and the FPGA takes care of that. Now, basically need to make sure the FPGA FIFO is topped off. Now, when come to end, you will need to fill extra bytes with 00 to empty the VS1053 Fifo and then the tune will end.

Now, the tricky parts is when one needs to stop the sound, there is also a process of filling the FIFO with 00 to cleanse the MP3 pipe. The specs talks about that.

This is as far as I went, now, I believe that if someone wants to play oggs and shit like that the controller need to be updated with new code since there are some issues in the latest tape out of the chip because remember people this is a DSP that actually can be programmed. There is actually an app note on how to use it to come out with Histogramic data (VUE bar app, with small LCD? anybody picking up on that? LOL) for one's pleasure

This is in a nutshell the process to playback stuff. Here is the Register File Details for the VS1053 interface:

$D700..$D707

   case( CPU_A_i[2:0] )
       3'b000: begin CPU_D_o = {Busy, VS1053B_Registers[0][6:0]}; end 
       3'b001: begin CPU_D_o = VS1053B_Registers[1]; end 
       3'b010: begin CPU_D_o = VS1053B_Command_Read[7:0]; end 
       3'b011: begin CPU_D_o = VS1053B_Command_Read[15:8]; end 
       3'b100: begin CPU_D_o = Data_FIFO_Count[7:0]; end
       3'b101: begin CPU_D_o = {VS1053B_FIFO_Empty, VS1053B_FIFO_Full, 3'b000, Data_FIFO_Count[10:8]}; end
       3'b110: begin CPU_D_o = 8'h00; end 
       3'b111: begin CPU_D_o = 8'h00; end
   endcase

VS1053B_Registers[0] - Bit Fields: ($D700..$D703)

[0] 1: Start Transfer

[1] 1: Read Register, 0: Write Register

[7] 1: SPI Transfer in Progress [Busy]

VS1053B_Registers[1]

[3:0] Register to Address

VS1053B_Registers[2] Data Access Low

VS1053B_Registers[3] Data Access Hi

There are 2 Accessible Area for the VS1053 The Control/Register Section with 16bits wide Data and 16 Addresses (See specs) The Other is the Data(Stream) Port, there is no Address and it is 8bits

When one wants to control the chip, one need to setup the address and data (for write) and address for read, one needs to setup the direction and when everything is ready, one needs to trigger the transaction. When one needs to write file data for playback, one needs only to write data to FIFO port @ $D704 and monitor FIFO @ $D705/$D706 Here is a piece of code, not the best, prolly not the most kosher either, but that ought to get you started. I am simply playing back a very tiny sound effect (small enough to fit in the memory so not much to play back)

MP3_Playing:

               lda #$42
               sta $d702   ; Set the Stream mode
               lda #$48
               sta $d703
               lda #$21    ; Start Transaction
               sta $d700
               lda #$20    ; Return to Zero
               sta $d700 
lda #$00
sta $d702
sta $d703
lda #$23  ; Go read the Command Register
sta $d700
lda $d702
lda $d703
               ldx #$00

VS_Pause:

               inx 
               cpx #$80
               bne VS_Pause
               lda #$80
               sta $00     ; Let's enable the MMU Edit, keep the MMU 00 in play
               lda #$08    ; Bring about the first 8K 
               sta $0D     ; It starts @ $08 == page 0
               setaxl 
               ldx #$0000
               ldy #$0000
Go Fill the FIFO
               setas

MP3_Fill_FIFO: ;lda @l MP3_Music,x

               lda $A000,x
               sta VS1053_STREAM_DATA      ; THere is 2K FIFO
               inx 
               iny 
               cpy #$0800                  ; Fill 2K
               bne MP3_Fill_FIFO

MP3_Fill_FIFO_Wait:

               ldy #$0000
               lda VS1053_FIFO_COUNT_HI    ; Load High Portion is monitor for 
               and #$80
               cmp #$80
               bne MP3_Fill_FIFO_Wait
               cpx #$2000
               bne MP3_Fill_FIFO
               ldx #$0000
               lda $0D
               inc A
               sta $0D 
               cmp #$0c 
               bne MP3_Fill_FIFO
               lda #$05
               sta $0D

MP3_We_are_Done:

               setaxs 
               rts