void set_gclk2_freq(int freq_hz) { const int gc_master_clock = 0; const int gc_tx_clock = 2; int temp; pm_gc_disable(&AVR32_PM, gc_master_clock); pm_gc_disable(&AVR32_PM, gc_tx_clock); switch (freq_hz) { // 32000 - stereo - 16 bits -> PLL0 (62.092MHz) case (32000*2*16): // Codec master clock - 12MHz pm_gc_setup(&AVR32_PM, gc_master_clock, AVR32_GC_USES_OSC, AVR32_GC_USES_OSC0, 0, 0); // I2S TX clock - 48MHz/46 ~ 1.024MHz = freq_hz pm_gc_setup(&AVR32_PM, gc_tx_clock, AVR32_GC_USES_PLL, AVR32_GC_USES_PLL1, 1, 22); // Configure the DAC aic23b_configure_freq(FOSC0, 32000); break; // 44100 - stereo - 16 bits -> OSC1 (11.289600MHz) case (44100*2*16): // Codec master clock - 11.289600MHz pm_gc_setup(&AVR32_PM, gc_master_clock, AVR32_GC_USES_OSC, AVR32_GC_USES_OSC1, 0, 0); // I2S TX clock - 11.289600MHz/8 = 1.4112MHz = freq_hz pm_gc_setup(&AVR32_PM, gc_tx_clock, AVR32_GC_USES_OSC, AVR32_GC_USES_OSC1, 1, 3); // Configure the DAC aic23b_configure_freq(FOSC1, 44100); break; // 48000 - stereo - 16 bits -> PLL1 (48MHz) case (48000*2*16): // Codec master clock - 12MHz pm_gc_setup(&AVR32_PM, gc_master_clock, AVR32_GC_USES_OSC, AVR32_GC_USES_OSC0, 0, 0); // I2S TX clock - 48MHz/32 ~ 1.536MHz = freq_hz pm_gc_setup(&AVR32_PM, gc_tx_clock, AVR32_GC_USES_PLL, AVR32_GC_USES_PLL1, 1, 15); // Configure the DAC aic23b_configure_freq(FOSC0, 48000); break; default: // not supported! (but we try anyway! to avoid locked-up conditions) // Codec master clock - 12MHz pm_gc_setup(&AVR32_PM, gc_master_clock, AVR32_GC_USES_OSC, AVR32_GC_USES_OSC0, 0, 0); // I2S TX clock temp = (FOSC0 + freq_hz) / (2*freq_hz) - 1; pm_gc_setup(&AVR32_PM, gc_tx_clock, AVR32_GC_USES_OSC, AVR32_GC_USES_OSC0, 1, temp); // Configure the DAC aic23b_configure_freq(FOSC0, freq_hz / (2*16)); } pm_gc_enable(&AVR32_PM, gc_tx_clock); pm_gc_enable(&AVR32_PM, gc_master_clock); }
//! //! @brief Entry point of the AK5394A task management //! void AK5394A_task(void *pvParameters) { portTickType xLastWakeTime; xLastWakeTime = xTaskGetTickCount(); int i; while (TRUE) { // All the hardwork is done by the pdca and the interrupt handler. // Just check whether sampling freq is changed, to do rate change etc. vTaskDelayUntil(&xLastWakeTime, configTSK_AK5394A_PERIOD); if (freq_changed){ if (current_freq.frequency == 96000){ pdca_disable_interrupt_reload_counter_zero(PDCA_CHANNEL_SSC_RX); pdca_disable(PDCA_CHANNEL_SSC_RX); gpio_set_gpio_pin(AK5394_DFS0); // L H -> 96khz gpio_clr_gpio_pin(AK5394_DFS1); pm_gc_disable(&AVR32_PM, AVR32_PM_GCLK_GCLK1); pm_gc_setup(&AVR32_PM, AVR32_PM_GCLK_GCLK1, // gc 0, // osc_or_pll: use Osc (if 0) or PLL (if 1) 1, // pll_osc: select Osc0/PLL0 or Osc1/PLL1 1, // diven - enabled 0); // divided by 2. Therefore GCLK1 = 6.144Mhz pm_gc_enable(&AVR32_PM, AVR32_PM_GCLK_GCLK1); if (Is_usb_full_speed_mode()) FB_rate = 96 << 14; else FB_rate = (96) << 13; } else if (current_freq.frequency == 192000) { pdca_disable_interrupt_reload_counter_zero(PDCA_CHANNEL_SSC_RX); pdca_disable(PDCA_CHANNEL_SSC_RX); gpio_clr_gpio_pin(AK5394_DFS0); // H L -> 192khz gpio_set_gpio_pin(AK5394_DFS1); pm_gc_disable(&AVR32_PM, AVR32_PM_GCLK_GCLK1); pm_gc_setup(&AVR32_PM, AVR32_PM_GCLK_GCLK1, // gc 0, // osc_or_pll: use Osc (if 0) or PLL (if 1) 1, // pll_osc: select Osc0/PLL0 or Osc1/PLL1 0, // diven - disabled 0); // GCLK1 = 12.288Mhz pm_gc_enable(&AVR32_PM, AVR32_PM_GCLK_GCLK1); if (Is_usb_full_speed_mode()) FB_rate = 192 << 14; else FB_rate = (192) << 13; } else if (current_freq.frequency == 48000) // 48khz { pdca_disable_interrupt_reload_counter_zero(PDCA_CHANNEL_SSC_RX); pdca_disable(PDCA_CHANNEL_SSC_RX); gpio_clr_gpio_pin(AK5394_DFS0); // L L -> 48khz gpio_clr_gpio_pin(AK5394_DFS1); pm_gc_disable(&AVR32_PM, AVR32_PM_GCLK_GCLK1); pm_gc_setup(&AVR32_PM, AVR32_PM_GCLK_GCLK1, // gc 0, // osc_or_pll: use Osc (if 0) or PLL (if 1) 1, // pll_osc: select Osc0/PLL0 or Osc1/PLL1 1, // diven - enabled 1); // divided by 4. Therefore GCLK1 = 3.072Mhz pm_gc_enable(&AVR32_PM, AVR32_PM_GCLK_GCLK1); if (Is_usb_full_speed_mode()) FB_rate = 48 << 14; else FB_rate = (48) << 13; } // re-sync SSC to LRCK // Wait for the next frame synchronization event // to avoid channel inversion. Start with left channel - FS goes low // However, the channels are reversed at 192khz if (current_freq.frequency == 192000) { while (gpio_get_pin_value(AK5394_LRCK)); while (!gpio_get_pin_value(AK5394_LRCK)); // exit when FS goes high } else { while (!gpio_get_pin_value(AK5394_LRCK)); while (gpio_get_pin_value(AK5394_LRCK)); // exit when FS goes low } // Enable now the transfer. pdca_enable(PDCA_CHANNEL_SSC_RX); // Init PDCA channel with the pdca_options. pdca_init_channel(PDCA_CHANNEL_SSC_RX, &PDCA_OPTIONS); // init PDCA channel with options. pdca_enable_interrupt_reload_counter_zero(PDCA_CHANNEL_SSC_RX); // reset freq_changed flag freq_changed = FALSE; } if (usb_alternate_setting_out_changed){ if (usb_alternate_setting_out != 1){ for (i = 0; i < SPK_BUFFER_SIZE; i++){ spk_buffer_0[i] = 0; spk_buffer_1[i] = 0; } }; usb_alternate_setting_out_changed = FALSE; } } }