Subversion Repositories group.electronics

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
130 pfowler 1
#include <avr/io.h>
2
#include <avr/wdt.h>
136 pfowler 3
#include <avr/eeprom.h>
130 pfowler 4
#include <avr/interrupt.h>
136 pfowler 5
#include <avr/pgmspace.h>
130 pfowler 6
#include <util/delay.h>
7
 
136 pfowler 8
 
130 pfowler 9
#include "config.h"
10
#include "avrutil.h"
136 pfowler 11
#include "usbdrv.h"
12
#include "i2cbb.h"
130 pfowler 13
 
14
 
15
#ifndef NULL
16
#define NULL    ((void *)0)
17
#endif
18
 
136 pfowler 19
static void calibrateOscillator(void);
20
void usbEventResetReady(void);
130 pfowler 21
 
137 pfowler 22
//static void updateDisplays();
23
static void updateDisplay(uint8_t dis);
130 pfowler 24
 
136 pfowler 25
#define DIS_COM_ACTIVE
26
#define DIS_COM_STANDBY
27
#define DIS_NAV_ACTIVE
28
#define DIS_NAV_STANDBY
130 pfowler 29
 
136 pfowler 30
// Hold the chars for the display panels
130 pfowler 31
 
136 pfowler 32
volatile uint8_t displays[5][6] = {
137 pfowler 33
							{ 6, 6, 6, 6, 6},	// DIS_COM_ACTIVE
34
							{ 7, 7, 7, 7, 7},	// DIS_COM_STANDBY
136 pfowler 35
							{ 0, 0, 0, 0, 0},	// DIS_NAV_ACTIVE
36
							{ 0, 0, 0, 0, 0},	// DIS_NAV_STANDBY
37
						 };
130 pfowler 38
 
136 pfowler 39
 
40
//static uchar usbReplyBuf[16];
41
volatile static uint8_t bytesRemaining;
137 pfowler 42
//volatile static uint8_t* writeIdx;
136 pfowler 43
 
130 pfowler 44
volatile uint8_t tmr0_ovf = 0;
137 pfowler 45
volatile uint8_t update = 255;
130 pfowler 46
 
136 pfowler 47
 
48
 
130 pfowler 49
int main(void) {
136 pfowler 50
	uchar   calibrationValue;
130 pfowler 51
 
136 pfowler 52
	calibrationValue = eeprom_read_byte(0); /* calibration value from last time */
53
	if(calibrationValue != 0xff){
54
		OSCCAL = calibrationValue;
55
	}
130 pfowler 56
 
136 pfowler 57
	/*
58
		DDR : 1 = Output, 0 = Input
59
		PORT: 1 = Pullup for Input, otherwise set output
60
		PIN : Read input pin
130 pfowler 61
 
136 pfowler 62
		PB0	-
63
		PB1	- 		- USB D- Low Speed
64
		PB2	-		- USB D+
65
		PB3	- 		- SCL i2c bb
66
		PB4	-		- SDA i2c bb
67
		PB5	-
68
	*/
69
	DDRB          = 0B00000001;
70
	PORTB         = 0B00000001;
71
 
137 pfowler 72
 
136 pfowler 73
    usbDeviceDisconnect();
137 pfowler 74
    _delay_ms(500);
136 pfowler 75
    usbDeviceConnect();
76
 
130 pfowler 77
    systime = 0;
78
    sysclockInit();
79
 
80
    wdt_enable(WDTO_1S);	// Watchdog for 1 sec
136 pfowler 81
    usbInit();
131 pfowler 82
    sei();			// Enable interrupts
130 pfowler 83
 
136 pfowler 84
 
85
/*
86
    cbi(PORTB, PB0);
87
    i2cbb_Init();
88
    i2cbb_Start();
89
    i2cbb_Write(0x4c);
90
    i2cbb_Write(0x05);
91
    i2cbb_Write(0x08);
92
    i2cbb_Stop();
93
    sbi(PORTB, PB0);
94
*/
95
 
137 pfowler 96
    uint8_t i;
97
    for (i=0; i<2; i++)
98
    	updateDisplay(i);
99
 
100
 
130 pfowler 101
    for(;;){
102
    	 wdt_reset();
136 pfowler 103
    	 usbPoll();
130 pfowler 104
 
137 pfowler 105
    	if (update != 255) {
106
    		updateDisplay(update);
107
    		update = 255;
130 pfowler 108
    	}
109
 
110
    }
111
    return 0;
112
}
113
 
137 pfowler 114
static void updateDisplay(uint8_t dis) {
115
    cbi(PORTB, PB0);
116
    i2cbb_Init();
117
    i2cbb_Start();
118
    i2cbb_Write(0x4c);
119
    i2cbb_Write(0x05);
120
    uint8_t n;
121
    for (n=0; n<5; n++) {
122
    	i2cbb_Write( ((n+5*dis)<<4) | (displays[dis][n] & 0x0f) );
123
    }
124
    i2cbb_Stop();
125
    sbi(PORTB, PB0);
126
}
127
 
