Forum Menu




 


Log in Problems?
New User? Sign Up!
AVR Freaks Forum Index

Post new topic   Reply to topic
View previous topic Printable version Log in to check your private messages View next topic
Author Message
mtwieg
PostPosted: Nov 07, 2011 - 10:21 PM
Hangaround


Joined: Dec 23, 2006
Posts: 154


Hi, I've been looking at the documentation provided for the peripheral DMA controller for the AT32UC3B devices, but it's pretty sparse. I had a few specific questions:

1) Can the DMA interact with the USB peripherals? I've read that the USB actually has its own DMA internal DMA, but I don't know if the general DMA can address the data memory of the USB, or if the USB has any kind of handshaking ability with the DMA.

2) When working in AVRstudio, how do you ensure that the memory buffers the DMA controller is operating on won't be used for anything else? I don't see how the compiler could know in advance what range of SRAM or FLASH the DMA will manipulate, so shouldn't there be a way to tell the compiler to not use that space for anything else?

3) The DMA can be configured to do transfers of bytes, half words, and full 32 bit words. Is each of these transfers a single operation, or is a half word transfer actually just two byte transfers, and are full word transfers just four bytes?

Unfortunately, atmel doesn't have any special app notes on the DMA for the UC3B devices (they give an old one from the AP7 series, but it's completely different as far as I can tell). And the only example project they give is just reading from predefined flash memory, which doesn't address my concerns at all.
 
 View user's profile Send private message  
Reply with quote Back to top
catweax
PostPosted: Nov 08, 2011 - 09:48 AM
Hangaround


Joined: Aug 25, 2011
Posts: 391
Location: Europe

The PDCA of the UC3B is pretty much the same as the one of the UC3A architecture, so you might want to have a look at some of those example projects. The USBB is very similar, but not exactly the same.

1) The PDCA has no handshake interface for the USBB, but in theory you might be able to just have the PDCA blindly write into the USBB’s memory banks, triggered by whatever peripheral you’re reading from. The the USB HSB Memory Map table for that. I can’t recommend this, though.

2) The compiler won’t know which areas the UDDMAC will manipulate, but you will. You have to tell the UDDMAC where to write data to or where to read from. That’s what the UDDMAnADDR registers are for. Allocate a buffer, tell the UDDMAC to use it, done.

3) I assume you’re talking about the PDCA: It uses exactly the word size you tell it to use. It won’t split larger word sizes into smaller blocks or use just byte transfers for everything. That’s why you can’t tell it to use three-byte “words”. I’m not sure whether the memory locations have to be aligned to their natural boundaries. The PDCA might puke if they aren’t.

I recommend to buffer whatever you’re transferring from your peripheral to the USBB. Use the PDCA to transfer from the peripheral into SRAM an once that’s done, use the UDDMAC to transfer from memory to the USBB endpoint. That way you get proper handshaking and flow control. You can also have the UDDMAC automatically switch endpoint banks for you, which the PDCA can’t do. You should also keep in mind that the USB endpoint can fill up and stall if you’re not picking up your data on the PC side fast enough. That depends on what kind of USB device you’re trying to build and what OS and driver you’re using. The UDDMAC can handle that and stalls as well, but the PDCA can’t and it’ll just drop data.

Hope this helps.
 
 View user's profile Send private message  
Reply with quote Back to top
iwoloschin
PostPosted: Nov 08, 2011 - 03:56 PM
Hangaround


Joined: May 11, 2011
Posts: 336
Location: Boston, MA

One thing to note, if you're not certain about how the PDCA/DMA transfers work, you might want to try basing your project (or the first revision at least) off of an existing ASF example. For instance, I'm doing some work with USB Mass Storage Devices, but I didn't really understand how the DMA worked to get the data from the disk (Dataflash, SD Card, whatever) to the USB endpoint. Instead of "wasting" time trying to figure out exactly how it worked, I started working with the ASF examples, and got a working proof of concept on my EVK1104. Now that I've proven that my project is feasible I can spend some more time trying to understand what's actually happening at a more detailed level, and try to find any areas I can optimize (speed, size, etc).

I personally found the datasheet to not be helpful in understanding the DMA controller. After reading that section I was still just as confused. It wasn't until reading through, and more importantly working with the examples that I began to understand how it all works.
 
 View user's profile Send private message  
Reply with quote Back to top
mtwieg
PostPosted: Nov 08, 2011 - 05:28 PM
Hangaround


Joined: Dec 23, 2006
Posts: 154


catweax wrote:
The PDCA of the UC3B is pretty much the same as the one of the UC3A architecture, so you might want to have a look at some of those example projects. The USBB is very similar, but not exactly the same.
In AVR studio, if I look at all the DMA example projects for AVR32 devices, all the ones using a PDCA do the same thing (transfer static flash memory to UART), while the others use a DMACA to do transfers from memory to memory, which isn't really relevant to the UC3B parts. Are you referring to other projects which happen to use the PDCA?
Quote:

