void SPUThread::mfcCommand(U32 cmd) { const auto& mfc = state->mfc; switch (cmd) { case MFC_PUT_CMD: case MFC_PUTB_CMD: case MFC_PUTF_CMD: case MFC_PUTR_CMD: case MFC_PUTRB_CMD: case MFC_PUTRF_CMD: case MFC_GET_CMD: case MFC_GETB_CMD: case MFC_GETF_CMD: dmaTransfer(cmd, mfc.eal, mfc.lsa, mfc.size); break; case MFC_PUTL_CMD: case MFC_PUTLB_CMD: case MFC_PUTLF_CMD: case MFC_PUTRL_CMD: case MFC_PUTRLB_CMD: case MFC_PUTRLF_CMD: case MFC_GETL_CMD: case MFC_GETLB_CMD: case MFC_GETLF_CMD: dmaTransferList(cmd, mfc.eal, mfc.lsa, mfc.size); break; default: assert_always("Unimplemented"); } }
void SPUThread::dmaTransferList(U32 cmd, U32 eal, U32 lsa, U32 size) { const U32 listAddr = eal & 0x3ffff; const U32 listSize = size / 8; const auto& memory = parent->memory; const auto* list = memory->ptr<MFCListElement>(listAddr); for (Size i = 0; i < listSize; i++) { const auto& entry = list[i]; if (entry.lts) { dmaTransfer(cmd, entry.leal, lsa, entry.lts); } if (entry.s) { assert_always("Unimplemented"); } } }
errc tapLoadFile(tFileSystemDirEntry *dir) { unsigned long addr, targetAddr; unsigned char pole[3]; unsigned char *ind; unsigned char data[512]; unsigned char state; unsigned int block_length, min; unsigned int memInd, sector; errc err; targetAddr = 0x80000; sector=0; state = 0; addr = 0; //prenesu snapshot do pameti. (dir->size) while (addr < (dir->size)) { //vypocitam si index do pole s daty. Pole je velke 512 bajtu memInd = addr & 0x1FF; //prectu odpovidajici sektor v souboru if (memInd == 0) { if ((err = fsReadFile(dir->cluster, sector, data)) != ERR_OK) return err; sector++; dmaSetDestAddr(targetAddr); dmaSetConfig(DMA_INC_DST | DMA_INC_SRC); } switch(state) { //DATA BLOCK case 0: //DATA LENGTH lsb block_length = data[memInd]; addr++; state = 1; break; case 1: //DATA LENGTH msb block_length |= (((unsigned int)data[memInd]) << 8); addr++; state = 2; break; //TAPE DATA case 2: //TAPE DATA min = 512 - memInd; min = (block_length > min ? min : block_length); //nastavim DMA radic dmaSetSrcAddr(swAddr2hwAddr(((unsigned long)data)+memInd)); dmaTransfer(min); targetAddr += min; block_length -= min; addr += min; if (block_length==0) state = 0; break; } } //pripravim ukazatel DMA na zacatek tape dat. ROMka pak muze cist kazetu pekne od zacatku dmaSetSrcAddr(0x80000); dmaSetConfig(DMA_INC_SRC); //spustim aplikaci ind = pole; ind += taskSetPC(ind,0,0); ind--; taskRun(ind,pole); return ERR_OK; }
THD_FUNCTION(Thread1, arg) { (void)arg; /* * Activate the serial driver 0 using the driver default configuration. */ sdStart(&SD0, NULL); while (chnGetTimeout(&SD0, TIME_INFINITE)) { chnWrite(&SD0, (const uint8_t *)start_msg, strlen(start_msg)); chThdSleepMilliseconds(2000); /* Test 1 - use DMA engine to execute a word-wise memory-to-memory copy. */ chnWrite(&SD0, (const uint8_t *)test_1_msg, strlen(test_1_msg)); strcpy(instring, "After DMA test \r\n"); strcpy(outstring, "Before DMA test \r\n"); if (strcmp("Before DMA test \r\n", outstring)) { chnWrite(&SD0, (const uint8_t *)fail_string, strlen(fail_string)); } request = &test_1_req; chSysLock(); dmaRequestS(request, TIME_INFINITE); chSysUnlock(); if (strcmp("After DMA test \r\n", outstring)) { chnWrite(&SD0, (const uint8_t *)fail_string, strlen(fail_string)); } else { chnWrite(&SD0, (const uint8_t *)succeed_string, strlen(succeed_string)); } /* Test 2 - use DMA engine to execute a byte-wise memory-to-memory copy. */ chnWrite(&SD0, (const uint8_t *)test_2_msg, strlen(test_2_msg)); strcpy(instring, "After DMA test \r\n"); strcpy(outstring, "Before DMA test \r\n"); if (strcmp("Before DMA test \r\n", outstring)) { chnWrite(&SD0, (const uint8_t *)fail_string, strlen(fail_string)); } request = &test_2_req; chSysLock(); dmaRequestS(request, TIME_INFINITE); chSysUnlock(); if (strcmp("After DMA test \r\n", outstring)) { chnWrite(&SD0, (const uint8_t *)fail_string, strlen(fail_string)); } else { chnWrite(&SD0, (const uint8_t *)succeed_string, strlen(succeed_string)); } /* Test 3 - use DMA engine to execute a word-wise memory-to-memory set. */ chnWrite(&SD0, (const uint8_t *)test_3_msg, strlen(test_3_msg)); strcpy(instring, "After DMA test \r\n"); strcpy(outstring, "Before DMA test \r\n"); if (strcmp("Before DMA test \r\n", outstring)) { chnWrite(&SD0, (const uint8_t *)fail_string, strlen(fail_string)); } request = &test_3_req; chSysLock(); dmaRequestS(request, TIME_INFINITE); chSysUnlock(); if (strcmp("AAAAAAAAAAAAAAAA\r\n", outstring)) { chnWrite(&SD0, (const uint8_t *)fail_string, strlen(fail_string)); } else { chnWrite(&SD0, (const uint8_t *)succeed_string, strlen(succeed_string)); } /* Test 4 - use DMA engine to execute a word-wise memory-to-memory copy, * then call a callback. */ chnWrite(&SD0, (const uint8_t *)test_4_msg, strlen(test_4_msg)); strcpy(instring, "After DMA test \r\n"); strcpy(outstring, "Before DMA test \r\n"); cb_arg = 1; if (strcmp("Before DMA test \r\n", outstring) || (cb_arg != 1)) { chnWrite(&SD0, (const uint8_t *)fail_string, strlen(fail_string)); } request = &test_4_req; chSysLock(); dmaRequestS(request, TIME_INFINITE); chSysUnlock(); if (strcmp("After DMA test \r\n", outstring) || cb_arg) { chnWrite(&SD0, (const uint8_t *)fail_string, strlen(fail_string)); } else { chnWrite(&SD0, (const uint8_t *)succeed_string, strlen(succeed_string)); } /* Test 5 - use exclusive DMA channel 0 to execute a word-wise * memory-to-memory copy. */ chnWrite(&SD0, (const uint8_t *)test_5_msg, strlen(test_5_msg)); strcpy(instring, "After DMA test \r\n"); strcpy(outstring, "Before DMA test \r\n"); if (strcmp("Before DMA test \r\n", outstring)) { chnWrite(&SD0, (const uint8_t *)fail_string, strlen(fail_string)); } request = &test_5_req; chSysLock(); dmaAcquireI(&ch, 0); chSysUnlock(); dmaTransfer(&ch, request); if (strcmp("After DMA test \r\n", outstring)) { chnWrite(&SD0, (const uint8_t *)fail_string, strlen(fail_string)); } else { chnWrite(&SD0, (const uint8_t *)succeed_string, strlen(succeed_string)); } /* Test 6 - Attempt to claim DMA channel 0, fail, release it, attempt to * claim it again */ chnWrite(&SD0, (const uint8_t *)test_6_msg, strlen(test_6_msg)); chSysLock(); result = dmaAcquireI(&ch, 0); chSysUnlock(); if (!result) { chnWrite(&SD0, (const uint8_t *)fail_string, strlen(fail_string)); } dmaRelease(&ch); chSysLock(); result = dmaAcquireI(&ch, 0); chSysUnlock(); if (result) { chnWrite(&SD0, (const uint8_t *)fail_string, strlen(fail_string)); } else { chnWrite(&SD0, (const uint8_t *)succeed_string, strlen(succeed_string)); } dmaRelease(&ch); /* Test 7 - use exclusive DMA channel 1 to execute a word-wise * memory-to-memory copy. */ chnWrite(&SD0, (const uint8_t *)test_7_msg, strlen(test_7_msg)); strcpy(instring, "After DMA test \r\n"); strcpy(outstring, "Before DMA test \r\n"); if (strcmp("Before DMA test \r\n", outstring)) { chnWrite(&SD0, (const uint8_t *)fail_string, strlen(fail_string)); } request = &test_5_req; chSysLock(); dmaAcquireI(&ch, 1); chSysUnlock(); dmaTransfer(&ch, request); if (strcmp("After DMA test \r\n", outstring)) { chnWrite(&SD0, (const uint8_t *)fail_string, strlen(fail_string)); } else { chnWrite(&SD0, (const uint8_t *)succeed_string, strlen(succeed_string)); } dmaRelease(&ch); /* Test 8 - Claim all 3 DMA channels, attempt dmaRequest, fail */ chnWrite(&SD0, (const uint8_t *)test_8_msg, strlen(test_8_msg)); chSysLock(); result = dmaAcquireI(&ch, 0); chSysUnlock(); if (result) { chnWrite(&SD0, (const uint8_t *)fail_string, strlen(fail_string)); } chSysLock(); result = dmaAcquireI(&ch1, 1); chSysUnlock(); if (result) { chnWrite(&SD0, (const uint8_t *)fail_string, strlen(fail_string)); } chSysLock(); result = dmaAcquireI(&ch2, 2); chSysUnlock(); if (result) { chnWrite(&SD0, (const uint8_t *)fail_string, strlen(fail_string)); } chSysLock(); result_i = dmaRequestS(request, TIME_IMMEDIATE); chSysUnlock(); if (result_i > 0) { chnWrite(&SD0, (const uint8_t *)fail_string, strlen(fail_string)); } else { chnWrite(&SD0, (const uint8_t *)succeed_string, strlen(succeed_string)); } dmaRelease(&ch); dmaRelease(&ch1); dmaRelease(&ch2); } }