[En-Nut-Discussion] Designing Interfaces, e.g. DMA
Ulrich Prinz
ulrich.prinz at googlemail.com
Mon Jul 2 22:00:46 CEST 2012
Hi Uwe,
Not only the DMA_Init is a difference, the setup is different too.
So for general compatibility and probably without any loss of memory it
sould be possible to generalize int DMA_Init( int dmaCid).
gcc should use R0 for parameter and for return code. With CPUs only
supporting a single controller, R0 is used for return code only.
If you add a check
if (dmaCid > DMA_MAX_CID)
return -1;
there will be no unsused compiler warning.
The second things is with the handling of a DMA transfer.
There is no general solution without getting more and more software
overhead or writing extremely nifty #define things.
I love the idea of a OSI handling of anything that runs in packets.
So register / reserve a packet, fill in what you know, do a function
call with the packet and get back what you need ( or an error :) )
So doing a
dma_call_t *dmapack;
dmapack = NutHeapAllocClear( sizeof(...
dmapack->cmd = DMA_CMD_INIT;
dmapack->cid = 0;
dmapack->src = source_address;
dmapack->dst = my_peripheral;
dmapack->mode = DMA_M_RAM2PER | DMA_M_AUTOREP | DMA_M_....
DMA_Command( dmapack);
dmapack->cmd = DMA_CMD_RUN;
DMA_Command( dmapack);
...
This is a pretty thing as the handling functions can live without almost
any local RAM or stack. This keeps the threads stacks flat.
On the other hand, I see that it is more newbie safe to to write
functions in the way call( where, what, how) and up we go. But with
respect to the fact, that DMA is nothing for newbies...
I did not check why LPC and STM code is different in that DMA thing. I
tried to automate a lot of things, i.E. you do not have to tell the
system if source or targets are periphery or memory and so on.
But it is always difficult. It might work in a unified way for STM and
LPC today but a new CPU will break it up tomorrow.
I think the OSI way is more efficient, as you keep the functions for all
chips identical but add or remove only features and commands in the
struct. Like the USART where some support BLOCK_MODE and some others don't.
Ah, for CAN:
I did only a very simple setup interface for it as we have a commercial
stack on top. Sorry.
Best regards
Ulrich
Am 29.06.2012 11:20, schrieb Uwe Bonnes:
> Hello,
>
> how is the ethernut strategy to implement functionality like DMA? While
> there is some common functionality in the families that have DMA, a lot is
> different too. E.g. for setup with NXP, Ole has :
>
> void Lpc17xxGPDMA_Init(void);
> int Lpc17xxGPDMA_Setup(gpdma_channel_cfg_t *ch_config);
> int Lpc17xxGPDMA_IntGetStatus(gpdma_status_t type, uint8_t ch);
> void Lpc17xxGPDMA_ClearIntPending(gpdma_state_clear_t type, uint8_t ch);
> void Lpc17xxGPDMA_ChannelCmd(uint8_t ch, int enabled);
>
> while Ulrich for STM did:
>
> void DMA_Setup( uint8_t ch, void* dst, void* src, uint16_t length, uint32_t flags);
> void DMA_Enable(uint8_t ch);
> void DMA_Disable(uint8_t ch);
> void DMA_Init(void);
> void DMA_IrqMask( uint8_t ch, uint32_t mask, uint8_t ena);
> void DMA_ClearFlag( uint8_t ch, uint32_t flags);
> uint32_t DMA_GetFlag( uint8_t ch);
>
> For STM void DMA_Init(void) should perhaps be DMA_Init(uint8_t ch), as
> otherwise in parts with two independant DMA controllers, both would be
> switched on and consume current, even when only one is needed.
>
> Should every architecture implement it's own incarnation or should we tailor
> a common feature set?
>
> Same holds for the ADC/CAN etc.
>
> Bye
>
More information about the En-Nut-Discussion
mailing list