1) The PDCA has no handshake interface for the USBB, but in theory you might be able to just have the PDCA blindly write into the USBB’s memory banks, triggered by whatever peripheral you’re reading from. The the USB HSB Memory Map table for that. I can’t recommend this, though.
Yeah that's what I assumed.
Quote:

2) The compiler won’t know which areas the UDDMAC will manipulate, but you will. You have to tell the UDDMAC where to write data to or where to read from. That’s what the UDDMAnADDR registers are for. Allocate a buffer, tell the UDDMAC to use it, done.
I was referring to the PDCA, not the UDDMA, but I guess the question still applies. How can the compiler know in advance what those address registers will be, and how much memory space the buffers will take? Do you have to declare the buffer as a static data type at the beginning of the program, and ensure it's big enough to fit whatever buffer size you could possibly want? That's what's done in the example project I have, anyways.

Quote:

3) I assume you’re talking about the PDCA: It uses exactly the word size you tell it to use. It won’t split larger word sizes into smaller blocks or use just byte transfers for everything. That’s why you can’t tell it to use three-byte “words”.
Okay, that's what I thought.
Quote:
I’m not sure whether the memory locations have to be aligned to their natural boundaries. The PDCA might puke if they aren’t.
What do you mean by "natural boundaries"?
Quote:

I recommend to buffer whatever you’re transferring from your peripheral to the USBB. Use the PDCA to transfer from the peripheral into SRAM an once that’s done, use the UDDMAC to transfer from memory to the USBB endpoint.
Okay this sounds reasonable, but I want to clarify a couple things:
Quote:
You can also have the UDDMAC automatically switch endpoint banks for you, which the PDCA can’t do.
So you mean that when an endpoint is full (while transmitting) or empty (when receiving) it can automatically start writing/reading another endpoint?
Quote:
You should also keep in mind that the USB endpoint can fill up and stall if you’re not picking up your data on the PC side fast enough.
Will this happen when just one endpoint fills up or all of the enabled ones?
Quote:

Hope this helps.
It does, thanks a lot.
 
 View user's profile Send private message  
Reply with quote Back to top
mtwieg
PostPosted: Nov 08, 2011 - 05:34 PM
Hangaround


Joined: Dec 23, 2006
Posts: 154


iwoloschin wrote:
One thing to note, if you're not certain about how the PDCA/DMA transfers work, you might want to try basing your project (or the first revision at least) off of an existing ASF example.
As I said, I'm not able to find any DMA-focused projects except the simple FLAH to UART one.
Quote:
For instance, I'm doing some work with USB Mass Storage Devices, but I didn't really understand how the DMA worked to get the data from the disk (Dataflash, SD Card, whatever) to the USB endpoint. Instead of "wasting" time trying to figure out exactly how it worked, I started working with the ASF examples, and got a working proof of concept on my EVK1104. Now that I've proven that my project is feasible I can spend some more time trying to understand what's actually happening at a more detailed level, and try to find any areas I can optimize (speed, size, etc).
Well so far I'm finding the USB stuff to be orders of magnitude more confusing than the DMA, so that probably wouldn't be a good starting point for me!
Quote:

I personally found the datasheet to not be helpful in understanding the DMA controller. After reading that section I was still just as confused. It wasn't until reading through, and more importantly working with the examples that I began to understand how it all works.
On the contrary, after reading through the datasheet I came off thinking that the DMA was too simple. At the bit/register level it's really straightforward, but the datasheet gives no insight into the details of handshaking, timing, or coding. At least that's the case for the PDCA; the UDDMA is still killing me. Nominally ASF takes care of that stuff, but I find the ASF USB code to be almost unusable.
 
 View user's profile Send private message  
Reply with quote Back to top
catweax
PostPosted: Nov 08, 2011 - 05:50 PM
Hangaround


Joined: Aug 25, 2011
Posts: 391
Location: Europe

