Sam7 Peripheral DMA Controller (PDC)

Having gotten the AIC working I thought I'd take a look at the DMA controller.
I was thinking about using the AIC for interrupt driven serial I/O but it seems for serial input the PDC can do what I want and I don't really need to interrupt drive it.

The PDC doesn't have a control register space of its own. Instead all the peripherals which have PDC support include PDC register at an offset of hex 100 from the peripheral base address.

If for example I'm interested in DMA for a USART with a base address of FFFC0000 then the Receive Pointer Register for this USART will be at FFFC0100

I've defined these as constants in the include file PDC.FTH - I renamed PERIPH(1)_RPR to PERIPH_RPR.

In emforth the base address of the system USART is kept in a variable called *USART.
Which USART is used depends on the particular SAM7 board I am running and is usually figured out by the kernel at boot time.
By using *USART to access the PDC my code should be work on different boards without recompilation.

Kernel hack.

To allow the lowest level serial input routines to be redirected the variable *TIMEDSIN was added to emforth Ver1.78.
This normally points to the rountine "TSIN" which is a serial byte input routine with an optional timeout.
This is called by several serial input words including SIN.
I needed to be able to point this to my new buffered version of TSIN.

The test code worked and adds buffered serial input to emforth. The buffer is 256 bytes but could easily be changed for more or less.

The serial input routine checks our buffer index plus buffer address against the PDC serial in pointer to determine if a new byte is present. If so it fetches it and adjusts the index.
If the index has reached past the end of the buffer it is reset and the NEXT pointer and counter are rewritten. The code is a little awkward because it can also loop around a set number of times as a crude timeout or loop forever. This works fine for the non-interrupted kernel but would most likely be changed to use a timer in any serious applications.

The rewriting of the NEXT registers could be done using interrupts but it easy to do it this way.