'****************************************************************
'* Author : Amit Pitaru, John Schimmel, Wlodek Koss *
'* Date : 4/28/2006 *
'* Version : 1.0 *
'* : Ramps mouse version with clicks *
'****************************************************************

'******************* need these lines to use Bootloader ************************
'********* if not using bootloader don't use - start with osc speed ************
DEFINE LOADER_USED 1
DEFINE RESET_ORG 800h ' For Microchip USB Bootloader
DEFINE INTERRUPT_ORG 808h ' For Microchip USB Bootmber of bits in result

'************************ set clock speed **************************************
Define OSC 48 'actual osc is 20 mghz

'********************* Define ADCIN parameters *********************************
Define ADC_BITS 10 ' Set number of bits in result
Define ADC_CLOCK 3 ' Set clock source (3=rc)
Define ADC_SAMPLEUS 50 ' Set sampling time in uS

'************************** set registers **************************************
TRISA = %00101000 ' Set PORTA input & output
'ADCON0 = %00000001
ADCON1 = %00000001 'set PortA anolog
ADCON2.7 = 1 'right justify

'******************** encoder/fsr input pins ***********************************
encoder1 var PORTD.3
encoder2 var portD.0
dir1 var portD.2 'only two states - high or low
dir2 var portD.1 'only two states - high or low

'************************ set port directiion **********************************
trisD.0 = 1
trisD.1 = 1
trisD.2 = 1
trisD.3 = 1

'***************************** variables ***************************************
buffer var byte[4] ' incoming string
encoderCnt var word[2] : encoderCnt[0] = 0 : encoderCnt[1] = 0
dir var bit [2]
fsr1 var word
fsr2 var word
fsr1Init var word
fsr2Init Var WORD
fsr1State var bit : fsr1State = 0
fsr2State var bit : fsr2State = 0
fsr1thresh Var word : fsr1thresh = 20 '(left click)
fsr2thresh Var word : fsr2thresh = 35 '(right click)
fsrGap var word : fsrGap = 0
i var word
k var byte
pause 3000
USBInit

'*********************** initialize buffer *************************************
buffer[0] = 0 ' mouse clicks
buffer[1] = 0 ' x direction positive is right, negative is left
buffer[2] = 0 ' y direction positive is down, negative is up
buffer[3] = 0 ' Device specific (optional)

'******************* calibrate fsr's at startup '*******************************
adcin 3, fsr1
adcin 4, fsr2
fsr1Init = fsr1
fsr2Init = fsr2

'************************** main loop ******************************************
main:

   USBService	' Must service USB regularly
gosub encoderspeed
gosub readfsr
gosub cursor_direc_speed
gosub mouseclick
goto main

'******************** how fast are encoders moving? ****************************
encoderspeed:
for k = 0 to 1 step 1
USBService
count encoder2, 6, encoderCnt[k]

           if k = 0 then
count encoder1, 6, encoderCnt[k]
else
dir[0] = dir1
dir[1] = dir2
endif
next k
return

'************************ read fsr info ****************************************
readfsr
adcin 3, fsr1
adcin 4, fsr2
return

'************** calculate spead and direction of cursor ************************
'***** based on how fast encoders are moving and state of direction pins *******
cursor_direc_speed:
if encoderCnt[0] > 0 and encoderCnt[1] > 0 then
if dir[0] = dir[1] then
' horizontal movement since encoders are mirrored
buffer[2] = 0
buffer[1] = (encoderCnt[0] + encoderCnt[1])*(-1 + dir[0]*2 )

            else
' vertical movement since encoders are mirrored
buffer[1] = 0
buffer[2] = (encoderCnt[1] + encoderCnt[0]) *(1 - dir[0]*2)
endif
encoderCnt[k] = 0
goSub sendUSB
else
if encoderCnt[0] > 0 then
buffer[1] = encoderCnt[0] *(-1 + dir[0]*2)
buffer[2] = encoderCnt[0] *(1 - dir[0]*2)\\ endif
if encoderCnt[1] > 0 then
buffer[1] = encoderCnt[1] *(-1 + dir[1]*2)
buffer[2] = encoderCnt[1] *(-1 + dir[1]*2)\\ endif
encoderCnt[k] = 0
goSub sendUSB
endif
buffer[1] = 0
buffer[2] = 0
Return

'************** calculate mouse click based on fsr value ***********************
mouseClick:
'***************************************
'*MANAGE LEFT CLICK
'***************************************
if fsr1 < (fsr1Init - fsr1thresh) then
if fsr1State<>1 then 'debounce check
buffer[0] = buffer[0] + %00000001 'send left mouse click
gosub sendusb
fsr1State = 1 'set state on
endif
else
buffer[0] = 0
gosub sendusb 'send reset mouse buffer
fsr1State = 0 ' set state off
endif

'***************************************
'* MANAGE RIGHT CLICK
'***************************************
if fsr2 < (fsr2Init - fsr2thresh) then
IF FSR2STATE <> 1 THEN 'debounce check
buffer[0] = buffer[0] + %00000010
gosub sendUSB 'send right mouse click
FSR2STATE = 1 'SET STATE ON
endif
else
buffer[0] = 0
gosub sendusb 'send reset mouse buffer
fsr2state = 0 'turn state off
endif
return

'******************** send info to computer ************************************
sendUSB:
USBService ' Must service USB regularly
USBOut 1, buffer, 4, sendUSB ' Send buffer to endpoint 1
return

'B.2 Protocol 2 (Mouse)
'The following illustration represents a Report descriptor for a boot interface for a
'mouse.
'Usage Page (Generic Desktop),
'Usage (Mouse),
'Collection (Application),
'Usage (Pointer),
'Collection (Physical),
'Report Count (3),
'Report Size (1),
'Usage Page (Buttons),
'Usage Minimum (1),
'Usage Maximum (3),
'Logical Minimum (0),
'Logical Maximum (1),
'Input (Data, Variable, Absolute),
'Report Count (1),
'Report Size (5),
'Input (Constant),
'Report Size (8),
'Report Count (2),
'Usage Page (Generic\\ Desktop), 'Usage (X),
'Usage (Y),
'Logical Minimum (-127),
'Logical Maximum (127),
'Input (Data, Variable, Relative),
'End Collection,
'End Collection
'Byte Bits Description
'0 0 Button 1
' 1 Button 2
' 2 Button 3
' 4 to 7 Device-specific
'1 0 to 7 X displacement
'2 0 to 7 Y displacement
'3 to n 0 to 7 Device specific (optional)\\