Subversion Repositories group.electronics

Rev

Rev 77 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 77 Rev 78
Line 47... Line 47...
47
        uint8_t current;
47
        uint8_t current;
48
        uint8_t last;
48
        uint8_t last;
49
        uint8_t mask;
49
        uint8_t mask;
50
} pcInt[1];
50
} pcInt[1];
51
 
51
 
-
 
52
volatile struct {
-
 
53
	uint8_t button;
-
 
54
	uint8_t timer;
-
 
55
} buttons;
-
 
56
 
-
 
57
 
52
static uchar    idleRate;           /* in 4 ms units */
58
static uchar    idleRate;           /* in 4 ms units */
-
 
59
volatile uint8_t tmr0_ovf = 0;
-
 
60
volatile uint32_t systime = 0;
53
 
61
 
54
/* ------------------------------------------------------------------------- */
62
/* ------------------------------------------------------------------------- */
55
 
63
 
56
const PROGMEM char usbHidReportDescriptor[USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH] = { /* USB report descriptor */
64
const PROGMEM char usbHidReportDescriptor[USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH] = { /* USB report descriptor */
57
    0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)
65
    0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)
Line 72... Line 80...
72
    0x19, 0x01,                    //     USAGE_MINIMUM (Button 1)
80
    0x19, 0x01,                    //     USAGE_MINIMUM (Button 1)
73
    0x29, 0x02,                    //     USAGE_MAXIMUM (Button 2)
81
    0x29, 0x02,                    //     USAGE_MAXIMUM (Button 2)
74
    0x15, 0x00,                    //     LOGICAL_MINIMUM (0)
82
    0x15, 0x00,                    //     LOGICAL_MINIMUM (0)
75
    0x25, 0x01,                    //     LOGICAL_MAXIMUM (1)
83
    0x25, 0x01,                    //     LOGICAL_MAXIMUM (1)
76
    0x75, 0x01,                    //     REPORT_SIZE (1)
84
    0x75, 0x01,                    //     REPORT_SIZE (1)
77
    0x95, 0x02,                    //     REPORT_COUNT (2)
85
    0x95, 0x08,                    //     REPORT_COUNT (2)
78
    0x81, 0x02,                    //     INPUT (Data,Var,Abs)
-
 
79
 
-
 
80
    0x75, 0x01,                    //     REPORT_SIZE (1)
-
 
81
    0x95, 0x06,                    //     REPORT_COUNT (6)
-
 
82
    0x81, 0x02,                    //     INPUT (Data,Var,Abs)
86
    0x81, 0x02,                    //     INPUT (Data,Var,Abs)
83
 
87
 
84
    0xc0,                          //   END_COLLECTION
88
    0xc0,                          //   END_COLLECTION
85
    0xc0                           // END_COLLECTION
89
    0xc0                           // END_COLLECTION
86
};
90
};
87
 
91
 
88
 
92
 
89
 
-
 
90
/* ------------------------------------------------------------------------- */
-
 
91
/* ------------------------ interface to USB driver ------------------------ */
-
 
92
/* ------------------------------------------------------------------------- */
-
 
93
 
-
 
