SuperPRO port configuration and control

basically miscellaneous, if it doesn't fit another sub-forum enter it here, we might even promote it to its own sub-forum
Post Reply
YahooArchive
Posts: 1462
Joined: Fri Oct 19, 2012 5:11 am

SuperPRO port configuration and control

Post by YahooArchive »

I am excited to learn the operation of the SuperPRO (new to microcontroller
programming). I could really use some help figuring out how to program ports
and pins with the SuperPRO. These statements were copied from the ARMbasic Help
files and the LED does blink (docs say the LED is Port 0 pin 15?), but don't
understand why it works, or rather, what exactly is happening with these two
statements, and what Port/pin is it really being affecting. There is nothing in
the following two statements I frankly relate to:

#define OUTPUT2(pin) FIO2DIR = FIO2DIR or (1 << pin)
OUTPUT2(10)

Thanks for any light you could shed.

Keith Wilde


'The simplified sample file from ARMbasic
#include
#define OUTPUT2(pin) FIO2DIR = FIO2DIR or (1 << pin)
OUTPUT2(10)
while 1
x=x+1
P2(10) = (x and 1) ' blinky for the SuperPRO and PROplus
wait(500)
loop



YahooArchive
Posts: 1462
Joined: Fri Oct 19, 2012 5:11 am

Re: SuperPRO port configuration and control

Post by YahooArchive »

> I am excited to learn the operation of the SuperPRO (new to microcontroller
programming). I could really use some help figuring out how to program ports
and pins with the SuperPRO. These statements were copied from the ARMbasic Help
files and the LED does blink (docs say the LED is Port 0 pin 15?),

Where do they say P0(15)? At the very least, P2(10) is an alternate.


> but don't understand why it works, or rather, what exactly is happening with
these two statements, and what Port/pin is it really being affecting. There is
nothing in the following two statements I frankly relate to:
>
> #define OUTPUT2(pin) FIO2DIR = FIO2DIR or (1 << pin)

The line above is a C-style macro, that's expanded in the source by a
pre-compiler...

> OUTPUT2(10)

... ergo, the statement above is expanded prior to compilation, to this:

FIO2DIR = FIO2DIR or (1 << 10)

The expression (1 << 10) bitwise left-shifts the value 1 by 10 positions; it
therefore evaluates to 0x400, aka 1024.

FIO2DIR is a register that's used to configure the pins in port 2; for a pin to
be an output you must set it's corresponding bit in this register. To make
P2(10) an output it could merely assign FIO2DIR = 1024, but that would
side-affect the rest of the port 2 pins, so instead it OR's [the value of only
bit 10 set, all other bits clear] to the current value of FIO2DIR.

The OUTPUT#(pin) macros were apparently added for consistency with the older
OUTPUT(pin) macro... so why not sets of IN#(p) and OUT#(p) macros to go with
them? Couldn't tell you, I'm just a user... my guess is that:

#define IN2(pin) P2(pin)

...looked ridiculous, so they just gave it a miss. :-)

Does that clear things up any?


-MM

YahooArchive
Posts: 1462
Joined: Fri Oct 19, 2012 5:11 am

Re: SuperPRO port configuration and control

Post by YahooArchive »

Great explanation on the use of macros in BASIC

>
> #define IN2(pin) P2(pin)
>
> ...looked ridiculous, so they just gave it a miss. :-)
>

IN comes from the original ARMexpress, where compatibility with PBASIC was
important. A macro for IN2 could be done, and could always be added by the user,
we chose to follow the NXP naming conventions going forward. P0(x) through
P5(x) are recognized by the compiler and compiled inline as the original IN was.

While INx can be done with macros, that is a bit harder with OUTx as it would
have to take the form of

OUTx(pin,value) ' much more like the Arduino style

rather than OUTx(pin) = value

Why do somethings in the compiler? vs the macros? The line can be arbitrary,
but the thinking is if it can easily be done with a macro, do it that way.
That's why OUTPUTx and INPUTx are in macros, but P0-P5 are not.

