[En-Nut-Discussion] RFC: extra GPIO, new LED driver, new button driver
Ulrich Prinz
uprinz2 at netscape.net
Thu Jul 9 12:48:24 CEST 2009
Hi!
I request your comments to the following ideas:
1) Extra GPIOs
I designed in an IO-Port Expander based on an I2C PCA9555. I'd like to
integrate devices like this into the gpio system.
The idea behind is the following:
On a development platform I have LEDs and pushbuttons connected to a
PCA9555 device. On the target application all leds and buttons are
connected to the cpu directly. So in my application code I always have to
decide which way to go. Can this be made easier?
Options:
a)
I write XGpioPort... and xGpioPin... functions with same header like
standard functions and do an abstraction of the platform by #defines
Pro: Does not affect NutOS
Con: This only works for io access from the application.
b)
I extend ioexpander.* to provide XGPIO_PORT.. and XGPIO_PIN..
Then I extend standard GpioPort and GpioPin functions to recognize if an
internal or external port is addressed and it reroutes all action
accordingly.
Pro: Even device drivers can access external components without driver
rewrite or driver duplication in your own application.
Con: gpio is cpu specific and the driver extention has to be integrated per
cpu.
2) New LED driver
The first thing one does is to write a small thread for a blinking LED...
But I have 5 LEDs on the addon board and 4 LEDs on the SAM7X-EK. The driver
in NutOS provieds support for 4 LEDs only. To bad.
Looking into the LED driver code shows, that there someone started to do
something but declared it #if0 ... #endif.
So I started my own code right there but I treat a LED like a device.
Registering something to be an LED is NutRegisterLED( handle, port, pin);
Additionally void NutSetLed( HANDLE *ledh, uint8_t state) exists to switch
an LED on, off or just flip it's state.
An extention is planned like this: NutSetLed( HANDLE *ledh, int time,
uint8_t state)
time and state are connected to enable the following options:
time = 0, state = LED_ON/LED_OFF/LED_FLIP -> put the LED into the given
state immediately
time = n, state = LED_ON -> LED blinks with n milliseconds
time = n, state = LED_OFF -> LED lights up for n milliseconds, then goes
off again.
For me this is enough, but there may be the need for having separate on-
and off-time intervals for blinking.
So options are:
a)
Single routine NutSetLed( handle, ontime, offtime, state)
ontime != 0 && offtime != 0, state == LED_FLIP -> blinking
state == LED_ON, ontime/offtime ignored -> LED set to on
state == LED_OFF, times ignored -> LED set to off
Pro: you can almost set up anything with this and variables have a clear
functionality
Con: lots of variable handling slows down small cpus.
b)
single routine NutSetLed( handle, ontime, offtime)
ontime != 0, offtime != 0 -> LED blinking
ontime == -1, offtime ignored -> LED constantly on
ontime == 0, offtime ignored -> LED constantly off
Pro: by defining LED_ON -1 and LED_OFF 0 you can spare state
Con: Flipping a LED is not possible anymore or a third special value is to
be reserved from the ontime.
c)
two routines
NutSetLed( handle, state)
NutFlashLed( handle, ontime, offtime)
NutSetLed sets state imediately disabling blinking.
NutFlashLed sets led to blink immediately. An offtime of 0 will issue a
single flash of ontime duration.
Pro: blink handling could be made configurable and so excluded for small
systems.
Con: I don't know
Implementation until yet:
I use malloc to create the configuration for each LED in memory. The
configurations are chained by a pointer. A single thread or timer can be
used to control all LEDs.
3) New buttton driver
I plan a new button driver, that works like the LED driver:
NutRegisterButton( handle, port, pin, func*, type, duration)
The function pointer is type of: void mybutton( state)
Details:
the button is registered and connected to a port and pin. Nothing special.
func* is a pointer to a function that is called when the button event takes
place. Type and duration are somewhat special:
type can be KEY_PRESS or KEY_RELEASE that means, the function is called
when the butten had been pressed or after release of the button.
duration enables 'multi function' buttons. So pressing a button and
releasing it immediately can call another function than pressign a button
for 5 seconds. Remeber MP3 player >>| button: pressing short: jump next
track, pressing long: fast forward inside actual track.
This implies that one can register the same button for multiple functions
if he states different types and durations.
Pros and Cons are not clear at the moment.
** Please keep in mind, that all this LED an button extensions make only
sense if codesize versus functionality are obeyed. For me it makes only
sense, if there is a unified gpio handling available as stated in 1).
Best regards
Ulrich
More information about the En-Nut-Discussion
mailing list