Subversion Repositories group.electronics

Rev

Rev 128 | Details | Compare with Previous | 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
 
128 pfowler 8
#include "config.h"
123 pfowler 9
#include "avrutil.h"
128 pfowler 10
#include "hc595.h"
11
#include "twires.h"
122 pfowler 12
 
128 pfowler 13
 
122 pfowler 14
#ifndef NULL
15
#define NULL    ((void *)0)
16
#endif
17
 
18
 
128 pfowler 19
void writeSegment(uint8_t digit, uint8_t value);
20
void pcInterrupt(void);
21
void receiveEvent(uint8_t howMany);
22
 
122 pfowler 23
/* ------------------------------------------------------------------------- */
24
 
128 pfowler 25
#define I2C_SLAVE_ADDR  0x26
26
#ifndef TWI_RX_BUFFER_SIZE
27
#define TWI_RX_BUFFER_SIZE ( 16 )
28
#endif
127 pfowler 29
 
122 pfowler 30
volatile uint8_t tmr0_ovf = 0;
127 pfowler 31
volatile struct {
32
        uint8_t current;
33
        uint8_t last;
34
        uint8_t mask;
128 pfowler 35
} pcInt;
122 pfowler 36
 
128 pfowler 37
struct {
127 pfowler 38
	int8_t outer;
39
	int8_t inner;
40
} input;
122 pfowler 41
 
128 pfowler 42
//volatile uint8_t doInt = 0;
123 pfowler 43
 
128 pfowler 44
 
45
 
46
uint8_t disVal[] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
47
uint8_t disPt[] = {0, 0};
48
 
122 pfowler 49
int main(void) {
50
 
51
 
52
  /*
53
  DDR : 1 = Output, 0 = Input
54
  PORT: 1 = Pullup for Input, otherwise set output
55
  PIN : Read input pin
56
  */
57
 
128 pfowler 58
 
122 pfowler 59
  /*
128 pfowler 60
		PA0	- Output					- System LED
61
		PA1	- Input, Pullup				- System button
62
		PA2 - N/A						- Reset
63
  */
64
  DDRA          = 0B00000001;
65
  PORTA         = 0B00000010;
66
  /*
67
        PB0     - Input, PCInt, Pullup	- Rot1a
68
        PB1     - Input, PCInt, Pullup	- Rot1b
69
        PB2     - Input, PCInt, Pullup	- Rot2a
70
        PB3     - Input, PCInt, Pullup	- Rot2b
71
        PB4     - Input, Pullup			- Swap button
127 pfowler 72
        PB5     -
73
        PB6     -
74
        PB7     -
122 pfowler 75
  */
128 pfowler 76
  DDRB          = 0B00000000;
77
  PORTB         = 0B00011111;
122 pfowler 78
 
79
  /*
127 pfowler 80
        PD0     -
81
        PD1     -
128 pfowler 82
        PD2     -	Output			- Decimal Point
83
        PD3     -	Output			- 4511 blanking
84
        PD4     -	Output			- HC595 DS
85
        PD5     - 	Output			- HC595 ST
86
        PD6     -	Output			- HC595 SH
122 pfowler 87
  */
128 pfowler 88
  DDRD          = 0B01111100;
89
  PORTD         = 0B00000000;
122 pfowler 90
 
128 pfowler 91
    systime = 0;
127 pfowler 92
    sysclockInit();
93
 
128 pfowler 94
    PCMSK |= (( 1 << PCINT0 ) | ( 1 << PCINT1 )| ( 1 << PCINT2 )| ( 1 << PCINT3 ));
95
    GIMSK |= (1 << PCIE);
96
    //PCICR |= ( 1 << PCIE1 );
127 pfowler 97
 
128 pfowler 98
    pcInt.last = PINB;
99
    pcInt.current = pcInt.last;
100
    pcInt.mask = 0;
127 pfowler 101
 
128 pfowler 102
    twires_begin(I2C_SLAVE_ADDR);
103
    twires_onReceive(receiveEvent);
122 pfowler 104
 
128 pfowler 105
    wdt_enable(WDTO_1S);	// Watchdog for 1 sec
106
    sei();					// Enable interrupts
122 pfowler 107
 
128 pfowler 108
    hc595_init();
109
    hc595_write(0x00);
127 pfowler 110
 
128 pfowler 111
    uint32_t refresh = systime;
127 pfowler 112
 
128 pfowler 113
    sbi(PORTA, PA0);
114
    _delay_ms(100);
115
    cbi(PORTA, PA0);
127 pfowler 116
 
117
 
128 pfowler 118
    uint8_t disIdx = 0;
127 pfowler 119
 
120
 
122 pfowler 121
    for(;;){
127 pfowler 122
    	 wdt_reset();
123 pfowler 123
 
128 pfowler 124
    	/*
125
		if ( rbi(PINA, PA1) )
126
			cbi(PORTA, PA0);
127
		else
128
			sbi (PORTA, PA0);
129
		*/
123 pfowler 130
 
128 pfowler 131
		if (pcInt.current != pcInt.last) {
132
			pcInterrupt();
133
			//doInt = 0;
127 pfowler 134
		}
135
 
128 pfowler 136
		if (systime > refresh) {
137
			writeSegment(disIdx, disVal[disIdx]);
138
			refresh = systime+2;
139
			disIdx++;
140
			if (disIdx > 10) disIdx = 0;
127 pfowler 141
		}
142
 
128 pfowler 143
		twires_stop_check();
144
    }
145
    return 0;
146
}
127 pfowler 147
 
