summaryrefslogtreecommitdiffstats
path: root/source/AVR_Studio/Soccer/hal/board.c
blob: d60834b4c213a8db3f8df7b3efe7e5912f7dd156 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
#include "board.h"

static int beepFreq = 0;

Board::Board() {
	// Pin 1-6 sind ausgänge, 0 und 7 eingänge
	DDRA = (1 << PA1) | (1 << PA2) | (1 << PA3) | (1 << PA4) | (1 << PA5) | (1 << PA6);
	PORTA = 0; // Alle Low, kein Pollup

	// Alle Ausgänge
	DDRB = (1 << PB0) | (1 << PB1) | (1 << PB2) | (1 << PB3) | (1 << PB4) | (1 << PB5) | (1 << PB6)  | (1 << PB7);
	PORTB = (1 << PB1); // Alle Low bis PB1 , kein Pollup

	// Alle Ausgänge
	DDRC = (1 << PC0) | (1 << PC1) | (1 << PC2) | (1 << PC3) | (1 << PC4) | (1 << PC5) | (1 << PC6)  | (1 << PC7);
	PORTC = 0; // Alle Low, kein Pollup

	// Alle Ausgänge bis auf PD0+1(I2C) + 2+3(RS232)
	DDRD = (1 << PD2) | (1 << PD3) | (1 << PD4) | (1 << PD5) | (1 << PD6)  | (1 << PD7);
	PORTD = (1 << PD0) | (1 << PD1); // Pollup-Widerstand an PD0+1 aktivieren

	// PE5 ist eingang
	DDRE = (1 << PE0) | (1 << PE1) | (1 << PE2) | (1 << PE3) | (1 << PE4) | (1 << PE6)  | (1 << PE7);
	PORTE = 0; // Alle Low, kein Pollup

	// Alle Eingänge mit Pollup
	DDRF = 0;
	PORTF = (1 << PF0) | (1 << PF1) | (1 << PF2) | (1 << PF3) | (1 << PF4) | (1 << PF5) | (1 << PF6)  | (1 << PF7);

	// Alle Ausgänge, PG0 und PG1 high
	DDRG = (1 << PG0) | (1 << PG1) | (1 << PG2) | (1 << PG3) | (1 << PG4); 
	PORTG = (1 << PG0) | (1 << PG1);	

	// aktiviere Kanal A+C auf PWM1 mit 8Bit
	//TCCR1A = (1<< COM1A1) | (1<< COM1C1) | (1<< WGM10);
	//TCCR1B = (1<<ICNC1) | (1<<CS12) | (1<<CS10); // set clock/prescaler 1/1024 -> enable counter

	// aktiviere Kanal A+B auf PWM3 mit 8Bit
	//TCCR3A = (1<< COM3A1) | (1<< COM3B1) | (1<< WGM10);
	//TCCR3B =  (1<<ICNC3) | (1<<CS32) | (1<<CS30); // set clock/prescaler 1/1024 -> enable counter

	// Schalte Motoren auf 0
	motor(0,0);
	motor(1,0);
	motor(2,0);
	motor(3,0);

	// Uart-Interface einschalten
	uart1_init( 10); // 9600 BAUD bei 16MHz Atmel

	// aktiviere interrupt
	sei();
}

Board::~Board() {

}

// Gibt einen Analogen Wert zurück
int Board::GetADC(uint8_t channel) {
	uint8_t i;
	uint16_t result = 0;
	
	// Den ADC aktivieren und Teilungsfaktor auf 64 stellen
	ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1);

	// Kanal des Multiplexers waehlen
	ADMUX = channel;
	// Interne Referenzspannung verwenden (also 2,56 V)
	ADMUX |= (1<<REFS1) | (1<<REFS0);
	
	// Den ADC initialisieren und einen sog. Dummyreadout machen
	ADCSRA |= (1<<ADSC);
	while(ADCSRA & (1<<ADSC));
	
	// Jetzt 3x die analoge Spannung and Kanal channel auslesen
	// und dann Durchschnittswert ausrechnen.
	for(i=0; i<3; i++) {
		// Eine Wandlung
		ADCSRA |= (1<<ADSC);
		// Auf Ergebnis warten...
		while(ADCSRA & (1<<ADSC));
		
		result += ADCW;
	}
	
	// ADC wieder deaktivieren
	ADCSRA &= ~(1<<ADEN);
	
	result /= 3;
	
	return result;
}

void Board::beep(int freq) {
	beepFreq = freq;
}

void Board::ledOff() {
	PORTB |= (1 << PB1); // set bit
}

void Board::ledOn() {
	PORTB &= ~(1 << PB1); // clear bit
}

void Board::led(bool status) {
	if(status) ledOn();
	else ledOff();
}


void Board::motor(int i, int speed)
{
	if((i < 0) || (i > 3)) return;
	const int OFFSET = 40; // Motor does not work with very low ratio
	const int PWM_MAX = 255;

	int pwm = abs(speed)+OFFSET;
	if(pwm > PWM_MAX) pwm = PWM_MAX;

	if(i == 0)
	{
		MOTOR0_PWM = pwm;
		if(speed > 0)
		{
			PORTD |= (1 << 5);//In 1 ein
			PORTD &= ~(1 << 4);//In 2 aus
		}
		else if(speed < 0)
		{
			PORTD |= (1 << 4);//In 2 ein
			PORTD &= ~(1 << 5);//In 1 aus
		}
		else
		{
			PORTD |= (1 << 4);//In 2 ein
			PORTD |= (1 << 5);//In 1 ein
		}
	}
	else if(i == 1)
	{
		MOTOR1_PWM = pwm;
		if(speed > 0)
		{
			PORTD |= (1 << 6);//In 1 ein
			PORTD &= ~(1 << 7);//In 2 aus
		}
		else if(speed < 0)
		{
			PORTD |= (1 << 7);//In 2 ein
			PORTD &= ~(1 << 6);//In 1 aus
		}
		else
		{
			PORTD |= (1 << 6);//In 2 ein
			PORTD |= (1 << 7);//In 1 ein
		}
	}
	else if(i == 2)
	{
		MOTOR2_PWM = pwm;
		if(speed > 0)
		{
			PORTB |= (1 << 0);//In 1 ein
			PORTB &= ~(1 << 1);//In 2 aus
		}
		else if(speed < 0)
		{
			PORTB |= (1 << 1);//In 2 ein
			PORTB &= ~(1 << 0);//In 1 aus
		}
		else
		{
			PORTB |= (1 << 1);//In 2 ein
			PORTB |= (1 << 0);//In 1 ein
		}
	}
	else if(i == 3)
	{
		DRIBBLER_PWM = pwm;
		if(speed > 0)
		{
			PORTB |= (1 << 2);//In 1 ein
			PORTB &= ~(1 << 3);//In 2 aus
		}
		else if(speed < 0)
		{
			PORTB |= (1 << 3);//In 2 ein
			PORTB &= ~(1 << 2);//In 1 aus
		}
		else
		{
			PORTB |= (1 << 2);//In 2 ein
			PORTB |= (1 << 3);//In 1 ein
		}
	}
}

//PWM routine für den Beeper
ISR (TIMER0_OVF_vect)
{
	static int counter = 255;

	if(counter > beepFreq/2) PORTG |= (1<<BEEPER_PIN);
	else PORTG &= ~(1<<BEEPER_PIN);

	if (counter==0) counter = 255;
	else counter--;
}