/** * Invoked when an audio channel get muted or unmuted. Mutes/unmutes the * channel at the DAC level. * \param mic Microphone/Speaker stream changed. * \param channel Channel number that changed. * \param muted Indicates the new mute status of the channel. */ void AUDDFunction_MuteChanged(uint8_t mic, uint8_t channel, uint8_t muted) { if (mic) return; /* Speaker Master channel */ if (channel == AUDD_CH_Master) { if (muted) { AudioPlayEnable(0); TRACE_WARNING("MuteMaster "); } else { TRACE_INFO("UnmuteMaster "); AudioPlayEnable(1); } } }
/** * Configure the TWI and DACC for audio output. * \param sampleRate Audio sample rate. * \param mck MCK frequency. */ static void _ConfigureAudioPlay(uint32_t sampleRate, uint32_t mck) { /* -- Pins Configuration -- */ PIO_Configure(pinsAudio, PIO_LISTSIZE(pinsAudio)); /* -- SSC Configuration -- */ sampleRate = sampleRate; /*dummy */ SSC_Configure(SSC, 0, mck); SSC_DisableTransmitter(SSC); SSC_DisableReceiver(SSC); SSC_ConfigureTransmitter(SSC, I2S_SLAVE_TX_SETTING, I2S_SLAVE_TX_FRM_SETTING); SSC_DisableTransmitter(SSC); /* Enable TWI peripheral clock */ PMC_EnablePeripheral(ID_TWIHS0); /* Configure and enable the TWI (required for accessing the DAC) */ TWI_ConfigureMaster(TWIHS0, TWI_CLOCK, mck); TWID_Initialize(&twid, TWIHS0); /* Initialize the audio DAC */ WM8904_Write(&twid, WM8904_SLAVE_ADDRESS, WM8904_REG_RESET, 0); Wait(100); /* WM8904 as master */ if (WM8904_Read(&twid, WM8904_SLAVE_ADDRESS, 0) != 0x8904) { printf("WM8904 not found!\n\r"); while (1); } WM8904_Init(&twid, WM8904_SLAVE_ADDRESS, PMC_MCKR_CSS_SLOW_CLK); _SyncAdjust(0); PMC_ConfigurePCK2(PMC_MCKR_CSS_SLOW_CLK, PMC_MCKR_PRES_CLK_1); /* Mute */ AudioPlayEnable(0); }
/** * \brief usb_iad_hid_aud Application entry point. * * Starts the driver and waits for an audio input stream to forward to the DAC. */ int main(void) { volatile uint8_t usbConn = 0; volatile uint8_t audioOn = 0; int32_t numDiff = 0, prevDiff = 0; int8_t clockAdjust = 0; /* Disable watchdog */ WDT_Disable(WDT); SCB_EnableICache(); SCB_EnableDCache(); printf("-- USB HID + Audio Device Example %s --\n\r", SOFTPACK_VERSION); printf("-- %s\n\r", BOARD_NAME); printf("-- Compiled: %s %s With %s--\n\r", __DATE__, __TIME__ , COMPILER_NAME); TimeTick_Configure(); /* Interrupt priority */ NVIC_SetPriority(USBHS_IRQn, 2); /* If they are present, configure Vbus & Wake-up pins */ PIO_InitializeInterrupts(0); /* Initialize all USB power (off) */ _ConfigureUsbhs(); /* ----- HID Function Initialize */ #ifdef NO_PUSHBUTTON printf("-- : DBG key 1 2 used as buttons\n\r"); printf("-- : 1st press to push, 2nd press to release\n\r"); #else /* Initialize key statuses and configure push buttons */ PIO_Configure(pinsPushButtons, PIO_LISTSIZE(pinsPushButtons)); #endif memset(keyStatus, 1, NUM_KEYS); //LED_Configure(LED_NUMLOCK); /* Audio STREAM LED */ LED_Configure(USBD_LEDOTHER); /* Configure Audio */ _ConfigureAudioPlay(AUDDevice_SAMPLERATE, BOARD_MCK); /* Configure DMA */ _ConfigureDma(); /* USB audio driver initialization */ HIDAUDDDriver_Initialize(&hidauddDriverDescriptors); /* connect if needed */ USBD_Connect(); /* Infinite loop */ while (1) { if (USBD_GetState() < USBD_STATE_CONFIGURED) { usbConn = 0; continue; } if (audioOn) { if (isDacActive == 0) { AudioPlayEnable(0); printf("audE "); isFirstFrame = 1; audioOn = 0; } else { numDiff = numBuffersToSend - DAC_DELAY; if (prevDiff != numDiff) { prevDiff = numDiff; if (numDiff > 1 && clockAdjust != 1) { printf("+"); /* USB too fast or SSC too slow: faster clock */ clockAdjust = 1; _SyncAdjust(1); } if (numDiff < -1 && clockAdjust != -1) { printf("-"); /* USB too slow or SSC too fast: slower clock */ clockAdjust = -1; _SyncAdjust(-1); } if (numDiff == 0 && clockAdjust != 0) { clockAdjust = 0; _SyncAdjust(0); } } } } else if (isDacActive) { printf("audS "); audioOn = 1; } if (usbConn == 0) { usbConn = 1; /* Start Reading the incoming audio stream */ AUDDFunction_Read(buffers[inBufferIndex], AUDDevice_BYTESPERFRAME, (TransferCallback) FrameReceived, 0); // No optional argument } HIDDKeyboardProcessKeys(); } }
/** * Configure the TC0 and DACC for audio output. * \param sampleRate Audio sample rate. * \param nbChannels Number of audio channels. * \param mck MCK frequence. */ static void ConfigureAudioPlay(uint32_t sampleRate, uint8_t nbChannels, uint32_t mck) { uint32_t div = 2; uint32_t tcclks = TC_CMR_TCCLKS_TIMER_CLOCK1; uint32_t freq = sampleRate * nbChannels; double ra, rc; /* Enable TC0 Peripheral */ PMC_EnablePeripheral(ID_TC0); { uint32_t divs[5] = {2, 8, 32, 128,BOARD_MCK / 32768}; uint8_t i = 0; divs[4] = mck/32768; /* Minimize DIV & Maxmize RC for better waveform */ while(freq < ((mck / divs[i]) / 65536)) { ++ i; if (i == 5) { TRACE_FATAL("Cann't find TC0 divisor!\n\r"); } } div = divs[i]; tcclks = i; } /* Configure TC for tioa output: 48M -> 48K*2 */ TC_Configure(TC0,0, tcclks /*MCK/2*/ | TC_CMR_ACPC_SET | TC_CMR_WAVE | TC_CMR_ACPA_CLEAR | TC_CMR_CPCTRG); /* 50% duty ,freq frequency*/ ra = (((double)mck/div)/(freq*2) + 0.5 ); rc = (((double)mck/div)/(freq) + 0.99); TC0->TC_CHANNEL[0].TC_RA = (uint32_t)ra; TC0->TC_CHANNEL[0].TC_RC = (uint32_t)ra*2; defaultRA = (uint32_t)ra; printf("-I- MCK %dKHz, Div %d(%x), RA: %d*.01(%x), RC: %d*.01(%x)\n\r", (int)mck/1000, (int)div, (unsigned int)div, (int)(ra*100), (int)ra, (int)(rc*100), (int)rc); /* Initialize DACC with HW as trigger */ DACC_Initialize( DACC, ID_DACC, 1, 1, 0, /* DACC_MR_WORD_HALF */ 0, BOARD_MCK, 8, CHANNEL_R, 1, 16); /* channel number is in the first 4 significant bits*/ DACC->DACC_MR |= DACC_MR_TAG; /* disable PDC for DAC */ DACC->DACC_PTCR = DACC_PTCR_TXTDIS; /* Mute */ AudioPlayEnable(0); /* Enable DACC ISR */ NVIC_EnableIRQ(DACC_IRQn); }