📄 new_download.c
字号:
#include <Reg52.h>
#include <absacc.h>
#include <stdio.h>
#include <intrins.h>
//#define DATA
#include "dsp_boot_code.h"
#include "dsp_code.h"
#ifdef DATA
#include "dsp_data.h"
#endif
/* 定义宏 */
#define uint16 unsigned short
#define uint8 unsigned char
#define int16 short
#define int8 char
#define VOL1 0x81
#define VOL2 0x82
/* TLV320AIC23寄存器地址 */
#define L_LINE_VOLUME 0x00 // 左线输入通道音量控制寄存器
#define R_LINE_VOLUME 0x01 // 右线输入通道音量控制寄存器
#define L_HEADPHONE_VOLUME 0x02 // 左通道耳机音量控制寄存器
#define R_HEADPHONE_VOLUME 0x03 // 右通道耳机音量控制寄存器
#define A_AUDIO_PATH 0x04
#define D_AUDIO_PATH 0x05
#define POWER_CON 0x06
#define D_AUDIO_INTERFACE 0x07
#define SAMPLE_RATE 0x08
#define D_INTERFACE_ACT 0x09
#define RESET 0x0f
/* 定义寄存器端口地址
---------------------------------------------------------------
A15 A14 A13 A12 A11 A10 A9 A8
---------------------------------------------------------------
X X X nHCS HR/nW HCNTL1 HCNTL0 HBIL
---------------------------------------------------------------*/
#define WR_HPICL XBYTE[0xe000]
#define WR_HPICH XBYTE[0xe100]
#define WR_HPID0L XBYTE[0xe200] // HCNTL0 = 0,HCNTL0 = 1,每写1次,HPIA事先增1
#define WR_HPID0H XBYTE[0xe300]
#define WR_HPIAL XBYTE[0xe400] // 只代表第一个字节,先高字节还是低字节由BOB位来决定
#define WR_HPIAH XBYTE[0xe500]
#define WR_HPID1L XBYTE[0xe600] // HCNTL0 = 1,HCNTL0 = 1,HPIA寄存器不受影响
#define WR_HPID1H XBYTE[0xe700]
#define RD_HPID0L XBYTE[0xeA00] // HCNTL0 = 0,HCNTL0 = 1,每读1次,HPIA事后增1
#define RD_HPID0H XBYTE[0xeB00]
#define RD_HPID1L XBYTE[0xeE00] // HCNTL0 = 1,HCNTL0 = 1,HPIA寄存器不受影响
#define RD_HPID1H XBYTE[0xeF00]
#define WR_CR XBYTE[0x7100]
#define WR_PARA XBYTE[0x7000]
// Addresses used for hand-shaking flags
#define DSP_READY 0x0300
#define PROG_BUF_READY DSP_READY + 1
#define DATA_BUF_READY DSP_READY + 2
#define COPY_DONE DSP_READY + 3
#define PMST_VAL DSP_READY + 4
// Boot buffer address
#define BOOT_BUF_START 0x0400
#define APP_PROG 0
#define APP_DATA 1
sbit DSPRST = P1^2;
sbit NETRST = P1^3;
sbit USBRST = P1^4;
sbit LCDRST = P1^5;
sbit CS = P3^3; // SPI
sbit SDIN = P3^4;
sbit SCLK = P3^5;
bit ok,readT,key_down;
unsigned char time,stoptime,ms,DSPorder;
unsigned char volume;
void wr_dsp_code(void);
void delay(uint16 wu);
void load_dsp_prog(void);
void init_51(void);
void init_aic23(void);
void write_aic23(uint8 addr, uint16 dat);
void dsp_rst(void);
void usb_rst(void);
void lcd_rst(void);
void net_rst(void);
unsigned char rd_hpi(uint16 addr);
unsigned char getDSP();
int main(void)
{
init_aic23();
delay(10000);
net_rst();
dsp_rst();
lcd_rst();
usb_rst();
load_dsp_prog();
init_51();
delay(30000);
volume = 108;
write_aic23(L_HEADPHONE_VOLUME, 0x0180+volume);
while(1);
return 0;
}
void delay(uint16 wu)
{
for (wu; wu > 0; wu--);
}
void lcd_rst(void)
{
LCDRST = 0;
delay(200);
LCDRST = 1;
delay(200);
}
void dsp_rst(void)
{
DSPRST = 0;
delay(200);
DSPRST = 1;
delay(200);
}
void usb_rst(void)
{
USBRST = 0;
delay(200);
USBRST = 1;
delay(200);
}
void net_rst(void)
{
NETRST = 1;
delay(200);
NETRST = 0;
delay(200);
}
void load_dsp_prog(void)
{
wr_dsp_code();
}
/*
unsigned char rd_hpi(uint16 addr)
{
int16 i;
WR_HPIAL = addr / 256;
WR_HPIAH = addr % 256;
i = RD_HPID0L;
i = (i << 8) | RD_HPID0H;
return(i);
}
void wr_hpi(uint16 addr, uint16 dat)
{
WR_HPIAL = addr / 256;
WR_HPIAH = addr % 256;
WR_HPID1L = dat / 256;
WR_HPID1H = dat % 256;
}
*/
void wr_dsp_code(void)
{
const uint16 *dspptr, *temp;
uint16 len;
uint16 addr;
uint8 i, correct, app_stage;
//console_init();
//aic23_init();
printf("HPI boot begins...\n");
WR_HPICL = 0x08; // clear HPIint,least is first BOB = 0,第1字节为高字节
WR_HPICH = 0x08; // HPIC是16位寄存器,主机写HPIC,第一字节与第二字节内容必须相同
// 第一阶段
dspptr = dsp_boot_program;
printf("The first stage:Load DSP boot program.\n");
len = *dspptr++;
while(len != 0) // 第一个字节表示数据长度(字节数),第二、三字节表示起始地址,高位字节在前
{
addr = *dspptr++;
temp = dspptr; // dspptr已经指向了准备写入的len长度的数据的首字节,将该地址保存起来
addr--; // HCNTL0 = 0,HCNTL0 = 1,每写1次,HPIA事先增1
WR_HPIAL = addr / 256; // 256 = 0x100,BOB = 0,第1字节为高字节,地址高8位
WR_HPIAH = addr % 256; // 地址低8位
for (i = 0; i < len; i++)
{
WR_HPID0L = *dspptr / 256; // 第一字节,16位数据高8位
WR_HPID0H = *dspptr % 256; // 第二字节,16位数据低8位
dspptr++;
}
dspptr = temp; // 指针回到刚刚写完的len长度数据的首字节,以便读出进行校验
addr++; // HCNTL0 = 0,HCNTL0 = 1,每读1次,HPIA事后增1
WR_HPIAL = addr / 256;
WR_HPIAH = addr % 256;
for (i = 0; i < len; i++)
{
if (RD_HPID0L != *dspptr / 256) // 写入的数据不等于读出的数据
{
dspptr = temp - 2; // 将dspptr指回到该len长度的首字节,以便重新写该len长度的数据
printf("Error occurs!\n");
break;
}
if (RD_HPID0H != *dspptr % 256)
{
dspptr = temp - 2;
printf("Error occurs!\n");
break;
}
dspptr++;
}
len = *dspptr++;
}
WR_HPIAL = 0x00; // 向地址0x007F写入pc指针加载地址
WR_HPIAH = 0x7F;
WR_HPID1L = 0x01; // THE START ADDRESS OF RUN
WR_HPID1H = 0x00;
addr = DSP_READY;
WR_HPIAL = addr / 256;
WR_HPIAH = addr % 256;
while(RD_HPID1H != 0x01); // 等待DSP准备好
// 第二阶段
for(i = 0; i < 5; i++) // 初始化所有握手信号为0
{
addr = DSP_READY - 1; // HCNTL0 = 0,HCNTL0 = 1,每写1次,HPIA事先增1
WR_HPIAL = addr / 256;
WR_HPIAH = addr % 256;
WR_HPID0L = 0x00;
WR_HPID0H = 0x00;
}
for(app_stage = APP_PROG; app_stage <=APP_DATA; app_stage++)
{
if(app_stage == APP_PROG)
{
dspptr = dsp_program;
printf("The second stage:Load DSP application program.\n");
}
else if(app_stage == APP_DATA)
{
#ifdef DATA
dspptr = dsp_data;
printf("The third stage:Load DSP application data.\n");
#else
printf("There is no DSP application data to load.\n");
break;
#endif
}
len = *dspptr;
while(len != 0)
{
printf("len = %d\n", len);
correct = 1;
temp = dspptr;
addr = BOOT_BUF_START - 1;
WR_HPIAL = addr / 256;
WR_HPIAH = addr % 256;
for(i = 0; i < len+2; i++)
{
WR_HPID0L = *dspptr / 256;
WR_HPID0H = *dspptr % 256;
dspptr++;
}
dspptr = temp; // 指针回到刚刚写完的len长度数据的首字节,以便读出进行校验
addr++; // HCNTL0 = 0,HCNTL0 = 1,每读1次,HPIA事后增1
WR_HPIAL = addr / 256;
WR_HPIAH = addr % 256;
for (i = 0; i < len+2; i++)
{
if (RD_HPID0L != *dspptr / 256) // 写入的数据不等于读出的数据
{
dspptr = temp; // 将dspptr指回到该len长度的首字节,以便重新写该len长度的数据
correct = 0;
printf("Error occurs!\n");
break;
}
if (RD_HPID0H != *dspptr % 256)
{
dspptr = temp;
correct = 0;
printf("Error occurs!\n");
break;
}
dspptr++;
}
if(correct)
{
if(app_stage == APP_PROG)
{
addr = PROG_BUF_READY;
}
else
{
addr = DATA_BUF_READY;
}
WR_HPIAL = addr / 256;
WR_HPIAH = addr % 256;
WR_HPID1L = 0x00;
WR_HPID1H = 0x01; // 将标志位置1以通知DSP处理
printf("waiting...\n");
//while(RD_HPID1H == 0x01); // 等待DSP完成数据的下载
do
{
delay(0xffff);
}while(RD_HPID1H == 0x01);
}
len = *dspptr;
}
}
addr = COPY_DONE;
WR_HPIAL = addr / 256;
WR_HPIAH = addr % 256;
WR_HPID1L = 0x00;
WR_HPID1H = 0x01;
printf("HPI boot ends.\n");
}
Timer0() interrupt 1
{
ok = 1;
ms++;
}
void init_51(void)
{
TMOD = 0x21;
SCON = 0x40;
REN = 1;
TH1 = 0xfd;
TL1 = 0xfd;
ET1 = 0;
ES = 0;
IT0 = 1;
EX0 = 0;
ET0 = 1;
EA = 1;
TR1 = 1;
TR0 = 1;
}
/***************************************************************/
/*
unsigned char getDSP()
{
WR_HPIL_A = 0;
WR_HPIH_A = 0x7d;
return(RD_HPIH0_D);
}
*/
void init_aic23(void)
{
write_aic23(RESET, 0);
write_aic23(D_INTERFACE_ACT, 0x001);
write_aic23(POWER_CON, 0);
//write_aic23(SAMPLE_RATE, 0x022); //44.1k
//write_aic23(SAMPLE_RATE, 0x062); //22.05k
write_aic23(SAMPLE_RATE, 0x02e); //8.021k
write_aic23(L_LINE_VOLUME, 0x0117);
write_aic23(L_LINE_VOLUME, 0x0117);
volume = 100;
write_aic23(L_HEADPHONE_VOLUME, 0x0180+volume); //0x1e4
write_aic23(R_HEADPHONE_VOLUME, 0x0180+volume);
//write_aic23(A_AUDIO_PATH, 0x009); //bypass DAC OFF
//write_aic23(A_AUDIO_PATH, 0x014); //MIC ADC DAC ON 0DB
//write_aic23(A_AUDIO_PATH, 0x1fc); //bypass MIC ADC DAC ON 0DB sidetone
write_aic23(A_AUDIO_PATH, 0x07d); //bypass MIC ADC DAC ON 20DB sidetone(-6db)
//write_AIC23(A_AUDIO_PATH, 0x011); //LINE ADC DAC ON
write_aic23(D_AUDIO_PATH, 0x04);
write_aic23(D_AUDIO_INTERFACE, 0x043); //master dsp mode
}
void write_aic23(uint8 addr, uint16 dat)
{
uint8 i;
dat |= addr << 9; // A[15..9]控制地址,A[8..0]控制数据
CS=0;
for (i = 0; i < 16; i++) // 模拟SPI时序发送
{
SCLK = 0;
if ((dat << i) & 0x8000)
SDIN = 1;
else
SDIN = 0;
SCLK = 1;
}
SCLK = 0;
CS = 1;
}
/*
unsigned char getkey()
{
uint8 key;
if(RI)
{
RI = 0;
key = SBUF;
return(key);
}
return(255);
}
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -