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. */
static void hwInit(void) { /* unmask all Interrupts */ MMDSP_EMU_MASKIT(INTERRUPT_ENABLE); /* Enable clock for all HW blocks */ #ifndef CLOCK_GATING_POWER_MGMT CKG_ENABLE_CLOCK(ALL_BLOCKS,ALL_BLOCKS); #else CKG_ENABLE_CLOCKS_RM(); #endif #ifdef __ndk8500_a0__ DMA_SET_REG(DMA_BSM_L,(MECC_R|CD_W|CD_R|REC_W)); DMA_SET_REG(DMA_BSM_H,(IME_CWL_R|IME_TPL_R|IME_SWL_R|IME_MVF_R|IME_MVF_W|IME_CCM_W|IPA_R|RECF_W|RECF_R)); #else DMA_SET_REG(DMA_BSM,(MECC_R|CD_W|CD_R|REC_W)); #endif /* CONFIGURE DMA priorities */ #ifdef __ndk8500_a0__ DMA_SET_REG_WAIT(DMA_PRIO_LEVEL0,(21<<3)); /* CUP_CTX_R */ DMA_SET_REG_WAIT(DMA_PRIO_LEVEL1,(13<<3)); /* MTF_R */ DMA_SET_REG_WAIT(DMA_PRIO_LEVEL2,(16<<3)); /* SWF_R */ DMA_SET_REG_WAIT(DMA_PRIO_LEVEL3,(14<<3)); /* CD_R */ DMA_SET_REG_WAIT(DMA_PRIO_LEVEL4,(4<<3)); /* VPP_L_R */ DMA_SET_REG_WAIT(DMA_PRIO_LEVEL5,(6<<3)); /* VPP_C_R */ DMA_SET_REG_WAIT(DMA_PRIO_LEVEL6,(17<<3)); /* VPP_PARAM_R */ DMA_SET_REG_WAIT(DMA_PRIO_LEVEL7,(25<<3)); /* IMC_R */ DMA_SET_REG_WAIT(DMA_PRIO_LEVEL8,(24<<3)); /* IME_CWL_R */ DMA_SET_REG_WAIT(DMA_PRIO_LEVEL9,(10<<3)); /* IME_TPL_R */ DMA_SET_REG_WAIT(DMA_PRIO_LEVEL10,(9<<3)); /* IME_SWL_R */ DMA_SET_REG_WAIT(DMA_PRIO_LEVEL11,(23<<3)); /* IME_MVF_R */ DMA_SET_REG_WAIT(DMA_PRIO_LEVEL12,(8<<3)); /* IPA_R */ DMA_SET_REG_WAIT(DMA_PRIO_LEVEL13,(1<<3)); /* RECF_R */ DMA_SET_REG_WAIT(DMA_PRIO_LEVEL14,(11<<3)); /* IME_CCM_W */ DMA_SET_REG_WAIT(DMA_PRIO_LEVEL15,(12<<3)); /* MTF_W */ DMA_SET_REG_WAIT(DMA_PRIO_LEVEL16,(2<<3)); /* SWF_W */ DMA_SET_REG_WAIT(DMA_PRIO_LEVEL17,(19<<3)); /* CD_W */ DMA_SET_REG_WAIT(DMA_PRIO_LEVEL18,(3<<3)); /* VPP_L_W */ DMA_SET_REG_WAIT(DMA_PRIO_LEVEL19,(5<<3)); /* VPP_C_W */ DMA_SET_REG_WAIT(DMA_PRIO_LEVEL20,(7<<3)); /* REC_W */ DMA_SET_REG_WAIT(DMA_PRIO_LEVEL21,(20<<3)); /* CUP_CTX_W */ DMA_SET_REG_WAIT(DMA_PRIO_LEVEL22,(18<<3)); /* CUP_DBX_W */ DMA_SET_REG_WAIT(DMA_PRIO_LEVEL23,(22<<3)); /* IME_MVF_W */ DMA_SET_REG_WAIT(DMA_PRIO_LEVEL24,(15<<3)); /* RECF_W */ /* from HW overview document, recommended values */ HW_MUX3TO1_WAIT(NOD_INIT1_PRIORITY) = 0x3; HW_MUX3TO1_WAIT(NOD_INIT2_PRIORITY) = 0x1; HW_MUX3TO1_WAIT(NOD_INIT3_PRIORITY) = 0x2; #endif #ifdef __ndk8500_ed__ /* updated based on 8820 cut B STBus arbitration spec 1.0 - March 2008 */ DMA_SET_REG_WAIT(DMA_PRIO_1,7<<3); /* MTF_R */ DMA_SET_REG_WAIT(DMA_PRIO_2,10<<3); /* SWF_R */ DMA_SET_REG_WAIT(DMA_PRIO_3,13<<3); /* CD_R */ DMA_SET_REG_WAIT(DMA_PRIO_4,8<<3); /* DEB_L_R */ DMA_SET_REG_WAIT(DMA_PRIO_5,8<<3); /* DEB_C_R */ DMA_SET_REG_WAIT(DMA_PRIO_6,9<<3); /* PARAM_R */ DMA_SET_REG_WAIT(DMA_PRIO_7,11<<3); /* MECC_R */ DMA_SET_REG_WAIT(DMA_PRIO_7A,11<<3); /* CUP_CTX_R */ DMA_SET_REG_WAIT(DMA_PRIO_8,7<<3); /* MTF_W */ DMA_SET_REG_WAIT(DMA_PRIO_9,10<<3); /* SWF_W */ DMA_SET_REG_WAIT(DMA_PRIO_10,13<<3); /* CD_W */ DMA_SET_REG_WAIT(DMA_PRIO_11,8<<3); /* DEB_L_W */ DMA_SET_REG_WAIT(DMA_PRIO_12,8<<3); /* DEB_C_W */ DMA_SET_REG_WAIT(DMA_PRIO_13,12<<3); /* REC_W */ DMA_SET_REG_WAIT(DMA_PRIO_14,12<<3); /* CUP_CTX_W */ DMA_SET_REG_WAIT(DMA_PRIO_15,12<<3); /* CUP_DBX_W */ #endif #ifdef __ndk20__ DMA_SET_REG_WAIT(DMA_PRIO_1,7); /* MTF_R */ DMA_SET_REG_WAIT(DMA_PRIO_2,10); /* SWF_R */ DMA_SET_REG_WAIT(DMA_PRIO_3,13); /* CD_R */ DMA_SET_REG_WAIT(DMA_PRIO_4,8); /* DEB_L_R */ DMA_SET_REG_WAIT(DMA_PRIO_5,8); /* DEB_C_R */ DMA_SET_REG_WAIT(DMA_PRIO_6,9); /* PARAM_R */ DMA_SET_REG_WAIT(DMA_PRIO_7,14); /* MECC_R */ DMA_SET_REG_WAIT(DMA_PRIO_8,7); /* MTF_W */ DMA_SET_REG_WAIT(DMA_PRIO_9,10); /* SWF_W */ DMA_SET_REG_WAIT(DMA_PRIO_10,13); /* CD_W */ DMA_SET_REG_WAIT(DMA_PRIO_11,8); /* DEB_L_W */ DMA_SET_REG_WAIT(DMA_PRIO_12,8); /* DEB_C_W */ DMA_SET_REG_WAIT(DMA_PRIO_13,12); /* REC_W */ #endif STPLUG_PGM(); } /* End of hwInit() 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; }