/* SCHint.h - Internal defines for Arduino hobby servo library.
   wanked by schip from Version 2 in Arduino 1.0.4
  Copyright (c) 2009 Michael Margolis.  All right reserved.
*/

#ifndef SCHint_h
#define SCHint_h

#include "SCHervo.h"	// get external defines

/** Define which and how many 16 bit timers can be used and in what order on what chips
 * Defines for 16 bit timers used with SCHervo library
 *
 * If _useTimerX is defined then TimerX is a 16 bit timer
 *  on the current board timer16_Sequence_t enumerates the sequence
 *  that the timers should be allocated
 *
 * _Nbr_16timers indicates how many 16 bit timers are available.
**/
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
#define _useTimer5
#define _useTimer1
#define _useTimer3
#define _useTimer4
typedef enum {
	_timer5, _timer1, _timer3, _timer4, _Nbr_16timers } timer16_Sequence_t ;

#elif defined(__AVR_ATmega32U4__)
#define _useTimer1
typedef enum { _timer1, _Nbr_16timers } timer16_Sequence_t ;

#elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
#define _useTimer3
#define _useTimer1
typedef enum { _timer3, _timer1, _Nbr_16timers } timer16_Sequence_t ;

#elif defined(__AVR_ATmega128__) ||defined(__AVR_ATmega1281__)||defined(__AVR_ATmega2561__)
#define _useTimer3
#define _useTimer1
typedef enum { _timer3, _timer1, _Nbr_16timers } timer16_Sequence_t ;

#else  // everything else
#define _useTimer1
typedef enum { _timer1, _Nbr_16timers } timer16_Sequence_t ;
#endif

// keep track of the actual output pin and state
typedef struct
{
  uint8_t nbr        :6 ;   // Arduino output pin number from 0 to 63
  uint8_t isActive   :1 ;   // true if this channel is enabled,
  							//  pin is not pulsed if false
} ServoPin_t;

// Keep track of each device and output pulse period
//  not in SCHervo class because accessed by interrupt and ServoUpdateTask
typedef struct
{
  SCHervo *myinstance;		// the SCHervo object for this pin
  ServoPin_t Pin;			// Arduino pin of interest
  unsigned int ticks;		// current Pulse ON microsec ticks
} servo_t;

// NOTE: 12 is prolly wrong, shdbe=8, even that is pushing it at 2700uS/servo max
#define SERVOS_PER_TIMER        8     // the max number of servos on one timer
#define MAX_SERVOS   (_Nbr_16timers  * SERVOS_PER_TIMER)

// master index of servo stuff, used by interrupt and Task functions
extern servo_t servos[MAX_SERVOS];
// the total number of attached servos, number of initialized elements in servos[]
extern uint8_t ServoCount;
// the task run at every servo update period
extern void ServoUpdateTask( uint16_t nada );

// utility macro to get element of servos array by servo index
#define SERVOP(sidx) (servos+sidx)

// servoMove struct state values
#define SS_START	0x00		// initial state
#define SS_RUN		0x01		// moving to new position still (not READY)
#define SS_ENDOFF	0x02		// turn-off motor when move complete

// 20ms per step update is the fastest we can go
//  because of the way the hobby servos are clocked
// and most servos can move about 6deg in that 20ms period or about 60deg in 200ms
#define REFRESHPERIOD	(REFRESH_INTERVAL / 1000)	// micro to milli seconds
#define DEGperREFRESH	 5	// max degrees in a 20ms refresh interval (rounded down)

#endif // SCHint_h
