/*                                             -*- mode:C++; fill-column:100 -*-
  SFBWiring.h - The 'Arduinoesque API' provided by the SFB.
  Copyright (C) 2008 The Regents of the University of New Mexico.  All rights reserved.

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this library; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
  USA

  $Id$
*/

/**
  \file SFBWiring.h SFB versions of the basic Arduino/Wiring functions
  \author David H. Ackley.  
  \date (C) 2008 All rights reserved.
  \lgpl
 */
#ifndef SFBWIRING_H
#define SFBWIRING_H

#include "SFBTypes.h"
#include "SFBConstants.h"
#include "SFBPins.h"

/**
  \ingroup basica

  Set a pin's value.  Also used to set the pullup (or pulldown) resistors on input pins.
 */
extern void digitalWrite(int sfbPin, int value);

/**
  \ingroup basica

  Read a pin's value.  
 */
extern int digitalRead(int sfbPin);

/**
  \ingroup basics

  Turn on one of the SFB built-in LEDs.
 */
inline void ledOn(int sfbPin) { digitalWrite(sfbPin,LOW); }

/**
  \ingroup basics
  Turn off one of the SFB built-in LEDs.
 */
inline void ledOff(int sfbPin) { digitalWrite(sfbPin,HIGH); }
/**
  \ingroup basics
  Turn on or off one of the SFB built-in LEDs.
 */
inline void ledSet(int sfbPin,bool on) { digitalWrite(sfbPin,on?LOW:HIGH); }

/**
  \ingroup basics
  Check if one of the SFB built-in LEDs is on or off.
  \returns \c true if the \a sfbPin is on, \c false otherwise
 */
inline bool ledIsOn(int sfbPin) { return digitalRead(sfbPin)==LOW; }

/**
  \ingroup basics
  Toggle one of the SFB built-in LEDs.
 */
void ledToggle(int sfbPin) ;

/**
  \ingroup basics
  Check if the SFB built-in button is currently down.
 Watch out!  This is not debounced!
 */
static inline bool buttonDown() { return digitalRead(BODY_SWITCH0_PIN)==LOW; }
extern bool buttonDown();

/**
  \ingroup basica
  Set a pin's function to input or output.  SFB extension: Set to 'reflex mode'.
 */
extern void pinMode(int sfbPin, int mode);

#ifdef HOST_MODE

/** 
The number of microseconds of uptime.  Rolls over after about 70 minutes. 
  \ingroup basica
*/
extern u32 micros();

/** The number of milliseconds of uptime.  Rolls over after about 49 days.  #millis() is much faster
    than #milliseconds(), but is not as accurate; #millis() may miss ticks due to interrupt load
  \ingroup basica
 */
extern u32 millis();

/** The number of microseconds of uptime.  Rolls over after about a half a million years.
    #microseconds() is quite fast, except for the overhead of dealing in \c u64 size, and its value
    is exact, unaffected by interrupt load.
  \ingroup basics
  */
extern u64 microseconds();

/** The number of milliseconds of uptime.  Rolls over after about 180 years. #milliseconds() is
    somewhat slow compared to #millis(), because it performs a non-power-of-2 division, but its
    value is exact, unaffected by interrupt load.
  \ingroup basics
 */
extern u32 milliseconds();

/** The number of seconds of uptime.  Rolls over after about 180 years. #seconds is somewhat slow
    (requires a division) but its value is exact, unaffected by interrupt load.
  \ingroup basics
 */
extern u32 seconds();

#else

#include "lpc/timer.h"

#endif

/** Delay for some number of microseconds.  
  \ingroup basica
 */
extern void delayMicroseconds(u32 usecondsToWait);

extern void delayMicrosecondsApproximate(u32 usecondsToWait);

/** Delay for some number of milliseconds
  \ingroup basica
 */
extern void delay(u32 millissecondToWait) ;

/** 
  \ingroup basica
 */
extern void shiftOut(int dataPin, int clockPin, int bitOrder, u8 val);

/** 
  \ingroup basica
 */
extern u32 pulseIn(int pin, int state, u32 timeoutUsec = 1000000);

#endif  /* SFBWIRING_H */
