Fix for bug 2283 (RVCT 4.0 support is missing from PDK 3.0.h)
Have multiple extension sections in the bld.inf, one for each version
of the compiler. The RVCT version building the tools will build the
runtime libraries for its version, but make sure we extract all the other
versions from zip archives. Also add the archive for RVCT4.
/*
* 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 <kernel/kern_priv.h>
#include <template_assp.h>
#include <drivers/gpio.h>
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;
}