Subversion Repositories group.electronics

Rev

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