Exemple #1
0
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;
}