VS1001

SwordfishUser.VS1001 History

Hide minor edits - Show changes to markup

Changed lines 1-2 from:

VS1001 module Available for SwordFish.

to:

VS1001 Module Available for SwordFish.

Added lines 1-269:

VS1001 module Available for SwordFish.

This module was designed and tested using the EasyPIC3 (18F452) and SmartMP3 add-on. Disable the LED's. Set pullups on PORTC. Set pull-downs on PORTD.

Example Code

#option SD_SPI = MSSP
#option SD_CS = PORTC.0                     // SPI CS To SD CS (SD pin 1)
#option SD_SUPPORT_SUB_DIRECTORIES = false
#option SD_SUPPORT_MULTIPLE_FILES = false
#option SD_REINIT_SPI = false
#option SD_SPI_SPEED = spiOscDiv64               ' 4,16,64
Include "SDFileSystem.bas"

Include "vs1001a.bas"

// main ------------------------------------
VS1001a.Initialize(25000)
Repeat
Until SD.Init()=errOK

If SD.OpenFile("seq_01.mp3") = errOK Then
  VS1001a.Reset(false)
  While Not SD.EOF
    SD.ReadNBytes(junk,32)
    For i=0 To 31
      VS1001a.WriteByte(junk(i))
    Next
  Wend
  SD.CloseFile
EndIf

Module Code

{
*****************************************************************************
*  Name    : VS1001a.BAS                                                   *
*  Date    : 4/16/2008                                                      *
*  Version : 1.0                                                            *
*  Notes   :                                                                *
*          :                                                                *
*****************************************************************************
}
Module VS1001a

#option VS_DCLK = PORTD.2
#option VS_SDATA = PORTD.3
#option VS_BSYNC = PORTD.1
#option VS_DREQ = PORTD.0
#option VS_XCS = PORTC.1 // SCI via MSSP

#option SSPI_SCK = VS_DCLK.VS_DCLK@
#option SSPI_SDO = VS_SDATA.VS_SDATA@

Include "sspi.bas"         // SDI (data)
Include "convert.bas"
Include "spi.bas"        // sci (control) and SD card


Const 
      OpRead = 3,
      OpWrite = 2,
      RegMode = 0,
      RegStatus = 1,
      RegClockf = 3,
      RegDecodeTime = 4,
      RegVolume = 11
      RegModeEnhancer = 7

Dim XCS As VS_XCS.VS_XCS@
Dim DCLK As VS_DCLK.VS_DCLK@
Dim SDATA As VS_SDATA.VS_SDATA@
Dim BSYNC As VS_BSYNC.VS_BSYNC@
Dim DREQ As VS_DREQ.VS_DREQ@

Dim FVolumeLeft As Byte,
    FVolumeRight As Byte,
    FClockF As Float

Public Dim 
       VolumeLeft As FVolumeLeft,
       VolumeRight As FVolumeRight,
       IsNotReady As DREQ,
       ByteSync As BSYNC,
       CS As XCS,
       i As Byte

// Send Command to MP3 SCI
Public Function SendCommand(ByVal pInOut As Byte, ByVal pAddr As Byte, ByVal pParam1 As Byte, ByVal pParam2 As Byte) As Word
       Low(XCS)
       SPI.WriteByte(pInOut)
       SPI.WriteByte(pAddr)
       If pInOut=OpWrite Then
              SPI.WriteByte(pParam1)
              SPI.WriteByte(pParam2)
       Else
              Result.Byte0=SPI.ReadByte()
              Result.Byte1=SPI.ReadByte()
       EndIf

       High(XCS)
       DelayUS(5)
End Function

Public Sub SetClock(ByVal pFreq As Word, ByVal pDoubler As Boolean)
       Dim vFreq As Word
       vFreq=pFreq/2
       If pDoubler=true Then
          vFreq=$8000 Or vFreq
       EndIf
       SendCommand(OpWrite,RegClockf,vFreq.Byte1,vFreq.Byte0)
End Sub

Public Sub SetVolume(ByVal pLeft As Byte, ByVal pRight As Byte)
       SendCommand(OpWrite,RegVolume,254-pLeft,254-pRight)
