EmbeddedRelated.com
Forums
The 2024 Embedded Online Conference

GPIO Port 0 bug?

Started by "h.belig" November 6, 2008
Hello,

the problem seems to be simple, nevertheless I could not solve it:
I want to output a word to PORT 0.
This is the initialisation:

PINSEL0 = 0; // P0[15]..[0] as GPIO (default)
PINMODE0 = 0; // with pull-up
resistor (default)

PINSEL1 = 0; // P0[31]..[16] as GPIO (default)
PINMODE1 = 0; // with pull-up resistor (default)

FIO0DIR = 0xffffffff; // P0[31]..[0] as output
FIO0MASK = 0; // mask P0[31]..[0]

and this is how I output the words:
FIO0PIN = *pt++;
FIO0PIN = *pt++;
FIO0PIN = *pt++;
....
There is no change on Port 0 pins, all of them are high.
However, if port 2 is addressed instead, its ok.
Port 1 also fails.

My first idea was that it has something to do with the fact, that port
0 and port 1 can run as slow (legacy) ports. But I did not find a hint
how to select the fast mode other than choosing the appropriate
registers as shown above.

The board I am using is EA's LPC2468 OEM board (without an OS).
But when I used Keil's MCB2300 (LPC2378), outputting data to port 0
wasn't possible either.

I then went through the code step by step and monitored FIO0PIN in the
memory (EA board with LPC2468).

With each
FIO0PIN = *pt++,
command the correct value of *pt++ has been written to memory.
Not to FIO0PIN, but to FIO0SET!!!! That is the explanation why all
pins of port0 remained constantly high.

That looks like a hardware bug to me, providing I didn't miss
something essential.

Does anybody know whether there is a work-around?
Using FIO0CLR and FIO0SET is not a solution because of performance
reasons. Neither can I use ports 2..4.

Henry

An Engineer's Guide to the LPC2100 Series

Hi,

> Hello,
>
> the problem seems to be simple, nevertheless I could not solve it:
> I want to output a word to PORT 0.
> This is the initialisation:
>
> PINSEL0 = 0; // P0[15]..[0] as GPIO (default)
> PINMODE0 = 0; // with pull-up
> resistor (default)
>
> PINSEL1 = 0; // P0[31]..[16] as GPIO (default)
> PINMODE1 = 0; // with pull-up resistor (default)
>
> FIO0DIR = 0xffffffff; // P0[31]..[0] as output
> FIO0MASK = 0; // mask P0[31]..[0]
>
> and this is how I output the words:
> FIO0PIN = *pt++;
> FIO0PIN = *pt++;
> FIO0PIN = *pt++;
> ....
> There is no change on Port 0 pins, all of them are high.

You need to enable Fast I/O on ports 0 and 1 to get them out of legacy mode;
look at GPIOM in the SCS register, IIRC.

--
Paul Curtis, Rowley Associates Ltd http://www.rowley.co.uk
CrossWorks for ARM, MSP430, AVR, MAXQ, and now Cortex-M3 processors
You have to enable fast io using the first bit in the SCS register.

--Ray

h.belig wrote:
>
> Hello,
>
> the problem seems to be simple, nevertheless I could not solve it:
> I want to output a word to PORT 0.
> This is the initialisation:
>
> PINSEL0 = 0; // P0[15]..[0] as GPIO (default)
> PINMODE0 = 0; // with pull-up
> resistor (default)
>
> PINSEL1 = 0; // P0[31]..[16] as GPIO (default)
> PINMODE1 = 0; // with pull-up resistor (default)
>
> FIO0DIR = 0xffffffff; // P0[31]..[0] as output
> FIO0MASK = 0; // mask P0[31]..[0]
>
> and this is how I output the words:
> FIO0PIN = *pt++;
> FIO0PIN = *pt++;
> FIO0PIN = *pt++;
> ....
> There is no change on Port 0 pins, all of them are high.
> However, if port 2 is addressed instead, its ok.
> Port 1 also fails.
>
> My first idea was that it has something to do with the fact, that port
> 0 and port 1 can run as slow (legacy) ports. But I did not find a hint
> how to select the fast mode other than choosing the appropriate
> registers as shown above.
>
> The board I am using is EA's LPC2468 OEM board (without an OS).
> But when I used Keil's MCB2300 (LPC2378), outputting data to port 0
> wasn't possible either.
>
> I then went through the code step by step and monitored FIO0PIN in the
> memory (EA board with LPC2468).
>
> With each
> FIO0PIN = *pt++,
> command the correct value of *pt++ has been written to memory.
> Not to FIO0PIN, but to FIO0SET!!!! That is the explanation why all
> pins of port0 remained constantly high.
>
> That looks like a hardware bug to me, providing I didn't miss
> something essential.
>
> Does anybody know whether there is a work-around?
> Using FIO0CLR and FIO0SET is not a solution because of performance
> reasons. Neither can I use ports 2..4.
>
> Henry
>
>

As both Paul and Ray say, it has to be enabled. From the LPC24xx Users
Manual (UM10237), page 190:

When PORT0 and PORT1 are used, user must select whether these ports will be
accessed via registers that provide enhanced features or a legacy set of
registers (see
Section 37 "Other system controls and status flags" on page 35). While both
of a port's
fast and legacy GPIO registers are controlling the same physical pins, these
two port
control branches are mutually exclusive and operate independently. For
example,
changing a pin's output via a fast register will not be observable via the
corresponding
legacy register.

