AUDIO DISCO_F746NG audioloop basic example

Dependencies:   BSP_DISCO_F746NG

Committer:
jeromecoutant
Date:
Thu Jun 08 13:21:00 2017 +0000
Revision:
4:bf9ab5993081
Parent:
0:da04816fb411
Child:
5:66c230f74325
Update libs

Who changed what in which revision?

UserRevisionLine numberNew contents of line
adustm 0:da04816fb411 1 #include "mbed.h"
adustm 0:da04816fb411 2 #include "AUDIO_DISCO_F746NG.h"
adustm 0:da04816fb411 3 #include "SDRAM_DISCO_F746NG.h"
adustm 0:da04816fb411 4
adustm 0:da04816fb411 5 AUDIO_DISCO_F746NG audio;
adustm 0:da04816fb411 6 // audio IN_OUT buffer is stored in the SDRAM, SDRAM needs to be initialized and FMC enabled
adustm 0:da04816fb411 7 SDRAM_DISCO_F746NG sdram;
adustm 0:da04816fb411 8
adustm 0:da04816fb411 9 DigitalOut led_green(LED1);
adustm 0:da04816fb411 10 DigitalOut led_red(LED2);
adustm 0:da04816fb411 11 Serial pc(USBTX, USBRX);
adustm 0:da04816fb411 12
adustm 0:da04816fb411 13 typedef enum
adustm 0:da04816fb411 14 {
adustm 0:da04816fb411 15 BUFFER_OFFSET_NONE = 0,
adustm 0:da04816fb411 16 BUFFER_OFFSET_HALF = 1,
adustm 0:da04816fb411 17 BUFFER_OFFSET_FULL = 2,
adustm 0:da04816fb411 18 }BUFFER_StateTypeDef;
adustm 0:da04816fb411 19
adustm 0:da04816fb411 20 #define AUDIO_BLOCK_SIZE ((uint32_t)512)
adustm 0:da04816fb411 21 #define AUDIO_BUFFER_IN SDRAM_DEVICE_ADDR /* In SDRAM */
adustm 0:da04816fb411 22 #define AUDIO_BUFFER_OUT (SDRAM_DEVICE_ADDR + (AUDIO_BLOCK_SIZE * 2)) /* In SDRAM */
adustm 0:da04816fb411 23 __IO uint32_t audio_rec_buffer_state = BUFFER_OFFSET_NONE;
adustm 0:da04816fb411 24 static uint8_t SetSysClock_PLL_HSE_200MHz();
adustm 0:da04816fb411 25 int main()
adustm 0:da04816fb411 26 {
adustm 0:da04816fb411 27 SetSysClock_PLL_HSE_200MHz();
adustm 0:da04816fb411 28 pc.baud(9600);
adustm 0:da04816fb411 29
adustm 0:da04816fb411 30 pc.printf("\n\nAUDIO LOOPBACK EXAMPLE START:\n");
adustm 0:da04816fb411 31 led_red = 0;
adustm 0:da04816fb411 32
adustm 0:da04816fb411 33 pc.printf("\nAUDIO RECORD INIT OK\n");
adustm 0:da04816fb411 34 pc.printf("Microphones sound streamed to headphones\n");
adustm 0:da04816fb411 35
adustm 0:da04816fb411 36 /* Initialize SDRAM buffers */
adustm 0:da04816fb411 37 memset((uint16_t*)AUDIO_BUFFER_IN, 0, AUDIO_BLOCK_SIZE*2);
adustm 0:da04816fb411 38 memset((uint16_t*)AUDIO_BUFFER_OUT, 0, AUDIO_BLOCK_SIZE*2);
adustm 0:da04816fb411 39 audio_rec_buffer_state = BUFFER_OFFSET_NONE;
adustm 0:da04816fb411 40
adustm 0:da04816fb411 41 /* Start Recording */
adustm 0:da04816fb411 42 audio.IN_Record((uint16_t*)AUDIO_BUFFER_IN, AUDIO_BLOCK_SIZE);
adustm 0:da04816fb411 43
adustm 0:da04816fb411 44 /* Start Playback */
adustm 0:da04816fb411 45 audio.OUT_SetAudioFrameSlot(CODEC_AUDIOFRAME_SLOT_02);
adustm 0:da04816fb411 46 audio.OUT_Play((uint16_t*)AUDIO_BUFFER_OUT, AUDIO_BLOCK_SIZE * 2);
adustm 0:da04816fb411 47
adustm 0:da04816fb411 48
adustm 0:da04816fb411 49 while (1) {
adustm 0:da04816fb411 50 /* Wait end of half block recording */
adustm 0:da04816fb411 51 while(audio_rec_buffer_state == BUFFER_OFFSET_HALF) {
adustm 0:da04816fb411 52 }
adustm 0:da04816fb411 53 audio_rec_buffer_state = BUFFER_OFFSET_NONE;
adustm 0:da04816fb411 54 /* Copy recorded 1st half block */
adustm 0:da04816fb411 55 memcpy((uint16_t *)(AUDIO_BUFFER_OUT), (uint16_t *)(AUDIO_BUFFER_IN), AUDIO_BLOCK_SIZE);
adustm 0:da04816fb411 56 /* Wait end of one block recording */
adustm 0:da04816fb411 57 while(audio_rec_buffer_state == BUFFER_OFFSET_FULL) {
adustm 0:da04816fb411 58 }
adustm 0:da04816fb411 59 audio_rec_buffer_state = BUFFER_OFFSET_NONE;
adustm 0:da04816fb411 60 /* Copy recorded 2nd half block */
adustm 0:da04816fb411 61 memcpy((uint16_t *)(AUDIO_BUFFER_OUT + (AUDIO_BLOCK_SIZE)), (uint16_t *)(AUDIO_BUFFER_IN + (AUDIO_BLOCK_SIZE)), AUDIO_BLOCK_SIZE);
adustm 0:da04816fb411 62 }
adustm 0:da04816fb411 63 }
adustm 0:da04816fb411 64 /*-------------------------------------------------------------------------------------
adustm 0:da04816fb411 65 Callbacks implementation:
adustm 0:da04816fb411 66 the callbacks API are defined __weak in the stm32746g_discovery_audio.c file
adustm 0:da04816fb411 67 and their implementation should be done in the user code if they are needed.
adustm 0:da04816fb411 68 Below some examples of callback implementations.
adustm 0:da04816fb411 69 -------------------------------------------------------------------------------------*/
adustm 0:da04816fb411 70 /**
adustm 0:da04816fb411 71 * @brief Manages the DMA Transfer complete interrupt.
adustm 0:da04816fb411 72 * @param None
adustm 0:da04816fb411 73 * @retval None
adustm 0:da04816fb411 74 */
adustm 0:da04816fb411 75 void BSP_AUDIO_IN_TransferComplete_CallBack(void)
adustm 0:da04816fb411 76 {
adustm 0:da04816fb411 77 audio_rec_buffer_state = BUFFER_OFFSET_FULL;
adustm 0:da04816fb411 78 return;
adustm 0:da04816fb411 79 }
adustm 0:da04816fb411 80
adustm 0:da04816fb411 81 /**
adustm 0:da04816fb411 82 * @brief Manages the DMA Half Transfer complete interrupt.
adustm 0:da04816fb411 83 * @param None
adustm 0:da04816fb411 84 * @retval None
adustm 0:da04816fb411 85 */
adustm 0:da04816fb411 86 void BSP_AUDIO_IN_HalfTransfer_CallBack(void)
adustm 0:da04816fb411 87 {
adustm 0:da04816fb411 88 audio_rec_buffer_state = BUFFER_OFFSET_HALF;
adustm 0:da04816fb411 89 return;
adustm 0:da04816fb411 90 }
adustm 0:da04816fb411 91
adustm 0:da04816fb411 92 static uint8_t SetSysClock_PLL_HSE_200MHz()
adustm 0:da04816fb411 93 {
adustm 0:da04816fb411 94 RCC_ClkInitTypeDef RCC_ClkInitStruct;
adustm 0:da04816fb411 95 RCC_OscInitTypeDef RCC_OscInitStruct;
adustm 0:da04816fb411 96
adustm 0:da04816fb411 97 // Enable power clock
adustm 0:da04816fb411 98 __PWR_CLK_ENABLE();
adustm 0:da04816fb411 99
adustm 0:da04816fb411 100 // Enable HSE oscillator and activate PLL with HSE as source
adustm 0:da04816fb411 101 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
adustm 0:da04816fb411 102 RCC_OscInitStruct.HSEState = RCC_HSE_ON; /* External xtal on OSC_IN/OSC_OUT */
adustm 0:da04816fb411 103
adustm 0:da04816fb411 104 // Warning: this configuration is for a 25 MHz xtal clock only
adustm 0:da04816fb411 105 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
adustm 0:da04816fb411 106 RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
adustm 0:da04816fb411 107 RCC_OscInitStruct.PLL.PLLM = 25; // VCO input clock = 1 MHz (25 MHz / 25)
adustm 0:da04816fb411 108 RCC_OscInitStruct.PLL.PLLN = 400; // VCO output clock = 400 MHz (1 MHz * 400)
adustm 0:da04816fb411 109 RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; // PLLCLK = 200 MHz (400 MHz / 2)
adustm 0:da04816fb411 110 RCC_OscInitStruct.PLL.PLLQ = 8; // USB clock = 50 MHz (400 MHz / 8)
adustm 0:da04816fb411 111
adustm 0:da04816fb411 112 if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
adustm 0:da04816fb411 113 {
adustm 0:da04816fb411 114 return 0; // FAIL
adustm 0:da04816fb411 115 }
adustm 0:da04816fb411 116
adustm 0:da04816fb411 117 // Activate the OverDrive to reach the 216 MHz Frequency
adustm 0:da04816fb411 118 if (HAL_PWREx_EnableOverDrive() != HAL_OK)
adustm 0:da04816fb411 119 {
adustm 0:da04816fb411 120 return 0; // FAIL
adustm 0:da04816fb411 121 }
adustm 0:da04816fb411 122
adustm 0:da04816fb411 123 // Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers
adustm 0:da04816fb411 124 RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
adustm 0:da04816fb411 125 RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; // 200 MHz
adustm 0:da04816fb411 126 RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; // 200 MHz
adustm 0:da04816fb411 127 RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4; // 50 MHz
adustm 0:da04816fb411 128 RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; // 100 MHz
adustm 0:da04816fb411 129
adustm 0:da04816fb411 130 if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_7) != HAL_OK)
adustm 0:da04816fb411 131 {
adustm 0:da04816fb411 132 return 0; // FAIL
adustm 0:da04816fb411 133 }
adustm 0:da04816fb411 134 HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_HSE, RCC_MCODIV_4);
adustm 0:da04816fb411 135 return 1; // OK
adustm 0:da04816fb411 136 }