static void I2C_MasterTransferDMAConfig(I2C_Type *base, i2c_master_dma_handle_t *handle) { dma_transfer_config_t transfer_config; dma_transfer_options_t transfer_options = kDMA_EnableInterrupt; if (handle->transfer.direction == kI2C_Read) { transfer_config.srcAddr = (uint32_t)I2C_GetDataRegAddr(base); transfer_config.destAddr = (uint32_t)(handle->transfer.data); transfer_config.transferSize = (handle->transfer.dataSize - 1); transfer_config.srcSize = kDMA_Transfersize8bits; transfer_config.enableSrcIncrement = false; transfer_config.destSize = kDMA_Transfersize8bits; transfer_config.enableDestIncrement = true; } else { transfer_config.srcAddr = (uint32_t)(handle->transfer.data + 1); transfer_config.destAddr = (uint32_t)I2C_GetDataRegAddr(base); transfer_config.transferSize = (handle->transfer.dataSize - 1); transfer_config.srcSize = kDMA_Transfersize8bits; transfer_config.enableSrcIncrement = true; transfer_config.destSize = kDMA_Transfersize8bits; transfer_config.enableDestIncrement = false; } DMA_SubmitTransfer(handle->dmaHandle, &transfer_config, transfer_options); DMA_StartTransfer(handle->dmaHandle); }
status_t SPIFI_TransferReceiveDMA(SPIFI_Type *base, spifi_dma_handle_t *handle, spifi_transfer_t *xfer) { assert(handle && (handle->dmaHandle)); dma_transfer_config_t xferConfig; status_t status; /* If previous TX not finished. */ if (kSPIFI_BusBusy == handle->state) { status = kStatus_SPIFI_Busy; } else { handle->state = kSPIFI_BusBusy; /* Prepare transfer. */ DMA_PrepareTransfer(&xferConfig, (void *)SPIFI_GetDataRegisterAddress(base), xfer->data, sizeof(uint32_t), xfer->dataSize, kDMA_PeripheralToMemory, NULL); /* Submit transfer. */ DMA_SubmitTransfer(handle->dmaHandle, &xferConfig); DMA_StartTransfer(handle->dmaHandle); /* Enable SPIFI TX DMA. */ SPIFI_EnableDMA(base, true); status = kStatus_Success; } return status; }
/* AsyncMemCopy * * Block size 0 = 64k. Enable the DMA channel to use first. * Then setup channel for copying data, increasing addresses, * no address pointer reload, with 8-byte bursts. * * \note This function is asynchronous and DOES NOT wait for * completion.This must be handled by the program * calling this function. * In this example, an interrupt. * */ void AsyncMemCopy( const void * src, void * dest, uint16_t blockSize, DMA_CH_t * dmaChannel ) { DMA_EnableChannel( dmaChannel ); DMA_SetupBlock( dmaChannel, src, DMA_CH_SRCRELOAD_NONE_gc, DMA_CH_SRCDIR_INC_gc, dest, DMA_CH_DESTRELOAD_NONE_gc, DMA_CH_DESTDIR_INC_gc, blockSize, DMA_CH_BURSTLEN_8BYTE_gc, 0, false ); DMA_StartTransfer( dmaChannel ); }
bool MemCopy( const void * src, void * dest, uint16_t blockSize, DMA_CH_t * dmaChannel ) { uint8_t flags = 0; DMA_EnableChannel( dmaChannel ); DMA_SetupBlock( dmaChannel, src, DMA_CH_SRCRELOAD_NONE_gc, DMA_CH_SRCDIR_INC_gc, dest, DMA_CH_DESTRELOAD_NONE_gc, DMA_CH_DESTDIR_INC_gc, blockSize, DMA_CH_BURSTLEN_8BYTE_gc, 0, false ); // no repeat DMA_StartTransfer( dmaChannel ); // Wait until the completion or error flag is set. The flags // must be cleared manually. do { flags = DMA_ReturnStatus_non_blocking( dmaChannel ); } while ( flags == 0 ); // Clear flags DMA.CH0.CTRLB |= ( flags ); // Check if error flag is set if ( ( flags & DMA_CH_ERRIF_bm ) != 0x00 ) { return true; } else { return false; } }
status_t USART_TransferReceiveDMA(USART_Type *base, usart_dma_handle_t *handle, usart_transfer_t *xfer) { assert(handle); assert(handle->rxDmaHandle); assert(xfer); assert(xfer->data); assert(xfer->dataSize); dma_transfer_config_t xferConfig; status_t status; /* If previous RX not finished. */ if (kUSART_RxBusy == handle->rxState) { status = kStatus_USART_RxBusy; } else { handle->rxState = kUSART_RxBusy; handle->rxDataSizeAll = xfer->dataSize; /* Enable DMA request from rxFIFO */ USART_EnableRxDMA(base, true); /* Prepare transfer. */ DMA_PrepareTransfer(&xferConfig, (void *)&base->FIFORD, xfer->data, sizeof(uint8_t), xfer->dataSize, kDMA_PeripheralToMemory, NULL); /* Submit transfer. */ DMA_SubmitTransfer(handle->rxDmaHandle, &xferConfig); DMA_StartTransfer(handle->rxDmaHandle); status = kStatus_Success; } return status; }
status_t UART_TransferReceiveDMA(UART_Type *base, uart_dma_handle_t *handle, uart_transfer_t *xfer) { assert(handle); assert(handle->rxDmaHandle); assert(xfer); assert(xfer->data); assert(xfer->dataSize); dma_transfer_config_t xferConfig; status_t status; /* If previous RX not finished. */ if (kUART_RxBusy == handle->rxState) { status = kStatus_UART_RxBusy; } else { handle->rxState = kUART_RxBusy; handle->rxDataSizeAll = xfer->dataSize; /* Prepare transfer. */ DMA_PrepareTransfer(&xferConfig, (void *)UART_GetDataRegisterAddress(base), sizeof(uint8_t), xfer->data, sizeof(uint8_t), xfer->dataSize, kDMA_PeripheralToMemory); /* Submit transfer. */ DMA_SubmitTransfer(handle->rxDmaHandle, &xferConfig, kDMA_EnableInterrupt); DMA_StartTransfer(handle->rxDmaHandle); /* Enable UART RX DMA. */ UART_EnableRxDMA(base, true); status = kStatus_Success; } return status; }
/*! \brief Example of a repeated block memory copy operation. * * Block size 0 = 64k. Enable the DMA channel to use first and the channel * will be disabled automatically. A parameter check to avoid illegal values. * Setup channel for copying data, increasing addresses, no address pointer * reload, with 8-byte bursts. * * \note This function wait until the transfer is complete and use a blocking * function which also makes this function blocking, hence the function * will dead-lock if the completion or error flag never get set. * * \retval true if success. * \retval false if failure. */ bool MultiBlockMemCopy( const void * src, void * dest, uint16_t blockSize, uint8_t repeatCount, volatile DMA_CH_t * dmaChannel ) { uint8_t flags; DMA_EnableChannel( dmaChannel ); DMA_SetupBlock( dmaChannel, src, DMA_CH_SRCRELOAD_NONE_gc, DMA_CH_SRCDIR_INC_gc, dest, DMA_CH_DESTRELOAD_NONE_gc, DMA_CH_DESTDIR_INC_gc, blockSize, DMA_CH_BURSTLEN_8BYTE_gc, repeatCount, true ); DMA_StartTransfer( dmaChannel ); /* Wait until the completion or error flag is set. The flags * must be cleared manually. */ do { flags = DMA_ReturnStatus_non_blocking( dmaChannel ); } while ( flags == 0); dmaChannel->CTRLB |= ( flags ); /* Check if error flag is set. */ if ( ( flags & DMA_CH_ERRIF_bm ) != 0x00 ) { return false; } else { return true; } }
/** * \brief Call back function for DMA transmit complete * * This function will be called when DMA transmit completes. * This function changes the source address of the DMA channel and * restarts the DMA transfer. * * \param dmaStatus [IN] Status of the DMA transfer * \param dataCallback [IN] I2S handle * * \return void * */ void I2S_DmaTxCallBack(PSP_DMATransferStatus dmaStatus, void *dataCallback) { #if 0 // currently unused Uint16 i; Int16 status; Uint16 * ptr_tx_left; Uint16 * ptr_tx_right; Uint16 * ptr_tx_codec_buf; Uint16 next_position; Uint16 wrap; prevDmaTxferComplete = TRUE; if((dataCallback != NULL) && (dmaStatus == PSP_DMA_TRANSFER_COMPLETE)) { if(usb_play_mode == FALSE) { //playback not active- use zero buffer DMA_ChangeI2SSrcAddr(hDmaTxLeft,gZeroBuf); DMA_ChangeI2SSrcAddr(hDmaTxRight,gZeroBuf); /* Start dma transfer */ DMA_StartTransfer(hDmaTxLeft); DMA_StartTransfer(hDmaTxRight); return; } // playback is active - get the next output buffer if(nextBuffer == TRUE) { nextBuffer = FALSE; //if(gEp2Buff2Full == TRUE) if(1) { // output pong buffer gEp2Buff2Full = FALSE; DMA_ChangeI2SSrcAddr(hDmaTxLeft,gi2sNextTxLeftBuf); DMA_ChangeI2SSrcAddr(hDmaTxRight,gi2sNextTxRightBuf); } else { // buffer is not ready // dma_error++; // DMA_ChangeI2SSrcAddr(hDmaTxLeft,gZeroBuf); // DMA_ChangeI2SSrcAddr(hDmaTxRight,gZeroBuf); } /* Start dma transfer */ DMA_StartTransfer(hDmaTxLeft); DMA_StartTransfer(hDmaTxRight); // fill the next buffer if(enable_asrc == TRUE) { // fill output buffer with ASRC output for(i = 0; i < I2S_TXBUFF_SIZE; i++) { /* Generate output samples L and R */ status = ASRC_genOutAdaptCoefs16b(hAsrc, (Int16 *)&ping_i2sTxLeftBuf[i]); if (status != ASRC_SOK) { dma_error++; } else { // save the right sample to the right output buffer ping_i2sTxRightBuf[i] = ping_i2sTxLeftBuf[i + 1]; } status = ASRC_accPhaseAdapt(hAsrc); if (status != ASRC_SOK) { dma_error++; } } } else // - fill output buffer with data from circular buffer { // this buffer needs to be filled with data to output ptr_tx_left = &ping_i2sTxLeftBuf[0]; ptr_tx_right = &ping_i2sTxRightBuf[0]; ptr_tx_codec_buf = &codec_output_buffer[codec_output_buffer_output_index]; next_position = codec_output_buffer_output_index + (2*I2S_TXBUFF_SIZE); //prepare the next buffer if(next_position < CODEC_OUTPUT_BUFFER_SIZE) { // copy without wrap for(i = 0; i < I2S_TXBUFF_SIZE; i++) { *ptr_tx_left++ = *ptr_tx_codec_buf++; *ptr_tx_right++ = *ptr_tx_codec_buf++; } // update index into circular buffer - 'x2' due to 2 writes codec_output_buffer_output_index += (2*I2S_TXBUFF_SIZE); } else { // copy with wrap outwrap++; wrap = (CODEC_OUTPUT_BUFFER_SIZE - codec_output_buffer_output_index)>>1; // copy prior to wrap for(i = 0; i < wrap; i++) { *ptr_tx_left++ = *ptr_tx_codec_buf++; *ptr_tx_right++ = *ptr_tx_codec_buf++; } // now wrap ptr_tx_codec_buf = &codec_output_buffer[0]; wrap = I2S_TXBUFF_SIZE - wrap; // copy after wrap for(i = 0; i < wrap; i++) { *ptr_tx_left++ = *ptr_tx_codec_buf++; *ptr_tx_right++ = *ptr_tx_codec_buf++; } // update index into circular buffer - 'x2' due to 2 writes codec_output_buffer_output_index = 2*wrap; } } } else {
/** * \brief DMA data read. * * Function to receive the data from I2S using DMA. * This API is called by the driver code from DDA to receive * I2S data using DMA. * * \param i2sHandle [IN] Handle to the I2S instance * \param nextRxLeftBuf [IN] Pointer to next left receive buffer * \param nextRxRightBuf [IN] Pointer to next right receive buffer * \param hDmaRxLeft [IN] Dma handle for left receive channel * \param hDmaRxRight [IN] Dma handle for right receive channel * * \return PSP_SOK - if successful, else suitable error code */ Int16 DDC_I2SDMARead(PSP_Handle i2sHandle, Uint32 *nextRxLeftBuf, Uint32 *nextRxRightBuf, DMA_ChanHandle hDmaRxLeft, DMA_ChanHandle hDmaRxRight) { DDC_I2SHandle hI2S; Uint16 leftDmaChanNum; Uint16 dmaChanCount; Uint16 dmaNum; Int16 status; PSP_Result status0; PSP_Result status1; status = PSP_E_INVAL_PARAM; status0 = PSP_E_INVAL_PARAM; status1 = PSP_E_INVAL_PARAM; if(i2sHandle != NULL) { hI2S = (DDC_I2SHandle)i2sHandle; leftDmaChanNum = hDmaRxLeft->chanNum; dmaChanCount = 4; dmaNum = 0; //gNextRxLeftBuf = (Uint32)nextRxLeftBuf; //gNextRxRightBuf = (Uint32)nextRxRightBuf; if(hDmaRxLeft != NULL) { /* Find out the DMA engine number and channel number for * left Rx DMA channel */ while(leftDmaChanNum >= dmaChanCount) { leftDmaChanNum -= dmaChanCount; dmaNum += 1; } /* Disable the DMA interrupts on left receive channel */ CSL_DMAEVTINT_REGS->DMAINTEN &= ~(0x0001 << (dmaNum*dmaChanCount + leftDmaChanNum)); } /* Enable I2S reception */ LLC_I2SEnable(hI2S->regs); switch(hI2S->chanType) { case PSP_I2S_CHAN_STEREO: /* Stereo data */ if((hDmaRxLeft != NULL) && (hDmaRxRight != NULL) && (nextRxLeftBuf != NULL) && (nextRxRightBuf != NULL)) { /* Enable transfer on two dma channels */ status0 = DMA_StartTransfer(hDmaRxLeft); status1 = DMA_StartTransfer(hDmaRxRight); } break; case PSP_I2S_CHAN_MONO: /* Mono data */ if((hDmaRxLeft != NULL) && (nextRxLeftBuf != NULL)) { /* Enable transfer on one dma channel */ status0 = DMA_StartTransfer(hDmaRxLeft); status1 = PSP_SOK; } break; default: break; } if((status0 == PSP_SOK) && (status1 == PSP_SOK)) { status = PSP_SOK; } } return status; }
/** * \brief Audio Class intialization function * * \param None * * \return None */ void CSL_acTest(void) { I2sInitPrms i2sInitPrms; CSL_UsbConfig usbConfig; PSP_Result result; Int16 status; HWI_Attrs attrs; LOG_printf(&trace, "USB ISO FULL SPEED MODE\n"); /* Initialize audio module */ result = AIC3254_init(); if(result != 0) { LOG_printf(&trace, "ERROR: Unable to configure audio codec"); } else { #if !defined(SAMPLE_BY_SAMPLE_PB) || !defined(SAMPLE_BY_SAMPLE_REC) DMA_HwInit(); DMA_DrvInit(); #endif /* Initialize I2S and associated DMA channels for Playback and Record */ i2sInitPrms.enablePlayback = TRUE; i2sInitPrms.enableStereoPb = TRUE; #ifdef SAMPLE_BY_SAMPLE_PB i2sInitPrms.sampleBySamplePb = TRUE; #else /* Configuration untested since ASRC only works with I2S in sample-by-sample mode */ i2sInitPrms.sampleBySamplePb = FALSE; i2sInitPrms.enableDmaPingPongPb = FALSE; i2sInitPrms.pingI2sTxLeftBuf = ping_i2sTxLeftBuf; i2sInitPrms.pongI2sTxLeftBuf = pong_i2sTxLeftBuf; i2sInitPrms.pingI2sTxRightBuf = ping_i2sTxRightBuf; i2sInitPrms.pongI2sTxRightBuf = pong_i2sTxRightBuf; i2sInitPrms.zeroBuf = ZeroBuf; #endif i2sInitPrms.i2sPb = PSP_I2S_TX_INST_ID; i2sInitPrms.enableRecord = TRUE; i2sInitPrms.enableStereoRec = FALSE; #ifdef SAMPLE_BY_SAMPLE_REC i2sInitPrms.sampleBySampleRec = TRUE; #else i2sInitPrms.sampleBySampleRec = FALSE; i2sInitPrms.enableDmaPingPongRec = TRUE; i2sInitPrms.pingI2sRxLeftBuf = (Int16 *)ping_pong_i2sRxLeftBuf; i2sInitPrms.pongI2sRxLeftBuf = NULL; i2sInitPrms.pingI2sRxRightBuf = (Int16 *)ping_pong_i2sRxRightBuf; i2sInitPrms.pongI2sRxRightBuf = NULL; #endif i2sInitPrms.i2sRec = PSP_I2S_RX_INST_ID; status = i2sInit(&i2sInitPrms); if (status != I2SSAMPLE_SOK) { LOG_printf(&trace, "ERROR: Unable to initialize I2S"); } #ifdef C5535_EZDSP_DEMO // initialize the OLED display oled_init(); #endif /* Initialising the Pointer to the Audio Class Handle to the Buffer Allocated */ AC_AppHandle.pAcObj = &ACAppBuffer[0]; usbConfig.devNum = CSL_USB0; usbConfig.opMode = CSL_USB_OPMODE_POLLED; #ifdef APP_USB_SELF_POWERED usbConfig.selfPowered = TRUE; #else usbConfig.selfPowered = FALSE; #endif usbConfig.maxCurrent = APP_USB_MAX_CURRENT; usbConfig.appSuspendCallBack = (CSL_USB_APP_CALLBACK)CSL_suspendCallBack; usbConfig.appWakeupCallBack = (CSL_USB_APP_CALLBACK)CSL_selfWakeupCallBack; usbConfig.startTransferCallback = StartTransfer; usbConfig.completeTransferCallback = CompleteTransfer; USB_init(&usbConfig); USB_setFullSpeedMode(0x40); /* parameter is EP0 data size in bytes */ USB_resetDev(CSL_USB0); /* Calling init routine */ /* Giving all the table hanldes and the buffers to the Audio Class module */ AC_AppHandle.strDescrApp = (char **)&string_descriptor[0]; AC_AppHandle.lbaBufferPbApp = &lbaBufferPbApp[0]; AC_AppHandle.lbaBufferRecApp = &lbaBufferRecApp[0]; AC_AppHandle.lbaBufferHidReportApp = &lbaBufferHidReportApp[0]; AC_AppHandle.acReqTableApp = USB_ReqTable; AC_AppHandle.pId = pId; AC_AppHandle.vId = vId; #ifndef ENABLE_PLAYBACK_TWO_SAMPLE_RATES #ifdef SAMPLE_RATE_TX_48kHz LOG_printf(&trace, "PLAYBACK: 48KHZ "); #ifdef ENABLE_STEREO_PLAYBACK LOG_printf(&trace, "STEREO\n"); AC_AppHandle.rxPktSize = EP_PB_MAXP; // max packet size for 48K stereo #else // ENABLE_STEREO_PLAYBACK LOG_printf(&trace, "MONO\n"); AC_AppHandle.rxPktSize = 0x60; // max packet size for 48K mono #endif // ENABLE_STEREO_PLAYBACK #endif // SAMPLE_RATE_TX_48kHz #ifdef SAMPLE_RATE_TX_44_1kHz LOG_printf(&trace, "PLAYBACK: 44.1KHZ "); #ifdef ENABLE_STEREO_PLAYBACK LOG_printf(&trace, "STEREO\n"); AC_AppHandle.rxPktSize = 0xB0; // max packet size for 44.1 stereo #else // ENABLE_STEREO_PLAYBACK LOG_printf(&trace, "MONO\n"); AC_AppHandle.rxPktSize = 0x58; // max packet size for 44.1 mono #endif // ENABLE_STEREO_PLAYBACK #endif // SAMPLE_RATE_TX_44_1kHz #ifdef SAMPLE_RATE_TX_32kHz LOG_printf(&trace, "PLAYBACK: 32KHZ "); #ifdef ENABLE_STEREO_PLAYBACK LOG_printf(&trace, "STEREO\n"); AC_AppHandle.rxPktSize = 0x80; // max packet size for 32K stereo #else // ENABLE_STEREO_PLAYBACK LOG_printf(&trace, "MONO\n"); AC_AppHandle.rxPktSize = 0x40; // max packet size for 32K mono #endif // ENABLE_STEREO_PLAYBACK #endif // SAMPLE_RATE_TX_32kHz #ifdef SAMPLE_RATE_TX_16kHz LOG_printf(&trace, "PLAYBACK: 16KHZ "); #ifdef ENABLE_STEREO_PLAYBACK LOG_printf(&trace, "STEREO\n"); AC_AppHandle.rxPktSize = RX_PKT_SIZE_16K_PLAYBACK_STEREO; // max packet size for 16K stereo rx_pkt_size_16K_playback = RX_PKT_SIZE_16K_PLAYBACK_STEREO; // max packet size for 16K stereo #else // ENABLE_STEREO_PLAYBACK LOG_printf(&trace, "MONO\n"); AC_AppHandle.rxPktSize = RX_PKT_SIZE_16K_PLAYBACK_MONO; // max packet size for 16K mono rx_pkt_size_16K_playback = RX_PKT_SIZE_16K_PLAYBACK_MONO; // max packet size for 16K mono #endif // ENABLE_STEREO_PLAYBACK #endif // SAMPLE_RATE_TX_16kHz #else /* ENABLE_PLAYBACK_TWO_SAMPLE_RATES */ LOG_printf(&trace, "PLAYBACK: 48KHZ "); #ifdef ENABLE_STEREO_PLAYBACK LOG_printf(&trace, "STEREO\n"); AC_AppHandle.rxPktSize = EP_PB_MAXP; // max packet size for 48K stereo #else // ENABLE_STEREO_PLAYBACK LOG_printf(&trace, "MONO\n"); AC_AppHandle.rxPktSize = 0x60; // max packet size for 48K mono #endif // ENABLE_STEREO_PLAYBACK LOG_printf(&trace, "PLAYBACK: 16KHZ "); #ifdef ENABLE_STEREO_PLAYBACK rx_pkt_size_16K_playback = RX_PKT_SIZE_16K_PLAYBACK_STEREO; // max packet size for 16K stereo LOG_printf(&trace, "STEREO\n"); #else // ENABLE_STEREO_PLAYBACK rx_pkt_size_16K_playback = RX_PKT_SIZE_16K_PLAYBACK_MONO; // max packet size for 16K mono LOG_printf(&trace, "MONO\n"); #endif // ENABLE_STEREO_PLAYBACK #endif /* ENABLE_PLAYBACK_TWO_SAMPLE_RATES */ AC_AppHandle.txPktSize = EP_REC_MAXP; // max packet size for 16K mono AC_AppHandle.hidTxPktSize = EP_HID_MAXP; // max packet size for HID output report /* All Function Handlers need to be Initialised */ AC_AppHandle.playAudioApp = appPlayAudio; AC_AppHandle.recordAudioApp = appRecordAudio; AC_AppHandle.initPlayAudioApp = appInitPlayAudio; AC_AppHandle.initRecordAudioApp = appInitRecordAudio; AC_AppHandle.stopPlayAudioApp = appStopPlayAudio; AC_AppHandle.stopRecordAudioApp = appStopRecordAudio; AC_AppHandle.mediaGetPresentStateApp = AppGetMediaStatus; AC_AppHandle.mediaInitApp = AppMediaInit; AC_AppHandle.mediaEjectApp = AppMediaEject; AC_AppHandle.mediaLockUnitApp = AppLockMedia; AC_AppHandle.getMediaSizeApp = AppGetMediaSize; AC_AppHandle.getHidReportApp = appGetHidReport; AC_AppHandle.ctrlHandler = appCtrlFxn; AC_AppHandle.isoHandler = appIsoFxn; AC_AppHandle.hidHandler = appHidFxn; AC_AppHandle.numLun = 2; /* Initialize End point descriptors */ AC_initDescriptors(AC_AppHandle.pAcObj, (Uint16 *)deviceDescriptorB, CSL_AC_DEVICE_DESCR, sizeof(deviceDescriptorB)); AC_initDescriptors(AC_AppHandle.pAcObj, (Uint16 *)deviceQualifierDescr, CSL_AC_DEVICE_QUAL_DESCR, 10); AC_initDescriptors(AC_AppHandle.pAcObj, (Uint16 *)configDescriptor, CSL_AC_CONFIG_DESCR, sizeof(configDescriptor)); AC_initDescriptors(AC_AppHandle.pAcObj, (Uint16 *)stringLanId, CSL_AC_STRING_LANGID_DESC, 6); AC_initDescriptors(AC_AppHandle.pAcObj, (Uint16 *)acHidReportDescriptor, CSL_AC_HID_REPORT_DESC, sizeof(acHidReportDescriptor)); /* Initialize HID */ AC_AppHandle.acHidIfNum = IF_NUM_HID; // HID interface number AC_AppHandle.acHidReportId = HID_REPORT_ID; // HID report ID AC_AppHandle.acHidReportLen = HID_REPORT_SIZE_BYTES; // HID report length (bytes) genHidReport(UI_PUSH_BUTTON_NONE, gHidReport); // init. HID report for Get Report /* Call Init API */ AC_Open(&AC_AppHandle); /* Enable CPU USB interrupts */ CSL_FINST(CSL_CPU_REGS->IER1, CPU_IER1_USB, ENABLE); /* Initialize active sample rate */ initSampleRate(RATE_48_KHZ, &active_sample_rate, &i2sTxBuffSz); /* Initialize ASRC */ Init_Sample_Rate_Converter(active_sample_rate); /* Reset codec output buffer */ reset_codec_output_buffer(); #ifdef ENABLE_RECORD #ifdef SAMPLE_RATE_RX_48kHz LOG_printf(&trace, "RECORD: 48KHZ "); #else LOG_printf(&trace, "RECORD: 16KHZ "); #endif // SAMPLE_RATE_RX_48kHz // start the rx DMAs DMA_StartTransfer(hDmaRxLeft); #ifdef ENABLE_STEREO_RECORD LOG_printf(&trace, "STEREO NOT SUPPORTED - RECORD WILL BE MONO\n"); DMA_StartTransfer(hDmaRxRight); #else LOG_printf(&trace, "MONO\n"); #endif #endif // ENABLE_RECORD #ifdef STORE_PARAMETERS_TO_SDRAM initSdram(FALSE, 0x0000); #endif // STORE_PARAMETERS_TO_SDRAM #ifdef SAMPLE_BY_SAMPLE_PB /* SampleBySample, init interrupt */ /* Use with compiler "interrupt" keyword */ //IRQ_plug(I2S_TX_EVENT, i2s_txIsr); /* Use with dispatcher, no "interrupt" keyword */ attrs.ier0mask = 0xFFFF; attrs.ier1mask = 0xFFFF; HWI_dispatchPlug(I2S_TX_EVENT, (Fxn)i2s_txIsr, &attrs); IRQ_enable(I2S_TX_EVENT); /* SampleBySample, enable IRQ for I2S Tx */ #endif #if defined(SAMPLE_BY_SAMPLE_REC) && !defined(COMBINE_I2S_TX_RX_ISR) /* SampleBySample, init interrupt */ /* Use with compiler "interrupt" keyword */ IRQ_plug(I2S_RX_EVENT, i2s_rxIsr); /* Use with dispatcher, no "interrupt" keyword */ //attrs.ier0mask = 0xFFFF; //attrs.ier1mask = 0xFFFF; //HWI_dispatchPlug(I2S_RX_EVENT, (Fxn)i2s_rxIsr, &attrs); IRQ_enable(I2S_RX_EVENT); /* SampleBySample, enable IRQ for I2S Rx */ #endif #if defined(SAMPLE_BY_SAMPLE_PB) || defined(SAMPLE_BY_SAMLE_REC) DDC_I2S_transEnable((DDC_I2SHandle)i2sHandleTx, TRUE); /* SampleBySample, enable I2S transmit and receive */ #endif #ifndef SAMPLE_BY_SAMPLE_PB i2sTxStart(); // - moved from appPlayAudio() #endif #ifdef C5535_EZDSP_DEMO // clock gating usused peripherals ClockGating(); #endif } }
status_t SPI_MasterTransferDMA(SPI_Type *base, spi_dma_handle_t *handle, spi_transfer_t *xfer) { assert(handle && xfer); dma_transfer_config_t config = {0}; /* Check if the device is busy */ if (handle->state == kSPI_Busy) { return kStatus_SPI_Busy; } /* Check if input parameter invalid */ if (((xfer->txData == NULL) && (xfer->rxData == NULL)) || (xfer->dataSize == 0U)) { return kStatus_InvalidArgument; } /* Disable SPI and then enable it, this is used to clear S register*/ SPI_Enable(base, false); SPI_Enable(base, true); /* Configure tx transfer DMA */ config.destAddr = SPI_GetDataRegisterAddress(base); config.enableDestIncrement = false; if (handle->bytesPerFrame == 1U) { config.srcSize = kDMA_Transfersize8bits; config.destSize = kDMA_Transfersize8bits; } else { config.srcSize = kDMA_Transfersize16bits; config.destSize = kDMA_Transfersize16bits; } config.transferSize = xfer->dataSize; /* Configure DMA channel */ if (xfer->txData) { config.enableSrcIncrement = true; config.srcAddr = (uint32_t)(xfer->txData); } else { /* Disable the source increasement and source set to dummyData */ config.enableSrcIncrement = false; config.srcAddr = (uint32_t)(&s_dummyData); } DMA_SubmitTransfer(handle->txHandle, &config, true); /* Handle rx transfer */ if (xfer->rxData) { /* Set the source address */ DMA_SetDestinationAddress(handle->rxHandle->base, handle->rxHandle->channel, (uint32_t)(xfer->rxData)); /* Set the transfer size */ DMA_SetTransferSize(handle->rxHandle->base, handle->rxHandle->channel, xfer->dataSize); } /* Change the state of handle */ handle->transferSize = xfer->dataSize; handle->state = kSPI_Busy; /* Start Rx transfer if needed */ if (xfer->rxData) { handle->rxInProgress = true; SPI_EnableDMA(base, kSPI_RxDmaEnable, true); DMA_StartTransfer(handle->rxHandle); } /* Always start Tx transfer */ handle->txInProgress = true; SPI_EnableDMA(base, kSPI_TxDmaEnable, true); DMA_StartTransfer(handle->txHandle); return kStatus_Success; }