--jc

On Thu, Nov 6, 2008 at 9:08 AM, Ray Molenkamp wrote:

> You have to enable fast io using the first bit in the SCS register.
>
> --Ray
> h.belig wrote:
> >
> > Hello,
> >
> > the problem seems to be simple, nevertheless I could not solve it:
> > I want to output a word to PORT 0.
> > This is the initialisation:
> >
> > PINSEL0 = 0; // P0[15]..[0] as GPIO (default)
> > PINMODE0 = 0; // with pull-up
> > resistor (default)
> >
> > PINSEL1 = 0; // P0[31]..[16] as GPIO (default)
> > PINMODE1 = 0; // with pull-up resistor (default)
> >
> > FIO0DIR = 0xffffffff; // P0[31]..[0] as output
> > FIO0MASK = 0; // mask P0[31]..[0]
> >
> > and this is how I output the words:
> > FIO0PIN = *pt++;
> > FIO0PIN = *pt++;
> > FIO0PIN = *pt++;
> > ....
> > There is no change on Port 0 pins, all of them are high.
> > However, if port 2 is addressed instead, its ok.
> > Port 1 also fails.
> >
> > My first idea was that it has something to do with the fact, that port
> > 0 and port 1 can run as slow (legacy) ports. But I did not find a hint
> > how to select the fast mode other than choosing the appropriate
> > registers as shown above.
> >
> > The board I am using is EA's LPC2468 OEM board (without an OS).
> > But when I used Keil's MCB2300 (LPC2378), outputting data to port 0
> > wasn't possible either.
> >
> > I then went through the code step by step and monitored FIO0PIN in the
> > memory (EA board with LPC2468).
> >
> > With each
> > FIO0PIN = *pt++,
> > command the correct value of *pt++ has been written to memory.
> > Not to FIO0PIN, but to FIO0SET!!!! That is the explanation why all
> > pins of port0 remained constantly high.
> >
> > That looks like a hardware bug to me, providing I didn't miss
> > something essential.
> >
> > Does anybody know whether there is a work-around?
> > Using FIO0CLR and FIO0SET is not a solution because of performance
> > reasons. Neither can I use ports 2..4.
> >
> > Henry
> >
> >
>
>

That is a well hidden feature!
Thank you very much, Paul, Ray and jc.
I works fine now.

Henry

--- In l..., "J.C. Wren" wrote:
>
> As both Paul and Ray say, it has to be enabled. From the LPC24xx Users
> Manual (UM10237), page 190:
>
> When PORT0 and PORT1 are used, user must select whether these ports
will be
> accessed via registers that provide enhanced features or a legacy set of
> registers (see
> Section 37 "Other system controls and status flags" on page 35).
While both
> of a port's
> fast and legacy GPIO registers are controlling the same physical
pins, these
> two port
> control branches are mutually exclusive and operate independently. For
> example,
> changing a pin's output via a fast register will not be observable
via the
> corresponding
> legacy register.
>
> --jc
>
> On Thu, Nov 6, 2008 at 9:08 AM, Ray Molenkamp wrote:
>
> > You have to enable fast io using the first bit in the SCS register.
> >
> > --Ray
> >
> >
> > h.belig wrote:
> > >
> > > Hello,
> > >
> > > the problem seems to be simple, nevertheless I could not solve it:
> > > I want to output a word to PORT 0.
> > > This is the initialisation:
> > >
> > > PINSEL0 = 0; // P0[15]..[0] as GPIO (default)
> > > PINMODE0 = 0; // with pull-up
> > > resistor (default)
> > >
> > > PINSEL1 = 0; // P0[31]..[16] as GPIO (default)
> > > PINMODE1 = 0; // with pull-up resistor (default)
> > >
> > > FIO0DIR = 0xffffffff; // P0[31]..[0] as output
> > > FIO0MASK = 0; // mask P0[31]..[0]
> > >
> > > and this is how I output the words:
> > > FIO0PIN = *pt++;
> > > FIO0PIN = *pt++;
> > > FIO0PIN = *pt++;
> > > ....
> > > There is no change on Port 0 pins, all of them are high.
> > > However, if port 2 is addressed instead, its ok.
> > > Port 1 also fails.
> > >
> > > My first idea was that it has something to do with the fact,
that port
> > > 0 and port 1 can run as slow (legacy) ports. But I did not find
a hint
> > > how to select the fast mode other than choosing the appropriate
> > > registers as shown above.
> > >
> > > The board I am using is EA's LPC2468 OEM board (without an OS).
> > > But when I used Keil's MCB2300 (LPC2378), outputting data to port 0
> > > wasn't possible either.
> > >
> > > I then went through the code step by step and monitored FIO0PIN
in the
> > > memory (EA board with LPC2468).
> > >
> > > With each
> > > FIO0PIN = *pt++,
> > > command the correct value of *pt++ has been written to memory.
> > > Not to FIO0PIN, but to FIO0SET!!!! That is the explanation why all
> > > pins of port0 remained constantly high.
> > >
> > > That looks like a hardware bug to me, providing I didn't miss
> > > something essential.
> > >
> > > Does anybody know whether there is a work-around?
> > > Using FIO0CLR and FIO0SET is not a solution because of performance
> > > reasons. Neither can I use ports 2..4.
> > >
> > > Henry
> > >
> > >
> >
> >
>
>
>
>


The 2024 Embedded Online Conference