VS1001

SwordfishUser.VS1001 History

Hide minor edits - Show changes to output

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
=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
=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
=]