Exemplo n.º 1
0
void dmacHw_setChannelUserData(dmacHw_HANDLE_t handle,	
			       void *userData	
    ) {
	dmacHw_CBLK_t *pCblk = dmacHw_HANDLE_TO_CBLK(handle);

	pCblk->userData = userData;
}
Exemplo n.º 2
0
int dmacHw_initChannel(dmacHw_HANDLE_t handle	
    ) {
	dmacHw_CBLK_t *pCblk = dmacHw_HANDLE_TO_CBLK(handle);
	int module = pCblk->module;
	int channel = pCblk->channel;

	
	memset((void *)pCblk, 0, sizeof(dmacHw_CBLK_t));
	pCblk->module = module;
	pCblk->channel = channel;

	
	dmacHw_DMA_ENABLE(pCblk->module);
	
	dmacHw_RESET_CONTROL_LO(pCblk->module, pCblk->channel);
	dmacHw_RESET_CONTROL_HI(pCblk->module, pCblk->channel);
	dmacHw_RESET_CONFIG_LO(pCblk->module, pCblk->channel);
	dmacHw_RESET_CONFIG_HI(pCblk->module, pCblk->channel);

	
	dmacHw_TRAN_INT_CLEAR(pCblk->module, pCblk->channel);
	dmacHw_BLOCK_INT_CLEAR(pCblk->module, pCblk->channel);
	dmacHw_ERROR_INT_CLEAR(pCblk->module, pCblk->channel);

	
	dmacHw_TRAN_INT_DISABLE(pCblk->module, pCblk->channel);
	dmacHw_BLOCK_INT_DISABLE(pCblk->module, pCblk->channel);
	dmacHw_STRAN_INT_DISABLE(pCblk->module, pCblk->channel);
	dmacHw_DTRAN_INT_DISABLE(pCblk->module, pCblk->channel);
	dmacHw_ERROR_INT_DISABLE(pCblk->module, pCblk->channel);

	return 0;
}
Exemplo n.º 3
0
int dmacHw_initChannel(dmacHw_HANDLE_t handle	/*   [ IN ] DMA Channel handle */
    ) {
	dmacHw_CBLK_t *pCblk = dmacHw_HANDLE_TO_CBLK(handle);
	int module = pCblk->module;
	int channel = pCblk->channel;

	/* Reinitialize the control block */
	memset((void *)pCblk, 0, sizeof(dmacHw_CBLK_t));
	pCblk->module = module;
	pCblk->channel = channel;

	/* Enable DMA controller */
	dmacHw_DMA_ENABLE(pCblk->module);
	/* Reset DMA channel */
	dmacHw_RESET_CONTROL_LO(pCblk->module, pCblk->channel);
	dmacHw_RESET_CONTROL_HI(pCblk->module, pCblk->channel);
	dmacHw_RESET_CONFIG_LO(pCblk->module, pCblk->channel);
	dmacHw_RESET_CONFIG_HI(pCblk->module, pCblk->channel);

	/* Clear all raw interrupt status */
	dmacHw_TRAN_INT_CLEAR(pCblk->module, pCblk->channel);
	dmacHw_BLOCK_INT_CLEAR(pCblk->module, pCblk->channel);
	dmacHw_ERROR_INT_CLEAR(pCblk->module, pCblk->channel);

	/* Mask event specific interrupts */
	dmacHw_TRAN_INT_DISABLE(pCblk->module, pCblk->channel);
	dmacHw_BLOCK_INT_DISABLE(pCblk->module, pCblk->channel);
	dmacHw_STRAN_INT_DISABLE(pCblk->module, pCblk->channel);
	dmacHw_DTRAN_INT_DISABLE(pCblk->module, pCblk->channel);
	dmacHw_ERROR_INT_DISABLE(pCblk->module, pCblk->channel);

	return 0;
}
Exemplo n.º 4
0
void dmacHw_setChannelUserData(dmacHw_HANDLE_t handle,	/*  [ IN ] DMA Channel handle */
			       void *userData	/*  [ IN ] User data */
    ) {
	dmacHw_CBLK_t *pCblk = dmacHw_HANDLE_TO_CBLK(handle);

	pCblk->userData = userData;
}
Exemplo n.º 5
0
void dmacHw_clearInterrupt(dmacHw_HANDLE_t handle	/* [ IN ] DMA Channel handle */
    ) {
	dmacHw_CBLK_t *pCblk = dmacHw_HANDLE_TO_CBLK(handle);

	dmacHw_TRAN_INT_CLEAR(pCblk->module, pCblk->channel);
	dmacHw_BLOCK_INT_CLEAR(pCblk->module, pCblk->channel);
	dmacHw_ERROR_INT_CLEAR(pCblk->module, pCblk->channel);
}
Exemplo n.º 6
0
void dmacHw_printDebugInfo(dmacHw_HANDLE_t handle,	/*  [ IN ] DMA Channel handle */
			   void *pDescriptor,	/*   [ IN ] Descriptor buffer */
			   int (*fpPrint) (const char *, ...)	/*  [ IN ] Print callback function */
    ) {
	dmacHw_CBLK_t *pCblk = dmacHw_HANDLE_TO_CBLK(handle);

	DisplayRegisterContents(pCblk->module, pCblk->channel, fpPrint);
	DisplayDescRing(pDescriptor, fpPrint);
}
Exemplo n.º 7
0
void dmacHw_stopTransfer(dmacHw_HANDLE_t handle	/*   [ IN ] DMA Channel handle */
    ) {
	dmacHw_CBLK_t *pCblk;

	pCblk = dmacHw_HANDLE_TO_CBLK(handle);

	/* Stop the channel */
	dmacHw_DMA_STOP(pCblk->module, pCblk->channel);
}
Exemplo n.º 8
0
void dmacHw_printDebugInfo(dmacHw_HANDLE_t handle,	
			   void *pDescriptor,	
			   int (*fpPrint) (const char *, ...)	
    ) {
	dmacHw_CBLK_t *pCblk = dmacHw_HANDLE_TO_CBLK(handle);

	DisplayRegisterContents(pCblk->module, pCblk->channel, fpPrint);
	DisplayDescRing(pDescriptor, fpPrint);
}
Exemplo n.º 9
0
void dmacHw_stopTransfer(dmacHw_HANDLE_t handle	
    ) {
	dmacHw_CBLK_t *pCblk;

	pCblk = dmacHw_HANDLE_TO_CBLK(handle);

	
	dmacHw_DMA_STOP(pCblk->module, pCblk->channel);
}
Exemplo n.º 10
0
dmacHw_TRANSFER_STATUS_e dmacHw_transferCompleted(dmacHw_HANDLE_t handle	
    ) {
	dmacHw_CBLK_t *pCblk = dmacHw_HANDLE_TO_CBLK(handle);

	if (CHANNEL_BUSY(pCblk->module, pCblk->channel)) {
		return dmacHw_TRANSFER_STATUS_BUSY;
	} else if (dmacHw_REG_INT_RAW_ERROR(pCblk->module) &
		   (0x00000001 << pCblk->channel)) {
		return dmacHw_TRANSFER_STATUS_ERROR;
	}

	return dmacHw_TRANSFER_STATUS_DONE;
}
Exemplo n.º 11
0
uint32_t dmacHw_descriptorPending(dmacHw_HANDLE_t handle,	
				  void *pDescriptor	
    ) {
	dmacHw_CBLK_t *pCblk = dmacHw_HANDLE_TO_CBLK(handle);
	dmacHw_DESC_RING_t *pRing = dmacHw_GET_DESC_RING(pDescriptor);

	
	if (!CHANNEL_BUSY(pCblk->module, pCblk->channel)) {
		
		if (pRing->pEnd) {
			
			return 1;
		}
	}
	return 0;
}
Exemplo n.º 12
0
uint32_t dmacHw_descriptorPending(dmacHw_HANDLE_t handle,	/*   [ IN ] DMA Channel handle */
				  void *pDescriptor	/*   [ IN ] Descriptor buffer */
    ) {
	dmacHw_CBLK_t *pCblk = dmacHw_HANDLE_TO_CBLK(handle);
	dmacHw_DESC_RING_t *pRing = dmacHw_GET_DESC_RING(pDescriptor);

	/* Make sure channel is not busy */
	if (!CHANNEL_BUSY(pCblk->module, pCblk->channel)) {
		/* Check if pEnd is not processed */
		if (pRing->pEnd) {
			/* Something left for processing */
			return 1;
		}
	}
	return 0;
}
Exemplo n.º 13
0
dmacHw_INTERRUPT_STATUS_e dmacHw_getInterruptStatus(dmacHw_HANDLE_t handle	/* [ IN ] DMA Channel handle */
    ) {
	dmacHw_CBLK_t *pCblk = dmacHw_HANDLE_TO_CBLK(handle);
	dmacHw_INTERRUPT_STATUS_e status = dmacHw_INTERRUPT_STATUS_NONE;

	if (dmacHw_REG_INT_STAT_TRAN(pCblk->module) &
	    ((0x00000001 << pCblk->channel))) {
		status |= dmacHw_INTERRUPT_STATUS_TRANS;
	}
	if (dmacHw_REG_INT_STAT_BLOCK(pCblk->module) &
	    ((0x00000001 << pCblk->channel))) {
		status |= dmacHw_INTERRUPT_STATUS_BLOCK;
	}
	if (dmacHw_REG_INT_STAT_ERROR(pCblk->module) &
	    ((0x00000001 << pCblk->channel))) {
		status |= dmacHw_INTERRUPT_STATUS_ERROR;
	}

	return status;
}
Exemplo n.º 14
0
static uint32_t GetFifoSize(dmacHw_HANDLE_t handle	
    ) {
	uint32_t val = 0;
	dmacHw_CBLK_t *pCblk = dmacHw_HANDLE_TO_CBLK(handle);
	dmacHw_MISC_t *pMiscReg =
	    (dmacHw_MISC_t *) dmacHw_REG_MISC_BASE(pCblk->module);

	switch (pCblk->channel) {
	case 0:
		val = (pMiscReg->CompParm2.lo & 0x70000000) >> 28;
		break;
	case 1:
		val = (pMiscReg->CompParm3.hi & 0x70000000) >> 28;
		break;
	case 2:
		val = (pMiscReg->CompParm3.lo & 0x70000000) >> 28;
		break;
	case 3:
		val = (pMiscReg->CompParm4.hi & 0x70000000) >> 28;
		break;
	case 4:
		val = (pMiscReg->CompParm4.lo & 0x70000000) >> 28;
		break;
	case 5:
		val = (pMiscReg->CompParm5.hi & 0x70000000) >> 28;
		break;
	case 6:
		val = (pMiscReg->CompParm5.lo & 0x70000000) >> 28;
		break;
	case 7:
		val = (pMiscReg->CompParm6.hi & 0x70000000) >> 28;
		break;
	}

	if (val <= 0x4) {
		return 8 << val;
	} else {
		dmacHw_ASSERT(0);
	}
	return 0;
}
Exemplo n.º 15
0
uint32_t dmacHw_getDmaControllerAttribute(dmacHw_HANDLE_t handle,	
					  dmacHw_CONTROLLER_ATTRIB_e attr	
    ) {
	dmacHw_CBLK_t *pCblk = dmacHw_HANDLE_TO_CBLK(handle);

	switch (attr) {
	case dmacHw_CONTROLLER_ATTRIB_CHANNEL_NUM:
		return dmacHw_GET_NUM_CHANNEL(pCblk->module);
	case dmacHw_CONTROLLER_ATTRIB_CHANNEL_MAX_BLOCK_SIZE:
		return (1 <<
			 (dmacHw_GET_MAX_BLOCK_SIZE
			  (pCblk->module, pCblk->module) + 2)) - 8;
	case dmacHw_CONTROLLER_ATTRIB_MASTER_INTF_NUM:
		return dmacHw_GET_NUM_INTERFACE(pCblk->module);
	case dmacHw_CONTROLLER_ATTRIB_CHANNEL_BUS_WIDTH:
		return 32 << dmacHw_GET_CHANNEL_DATA_WIDTH(pCblk->module,
							   pCblk->channel);
	case dmacHw_CONTROLLER_ATTRIB_CHANNEL_FIFO_SIZE:
		return GetFifoSize(handle);
	}
	dmacHw_ASSERT(0);
	return 0;
}
Exemplo n.º 16
0
void *dmacHw_getChannelUserData(dmacHw_HANDLE_t handle	/*  [ IN ] DMA Channel handle */
    ) {
	dmacHw_CBLK_t *pCblk = dmacHw_HANDLE_TO_CBLK(handle);

	return pCblk->userData;
}
Exemplo n.º 17
0
int dmacHw_setVariableDataDescriptor(dmacHw_HANDLE_t handle,	
				     dmacHw_CONFIG_t *pConfig,	
				     void *pDescriptor,	
				     uint32_t srcAddr,	
				     void *(*fpAlloc) (int len),	
				     int len,	
				     int num	
    ) {
	dmacHw_CBLK_t *pCblk = dmacHw_HANDLE_TO_CBLK(handle);
	dmacHw_DESC_t *pProg = NULL;
	dmacHw_DESC_t *pLast = NULL;
	dmacHw_DESC_RING_t *pRing = dmacHw_GET_DESC_RING(pDescriptor);
	uint32_t dstAddr;
	uint32_t controlParam;
	int i;

	dmacHw_ASSERT(pConfig->transferType ==
		      dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM);

	if (num > pRing->num) {
		return -1;
	}

	pLast = pRing->pEnd;	
	pProg = pRing->pHead;	

	controlParam = pConfig->srcUpdate |
	    pConfig->dstUpdate |
	    pConfig->srcMaxTransactionWidth |
	    pConfig->dstMaxTransactionWidth |
	    pConfig->srcMasterInterface |
	    pConfig->dstMasterInterface |
	    pConfig->srcMaxBurstWidth |
	    pConfig->dstMaxBurstWidth |
	    dmacHw_REG_CTL_TTFC_PM_PERI |
	    dmacHw_REG_CTL_LLP_DST_EN |
	    dmacHw_REG_CTL_LLP_SRC_EN | dmacHw_REG_CTL_INT_EN;

	for (i = 0; i < num; i++) {
		
		if (((pRing->pHead->ctl.hi & dmacHw_DESC_FREE) == 0) ||
		    ((dmacHw_DESC_t *) pRing->pHead->llp == pRing->pTail)
		    ) {
			
			break;
		}
		
		pRing->pHead->sar = srcAddr;
		if (fpAlloc) {
			
			dstAddr = (uint32_t) (*fpAlloc) (len);
			
			if (dstAddr == 0) {
				if (i == 0) {
					
					return -1;
				}
				break;
			}
			
			pRing->pHead->dar = dstAddr;
		}
		
		pRing->pHead->ctl.lo = controlParam;
		
		pRing->pHead->devCtl = dmacHw_FREE_USER_MEMORY;
		
		pRing->pHead->ctl.hi = 0;
		
		pRing->pEnd = pRing->pHead;
		
		dmacHw_NEXT_DESC(pRing, pHead);
	}

	
	pRing->pEnd->ctl.lo &=
	    ~(dmacHw_REG_CTL_LLP_DST_EN | dmacHw_REG_CTL_LLP_SRC_EN);
	
	if (pLast != pProg) {
		pLast->ctl.lo |=
		    dmacHw_REG_CTL_LLP_DST_EN | dmacHw_REG_CTL_LLP_SRC_EN;
	}
	
	pCblk->descUpdated = 1;
	if (!pCblk->varDataStarted) {
		
		dmacHw_SET_LLP(pCblk->module, pCblk->channel,
			       (uint32_t) pProg - pRing->virt2PhyOffset);
		
		pCblk->varDataStarted = 1;
	}

	return i;
}
Exemplo n.º 18
0
int dmacHw_setVariableDataDescriptor(dmacHw_HANDLE_t handle,	/*   [ IN ] DMA Channel handle */
				     dmacHw_CONFIG_t *pConfig,	/*   [ IN ] Configuration settings */
				     void *pDescriptor,	/*   [ IN ] Descriptor buffer */
				     uint32_t srcAddr,	/*   [ IN ] Source peripheral address */
				     void *(*fpAlloc) (int len),	/*   [ IN ] Function pointer  that provides destination memory */
				     int len,	/*   [ IN ] Number of bytes "fpAlloc" will allocate for destination */
				     int num	/*   [ IN ] Number of descriptor to set */
    ) {
	dmacHw_CBLK_t *pCblk = dmacHw_HANDLE_TO_CBLK(handle);
	dmacHw_DESC_t *pProg = NULL;
	dmacHw_DESC_t *pLast = NULL;
	dmacHw_DESC_RING_t *pRing = dmacHw_GET_DESC_RING(pDescriptor);
	uint32_t dstAddr;
	uint32_t controlParam;
	int i;

	dmacHw_ASSERT(pConfig->transferType ==
		      dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM);

	if (num > pRing->num) {
		return -1;
	}

	pLast = pRing->pEnd;	/* Last descriptor updated */
	pProg = pRing->pHead;	/* First descriptor in the new list */

	controlParam = pConfig->srcUpdate |
	    pConfig->dstUpdate |
	    pConfig->srcMaxTransactionWidth |
	    pConfig->dstMaxTransactionWidth |
	    pConfig->srcMasterInterface |
	    pConfig->dstMasterInterface |
	    pConfig->srcMaxBurstWidth |
	    pConfig->dstMaxBurstWidth |
	    dmacHw_REG_CTL_TTFC_PM_PERI |
	    dmacHw_REG_CTL_LLP_DST_EN |
	    dmacHw_REG_CTL_LLP_SRC_EN | dmacHw_REG_CTL_INT_EN;

	for (i = 0; i < num; i++) {
		/* Allocate Rx buffer only for idle descriptor */
		if (((pRing->pHead->ctl.hi & dmacHw_DESC_FREE) == 0) ||
		    ((dmacHw_DESC_t *) pRing->pHead->llp == pRing->pTail)
		    ) {
			/* Rx descriptor is not idle */
			break;
		}
		/* Set source address */
		pRing->pHead->sar = srcAddr;
		if (fpAlloc) {
			/* Allocate memory for buffer in descriptor */
			dstAddr = (uint32_t) (*fpAlloc) (len);
			/* Check the destination address */
			if (dstAddr == 0) {
				if (i == 0) {
					/* Not a single descriptor is available */
					return -1;
				}
				break;
			}
			/* Set destination address */
			pRing->pHead->dar = dstAddr;
		}
		/* Set control information */
		pRing->pHead->ctl.lo = controlParam;
		/* Use "devCtl" to mark the memory that need to be freed later */
		pRing->pHead->devCtl = dmacHw_FREE_USER_MEMORY;
		/* Descriptor is now owned by the channel */
		pRing->pHead->ctl.hi = 0;
		/* Remember the descriptor last updated */
		pRing->pEnd = pRing->pHead;
		/* Update next descriptor */
		dmacHw_NEXT_DESC(pRing, pHead);
	}

	/* Mark the end of the list */
	pRing->pEnd->ctl.lo &=
	    ~(dmacHw_REG_CTL_LLP_DST_EN | dmacHw_REG_CTL_LLP_SRC_EN);
	/* Connect the list */
	if (pLast != pProg) {
		pLast->ctl.lo |=
		    dmacHw_REG_CTL_LLP_DST_EN | dmacHw_REG_CTL_LLP_SRC_EN;
	}
	/* Mark the descriptors are updated */
	pCblk->descUpdated = 1;
	if (!pCblk->varDataStarted) {
		/* LLP must be pointing to the first descriptor */
		dmacHw_SET_LLP(pCblk->module, pCblk->channel,
			       (uint32_t) pProg - pRing->virt2PhyOffset);
		/* Channel, handling variable data started */
		pCblk->varDataStarted = 1;
	}

	return i;
}
Exemplo n.º 19
0
void dmacHw_initiateTransfer(dmacHw_HANDLE_t handle,	/*   [ IN ] DMA Channel handle */
			     dmacHw_CONFIG_t *pConfig,	/*   [ IN ] Configuration settings */
			     void *pDescriptor	/*   [ IN ] Descriptor buffer */
    ) {
	dmacHw_DESC_RING_t *pRing;
	dmacHw_DESC_t *pProg;
	dmacHw_CBLK_t *pCblk;

	pCblk = dmacHw_HANDLE_TO_CBLK(handle);
	pRing = dmacHw_GET_DESC_RING(pDescriptor);

	if (CHANNEL_BUSY(pCblk->module, pCblk->channel)) {
		/* Not safe yet to program the channel */
		return;
	}

	if (pCblk->varDataStarted) {
		if (pCblk->descUpdated) {
			pCblk->descUpdated = 0;
			pProg =
			    (dmacHw_DESC_t *) ((uint32_t)
					       dmacHw_REG_LLP(pCblk->module,
							      pCblk->channel) +
					       pRing->virt2PhyOffset);

			/* Load descriptor if not loaded */
			if (!(pProg->ctl.hi & dmacHw_REG_CTL_DONE)) {
				dmacHw_SET_SAR(pCblk->module, pCblk->channel,
					       pProg->sar);
				dmacHw_SET_DAR(pCblk->module, pCblk->channel,
					       pProg->dar);
				dmacHw_REG_CTL_LO(pCblk->module,
						  pCblk->channel) =
				    pProg->ctl.lo;
				dmacHw_REG_CTL_HI(pCblk->module,
						  pCblk->channel) =
				    pProg->ctl.hi;
			} else if (pProg == (dmacHw_DESC_t *) pRing->pEnd->llp) {
				/* Return as end descriptor is processed */
				return;
			} else {
				dmacHw_ASSERT(0);
			}
		} else {
			return;
		}
	} else {
		if (pConfig->transferMode == dmacHw_TRANSFER_MODE_PERIODIC) {
			/* Do not make a single chain, rather process one descriptor at a time */
			pProg = pRing->pHead;
			/* Point to the next descriptor for next iteration */
			dmacHw_NEXT_DESC(pRing, pHead);
		} else {
			/* Return if no more pending descriptor */
			if (pRing->pEnd == NULL) {
				return;
			}

			pProg = pRing->pProg;
			if (pConfig->transferMode ==
			    dmacHw_TRANSFER_MODE_CONTINUOUS) {
				/* Make sure a complete ring can be formed */
				dmacHw_ASSERT((dmacHw_DESC_t *) pRing->pEnd->
					      llp == pRing->pProg);
				/* Make sure pProg pointing to the pHead */
				dmacHw_ASSERT((dmacHw_DESC_t *) pRing->pProg ==
					      pRing->pHead);
				/* Make a complete ring */
				do {
					pRing->pProg->ctl.lo |=
					    (dmacHw_REG_CTL_LLP_DST_EN |
					     dmacHw_REG_CTL_LLP_SRC_EN);
					pRing->pProg =
					    (dmacHw_DESC_t *) pRing->pProg->llp;
				} while (pRing->pProg != pRing->pHead);
			} else {
				/* Make a single long chain */
				while (pRing->pProg != pRing->pEnd) {
					pRing->pProg->ctl.lo |=
					    (dmacHw_REG_CTL_LLP_DST_EN |
					     dmacHw_REG_CTL_LLP_SRC_EN);
					pRing->pProg =
					    (dmacHw_DESC_t *) pRing->pProg->llp;
				}
			}
		}

		/* Program the channel registers */
		dmacHw_SET_SAR(pCblk->module, pCblk->channel, pProg->sar);
		dmacHw_SET_DAR(pCblk->module, pCblk->channel, pProg->dar);
		dmacHw_SET_LLP(pCblk->module, pCblk->channel,
			       (uint32_t) pProg - pRing->virt2PhyOffset);
		dmacHw_REG_CTL_LO(pCblk->module, pCblk->channel) =
		    pProg->ctl.lo;
		dmacHw_REG_CTL_HI(pCblk->module, pCblk->channel) =
		    pProg->ctl.hi;
		if (pRing->pEnd) {
			/* Remember the descriptor to use next */
			pRing->pProg = (dmacHw_DESC_t *) pRing->pEnd->llp;
		}
		/* Indicate no more pending descriptor  */
		pRing->pEnd = (dmacHw_DESC_t *) NULL;
	}
	/* Start DMA operation */
	dmacHw_DMA_START(pCblk->module, pCblk->channel);
}
Exemplo n.º 20
0
int dmacHw_configChannel(dmacHw_HANDLE_t handle,	/*   [ IN ] DMA Channel handle */
			 dmacHw_CONFIG_t *pConfig	/*   [ IN ] Configuration settings */
    ) {
	dmacHw_CBLK_t *pCblk = dmacHw_HANDLE_TO_CBLK(handle);
	uint32_t cfgHigh = 0;
	int srcTrSize;
	int dstTrSize;

	pCblk->varDataStarted = 0;
	pCblk->userData = NULL;

	/* Configure
	   - Burst transaction when enough data in available in FIFO
	   - AHB Access protection 1
	   - Source and destination peripheral ports
	 */
	cfgHigh =
	    dmacHw_REG_CFG_HI_FIFO_ENOUGH | dmacHw_REG_CFG_HI_AHB_HPROT_1 |
	    dmacHw_SRC_PERI_INTF(pConfig->
				 srcPeripheralPort) |
	    dmacHw_DST_PERI_INTF(pConfig->dstPeripheralPort);
	/* Set priority */
	dmacHw_SET_CHANNEL_PRIORITY(pCblk->module, pCblk->channel,
				    pConfig->channelPriority);

	if (pConfig->dstStatusRegisterAddress != 0) {
		/* Destination status update enable */
		cfgHigh |= dmacHw_REG_CFG_HI_UPDATE_DST_STAT;
		/* Configure status registers */
		dmacHw_SET_DSTATAR(pCblk->module, pCblk->channel,
				   pConfig->dstStatusRegisterAddress);
	}

	if (pConfig->srcStatusRegisterAddress != 0) {
		/* Source status update enable */
		cfgHigh |= dmacHw_REG_CFG_HI_UPDATE_SRC_STAT;
		/* Source status update enable */
		dmacHw_SET_SSTATAR(pCblk->module, pCblk->channel,
				   pConfig->srcStatusRegisterAddress);
	}
	/* Configure the config high register */
	dmacHw_GET_CONFIG_HI(pCblk->module, pCblk->channel) = cfgHigh;

	/* Clear all raw interrupt status */
	dmacHw_TRAN_INT_CLEAR(pCblk->module, pCblk->channel);
	dmacHw_BLOCK_INT_CLEAR(pCblk->module, pCblk->channel);
	dmacHw_ERROR_INT_CLEAR(pCblk->module, pCblk->channel);

	/* Configure block interrupt */
	if (pConfig->blockTransferInterrupt == dmacHw_INTERRUPT_ENABLE) {
		dmacHw_BLOCK_INT_ENABLE(pCblk->module, pCblk->channel);
	} else {
		dmacHw_BLOCK_INT_DISABLE(pCblk->module, pCblk->channel);
	}
	/* Configure complete transfer interrupt */
	if (pConfig->completeTransferInterrupt == dmacHw_INTERRUPT_ENABLE) {
		dmacHw_TRAN_INT_ENABLE(pCblk->module, pCblk->channel);
	} else {
		dmacHw_TRAN_INT_DISABLE(pCblk->module, pCblk->channel);
	}
	/* Configure error interrupt */
	if (pConfig->errorInterrupt == dmacHw_INTERRUPT_ENABLE) {
		dmacHw_ERROR_INT_ENABLE(pCblk->module, pCblk->channel);
	} else {
		dmacHw_ERROR_INT_DISABLE(pCblk->module, pCblk->channel);
	}
	/* Configure gather register */
	if (pConfig->srcGatherWidth) {
		srcTrSize =
		    dmacHw_GetTrWidthInBytes(pConfig->srcMaxTransactionWidth);
		if (!
		    ((pConfig->srcGatherWidth % srcTrSize)
		     && (pConfig->srcGatherJump % srcTrSize))) {
			dmacHw_REG_SGR_LO(pCblk->module, pCblk->channel) =
			    ((pConfig->srcGatherWidth /
			      srcTrSize) << 20) | (pConfig->srcGatherJump /
						   srcTrSize);
		} else {
			return -1;
		}
	}
	/* Configure scatter register */
	if (pConfig->dstScatterWidth) {
		dstTrSize =
		    dmacHw_GetTrWidthInBytes(pConfig->dstMaxTransactionWidth);
		if (!
		    ((pConfig->dstScatterWidth % dstTrSize)
		     && (pConfig->dstScatterJump % dstTrSize))) {
			dmacHw_REG_DSR_LO(pCblk->module, pCblk->channel) =
			    ((pConfig->dstScatterWidth /
			      dstTrSize) << 20) | (pConfig->dstScatterJump /
						   dstTrSize);
		} else {
			return -1;
		}
	}
	return 0;
}
Exemplo n.º 21
0
void dmacHw_initiateTransfer(dmacHw_HANDLE_t handle,	
			     dmacHw_CONFIG_t *pConfig,	
			     void *pDescriptor	
    ) {
	dmacHw_DESC_RING_t *pRing;
	dmacHw_DESC_t *pProg;
	dmacHw_CBLK_t *pCblk;

	pCblk = dmacHw_HANDLE_TO_CBLK(handle);
	pRing = dmacHw_GET_DESC_RING(pDescriptor);

	if (CHANNEL_BUSY(pCblk->module, pCblk->channel)) {
		
		return;
	}

	if (pCblk->varDataStarted) {
		if (pCblk->descUpdated) {
			pCblk->descUpdated = 0;
			pProg =
			    (dmacHw_DESC_t *) ((uint32_t)
					       dmacHw_REG_LLP(pCblk->module,
							      pCblk->channel) +
					       pRing->virt2PhyOffset);

			
			if (!(pProg->ctl.hi & dmacHw_REG_CTL_DONE)) {
				dmacHw_SET_SAR(pCblk->module, pCblk->channel,
					       pProg->sar);
				dmacHw_SET_DAR(pCblk->module, pCblk->channel,
					       pProg->dar);
				dmacHw_REG_CTL_LO(pCblk->module,
						  pCblk->channel) =
				    pProg->ctl.lo;
				dmacHw_REG_CTL_HI(pCblk->module,
						  pCblk->channel) =
				    pProg->ctl.hi;
			} else if (pProg == (dmacHw_DESC_t *) pRing->pEnd->llp) {
				
				return;
			} else {
				dmacHw_ASSERT(0);
			}
		} else {
			return;
		}
	} else {
		if (pConfig->transferMode == dmacHw_TRANSFER_MODE_PERIODIC) {
			
			pProg = pRing->pHead;
			
			dmacHw_NEXT_DESC(pRing, pHead);
		} else {
			
			if (pRing->pEnd == NULL) {
				return;
			}

			pProg = pRing->pProg;
			if (pConfig->transferMode ==
			    dmacHw_TRANSFER_MODE_CONTINUOUS) {
				
				dmacHw_ASSERT((dmacHw_DESC_t *) pRing->pEnd->
					      llp == pRing->pProg);
				
				dmacHw_ASSERT((dmacHw_DESC_t *) pRing->pProg ==
					      pRing->pHead);
				
				do {
					pRing->pProg->ctl.lo |=
					    (dmacHw_REG_CTL_LLP_DST_EN |
					     dmacHw_REG_CTL_LLP_SRC_EN);
					pRing->pProg =
					    (dmacHw_DESC_t *) pRing->pProg->llp;
				} while (pRing->pProg != pRing->pHead);
			} else {
				
				while (pRing->pProg != pRing->pEnd) {
					pRing->pProg->ctl.lo |=
					    (dmacHw_REG_CTL_LLP_DST_EN |
					     dmacHw_REG_CTL_LLP_SRC_EN);
					pRing->pProg =
					    (dmacHw_DESC_t *) pRing->pProg->llp;
				}
			}
		}

		
		dmacHw_SET_SAR(pCblk->module, pCblk->channel, pProg->sar);
		dmacHw_SET_DAR(pCblk->module, pCblk->channel, pProg->dar);
		dmacHw_SET_LLP(pCblk->module, pCblk->channel,
			       (uint32_t) pProg - pRing->virt2PhyOffset);
		dmacHw_REG_CTL_LO(pCblk->module, pCblk->channel) =
		    pProg->ctl.lo;
		dmacHw_REG_CTL_HI(pCblk->module, pCblk->channel) =
		    pProg->ctl.hi;
		if (pRing->pEnd) {
			
			pRing->pProg = (dmacHw_DESC_t *) pRing->pEnd->llp;
		}
		
		pRing->pEnd = (dmacHw_DESC_t *) NULL;
	}
	
	dmacHw_DMA_START(pCblk->module, pCblk->channel);
}
Exemplo n.º 22
0
int dmacHw_configChannel(dmacHw_HANDLE_t handle,	
			 dmacHw_CONFIG_t *pConfig	
    ) {
	dmacHw_CBLK_t *pCblk = dmacHw_HANDLE_TO_CBLK(handle);
	uint32_t cfgHigh = 0;
	int srcTrSize;
	int dstTrSize;

	pCblk->varDataStarted = 0;
	pCblk->userData = NULL;

	cfgHigh =
	    dmacHw_REG_CFG_HI_FIFO_ENOUGH | dmacHw_REG_CFG_HI_AHB_HPROT_1 |
	    dmacHw_SRC_PERI_INTF(pConfig->
				 srcPeripheralPort) |
	    dmacHw_DST_PERI_INTF(pConfig->dstPeripheralPort);
	
	dmacHw_SET_CHANNEL_PRIORITY(pCblk->module, pCblk->channel,
				    pConfig->channelPriority);

	if (pConfig->dstStatusRegisterAddress != 0) {
		
		cfgHigh |= dmacHw_REG_CFG_HI_UPDATE_DST_STAT;
		
		dmacHw_SET_DSTATAR(pCblk->module, pCblk->channel,
				   pConfig->dstStatusRegisterAddress);
	}

	if (pConfig->srcStatusRegisterAddress != 0) {
		
		cfgHigh |= dmacHw_REG_CFG_HI_UPDATE_SRC_STAT;
		
		dmacHw_SET_SSTATAR(pCblk->module, pCblk->channel,
				   pConfig->srcStatusRegisterAddress);
	}
	
	dmacHw_GET_CONFIG_HI(pCblk->module, pCblk->channel) = cfgHigh;

	
	dmacHw_TRAN_INT_CLEAR(pCblk->module, pCblk->channel);
	dmacHw_BLOCK_INT_CLEAR(pCblk->module, pCblk->channel);
	dmacHw_ERROR_INT_CLEAR(pCblk->module, pCblk->channel);

	
	if (pConfig->blockTransferInterrupt == dmacHw_INTERRUPT_ENABLE) {
		dmacHw_BLOCK_INT_ENABLE(pCblk->module, pCblk->channel);
	} else {
		dmacHw_BLOCK_INT_DISABLE(pCblk->module, pCblk->channel);
	}
	
	if (pConfig->completeTransferInterrupt == dmacHw_INTERRUPT_ENABLE) {
		dmacHw_TRAN_INT_ENABLE(pCblk->module, pCblk->channel);
	} else {
		dmacHw_TRAN_INT_DISABLE(pCblk->module, pCblk->channel);
	}
	
	if (pConfig->errorInterrupt == dmacHw_INTERRUPT_ENABLE) {
		dmacHw_ERROR_INT_ENABLE(pCblk->module, pCblk->channel);
	} else {
		dmacHw_ERROR_INT_DISABLE(pCblk->module, pCblk->channel);
	}
	
	if (pConfig->srcGatherWidth) {
		srcTrSize =
		    dmacHw_GetTrWidthInBytes(pConfig->srcMaxTransactionWidth);
		if (!
		    ((pConfig->srcGatherWidth % srcTrSize)
		     && (pConfig->srcGatherJump % srcTrSize))) {
			dmacHw_REG_SGR_LO(pCblk->module, pCblk->channel) =
			    ((pConfig->srcGatherWidth /
			      srcTrSize) << 20) | (pConfig->srcGatherJump /
						   srcTrSize);
		} else {
			return -1;
		}
	}
	
	if (pConfig->dstScatterWidth) {
		dstTrSize =
		    dmacHw_GetTrWidthInBytes(pConfig->dstMaxTransactionWidth);
		if (!
		    ((pConfig->dstScatterWidth % dstTrSize)
		     && (pConfig->dstScatterJump % dstTrSize))) {
			dmacHw_REG_DSR_LO(pCblk->module, pCblk->channel) =
			    ((pConfig->dstScatterWidth /
			      dstTrSize) << 20) | (pConfig->dstScatterJump /
						   dstTrSize);
		} else {
			return -1;
		}
	}
	return 0;
}