128 pfowler 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
				}
127 pfowler 157
		}
128 pfowler 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
}
127 pfowler 183
 
128 pfowler 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;
127 pfowler 188
 
128 pfowler 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
193
	sbi(PORTD, PD3);			// Enable the 4511
122 pfowler 194
}
195
 
128 pfowler 196
void pcInterrupt() {
127 pfowler 197
		wdt_reset();
122 pfowler 198
 
128 pfowler 199
		pcInt.mask = pcInt.current ^ pcInt.last;
200
		pcInt.last = pcInt.current;
127 pfowler 201
 
128 pfowler 202
        if (pcInt.mask == 0)
203
        	return;
204
 
127 pfowler 205
        // Check which pin caused the interrupt. If they both
206
        //  equal 0 || 1, the pin that interrupted is the direction
128 pfowler 207
        if (((rbi(pcInt.current, PCINT0) == 1 &&
208
             rbi(pcInt.current, PCINT1) == 1) ||
209
             (rbi(pcInt.current, PCINT0) == 0 &&
210
              rbi(pcInt.current, PCINT1) == 0))) {
211
              if (rbi(pcInt.mask, PCINT0) ) {
127 pfowler 212
        		input.outer += 1;
128 pfowler 213
              } else if (rbi(pcInt.mask, PCINT1) ) {
214
            	input.outer -= 1;
215
              }
127 pfowler 216
 
128 pfowler 217
        }
127 pfowler 218
 
128 pfowler 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) ) {
127 pfowler 224
        		input.inner += 1;
128 pfowler 225
        	} else if (rbi(pcInt.mask, PCINT3) ) {
127 pfowler 226
        		input.inner -= 1;
128 pfowler 227
        	}
127 pfowler 228
        }
128 pfowler 229
        // Clear the mask so we know we've dealt with it
230
        pcInt.mask = 0;
127 pfowler 231
 
232
}
233
 
128 pfowler 234
#ifdef _AVR_ATtiny4313_H_
235
ISR(PCINT_B_vect) {
236
#else
237
ISR(PCINT_vect) {
238
#endif
239
	pcInt.current = PINB;
240
	//doInt = 1;
127 pfowler 241
}
242
 
122 pfowler 243
ISR(TIMER0_OVF_vect) {
128 pfowler 244
    tmr0_ovf++;
122 pfowler 245
 
246
	// Clk/1 TCCR0B = (1<< CS00);
247
	//20.0Mhz, 1ms = 78ovf
248
	//16.5Mhz, 1ms = 64ovf
249
	//16.0Mhz, 1ms = 62ovf
250
	//12.0Mhz, 1ms = 46ovf
128 pfowler 251
	// 8.0Mhz, 1ms = 31ovf
252
    // 8.0Mhz, .5ms = 15ovf, 160r
122 pfowler 253
 
128 pfowler 254
	if (tmr0_ovf>=15) {
255
			systime++;
256
			tmr0_ovf = 0;
257
	}
127 pfowler 258
 
122 pfowler 259
}