/* ** =================================================================== ** Method : HandleInterrupt (component DMAController) ** ** Description : ** This method is internal. It is used by Processor Expert only. ** =================================================================== */ static void HandleInterrupt(DMA1_TChnDevData *ChnDevDataPtr) { DMA1_TChnDevConst const *ChnDevConstPtr = ChnDevDataPtr->ChnDevConstPtr; uint8_t PhyChnNum = ChnDevConstPtr->PhyChnNum; uint32_t ErrorStatus; if (DMA_PDD_GetChannelErrorFlag(DMA_BASE_PTR, PhyChnNum)) { /* Channel error detected */ /* Transfer error */ ErrorStatus = DMA_PDD_GetErrorStatusFlags(DMA_BASE_PTR); /* Get error flags */ if (ErrorStatus != 0U) { /* Any error flag set? */ if (DMA_PDD_GetErrorStatusChannel(DMA_BASE_PTR) == ChnDevConstPtr->PhyChnNum) { /* Channel error flags valid? */ /* Remember all (device and channel) error flags */ ChnDevDataPtr->ErrorFlags |= ErrorStatus; } else { /* Remember device error flags only (if any flag set) */ ChnDevDataPtr->ErrorFlags |= (ErrorStatus & DMA_PDD_DEVICE_ERROR_FLAGS); /* Remember channel error flags are not valid */ ChnDevDataPtr->ErrorFlags |= LDD_DMA_UNKNOWN_ERROR; } } else { /* Error flags not valid */ ChnDevDataPtr->ErrorFlags |= LDD_DMA_UNKNOWN_ERROR; } DMAMUX_PDD_EnableChannel(DMAMUX_BASE_PTR, ChnDevConstPtr->PhyChnNum, PDD_DISABLE); DMA_PDD_ClearChannelErrorFlag(DMA_BASE_PTR, ChnDevConstPtr->PhyChnNum); if (ChnDevDataPtr->Events.OnErrorFnPtr != NULL) { ChnDevDataPtr->Events.OnErrorFnPtr(ChnDevDataPtr->UserDataPtr); } } else if (DMA_PDD_GetDoneFlag(DMA_BASE_PTR, PhyChnNum)) { /* Transfer done without error */ DMA_PDD_ClearChannelInterruptFlag(DMA_BASE_PTR, ChnDevConstPtr->PhyChnNum); DMA_PDD_ClearDoneFlag(DMA_BASE_PTR, ChnDevConstPtr->PhyChnNum); if (ChnDevDataPtr->Events.OnCompleteFnPtr != NULL) { ChnDevDataPtr->Events.OnCompleteFnPtr(ChnDevDataPtr->UserDataPtr); } } else { } }
static uint8_t Transfer(uint32_t dataAddress, size_t nofBytes) { static const uint8_t OneValue = 0xFF; /* value to clear or set the port bits */ TMOUT1_CounterHandle handle; bool isTimeout; uint32_t done0, done1, done2; /* clear any pending done flags for DMA channels */ DMA_PDD_ClearDoneFlag(DMA_BASE_PTR, DMA_PDD_CHANNEL_0); DMA_PDD_ClearDoneFlag(DMA_BASE_PTR, DMA_PDD_CHANNEL_1); DMA_PDD_ClearDoneFlag(DMA_BASE_PTR, DMA_PDD_CHANNEL_2); /* set DMA source addresses */ DMA_PDD_SetSourceAddress(DMA_BASE_PTR, DMA_PDD_CHANNEL_0, (uint32_t)&OneValue); /* set source address */ DMA_PDD_SetSourceAddress(DMA_BASE_PTR, DMA_PDD_CHANNEL_1, dataAddress); /* set source address */ DMA_PDD_SetSourceAddress(DMA_BASE_PTR, DMA_PDD_CHANNEL_2, (uint32_t)&OneValue); /* set source address */ /* set byte count addresses */ DMA_PDD_SetByteCount(DMA_BASE_PTR, DMA_PDD_CHANNEL_0, nofBytes); /* set number of bytes to transfer */ DMA_PDD_SetByteCount(DMA_BASE_PTR, DMA_PDD_CHANNEL_1, nofBytes); /* set number of bytes to transfer */ DMA_PDD_SetByteCount(DMA_BASE_PTR, DMA_PDD_CHANNEL_2, nofBytes); /* set number of bytes to transfer */ /* reset TPM counter */ TPM_PDD_InitializeCounter(TPM0_DEVICE); /* reset timer counter */ TPM_PDD_ClearChannelFlags(TPM0_DEVICE, 0x00); TPM_PDD_ClearOverflowInterruptFlag(TPM0_DEVICE); /* re-enable DMA Muxing: it will disabled at the end of the transfer */ DMAMUX_PDD_EnableChannel(DMAMUX0_BASE_PTR, 0, PDD_ENABLE); DMAMUX_PDD_EnableChannel(DMAMUX0_BASE_PTR, 1, PDD_ENABLE); DMAMUX_PDD_EnableChannel(DMAMUX0_BASE_PTR, 2, PDD_ENABLE); /* enable DMA peripheral requests */ DMA_PDD_EnablePeripheralRequest(DMA_BASE_PTR, DMA_PDD_CHANNEL_2, PDD_ENABLE); /* enable request from peripheral */ DMA_PDD_EnablePeripheralRequest(DMA_BASE_PTR, DMA_PDD_CHANNEL_1, PDD_ENABLE); /* enable request from peripheral */ DMA_PDD_EnablePeripheralRequest(DMA_BASE_PTR, DMA_PDD_CHANNEL_0, PDD_ENABLE); /* enable request from peripheral */ /* clear timer flags and status so it starts from a clean starting point */ TPM_PDD_ClearChannelFlags(TPM0_DEVICE, 0x00); TPM_PDD_ClearOverflowInterruptFlag(TPM0_DEVICE); /* enable TPM DMA */ TPM_PDD_WriteStatusControlReg(TPM0_DEVICE,TPM_PDD_ReadStatusControlReg(TPM0_DEVICE)|TPM_SC_DMA_MASK); TPM_PDD_EnableChannelDma(TPM0_DEVICE, 1); TPM_PDD_EnableChannelDma(TPM0_DEVICE, 0); /* start the TPM timer */ StartTimer(); isTimeout = FALSE; handle = TMOUT1_GetCounter(100/TMOUT1_TICK_PERIOD_MS); for(;;) { /* wait until transfer is complete */ if (TMOUT1_CounterExpired(handle)) { isTimeout = TRUE; break; /* leave loop */ } done0 = DMA_PDD_GetDoneFlag(DMA_BASE_PTR, DMA_PDD_CHANNEL_0); done1 = DMA_PDD_GetDoneFlag(DMA_BASE_PTR, DMA_PDD_CHANNEL_1); done2 = DMA_PDD_GetDoneFlag(DMA_BASE_PTR, DMA_PDD_CHANNEL_2); if (done0 && done1 && done2) { break; /* done! */ } WAIT1_WaitOSms(1); /* give back some time */ } TMOUT1_LeaveCounter(handle); WAIT1_Waitus(50); /* latch, low for at least 50 us (40x1.25us) */ /* disable DMA-Muxing: necessary, otherwise DMA events on TPM0 channel 0 might be still latched. * Will enable muxing for next transfer */ DMAMUX_PDD_EnableChannel(DMAMUX0_BASE_PTR, 0, PDD_DISABLE); DMAMUX_PDD_EnableChannel(DMAMUX0_BASE_PTR, 1, PDD_DISABLE); DMAMUX_PDD_EnableChannel(DMAMUX0_BASE_PTR, 2, PDD_DISABLE); /* disable peripheral DMA */ TPM_PDD_WriteStatusControlReg(TPM0_DEVICE,TPM_PDD_ReadStatusControlReg(TPM0_DEVICE)&(~TPM_SC_DMA_MASK)); TPM_PDD_DisableChannelDma(TPM0_DEVICE, 1); TPM_PDD_DisableChannelDma(TPM0_DEVICE, 0); StopTimer(); /* stop TPM */ if (isTimeout) { return ERR_BUSY; } return ERR_OK; }