Hi,
I have a question about BSY and DONE flags of DMA controller in KL25Z microcontroller. I've read datasheet but unfortunately I cannot understand completely differences between them. So, I've made a simple project with DAC and when I want to turn off the DAC signal then I check BSY or DONE flag and stop generating requests. On oscilloscope I found that when BSY is checked then all data samples of signal are transferred, but when DONE is checked then not always all signal samples are transferred. Is this correct?
Hi,
If possible could you post some of your code for me to see how you are initializing the modules and checking the BSY and DONE bits? The BSY flag is set the first time the channel is enabled after a transfer is initiated and cleared when the DMA has finished the last transaction. The DONE flag is set either when the BCR has reached zero, or when an error condition exists. Are you seeing any error flags when checking the DONE flag?
Best regards,
Martyn
// Turn on DAC
DAC0_C0 |= DAC_C0_DACEN_MASK;
// DMA configuration
DMA0->DMA[0].SAR = (uint32_t) g_samples; // Set source address
DMA0->DMA[0].DAR = (uint32_t) &(DAC0->DAT[0]); // Set destination address
DMA0->DMA[0].DCR = 0; // Clear DCR register
DMA0->DMA[0].DCR |= DMA_DCR_SINC_MASK; // Increment SAR after a successful transfer
DMA0->DMA[0].DCR &= ~(uint32_t)(DMA_DCR_DINC_MASK); // No change to the DAR after a successful transfer
DMA0->DMA[0].DCR |= DMA_DCR_SSIZE(2); // Source data size is 16 bit
DMA0->DMA[0].DCR |= DMA_DCR_DSIZE(2); // Destination data size is 16 bit
DMA0->DMA[0].DCR |= DMA_DCR_CS_MASK; // Force a single read/write transfer per request
DMA0->DMA[0].DCR |= DMA_DCR_ERQ_MASK; // Enable peripheral request to initiate transfer
DMA0->DMA[0].DCR |= DMA_DCR_EINT_MASK; // Enable interrupt on completion of transfer
DMA0->DMA[0].DSR_BCR = g_nr_of_samples*2; // Set number of bytes to transfer (# of words x 2)
// Turn on TPM
TPM0->SC |= TPM_SC_CMOD(1);
Then I want to stop generating signal by waiting for end
// Disable interrupt on completion of transfer
DMA0->DMA[0].DCR &= ~((uint32_t)DMA_DCR_EINT_MASK);
// Wait for completion of transfer
while(DMA0->DMA[0].DSR_BCR & DMA_DSR_BCR_BSY_MASK);
// Turn off TPM counter
TPM0->SC &= ~(uint32_t)TPM_SC_CMOD_MASK;
// Clear DMA status bits by writing a '1' to the DONE bit
DMA0->DMA[0].DSR_BCR = DMA_DSR_BCR_DONE_MASK;
// Clear status register
DMA0->DMA[0].DSR_BCR = 0;