Subversion Repositories group.NITPanels

Rev

Rev 18 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
17 pfowler 1
#include <avr/io.h>
2
#include <avr/wdt.h>
3
#include <avr/interrupt.h>
4
#include <avr/pgmspace.h>
5
#include <util/delay.h>
6
 
7
#include "usbdrv.h"
8
#include "config.h"
9
 
10
#ifndef NULL
11
#define NULL    ((void *)0)
12
#endif
13
 
18 pfowler 14
#define USB_GET_STATE  		100
15
#define USB_LEDS_SET  		101
16
#define USB_GET_ANALOG 		102
17
#define USB_SET_POWER_LED	103
17 pfowler 18
 
19
/* ------------------------------------------------------------------------- */
20
 
21
uint8_t getKey(void);
18 pfowler 22
inline void setLeds();
17 pfowler 23
 
18 pfowler 24
void analogInit();
25
uint8_t analogRead(uint8_t channel);
17 pfowler 26
 
18 pfowler 27
/*
17 pfowler 28
volatile struct {
29
	uint8_t data;
30
	union {
31
		uint8_t led_method:1;
32
		uint8_t other:1;
33
		uint8_t reserved:6;
34
	};
18 pfowler 35
} config;*/
17 pfowler 36
 
37
static uchar usbReplyBuf[16];
38
 
18 pfowler 39
volatile uint8_t pwrLed = 0;
17 pfowler 40
volatile uint8_t currLeds = 0;
41
volatile uint8_t currKeys = 0;
18 pfowler 42
volatile uint8_t analogPin = 0;
17 pfowler 43
volatile uint8_t tmr0_ovf = 0;
44
volatile uint32_t systime = 0;
45
 
46
/* ------------------------------------------------------------------------- */
47
 
48
void hadUsbReset(void) {
49
}
50
 
51
 
52
uchar	usbFunctionSetup(uchar data[8])
53
{
54
    usbRequest_t    *rq = (void *)data;
55
 
56
        switch (rq->bRequest ) {
57
		case USB_GET_STATE:
58
			usbReplyBuf[0] = currLeds;
59
			usbReplyBuf[1] = currKeys;
60
			usbMsgPtr = usbReplyBuf;
61
			return sizeof(usbReplyBuf);
62
		case USB_LEDS_SET:
63
			currLeds = rq->wValue.bytes[0];
64
			return 0;
18 pfowler 65
		case USB_GET_ANALOG:
66
			usbReplyBuf[0] = (analogPin);
67
			usbMsgPtr = usbReplyBuf;
68
			return sizeof(usbReplyBuf);
69
		case USB_SET_POWER_LED:
70
			pwrLed = rq->wValue.bytes[0];
17 pfowler 71
        }
72
 
73
	return 0;
74
}
75
 
76
int main(void) {
77
 
78
	DIDR0 = 0x00;
79
 
80
  /*
81
  DDR : 1 = Output, 0 = Input
82
  PORT: 1 = Pullup for Input, otherwise set output
83
  PIN : Read input pin
84
  */
85
 
86
  /*
18 pfowler 87
        PB0     - Output            - LED 3
88
        PB1     - Output            - LED 4
89
        PB2     - Output            - LED 5
90
        PB3     - Output            - LED 6
91
        PB4     - Output            - LED 7
92
        PB5     - Input				- Config Switch 1
93
        PB6     - Osc
94
        PB7     - Osc
17 pfowler 95
  */
96
  DDRB          = 0B00011111;
97
  PORTB         = 0B00000000;
98
 
99
  /*
18 pfowler 100
        PC0     - Input, ADC		- Potentiometer
101
        PC1     - Output			- Power LED
17 pfowler 102
        PC2     - Input, Pullup		- ButtonPad 0
103
        PC3     - Input, Pullup		- ButtonPad 1
104
        PC4     - Input, Pullup		- ButtonPad 2
105
        PC5     - Input, Pullup		- ButtonPad 3
18 pfowler 106
        PC6		- Reset
17 pfowler 107
  */
18 pfowler 108
  DDRC          = 0B00000010;
109
  PORTC         = 0B00111100;
17 pfowler 110
 
111
  /*
18 pfowler 112
        PD0     - Output		- ButtonPad Gnd0
113
        PD1     - Output		- ButtonPad Gnd1
114
        PD2     - USB D+
115
        PD3     - USB D-
116
        PD4     - Input			- Config Switch 2
17 pfowler 117
        PD5     - Output		- LED 0
118
        PD6     - Output		- LED 1
119
        PD7     - Output		- LED 2
120
  */
18 pfowler 121
  DDRD          = 0B11100011;
122
  PORTD         = 0B00000011;
17 pfowler 123
 
18 pfowler 124
	// The USB connect stuff, flash the power led
20 pfowler 125
  	sbi(PORTC, PC1);
17 pfowler 126
    usbDeviceDisconnect();
127
    _delay_ms(500);
128
    usbDeviceConnect();
20 pfowler 129
    cbi(PORTC, PC1);
17 pfowler 130
 
18 pfowler 131
    // @TODO: Don't really need the system time anymore, remove?
132
    TIMSK0 = (1<<TOIE0);            // Enable timer overflow
133
    TCNT0 = 0x00;                   // Set Timer0 initial value to 0
134
    TCCR0B = (1<< CS00) ;           // /1 prescaler
17 pfowler 135
 
18 pfowler 136
    wdt_enable(WDTO_1S);			// WatchDog at 1s
137
    usbInit();						// Init the USB port
138
    sei();							// Enable interrupts
17 pfowler 139
 
18 pfowler 140
	setLeds();						// Set default LED status
17 pfowler 141
 
18 pfowler 142
	analogInit();					// Init the ADC for PC0 (ADC0)
17 pfowler 143
 
144
    for(;;){
145
        wdt_reset();
18 pfowler 146
        usbPoll();					// Poll USB port (Every ~10ms!)
147
        currKeys = getKey();		// Check the button presses
148
        analogPin = analogRead(0);	// Read the pot (VolControl)
149
		setLeds();					// Set the leds
150
									// @TODO: Only do this on change
17 pfowler 151
    }
152
 
153
    return 0;
154
}
155
 
