Subversion Repositories group.electronics

Rev

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

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