End Sub

Public Sub EnableEnhancer()
       Dim Mode As Word
       Mode=SendCommand(OpRead,RegMode,0,0)
       Mode.byte0.bits(RegModeEnhancer)=1
       SendCommand(OpWrite,RegMode,Mode.byte1, Mode.byte0)
End Sub

Public Sub VolumeUp()
       If FVolumeLeft<255 Then
          Inc(FVolumeLeft)
       EndIf
       If FVolumeRight<255 Then
          Inc(FVolumeRight)
       EndIf
       SetVolume(FVolumeLeft,FVolumeRight)
End Sub

Public Sub VolumeDown()
       If FVolumeLeft>0 Then
          Dec(FVolumeLeft)
       EndIf
       If FVolumeRight>0 Then
          Dec(FVolumeRight)
       EndIf       
       SetVolume(FVolumeLeft,FVolumeRight)
End Sub

Public Sub Mute()
       SetVolume(0,0)
End Sub

// Write a byte to SDI
Public Sub WriteByte(ByVal pData As Byte)
       While IsNotReady=0
       Wend

       High(BSYNC)
       SSPI.WriteByte(pData)
       Low(BSYNC)
End Sub

// Write a byte to SDI (bit bang)
Public Sub WriteByte_(ByVal pData As Byte)
       While IsNotReady=0
       Wend

       High(BSYNC)
       For i=0 To 7
              Low(DCLK)
              SDATA=pData.bits(i)
              High(DCLK)
       Next
       Low(BSYNC)      
       Low(DCLK)
End Sub


// Write a block of 32 bytes to SDI
Public Sub WriteBlock(ByRef pDataBuf() As Byte)
       Dim i As Byte
       FSR1=pDataBuf(0)
       For i=0 To Bound(pDataBuf)
              SSPI.WriteByte(POSTINC1)
       Next
End Sub

// soft Reset the VS1001
Public Sub Reset(ByVal ClearData As Boolean = false)
    Dim i As Byte
    Dim DataBuf(32) As Byte

    SendCommand(OpWrite,RegMode,0,4)
    DelayUS(2)       

    // wait for the DREQ to go high    
    While IsNotReady=0
    Wend

    If ClearData Then
       For i = 0 To 31
           DataBuf(i)=0
       Next
       For i = 0 To 63
           VS1001a.WriteBlock(DataBuf)
       Next
    Else
       VS1001a.WriteByte(0)
    EndIf
End Sub

Public Sub SineTest()
       Reset(false)
       VS1001a.WriteByte($53)
       VS1001a.WriteByte($EF)
       VS1001a.WriteByte($6E)
       VS1001a.WriteByte($44)
       VS1001a.WriteByte(0)
       VS1001a.WriteByte(0)
       VS1001a.WriteByte(0)
       VS1001a.WriteByte(0)       
       DelayMS(500)
       VS1001a.WriteByte($45)
       VS1001a.WriteByte($78)
       VS1001a.WriteByte($69)
       VS1001a.WriteByte($74)
       VS1001a.WriteByte(0)
       VS1001a.WriteByte(0)
       VS1001a.WriteByte(0)
       VS1001a.WriteByte(0)
       Reset(false)
End Sub

// Initialze peripherals
Public Sub Initialize(ByVal pClockF As Float = 0)
       Low(DCLK)
       Low(SDATA)
       Low(DREQ)

       Output(DCLK)
       Output(SDATA)

       High(XCS)
       Output(XCS)

       Input(DREQ)

       Low(BSYNC)
       Output(BSYNC)

       ' init hardware spi      
       SPI.SetClock(SPI.spiIdleLow, SPI.spiRisingEdge)
       SPI.SetAsMaster(SPI.spiOscDiv16)
       SPI.SetSample(SPI.spiSampleMiddle)
       SPI.Enabled=true // data

       ' init software spi for SDI
       SSPI.Initialize
       SSPI.SetClock(SSPI.spiIdleLow)


       Reset(false)
       VS1001a.SetClock(pClockF,false)
       FVolumeLeft=240
       FVolumeRight=240
       SetVolume(FVolumeLeft,FVolumeRight)
End Sub