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; }
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)); }