-
Notifications
You must be signed in to change notification settings - Fork 66
/
3DPmain.c
190 lines (148 loc) · 4.89 KB
/
3DPmain.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
/*******************************************************************************
* File Name : main.c
* Project : 3DP-Vert, Microsoft Sidewinder 3D Pro/PP/FFP to USB converter
* Date : 2006/12/15, 2008/02/12, 2009/06/26
* Version : 4.0
* Target MCU : AT90USB162/AT90USB82, ATMEGA16U4/ATMEGA32U4
* Tool Chain : Atmel AVR Studio 4.17 666 / WinAVR 20090313
* Author : Detlef "Grendel" Mueller
* References :
* Description : USB to 3D Pro converter main program
* Device : Microsoft SideWinder 3D Pro, Precision Pro, Force Feedback Pro
*
* Release Notes:
*
* $Id: main.c 1.7 2010/04/23 05:32:26 Detlef Exp Detlef $
******************************************************************************/
#include "3DPro.h"
#include "usb_hid.h"
#include "ffb.h"
//------------------------------------------------------------------------------
// Delay until reading stick after last report was sent
#define READ_DEL MS2TM( 4.5, 1024 )
#define IDLE_DEL MS2TM( 4 , 64 )
//------------------------------------------------------------------------------
uint8_t
sw_reportsz ; // Size of SW report in bytes
uint8_t
idle_rate, // idle rate in 4ms clicks, 0 for indefinite
idle_cnt, // idle timer (count down)
sw_repsav[SW_REPSZ_3DP + ADDED_REPORT_DATA_SIZE] ; // USB report data saved
//------------------------------------------------------------------------------
// Watchdog is not turned off by a reset, see avr-libc's wdt.h documentation
// uint8_t VA_NOINIT( mcusr_cpy ) ;
void FA_INIT3( Init3 ) ( void )
{
// mcusr_cpy = MCUSR ; // If we need to examine reset reason
MCUSR = 0 ;
wdt_disable() ;
}
//------------------------------------------------------------------------------
// Check if current report differs from the last saved one and save it.
static uint8_t sw_repchg ( void )
{
uint8_t
r = FALSE,
i = sw_reportsz ;
for ( ; i-- ; )
if ( sw_repsav[i] != sw_report[i] )
{
sw_repsav[i] = sw_report[i] ;
r = TRUE ;
}
return ( r ) ;
}
//------------------------------------------------------------------------------
int FA_NORETURN( main ) ( void )
{
uint8_t
sw_sendrep ;
// Initialize..
init_hw() ; // hardware. Note: defined as naked !
sw_reportsz = // report size
(sw_id == SW_ID_3DP ? SW_REPSZ_3DP : SW_REPSZ_FFP) + ADDED_REPORT_DATA_SIZE;
usb_init() ; // USB stack
sei() ; // Enable interrupts
SetTMPS( 1, 64 ) ; // Set T1 prescaler to /64
SetTMPS( 0, 1024 ) ; // Set T0 prescaler to / 1024 for delay
sw_sendrep = sw_repchg() ; // Init send report flag, saved report
WaitMs(1000);
FfbInitMidi();
wdt_enable( WDTO_500MS ) ; // Unleash watchdog
uint8_t ffb_init_sent = 0, ffb_test_sent = 0, ffb_pause_sent = 0;
for ( ;; ) // Forever..
{
wdt_reset() ; // Calm watchdog
if ( usb_configuration )
{
if ( TMexp( 0 ) ) // Time to read the stick
{
SetTMPS( 0, 64 ) ; // Set T0 prescaler to / 64 for query
getdata() ; // read 3DP data
SetTMPS( 0, 1024 ) ; // Set T0 prescaler to / 1024 for delay
ResetTM( 0, READ_DEL ) ;
// Read the additional controls
// ???? TODO: read pedals and trims
sw_report[sw_reportsz-1] = 5; // ???? test a rudder position
if ( sw_repchg() ) // Report changed,
sw_sendrep = TRUE ; // need to send it
}
if ( TMexp( 1 ) ) // Idle timed out
{
ResetTM( 1, IDLE_DEL ) ;
if ( ! --idle_cnt && idle_rate )// Idle counter expired, rate not indef.
sw_sendrep = TRUE ; // need to send current report
}
if ( sw_sendrep && ! usb_IN_busy() )
{
LED_on() ;
// ???? Test FFB: when certain buttons are pressed
// -------0 -------1 -------2 -------3 -------4 -------5
// XXXXXXXX YYYYYYXX HHHHYYYY BBRRRRRR TBBBBBBB 00TTTTTT
// 76543210 54321098 32109876 21543210 09876543 654321
if (sw_report[3] & 0b01000000) // Button 1
{
if (ffb_init_sent == 0)
{
ffb_init_sent = 1;
FfbInitMidi();
}
}
else
ffb_init_sent = 0;
if (sw_report[3] & 0b10000000) // button 2
{
if (ffb_test_sent == 0)
{
ffb_test_sent = 1;
FfbTest();
}
}
else
ffb_test_sent = 0;
if (sw_report[4] & 0b00000001) // Button 3
{
if (ffb_pause_sent == 0)
{
ffb_pause_sent = 1;
FfbSendDisable();
}
}
else
ffb_pause_sent = 0;
usb_send_IN( sw_report, sw_reportsz ) ;
sw_sendrep = FALSE ; // reset send report flag
idle_cnt = idle_rate ; // reset idle counter
ResetTM( 1, IDLE_DEL ) ; // reset idle timer
LED_off() ;
}
}
else
{
ResetTM( 1, IDLE_DEL ) ; // reset idle timer
ResetTM( 0, READ_DEL ) ; // reset SW timer
}
}
}
//------------------------------------------------------------------------------