bsptemplate/asspandvariant/template_assp/gpio.cpp
changeset 0 a41df078684a
child 90 947f0dc9f7a8
equal deleted inserted replaced
-1:000000000000 0:a41df078684a
       
     1 /*
       
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the License "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:
       
    15 *
       
    16 */
       
    17 #include <kernel/kern_priv.h>
       
    18 #include <template_assp.h>
       
    19 #include <drivers/gpio.h>
       
    20 
       
    21 const TInt32		KHwGpioPinMax		= 0;	// TO DO: max pin number this GPIO chip supports
       
    22 const TInt32		KIntIdGpio		= 0;	// TO DO: need to define which interrupt the GPIO chip is attached to
       
    23 
       
    24 //
       
    25 // TO DO: if the GPIO chip doesn't support specific features
       
    26 // such as debouncing or pin modes, then it may be
       
    27 // necessary to store them ourselves in an array of GpioPins
       
    28 // other features such as pin bias or idle configurations
       
    29 // may be left as KErrNotSupported
       
    30 //
       
    31 class GpioPin
       
    32 	{
       
    33 public:
       
    34    	TGpioIsr		iIsr;	// e.g. we may want to remeber the isr attached to a pin
       
    35 	TAny *			iPtr;	// argument to pass to isr
       
    36 	};
       
    37 
       
    38 static GpioPin	GpioPins[KHwGpioPinMax+1];
       
    39 
       
    40 static TInt32	GpioInterruptId; // place to store interrupt handle returned from Interrupt::Bind()
       
    41 
       
    42 /**
       
    43 GPIO interrupt handler
       
    44 generic argument (TAny*) is a pointer to the GpioPins array
       
    45 */
       
    46 void GpioIsrDispatch(TAny *aPtr)
       
    47 	{
       
    48 	// TO DO: work out which pins have interrupts pending
       
    49 	// and dispatch the appropriate ISR
       
    50 	GpioPin	*pins = (GpioPin *)aPtr;
       
    51 	TUint32 interrupt = 0xff; // TO DO: read gpio pending interupts
       
    52 	TUint32 enabled = 0x00; // TO DO: read gpio enabled interupts
       
    53 	TUint32	masked = interrupt & enabled; // TO DO: read masked interrupts
       
    54 
       
    55 	// check each pin and dispatch ISR if necessary
       
    56 	for (TInt i = 0; i <= KHwGpioPinMax; i++)
       
    57 		{
       
    58 		if ((masked & 0x1) && (pins[i].iIsr != NULL))
       
    59 			{
       
    60 			// we have a pending interrupt and a registered ISR
       
    61 			(*pins[i].iIsr)(pins[i].iPtr); // dispatch this pin's ISR
       
    62 			}
       
    63 		masked >>= 1;
       
    64 		}
       
    65 	Interrupt::Clear(GpioInterruptId);
       
    66 	}
       
    67 
       
    68 
       
    69 EXPORT_C TInt GPIO::SetPinMode
       
    70 	(
       
    71 	TInt      aId,
       
    72    	TGpioMode aMode
       
    73 	)
       
    74 	{
       
    75 	if (aId < 0 || aId > KHwGpioPinMax)
       
    76 		{
       
    77 		return KErrArgument;
       
    78 		}
       
    79 	// TO DO: store pin mode and return
       
    80 	return KErrNone;
       
    81 	}
       
    82 
       
    83 EXPORT_C TInt GPIO::GetPinMode
       
    84 	(
       
    85 	TInt        aId,
       
    86    	TGpioMode & aMode
       
    87 	)
       
    88 	{
       
    89 	if (aId < 0 || aId > KHwGpioPinMax)
       
    90 		{
       
    91 		return KErrArgument;
       
    92 		}
       
    93 	// TO DO: set aMode = pin mode
       
    94 	return KErrNone;
       
    95 	}
       
    96 
       
    97 EXPORT_C TInt GPIO::SetPinDirection
       
    98 	(
       
    99 	TInt           aId,
       
   100    	TGpioDirection aDirection
       
   101 	)
       
   102 	{
       
   103 	if (aId < 0 || aId > KHwGpioPinMax || aDirection == ETriStated)
       
   104 		{
       
   105 		return KErrArgument;
       
   106 		}
       
   107 	// TO DO: if we support setting the pin direction then do it here
       
   108 	return KErrNone;
       
   109 	}
       
   110 
       
   111 EXPORT_C TInt GPIO::GetPinDirection
       
   112 	(
       
   113 	TInt             aId,
       
   114    	TGpioDirection & aDirection
       
   115 	)
       
   116 	{
       
   117 	if (aId < 0 || aId > KHwGpioPinMax)
       
   118 		{
       
   119 		return KErrArgument;
       
   120 		}
       
   121 	// TO DO: if we support getting the pin direction then do it here
       
   122 	return KErrNone;
       
   123 	}
       
   124 
       
   125 EXPORT_C TInt GPIO::SetPinBias
       
   126 	(
       
   127 	TInt      aId,
       
   128    	TGpioBias aBias
       
   129 	)
       
   130 	{
       
   131 	if (aId < 0 || aId > KHwGpioPinMax)
       
   132 		{
       
   133 		return KErrArgument;
       
   134 		}
       
   135 	// TO DO: if we support setting the pin bias then do it here
       
   136 	return KErrNone;
       
   137 	}
       
   138 
       
   139 EXPORT_C TInt GPIO::GetPinBias
       
   140 	(
       
   141 	TInt        aId,
       
   142    	TGpioBias & aBias
       
   143 	)
       
   144 	{
       
   145 	if (aId < 0 || aId > KHwGpioPinMax)
       
   146 		{
       
   147 		return KErrArgument;
       
   148 		}
       
   149 	// TO DO: if we support getting the pin bias then do it here
       
   150 	return KErrNone;
       
   151 	}
       
   152 
       
   153 EXPORT_C TInt GPIO::SetPinIdleConfigurationAndState
       
   154 	(
       
   155 	TInt        aId,
       
   156    	TInt		/*aConf*/
       
   157 	)
       
   158 	{
       
   159 	if (aId < 0 || aId > KHwGpioPinMax)
       
   160 		{
       
   161 		return KErrArgument;
       
   162 		}
       
   163 	// TO DO: if we support setting the pin idle config then do it here
       
   164 	return KErrNone;
       
   165 	}
       
   166 
       
   167 EXPORT_C TInt GPIO::GetPinIdleConfigurationAndState
       
   168 	(
       
   169 	TInt        aId,
       
   170    	TInt	  & aBias
       
   171 	)
       
   172 	{
       
   173 	if (aId < 0 || aId > KHwGpioPinMax)
       
   174 		{
       
   175 		return KErrArgument;
       
   176 		}
       
   177 	// TO DO: if we support getting the pin idle config then do it here
       
   178 	return KErrNone;
       
   179 	}
       
   180 
       
   181 EXPORT_C TInt GPIO::BindInterrupt
       
   182 	(
       
   183 	TInt     aId,
       
   184    	TGpioIsr aIsr,
       
   185    	TAny *   aPtr
       
   186 	)
       
   187 	{
       
   188 	if (aId < 0 || aId > KHwGpioPinMax || aIsr == NULL)
       
   189 		{
       
   190 		return KErrArgument;
       
   191 		}
       
   192 	if (GpioPins[aId].iIsr != NULL)
       
   193 		{
       
   194 		// already bound
       
   195 		return KErrInUse;
       
   196 		}
       
   197 	// record isr and arg bound to this pin
       
   198 	GpioPins[aId].iIsr = aIsr;
       
   199 	GpioPins[aId].iPtr = aPtr;
       
   200 	return KErrNone;
       
   201 	}
       
   202 
       
   203 EXPORT_C TInt GPIO::UnbindInterrupt
       
   204 	(
       
   205 	TInt aId
       
   206 	)
       
   207 	{
       
   208 	if (aId < 0 || aId > KHwGpioPinMax)
       
   209 		{
       
   210 		return KErrArgument;
       
   211 		}
       
   212 	if (GpioPins[aId].iIsr == NULL)
       
   213 		{
       
   214 		// nothing bound
       
   215 		return KErrGeneral;
       
   216 		}
       
   217 	// NULL isr bound to this pin
       
   218 	GpioPins[aId].iIsr = NULL;
       
   219 	GpioPins[aId].iPtr = NULL;
       
   220 	return KErrNone;
       
   221 	}
       
   222 
       
   223 EXPORT_C TInt GPIO::EnableInterrupt
       
   224 	(
       
   225 	TInt aId
       
   226 	)
       
   227 	{
       
   228 	if (aId < 0 || aId > KHwGpioPinMax)
       
   229 		{
       
   230 		return KErrArgument;
       
   231 		}
       
   232 	if (GpioPins[aId].iIsr == NULL)
       
   233 		{
       
   234 		// nothing bound
       
   235 		return KErrGeneral;
       
   236 		}
       
   237 	// TODO: enable interrupts on this pin
       
   238 	return KErrNone;
       
   239 	}
       
   240 
       
   241 EXPORT_C TInt GPIO::DisableInterrupt
       
   242 	(
       
   243 	TInt aId
       
   244 	)
       
   245 	{
       
   246 	if (aId < 0 || aId > KHwGpioPinMax)
       
   247 		{
       
   248 		return KErrArgument;
       
   249 		}
       
   250 	if (GpioPins[aId].iIsr == NULL)
       
   251 		{
       
   252 		// nothing bound
       
   253 		return KErrGeneral;
       
   254 		}
       
   255 	// TODO: disable interrupts on this pin
       
   256 	return KErrNone;
       
   257 	}
       
   258 
       
   259 EXPORT_C TInt GPIO::IsInterruptEnabled
       
   260 	(
       
   261 	TInt    aId,
       
   262    	TBool & aEnable
       
   263 	)
       
   264 	{
       
   265 	if (aId < 0 || aId > KHwGpioPinMax)
       
   266 		{
       
   267 		return KErrArgument;
       
   268 		}
       
   269 	if (GpioPins[aId].iIsr == NULL)
       
   270 		{
       
   271 		// nothing bound
       
   272 		return KErrGeneral;
       
   273 		}
       
   274 	// TO DO: are interrupts enabled on this pin ?
       
   275 	return KErrNone;
       
   276 	}
       
   277 
       
   278 EXPORT_C TInt GPIO::ClearInterrupt
       
   279 	(
       
   280 	TInt aId
       
   281 	)
       
   282 	{
       
   283 	if (aId < 0 || aId > KHwGpioPinMax)
       
   284 		{
       
   285 		return KErrArgument;
       
   286 		}
       
   287 	if (GpioPins[aId].iIsr == NULL)
       
   288 		{
       
   289 		// nothing bound
       
   290 		return KErrGeneral;
       
   291 		}
       
   292 	// TO DO: clear pin interrupt status
       
   293 	return KErrNone;
       
   294 	}
       
   295 
       
   296 EXPORT_C TInt GPIO::GetMaskedInterruptState
       
   297 	(
       
   298 	TInt    aId,
       
   299    	TBool & aActive
       
   300 	)
       
   301 	{
       
   302 	if (aId < 0 || aId > KHwGpioPinMax)
       
   303 		{
       
   304 		return KErrArgument;
       
   305 		}
       
   306 	// TO DO: set aActive to masked interrupt state
       
   307 	return KErrNone;
       
   308 	}
       
   309 
       
   310 EXPORT_C TInt GPIO::GetRawInterruptState
       
   311 	(
       
   312 	TInt    aId,
       
   313    	TBool & aActive
       
   314 	)
       
   315 	{
       
   316 	if (aId < 0 || aId > KHwGpioPinMax)
       
   317 		{
       
   318 		return KErrArgument;
       
   319 		}
       
   320 	// TO DO: set aActive to raw (unmasked) interrupt state
       
   321 	return KErrNone;
       
   322 	}
       
   323 
       
   324 EXPORT_C TInt GPIO::SetInterruptTrigger
       
   325 	(
       
   326 	TInt                  aId,
       
   327    	TGpioDetectionTrigger aTrigger
       
   328 	)
       
   329 	{
       
   330 	if (aId < 0 || aId > KHwGpioPinMax)
       
   331 		{
       
   332 		return KErrArgument;
       
   333 		}
       
   334 	// TO DO: set interrupt trigger on this pin
       
   335 	return KErrNone;
       
   336 	}
       
   337 
       
   338 EXPORT_C TInt GPIO::EnableWakeup
       
   339 	(
       
   340 	TInt aId
       
   341 	)
       
   342 	{
       
   343 	if (aId < 0 || aId > KHwGpioPinMax)
       
   344 		{
       
   345 		return KErrArgument;
       
   346 		}
       
   347 	// TO DO: enable wakeup on this pin
       
   348 	return KErrNone;
       
   349 	}
       
   350 
       
   351 EXPORT_C TInt GPIO::DisableWakeup
       
   352 	(
       
   353 	TInt aId
       
   354 	)
       
   355 	{
       
   356 	if (aId < 0 || aId > KHwGpioPinMax)
       
   357 		{
       
   358 		return KErrArgument;
       
   359 		}
       
   360 	// TO DO: disable wakeup on this pin
       
   361 	return KErrNone;
       
   362 	}
       
   363 
       
   364 EXPORT_C TInt GPIO::IsWakeupEnabled
       
   365 	(
       
   366 	TInt    aId,
       
   367    	TBool & aEnable
       
   368 	)
       
   369 	{
       
   370 	if (aId < 0 || aId > KHwGpioPinMax)
       
   371 		{
       
   372 		return KErrArgument;
       
   373 		}
       
   374 	// TO DO: set aEnable wakeup state for this pin
       
   375 	return KErrNone;
       
   376 	}
       
   377 
       
   378 EXPORT_C TInt GPIO::SetWakeupTrigger
       
   379 	(
       
   380 	TInt                  aId,
       
   381    	TGpioDetectionTrigger aTrigger
       
   382 	)
       
   383 	{
       
   384 	if (aId < 0 || aId > KHwGpioPinMax)
       
   385 		{
       
   386 		return KErrArgument;
       
   387 		}
       
   388 	// TO DO: set wakeup trigger on this pin
       
   389 	return KErrNone;
       
   390 	}
       
   391 
       
   392 EXPORT_C TInt GPIO::SetDebounceTime
       
   393 	(
       
   394 	TInt aId,
       
   395    	TInt aTime
       
   396 	)
       
   397 	{
       
   398 	if (aId < 0 || aId > KHwGpioPinMax)
       
   399 		{
       
   400 		return KErrArgument;
       
   401 		}
       
   402 	// TO DO: set debounce time for this pin
       
   403 	// it may be necessary to emulate debouncing ourselves
       
   404 	return KErrNone;
       
   405 	}
       
   406 
       
   407 EXPORT_C TInt GPIO::GetDebounceTime
       
   408 	(
       
   409 	TInt   aId,
       
   410    	TInt & aTime
       
   411 	)
       
   412 	{
       
   413 	if (aId < 0 || aId > KHwGpioPinMax)
       
   414 		{
       
   415 		return KErrArgument;
       
   416 		}
       
   417 	// TO DO: get debounce time for this pin
       
   418 	return KErrNone;
       
   419 	}
       
   420 
       
   421 EXPORT_C TInt GPIO::GetInputState
       
   422 	(
       
   423 	TInt         aId,
       
   424    	TGpioState & aState
       
   425 	)
       
   426 	{
       
   427 	if (aId < 0 || aId > KHwGpioPinMax)
       
   428 		{
       
   429 		return KErrArgument;
       
   430 		}
       
   431 	// TO DO: read the input state of this pin
       
   432 	// if debouncing is handled by the driver here
       
   433 	// is where we will need to work out what the
       
   434 	// debounced state is
       
   435 
       
   436 	return KErrNone;
       
   437 	}
       
   438 
       
   439 EXPORT_C TInt GPIO::SetOutputState
       
   440 	(
       
   441 	TInt       aId,
       
   442    	TGpioState aState
       
   443 	)
       
   444 	{
       
   445 	if (aId < 0 || aId > KHwGpioPinMax)
       
   446 		{
       
   447 		return KErrArgument;
       
   448 		}
       
   449 	// TO DO: set the output state of this pin
       
   450 	return KErrNone;
       
   451 	}
       
   452 
       
   453 EXPORT_C TInt GPIO::GetOutputState
       
   454 	(
       
   455 	TInt         aId,
       
   456    	TGpioState & aState
       
   457 	)
       
   458 	{
       
   459 	if (aId < 0 || aId > KHwGpioPinMax)
       
   460 		{
       
   461 		return KErrArgument;
       
   462 		}
       
   463 	// TO DO: get the output state of this pin
       
   464 	return KErrNone;
       
   465 	}
       
   466 
       
   467 EXPORT_C TInt GPIO::GetInputState
       
   468 	(
       
   469 	TInt                  aId,
       
   470    	TGpioCallback		* aCb
       
   471 	)
       
   472 	{
       
   473 	if (aId < 0 || aId > KHwGpioPinMax)
       
   474 		{
       
   475 		return KErrArgument;
       
   476 		}
       
   477 	// TO DO: get the input state of this pin
       
   478 	return KErrNone;
       
   479 	}
       
   480 
       
   481 EXPORT_C TInt GPIO::SetOutputState
       
   482 	(
       
   483 	TInt                  aId,
       
   484 	TGpioState			  aState,
       
   485    	TGpioCallback		* aCb
       
   486 	)
       
   487 	{
       
   488 	if (aId < 0 || aId > KHwGpioPinMax)
       
   489 		{
       
   490 		return KErrArgument;
       
   491 		}
       
   492 	// TO DO: set the ouput state of this pin
       
   493 	return KErrNone;
       
   494 	}
       
   495 
       
   496 EXPORT_C TInt GPIO::StaticExtension
       
   497 	(
       
   498 	TInt	  aId,
       
   499 	TInt	  aCmd,
       
   500 	TAny	* aArg1,
       
   501 	TAny	* aArg2
       
   502 	)
       
   503 	{
       
   504 	if (aId < 0 || aId > KHwGpioPinMax)
       
   505 		{
       
   506 		return KErrArgument;
       
   507 		}
       
   508 	// TO DO: call the appropriate static extension if supported
       
   509 	return KErrNotSupported;
       
   510 	}
       
   511 
       
   512 
       
   513 //
       
   514 // entry point for GPIO setup
       
   515 //
       
   516 DECLARE_STANDARD_EXTENSION()
       
   517 	{
       
   518 
       
   519 	// initialise GPIO pins array (if necessary)
       
   520 	for (TInt32 i = 0; i <= KHwGpioPinMax; i++)
       
   521 		{
       
   522 		GpioPins[i].iIsr = NULL;
       
   523 		GpioPins[i].iPtr = NULL;
       
   524 		}
       
   525 	// bind and enable GPIO Isr
       
   526 	// NB Interrupt::Bind() now returns a handle (-ve value means an error)
       
   527 	TInt r = Interrupt::Bind(KIntIdGpio, GpioIsrDispatch, &GpioPins[0]);
       
   528 	if (r < 0)
       
   529 		{
       
   530 		return r;
       
   531 		}
       
   532 	// store handle
       
   533 	GpioInterruptId = r;
       
   534 	// NB Interrupt::Enable() now expects the handle return from Bind
       
   535 	r = Interrupt::Enable(r);
       
   536 	return r;
       
   537 	}