diff -r 000000000000 -r a41df078684a bsptemplate/asspandvariant/template_assp/gpio.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/bsptemplate/asspandvariant/template_assp/gpio.cpp Mon Oct 19 15:55:17 2009 +0100 @@ -0,0 +1,537 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ +#include +#include +#include + +const TInt32 KHwGpioPinMax = 0; // TO DO: max pin number this GPIO chip supports +const TInt32 KIntIdGpio = 0; // TO DO: need to define which interrupt the GPIO chip is attached to + +// +// TO DO: if the GPIO chip doesn't support specific features +// such as debouncing or pin modes, then it may be +// necessary to store them ourselves in an array of GpioPins +// other features such as pin bias or idle configurations +// may be left as KErrNotSupported +// +class GpioPin + { +public: + TGpioIsr iIsr; // e.g. we may want to remeber the isr attached to a pin + TAny * iPtr; // argument to pass to isr + }; + +static GpioPin GpioPins[KHwGpioPinMax+1]; + +static TInt32 GpioInterruptId; // place to store interrupt handle returned from Interrupt::Bind() + +/** +GPIO interrupt handler +generic argument (TAny*) is a pointer to the GpioPins array +*/ +void GpioIsrDispatch(TAny *aPtr) + { + // TO DO: work out which pins have interrupts pending + // and dispatch the appropriate ISR + GpioPin *pins = (GpioPin *)aPtr; + TUint32 interrupt = 0xff; // TO DO: read gpio pending interupts + TUint32 enabled = 0x00; // TO DO: read gpio enabled interupts + TUint32 masked = interrupt & enabled; // TO DO: read masked interrupts + + // check each pin and dispatch ISR if necessary + for (TInt i = 0; i <= KHwGpioPinMax; i++) + { + if ((masked & 0x1) && (pins[i].iIsr != NULL)) + { + // we have a pending interrupt and a registered ISR + (*pins[i].iIsr)(pins[i].iPtr); // dispatch this pin's ISR + } + masked >>= 1; + } + Interrupt::Clear(GpioInterruptId); + } + + +EXPORT_C TInt GPIO::SetPinMode + ( + TInt aId, + TGpioMode aMode + ) + { + if (aId < 0 || aId > KHwGpioPinMax) + { + return KErrArgument; + } + // TO DO: store pin mode and return + return KErrNone; + } + +EXPORT_C TInt GPIO::GetPinMode + ( + TInt aId, + TGpioMode & aMode + ) + { + if (aId < 0 || aId > KHwGpioPinMax) + { + return KErrArgument; + } + // TO DO: set aMode = pin mode + return KErrNone; + } + +EXPORT_C TInt GPIO::SetPinDirection + ( + TInt aId, + TGpioDirection aDirection + ) + { + if (aId < 0 || aId > KHwGpioPinMax || aDirection == ETriStated) + { + return KErrArgument; + } + // TO DO: if we support setting the pin direction then do it here + return KErrNone; + } + +EXPORT_C TInt GPIO::GetPinDirection + ( + TInt aId, + TGpioDirection & aDirection + ) + { + if (aId < 0 || aId > KHwGpioPinMax) + { + return KErrArgument; + } + // TO DO: if we support getting the pin direction then do it here + return KErrNone; + } + +EXPORT_C TInt GPIO::SetPinBias + ( + TInt aId, + TGpioBias aBias + ) + { + if (aId < 0 || aId > KHwGpioPinMax) + { + return KErrArgument; + } + // TO DO: if we support setting the pin bias then do it here + return KErrNone; + } + +EXPORT_C TInt GPIO::GetPinBias + ( + TInt aId, + TGpioBias & aBias + ) + { + if (aId < 0 || aId > KHwGpioPinMax) + { + return KErrArgument; + } + // TO DO: if we support getting the pin bias then do it here + return KErrNone; + } + +EXPORT_C TInt GPIO::SetPinIdleConfigurationAndState + ( + TInt aId, + TInt /*aConf*/ + ) + { + if (aId < 0 || aId > KHwGpioPinMax) + { + return KErrArgument; + } + // TO DO: if we support setting the pin idle config then do it here + return KErrNone; + } + +EXPORT_C TInt GPIO::GetPinIdleConfigurationAndState + ( + TInt aId, + TInt & aBias + ) + { + if (aId < 0 || aId > KHwGpioPinMax) + { + return KErrArgument; + } + // TO DO: if we support getting the pin idle config then do it here + return KErrNone; + } + +EXPORT_C TInt GPIO::BindInterrupt + ( + TInt aId, + TGpioIsr aIsr, + TAny * aPtr + ) + { + if (aId < 0 || aId > KHwGpioPinMax || aIsr == NULL) + { + return KErrArgument; + } + if (GpioPins[aId].iIsr != NULL) + { + // already bound + return KErrInUse; + } + // record isr and arg bound to this pin + GpioPins[aId].iIsr = aIsr; + GpioPins[aId].iPtr = aPtr; + return KErrNone; + } + +EXPORT_C TInt GPIO::UnbindInterrupt + ( + TInt aId + ) + { + if (aId < 0 || aId > KHwGpioPinMax) + { + return KErrArgument; + } + if (GpioPins[aId].iIsr == NULL) + { + // nothing bound + return KErrGeneral; + } + // NULL isr bound to this pin + GpioPins[aId].iIsr = NULL; + GpioPins[aId].iPtr = NULL; + return KErrNone; + } + +EXPORT_C TInt GPIO::EnableInterrupt + ( + TInt aId + ) + { + if (aId < 0 || aId > KHwGpioPinMax) + { + return KErrArgument; + } + if (GpioPins[aId].iIsr == NULL) + { + // nothing bound + return KErrGeneral; + } + // TODO: enable interrupts on this pin + return KErrNone; + } + +EXPORT_C TInt GPIO::DisableInterrupt + ( + TInt aId + ) + { + if (aId < 0 || aId > KHwGpioPinMax) + { + return KErrArgument; + } + if (GpioPins[aId].iIsr == NULL) + { + // nothing bound + return KErrGeneral; + } + // TODO: disable interrupts on this pin + return KErrNone; + } + +EXPORT_C TInt GPIO::IsInterruptEnabled + ( + TInt aId, + TBool & aEnable + ) + { + if (aId < 0 || aId > KHwGpioPinMax) + { + return KErrArgument; + } + if (GpioPins[aId].iIsr == NULL) + { + // nothing bound + return KErrGeneral; + } + // TO DO: are interrupts enabled on this pin ? + return KErrNone; + } + +EXPORT_C TInt GPIO::ClearInterrupt + ( + TInt aId + ) + { + if (aId < 0 || aId > KHwGpioPinMax) + { + return KErrArgument; + } + if (GpioPins[aId].iIsr == NULL) + { + // nothing bound + return KErrGeneral; + } + // TO DO: clear pin interrupt status + return KErrNone; + } + +EXPORT_C TInt GPIO::GetMaskedInterruptState + ( + TInt aId, + TBool & aActive + ) + { + if (aId < 0 || aId > KHwGpioPinMax) + { + return KErrArgument; + } + // TO DO: set aActive to masked interrupt state + return KErrNone; + } + +EXPORT_C TInt GPIO::GetRawInterruptState + ( + TInt aId, + TBool & aActive + ) + { + if (aId < 0 || aId > KHwGpioPinMax) + { + return KErrArgument; + } + // TO DO: set aActive to raw (unmasked) interrupt state + return KErrNone; + } + +EXPORT_C TInt GPIO::SetInterruptTrigger + ( + TInt aId, + TGpioDetectionTrigger aTrigger + ) + { + if (aId < 0 || aId > KHwGpioPinMax) + { + return KErrArgument; + } + // TO DO: set interrupt trigger on this pin + return KErrNone; + } + +EXPORT_C TInt GPIO::EnableWakeup + ( + TInt aId + ) + { + if (aId < 0 || aId > KHwGpioPinMax) + { + return KErrArgument; + } + // TO DO: enable wakeup on this pin + return KErrNone; + } + +EXPORT_C TInt GPIO::DisableWakeup + ( + TInt aId + ) + { + if (aId < 0 || aId > KHwGpioPinMax) + { + return KErrArgument; + } + // TO DO: disable wakeup on this pin + return KErrNone; + } + +EXPORT_C TInt GPIO::IsWakeupEnabled + ( + TInt aId, + TBool & aEnable + ) + { + if (aId < 0 || aId > KHwGpioPinMax) + { + return KErrArgument; + } + // TO DO: set aEnable wakeup state for this pin + return KErrNone; + } + +EXPORT_C TInt GPIO::SetWakeupTrigger + ( + TInt aId, + TGpioDetectionTrigger aTrigger + ) + { + if (aId < 0 || aId > KHwGpioPinMax) + { + return KErrArgument; + } + // TO DO: set wakeup trigger on this pin + return KErrNone; + } + +EXPORT_C TInt GPIO::SetDebounceTime + ( + TInt aId, + TInt aTime + ) + { + if (aId < 0 || aId > KHwGpioPinMax) + { + return KErrArgument; + } + // TO DO: set debounce time for this pin + // it may be necessary to emulate debouncing ourselves + return KErrNone; + } + +EXPORT_C TInt GPIO::GetDebounceTime + ( + TInt aId, + TInt & aTime + ) + { + if (aId < 0 || aId > KHwGpioPinMax) + { + return KErrArgument; + } + // TO DO: get debounce time for this pin + return KErrNone; + } + +EXPORT_C TInt GPIO::GetInputState + ( + TInt aId, + TGpioState & aState + ) + { + if (aId < 0 || aId > KHwGpioPinMax) + { + return KErrArgument; + } + // TO DO: read the input state of this pin + // if debouncing is handled by the driver here + // is where we will need to work out what the + // debounced state is + + return KErrNone; + } + +EXPORT_C TInt GPIO::SetOutputState + ( + TInt aId, + TGpioState aState + ) + { + if (aId < 0 || aId > KHwGpioPinMax) + { + return KErrArgument; + } + // TO DO: set the output state of this pin + return KErrNone; + } + +EXPORT_C TInt GPIO::GetOutputState + ( + TInt aId, + TGpioState & aState + ) + { + if (aId < 0 || aId > KHwGpioPinMax) + { + return KErrArgument; + } + // TO DO: get the output state of this pin + return KErrNone; + } + +EXPORT_C TInt GPIO::GetInputState + ( + TInt aId, + TGpioCallback * aCb + ) + { + if (aId < 0 || aId > KHwGpioPinMax) + { + return KErrArgument; + } + // TO DO: get the input state of this pin + return KErrNone; + } + +EXPORT_C TInt GPIO::SetOutputState + ( + TInt aId, + TGpioState aState, + TGpioCallback * aCb + ) + { + if (aId < 0 || aId > KHwGpioPinMax) + { + return KErrArgument; + } + // TO DO: set the ouput state of this pin + return KErrNone; + } + +EXPORT_C TInt GPIO::StaticExtension + ( + TInt aId, + TInt aCmd, + TAny * aArg1, + TAny * aArg2 + ) + { + if (aId < 0 || aId > KHwGpioPinMax) + { + return KErrArgument; + } + // TO DO: call the appropriate static extension if supported + return KErrNotSupported; + } + + +// +// entry point for GPIO setup +// +DECLARE_STANDARD_EXTENSION() + { + + // initialise GPIO pins array (if necessary) + for (TInt32 i = 0; i <= KHwGpioPinMax; i++) + { + GpioPins[i].iIsr = NULL; + GpioPins[i].iPtr = NULL; + } + // bind and enable GPIO Isr + // NB Interrupt::Bind() now returns a handle (-ve value means an error) + TInt r = Interrupt::Bind(KIntIdGpio, GpioIsrDispatch, &GpioPins[0]); + if (r < 0) + { + return r; + } + // store handle + GpioInterruptId = r; + // NB Interrupt::Enable() now expects the handle return from Bind + r = Interrupt::Enable(r); + return r; + }