Here's a working code, written by ChatGPT, which allows to control playback of DY-SV17F and similar "DY" series mp3 modules. These modules provide far better audio quality, no noise and cracking, compared to more common, "Dfplayer" type of modules, and also, they have 4mb of onboard flash (and also MicroSD and USB flash support), which is quite handy, when you need to design an announcement or counter system.

This code took multiple iterations - it was not compiling initially because it used Proton Basic statements randomly. It was figured out. Code compiled, but not working. After reading the datasheet, I've figured out that it was not sending "source selection" statement. After pointing it to that, it took about 20 minutes to generate the code. It was still far from perfect, because "main" part was at the bottom, so module was confused. Now I've moved manually the "Main" code to the proper place and yay, it works!

The moral of story? - It coded a lot of code, which most likely I would never be able to write, considering my limited skills, but until I suggested what is wrong and needs to be fixed, it was struggling with the working code, despite making several attempts.

Code:
' Use software UART on a chosen pin
MP3_TX   VAR PORTB.1     ' pick your PIC output pin
BAUD9600 CON 84          ' 9600 baud, N,8,1 for SEROUT2


' === Constants from DY-SV17F datasheet ===
USB     CON $00
TF_CARD CON $01
FLASH   CON $02


' Command IDs
CMD_PLAY          CON $02
CMD_PAUSE         CON $03
CMD_STOP          CON $04
CMD_PREV          CON $05
CMD_NEXT          CON $06
CMD_PLAY_SPECIFIC CON $07
CMD_SWITCH_DEVICE CON $0B
CMD_VOL_SET       CON $13


' === Variables ===
dyCmd    VAR BYTE
dyLen    VAR BYTE
dyBuf    VAR BYTE[8]
i        VAR BYTE
sumW     VAR WORD
crc      VAR BYTE
track    VAR WORD
hiB      VAR BYTE
loB      VAR BYTE
vol      VAR BYTE




' --- Example main ---
Main:
    PAUSE 500
    GOSUB DY_SelectDeviceFlash      ' set source = FLASH


    vol = 20
    GOSUB DY_SetVolume


    track = 1
    GOSUB DY_PlayTrack


    PAUSE 5000
    GOSUB DY_Pause
    PAUSE 1500
    GOSUB DY_Play
    PAUSE 3000
    GOSUB DY_Stop
END


' --- Low-level: send DY-SV17F packet (AA, cmd, len, data..., crc) ---
DY_Send:
    sumW = 0
    SEROUT2 MP3_TX, BAUD9600, [$AA]
    sumW = sumW + $AA


    SEROUT2 MP3_TX, BAUD9600, [dyCmd]
    sumW = sumW + dyCmd


    SEROUT2 MP3_TX, BAUD9600, [dyLen]
    sumW = sumW + dyLen


    IF dyLen > 0 THEN
        FOR i = 0 TO dyLen-1
            SEROUT2 MP3_TX, BAUD9600, [dyBuf[i]]
            sumW = sumW + dyBuf[i]
        NEXT
    ENDIF


    crc = sumW & $FF
    SEROUT2 MP3_TX, BAUD9600, [crc]
    PAUSE 10
RETURN


' --- High-level helpers ---
DY_SelectDeviceFlash:              ' Switch to internal FLASH (02)
    dyCmd = CMD_SWITCH_DEVICE
    dyLen = 1
    dyBuf[0] = FLASH
    GOSUB DY_Send
    PAUSE 150                       ' module auto-plays first track after switch
    ' Stop playback immediately so only source is selected:
    dyCmd = CMD_STOP
    dyLen = 0
    GOSUB DY_Send
RETURN


DY_Play:
    dyCmd = CMD_PLAY : dyLen = 0
    GOSUB DY_Send
RETURN


DY_Pause:
    dyCmd = CMD_PAUSE : dyLen = 0
    GOSUB DY_Send
RETURN


DY_Stop:
    dyCmd = CMD_STOP : dyLen = 0
    GOSUB DY_Send
RETURN


DY_Next:
    dyCmd = CMD_NEXT : dyLen = 0
    GOSUB DY_Send
RETURN


DY_Prev:
    dyCmd = CMD_PREV : dyLen = 0
    GOSUB DY_Send
RETURN


DY_SetVolume:                       ' vol = 0..30
    dyCmd = CMD_VOL_SET
    dyLen = 1
    dyBuf[0] = vol
    GOSUB DY_Send
RETURN


DY_PlayTrack:                       ' track = 1..65535
    hiB = track >> 8
    loB = track & $FF
    dyCmd = CMD_PLAY_SPECIFIC
    dyLen = 2
    dyBuf[0] = hiB
    dyBuf[1] = loB
    GOSUB DY_Send
RETURN