玩这个真是太少了,怎么验证对不对,因为是基于DISCO肯定是没问题,所以先试试分析逻辑,发现他把整个QSPI Flash当WAV文件看了.为了保证文件完整没BUG,我就用最高采样率,录满所有音频,然后等下保存下QSPI的内容,看看结果.
PS:实际上DISCO的例程有QSPI_STORAGE和RECORD_LOOPBACK两种,但是我们最终音频肯定要储存分析的.所以只能选QSPI_STORAGE,Flash大小是0xFA0000,因为型号是N25Q128,WAV头大小是44字节.然后DISCO的程序反正都是要全擦用来记文件,为什么是擦一下写一下,为什么不开机执行Mass Erase,搞不懂呢.虽然音频速度不快~
然后读取这么慢,可能是因为STM32是USB 1.1的,再加上还要走一段路才能回来.
然后发现开机就执行BSP_QSPI_Erase_Sector,移动一下这个函数位置,让他开机不要立马擦,不然怎么都dump不出数据.第二个坑,用STLINK竟然DUMP不出数据,提示cannot save hex/srec file to bin file,用命令行就没问题了.注意路径不能有空格,也不能太深,也不能太长文件名.什么鬼,说我76.7V了.STLINK好处是,官方板的外部loader都自带了.但是其实stlink速度感觉没jlink快.
不会的话就客户端然后用HEX2BIN软件也行.验证是可以听得...保存出来的确实是WAV.
因为上一节入坑已经分析了DFSDM的基本逻辑,现在分析QSPI的基本逻辑,他是怎么写数据进去的.之前就知道WAV有头,RIFF什么的.初始化时候就擦掉了0扇区,以便一开始就能录音.然后跳到AudioRecorder_Run->AudioRecorder_Start.初始化的结构体,还不知道音频文件多大.
/* Initialize the WAV header */ WavHeader.SampleRate = RECORD_SAMPLE_RATE; WavHeader.NumChannels = DEFAULT_AUDIO_IN_CHANNEL_NBR; WavHeader.BitsPerSample = DEFAULT_AUDIO_IN_BIT_RESOLUTION; WavHeader.AudioLength = 0; WavHeader.AudioStartAddr = WAV_HEADER_SIZE; WavHeader.RIFFchunksize = WAV_HEADER_SIZE; WavHeader.FormatTag = 1; WavHeader.ByteRate = WavHeader.SampleRate * (WavHeader.BitsPerSample/8) * WavHeader.NumChannels; WavHeader.BlockAlign = WavHeader.NumChannels * (WavHeader.BitsPerSample/8); WavHeader.DataSize = 0;
但是会先把他编程进去,我就奇怪了,把Length填0,那么岂不是等下还要擦掉才能写长度?果然是这样的.
/* Write the number of sample data ------------------------------------------*/ /* This field will be overwritten at the end of the recording operation */ WavHeaderBuffer[40] = 0xFC; WavHeaderBuffer[41] = 0x17; WavHeaderBuffer[42] = 0x0A; WavHeaderBuffer[43] = 0x00;
然后到AudioRecorder_Thread.每次都擦掉一下个块.
if ( (BSP_QSPI_GetStatus() == QSPI_OK) && (hAudioRecorder.NextSectorToErase < QSPI_SECTOR_NB)) { if (BSP_QSPI_Erase_Sector(hAudioRecorder.NextSectorToErase) != 0) { Error_Handler(); } hAudioRecorder.NextSectorToErase++; }
结果如下:
/* Read QSPI first sub-sector */ if (BSP_QSPI_Read(hAudioRecorder.QspiSubSector, 0, QSPI_SUBSECTOR_SIZE) != QSPI_OK) { Error_Handler(); } /* Update WAV header */ hAudioRecorder.RecordTotalSize -= 8; pData = (uint32_t*)&hAudioRecorder.QspiSubSector[FILE_SIZE_OFFSET]; *pData = hAudioRecorder.RecordTotalSize; hAudioRecorder.RecordTotalSize -= 44; pData = (uint32_t*)&hAudioRecorder.QspiSubSector[DATA_SIZE_OFFSET]; *pData = hAudioRecorder.RecordTotalSize; /* Erase QSPI first sub-sector */ if (BSP_QSPI_Erase_Block(0) != QSPI_OK) { Error_Handler(); } /* Program QSPI first sub-sector */ if (BSP_QSPI_Write(hAudioRecorder.QspiSubSector, 0, QSPI_SUBSECTOR_SIZE) != QSPI_OK) { Error_Handler(); }