94
uchar	usbFunctionSetup(uchar data[8])
93
uchar	usbFunctionSetup(uchar data[8])
95
{
94
{
96
usbRequest_t    *rq = (void *)data;
95
    usbRequest_t    *rq = (void *)data;
97
 
96
 
98
    //usbMsgPtr = reportBuffer;
97
    //usbMsgPtr = reportBuffer;
99
    if((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS){ 
98
    if((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS){ 
100
        if(rq->bRequest == USBRQ_HID_GET_REPORT){ 
99
        if(rq->bRequest == USBRQ_HID_GET_REPORT){ 
101
            return sizeof(reportBuffer);
100
            return sizeof(reportBuffer);
Line 110... Line 109...
110
    }
109
    }
111
	return 0;
110
	return 0;
112
}
111
}
113
 
112
 
114
 
113
 
115
/* ------------------------------------------------------------------------- */
-
 
116
/* ------------------------ Oscillator Calibration ------------------------- */
-
 
117
/* ------------------------------------------------------------------------- */
-
 
118
 
-
 
119
/* Calibrate the RC oscillator to 8.25 MHz. The core clock of 16.5 MHz is
-
 
120
 * derived from the 66 MHz peripheral clock by dividing. Our timing reference
-
 
121
 * is the Start Of Frame signal (a single SE0 bit) available immediately after
-
 
122
 * a USB RESET. We first do a binary search for the OSCCAL value and then
-
 
123
 * optimize this value with a neighboorhod search.
-
 
124
 * This algorithm may also be used to calibrate the RC oscillator directly to
-
 
125
 * 12 MHz (no PLL involved, can therefore be used on almost ALL AVRs), but this
-
 
126
 * is wide outside the spec for the OSCCAL value and the required precision for
-
 
127
 * the 12 MHz clock! Use the RC oscillator calibrated to 12 MHz for
-
 
128
 * experimental purposes only!
-
 
129
 */
-
 
130
static void calibrateOscillator(void)
114
static void calibrateOscillator(void) {
131
{
-
 
132
uchar       step = 128;
115
    uchar step = 128;
133
uchar       trialValue = 0, optimumValue;
116
    uchar trialValue = 0, optimumValue;
-
 
117
    int x, optimumDev;
134
int         x, optimumDev, targetValue = (unsigned)(1499 * (double)F_CPU / 10.5e6 + 0.5);
118
    int targetValue = (unsigned)(1499 * (double)F_CPU / 10.5e6 + 0.5);
135
 
119
 
136
    /* do a binary search: */
120
    /* do a binary search: */
137
    do{
121
    do {
138
        OSCCAL = trialValue + step;
122
        OSCCAL = trialValue + step;
139
        x = usbMeasureFrameLength();    /* proportional to current real frequency */
123
        x = usbMeasureFrameLength();    /* proportional to current real frequency */
140
        if(x < targetValue)             /* frequency still too low */
124
        if(x < targetValue)             /* frequency still too low */
141
            trialValue += step;
125
            trialValue += step;
142
        step >>= 1;
126
        step >>= 1;
143
    }while(step > 0);
127
    } while(step > 0);
144
    /* We have a precision of +/- 1 for optimum OSCCAL here */
128
    /* We have a precision of +/- 1 for optimum OSCCAL here */
145
    /* now do a neighborhood search for optimum value */
129
    /* now do a neighborhood search for optimum value */
146
    optimumValue = trialValue;
130
    optimumValue = trialValue;
147
    optimumDev = x; /* this is certainly far away from optimum */
131
    optimumDev = x; /* this is certainly far away from optimum */
148
    for(OSCCAL = trialValue - 1; OSCCAL <= trialValue + 1; OSCCAL++){
132
    for(OSCCAL = trialValue - 1; OSCCAL <= trialValue + 1; OSCCAL++){
Line 154... Line 138...
154
            optimumValue = OSCCAL;
138
            optimumValue = OSCCAL;
155
        }
139
        }
156
    }
140
    }
157
    OSCCAL = optimumValue;
141
    OSCCAL = optimumValue;
158
}
142
}
159
/*
-
 
160
Note: This calibration algorithm may try OSCCAL values of up to 192 even if
-
 
161
the optimum value is far below 192. It may therefore exceed the allowed clock
-
 
162
frequency of the CPU in low voltage designs!
-
 
163
You may replace this search algorithm with any other algorithm you like if
-
 
164
you have additional constraints such as a maximum CPU clock.
-
 
165
For version 5.x RC oscillators (those with a split range of 2x128 steps, e.g.
-
 
166
ATTiny25, ATTiny45, ATTiny85), it may be useful to search for the optimum in
-
 
167
both regions.
-
 
168
*/
-
 
169
 
143
 
170
void    usbEventResetReady(void)
144
void usbEventResetReady(void) {
171
{
-
 
172
    /* Disable interrupts during oscillator calibration since
-
 
173
     * usbMeasureFrameLength() counts CPU cycles.
-
 
174
     */
-
 
175
    cli();
145
    cli();
176
    calibrateOscillator();
146
    calibrateOscillator();
177
    sei();
147
    sei();
178
    eeprom_write_byte(0, OSCCAL);   /* store the calibrated value in EEPROM */
148
    eeprom_write_byte(0, OSCCAL);   /* store the calibrated value in EEPROM */
179
}
149
}
180
 
150
 
181
 
151
 
182
void usbSendHidReport(uchar * data, uchar len) {
152
void usbSendHidReport(uchar * data, uchar len) {
183
        while(1)
-
 
184
        {
-
 
185
                usbPoll();
-
 
186
                if (usbInterruptIsReady())
-
 
187
                {
-
 
188
                        usbSetInterrupt(data, len);
153
	usbSetInterrupt(data, len);
189
                        break;
-
 
190
                }
-
 
191
        }
-
 
192
}
154
}
193
 
155
 
194
 
156
 
195
int main(void)
157
int main(void) {
196
{
-
 
197
uchar   i;
158
uchar   i;
198
uchar   calibrationValue;
159
uchar   calibrationValue;
199
 
160
 
200
    calibrationValue = eeprom_read_byte(0); /* calibration value from last time */
161
    calibrationValue = eeprom_read_byte(0); /* calibration value from last time */
201
    if(calibrationValue != 0xff){
162
    if(calibrationValue != 0xff){
Line 212... Line 173...
212
    wdt_enable(WDTO_1S);
173
    wdt_enable(WDTO_1S);
213
 
174
 
214
  PCMSK |= (( 1 << PCINT3 ) | ( 1 << PCINT4 )); //enable encoder pins interrupt sources
175
  PCMSK |= (( 1 << PCINT3 ) | ( 1 << PCINT4 )); //enable encoder pins interrupt sources
215
  GIMSK |= ( 1 << PCIE ); //enable pin change interupts
176
  GIMSK |= ( 1 << PCIE ); //enable pin change interupts
216
 
177
 
-
 
178
        TIMSK = (1<<TOIE0);                    // Enable timer overflow
-
 
179
        TCNT0 = 0x00;                           // Set Timer0 initial value to 0
-
 
180
        TCCR0B = (1<< CS01) ;                   // /1 prescaler
-
 
181
 
217
  DDRB          = 0B00000001;
182
  DDRB          = 0B00000001;
218
  PORTB         = 0B00000000;
183
  PORTB         = 0B00000000;
219
 
184
 
220
    usbInit();
185
    usbInit();
221
    sei();
186
    sei();
Line 227... Line 192...
227
 
192
 
228
    for(;;){    /* main event loop */
193
    for(;;){    /* main event loop */
229
        wdt_reset();
194
        wdt_reset();
230
        usbPoll();
195
        usbPoll();
231
 
196
 
-
 
197
	
-
 
198
 
232
        if(usbInterruptIsReady()){ 
199
        if(usbInterruptIsReady()){ 
-
 
200
 
-
 
201
		// Check if our buttons need pressing
-
 
202
		reportBuffer.buttons = 0;
-
 
203
		if (buttons.timer != 0) {
-
 
204
			if (buttons.button == 1)
-
 
205
				reportBuffer.b1 = 1;
-
 
206
			else
-
 
207
				reportBuffer.b2 = 1;
-
 
208
		}
-
 
209
 
233
		usbSendHidReport(&reportBuffer, sizeof(reportBuffer));
210
		usbSendHidReport(&reportBuffer, sizeof(reportBuffer));
234
    		reportBuffer.buttons = 0;
-
 
235
        }
211
        }
236
    }
212
    }
237
    return 0;
213
    return 0;
238
}
214
}
239
 
215
 
Line 255... Line 231...
255
                && rbi(pcInt[pcint].mask, PCINT4) ) {
231
                && rbi(pcInt[pcint].mask, PCINT4) ) {
256
 
232
 
257
                        if (reportBuffer.axis2 < 32500)
233
                        if (reportBuffer.axis2 < 32500)
258
                                reportBuffer.axis2 += 200;
234
                                reportBuffer.axis2 += 200;
259
 
235
 
-
 
236
			buttons.button = 1;
260
			reportBuffer.b1 = 1;
237
			buttons.timer = 5;
261
 
238
 
262
        } else if (rbi(pcInt[pcint].current, PCINT3) == 0
239
        } else if (rbi(pcInt[pcint].current, PCINT3) == 0
263
                && rbi(pcInt[pcint].current, PCINT4) == 0
240
                && rbi(pcInt[pcint].current, PCINT4) == 0
264
                && rbi(pcInt[pcint].mask, PCINT3) ) {
241
                && rbi(pcInt[pcint].mask, PCINT3) ) {
265
 
242
 
266
                        if (reportBuffer.axis2 > -32500)
243
                        if (reportBuffer.axis2 > -32500)
267
                                reportBuffer.axis2 -= 200;
244
                                reportBuffer.axis2 -= 200;
268
 
245
 
-
 
246
			buttons.button = 2;
269
			reportBuffer.b2 = 1;
247
			buttons.timer = 5;
270
 
-
 
271
        }
248
        }
272
 
249
 
273
        // Clear the mask so we know we've delth with it
250
        // Clear the mask so we know we've delth with it
274
        pcInt[pcint].mask = 0;
251
        pcInt[pcint].mask = 0;
275
}
252
}
276
 
253
 
277
ISR(PCINT0_vect) {
254
ISR(PCINT0_vect) {
278
        pcInterrupt(0);
255
        pcInterrupt(0);
279
}
256
}
-
 
257
 
-
 
258
ISR(TIMER0_OVF_vect) {
-
 
259
        tmr0_ovf++;
-
 
260
        if (tmr0_ovf>=50) {
-
 
261
                systime++;
-
 
262
                tmr0_ovf = 0;
-
 
263
 
-
 
264
		if (buttons.timer != 0) 
-
 
265
			buttons.timer--;
-
 
266
        }
-
 
267
}