What is the purpose of a completion interrupt at the conclusion of a DMA transfer?

Hi

I followed some hints you mentioned and still the program freezes in the mentioned while loop. Here's my EDMA config code...:

    unsigned int chIdTX0 = EDMA3_DRV_HW_CHANNEL_EVENT_1;
    unsigned int chIdTX1 = EDMA3_DRV_DMA_CHANNEL_ANY;

   

unsigned int tccTX0 = EDMA3_DRV_TCC_ANY;
    unsigned int tccTX1 = EDMA3_DRV_TCC_ANY;

     unsigned int tccTXLink0 = EDMA3_DRV_TCC_ANY;
    unsigned int tccTXLink1 = EDMA3_DRV_TCC_ANY;

     unsigned int chIdTXLink0 = EDMA3_DRV_LINK_CHANNEL;
    unsigned int chIdTXLink1 = EDMA3_DRV_LINK_CHANNEL;

         EDMA3_DRV_PaRAMRegs paramSetTX0 = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
    EDMA3_DRV_PaRAMRegs paramSetTX1 = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

     EDMA3_DRV_Result result = EDMA3_DRV_SOK;

     //-------------------TX1--------------------
    result = EDMA3_DRV_requestChannel(hEdma[0], &chIdTXLink1, &tccTXLink1, (EDMA3_RM_EventQueue)0, NULL, NULL);
    if (result != EDMA3_DRV_SOK) {
        return result;
    }
    result = EDMA3_DRV_requestChannel(hEdma[0], &chIdTX1, &tccTX1, (EDMA3_RM_EventQueue)0, NULL, NULL);
    if (result != EDMA3_DRV_SOK) {
        return result;
    }

    printf("CHAN: %d\n", chIdTX1); //returns 10
    printf("LINK: %d\n", chIdTXLink1); //returns 64
    printf("TCC TX1: %d\n", tccTX1); //returns 10

     paramSetTX1.srcAddr    = (unsigned int) txTmp;
    paramSetTX1.destAddr   = (unsigned int) 0x01D02000;

     paramSetTX1.srcBIdx    = 0;
    paramSetTX1.destBIdx   = 0;
    paramSetTX1.srcCIdx    = 0;
    paramSetTX1.destCIdx   = 0;

     paramSetTX1.aCnt       = 32;
    paramSetTX1.bCnt       = 5;
    paramSetTX1.cCnt       = 1;

     paramSetTX1.bCntReload = 0;

     paramSetTX1.linkAddr   = 0x4400;

     paramSetTX1.opt = (1 << 20) | (tccTX1 << 12);  //INT on completion, TCC is tccTX1

         result = EDMA3_DRV_setPaRAM(hEdma[0], chIdTXLink1, &paramSetTX1);
    if (result != EDMA3_DRV_SOK) {
        return result;
    }
    result = EDMA3_DRV_setPaRAM(hEdma[0], chIdTX1, &paramSetTX1);
    if (result != EDMA3_DRV_SOK) {
        return result;
    }

   

*((unsigned int *) 0x01c01060) = (1 << tccTX1); //IESR
    *((unsigned int *) 0x01c00348) |= (1 << tccTX1); //DRAE1

     //-------------------TX0-------------------
    result = EDMA3_DRV_requestChannel(hEdma[0], &chIdTXLink0, &tccTXLink0, (EDMA3_RM_EventQueue)0, NULL, NULL);
    if (result != EDMA3_DRV_SOK) {
        return result;
    }
    result = EDMA3_DRV_requestChannel(hEdma[0], &chIdTX0, &tccTX0, (EDMA3_RM_EventQueue)0, NULL, NULL);
    if (result != EDMA3_DRV_SOK) {
        return result;
    }
    printf("MAIN: %d\n", chIdTX0);
    printf("LINK: %d\n", chIdTXLink0);

     paramSetTX0.srcAddr    = (unsigned int) txAddr;
    paramSetTX0.destAddr   = (unsigned int) txTmp;

     paramSetTX0.srcBIdx    = 5;
    paramSetTX0.destBIdx   = 4;
    paramSetTX0.srcCIdx    = 1;
    paramSetTX0.destCIdx   = 0;

     paramSetTX0.aCnt       = 1;
    paramSetTX0.bCnt       = 8;
    paramSetTX0.cCnt       = 5;

     paramSetTX0.bCntReload = 0;

     paramSetTX0.linkAddr   = 0x4420;

     paramSetTX0.opt = (1 << 23) | (1 << 22) | (chIdTX1 << 12) | (1 << 2);  //chain chIdTX1 every intermediate and final transfer, AB synchronized

         result = EDMA3_DRV_setPaRAM(hEdma[0], chIdTXLink0, &paramSetTX0);
    if (result != EDMA3_DRV_SOK) {
        return result;
    }
    result = EDMA3_DRV_setPaRAM(hEdma[0], chIdTX0, &paramSetTX0);
    if (result != EDMA3_DRV_SOK) {
        return result;
    }

    result = EDMA3_DRV_enableTransfer(hEdma[0], chIdTX0, EDMA3_DRV_TRIG_MODE_EVENT);

I checked the registers and DRAE1 is 0x400, IER is 0x400 and IPR is 0x400. As I mentioned the code freezes and my ISR does not execute. If I comment the lines that set DRAE1 and IER it works just fine, but naturally I don't get any interrups either.

Also In my TCF file I have:

bios.HWI.instance("HWI_INT5").interruptSelectNumber = 8;
bios.HWI.instance("HWI_INT5").useDispatcher = 1;
bios.HWI.instance("HWI_INT5").fxn = prog.extern("pcm_isr");
bios.HWI.instance("HWI_INT5").monitor = "Nothing";

And at the beggining of main(): C64_enableIER(C64_EINT5);

What is the role of interrupt in DMA?

Interrupt Acknowledge Cycle The processor registers the interrupt and waits to finish the current instruction execution. Once the current instruction execution is completed, the processor initiates the interrupt handling by saving the current register contents on the stack.

What happens during DMA transfer?

In this mode, the DMA controller sends a HOLD signal to the microprocessor and waits for the HLDA signal. After receiving the HLDA signal, the DMA controller gains control of the system bus and executes only one DMA cycle. This concept of utilizing the bus for DMA operations is known as cycle stealing.

What are the two control signals that facilitate the DMA transfer?

Two control signals are used to request and acknowledge a direct memory access (DMA) transfer in the microprocessor-based system. The HOLD signal as an input(to the processor) is used to request a DMA action. The HLDA signal as an output that acknowledges the DMA action.