18 pfowler 156
inline void setLeds() {
157
	// Set the status leds.
158
	// @TODO: Verify that this doesn't mess with other port functions
17 pfowler 159
	PORTB &= 0xE0;
18 pfowler 160
	PORTB |= (0x1F & (currLeds >> 3));
17 pfowler 161
	PORTD &= 0x1F;
18 pfowler 162
	PORTD |= (0xE0 & (currLeds << 5));
17 pfowler 163
 
20 pfowler 164
	// Set the power led state
18 pfowler 165
	if (pwrLed)
166
		sbi(PORTC, PC1);
167
	else
168
		cbi(PORTC, PC1);
17 pfowler 169
}
170
 
18 pfowler 171
// Gnd = PD0, PD1
17 pfowler 172
// Btn = PC2, PC3, PC4, PC5
173
uint8_t getKey() {
174
        uint8_t key = 0;
175
 
18 pfowler 176
        cbi(PORTD, PD1);		// Read the first row of buttons
177
        _delay_us(10);			// Wait for the port change
178
        if (rbi(PINC, PC2) == 0) key = 1;
179
        if (rbi(PINC, PC3) == 0) key = 2;
180
        if (rbi(PINC, PC4) == 0) key = 4;
181
        if (rbi(PINC, PC5) == 0) key = 8;
182
        sbi(PORTD, PD1);
17 pfowler 183
 
18 pfowler 184
        cbi(PORTD, PD0);		// Read the second row of buttons
17 pfowler 185
        _delay_us(10);
18 pfowler 186
        if (rbi(PINC, PC2) == 0) key = 16;
187
        if (rbi(PINC, PC3) == 0) key = 32;
188
        if (rbi(PINC, PC4) == 0) key = 64;
189
        if (rbi(PINC, PC5) == 0) key = 128;
190
        sbi(PORTD, PD0);
17 pfowler 191
 
192
        return key;
193
}
194
 
18 pfowler 195
uint8_t analogRead(uint8_t channel) {
196
        ADMUX = (1<<ADLAR) | (1<<REFS0) | (0<<REFS1) | (channel & 0x0f);
197
        ADCSRA |= (1<<ADSC);            	// Start converting
17 pfowler 198
 
18 pfowler 199
        while (((ADCSRA >> ADSC) & 1)) {}   //Wait until conversion finished
200
        uint8_t result = ADCH;
201
        //ADCSRA |= (0<<ADSC);          	// Stop converting
202
 
203
        return result;
204
}
205
 
206
void analogInit() {
207
	ACSR |= (1<<ACD); // Disable analog comparator
208
 
209
	/*
210
        Setup ADC
211
        ADMUX: 8 bit mode, Avcc ref
212
        ADCSRA: Enable, 128 prescale
213
	*/
214
	ADMUX = (1<<ADLAR) | (0<<REFS0) | (1<<REFS1);
215
	ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0) ;
216
}
217
 
17 pfowler 218
ISR(TIMER0_OVF_vect) {
219
        tmr0_ovf++;
220
 
221
	// Clk/1 TCCR0B = (1<< CS00);
222
	//20.0Mhz, 1ms = 78ovf
223
	//16.5Mhz, 1ms = 64ovf
224
	//12.0Mhz, 1ms = 46ovf
225
 
226
        if (tmr0_ovf>=78) {
227
                systime++;
228
                tmr0_ovf = 0;
229
        }
230
}