//-----------------------------------------
// define target processor and resources
//-----------------------------------------

#include <16F877.h>
#device ADC=8
#device *=16
//#device ICD=FALSE
#use delay(clock=20000000)
#use rs232(baud=38400,parity=n,bits=8,xmit=PIN_C6,rcv=PIN_C7)
#fuses HS,NOWDT,PUT,NOLVP,NOBROWNOUT
#use I2C(master, sda=PIN_C4, scl=PIN_C3, FORCE_HW)


//-----------------------------------------
// define software structures and constants
//-----------------------------------------

typedef    unsigned char  UINT8;
typedef    unsigned long UINT16;
typedef    unsigned int32  UINT32;

//
// commands
//
#define     SYNC_CMD             '.'
#define     NAME_CMD             'N'
#define     CONSTANT_CMD         'F'
#define     COAST_CMD            'C'
#define     RESET_CMD            'R'
#define     GET_STATUS_CMD       'S'
#define     ECHO_CMD             'E'
#define     VELOCITY_CMD         'V'
#define     ANGLE_CMD            'W'
#define     DISTANCE_CMD         'D'
#define     TIME_CMD             'T'
#define     MOTOR_CMD            'M'
#define     PERIOD_CMD           'P'

//
// error codes
//
#define     OK                         1
#define     ERROR                    128
#define     SYNC_FAIL            ERROR+1
#define     GET_CONSTANT_FAIL    ERROR+2
#define     SET_CONSTANT_FAIL    ERROR+3
#define     COAST_FAIL           ERROR+5
#define     RESET_FAIL           ERROR+6
#define     ECHO_FAIL            ERROR+7
#define     GET_STATUS_FAIL      ERROR+8
#define     GET_VELOCITY_FAIL    ERROR+11
#define     GET_ANGLE_FAIL       ERROR+14
#define     GET_DISTANCE_FAIL    ERROR+16
#define     GET_TIME_FAIL        ERROR+17
#define     GET_PULSEWIDTH_FAIL  ERROR+18
#define     SET_PULSEWIDTH_FAIL  ERROR+19
#define     GET_PERIOD_FAIL      ERROR+20
#define     GET_NAME_FAIL        ERROR+21

//
// UC_command holds the details of a full I2C command and the returned data.
//
struct
{
    UINT8 cmd[6];                                                                                  // command byte list
    int   send_count;                                                                              // number of bytes to be sent
    UINT8 reply[6];                                                                                // list of byte values received
    int   get_count;                                                                               // number of bytes to be read
    UINT8 delay;                                                                                   // delay in mS between command write and data read
    UINT8 status;                                                                                  // error code or OK
} UC_command;


// constants
#define CONTROL_LOOP_COUNT 200                             // number of timer2 overflows per control loop period (200 = 24.4Hz, because overflows at 4883 Hz)
#define ME210_ID           0x30
#define MODE_STOP_START    0x0F
#define MODE_RESTART       0xF0


//-----------------------------------------
// define hardware
//-----------------------------------------
#define ENC_CLK    PIN_A4                                // I/O 1, TOCKI
#define ENC_DIR    PIN_B3                                // decoded direction

#use fast_io(A)
#use fast_io(B)
#use fast_io(C)
#use fast_io(D)
#use fast_io(E)

#define TRIS_A_VAL 0x1B                                    // 1 = input; A2 and A5 are outputs
#define TRIS_B_VAL 0xFF
#define TRIS_C_VAL 0xFF
#define TRIS_D_VAL 0xFF
#define TRIS_E_VAL 0xFF


// function prototypes
UINT16 init_unicoder();
void do_sync(void);
UINT16 do_get_name(char *buf);
void do_set_constant(UINT8 const_address, UINT8 new_value);
UINT8 do_get_constant(UINT8 const_address);
UINT16 do_get_status(void);
void do_coast(void);
void do_reset(void);
void do_echo(void);
void exec_command(UINT8 mode);
INT16 do_get_velocity(void);
INT32 do_get_period(void);
INT16 do_get_angle(void);
INT32 do_get_time(void);
INT16 do_get_pulsewidth(void);
void do_set_pulsewidth(INT16 pw);




