[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