Flexbus delay

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

Flexbus delay

Jump to solution
3,179 Views
filipdossche
Contributor III

Hi,

 

I am using an MCF54415 processor running on a Netburner MOD54415 module.

I have an application where I need to read an AD converter value at a rate of 128 nanosconds.

The processor is set up to run at 250MHz and the FB_CLK runs at 125 MHz.

I have checked that and it does produce a 125 MHz signal on the FB_CLK pin.

I have set up chip select 1 to be accessed within range 0x0200000...0x0200FFFF

 

According to the documentation in the reference manual the minimum total time to execute a read transfer from the specified address is 32 nanoseconds (4 FB_CLK cycles). to make it work OK with the AD converters I need to introduce 1 wait cycle during the generation of the CS signal which would put the total cycle time at 40 ns (i.e: 5 cycles).

 

To test how long it really takes I have put the single instruction that does the transfer in between two other which each in turn toggle an RGPIO pin.

Once every second The RGPIO pin is first toggled 10 times, then the transfer instruction is executed and the RGPIO pin is toggled another 40 times.

 

This the small section of code:

 

   asm(" move.w %d5,%a5@");     // Toggle pin

   asm(" move.w %d5,%a5@");     // Toggle pin

   asm(" move.w %a0@,%d0");     // transfer from AD

 

   asm(" move.w %d5,%a5@");     // Toggle pin
   asm(" move.w %d5,%a5@");     //Toggle pin

 

The RGPIO toggling gives me a very nice trace to use my scope with and test how fast things are running.

The subsequent toggle instructions consistently and repetitively make the state of the pin change every 16 nanoseconds.

Oddly enough it seems to take at least 80 nanoseconds to execute the single transfer instruction, that is the smallest amount of time I can measure between the last toggle instruction before the transfer and the next one after it.

That puts the total number of bus cycles for the transfer operation at 10 instead of the expected 5.

The flexbus is definitely running at 125 MHz because as I increase or decrease the number of wait states during the generation of the CS signal it gets longer or shorter with 8 nanoseconds/wait state.

 

Anyone have any ideas or suggestions what might be going on ?

Labels (1)
0 Kudos
1 Solution
2,034 Views
TomE
Specialist II

> I am thinking of using the 7.8125 MHz signal for triggering an interrupt routine which simply

> reads and stores the AD values.

If that is absolutely the only thing that the CPU is doing, then it might work OK, but I doubt it. You're only leaving 128-64 = 64ns for the interrupt, the service routine and the return from interrupt. That is only 16 CPU clocks! An interrupt takes longer than that, especially if any background routine has evicted the interrupt service routine from the cache - the instructions won't even make it from the RAM to the CPU in that time. And you'd better be storing the data read from the ADC in the Static RAM as you'll get cache-write-stalls writing to main memory.

That isn't considering the often ignored problems of interrupt latency. Again, if the CPU is doing absolutely nothing else then you might be able to keep the latency down, but if there are any other interrupts in the system (timer interrupts, network and so on) they may prevent the ADC interrupt from running unless you run the latter at IPL7. That is never a good idea.

You'd better not have and Divide or Rem instructions in your code. They take up to 35 clocks, which is 140ns, and aren't interruptible.

You should use the eDMA. That's what it is for. The DMA can be triggered by the PWM, so you should be able to use the same PWM signals you're using to drive the scanner to trigger the read of the data.

Tom

View solution in original post

0 Kudos
7 Replies
2,035 Views
filipdossche
Contributor III

Hi,

After Tom's advice I looked at how to set up a DMA transfer on a particular value occurring in a PWM counter register. As I have an example on how to do something similar from my Netburner development kit I managed to set up the eDMA module correctly and chose channel 57 to link the transfer to a register value match in the mcPWM module.

Apart from the example I am using document MCF54418RM_V3.PDF that is where I am having some problems. In the document it says that bit VALDE in register PWM_SMnDMAEN needs to be set to enable this but other than that it does not say anything else.

I would like to tie the DMA transfer to a particular PWM_SMnVALm register match occurring but I can't find any info on how to do that. The document lists a lot more detail on how to configure stuff for capture register matches but little or nothing on how to set things up for register matches.

It also provides a lot of info on how to provide interrupts or output triggers on particular register matches. The interrupts I don't need and the output triggers are linked to the on-board AD converters which I don't use.

