LOCAL void HX8309_Clear( uint32 color //color to fill the whole lcd. ) { uint32 i; uint16 *buf_ptr = (uint16 *)LCD_GetLCDBuffer(); uint16 fill_color = color; for(i=0; i<(HX8309_HEIGHT ); i++) { #ifdef LCD_USE_DMA dma_request(0, (uint32)&fill_color, (uint32)(buf_ptr + i * HX8309_WIDTH), HX8309_WIDTH, 1, 1); #else { int j; for (j = 0; j < HX8309_WIDTH; j++) { HX8309_SEND_DATA(*(buf_ptr+i*HX8309_WIDTH+j)); } } #endif } HX8309_Invalidate(); }
static int transferToFlash(void* buffer, int size) { int controller = 0; int channel = 0; if((((uint32_t)buffer) & 0x3) != 0) { // the buffer needs to be aligned for DMA, last two bits have to be clear return ERROR_ALIGN; } SET_REG(NAND + NAND_CONFIG, GET_REG(NAND + NAND_CONFIG) | (1 << NAND_CONFIG_DMASETTINGSHIFT)); SET_REG(NAND + NAND_TRANSFERSIZE, size - 1); SET_REG(NAND + NAND_CON, 0x7F4); CleanCPUDataCache(); dma_request(DMA_MEMORY, 4, 4, DMA_NAND, 4, 4, &controller, &channel, NULL); dma_perform((uint32_t)buffer, DMA_NAND, size, 0, &controller, &channel); if(dma_finish(controller, channel, 500) != 0) { bufferPrintf("nand: dma timed out\r\n"); return ERROR_TIMEOUT; } if(wait_for_status_bit_3(500) != 0) { bufferPrintf("nand: waiting for status bit 3 timed out\r\n"); return ERROR_TIMEOUT; } SET_REG(NAND + NAND_CON, NAND_CON_SETTING1); CleanAndInvalidateCPUDataCache(); return 0; }
static int transferToFlash(void* buffer, int size) { int controller = 0; int channel = 0; if((((uint32_t)buffer) & 0x3) != 0) { // the buffer needs to be aligned for DMA, last two bits have to be clear return ERROR_ALIGN; } SET_REG(NAND + FMCTRL0, GET_REG(NAND + FMCTRL0) | (1 << FMCTRL0_DMASETTINGSHIFT)); SET_REG(NAND + FMDNUM, size - 1); SET_REG(NAND + FMCTRL1, 0x7F4); CleanCPUDataCache(); dma_request(DMA_MEMORY, 4, 4, DMA_NAND, 4, 4, &controller, &channel, NULL); dma_perform((uint32_t)buffer, DMA_NAND, size, 0, &controller, &channel); if(dma_finish(controller, channel, 500) != 0) { bufferPrintf("nand: dma timed out\r\n"); return ERROR_TIMEOUT; } if(wait_for_transfer_done(500) != 0) { bufferPrintf("nand: waiting for transfer done timed out\r\n"); return ERROR_TIMEOUT; } SET_REG(NAND + FMCTRL1, FMCTRL1_FLUSHFIFOS); CleanAndInvalidateCPUDataCache(); return 0; }
LOCAL ERR_LCD_E HX8309_Invalidate(void) { uint16 i,j; uint16 address = 0; uint16 *buf_ptr = (uint16 *)LCD_GetLCDBuffer(); #ifdef LCD_USE_DMA uint32 dummy_before,dummy_after; address = (uint16) ( (((HX8309_WIDTH - 1 + OFFSET_X) & 0xFF ) << 8 ) | (OFFSET_X)); HX8309_sendcommand1(0x44, address); // set horizon address address = (uint16) ( ((HX8309_HEIGHT-1) & 0xFF) << 8 ); HX8309_sendcommand1(0x45, address); // set vertical address HX8309_sendcommand1(0x0021, OFFSET_X); HX8309_SEND_COMMAND(0x0022); // send data. dummy_before = 1 % 4; // Inserted numbers befor every arrow. dummy_after = 3 - (HX8309_WIDTH % 4); // Inserted numbers after every arrow. for(j=0; j<(HX8309_HEIGHT ); j++) { dma_request(0, (uint32)(buf_ptr + j * HX8309_WIDTH), 0x58008000, HX8309_WIDTH, 1, 0); } #else address = (uint16) ( (((HX8309_WIDTH - 1 + OFFSET_X) & 0xFF ) << 8 ) | (OFFSET_X)); HX8309_sendcommand1(0x16, address); // set horizon address address = (uint16) ( ((HX8309_HEIGHT-1) & 0xFF) << 8 ); HX8309_sendcommand1(0x17, address); // set vertical address // Set start RAM address (AC register) HX8309_sendcommand1(0x21, OFFSET_X); HX8309_SEND_COMMAND(0x0022); // send data. for(i=0; i<(HX8309_WIDTH * HX8309_HEIGHT); i++) HX8309_SEND_DATA( *buf_ptr++ ); #endif return ERR_LCD_NONE; }
IODMARegion *IODMARegion::initWithRequest(uint32_t request, size_t pages) { if(!super::init()) return 0; _wrapped = dma_request(pages, request); if(!_wrapped) { release(); return 0; } return this; }
void cmd_dma(int argc, char** argv) { if(argc < 4) { bufferPrintf("Usage: %s <source> <dest> <size>\r\n", argv[0]); return; } uint32_t source = parseNumber(argv[1]); uint32_t dest = parseNumber(argv[2]); uint32_t size = parseNumber(argv[3]); int controller = 0; int channel = 0; bufferPrintf("dma_request: %d\r\n", dma_request(DMA_MEMORY, 4, 8, DMA_MEMORY, 4, 8, &controller, &channel)); bufferPrintf("dma_perform(controller: %d, channel %d): %d\r\n", controller, channel, dma_perform(source, dest, size, FALSE, &controller, &channel)); bufferPrintf("dma_finish(controller: %d, channel %d): %d\r\n", controller, channel, dma_finish(controller, channel, 500)); }
/*** VDDRequestDMA - This service is provided for VDDs to request a DMA * transfer. * * INPUT: * hVDD VDD Handle * iChannel DMA Channel on which the operation to take place * Buffer Buffer where to or from transfer to take place * length Transfer Count (in bytes) * * If Zero, returns the Current VDMA transfer count * in bytes. * * OUTPUT * DWORD returns bytes transferred * if Zero check GetLastError to determine if the * call failed or succeeded * GetLastError has the extended error information. * * NOTES * 1. This service is intended for those VDDs which do not want to * carry on the DMA operation on their own. Carrying on a DMA * operation involves understanding all the DMA registers and * figuring out what has to be copied, from where and how much. * * 2. This service will be slower than using VDDQueryDMA/VDDSetDMA and * doing the transfer on your own. * * 3. Extended Error codes: * * ERROR_ALREADY_EXISTS - Vdd already has active IO port handlers * ERROR_OUTOFMEMORY - Insufficient resources for additional VDD * Port handler set. * ERROR_INVALID_ADDRESS - One of the IO port handlers has an invalid * address. * */ DWORD VDDRequestDMA ( HANDLE hVDD, WORD iChannel, PVOID Buffer, DWORD length ) { DMA_ADAPT *pDmaAdp; DMA_CNTRL *pDcp; WORD Chan; WORD Size; WORD tCount; BOOL bMore; if (iChannel > DMA_CONTROLLER_CHANNELS*DMA_ADAPTOR_CONTROLLERS) { SetLastError(ERROR_INVALID_ADDRESS); return FALSE; } pDmaAdp = dmaGetAdaptor(); pDcp = &pDmaAdp->controller[dma_physical_controller(iChannel)]; Chan = dma_physical_channel(iChannel); Size = dma_unit_size(iChannel); // if the controller or the channel is disabled, return 0 if (pDcp->command.bits.controller_disable == 1 || (pDcp->mask & (1 << Chan)) == 0) return (0); tCount = ((WORD)pDcp->current_count[Chan][1] << 8) | (WORD)pDcp->current_count[Chan][0]; SetLastError(0); // assume success // return requested transfer count (in bytes) if (!length) { return (DWORD)Size*((DWORD)tCount + 1); } length = length/Size - 1; if (length > 0xFFFF) { length = 0xFFFF; } try { bMore = (BOOL) dma_request((half_word)iChannel, Buffer, (word) length); } except(EXCEPTION_EXECUTE_HANDLER) { SetLastError(ERROR_INVALID_ADDRESS); return 0; } if (!bMore) { // terminal count has been reached return ((DWORD)tCount+1) * (DWORD)Size; } tCount -= ((WORD)pDcp->current_count[Chan][1] << 8) | (WORD)pDcp->current_count[Chan][0]; return ((DWORD)tCount + 1) * (DWORD)Size; }
LOCAL ERR_LCD_E HX8309_InvalidateRectImage( uint16 left, //the left value of the rectangel uint16 top, //top of the rectangle uint16 right, //right of the rectangle uint16 bottom, //bottom of the rectangle uint16 *buf_ptr, uint8 is_invert//ignore ) { uint32 i, j; //uint32 dummy_before, dummy_after; uint32 row, column,rect_width; left = (left >= MP4_MAX_WIDTH) ? MP4_MAX_WIDTH-1 : left; right = (right >= MP4_MAX_WIDTH) ? MP4_MAX_WIDTH-1 : right; top = (top >= MP4_MAX_HEIGHT) ? MP4_MAX_HEIGHT-1 : top; bottom = (bottom >= MP4_MAX_HEIGHT) ? MP4_MAX_HEIGHT-1 : bottom; if ( ( right < left ) || ( bottom < top ) ) { return ERR_LCD_PARAMETER_WRONG; } HX8309_set_display_window(left, top, right, bottom); // In High Speed RAM Write Mode. Maybe some dummy data are insterted. //dummy_before = (left) % 4; // Inserted numbers befor every arrow. //dummy_after = 3 - (right % 4); // Inserted numbers after every arrow. #ifdef LCD_USE_DMA HX8309_set_start_address(left, top); HX8309_SEND_COMMAND(0x22); // send data. rect_width = right-left+1; for (j = top; j <= bottom; j++) { dma_request(0, (uint32)(buf_ptr + j * rect_width +left), 0x58008000, rect_width, 1, 0); } #else row = bottom - top; column = right - left; HX8309_set_start_address(left, top); HX8309_SEND_COMMAND(0x22); // send data. for (i = 0; i <= row; i++) { //for(j = 0; j<dummy_before; j++) // Insert dummy write befor real write. //R61500_SEND_DATA(0x00); for (j = 0; j <= column; j++) // real write HX8309_SEND_DATA( *(buf_ptr + (top+i)*HX8309_WIDTH + left+j) ); //for(j=0; j<dummy_after; j++) // Insert dummy write after real write. //R61500_SEND_DATA(0x00); } #endif return ERR_LCD_NONE; }