/**
 * Send the data p over interface netif
 *
 * @param netif the netif to send the data
 * @param p the pbuf containing the data
 * @return An error code
 */
static err_t eth_output(struct netif *netif, struct pbuf *p) {
	/* Wait for previous DMA (one could also implement queueing here...) */
	while (dma_running)
		;

	/*
	 * Free the memory
	 */
	if (active_dma != NULL) {
		pbuf_free(active_dma);
#ifdef DEBUG_MALLOC
		UARTprintf("%x %d free, %s:%d;\r\n", active_dma, debug_ctr++, __FILE__, __LINE__);
#endif
	}

	active_dma = p;
	dma_running = 1;
	/* Reserve the pbuf so that it is not free()d */
	pbuf_ref(p);

	char *buf = p->payload;
	int len = p->len;
	uint16_t *len_buf = (uint16_t*)buf;
	*len_buf = len - PBUF_LINK_HLEN;

	len += 2;

	/**
	 * If this enters the infinite loop, the buffer is not correctly aligned!
	 */
	if (((unsigned long) buf & 3) != 0)
		for (;;)
			;

	/* Ensure that DMA sends all the data (and up to 3 bytes garbage extra) */
	while ((len & 3) != 0)
		len++;

	/*
	 * Configure the TX DMA channel to transfer the packet buffer.
	 */
	uDMAChannelTransferSet(UDMA_CHANNEL_ETH0TX, UDMA_MODE_AUTO,
			buf, (void *) (ETH_BASE + MAC_O_DATA), len >> 2);
	/*
	 * Enable the Ethernet Transmit DMA channel.
	 */
	uDMAChannelEnable(UDMA_CHANNEL_ETH0TX);

	/*
	 * Issue a software request to start the channel running.
	 */
	uDMAChannelRequest(UDMA_CHANNEL_ETH0TX);

	return ERR_OK;
}
Beispiel #2
0
//*****************************************************************************
//
// Configure the SysTick and SysTick interrupt with a period of 1 second.
//
//*****************************************************************************
int
main(void)
{
    uint16_t i;
  
    //
    // Set the clocking to run directly from the external crystal/oscillator.
    // (no ext 32k osc, no internal osc)
    //
    SysCtrlClockSet(false, false, SYS_CTRL_SYSDIV_32MHZ);

    //
    // Set IO clock to the same as system clock
    //
    SysCtrlIOClockSet(SYS_CTRL_SYSDIV_32MHZ);
    
    
    //
    // Set up the serial console to use for displaying messages.  This is
    // just for this example program and is not needed for Systick operation.
    //
    InitConsole();

    //
    // Display the setup on the console.
    //
    UARTprintf("DMA SW example mem to mem!\n");
    
    //
    // Fill Source buffer with some data
    //
    for(i=0; i<256; i++)
    {
        ucSourceBuffer[i] = '0' + (i % 10);
    }
    
    //
    // Enable the uDMA controller.
    //
    uDMAEnable();

    //
    // Set the base for the channel control table.
    //
    uDMAControlBaseSet(&ucDMAControlTable[0]);

    //
    // No attributes must be set for a software-based transfer.
    // The attributes are cleared by default, but are explicitly cleared
    // here, in case they were set elsewhere.
    //
    uDMAChannelAttributeDisable(UDMA_CH30_SW, UDMA_ATTR_ALL);
    
    //
    // Now set up the characteristics of the transfer for
    // 8-bit data size, with source and destination increments
    // in bytes, and a byte-wise buffer copy.  A bus arbitration
    // size of 8 is used.
    //
    uDMAChannelControlSet(UDMA_CH30_SW | UDMA_PRI_SELECT,
                          UDMA_SIZE_8 | UDMA_SRC_INC_8 |
                          UDMA_DST_INC_8 | UDMA_ARB_8);

    //
    // The transfer buffers and transfer size are now configured.
    // The transfer uses AUTO mode, which means that the
    // transfer automatically runs to completion after the first
    // request.
    //
    uDMAChannelTransferSet(UDMA_CH30_SW | UDMA_PRI_SELECT,
                           UDMA_MODE_AUTO, ucSourceBuffer, ucDestBuffer,
                           sizeof(ucDestBuffer));

    //
    // Enable Interrupt for DMA
    //
    IntEnable(INT_UDMA);
    
    //
    // Finally, the channel must be enabled.  Because this is a
    // software-initiated transfer, a request must also be made.
    // The request starts the transfer.
    //
    uDMAChannelEnable(UDMA_CH30_SW);
    uDMAChannelRequest(UDMA_CH30_SW);    
    
    //
    // Put cpu to sleep and wait for interrupt (when DMA transfer is done)
    //
    SysCtrlSleep();
    
    //
    // Loop forever while the SysTick runs.
    //
    while(1)
    {
    }
}