Subversion Repositories group.electronics

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
122 pfowler 1
#include <avr/io.h>
2
#include <avr/wdt.h>
3
#include <avr/interrupt.h>
127 pfowler 4
#include <string.h>
122 pfowler 5
#include <util/delay.h>
6
#include <stdlib.h>
7
 
123 pfowler 8
#include "avrutil.h"
9
#include "wire.h"
10
#include "lcd.h"
122 pfowler 11
#include "config.h"
12
#include "uart.h"
127 pfowler 13
#include "lmd.h"
122 pfowler 14
 
15
#ifndef NULL
16
#define NULL    ((void *)0)
17
#endif
18
 
19
 
20
/* ------------------------------------------------------------------------- */
21
 
127 pfowler 22
#define LCD_SEND_DELAY 80
23
 
24
#define OLED_SEND_DELAY		500
25
#define OLED_LCDWIDTH				128
26
#define OLED_LCDHEIGHT				64
27
 
122 pfowler 28
#define UART_BAUD_RATE	9600
29
 
127 pfowler 30
volatile uint8_t lcdTimer = LCD_SEND_DELAY;
31
volatile uint16_t oledTimer = OLED_SEND_DELAY;
32
 
122 pfowler 33
volatile uint8_t tmr0_ovf = 0;
127 pfowler 34
char display[10];
122 pfowler 35
 
127 pfowler 36
volatile struct {
37
        uint8_t current;
38
        uint8_t last;
39
        uint8_t mask;
40
} pcInt[3];
122 pfowler 41
 
127 pfowler 42
volatile struct {
43
	int8_t outer;
44
	int8_t inner;
45
} input;
122 pfowler 46
 
127 pfowler 47
volatile uint8_t doInt = 0;
48
void pcInterrupt(uint8_t pcint);
123 pfowler 49
 
122 pfowler 50
int main(void) {
51
 
52
 
53
  /*
54
  DDR : 1 = Output, 0 = Input
55
  PORT: 1 = Pullup for Input, otherwise set output
56
  PIN : Read input pin
57
  */
58
 
59
  /*
127 pfowler 60
        PB0     -
61
        PB1     -
62
        PB2     -
63
        PB3     -
64
        PB4     -
65
        PB5     -
66
        PB6     -
67
        PB7     -
122 pfowler 68
  */
127 pfowler 69
  DDRB          = 0B00000111;
122 pfowler 70
  PORTB         = 0B00000000;
71
 
72
  /*
127 pfowler 73
        PC0     -
74
        PC1     -
75
        PC2     -
76
        PC3     -
77
        PC4     -
78
        PC5     -
122 pfowler 79
  */
127 pfowler 80
  DDRC          = 0B00000000;
81
  PORTC         = 0B00001111;
122 pfowler 82
 
83
  /*
127 pfowler 84
        PD0     -
85
        PD1     -
86
        PD2     -
87
        PD3     -
88
        PD4     -
122 pfowler 89
        PD5     - Input PcInt		- * I/O Interrupt PCINT21
90
        PD6     - Output		- * Status LED
91
        PD7     - Input, Pullup		- * Button
92
  */
127 pfowler 93
  DDRD          = 0B01000000;
122 pfowler 94
  PORTD         = 0B10000000;
95
 
127 pfowler 96
  	systime = 0;
97
    sysclockInit();
98
 
123 pfowler 99
    uart_init( UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU) );
127 pfowler 100
 
122 pfowler 101
    wdt_enable(WDTO_1S);		// Watchdog for 1 sec
102
    sei();				// Enable interrupts
127 pfowler 103
 
123 pfowler 104
    i2c_master();
105
    lcd_init();
122 pfowler 106
 
127 pfowler 107
    sbi(PORTD, PD6);
123 pfowler 108
    _delay_us(100);
109
    cbi(PORTD, PD6);
122 pfowler 110
 
127 pfowler 111
    lcd_setCursor(0, 1);
112
    lcd_print("Time:\0");
113
 
114
    lmd_init(0x03, PB0, PB1, PB2, 2); // PORTB = 0x03, 5 digits = 0x04
115
    // Let the MAX's settle. There's also a 200us delay inside the init
116
    _delay_ms(200);
117
 
118
 
119
    uint16_t comm1[2];
120
    comm1[0] = 12010;
121
    comm1[1] = 12190;
122
 
123
    input.outer = 0;
124
    input.inner = 0;
125
 
126
    uint8_t c;
127
    for (c=0; c<=1; c++) {
128
    	lmd_scanlimit(c, 0x04);
129
		lmd_decodemode(c, 0xff);
130
		lmd_dp(c, 0x04);
131
		lmd_print_u16(c, comm1[c]);
132
    }
133
 
134
    //PORTC |= (( 1 << PCINT8 ) | ( 1 << PCINT9 )| ( 1 << PCINT10 )| ( 1 << PCINT11 ));
135
    PCMSK1 |= (( 1 << PCINT8 ) | ( 1 << PCINT9 )| ( 1 << PCINT10 )| ( 1 << PCINT11 ));
136
    PCICR |= ( 1 << PCIE1 );
137
 
122 pfowler 138
    for(;;){
127 pfowler 139
    	 wdt_reset();
123 pfowler 140
 
127 pfowler 141
    	 if (doInt) {
142
    		 doInt = 0;
143
    		 pcInterrupt(1);
144
    	 }
123 pfowler 145
 
127 pfowler 146
 
147
		if (!lcdTimer) {
148
		  ultoa(systime, display, 10);
149
		  lcd_overprint_right(display, 10, 6, 1);
150
 
151
		  lcdTimer = LCD_SEND_DELAY;
152
		}
153
 
154
		if (!oledTimer && !rbi(PIND, PD7)) {
155
			cli();
156
			statusLed(ON);
157
 
158
			//swap_u16(&comm1[0], &comm1[1]);
159
			uint16_t t = comm1[1];
160
			comm1[1] = comm1[0];
161
			comm1[0] = t;
162
			_delay_ms(100);
163
 
164
			statusLed(OFF);
165
			sei();
166
			oledTimer = OLED_SEND_DELAY;
167
 
168
			lmd_print_u16(0, comm1[0]);
169
			lmd_print_u16(1, comm1[1]);
170
 
171
			uart_puts("Swap: ");
172
			utoa(systime, display, 10);
173
			uart_puts(display);
174
			uart_puts("\r\n");
175
		}
176
 
177
		if (input.inner != 0 || input.outer != 0) {
178
 
179
			int16_t delta = 0;
180
 
181
			if (input.inner) {
182
				delta = (input.inner * 5);
183
			}
184
			if (input.outer) {
185
				delta = (input.outer * 100);
186
			}
187
 
188
	    	input.inner = 0;
189
	    	input.outer = 0;
190
 
191
			comm1[1] += delta;
192
			lmd_print_u16(1, comm1[1]);
193
		}
194
 
195
    	_delay_ms(1);
122 pfowler 196
    }
127 pfowler 197
 
198
 
199
 
122 pfowler 200
    return 0;
201
}
202
 
127 pfowler 203
void pcInterrupt(uint8_t pcint) {
204
		wdt_reset();
205
        switch (pcint) {
206
                case 1: pcInt[pcint].current = PINC; break;
207
        }
208
        pcInt[pcint].mask = pcInt[pcint].current ^ pcInt[pcint].last;
209
        pcInt[pcint].last = pcInt[pcint].current;
122 pfowler 210
 
127 pfowler 211
        if (pcInt[pcint].mask == 0)
212
        		return;
213
 
214
        // Check which pin caused the interrupt. If they both
215
        //  equal 0 || 1, the pin that interrupted is the direction
216
        if ((
217
        	(rbi(pcInt[pcint].current, PCINT8) == 1 &&
218
             rbi(pcInt[pcint].current, PCINT9) == 1) ||
219
             (rbi(pcInt[pcint].current, PCINT8) == 0 &&
220
              rbi(pcInt[pcint].current, PCINT9) == 0)) &&
221
            rbi(pcInt[pcint].mask, PCINT8) ) {
222
 
223
        		input.outer += 1;
224
        } else if ((
225
        		(rbi(pcInt[pcint].current, PCINT8) == 1 &&
226
                 rbi(pcInt[pcint].current, PCINT9) == 1) ||
227
                (rbi(pcInt[pcint].current, PCINT8) == 0 &&
228
                 rbi(pcInt[pcint].current, PCINT9) == 0)) &&
229
               rbi(pcInt[pcint].mask, PCINT9) ) {
230
 
231
        		input.outer -= 1;
232
        } else if ((
233
        		(rbi(pcInt[pcint].current, PCINT10) == 1 &&
234
                rbi(pcInt[pcint].current, PCINT11) == 1) ||
235
                (rbi(pcInt[pcint].current, PCINT10) == 0 &&
236
                 rbi(pcInt[pcint].current, PCINT11) == 0)) &&
237
               rbi(pcInt[pcint].mask, PCINT10) ) {
238
 
239
        		input.inner += 1;
240
        } else if ((
241
        		(rbi(pcInt[pcint].current, PCINT10) == 1 &&
242
        		 rbi(pcInt[pcint].current, PCINT11) == 1) ||
243
        			(rbi(pcInt[pcint].current, PCINT10) == 0 &&
244
        			 rbi(pcInt[pcint].current, PCINT11) == 0)) &&
245
                   rbi(pcInt[pcint].mask, PCINT11) ) {
246
 
247
        		input.inner -= 1;
248
        }
249
 
250
        // Clear the mask so we know we've delth with it
251
        pcInt[pcint].mask = 0;
252
 
253
}
254
 
255
ISR(PCINT0_vect) {
256
	doInt = 1;
257
}
258
ISR(PCINT1_vect) {
259
	doInt = 1;
260
}
261
ISR(PCINT2_vect) {
262
	doInt = 1;
263
}
264
 
265
 
122 pfowler 266
ISR(TIMER0_OVF_vect) {
267
        tmr0_ovf++;
268
 
269
	// Clk/1 TCCR0B = (1<< CS00);
270
	//20.0Mhz, 1ms = 78ovf
271
	//16.5Mhz, 1ms = 64ovf
272
	//16.0Mhz, 1ms = 62ovf
273
	//12.0Mhz, 1ms = 46ovf
274
 
275
        if (tmr0_ovf>=64) {
276
                systime++;
277
                tmr0_ovf = 0;
127 pfowler 278
 
279
			if (lcdTimer)
280
				lcdTimer--;
281
 
282
			if (oledTimer)
283
				oledTimer--;
122 pfowler 284
        }
285
}