⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vs1001.c

📁 用ATmega8 做的MP3播放器
💻 C
字号:
/*
 * Copyright (c) 2003-2004 K. John '2B|!2B' Crispin
 * Copyright (c) 2005      Stephan Dobretsberger
 *
 * 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, MA02111-1307USA
 *
 * Feedback, Bugs, ... mail stephan.dobretsberger@gmx.at
 *
 */

#include <avr/io.h>
#include <avr/signal.h>
#include <avr/interrupt.h>
#include "config.h"
#include "types.h"
#include "delay.h"
#include "vs1001.h"
#include "spi.h"

void VS1001_send_SCI(u08 reg, u16 data)
{ // pull the CS line low
  VS_CS_LO;
  // do the pseudo i2c start
  VS1001_WRITE;
  spi_io(reg);
  // send the data
  spi_io(HIBYTE(data));
  spi_io(LOBYTE(data));
  // pull the cs line back up
  VS_CS_HI;
};

u16 VS1001_read_SCI(u08 reg)
{ u16 data;
  // pull the CS line low
  VS_CS_LO;
  // do the pseudo i2c start
  VS1001_READ;
  spi_io(reg);
  // get the reg data
  data = TO_HIBYTE(spi_io(0x00));
  data += spi_io(0x00);
  // pull the cs line back up
  VS_CS_HI;
  return data;
};

void VS1001_send_SDI(u08 data)
{ VS_BSYNC_HI;
  outp(data, SPDR);   // send data
  // after 3 NOPs the fourth tick pulls bsync low, as a spi
  // level change takes 4 ticks, they switch at the same time and vs1001 takes in mp3 data
  NOP;NOP;NOP;
  VS_BSYNC_LO;
  // wait for data to be sent
  while((inp(SPSR)&(1<<SPIF))== 0x00){};
};

void VS1001_send_SDI_32(u08* data)
{ int i;
  VS1001_WHILE_NEEDS_NO_DATA;
  for(i=0; i<32; i++)
  { VS1001_send_SDI(data[i]);
  };
};

void VS1001_send_zeros(u08 count)
{ do
  { VS1001_send_SDI(0x0);
    count--;
  }while(count);
};

void VS1001_SW_reset(void)
{ // for sanity
  delay_ms(100);
  u16 regval = 0x04;
  // set bit 2 of mode reg to 1 for reset
  VS1001_send_SCI(REG_MODE, regval);
  // for sanity
  delay_ms(2);
  //while(VS1001_NEEDS_NO_DATA){};
  VS1001_WHILE_NEEDS_NO_DATA
  // set 25.0 MHz clock
  regval = 12500; // = clock / 2000
  VS1001_send_SCI(REG_CLOCKF, regval);
  // according to datasheet
  VS1001_send_zeros(32);
};

void VS1001_HW_reset(void)
{ // pull down the reset pin for 1 second
  VS_RESET_LO;
  // delay
  DELAY_1SEC;
  // pull up again
  VS_RESET_HI;
  // delay
  DELAY_1SEC;
};

void VS1001_init(void)
{ // set bsync output low
  cbi(VS1001_PORT,PIN_VS1001_BSYNC);
  sbi(VS1001_DDR, PIN_VS1001_BSYNC);

  // set DREQ input with pull up
  sbi(VS1001_PORT,PIN_VS1001_DREQ);
  cbi(VS1001_DDR, PIN_VS1001_DREQ);

  // set /CS output high
  sbi(VS1001_PORT,PIN_VS1001_CS);
  sbi(VS1001_DDR, PIN_VS1001_CS);

  // set RESET output low
  // make sure to do a reset after the init
  cbi(VS1001_PORT,PIN_VS1001_RESET);
  sbi(VS1001_DDR, PIN_VS1001_RESET);

  VS1001_HW_reset();
  VS1001_SW_reset();
};

void VS1001_sine(BOOL state, u08 freq)
{ //VS1001_send_zeros(16);
  if(state == 0x01)
  { VS1001_send_SDI(0x53);
    VS1001_send_SDI(0xEF);
    VS1001_send_SDI(0x6E);
    VS1001_send_SDI(freq);
    VS1001_send_zeros(0x04);
  }
  else
  { VS1001_send_SDI(0x45);
    VS1001_send_SDI(0x78);
    VS1001_send_SDI(0x69);
    VS1001_send_SDI(0x74);
    VS1001_send_zeros(0x04);
  };
};

// sets the Volume register for VS1001
void VS1001_volume(u08 left, u08 right)
{ u16 regval = TO_HIBYTE(left)+(u16)right;
  VS1001_send_SCI(REG_VOL, regval);
};

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -