EmbeddedRelated.com
Forums
Memfault Beyond the Launch

'9260: EBI difference with and w/o MMU

Started by flashzr February 4, 2011
I'm using the EBI to communicate with the FPGA.

At some point I decided to test it with MMU disabled,
and then FPGA didn't work any more.
Reading is OK, but writing has one spurious WR signal.

prog:

// FPGA registers (only one shown)
typedef struct {
volatile DWORD a0;
} REG_EBI, *pREG_EBI;

// put REG_EBI on CS6 address
#define REG_BASE (AT91_CAST(pREG_EBI) AT91C_EBI_CS6)

// define REG as first register
#define REG REG_BASE->a0

void startup (void)
{
// REG EBI setup (RD 150ns, WR 120ns)
AT91C_BASE_PIOC->PIO_BSR = (1 << 13); // select B (CS6)
AT91C_BASE_PIOC->PIO_PDR = (1 << 13); // enable B

AT91C_BASE_SMC->SMC_SETUP6 = (0) | (0 << 8) | (3 << 16) | ( 0 << 24);
AT91C_BASE_SMC->SMC_PULSE6 = (5) | (7 << 8) | (5 << 16) | (10 << 24);
AT91C_BASE_SMC->SMC_CYCLE6 = (12) | (12 << 16);
AT91C_BASE_SMC->SMC_CTRL6 = (1) | (1 << 1) | (1 << 8) | (2 << 12);

// write in a loop to REG
while (1) {
REG = 0;
}
}

photo:
http://www37.zippyshare.com/v/71701808/file.html

image above, MMU enabled:

top signal is WR, bottom signal is CS.
Both WR and CS fall at the same time,
WR rises 20ns before WR.

image below, MMU disabled:

top signal is WR, bottom signal is CS.
no matter how I change the EBI setup,
there is always a spurious write.

Here are my clock settings:

#define MAIN_CLOCK 18432000

#define DIVA 2
#define MULA 21
#define PLLACOUNT 63
#define OUTA 2
#define PLLA_SETTINGS (1 << 29 | MULA << 16 | OUTA << 14 | PLLACOUNT << 8 | DIVA)

#define PLLA_CLOCK (MAIN_CLOCK / DIVA * (MULA+1))

#define MASTER_CLOCK (PLLA_CLOCK /2)
P.S.
I've tried to post at www.at91.com
but it wants me to login every time
I try to post, and never actually lets
me to post anything. Tried Opera 11 and IE 8.

I'm looking at the bottom picture and I don't see a problem. The WR- (top trace) is low for much more time than when you need it low, but the CS- (bottom trace) is high during that time. So there will be no spurious write... at least if you are using the CS- signal as a chip enable.

The way static ram works, the CS- can be held low and the WR- pulsed low, or you can hold the WR- low and pulse the CS- low or you can use any combination of one edge happening first and the other edge will define the start or stop of the write operation. In essence, the two signals are logically ANDed to create an internal write signal.

Your FPGA should operate the same way.

Rick

--- In A..., "flashzr" wrote:
>
> I'm using the EBI to communicate with the FPGA.
>
> At some point I decided to test it with MMU disabled,
> and then FPGA didn't work any more.
> Reading is OK, but writing has one spurious WR signal.
>
> prog:
>
> // FPGA registers (only one shown)
> typedef struct {
> volatile DWORD a0;
> } REG_EBI, *pREG_EBI;
>
> // put REG_EBI on CS6 address
> #define REG_BASE (AT91_CAST(pREG_EBI) AT91C_EBI_CS6)
>
> // define REG as first register
> #define REG REG_BASE->a0
>
> void startup (void)
> {
> // REG EBI setup (RD 150ns, WR 120ns)
> AT91C_BASE_PIOC->PIO_BSR = (1 << 13); // select B (CS6)
> AT91C_BASE_PIOC->PIO_PDR = (1 << 13); // enable B
>
> AT91C_BASE_SMC->SMC_SETUP6 = (0) | (0 << 8) | (3 << 16) | ( 0 << 24);
> AT91C_BASE_SMC->SMC_PULSE6 = (5) | (7 << 8) | (5 << 16) | (10 << 24);
> AT91C_BASE_SMC->SMC_CYCLE6 = (12) | (12 << 16);
> AT91C_BASE_SMC->SMC_CTRL6 = (1) | (1 << 1) | (1 << 8) | (2 << 12);
>
> // write in a loop to REG
> while (1) {
> REG = 0;
> }
> }
>
> photo:
> http://www37.zippyshare.com/v/71701808/file.html
>
> image above, MMU enabled:
>
> top signal is WR, bottom signal is CS.
> Both WR and CS fall at the same time,
> WR rises 20ns before WR.
>
> image below, MMU disabled:
>
> top signal is WR, bottom signal is CS.
> no matter how I change the EBI setup,
> there is always a spurious write.
>
> Here are my clock settings:
>
> #define MAIN_CLOCK 18432000
>
> #define DIVA 2
> #define MULA 21
> #define PLLACOUNT 63
> #define OUTA 2
> #define PLLA_SETTINGS (1 << 29 | MULA << 16 | OUTA << 14 | PLLACOUNT << 8 | DIVA)
>
> #define PLLA_CLOCK (MAIN_CLOCK / DIVA * (MULA+1))
>
> #define MASTER_CLOCK (PLLA_CLOCK /2)
> P.S.
> I've tried to post at www.at91.com
> but it wants me to login every time
> I try to post, and never actually lets
> me to post anything. Tried Opera 11 and IE 8.
>

I do see a problem.

The WR signal is not asynchronous,
but is connected to GCLK of FPGA, rising edge only.

The smaller WR spike could be interpreted as a valid
clock, and the CS in that time could be seen as LOW.
The second (valid) rising edge of WR would then
write for the second time. That could cause problems.

Anyway, why is the WR LOW for that long?
And why the period isn't constant?

I don't see why MMU would affect EBI timings
in such a way that it does..

Is there something wrong with my EBI setup?

--- In A..., "gnuarm" wrote:
>
> I'm looking at the bottom picture and I don't see a problem. The WR- (top trace) is low for much more time than when you need it low, but the CS- (bottom trace) is high during that time. So there will be no spurious write... at least if you are using the CS- signal as a chip enable.
>
> The way static ram works, the CS- can be held low and the WR- pulsed low, or you can hold the WR- low and pulse the CS- low or you can use any combination of one edge happening first and the other edge will define the start or stop of the write operation. In essence, the two signals are logically ANDed to create an internal write signal.
>
> Your FPGA should operate the same way.
>
> Rick
>
> --- In A..., "flashzr" wrote:
> >
> > I'm using the EBI to communicate with the FPGA.
> >
> > At some point I decided to test it with MMU disabled,
> > and then FPGA didn't work any more.
> > Reading is OK, but writing has one spurious WR signal.
> >
> > prog:
> >
> > // FPGA registers (only one shown)
> > typedef struct {
> > volatile DWORD a0;
> > } REG_EBI, *pREG_EBI;
> >
> > // put REG_EBI on CS6 address
> > #define REG_BASE (AT91_CAST(pREG_EBI) AT91C_EBI_CS6)
> >
> > // define REG as first register
> > #define REG REG_BASE->a0
> >
> > void startup (void)
> > {
> > // REG EBI setup (RD 150ns, WR 120ns)
> > AT91C_BASE_PIOC->PIO_BSR = (1 << 13); // select B (CS6)
> > AT91C_BASE_PIOC->PIO_PDR = (1 << 13); // enable B
> >
> > AT91C_BASE_SMC->SMC_SETUP6 = (0) | (0 << 8) | (3 << 16) | ( 0 << 24);
> > AT91C_BASE_SMC->SMC_PULSE6 = (5) | (7 << 8) | (5 << 16) | (10 << 24);
> > AT91C_BASE_SMC->SMC_CYCLE6 = (12) | (12 << 16);
> > AT91C_BASE_SMC->SMC_CTRL6 = (1) | (1 << 1) | (1 << 8) | (2 << 12);
> >
> > // write in a loop to REG
> > while (1) {
> > REG = 0;
> > }
> > }
> >
> > photo:
> > http://www37.zippyshare.com/v/71701808/file.html
> >
> > image above, MMU enabled:
> >
> > top signal is WR, bottom signal is CS.
> > Both WR and CS fall at the same time,
> > WR rises 20ns before WR.
> >
> > image below, MMU disabled:
> >
> > top signal is WR, bottom signal is CS.
> > no matter how I change the EBI setup,
> > there is always a spurious write.
> >
> > Here are my clock settings:
> >
> > #define MAIN_CLOCK 18432000
> >
> > #define DIVA 2
> > #define MULA 21
> > #define PLLACOUNT 63
> > #define OUTA 2
> > #define PLLA_SETTINGS (1 << 29 | MULA << 16 | OUTA << 14 | PLLACOUNT << 8 | DIVA)
> >
> > #define PLLA_CLOCK (MAIN_CLOCK / DIVA * (MULA+1))
> >
> > #define MASTER_CLOCK (PLLA_CLOCK /2)
> >
> >
> > P.S.
> > I've tried to post at www.at91.com
> > but it wants me to login every time
> > I try to post, and never actually lets
> > me to post anything. Tried Opera 11 and IE 8.
>

> And why the period isn't constant?

The compiler generated two writes, then a jump to the loop,
thats way the period is not always the same.
Not important anyway, though...

Whoa! I would never connect an async write signal to a clock in an FPGA. These signals are for connecting to aync memory which uses logic to AND the WR and CS before being used to clock the internal logic. Being a fully custom design, the async memory can accurately control the delay paths and avoid splinter pulses internally. In an FPGA I would sample both WR and CS with a faster clock, say 100 MHz. Then AND them and look for edges of the combined signal by comparing the current state to the previous state.

When I look at your photo, I see a splinter pulse that is above 2 volts before CS goes below 2 volts. So I see both signals at a "1" before the write starts. If you can control your path delays inside the FPGA by using constraints that very tightly limit the placement of the LUT and the path from the IO to the LUT (and assuming the two IO pins are very close on the FPGA) you have a shot at using the AND of the two inputs as a clock.

Or you can try usin WR as a clock and use CS as an enable. Treat the address and data as data which is captured in FFs, to be analyzed for address match AFTER the clock edge. Again you will need to use tight timing constraints to get the path delays of the WR and CS signals as equal as possible. Looks to me like you have perhaps 10 ns of hold time relative to the WR- rising edge. You will need to have control logic that syncs the WR clock edge with your internal clock domain. A clock domain crossing circuit would work well here.

BTW, the WR- is low for a long time because the chip is writing to some other addresses that are not within the CS address range. At least that is what I have seen on other devices. Even internal accesses can be reflected on the external bus.

One last thought... check the specs on the FPGA input to make sure 2.2 volts is high enough to assure the input is seen as a '1. This voltage may just be to low to work reliably.

What happens if you add an EBI read just before the write? You may need to use some assembly code to get this the way you want it. I went back to your original post where you mention the MMU. Does the MMU isolate the EBI so that these other writes before the write to your CS address space never make it to the EBI?

Rick
--- In A..., "flashzr" wrote:
>
> I do see a problem.
>
> The WR signal is not asynchronous,
> but is connected to GCLK of FPGA, rising edge only.
>
> The smaller WR spike could be interpreted as a valid
> clock, and the CS in that time could be seen as LOW.
> The second (valid) rising edge of WR would then
> write for the second time. That could cause problems.
>
> Anyway, why is the WR LOW for that long?
> And why the period isn't constant?
>
> I don't see why MMU would affect EBI timings
> in such a way that it does..
>
> Is there something wrong with my EBI setup?
>
> --- In A..., "gnuarm" wrote:
> >
> >
> >
> > I'm looking at the bottom picture and I don't see a problem. The WR- (top trace) is low for much more time than when you need it low, but the CS- (bottom trace) is high during that time. So there will be no spurious write... at least if you are using the CS- signal as a chip enable.
> >
> > The way static ram works, the CS- can be held low and the WR- pulsed low, or you can hold the WR- low and pulse the CS- low or you can use any combination of one edge happening first and the other edge will define the start or stop of the write operation. In essence, the two signals are logically ANDed to create an internal write signal.
> >
> > Your FPGA should operate the same way.
> >
> > Rick
> >
> > --- In A..., "flashzr" wrote:
> > >
> > > I'm using the EBI to communicate with the FPGA.
> > >
> > > At some point I decided to test it with MMU disabled,
> > > and then FPGA didn't work any more.
> > > Reading is OK, but writing has one spurious WR signal.
> > >
> > > prog:
> > >
> > > // FPGA registers (only one shown)
> > > typedef struct {
> > > volatile DWORD a0;
> > > } REG_EBI, *pREG_EBI;
> > >
> > > // put REG_EBI on CS6 address
> > > #define REG_BASE (AT91_CAST(pREG_EBI) AT91C_EBI_CS6)
> > >
> > > // define REG as first register
> > > #define REG REG_BASE->a0
> > >
> > > void startup (void)
> > > {
> > > // REG EBI setup (RD 150ns, WR 120ns)
> > > AT91C_BASE_PIOC->PIO_BSR = (1 << 13); // select B (CS6)
> > > AT91C_BASE_PIOC->PIO_PDR = (1 << 13); // enable B
> > >
> > > AT91C_BASE_SMC->SMC_SETUP6 = (0) | (0 << 8) | (3 << 16) | ( 0 << 24);
> > > AT91C_BASE_SMC->SMC_PULSE6 = (5) | (7 << 8) | (5 << 16) | (10 << 24);
> > > AT91C_BASE_SMC->SMC_CYCLE6 = (12) | (12 << 16);
> > > AT91C_BASE_SMC->SMC_CTRL6 = (1) | (1 << 1) | (1 << 8) | (2 << 12);
> > >
> > > // write in a loop to REG
> > > while (1) {
> > > REG = 0;
> > > }
> > > }
> > >
> > > photo:
> > > http://www37.zippyshare.com/v/71701808/file.html
> > >
> > > image above, MMU enabled:
> > >
> > > top signal is WR, bottom signal is CS.
> > > Both WR and CS fall at the same time,
> > > WR rises 20ns before WR.
> > >
> > > image below, MMU disabled:
> > >
> > > top signal is WR, bottom signal is CS.
> > > no matter how I change the EBI setup,
> > > there is always a spurious write.
> > >
> > > Here are my clock settings:
> > >
> > > #define MAIN_CLOCK 18432000
> > >
> > > #define DIVA 2
> > > #define MULA 21
> > > #define PLLACOUNT 63
> > > #define OUTA 2
> > > #define PLLA_SETTINGS (1 << 29 | MULA << 16 | OUTA << 14 | PLLACOUNT << 8 | DIVA)
> > >
> > > #define PLLA_CLOCK (MAIN_CLOCK / DIVA * (MULA+1))
> > >
> > > #define MASTER_CLOCK (PLLA_CLOCK /2)
> > >
> > >
> > > P.S.
> > > I've tried to post at www.at91.com
> > > but it wants me to login every time
> > > I try to post, and never actually lets
> > > me to post anything. Tried Opera 11 and IE 8.
> > >
>

People have told me several times that
I don't explain well enough :)
In my first post, I didn't even ask a single question!!

Nor did I comment on the photo: 2V, 100ns

I'm having a weird problem, explained here:
http://elm-chan.org/fsw/ff/bd/?show4

I thought maybe disabling the MMU will help,
but that just got me into deeper poo.
(don't you just love 'solving' problems by creating new ones?)

Since my original problem disappears when using the
previous version of FatFs, I don't really need non-MMU
operation to work. I'm now just wondering if my EBI setup
is wrong but it works by pure luck with MMU enabled.
I mean, I'd be happier if someone from the Atmel
would comment on my EBI setup, than to waste your time
and mine on something I don't really need.
Or, if someone has the time and AT91SAM9260 to do
some testings.. at least to say 'Yeah, I see what you see'.
> BTW, the WR- is low for a long time because the chip is writing to some other addresses that are not within the CS address range. Even internal accesses can be reflected on the external bus.

But there should be no accesses other than the ones I'm creating.
(especially the ones not respecting setup/hold times)
> Does the MMU isolate the EBI so that these other writes before the write to your CS address space never make it to the EBI?

I don't think there are any other writes.
I'm more inclined to say that EBI hardware has a bug.

Who creates those other writes?
Caching is disabled, so there is no flushing.
Interrupts are disabled, no other code executes.

You've mentioned internal writes being reflected on EBI.

This was my first test prog:
while (1)
REG = 0;
For some reason, compiler generated two writes:
2000406c: e5823000 str r3, [r2]
20004070: e5823000 str r3, [r2]
20004074: eafffffc b 2000406c

So I've added a write to port A
while (1) {
REG = 0;
AT91C_BASE_PIOA->PIO_SODR = 0;
}
and the compiler generated the expected code:
20004074: e5813000 str r3, [r1]
20004078: e50230cf str r3, [r2, #-207] ; 0xcf
2000407c: eafffffc b 20004074

That didn't change EBI waveforms.
Thus IMHO internal writes are not reflected on EBI.

--- In A..., "flashzr" wrote:
>
> People have told me several times that
> I don't explain well enough :)
> In my first post, I didn't even ask a single question!!

I won't argue with that. After reading this post I'm still not sure I understand the issue.

> Nor did I comment on the photo: 2V, 100ns

There is something that is not clear... what is "photo" 2V, 100ns"? Do you mean the original photo of the o'scope waveforms which look like they were taken with settings of 2V/div and 100ns/div?

Is there something you want to say about them? Why are you pointing out that you didn't comment on them before?
> I'm having a weird problem, explained here:
> http://elm-chan.org/fsw/ff/bd/?show4

I don't see where this applies to the problem you originally described in your first post on this here.
> I thought maybe disabling the MMU will help,
> but that just got me into deeper poo.
> (don't you just love 'solving' problems by creating new ones?)
>
> Since my original problem disappears when using the
> previous version of FatFs, I don't really need non-MMU
> operation to work. I'm now just wondering if my EBI setup
> is wrong but it works by pure luck with MMU enabled.
> I mean, I'd be happier if someone from the Atmel
> would comment on my EBI setup, than to waste your time
> and mine on something I don't really need.
> Or, if someone has the time and AT91SAM9260 to do
> some testings.. at least to say 'Yeah, I see what you see'.

I don't see anything wrong in the o'scope images that would make you think there is something wrong with the EBI setup. I am not at all clear that the spike you see is illegal. I would need to check the data sheet for the CPU and a static RAM to be sure.
> > BTW, the WR- is low for a long time because the chip is writing to some other addresses that are not within the CS address range. Even internal accesses can be reflected on the external bus.
>
> But there should be no accesses other than the ones I'm creating.
> (especially the ones not respecting setup/hold times)

What makes you think you are not creating any other writes? I haven't seen your code.
> > Does the MMU isolate the EBI so that these other writes before the write to your CS address space never make it to the EBI?
>
> I don't think there are any other writes.
> I'm more inclined to say that EBI hardware has a bug.

Yes... if you don't understand what is going on, assume someone else's work is at fault.
> Who creates those other writes?
> Caching is disabled, so there is no flushing.
> Interrupts are disabled, no other code executes.

I haven't looked at your code.
> You've mentioned internal writes being reflected on EBI.
>
> This was my first test prog:
> while (1)
> REG = 0;
> For some reason, compiler generated two writes:
> 2000406c: e5823000 str r3, [r2]
> 20004070: e5823000 str r3, [r2]
> 20004074: eafffffc b 2000406c
>
> So I've added a write to port A
> while (1) {
> REG = 0;
> AT91C_BASE_PIOA->PIO_SODR = 0;
> }
> and the compiler generated the expected code:
> 20004074: e5813000 str r3, [r1]
> 20004078: e50230cf str r3, [r2, #-207] ; 0xcf
> 2000407c: eafffffc b 20004074
>
> That didn't change EBI waveforms.
> Thus IMHO internal writes are not reflected on EBI.

I'm not following. Both pieces of code generate two writes. Are you saying that R2 points to an internal location and the first program generates the same waveform as is displayed in the photo you posted earlier? That should be impossible since that photo clearly shows writes to a location on the EBI bus and another that is not on the same chip select, external or internal. Since R2 does not change between the two instructions, the writes can't be different.

You obviously are referring to some other waveform that you have not indicated.

If you don't provide the information, what am I supposed to consider about your question?

Regardless of any of this, why do you think the waveform is illegal? What spec is it violating? The WR- signal can go low anytime it wants if CS- is not also low. I wouldn't expect it, but it is not illegal. As to "setup" time, what setup time are you referring to?

Looking at the comments in your code for the EBI setup and the waveforms in your photo, I would say you have the CS- programmed to be low for 60 ns and high for 60 ns, the WR- low for 40 ns and the rising edge is 20 ns before the CS- rising edge.

I think if you moved the WR- so the falling edge is 20 ns after the falling edge of CS- it might make the splinter pulse go away. From the long high time of the WR- pulse in your photos I don't think it will give you a splinter at the end of your EBI write. Meanwhile you can add a delay to the CS- signal at the input to the FPGA to assure adequate setup time.

Rick

My bad, as always. I've used NWR1 instead of NWR0 (NWE).

NWR1 (also called NBS1) is also used with SDRAM.
Since I was using that signal as clock to FPGA,
every rising edge of NBS1 was detected by FPGA.

After changing to NWE there are no problems.

Hopefully this thread didn't discourage anyone
from using the EBI with the FPGA...


Memfault Beyond the Launch