This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

AM335x EDMA 3-dimensions transfer

Hi All,

I'm working on a bare metal project using StarterWare and grlib.  My current implementation for the RectFill display driver looks like this:

void NHD_70_800480EF_ATXV_CPT::RectFill(const uint16_t top, const uint16_t left, const uint16_t bottom, const uint16_t right, uint32_t color)
{
	uint32_t* pLineStart = ((uint32_t*)(m_pixBuf.Pixels)) + ((m_Width * top) + left);
	uint16_t lineLength = right - left;

	while(pLineStart <= (((uint32_t*)(m_pixBuf.Pixels)) + (m_Width * bottom) + right))
	{
		for(uint32_t* pStartX = pLineStart; pStartX <= pLineStart + lineLength; pStartX++)
		{
			*pStartX = color;
		}

		pLineStart += m_Width;
	}
}

where the function parameters top, left, bottom and right are the screen coördinates of the rectangle to be filled with color color (a 32-bits value 0x00RRGGBB). The variable m_pixBuf.Pixels is an array of uint8_t.  It's the framebuffer who's content is displayed at the screen.  The first 4 bytes describe the color of the upper-left pixel on the screen, scanning from left to right and then from top to bottom. m_Width and m_Height are both uint16_t variables holding resp the width and height (in pixels) of the screen.

For performance reasons I would like to use the EDMA peripheral.  After consulting the EDMA in the TRM, I came up with this code:

void NHD_70_800480EF_ATXV_CPT::RectFill(const uint16_t top, const uint16_t left, const uint16_t bottom, const uint16_t right, uint32_t color)
{
	EDMA::EDMA3CCPaRAMEntry PaRAM;
	memset(&PaRAM, 0, sizeof(EDMA::EDMA3CCPaRAMEntry));

	PaRAM.opt = 	(2 << 8)	//	FIFO WIDTH = 32-bit
		|	(1 << 3)	//	this set is static
		|	(1 << 2)	//	Transfer synchronization dimension
		|	(1 << 0)	//	Source Address Mode
					;
	PaRAM.srcAddr = (uint32_t)&color;
	PaRAM.destAddr = (uint32_t)(m_pixBuf.Pixels + (top * m_Width * 4) + (left * 4));
	PaRAM.aCnt = 4;
	PaRAM.bCnt = right - left;
	PaRAM.cCnt = bottom - top;
	PaRAM.bCntReload = right - left;
	PaRAM.destBIdx = 4;
	PaRAM.destCIdx = m_Width * 4;

	m_pEDMA->SetPaRAM(1, &PaRAM);
	m_pEDMA->EnableTransfer(1, EDMA3_TRIG_MODE_MANUAL);
}

The problem is that this code only transfers one 2nd dimension, resulting in only the top (horizontal) line filled with zeros (black line).... (while the color parameter wasn't "black").

OTOH, I also wrote a EDMA-based function to transfer a 2-dimensional array of pixels from an image to the screen buffer, and this works flawless:

void NHD_70_800480EF_ATXV_CPT::ImageCopy(Rectangle& DisplayRect, Point& BmpOrg, Image* pImage)
{
	EDMA::EDMA3CCPaRAMEntry PaRAM;
	memset(&PaRAM, 0, sizeof(PaRAM));

	PaRAM.opt =		(1 << 20)	//	TCINTEN
			|	(1 <<  3)	//	STATIC
			|	(1 <<  2)	//	SYNCDIM
			;
	PaRAM.srcAddr = (uint32_t)(pImage->getData() + (BmpOrg.getY() * pImage->getSize().getWidth() * 4) + (BmpOrg.getX() * 4));
	PaRAM.destAddr = (uint32_t)(m_pixBuf.Pixels + (DisplayRect.getTop() * m_Width * 4) + (DisplayRect.getLeft() * 4));
	PaRAM.aCnt = DisplayRect.getWidth() * 4;
	PaRAM.bCnt = DisplayRect.getHeight();
	PaRAM.destBIdx = m_Width * 4;
	PaRAM.srcBIdx = pImage->getSize().getWidth() * 4;
	PaRAM.cCnt = 1;

	m_pEDMA->SetPaRAM(0, &PaRAM);
	m_pEDMA->EnableTransfer(0, EDMA3_TRIG_MODE_MANUAL);
}

So the obvious question is:

  1. What are the mistakes I made in setting up the PaRAM structure to accomplish what I intend to do?
  2. Where to find info on debugging, single stepping the EDMA, or monitoring (logging) the activity of the EDMA peripheral?

Any tips are welcome !

Thanks in advance,

Paul