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:
- What are the mistakes I made in setting up the PaRAM structure to accomplish what I intend to do?
- 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