/*---------------------------------------------------------------------*/
/* --- Web: www.STCAI.com ---------------------------------------------*/
/*---------------------------------------------------------------------*//*************  功能说明    **************本例程基于AI8051U为主控芯片的实验箱进行编写测试。flash需烧录video.bin\audio.bin\end.bin三个文件,
视频默认fps20,分辨率160*80,rgb565be格式
音频双通道16bit采样率16000,pcm_s16le格式
使用实验箱自带128Mbit W25Q大概存储25s音视频。下载时, 选择时钟 40MHz******************************************/#include "config.h"
#include "lcd.h"
#include "flash_spi.h"
#include "I2S.h"
#include "TLV320AIC23.h"
#include "video.h"
#include "stdio.h"
#include "string.h"
#define BAUD (65536 - MAIN_Fosc / 4 / 115200) // 调试串口波特率sbit TIME_PIN = P2^2;
sbit KEY_PIN = P3^4;// 按键所需变量
bit Key_Flag;
bit Test_Start_Flag;
bit SetRegion_Flag;
bit singlePicModel;
WORD Key_cnt;
WORD itv_value;void usart1_spi_init();
void sys_init();void USARTSPI_P2P_SPI_Start();
void set_dma_itv(BYTE xdata *pdat);
extern void SPI_Init(void);
void enablePP(u8 flag)
{if (flag){P4PU = 0x06; // 41 42 上拉P5PU = 0x0c; // 52 53 上拉}else{P4PU = 0x00;P5PU = 0x00;}
}FAT xdata Fat _at_(0); // 文件分配表
DWORD dwOffset;        // 图片数据的偏移地址
int nIndex;            // 图片索引
int nCount;            // 图片数据装载次数
BOOL fLoading;         // 装载数据标志extern bit spiDmaFlag;BYTE flash_spi_shift(BYTE dat)
{enablePP(1);TI = 0;SBUF = dat; // 发送数据while (!TI); // TI标志是主机模式发送/接收数据完成标志return SBUF; // 读取接收的数据
}
BYTE flash_spi_rcv(BYTE dat)
{enablePP(0);TI = 0;SBUF = 0xFF; // 发送数据while (!TI); // TI标志是主机模式发送/接收数据完成标志return SBUF; // 读取接收的数据
}// 向SPI总线传输一个8位数据
void LCD_SPI_WriteData(u8 Data)
{SPSTAT = 0x80 + 0x40; // 清0 SPIF和WCOL标志// SPI_DisableInt();SPDAT = Data; // 发送一个字节while (SPIF == 0);                 // 等待发送完成// SPI_EnableInt();
}void main()
{int i;sys_init();        // 系统初始化CLKSEL = 0x00;HSCLKDIV = 1;SPI_CLKDIV = 1;   usart1_spi_init(); // USART1使能SPI模式初始化SPI_Init();I2S_Init();usb_init();        // USB初始化EA = 1;while (DeviceState != DEVSTATE_CONFIGURED){}; // 等待USB完成配置delay_ms(1000);AIC23_Init();delay_ms(50);AIC32_InitSet();SetHeadPhoneVolume(60);	//设置音量nIndex = 0;nCount = 0;lcd_initial();TFT_Clear(RED);spiDmaFlag = 0;Test_Start_Flag = 0;singlePicModel = 0;vInfo.isPlay = 0;while (1){video_play_run();if (bUsbOutReady){if (strncmp(UsbOutBuffer,"video",4) == 0){video_play_init();}else{printf("USB OUT DONE\r\n");}memset(UsbOutBuffer, 0, 64);usb_OUT_done(); // 接收应答(固定格式)}}
}void sys_init()
{WTST = 0;  // 设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快EAXFR = 1; // 扩展寄存器(XFR)访问使能CKCON = 0; // 提高访问XRAM速度P0M1 = 0x00;P0M0 = 0x00; // 设置为准双向口P1M1 = 0x00;P1M0 = 0x00; // 设置为准双向口P2M1 = 0x00;P2M0 = 0x00; // 设置为准双向口P3M1 = 0x00;P3M0 = 0x00; // 设置为准双向口P4M1 = 0x00;P4M0 = 0x00; // 设置为准双向口P5M1 = 0x00;P5M0 = 0x00; // 设置为准双向口P6M1 = 0x00;P6M0 = 0x00; // 设置为准双向口P7M1 = 0x00;P7M0 = 0x00; // 设置为准双向口P1SR = 0;P2SR = 0;P3SR = 0;	//	设置为高速模式P4SR = 0; // P4.0~P4.3快速翻转P5SR = 0;P4M0 = 0x09;P4M1 = 0x00; // 40 43 强推挽enablePP(1);P3M1 = 0x00; P1M0 = 0x02;P1M1 = 0x00; // 11 强推挽P4M0 |= 0x80;P4M0 &= ~0x80; // 47 强推挽
}void usart1_spi_init()
{S1SPI_S1 = 1; // 00: P1.4 P1.5 P1.6 P1.7, 01: P2.4 P2.5 P2.6 P2.7, 10: P4.0 P4.1 P4.2 P4.3, 11: P3.5 P3.4 P3.3 P3.2S1SPI_S0 = 0; // 切换S1SPI到P4.0/S1SS,P4.1/S1MOSI,P4.2/S1MISO,P4.3/S1SCLKSCON = 0x10;  // 使能接收,必须设置为串口模式0DMA_UR1R_CR = 0x01;DMA_UR1T_CR = 0x00;USARTCR1 = 0x10; // 使能USART1的SPI模式//  USARTCR1 |= 0x40;                   //DORD=1USARTCR1 &= ~0x40; // DORD=0//  USARTCR1 |= 0x04;                   //从机模式USARTCR1 &= ~0x04; // 主机模式USARTCR1 |= 0x00;  // CPOL=0, CPHA=0//  USARTCR1 |= 0x01;                   //CPOL=0, CPHA=1//  USARTCR1 |= 0x02 ;                  //CPOL=1, CPHA=0//  USARTCR1 |= 0x03;                   //CPOL=1, CPHA=1USARTCR4 = 0x00; // SPI速度为SYSCLK/4// USARTCR4 = 0x01;                    //SPI速度为SYSCLK/8// USARTCR4 = 0x02;                    //SPI速度为SYSCLK/16//USARTCR4 = 0x03;                    //SPI速度为SYSCLK/2itv_value = 0;DMA_UR1_ITVH = (BYTE)(itv_value >> 8);DMA_UR1_ITVL = (BYTE)(itv_value & 0xFF);USARTCR1 |= 0x08; // 使能SPI功能	
}void flash_read_2_spi(DWORD addr, WORD len)
{WORD sz;BYTE *ptr;WORD bufferAddr = 0x8000;while (flash_is_busy());//if (nCount == 1) //大屏需要分包发送,第一包设置窗口{TFT_SET_ADD(0x0000, 0x0000, TFT_COLUMN_NUMBER - 1, TFT_LINE_NUMBER - 1);}S1SS = 0;flash_spi_shift(0x03); // 发送读取FLASH数据命令flash_spi_shift((BYTE)(addr >> 16));flash_spi_shift((BYTE)(addr >> 8));flash_spi_shift((BYTE)(addr)); // 设置目标地址enablePP(0);len--;              // DMA传输字节数比实际少1DMA_P2P_CR1 = 0x15; // P2P_USART | P2P_SPIlcd_cs_pin = 0;spiDmaFlag = 0;DMA_SPI_Disable();DMA_SPI_DisableInt();DMA_SPI_ClearFlag(); // 清除SPI DMA中断标志DMA_SPI_SetAmount(len);//HSSPI_EnableFIFO();HSSPI_DisableFIFO();DMA_SPI_Enable();//DMA_UR1R_CFG = 0x00; // 关闭DMA中断DMA_UR1R_CFG = 0x80;DMA_UR1R_STA = 0x00; // 清除DMA状态DMA_UR1R_AMT = len;  // 设置DMA传输字节数DMA_UR1R_AMTH = len >> 8;DMA_UR1R_CR = 0x81; // 使能DMA,清空接收FIFO//注意:接收数据时必须同时启动发送DMA//DMA_UR1T_CFG = 0x00; // 关闭DMA中断DMA_UR1T_CFG = 0x80;DMA_UR1T_STA = 0x00; // 清除DMA状态DMA_UR1T_AMT = len;  // 设置DMA传输字节数DMA_UR1T_AMTH = len >> 8;DMA_UR1T_CR = 0x80;TIME_PIN = 1;DMA_UR1T_CR = 0xc0; // 使能DMA,触发串口1发送数据DMA_UR1R_CR = 0xa0;printf("DMA START \r\n");
}void delay_ms(WORD ms)
{WORD i;do{i = MAIN_Fosc / 6000;while (--i);} while (--ms);
}void DMA_UR2R_ISR() interrupt DMA_UR2R_VECTOR
{if (DMA_UR2R_STA & 0x01) // 接收完成{DMA_UR2R_STA &= ~0x01;DMA_UR2R_CR = 0;DMA_P2P_CR2 = 0;}if (DMA_UR2R_STA & 0x02) // 数据丢弃{DMA_UR2R_STA &= ~0x02;}
}
void DMA_UR1R_ISR() interrupt DMA_UR1R_VECTOR
{if (DMA_UR1R_STA & 0x02) // 数据丢弃{//printf("DMA UR1R LOSS \r\n");DMA_UR1R_STA &= ~0x02;}if (DMA_UR1R_STA & 0x01) {TIME_PIN =0;if (DMA_UR1R_STA & 0x01){//printf("DMA UR1R END \r\n");}// DMA_SPI_ClearFlag(); // 清除SPI DMA中断标志// DMA_UR1T_STA = 0x00; // 清除DMA状态// DMA_UR1T_CR = 0x00;  // 关闭DMADMA_UR1R_STA = 0x00; // 清除DMA状态// DMA_UR1R_CR = 0x00;  // 关闭DMAS1SS = 1;DMA_P2P_CR1 = 0; // 关闭P2PSPSTAT = 0x80 + 0x40; // 清0 SPIF和WCOL标志 HSSPI_DisableFIFO();  // 使用SPI查询或中断方式时,要禁止FIFOlcd_cs_pin = 1;spiDmaFlag = 1;}}
void DMA_UR1T_ISR() interrupt DMA_UR1T_VECTOR
{if (DMA_UR1T_STA & 0x01){DMA_UR1T_STA = 0x00; // 清除DMA状态DMA_UR1T_CR = 0x00;  // 关闭DMA}
}