128
/*
136 pfowler 129
static void updateDisplays() {
130
    cbi(PORTB, PB0);
131
    i2cbb_Init();
132
    i2cbb_Start();
133
    i2cbb_Write(0x4c);
134
    i2cbb_Write(0x05);
135
    i2cbb_Write(0x00 | displays[0][0]);
136
    i2cbb_Write(0x10 | displays[0][1]);
137
    i2cbb_Write(0x20 | displays[0][2]);
138
    i2cbb_Write(0x30 | displays[0][3]);
139
    i2cbb_Write(0x40 | displays[0][4]);
140
 
141
    i2cbb_Stop();
142
    sbi(PORTB, PB0);
143
 
144
    cbi(PORTB, PB0);
145
    i2cbb_Init();
146
    i2cbb_Start();
147
    i2cbb_Write(0x4c);
148
    i2cbb_Write(0x05);
149
    i2cbb_Write(0x50 | displays[1][0]);
150
    i2cbb_Write(0x60 | displays[1][1]);
151
    i2cbb_Write(0x70 | displays[1][2]);
152
    i2cbb_Write(0x80 | displays[1][3]);
153
    i2cbb_Write(0x90 | displays[1][4]);
154
    i2cbb_Stop();
155
    sbi(PORTB, PB0);
156
 
157
 
158
	update = 0;
159
}
137 pfowler 160
*/
136 pfowler 161
 
162
static void calibrateOscillator(void) {
163
    uchar step = 128;
164
    uchar trialValue = 0, optimumValue;
165
    int x, optimumDev;
166
    int targetValue = (unsigned)(1499 * (double)F_CPU / 10.5e6 + 0.5);
167
 
168
    /* do a binary search: */
169
    do {
170
        OSCCAL = trialValue + step;
171
        x = usbMeasureFrameLength();    /* proportional to current real frequency */
172
        if(x < targetValue)             /* frequency still too low */
173
            trialValue += step;
174
        step >>= 1;
175
    } while(step > 0);
176
    /* We have a precision of +/- 1 for optimum OSCCAL here */
177
    /* now do a neighborhood search for optimum value */
178
    optimumValue = trialValue;
179
    optimumDev = x; /* this is certainly far away from optimum */
180
    for(OSCCAL = trialValue - 1; OSCCAL <= trialValue + 1; OSCCAL++){
181
        x = usbMeasureFrameLength() - targetValue;
182
        if(x < 0)
183
            x = -x;
184
        if(x < optimumDev){
185
            optimumDev = x;
186
            optimumValue = OSCCAL;
187
        }
188
    }
189
    OSCCAL = optimumValue;
190
}
191
 
192
#define USB_GET_CONT_VER		10		// Send the controller version data
193
#define USB_GET_COMM_VER		11		// Send the comm display version data
194
#define USB_GET_NAV_VER			12		// Send the nav display version data
195
 
137 pfowler 196
#define USB_SET_DIGIT			20		// Set a digit on display
136 pfowler 197
 
198
#define USB_GET_COMM_ENC		30		// Send the comm rotary encoder position
199
#define USB_RESET_COMM_ENC		31		// Reset the comm encoder to 0
200
#define USB_GET_NAV_ENC			32		// Send the nav rotary encoder position
201
#define USB_RESET_NAV_ENC		33		// Reset the nav encoder to 0
202
 
203
#define USB_GET_BUTTONS			32		// Send the status of all the buttons
204
 
205
 
206
 
207
usbMsgLen_t usbFunctionSetup(uchar data[8])
208
{
209
    usbRequest_t    *rq = (void *)data;
210
 
211
 
212
	switch (rq->bRequest ) {
137 pfowler 213
		case USB_SET_DIGIT: {
214
			uint8_t dis = rq->wValue.bytes[1];
215
			uint8_t dig = rq->wValue.bytes[0];
216
			uint8_t val = rq->wIndex.bytes[0];
217
			displays[dis][dig] = val;
218
			update = dis;
219
			break;
136 pfowler 220
		}
221
 
222
	}
223
	return 0;
224
}
225
 
226
/*
227
uchar usbFunctionWrite(uchar *data, uchar len) {
228
	uint8_t i;
229
	if (len > bytesRemaining)
230
		len = bytesRemaining;
231
	bytesRemaining -= len;
232
	for (i=0; i<len; i++) {
233
		*writeIdx++ = data[i];
234
	}
235
	displays[0][3] = 2;
236
	displays[0][4] = 2;
237
	update = 1;
238
	return (bytesRemaining == 0);
239
}
240
*/
241
 
242
void usbEventResetReady(void) {
243
    cli();
244
    calibrateOscillator();
245
    sei();
246
    eeprom_write_byte(0, OSCCAL);   /* store the calibrated value in EEPROM */
247
}
248
 
132 pfowler 249
ISR(TIM0_OVF_vect) {
130 pfowler 250
 
132 pfowler 251
	tmr0_ovf++;
130 pfowler 252
 
253
	// Clk/1 TCCR0B = (1<< CS00);
254
	//20.0Mhz, 1ms = 78ovf
255
	//16.5Mhz, 1ms = 64ovf
256
	//16.0Mhz, 1ms = 62ovf
257
	//12.0Mhz, 1ms = 46ovf
258
	// 8.0Mhz, 1ms = 31ovf
131 pfowler 259
	// 8.0Mhz, .5ms = 15ovf, 160r
130 pfowler 260
 
132 pfowler 261
	if (tmr0_ovf>=64) {
130 pfowler 262
			systime++;
263
			tmr0_ovf = 0;
264
	}
265
 
266
}