Does anyone have any suggestions on how to set up the DMA via a PWM value register match? If there is any document out there explaining it that would be fine as well.

0 Kudos
2,035 Views
TomE
Specialist II

Part of the problem as I see it is that the different "modules" that are assembled to make a specific model of ColdFire part come with a chapter describing the operation of that module. How the modules all tie together (which pins a module can connect to and which interrupts it generates) have to be documented "somewhere else" in the manual for that specific part. That's harder work than lining up the individual module chapters.

DMA Capability is an "extra feature" implemented by the eDMA module. Detailed information on how to use it doesn't belong in the module chapters, and since the eDMA part is "general purpose", the details don't belong in its chapter either. They belong in a "this is how all these modules can be used to do something useful" chapter, which is more likely to be written as an App Note.

From my reading of the manual, all you get is "Table 19-6. DMA Request Summary for eDMA (continued)", which lists "Channel 56, Source depends on PWM_SMnDMAEN[CAPTDE], mcPWM Capture" and "Channel 57, PWM_SMnSR[RF] mcPWM Value".

You want to use the Value, not the Capture. So that means "Table 34-13. PWM_SMnDMAEN Field Descriptions" and VALDE, which is "Value registers DMA enable. Enables DMA write requests to the PWM_SMnVALm registers when PWM_SMnSR[RF] is set."

Those bits are normally used to trigger interrupts. This is a common way to add DMA capability to a module in a part - hook into the interrupt request bits somehow.

But... One way of using PWM hardware is to use it as a modulated output. This is the way the Audio worked on the original 1984 Apple Macintosh. Every horizontal sweep interrupt it reloaded a PWm controller with a new output value. That was the way it made sounds. You may also want to ramp the PWM output to fade a light or change a power setting. This involves reloading the PWM Value register every cycle. THAT'S what the "value" DMA request is for, pushing a queue of new "width" values into the PWM controller.

"Each submodule can request a DMA read access for its capture FIFOs and a DMA write request for its

double-buffered PWM_SMnVALm registers."

So I don't think you can use the PWM to trigger DMA reads from an external device.

That's what the DMA Timers are for. Can you use them instead to make your external ADC work?

If you need to use the PWM Timers, then you have to hook a signal back into DREQ0 or DREQ1 to trigger the DMA Read of the external ADC.

Tom


2,035 Views
filipdossche
Contributor III

Hi Tom,

By yesterday evening I was also beginning to suspect that DMA channel 57 could only be used to write stuff to the PWM value registers. It is not clear how a particular value register could be written to but that is not what I need anyway so I won't check it out any further.

The suggestion about feeding back a signal to DREQ0 or 1 though is really excellent and it is the method I am going to use.

As I am new to this processor and its capabilities I did not think of it but yes: it is a very obvious and elegant way of doing it.

In fact I am using PWM_A0 to generate my external ADC clock and for now I am not using PWM_B0.

I will use PWM_B0 as the signal to feed back to DREQ0.

PWM_B0 generates a signal which has the same basic clock frequency as PWM_A0 so by setting up the value registers for PWM B0's signal correctly I can arrange precisely when the DMA data transfer occurs relative to the clock signal which triggers the AD conversion. That is exactly what my application requires so it is right on the mark.

Thanks for the excellent info, appreciate it.

Filip Dossche

0 Kudos
2,035 Views
TomE
Specialist II

The reason that RGPIO exists is that most other I/O isn't Rapid at all.

Re: Help with MCF5475 speed problem.

On V2 processors all accesses to GPIO registers spends I think 12 wait states. On V4 it may be even worse.

overcoming the 12 cycle GPIO waitstate for TFT LCD

Re: MCF5307, execution speed question

Re: excution time

I've worked on a CPU that lost 200 CPU clock cycles on a GPIO read or write!

There is a fair bit of hardware between the CPU and the FlexBus. Just as the bus bridges between the I/O hardware slow down GPIO cycles, I suspect you're seeing various bridge and pipeline delays on Flexbus reads.

Have you checked the Crossbar? If it hasn't been changed it should default to "park on the CPU" which should be the fastest for you.

