void FMD_Write2Byte(void* pBuf, unsigned int u32StartAddr) { unsigned int i; uint32_t MoreByte = u32StartAddr%PAGE_SIZE; SPI1_Write_Enable(); __SPI1_CS_ACTIVE /* activate */ SPI1_SendInt((IS_PAGE_PROGRAM << 24) | (u32StartAddr - MoreByte)); /* Write page program command */ /* Write data to SPI Flash */ for ( i = 0; i < PAGE_SIZE; i++ ) { if(i == MoreByte) SPI1_SendByte(((unsigned char *)pBuf)[0]); else if(i == (MoreByte+1)) SPI1_SendByte(((unsigned char *)pBuf)[1]); else SPI1_SendByte(0xFF); } __SPI1_CS_INACTIVE /* deactivate */ WaitWriteComplete(); }
//myAccel3LV02의 특정 레지스터에서 데이터를 읽어옴 unsigned char Accel_ReadReg(unsigned char reg) { uint8_t ret = 0; // CS를 low로 떨어트려서 SPI 통신 시작. SPI1_CS_LOW(); /* * register address를 송신. Read일 경우 최상의 비트는 High * 송신 완료될때까지 대기. * 수신된 데이터를 저장. 이 데이터는 더미데이터 이다. */ ret = SPI1_SendByte(0x80|reg); /* * 더미 데이터를 송신. * 송신 완료될때까지 대기. * 수신된 data byte를 저장. */ ret = SPI1_SendByte(0); // CS를 high로 올려주면서 SPI 통신 종료. SPI1_CS_HIGH(); return ret; }
//myAccel3LV02의 특정 레지스터에 데이터를 기록 void Accel_WriteReg(unsigned char reg, unsigned char data) { // CS를 low로 떨어트려서 SPI 통신 시작. SPI1_CS_LOW(); // register address를 송신. // 송신 완료될때까지 대기. SPI1_SendByte(reg); // data 송신. // 송신 완료될때까지 대기. SPI1_SendByte(data); // CS를 high로 올려주면서 SPI 통신 종료. SPI1_CS_HIGH(); }
void SPI_Init(void) { //DrvSPI_Open(eDRVSPI_PORT0, eDRVSPI_MASTER, eDRVSPI_TYPE1, 32); SYSCLK->APBCLK.SPI0_EN = 1; SYS->IPRSTC2.SPI0_RST = 1; SYS->IPRSTC2.SPI0_RST = 0; SYS->GPA_ALT.GPA0 = 1; // MOSI0 SYS->GPA_ALT.GPA1 = 1; // SCLK SYS->GPA_ALT.GPA2 = 1; // SSB0 SYS->GPA_ALT.GPA3 = 1; // MISO0 /* Check busy*/ while(SPI0->CNTRL.GO_BUSY) {} SPI0->CNTRL.TX_BIT_LEN = 8; // //DrvSPI_SetBitLength(eDRVSPI_PORT0, 8); SPI0->JS.JS = 0; // DrvSPI_DisableAutoCS(eDRVSPI_PORT0); SPI0->SSR.SSR = eDRVSPI_NONE; SPI0->SSR.ASS = 0; //eDRVSPI_TYPE1 SPI0->CNTRL.CLKP = 0; SPI0->CNTRL.TX_NEG = 1; SPI0->CNTRL.RX_NEG = 0; // set SPI clk SPI0->DIVIDER.DIVIDER = 2; SPI0->DIVIDER.DIVIDER2 = 1; SPI0->CNTRL.LSB = 0; //DrvSPI_SetEndian(eDRVSPI_PORT0, eDRVSPI_MSB_FIRST); SPI0->CNTRL.SLEEP = 0; //DrvSPI_SetByteSleep(eDRVSPI_PORT0, FALSE); SPI0->CNTRL.BYTE_ENDIAN = 0; //DrvSPI_SetByteEndian(eDRVSPI_PORT0, FALSE); SPI0->SSR.SS_LVL = eDRVSPI_ACTIVE_LOW_FALLING; //DrvSPI_SetSlaveSelectActiveLevel(eDRVSPI_PORT0, eDRVSPI_ACTIVE_LOW_FALLING); //DrvSPI_BurstTransfer(eDRVSPI_PORT0, 1, 2); SPI0->CNTRL.TX_NUM = 1 - 1; SPI0->CNTRL.SLEEP = 2 - 2; /* * Release from power down */ __SPI1_CS_ACTIVE SPI1_SendByte(IS_Release_DP); __SPI1_CS_INACTIVE // Delay for a while (3us) for waiting SPIFlash stable //HW_WaitTimeout(3); /* { // 测试数据读取 unsigned char buff[16]; FMD_ReadData(buff, 0x340, 4); FMD_ReadData(buff, 0x340, 4); FMD_ReadData(buff, 0x340, 4); } */ }
// Wait write operation complete __inline void WaitWriteComplete(void) { uint32_t u32TimeOut, i; u32TimeOut = 10; __WaitWriteComplete_BUS_ERROR: i = 1000; __SPI1_CS_ACTIVE SPI1_SendByte(IS_READ_STATUS_REGISTER); //LOG(("/")); while ( 1 ) { unsigned char uSR = SPI1_ReadByte(); if ( !(uSR & SR_BIT0_BUSY) ) { break; } if ( u32TimeOut-- ) { while ( i-- ) { __SPI1_CS_INACTIVE } goto __WaitWriteComplete_BUS_ERROR; } //LOG(("-")); } __SPI1_CS_INACTIVE }
void FMD_WriteData(void* pBuf, unsigned int u32StartAddr) { unsigned int i; // WaitWriteComplete(); SPI1_Write_Enable(); __SPI1_CS_ACTIVE /* activate */ SPI1_SendInt((IS_PAGE_PROGRAM << 24) | u32StartAddr); /* Write page program command */ /* Write data to SPI Flash */ for ( i = 0; i < PAGE_SIZE; i++ ) { SPI1_SendByte(((unsigned char *)pBuf)[i]); } __SPI1_CS_INACTIVE /* deactivate */ // WEL bit is automatically reset after Power-up and upon completion of the // Write status register, Page program, Sector Erase, Block erase and Chip erase instruction. // SPI1_Write_Disable();; // Wait for complete WaitWriteComplete(); }
__inline void SPI1_Write_Enable() { __SPI1_CS_ACTIVE SPI1_SendByte(IS_WRITE_ENABLE); __SPI1_CS_INACTIVE }
BOOL SPI_CheckWriteBusy(void) { unsigned char uSR; // Read status register __SPI1_CS_ACTIVE SPI1_SendByte(IS_READ_STATUS_REGISTER); uSR = SPI1_ReadByte(); __SPI1_CS_INACTIVE return (uSR & SR_BIT0_BUSY); }
// Wait write operation complete __inline void WaitWriteComplete(void) { // Read status register __SPI1_CS_ACTIVE SPI1_SendByte(IS_READ_STATUS_REGISTER); while ( 1 ) { unsigned char uSR = SPI1_ReadByte(); if ( !(uSR & SR_BIT0_BUSY) ) { break; } } __SPI1_CS_INACTIVE }
void SPI_Term(void) { /* * SPIFlash power down mode */ __SPI1_CS_ACTIVE SPI1_SendByte(IS_Power_Down); __SPI1_CS_INACTIVE //DrvSPI_Close(eDRVSPI_PORT0); /* Wait SPIMS Busy */ while(SPI0->CNTRL.GO_BUSY) {} SYS->IPRSTC2.SPI0_RST = 1; SYS->IPRSTC2.SPI0_RST = 0; SYSCLK->APBCLK.SPI0_EN = 0; }
BYTE MEGA8_ADCRead(BYTE channel) { BYTE adcVal = 0; DWORD i = 0; IOCLR0 |= SPI1_SLAVE_SELECT; // slave select enable SPI1_SendByte(channel); //Delay for settling down (80 uS) for (i=0; i<1000; i++); adcVal = SPI1_ReceiveByte(); IOSET0 |= SPI1_SLAVE_SELECT; // slave select disable //Delay for settling down (80 uS) for (i=0; i<1000; i++); return adcVal; }
/**************************************************************************** * 名 称:void Play_Music(void) * 功 能:TXT文件输出函数 * 入口参数:无 * 出口参数:无 * 说 明: * 调用方法:无 ****************************************************************************/ void Play_Music(void) { FILINFO finfo; DIR dirs; unsigned int count=0; char path[50]={""},j=0; char *result1,*result2,*result3,*result4; /*开启长文件名功能时, 要预先初始化文件名缓冲区的长度 */ #if _USE_LFN static char lfn[_MAX_LFN * (_DF1S ? 2 : 1) + 1]; finfo.lfname = lfn; finfo.lfsize = sizeof(lfn); #endif USART_OUT(USART1,"\n文件系统(Tini-FatFS0.09a)启动成功! \n"); disk_initialize(0); //fatfs可以管理多个介质的分区, 所以把物理存储介质SST25VF016B标示为0区,相当于磁盘编号 VS1003_start(); f_mount(0, &fs); //将文件系统设置到0区 if (f_opendir(&dirs, path) == FR_OK) //读取该磁盘的根目录 { while (f_readdir(&dirs, &finfo) == FR_OK) //循环依次读取文件名 { if (finfo.fattrib & AM_ARC) //判断文件属性是否为存档型 TXT文件一般都为存档型 { if(!finfo.fname[0]) break; //如果是文件名为空表示到目录的末尾。退出 if(finfo.lfname[0]){ //长文件名 USART_OUT(USART1,"\r\n文件名是:\n %s\n",finfo.lfname); //输出文件名 result1=strstr(finfo.lfname,".mp3"); //比较后缀是否为音频文件 result2=strstr(finfo.lfname,".mid"); //比较后缀是否为音频文件 result3=strstr(finfo.lfname,".wav"); //比较后缀是否为音频文件 result4=strstr(finfo.lfname,".wma"); //比较后缀是否为音频文件 } else{ //8.3格式文件名 USART_OUT(USART1,"\r\n文件名是:\n %s\n",finfo.fname); //输出文件名 result1=strstr(finfo.fname,".mp3"); //比较后缀是否为音频文件 result2=strstr(finfo.fname,".mid"); //比较后缀是否为音频文件 result3=strstr(finfo.fname,".wav"); //比较后缀是否为音频文件 result4=strstr(finfo.fname,".wma"); //比较后缀是否为音频文件 } if(result1!=NULL||result2!=NULL||result3!=NULL||result4!=NULL){ if(finfo.lfname[0]){ //长文件名 res = f_open(&fsrc, finfo.lfname, FA_OPEN_EXISTING | FA_READ); } else{ //8.3格式文件名 res = f_open(&fsrc, finfo.fname, FA_OPEN_EXISTING | FA_READ); } USART_OUT(USART1,"\r\n Playing..."); br=1; XDCS_SET(0); //xDCS = 0,选择vs1003的数据接口 LED1_ON; for (;;) { res = f_read(&fsrc, buffer, sizeof(buffer), &br); if(res==0){ count=0; Delay_us(1000); while(count<512){ //根据SD卡介质的原因,文件每次只能读出512字节 if(DREQ!=0){ //VS1003数据申请口线, 每次为高后,可以通过SPI2写入32字节的音频数据 for(j=0;j<32;j++) //每次送32个数据 { VS1003_WriteByte(buffer[count]); //写入音频数据 /*修改的地方*/ // USART_OUT(USART1,"%d\n",buffer[count]); SPI1_SendByte(buffer[count]); count++; } } if (res || br == 0) break; // 是否到文件尾 } } if (res || br == 0) break; // 是否到文件尾 } LED1_OFF; count=0; while(count<2048){ //根据VS1003的特性,需要音乐文件的末尾发送一些个0 ,保证下一个音频文件的播放 if(DREQ!=0){ for(j=0;j<32;j++) //每次送32个数据 { VS1003_WriteByte(0); count++; } } } XDCS_SET(1); f_close(&fsrc); } } } } }
uint8 IINCHIP_SpiSendData(uint8 dat) { return(SPI1_SendByte(dat)); }