YahooArchive
Posts: 1462
Joined: Fri Oct 19, 2012 5:11 am

Re: SuperPRO port configuration and control

Post by YahooArchive »

Mark, your explanations of the code helped a lot! I was trying to program the
ports using base 10 mentality. By the way, P2(10) is the LED on the board (I
have looked through so many docs, I mixed up a reference on a table for a
different module). I got the ports working now as expected. Thanks for your
reply.


Keith Wilde

YahooArchive
Posts: 1462
Joined: Fri Oct 19, 2012 5:11 am

Re: SuperPRO port configuration and control

Post by YahooArchive »

What you have to understand is the the microcontroller uses memory mapped I/O to
set registers.

In other words there are switches connected to what would otherwise be a byte in
memory. Each bit of that byte (actually several bytes in this case) is a switch
that tells the microcontroller to do something.

In this case, FIO2DIR is the register (or set of switches) that tells the
controller which way the inputs/outputs go for the pins in the P2 group.

FIO2DIR is defined in the header files. Those files are in the install
directory in the "lib/BASIClib/LPC17xx.bas" file if you want to look at them.

The Super Pro uses an LPC1756 microcontroller chip, so you use the LPC17xx.bas
library. If you had one of the boards with the LPC2138 or LPC2103 chips in it,
you use the LPC21xx.bas library file because those chips have different
addresses for the various switches.

It assigns the label "FIO2DIR" to a hexadecimal address where the switches are
located: #define FIO2DIR *(FIO_BASE_ADDR + &H40)

FIO_BASE_ADDR is defined above that as:
#define FIO_BASE_ADDR &H2009C000

so this would actually be: #define FIO2DIR *(&H2009C000 + &H40) which is the
address of the beginning of the set of registers (or memory locations) where all
the "Fast I/O" stuff, called FIO, is located.

OUTPUT2(10) is a lot easier to read than:

*(&H2009C000 + &H40) = *(&H2009C000 + &H40) or (1<<10)

The "*" indicates it's a memory address. The &H indicates the address is in
hexadeciml rather than binary or decimal.


The "<<" is a bit shift operation. In this case they are shifting the bit "pin"
number of spaces to the left.

The OUTPUT2(10) is just an easier way of saying FIO2DIR = FIO2DIR or (1 << 10)

That lets you write "OUTPUT2(10)" to set pin 2.10 to an output rather than an
input.

Bit 10 controls the direction of pin P2.10, bit 9 controls the direction of
P2.9, etc.

A preprocessor reads through the program and replaces the shorthand
"OUTPUT2(10)" with "FIO2DIR = FIO2DIR or (1 << 10)" before the program runs.
Then it replaces FIO2DIR with *(&H2009C000 + &H40)

The reason they are using the "or" in "FIO2DIR = FIO2DIR or (1 << 10)" is so you
don't mess up the other pins by changing bit 10.

The shift (<<) moves the one over 10 bits and the "or" does a bitwise or, which
tuns on any bits that are already 1 in FIO2DIR or the 10th bit, which has the
effect of changing the 10th bit and leaving the others alone.

If you used FIO2DIR = (1 << 10) it would turn off all bits except 10 and screw
up the I/O directions of all the other P2.x pins.

In the libraries that get included in your program, there are direction
definitions (addresses) for all of the pin groups on the controller (P1.x, P2.x,
etc).

There are also registers that control the setup for the analog pins, pulse width
modulation, timers, time of day clock, etc., etc.

All the control settings of the microcontroller handled this way.

The Coridium folks have written these libraries so you don't need to go through
the LPC1756 manual to find these addresses.

They did it for you.

Sometimes there are chip functions that they didn't include in the libraries, so
you have to go find them yourself.

Most of the stuff used every day is done, though.

If you do end up having to "roll your own" look at their libraries and write you
own library that you include in your programs. They way you only have to look
it up once. Then you hive it a name using #define that's easy to remember and
easy to read.

Rick

Post Reply