I was having trouble with MCF5329 DRAM read and write speed. Read specifically. The only documentation on "memory read speed" is in the LCDC App Note, and lists 128MB/s without any references, proof or detailing what DRAM was being used.. I was never able to get the CPU reading any faster than 87MB/s (14.7 memory clocks per 16-byte cache-line), but could write at 207MB/s (6.17 clocks/cache-line). The difference is that the CPU doesn't have to wait after a write before starting execution of the next cycle. After starting a read it is blocked waiting for the data before it can do anything else, and then suffers a bunch of stalls to get running again.

I suspect something similar may be happening to you.

I'd suggest back-to-back Flexbus read cycles (in your assembly code) and then see how close the cycles are. Don't trust the RGPIO to not be interfering. I'd then try a 32-bit read, which should result in two back-to-back 16-bit cycles (if you have the Flexbus programmed to be 16 bit). You may be able to use this to double the read speed.

What are you expecting to use to establish the 128ns ADC Cycle time? Do the ADCs run at this rate and you have to keep up reading them, or do they "read on command" from bus reads? If you can get the ADCs to generate a DMA Request, then that may be the best way to run them.If they need to be read (to trigger the conversion), then have the eDMA do this, triggered from a DMA Timer. That offloads the CPU. You may need to set up the Crossbar to give the eDMA priority over the CPU and everything else.

Tom

2,035 Views
filipdossche
Contributor III

Thanks Tom,

In the mean time I think I have figured it out.

If I do sequential toggling of the rapid GPIO pin I see 16 ns between two toggle events. If I stick the transfer instruction in between I get to see 80 ns. Net result: the total time taken by the transfer takes 64 ns (80-16). 40 ns of that is due to the normal foreseen flow for the read operation (4 standard cycles + 1 wait state). That leaves 24 ns for the processor to read the instruction, decode, switch from one bus to the other etc... I suppose that is fairly normal.

The 128 ns comes from a 7.8125 MHz clock signal for the ADC's which I generate by means of the PWM output block. I generate another signal at half that frequency and a start pulse for a line scanner I am using to provide the analog signals.

The PWM function block does that really well and keeps those signals perfectly in sync.

I am thinking of using the 7.8125 MHz signal for triggering an interrupt routine which simply reads and stores the AD values. If 128 ns is a bit tight to do that I can always lower the frequencies a little to get a bit more time.

Now that I have an idea of what is going on it should not be to much of a problem any more.

Filip

0 Kudos
2,035 Views
TomE
Specialist II

> I am thinking of using the 7.8125 MHz signal for triggering an interrupt routine which simply

> reads and stores the AD values.

If that is absolutely the only thing that the CPU is doing, then it might work OK, but I doubt it. You're only leaving 128-64 = 64ns for the interrupt, the service routine and the return from interrupt. That is only 16 CPU clocks! An interrupt takes longer than that, especially if any background routine has evicted the interrupt service routine from the cache - the instructions won't even make it from the RAM to the CPU in that time. And you'd better be storing the data read from the ADC in the Static RAM as you'll get cache-write-stalls writing to main memory.

That isn't considering the often ignored problems of interrupt latency. Again, if the CPU is doing absolutely nothing else then you might be able to keep the latency down, but if there are any other interrupts in the system (timer interrupts, network and so on) they may prevent the ADC interrupt from running unless you run the latter at IPL7. That is never a good idea.

You'd better not have and Divide or Rem instructions in your code. They take up to 35 clocks, which is 140ns, and aren't interruptible.

You should use the eDMA. That's what it is for. The DMA can be triggered by the PWM, so you should be able to use the same PWM signals you're using to drive the scanner to trigger the read of the data.

Tom

0 Kudos
2,033 Views
filipdossche
Contributor III

Hi Tom,

Having read your suggestion I have read the MCF54418 reference manual and you are right: that is the only right way to do it.

I have got an example on using the eDMA from the Netburner development kit I have got so it should not be to difficult to work out how to link it to a PWM capture event.

Thanks for the info.

Filip Dossche

Design Engineer

Covan Systems - Dekimo (Belgium) - Industrielaan 6/3 - 8520 Kuurne - filipd@covan.be<mailto:g@covan.be> - www.covan.be<http://www.covan.be/>; - www.Dekimo.com<http://www.dekimo.com/>;

tel +32(0)56/25.99.81 - fax +32(0)56/25.76.41 - mob +32(0)499/52.98.20

0 Kudos