bsptemplate/asspandvariant/template_assp/gpio.cpp
changeset 0 a41df078684a
child 90 947f0dc9f7a8
--- /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 <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;
+	}