5.5.1.2 XDMAC Channel Initialization
A DMA channel from the XDMAC module is configured to transfer the audio data from an array in the main memory to the Transmit Holding Register (THR) of the I2SC. The code snippet below configures the XDMAC channel 0 in a single block – Single Micro Block mode with a micro block length equal to the total number of audio samples * 2 (for 2 channels).
The data transfer is done one channel sample (16 bits) at a time.
/* Enable peripheral clock for XDMAC1 */
PMC->PMC_PCER0 = (1u << ID_XDMAC1);
/* Read the interrupt status register to clear the interrupt flags */
temp = XDMAC1->XDMAC_CHID[0].XDMAC_CIS;
/* Set source address as starting address of audio buffer */
XDMAC1->XDMAC_CHID[0].XDMAC_CSA = (uint32_t)audio_samples;
/* Set destination address as I2SC_THR register’s 16 MSB bits */
XDMAC1->XDMAC_CHID[0].XDMAC_CDA = ((uint32_t)&I2SC0->I2SC_THR) + 2;
/* Set micro block length */
XDMAC1->XDMAC_CHID[0].XDMAC_CUBC = sizeof(audio_samples)/2;
/* Set DMA channel parameters */
XDMAC1->XDMAC_CHID[0].XDMAC_CC = XDMAC_CC_TYPE_PER_TRAN
| XDMAC_CC_MBSIZE_SINGLE
| XDMAC_CC_DSYNC_MEM2PER
| XDMAC_CC_CSIZE_CHK_1
| XDMAC_CC_DWIDTH_HALFWORD
| XDMAC_CC_SIF_AHB_IF0
| XDMAC_CC_DIF_AHB_IF1
| XDMAC_CC_SAM_INCREMENTED_AM
| XDMAC_CC_DAM_FIXED_AM
| XDMAC_CC_PERID(31);
/* Set all registers related to descriptor to 0 */
XDMAC1->XDMAC_CHID[0].XDMAC_CNDC = 0;
XDMAC1->XDMAC_CHID[0].XDMAC_CBC = 0;
XDMAC1->XDMAC_CHID[0].XDMAC_CDS_MSP = 0;
XDMAC1->XDMAC_CHID[0].XDMAC_CSUS = 0;
XDMAC1->XDMAC_CHID[0].XDMAC_CDUS = 0;
The DMA channel source address is set to the start of the audio sample array, and the destination address is set to the start of the 16 MSB of the THR register. This is because we need to send the 16-bit audio sample first in the MSB part of the I2SC 32-bit word. "audio_samples" is an array of the type "signed 16-bit integer". The transfer size is set to half-word with the source address incrementing and the destination address fixed for each transfer.
No descriptors are used for the transfer, so the XDMAC registers related to the descriptor configuration are set to 0.
Note that the XDMAC1 controller is used instead of the XDMAC0 controller as described in previous chapters because the I2SC0 peripheral is connected to the APB1 bridge, whose DMA transactions are handled by the XDMAC1 controller.
