📄 vs1001.asm
字号:
/* *************************************************************************** Copyright (C) 2002 Jesper Hansen <jesperh@telia.com> and ** Romuald Bialy (MIS) <romek_b@o2.pl>.****** Yampp-7/USB - low level support library********************************************************************************* 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.******************************************************************************* Revision History**** when what who why**** 2002-09-22 1.0 MIS initial public release************************************************************************* */#define __ASSEMBLER__ 1#define __SFR_OFFSET 0#include <avr/io.h>//// VS1001 I/O pins// #define MP3_PORT PORTC #define BSYNC_PORT PORTB #define RESET_PORT PORTB #define DREQ_PORT PORTD #define MP3_PIN PC4 // MP3 control bit #define BSYNC_PIN PB2 // BSYNC signal #define RESET_PIN PB1 // RESET (also for CF card) #define DREQ_PIN PD0 // 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.extern delay//// local functions//; r24 r22; void startSCI(u08 mode, u08 address)startSCI: mov r1,r24 clr r24 out SPSR,r24 ; clear double speed bit in r24,SPSR mov r24,r1 clr r1 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 ldi r24,1 out SPSR,r24 in r24,SPSR clr r25 ; do a ldi r24,5 ; 10 uS jmp delay10 ; delayspi_tx_rx: out SPDR, r24 ; send over SPIvspi1: 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_datavs1001_send_data: cli mov r1,r24 clr r24 out SPSR,r24 mov r24,r1 clr r1 sbi BSYNC_PORT,BSYNC_PIN ; start BSYNC out SPDR, r24 ; send over SPI nop nop nop cbi BSYNC_PORT,BSYNC_PIN ; stop BSYNCvssd1: sbis SPSR,SPIF ; while flag is clear rjmp vssd1 ; wait for SPI sei ldi r24,1 out SPSR,r24 in r24,SPSR ret; r24;u16 vs1001_read(u08 address) .global vs1001_readvs1001_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 movw r24,r22 ; get back word ret; r24 r23/r22;void vs1001_write(u08 address, u16 data) .global vs1001_writevs1001_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/*; r24 r22 r21/r20;void vs1001_readmultiple(u08 address, u08 count, u16 *pData) .global vs1001_readmultiplevs1001_readmultiple: mov r18,r22 ; count in r18 mov r22,r24 ; save address movw r30,r20 ; pData in Z ldi r24,VS1001_READ rcall startSCI ; start SCI communicationvs_rd1: clr r24 rcall spi_tx_rx ; send NULL and get input data std Z+1,r24 ; store in *pData+1 rcall spi_tx_rx ; send NULL and get input data st Z,r24 ; store in *pData adiw r30,2 ; bump pointer dec r18 ; dec loop count brne vs_rd1 ; and do again rjmp endSCI*//*; r24 r22 r21/r20;void vs1001_writemultiple(u08 address, u08 count, u16 *pData) .global vs1001_writemultiplevs1001_writemultiple: mov r18,r22 ; count in r18 mov r22,r24 ; save address mov r31,r21 ; pData in Z mov r30,r20 ldi r24,VS1001_READ rcall vs1001_startSCI ; start SCI communicationvs_wr1: ldd r24,Z+1 ; get hi byte rcall spi_tx_rx ; send it ld r24,Z ; get lo byte rcall spi_tx_rx ; send it adiw r30,2 ; bump pointer dec r18 ; dec loop count brne vs_wr1 ; and do again rjmp endSCI; send a 32 byte block of data to the VS1001; using the SPI port.*/; r25/r24;void vs1001_send32(char *pData); .global vs1001_send32vs1001_send32: mov r31,r25 ; transfer input pointer to Z mov r30,r24 ldi r25,32 ; init loop countervs32_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_nullsvs1001_nulls: movw r30,r24vs1001_nulls_2: clr r24 rcall vs1001_send_data sbiw r30,1 brne vs1001_nulls_2 ret; r24 r22;void vs1001_setvolume(u08 volume, s08 balance) .global vs1001_setvolumevs1001_setvolume: mov r0,r22 ; save balance value mov r23,r24 ; r23 = left volume sbrs r0,7 ; skip if balance < 0 add r23,r0 ; add balance value neg r0 ; negate balance (signed value) mov r22,r24 ; r22 = right volume sbrs r0,7 ; skip if balance < 0 add r22,r0 ; add balance value ldi r24,11 ; volume register rjmp vs1001_write;void vs1001_init_io(void) .global vs1001_init_iovs1001_init_io: ; setup BSYNC cbi BSYNC_PORT, BSYNC_PIN ; output low sbi BSYNC_PORT-1, BSYNC_PIN ; pin is output for BSYNC ; set the MP3/ChipSelect pin hi sbi MP3_PORT, MP3_PIN ; output hi (deselect MP3) sbi MP3_PORT-1, MP3_PIN ; pin output for xCS ; set the RESET pin hi sbi RESET_PORT, RESET_PIN ; output hi sbi RESET_PORT-1, RESET_PIN ; pin output ; setup serial data I/O pins sbi DDRB, PB5 ; set MOSI a output sbi DDRB, PB4 ; SS must be output for Master mode to work sbi PORTB, PB6 ; activate pull-up on MISO line cbi PORTB, PB7 ; set SCK lo sbi DDRB, PB7 ; set SCK as output ; setup serial data interface ; select clock phase positive going in middle of data ; master mode ; enable SPI ; speed is CPUclock/2 ldi r24,(1<<MSTR) | (1<<SPE); ; Master Mode, Enable SPI, fCPU/4 clock out SPCR,r24 ldi r24,1 ; clear double speed bit out SPSR,r24 in r24,SPSR ; clear status ret.comm vs1001_xtalcomp,2 ; compensation value for the VS1001 xtal; r24;void vs1001_reset(bool bLoud) .global vs1001_resetvs1001_reset: push r24 ldi r25,8 clr r24 rcall vs1001_nulls ldi r24,VS1001_MODE clr r23 ldi r22,4 ; RESET value rcall vs1001_write call delay10 ; 10us delayw_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 ror r24 ; rotate bit into carry ror r22 ; rotate carry to high bit clr r23 ldi r24,VS1001_MODE rcall vs1001_write ret; r25/r24; void vs1001_setcomp(u16 comp).global vs1001_setcompvs1001_setcomp: sts vs1001_xtalcomp,r24 sts vs1001_xtalcomp+1,r25 ret
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -