MCF5329 USB OTG (Device) and DMA

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

MCF5329 USB OTG (Device) and DMA

1,158 Views
sbouvet
Contributor I

Hello,

 I use the USB OTG in mode device.

I would like to know, how use it in DMA mode.

In my source code I load dest source in dtd_buffer, but I lose some packets if my Dtd buffer isn't aligned on 1024 Bytes.

Probably I don’t use correctly the mechanism, someone can help me?

 

 I join my source code if can help you, to help me.

 

Thanks.

Labels (1)
0 Kudos
4 Replies

469 Views
TomE
Specialist II

> I load dest source in dtd_buffer

 

There are no variables in that source code called "dtd_buffer". it would help if you said exactly what buffer you are using. is it one of these?

 

 

uint8 recv_buf[MAX_QH_PACKET_SIZE];uint8 send_buf[MAX_QH_PACKET_SIZE];uint8 tmp_buf[MAX_USB_DESC_SIZE];uint8  buf_rd[BUFSIZ];

 I can't see anything that would align these buffers. The compiler is free to align them to any byte let alone any four bytes.

 

The proper way is to declare these buffers in special reserved memory segments in the linker script.

 

You should download all the sample USB code sources for this chip and see how they do it.

 

The hacked way to align buffers is to do what I'm doing in my code to allocate buffers on 16 byte boundaries:

 

 

/* * To force buffer alignment of "A" it is necessary to * add (A - 1) to the size and pointer and then mask. This * only applies if the underlying alignment "a" is one. More * generally, (A - a) needs to be added. */#define CPU_MCF_CACHE_SIZE_BYTES  (16)#define CANVAS_BUFFER_ALIGN       (CPU_MCF_CACHE_SIZE_BYTES)#define MALLOC_ALIGNMENT          (8)#define CANVAS_BUFFER_ADD         (CPU_MCF_CACHE_SIZE_BYTES - MALLOC_ALIGNMENT)#define CANVAS_ADDRESS_MASK       (~(CPU_MCF_CACHE_SIZE_BYTES - 1))pBmp = malloc(bmpSize + CANVAS_BUFFER_ADD);pBmp = (uint32_t *)(((uint32_t)pBmp + CANVAS_BUFFER_ADD) & CANVAS_ADDRESS_MASK);

 In your case, to allocate a 1k buffer aligned at a 1k boundary, declare a 2k buffer and then find the 1k chunk inside it which is aligned:

 

 

char bufUnaligned[2 * 1024];char *pBufAligned;uint32_t nPtr;pBufAligned = bufUnaligned + 1024;pBufAligned = (char *)(((uint32_t)pBufAligned) & ~(1024 - 1));ornPtr = (uint32_t)&bufUnaligned[0];nPtr += 1024;nPtr &= 0xfffffc00;pBufAligned = (char *)nPtr;

 If you need a bunch of aligned buffers, make one big one that can hold all of them plus the worst alignment offset, and then sequentially assign known-aligned buffers within that big one.

 

 

 

 

 

 

 

0 Kudos

469 Views
sbouvet
Contributor I

Thanks for your answer.

But my problem is not to align my buffer,

but I don't understand Why I would like receive 64 packets of 64 bytes the end of some packet are lost.

I have this problem  when my buffer address is 0x40FEFF00 all data received after 0x40FEFFFF are not in my SDRAM.

 

I don't know if my explain it is more clear.

 

Thanks.

0 Kudos

469 Views
TomE
Specialist II

You said:

> but I lose some packets if my Dtd buffer isn't aligned on 1024 Bytes.

 

I advised how to align buffers.

 

I also asked you:

 

> it would help if you said exactly what buffer you are using. is it one of these?

 

You haven't said WHICH buffer needs aligning in the code, so that makes it hard to help you.

 

You then said:

 

> But my problem is not to align my buffer,

 

So what is the problem? From what you say, you only lose data if the buffers aren't aligned. So align the buffers and the problem is solved.

 

> But I don't understand Why I would like receive 64 packets of 64 bytes the end of some packet are lost.

 

I don't understand why you want to like to lose packets either.

 

> I don't know if my explain it is more clear.

 

Very unclear. Can you get someone else to check and edit your question before posting next time?

 

> I have this problem  when my buffer address is 0x40FEFF00 all data received after 0x40FEFFFF are not in my SDRAM.

 

So DON'T use that buffer address!

 

It is common practice with cheaply designed DMA hardware like the MCF5329 has in the USB and LCD controller, that they don't use 32-bit adders to calculate the addresses. For instance, in the LCD controller (this bit me yesterday) that the entire DMA buffer must fit within a 4M memory page. This is because the hardware only increments the bottom 22 bits of the DMA address, so Address Bit A21 doesn't carry into A22. This means the address after 0x003fffff is 0x00000000 (and 0x413fffff is 0x41000000 and so on).

 

If this buffer is "4k aligned" then "x40FEFFFF + 1 = 0x40FEF000" and not 0x40FF0000. Look in memory at 0x40FEF000 and see if that is where it has copied your data.

 

If you search for the word "align" in the Reference Manual there are 6 matches in the USB chapters. The code we bought allocates all USB DMA memory from a 4k aligned block. The comment on this says "This address must be 4KB aligned because the periodic list uses it".

 

If you read the EHCI Specification it says "The frame list must always be aligned on a 4K page boundary. This requirement ensures that the frame list is always physically contiguous.". That spec might answer your question.

 

 

0 Kudos

469 Views
sbouvet
Contributor I

Thanks for your answer, I know my first post it is not really clear.

your second answer help me to undersyand Why i lost some packet.

 

0 Kudos