
0.0
Dependencies: DISCO-F746NG_BLOCK_DEVICE_WITH_FAT_FILESYSTEM_ON_SDCARD SDRAM_DISCO_F746NG BSP_DISCO_F746NG BD_SD_DISCO_F746NG AUDIO_DISCO_F746NG
Revision 4:ce6b2364970d, committed 2019-09-05
- Comitter:
- KKBanana
- Date:
- Thu Sep 05 10:16:20 2019 +0000
- Parent:
- 3:7f991a3d4e71
- Commit message:
- 0.0
Changed in this revision
diff -r 7f991a3d4e71 -r ce6b2364970d AUDIO_DISCO_F746NG.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/AUDIO_DISCO_F746NG.lib Thu Sep 05 10:16:20 2019 +0000 @@ -0,0 +1,1 @@ +https://os.mbed.com/users/KKBanana/code/AUDIO_DISCO_F746NG/#523578a63f67
diff -r 7f991a3d4e71 -r ce6b2364970d BD_SD_DISCO_F746NG.lib --- a/BD_SD_DISCO_F746NG.lib Wed Apr 04 19:49:22 2018 +0000 +++ b/BD_SD_DISCO_F746NG.lib Thu Sep 05 10:16:20 2019 +0000 @@ -1,1 +1,1 @@ -https://os.mbed.com/users/roykrikke/code/BD_SD_DISCO_F746NG/#d1d99cfe13df +https://os.mbed.com/users/KKBanana/code/BD_SD_DISCO_F746NG/#37eb200d58b3
diff -r 7f991a3d4e71 -r ce6b2364970d BSP_DISCO_F746NG.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/BSP_DISCO_F746NG.lib Thu Sep 05 10:16:20 2019 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/teams/ST/code/BSP_DISCO_F746NG/#df2ea349c37a
diff -r 7f991a3d4e71 -r ce6b2364970d ItWorks.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ItWorks.lib Thu Sep 05 10:16:20 2019 +0000 @@ -0,0 +1,1 @@ +https://os.mbed.com/users/roykrikke/code/DISCO-F746NG_BLOCK_DEVICE_WITH_FAT_FILES/#7f991a3d4e71
diff -r 7f991a3d4e71 -r ce6b2364970d SDRAM_DISCO_F746NG.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SDRAM_DISCO_F746NG.lib Thu Sep 05 10:16:20 2019 +0000 @@ -0,0 +1,1 @@ +https://developer.mbed.org/teams/ST/code/SDRAM_DISCO_F746NG/#370f402a2219
diff -r 7f991a3d4e71 -r ce6b2364970d main.cpp --- a/main.cpp Wed Apr 04 19:49:22 2018 +0000 +++ b/main.cpp Thu Sep 05 10:16:20 2019 +0000 @@ -18,14 +18,159 @@ #include "mbed.h" #include "FATFileSystem.h" #include "SDBlockDeviceDISCOF746NG.h" +#include "AUDIO_DISCO_F746NG.h" +#include "SDRAM_DISCO_F746NG.h" #include <stdio.h> +#include <stdlib.h> #include <errno.h> +#define AUDIO_IN_PCM_BUFFER_SIZE 4*2304 /* buffer size in half-word */ -DigitalOut led (LED1); +typedef enum { + BUFFER_EMPTY = 0, + BUFFER_FULL, +}WR_BUFFER_StateTypeDef; + + +typedef struct { + uint32_t ChunkID; /* 0 */ + uint32_t FileSize; /* 4 */ + uint32_t FileFormat; /* 8 */ + uint32_t SubChunk1ID; /* 12 */ + uint32_t SubChunk1Size; /* 16*/ + uint16_t AudioFormat; /* 20 */ + uint16_t NbrChannels; /* 22 */ + uint32_t SampleRate; /* 24 */ + + uint32_t ByteRate; /* 28 */ + uint16_t BlockAlign; /* 32 */ + uint16_t BitPerSample; /* 34 */ + uint32_t SubChunk2ID; /* 36 */ + uint32_t SubChunk2Size; /* 40 */ +} WAVE_FormatTypeDef; + +typedef struct { + uint16_t pcm_buff[AUDIO_IN_PCM_BUFFER_SIZE]; + uint32_t pcm_ptr; + WR_BUFFER_StateTypeDef wr_state; + uint32_t offset; + uint32_t fptr; +}AUDIO_IN_BufferTypeDef; + +static uint32_t WavProcess_EncInit(uint32_t Freq, uint8_t* pHeader); +static uint32_t WavProcess_HeaderInit(uint8_t* pHeader, WAVE_FormatTypeDef* pWaveFormatStruct); // Instantiate the Block Device for sd card on DISCO-F746NG SDBlockDeviceDISCOF746NG bd; +AUDIO_DISCO_F746NG audio; +// audio IN_OUT buffer is stored in the SDRAM, SDRAM needs to be initialized and FMC enabled +SDRAM_DISCO_F746NG sdram; FATFileSystem fs ("fs"); +//static AUDIO_IN_BufferTypeDef BufferCtl; +static __IO uint32_t uwVolume = 100; +extern WAVE_FormatTypeDef WaveFormat; +extern FIL WavFile; +//static uint32_t display_update = 1; + +static uint32_t WavProcess_EncInit(uint32_t Freq, uint8_t *pHeader) +{ + /* Initialize the encoder structure */ + WaveFormat.SampleRate = Freq; /* Audio sampling frequency */ + WaveFormat.NbrChannels = 2; /* Number of channels: 1:Mono or 2:Stereo */ + WaveFormat.BitPerSample = 16; /* Number of bits per sample (16, 24 or 32) */ + WaveFormat.FileSize = 0x001D4C00; /* Total length of useful audio data (payload) */ + WaveFormat.SubChunk1Size = 44; /* The file header chunk size */ + WaveFormat.ByteRate = (WaveFormat.SampleRate * \ + (WaveFormat.BitPerSample/8) * \ + WaveFormat.NbrChannels); /* Number of bytes per second (sample rate * block align) */ + WaveFormat.BlockAlign = WaveFormat.NbrChannels * \ + (WaveFormat.BitPerSample/8); /* channels * bits/sample / 8 */ + + /* Parse the wav file header and extract required information */ + if(WavProcess_HeaderInit(pHeader, &WaveFormat)) { + return 1; + } + return 0; +} + +static uint32_t WavProcess_HeaderInit(uint8_t* pHeader, WAVE_FormatTypeDef* pWaveFormatStruct) +{ + /* Write chunkID, must be 'RIFF' ------------------------------------------*/ + pHeader[0] = 'R'; + pHeader[1] = 'I'; + pHeader[2] = 'F'; + pHeader[3] = 'F'; + + /* Write the file length ---------------------------------------------------*/ + /* The sampling time: this value will be written back at the end of the + recording operation. Example: 661500 Btyes = 0x000A17FC, byte[7]=0x00, byte[4]=0xFC */ + pHeader[4] = 0x00; + pHeader[5] = 0x4C; + pHeader[6] = 0x1D; + pHeader[7] = 0x00; + /* Write the file format, must be 'WAVE' -----------------------------------*/ + pHeader[8] = 'W'; + pHeader[9] = 'A'; + pHeader[10] = 'V'; + pHeader[11] = 'E'; + + /* Write the format chunk, must be'fmt ' -----------------------------------*/ + pHeader[12] = 'f'; + pHeader[13] = 'm'; + pHeader[14] = 't'; + pHeader[15] = ' '; + + /* Write the length of the 'fmt' data, must be 0x10 ------------------------*/ + pHeader[16] = 0x10; + pHeader[17] = 0x00; + pHeader[18] = 0x00; + pHeader[19] = 0x00; + + /* Write the audio format, must be 0x01 (PCM) ------------------------------*/ + pHeader[20] = 0x01; + pHeader[21] = 0x00; + + /* Write the number of channels, ie. 0x01 (Mono) ---------------------------*/ + pHeader[22] = pWaveFormatStruct->NbrChannels; + pHeader[23] = 0x00; + + /* Write the Sample Rate in Hz ---------------------------------------------*/ + /* Write Little Endian ie. 8000 = 0x00001F40 => byte[24]=0x40, byte[27]=0x00*/ + pHeader[24] = (uint8_t)((pWaveFormatStruct->SampleRate & 0xFF)); + pHeader[25] = (uint8_t)((pWaveFormatStruct->SampleRate >> 8) & 0xFF); + pHeader[26] = (uint8_t)((pWaveFormatStruct->SampleRate >> 16) & 0xFF); + pHeader[27] = (uint8_t)((pWaveFormatStruct->SampleRate >> 24) & 0xFF); + + /* Write the Byte Rate -----------------------------------------------------*/ + pHeader[28] = (uint8_t)((pWaveFormatStruct->ByteRate & 0xFF)); + pHeader[29] = (uint8_t)((pWaveFormatStruct->ByteRate >> 8) & 0xFF); + pHeader[30] = (uint8_t)((pWaveFormatStruct->ByteRate >> 16) & 0xFF); + pHeader[31] = (uint8_t)((pWaveFormatStruct->ByteRate >> 24) & 0xFF); + + /* Write the block alignment -----------------------------------------------*/ + pHeader[32] = pWaveFormatStruct->BlockAlign; + pHeader[33] = 0x00; + + /* Write the number of bits per sample -------------------------------------*/ + pHeader[34] = pWaveFormatStruct->BitPerSample; + pHeader[35] = 0x00; + + /* Write the Data chunk, must be 'data' ------------------------------------*/ + pHeader[36] = 'd'; + pHeader[37] = 'a'; + pHeader[38] = 't'; + pHeader[39] = 'a'; + + /* Write the number of sample data -----------------------------------------*/ + /* This variable will be written back at the end of the recording operation */ + pHeader[40] = 0x00; + pHeader[41] = 0x4C; + pHeader[42] = 0x1D; + pHeader[43] = 0x00; + + /* Return 0 if all operations are OK */ + return 0; +} + void return_error (int ret_val) @@ -44,72 +189,122 @@ else printf (" done.\r\n"); } +typedef enum { + BUFFER_OFFSET_NONE = 0, + BUFFER_OFFSET_HALF = 1, + BUFFER_OFFSET_FULL = 2, +} BUFFER_StateTypeDef; + +#define AUDIO_BLOCK_SIZE ((uint32_t)12800) +#define AUDIO_BUFFER_IN SDRAM_DEVICE_ADDR /* In SDRAM */ +__IO uint32_t audio_rec_buffer_state = BUFFER_OFFSET_NONE; +static uint8_t SetSysClock_PLL_HSE_200MHz(); int main () { Serial pc (SERIAL_TX, SERIAL_RX); - pc.baud(115200); + SetSysClock_PLL_HSE_200MHz(); + pc.baud(9600); printf("Start\n"); - int error = 0; - printf("Welcome to the filesystem example.\r\n" - "Formatting a FAT, RAM-backed filesystem. "); error = FATFileSystem::format(&bd); return_error(error); - - printf("Mounting the filesystem on \"/fs\". "); error = fs.mount(&bd); return_error(error); - - printf("Opening a new file, numbers.txt."); - FILE* fd = fopen("/fs/numbers.txt", "w"); - errno_error(fd); - - for (int i = 0; i < 20; i++) { - printf("Writing decimal numbers to a file (%d/20)\r", i); - fprintf(fd, "%d\r\n", i); + FILE* fd; + int filenum = 0,filecount = 0; + char filenums[1000]; + memset((uint16_t*)AUDIO_BUFFER_IN, 0, AUDIO_BLOCK_SIZE*2); + audio_rec_buffer_state = BUFFER_OFFSET_NONE; + audio.IN_Record((uint16_t*)AUDIO_BUFFER_IN, AUDIO_BLOCK_SIZE); + uint8_t pHeaderBuff[44]; + while(true) { + if(filecount == 0) { + sprintf(filenums,"/fs/%d.wav",filenum++); + fd = fopen(filenums, "wb"); + errno_error(fd); + WavProcess_EncInit(DEFAULT_AUDIO_IN_FREQ, pHeaderBuff); + fwrite(pHeaderBuff,sizeof(uint8_t), 44,fd); + } + BSP_AUDIO_IN_Resume(); + while(audio_rec_buffer_state == BUFFER_OFFSET_HALF) { + } + audio_rec_buffer_state = BUFFER_OFFSET_NONE; + BSP_AUDIO_IN_Pause(); + fwrite ((uint16_t *)(AUDIO_BUFFER_IN), 1, AUDIO_BLOCK_SIZE, fd); + BSP_AUDIO_IN_Resume(); + while(audio_rec_buffer_state == BUFFER_OFFSET_FULL) { + } + audio_rec_buffer_state = BUFFER_OFFSET_NONE; + BSP_AUDIO_IN_Pause(); + fwrite ((uint16_t *)(AUDIO_BUFFER_IN + (AUDIO_BLOCK_SIZE)), 1, AUDIO_BLOCK_SIZE, fd); + if(filecount++ == 100) { + filecount = 0; + printf("Closing %d.",filenum-1); + fclose(fd); + printf(" done.\r\n"); + } } - printf("Writing decimal numbers to a file (20/20) done.\r\n"); +} - printf("Closing file."); - fclose(fd); - printf(" done.\r\n"); - - printf("Re-opening file read-only."); - fd = fopen("/fs/numbers.txt", "r"); - errno_error(fd); - printf("Dumping file to screen.\r\n"); - char buff[16] = { 0 }; - while(!feof (fd)) { - int size = fread(&buff[0], 1, 15, fd); - fwrite(&buff[0], 1, size, stdout); - } - printf("EOF.\r\n"); +void BSP_AUDIO_IN_TransferComplete_CallBack(void) +{ + audio_rec_buffer_state = BUFFER_OFFSET_FULL; + return; +} + +/** + * @brief Manages the DMA Half Transfer complete interrupt. + * @param None + * @retval None + */ +void BSP_AUDIO_IN_HalfTransfer_CallBack(void) +{ + audio_rec_buffer_state = BUFFER_OFFSET_HALF; + return; +} - printf("Closing file."); - fclose(fd); - printf(" done.\r\n"); +static uint8_t SetSysClock_PLL_HSE_200MHz() +{ + RCC_ClkInitTypeDef RCC_ClkInitStruct; + RCC_OscInitTypeDef RCC_OscInitStruct; + + // Enable power clock + __PWR_CLK_ENABLE(); - printf("Opening root directory."); - DIR* dir = opendir("/fs/"); - errno_error(fd); + // Enable HSE oscillator and activate PLL with HSE as source + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; + RCC_OscInitStruct.HSEState = RCC_HSE_ON; /* External xtal on OSC_IN/OSC_OUT */ - struct dirent* de; - printf("Printing all filenames:\r\n"); - while((de = readdir (dir)) != NULL) { - printf(" %s\r\n", &(de->d_name)[0]); + // Warning: this configuration is for a 25 MHz xtal clock only + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; + RCC_OscInitStruct.PLL.PLLM = 25; // VCO input clock = 1 MHz (25 MHz / 25) + RCC_OscInitStruct.PLL.PLLN = 400; // VCO output clock = 400 MHz (1 MHz * 400) + RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; // PLLCLK = 200 MHz (400 MHz / 2) + RCC_OscInitStruct.PLL.PLLQ = 8; // USB clock = 50 MHz (400 MHz / 8) + + if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { + return 0; // FAIL } - printf("Closeing root directory. "); - error = closedir(dir); - return_error(error); - printf("Filesystem Demo complete.\r\n"); + // Activate the OverDrive to reach the 216 MHz Frequency + if (HAL_PWREx_EnableOverDrive() != HAL_OK) { + return 0; // FAIL + } - // Blink led with 2 Hz - while(true) { - led = !led; - wait (0.5); + // Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers + RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; // 200 MHz + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; // 200 MHz + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4; // 50 MHz + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; // 100 MHz + + if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_7) != HAL_OK) { + return 0; // FAIL } + HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_HSE, RCC_MCODIV_4); + return 1; // OK }