uni project to alow input from line in and audio eq
Dependencies: AUDIO_DISCO_F746NG_project BSP_DISCO_F746NG_project SDRAM_DISCO_F746NG mbed
Fork of DISCO-F746NG_AUDIO_demo by
main.cpp@5:bde0299905d9, 2017-04-10 (annotated)
- Committer:
- valadore
- Date:
- Mon Apr 10 14:50:39 2017 +0000
- Revision:
- 5:bde0299905d9
- Parent:
- 0:da04816fb411
changes to make looping audio work;
Who changed what in which revision?
User | Revision | Line number | New 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 | } |