EE_INTERRUPT void METH(IT12handler)(void) { #ifdef __ndk8500_a0__ t_uint16 ret=(DMA_GET_REG(DMA_ISR_L)&CD_W) | (DMA_GET_REG(DMA_ISR_L)&CD_R); DMA_SET_REG_32(DMA_ISR_L,DMA_ISR_H,0xFFFFFFFFUL); /* ACKNOWLEDGE IT */ #elif defined __ndk8500_ed__ t_uint16 ret=(DMA_GET_REG(DMA_ISR)&CD_W) | (DMA_GET_REG(DMA_ISR)&CD_R); DMA_SET_REG(DMA_ISR,0xFFFFU); /* ACKNOWLEDGE IT */ #elif defined __ndk20__ t_uint16 ret = 1; DMA_SET_REG(DMA_ISR,0x0); #endif printf("\n\nRM:Interrupt:: IT12handler, ret = %d\n",ret); if(ret) { call_interrupt(12); // BUFFER_EOW } } /* End of IT12() function. */
int main() { int bufId = 0; init_platform(); printf("Hello World\n\r"); if(i2c_init_clk() != XST_SUCCESS) return -1; // Actual test // We'll allocate four packets on the heap uint8_t* buf[4]; for(bufId = 0; bufId < 4; bufId++) { //buf[bufId] = malloc(TEST_PKT_SIZE); buf[bufId] = memalign(8, TEST_PKT_SIZE); if(buf[bufId] == 0) printf("ERROR: Buffer %d allocation failed\r\n", bufId); // Sanity check the alignment if((uint32_t)buf[bufId] & 0x7) { printf("ERROR: Buffer %d allocated at %p has invalid alignment\r\n", bufId, buf[bufId]); return -1; } } uint8_t destMac[6] = {0x00, 0x11, 0x22, 0x33, 0x01, 0x00}; uint8_t srcMac[6] = {0x00, 0x11, 0x22, 0x33, 0x00, 0x00}; // First, set up the actual contents of those packets for(bufId = 0; bufId < 4; bufId++) { int i = 0; // Fill in the MAC addresses for(i = 0; i < 6; i++) { buf[bufId][i] = destMac[i]; buf[bufId][i+6] = srcMac[i]; } // Fill out the ethertype buf[bufId][12] = 0x08; buf[bufId][13] = 0x00; memset(&buf[bufId][14], bufId+0xAA, TEST_PKT_SIZE - 14); } // Now fill in the bd descriptors // Alloc the BD descriptors XAxiDma_Bd* bd[4]; for(bufId = 0; bufId < 4; bufId++) { //bd[bufId] = malloc(sizeof(XAxiDma_Bd)); bd[bufId] = memalign(64, sizeof(XAxiDma_Bd)); if(bd[bufId] == 0) printf("ERROR: Buffer BD descriptor %d allocation failed\r\n", bufId); memset(bd[bufId], 0, sizeof(XAxiDma_Bd)); // Sanity check that they're aligned appropriately // They need to be on a 16-word (i.e. 64-byte) boundary if((uint32_t)bd[bufId] & 0x3F) { printf("ERROR: Buffer BD descriptor %d allocated at %p has invalid alignment\r\n", bufId, bd[bufId]); return -1; } // Fill in the descriptor fields //XAxiDma_BdSetBufAddr(bd[bufId], (uint32_t)buf[bufId]); //XAxiDma_BdSetLength(bd[bufId], TEST_PKT_SIZE, DMA_BUF_MAX); // Just do those manually - the driver appears to expect some metadata to be // added by the ring manager, which we don't add ourselves. XAxiDma_BdWrite(bd[bufId], XAXIDMA_BD_BUFA_OFFSET, (uint32_t)buf[bufId]); XAxiDma_BdWrite(bd[bufId], XAXIDMA_BD_CTRL_LEN_OFFSET, TEST_PKT_SIZE); // Need to set SOF and EOF bits too // Do that manually - the API doesn't appear to expose it properly // XAxiDma_Bd is actually an array behind the scenes, hence this syntax uint32_t tmp = XAxiDma_BdRead(bd[bufId], XAXIDMA_BD_CTRL_LEN_OFFSET); tmp |= (XAXIDMA_BD_CTRL_TXSOF_MASK | XAXIDMA_BD_CTRL_TXEOF_MASK); XAxiDma_BdWrite(bd[bufId], XAXIDMA_BD_CTRL_LEN_OFFSET, tmp); } for(bufId = 0; bufId < 4; bufId++) { // Set the "next" descriptor pointers now everything has been allocated properly. XAxiDma_BdWrite(bd[bufId], XAXIDMA_BD_NDESC_OFFSET, (uint32_t)(bd[(bufId + 1) % 4])); // Debugging sanity check XAxiDma_DumpBd(bd[bufId]); } // Buffers should now be set up // Set up the DMA core and (hopefully) start! // Flush caches to ensure that everything is coherent for(bufId = 0; bufId < 4; bufId++) { XAXIDMA_CACHE_FLUSH(bd[bufId]); // Also flush packets // Syntax stolen from xaxidma_bd.h Xil_DCacheFlushRange((uint32_t)buf[bufId], TEST_PKT_SIZE); } // First, reset the DMA core uint32_t reg = 0; reg = DMA_GET_REG(XAXIDMA_CR_OFFSET); reg |= XAXIDMA_CR_RESET_MASK; DMA_SET_REG(XAXIDMA_CR_OFFSET, reg); while(DMA_GET_REG(XAXIDMA_CR_OFFSET) & XAXIDMA_CR_RESET_MASK); printf("DMA Reset\r\n"); // Update the "next" pointer DMA_SET_REG(XAXIDMA_CDESC_OFFSET, (uint32_t)bd[0]); // The tail pointer should already be zero. Leave it. // Enable cyclic BD mode reg = DMA_GET_REG(XAXIDMA_CR_OFFSET); reg |= XAXIDMA_CR_CYCLIC_MASK; DMA_SET_REG(XAXIDMA_CR_OFFSET, reg); // Set run mode! reg = DMA_GET_REG(XAXIDMA_CR_OFFSET); reg |= XAXIDMA_CR_RUNSTOP_MASK; DMA_SET_REG(XAXIDMA_CR_OFFSET, reg); // Quickly check we can read the base address from the ethernet... printf("TEST: 0x%x\r\n", DMA_GET_REG(XAXIDMA_CR_OFFSET)); // Cyclic mode seems to require that we write something to the tail descriptor DMA_SET_REG(XAXIDMA_TDESC_OFFSET, 0x0); while(1) { volatile int x = 0; uint32_t tmp = 0; uint32_t tmpHigh = 0; tmp = DMA_GET_REG(XAXIDMA_SR_OFFSET); printf("DMA STATUS: 0x%x\r\n", tmp); tmp = TENGIG_GET_REG(0x200); // LSW bytes recv tmpHigh = TENGIG_GET_REG(0x204); // MSW bytes recv printf("RX BYTES: 0x%x%x\r\n", tmpHigh, tmp); tmp = TENGIG_GET_REG(0x208); // LSW bytes tx tmpHigh = TENGIG_GET_REG(0x20C); // MSW bytes tx printf("TX BYTES: 0x%x%x\r\n", tmpHigh, tmp); tmp = TENGIG_GET_REG(0x2D8); tmpHigh = TENGIG_GET_REG(0x2DC); printf("TX OK: 0x%x%x\r\n", tmpHigh, tmp); tmp = TENGIG_GET_REG(0x2E0); tmpHigh = TENGIG_GET_REG(0x2E4); printf("TX BROADCAST: 0x%x%x\r\n", tmpHigh, tmp); tmp = TENGIG_GET_REG(0x2F0); tmpHigh = TENGIG_GET_REG(0x2F4); printf("TX UNDERRUN: 0x%x%x\r\n", tmpHigh, tmp); tmp = DMA_GET_REG(0x8); printf("CURDES: 0x%x\r\n", tmp); printf("\r\n"); for(x = 0 ; x < 100000000; x++); } cleanup_platform(); return 0; }