mtwieg wrote:
In AVR studio, if I look at all the DMA example projects for AVR32 devices, all the ones using a PDCA do the same thing (transfer static flash memory to UART), while the others use a DMACA to do transfers from memory to memory, which isn't really relevant to the UC3B parts. Are you referring to other projects which happen to use the PDCA?
Not really. I just thought there were more interesting example projects available without checking. :-/
mtwieg wrote:
I was referring to the PDCA, not the UDDMA, but I guess the question still applies. How can the compiler know in advance what those address registers will be, and how much memory space the buffers will take? Do you have to declare the buffer as a static data type at the beginning of the program, and ensure it's big enough to fit whatever buffer size you could possibly want? That's what's done in the example project I have, anyways.
The compiler can’t know that so you either have to use static buffers or use malloc() for dynamic buffers. It’s up to you to make sure that the used buffer is large enough for whatever you want to put in there. Btw, don’t use local variables/arrays as buffers because they’ll be invalidated once you leave the function you declared them in.
mtwieg wrote:
Quote:
I’m not sure whether the memory locations have to be aligned to their natural boundaries. The PDCA might puke if they aren’t.
What do you mean by "natural boundaries"?
Half-words must start at an address that’s evenly divisible by 2, words must start at an address that’s evenly divisible by 4. (And quarter-words, aka. bytes, must start at an address that’s evenly divisible by 1. Razz)
mtwieg wrote:
Quote:
You can also have the UDDMAC automatically switch endpoint banks for you, which the PDCA can’t do.
So you mean that when an endpoint is full (while transmitting) or empty (when receiving) it can automatically start writing/reading another endpoint?
No. You can configure an endpoint to use two banks with half the endpoint’s size each. You can only have one bank open for access at any time and you have to release it when it’s full/empty. With two banks you can access one while the USBB filling/emptying the other one, increasing performance and avoiding wait times. It’s explained in the AVR32B’s datasheet.
mtwieg wrote:
catweax wrote:
You should also keep in mind that the USB endpoint can fill up and stall if you’re not picking up your data on the PC side fast enough.
Will this happen when just one endpoint fills up or all of the enabled ones?
Each endpoint is completely independent of all other endpoints.
mtwieg wrote:
Well so far I'm finding the USB stuff to be orders of magnitude more confusing than the DMA,(...)
You got that right. Razz
mtwieg wrote:
On the contrary, after reading through the datasheet I came off thinking that the DMA was too simple. At the bit/register level it's really straightforward, but the datasheet gives no insight into the details of handshaking, timing, or coding. At least that's the case for the PDCA;
You might want to have a look at the the other UC3s’ datasheets. I think the PDCA is explained much nicer in the UC3A3 datasheet. It’s a bit different, but the better explanations might help you.
mtwieg wrote:
the UDDMA is still killing me. Nominally ASF takes care of that stuff, but I find the ASF USB code to be almost unusable.
When I started with that stuff, I only found an example program for manually accessing the USBB without the UDDMAC, to I had to figure out the UDDMAC by myself. I found it to be non-trivial as well, but once you ignore all that stuff about automatic descriptor loading and linked lists, it’s not that complicated.
 
 View user's profile Send private message  
Reply with quote Back to top
mtwieg
PostPosted: Nov 10, 2011 - 01:12 PM
Hangaround


Joined: Dec 23, 2006
Posts: 154


catweax wrote:
The compiler can’t know that so you either have to use static buffers or use malloc() for dynamic buffers. It’s up to you to make sure that the used buffer is large enough for whatever you want to put in there. Btw, don’t use local variables/arrays as buffers because they’ll be invalidated once you leave the function you declared them in.
Okay I'll probably stick with static buffers for now to be safe. I haven't touched the malloc() stuff yet...
Quote:
Half-words must start at an address that’s evenly divisible by 2, words must start at an address that’s evenly divisible by 4. (And quarter-words, aka. bytes, must start at an address that’s evenly divisible by 1. Razz)
The whole thing with each byte having its own address still confuses me... but this actually sounds useful for an issue I was thinking about.

I'm going to want to take 16 bit SPI data and transfer it to a UART in bytes. So I can I use a DMA channel (say 0) to do half word transers from SPI to a buffer, and then use another DMA channel (say 1) to do byte transfers from the same buffer to the UART? Will each 32 bit register in the buffer be used fully (storing two 16 bit SPI results), since DMA channel 0 increments its address by two bytes, rather than by a whole register? And will channel 1 not miss any of the bytes?

Quote:
No. You can configure an endpoint to use two banks with half the endpoint’s size each. You can only have one bank open for access at any time and you have to release it when it’s full/empty. With two banks you can access one while the USBB filling/emptying the other one, increasing performance and avoiding wait times. It’s explained in the AVR32B’s datasheet.
Okay so I take it when you say "bank," you don't mean the endpoint itself, but a block of SRAM that's meant as a buffer for the endpoints...?

Thanks again for all the help.
 
 View user's profile Send private message  
Reply with quote Back to top
catweax
PostPosted: Nov 10, 2011 - 01:45 PM
Hangaround


Joined: Aug 25, 2011
Posts: 391
Location: Europe

mtwieg wrote:
I'm going to want to take 16 bit SPI data and transfer it to a UART in bytes. So I can I use a DMA channel (say 0) to do half word transers from SPI to a buffer, and then use another DMA channel (say 1) to do byte transfers from the same buffer to the UART? Will each 32 bit register in the buffer be used fully (storing two 16 bit SPI results), since DMA channel 0 increments its address by two bytes, rather than by a whole register? And will channel 1 not miss any of the bytes?
Use one channel to transfer, let’s say, 10 16 bit values from SPI to a buffer, so 20 bytes in total. Then you can use another PDCA channel to transfer 20 8 bit values to the USART. As the channels increment their address pointers by the configured transfer size, no space will be wasted inside the buffer.
mtwieg wrote:
Okay so I take it when you say "bank," you don't mean the endpoint itself, but a block of SRAM that's meant as a buffer for the endpoints...?
Yes. A block of SRAM inside the USBB, not system SRAM.
 
 View user's profile Send private message  
Reply with quote Back to top
Display posts from previous:     
Jump to:  
All times are GMT + 1 Hour
Post new topic   Reply to topic
View previous topic Printable version Log in to check your private messages View next topic
Powered by PNphpBB2 © 2003-2006 The PNphpBB Group
Credits