📄 vs1001.s
字号:
/*
Copyright (C) 2001 Jesper Hansen <jesperh@telia.com>.
This file is part of the yampp system.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <io-avr.h>
//
// VS1001 I/O pins
//
#define MP3_PORT PORTB
#define BSYNC_PORT PORTB
#define DREQ_PORT PORTB
#define MP3_PIN PB4 // MP3 control bit
#define BSYNC_PIN PB3 // BSYNC signal
#define DREQ_PIN PB2 // DREQ signal
//
// VS1001 commands
//
#define VS1001_READ 0x03
#define VS1001_WRITE 0x02
//
// VS1001 registers
//
#define VS1001_MODE 0x00
#define VS1001_STATUS 0x01
#define VS1001_INTFCTLH 0x02
#define VS1001_CLOCKF 0x03
#define VS1001_PLAYTIME 0x04
#define VS1001_AUDATA 0x05
#define VS1001_VOLUME 0x0B
.section .text
//
// local functions
//
; r24 r22
; void startSCI(u08 mode, u08 address)
startSCI:
cbi MP3_PORT,MP3_PIN ; activate VS1001 Chip Select
rcall spi_tx_rx ; send the mode (READ or WRITE)
mov r24,r22 ; get address
rjmp spi_tx_rx ; send address
; void endSCI(void)
endSCI:
sbi MP3_PORT, MP3_PIN ; set CS hi
clr r25 ; do a 10us
rcall delay10us ; delay
ret
spi_tx_rx:
out SPDR, r24 ; send over SPI
vspi1: sbis SPSR,SPIF ; while flag is clear
rjmp vspi1 ; wait for SPI
in r24, SPDR ; and get input data
ret ; done
//
// global functions
//
; r24
;void vs1001_send_data(u08 data)
.global vs1001_send_data
vs1001_send_data:
cli
sbi BSYNC_PORT,BSYNC_PIN ; start BSYNC
out SPDR, r24 ; send over SPI
nop
nop
nop
cbi BSYNC_PORT,BSYNC_PIN ; stop BSYNC
vssd1: sbis SPSR,SPIF ; while flag is clear
rjmp vssd1 ; wait for SPI
sei
ret
; r24
;u16 vs1001_read(u08 address)
.global vs1001_read
vs1001_read:
mov r22,r24 ; address in r22
ldi r24,VS1001_READ
rcall startSCI ; start SCI communication
clr r24
rcall spi_tx_rx ; get a byte
mov r23,r24
clr r24
rcall spi_tx_rx ; get a byte
mov r22,r24
rcall endSCI
mov r24,r22 ; get back word
mov r25,r23 ; get back word
ret
; r24 r23/r22
;void vs1001_write(u08 address, u16 data)
.global vs1001_write
vs1001_write:
mov r18,r22 ; save register
mov r22,r24 ; address in r22
ldi r24,VS1001_WRITE
rcall startSCI ; start SCI communication
mov r24,r23 ; get hi byte
rcall spi_tx_rx ; send it
mov r24,r18 ; get lo byte
rcall spi_tx_rx ; send it
rjmp endSCI
; send a 32 byte block of data to the VS1001
; using the SPI port.
; r25/r24
;void vs1001_send_32(char *pData);
.global vs1001_send_32
vs1001_send_32:
mov r31,r25 ; transfer input pointer to Z
mov r30,r24
ldi r25,32 ; init loop counter
vs32_2: ld r24,Z+ ; get a byte and inc pointer
rcall vs1001_send_data
dec r25 ; dec loop counter
brne vs32_2 ; loop if not zero
ret
; r25/r24
; void vs1001_nulls(u16 nNulls)
.global vs1001_nulls
vs1001_nulls:
mov r30,r24
mov r31,r25
vs1001_nulls_2:
clr r24
rcall vs1001_send_data
sbiw r30,1
brne vs1001_nulls_2
ret
; r24 r22
;void vs1001_setvolume(u08 left, u08 right)
.global vs1001_setvolume
vs1001_setvolume:
mov r23,r24
ldi r24,11 ; volume register
rjmp vs1001_write
.comm vs1001_xtalcomp,2 ; compensation value for the VS1001 xtal
; r24
;void vs1001_reset(bool bLoud)
.global vs1001_reset
vs1001_reset:
push r24
ldi r25,8
clr r24
rcall vs1001_nulls
ldi r24,VS1001_MODE
clr r23
ldi r22,4
rcall vs1001_write
rcall delay10us ; delay
w_dreq:
sbis DREQ_PORT-2,DREQ_PIN ; wait for DREQ
rjmp w_dreq
clr r25
ldi r24,32;
rcall vs1001_nulls
; set CLOCKF to compensate for a non 24,576 MHz x-tal
ldi r24,VS1001_CLOCKF
lds r23,vs1001_xtalcomp+1
lds r22,vs1001_xtalcomp
rcall vs1001_write
; set sound enchance bit
pop r24
clr r22 ; clear r22
ror r24 ; rotate bit into carry
ror r22 ; rotate carry to high bit of r22
clr r23
ldi r24,VS1001_MODE
rjmp vs1001_write
; r25/r24
; void vs1001_setcomp(u16 comp)
.global vs1001_setcomp
vs1001_setcomp:
sts vs1001_xtalcomp,r24
sts vs1001_xtalcomp+1,r25
ret
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -