xyControl
0.1
Quadrotor Flight Controller on AVR Basis
Main Page
Modules
Data Structures
Files
Examples
File List
Globals
•
All
Data Structures
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Groups
lib
xycontrol.c
Go to the documentation of this file.
1
/*
2
* xycontrol.c
3
*
4
* Copyright (c) 2013, Thomas Buck <xythobuz@me.com>
5
* All rights reserved.
6
*
7
* Redistribution and use in source and binary forms, with or without
8
* modification, are permitted provided that the following conditions
9
* are met:
10
*
11
* - Redistributions of source code must retain the above copyright notice,
12
* this list of conditions and the following disclaimer.
13
*
14
* - Redistributions in binary form must reproduce the above copyright
15
* notice, this list of conditions and the following disclaimer in the
16
* documentation and/or other materials provided with the distribution.
17
*
18
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
20
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
22
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
*/
30
#include <avr/io.h>
31
#include <stdint.h>
32
#include <stdlib.h>
33
#include <stdio.h>
34
#include <avr/interrupt.h>
35
#include <avr/pgmspace.h>
36
#include <avr/wdt.h>
37
38
#include <
serial.h
>
39
#include <
spi.h
>
40
#include <
time.h
>
41
#include <
xmem.h
>
42
#include <
xycontrol.h
>
43
#include <
twi.h
>
44
#include <
adc.h
>
45
#include <
uartMenu.h
>
46
#include <
tasks.h
>
47
#include <
config.h
>
48
59
char
PROGMEM
helpText
[] =
"Print this Help"
;
60
char
PROGMEM
resetText
[] =
"Reset MCU"
;
62
FILE
inFile
;
63
FILE
outFile
;
66
int
uartoutput
(
char
c, FILE *f) {
67
// Inject CR here, instead of in the serial library,
68
// so we can still do binary transfers with serialWrite()...
69
if
(c ==
'\n'
) {
70
for
(uint8_t i = 0; i <
serialAvailable
(); i++)
71
serialWrite
(i,
'\r'
);
72
}
73
if
(c !=
'\r'
) {
74
for
(uint8_t i = 0; i <
serialAvailable
(); i++)
75
serialWrite
(i, c);
76
}
77
return
0;
78
}
79
81
int
uartinput
(FILE *f) {
82
for
(;;) {
83
for
(uint8_t i = 0; i <
serialAvailable
(); i++) {
84
if
(
serialHasChar
(i)) {
85
return
serialGet
(i);
86
}
87
}
88
}
89
}
90
91
void
xyInit
(
void
) {
92
xmemInit
();
// Most important!
93
94
// LEDs
95
LED0DDR
|= (1 <<
LED0PIN
);
96
LED1DDR
|= (1 <<
LED1PIN
);
97
LED2DDR
|= (1 <<
LED2PIN
);
98
LED3DDR
|= (1 <<
LED3PIN
);
99
xyLed
(4, 1);
100
101
initSystemTimer
();
102
for
(uint8_t i = 0; i <
serialAvailable
(); i++) {
103
serialInit
(i,
BAUD
(38400, F_CPU));
104
}
105
twiInit
();
106
spiInit
(
MODE_0
,
SPEED_2
);
107
adcInit
(
AVCC
);
108
109
addMenuCommand
(
'q'
,
resetText
, &
xySelfReset
);
110
addMenuCommand
(
'h'
,
helpText
, &
uartMenuPrintHelp
);
111
addTask
(&
uartMenuTask
);
112
113
// fdevopen() is using malloc, so printf in a different
114
// memory bank will not work!
115
// fdevopen(&uartoutput, NULL); // stdout & stderr
116
// fdevopen(NULL, &uartinput); // stdin
117
// Instead we have the FILE structs as static variables
118
// and assign them to stdin, stdout and stderr
119
120
fdev_setup_stream(&
outFile
, &
uartoutput
, NULL, _FDEV_SETUP_WRITE);
121
fdev_setup_stream(&
inFile
, NULL, &
uartinput
, _FDEV_SETUP_READ);
122
stdin = &
inFile
;
123
stdout = &
outFile
;
124
stderr = &
outFile
;
125
126
sei();
127
}
128
134
void
xyLedInternal
(uint8_t v,
volatile
uint8_t *port, uint8_t pin) {
135
if
(v == 0) {
136
*port &= ~(1 << pin);
137
}
else
if
(v == 1) {
138
*port |= (1 << pin);
139
}
else
{
140
*port ^= (1 << pin);
141
}
142
}
143
144
void
xyLed
(uint8_t l, uint8_t v) {
145
if
(l ==
LED_RED0
) {
146
xyLedInternal
(v, &
LED0PORT
,
LED0PIN
);
147
}
else
if
(l ==
LED_RED1
) {
148
xyLedInternal
(v, &
LED1PORT
,
LED1PIN
);
149
}
else
if
(l ==
LED_GREEN0
) {
150
xyLedInternal
(v, &
LED2PORT
,
LED2PIN
);
151
}
else
if
(l ==
LED_GREEN1
) {
152
xyLedInternal
(v, &
LED3PORT
,
LED3PIN
);
153
}
else
if
(l ==
LED_ALL
){
154
xyLed
(0, v);
155
xyLed
(1, v);
156
xyLed
(2, v);
157
xyLed
(3, v);
158
}
else
if
(l ==
LED_BITMAP
) {
159
xyLed
(0, v & 0x01);
160
xyLed
(1, (v & 0x02) >> 1);
161
xyLed
(2, (v & 0x04) >> 2);
162
xyLed
(3, (v & 0x08) >> 3);
163
}
else
if
(l ==
LED_GREEN
) {
164
xyLed
(
LED_GREEN0
, v);
165
xyLed
(
LED_GREEN1
, v);
166
}
else
if
(l ==
LED_RED
) {
167
xyLed
(
LED_RED0
, v);
168
xyLed
(
LED_RED1
, v);
169
}
170
}
171
172
double
getVoltage
(
void
) {
173
adcStart
(
BATT_CHANNEL
);
174
while
(!
adcReady
());
175
uint16_t v =
adcGet
(0) *
BATT_MAX
;
176
return
((
double
)v / 1024.0);
177
}
178
179
void
xySelfReset
(
void
) {
180
wdt_enable(WDTO_15MS);
181
for
(;;);
182
}
183
184
int64_t
map
(int64_t value, int64_t oldMin, int64_t oldMax, int64_t newMin, int64_t newMax) {
185
return
(value - oldMin) * (newMax - newMin) / (oldMax - oldMin) + newMin;
186
}
Generated by
1.8.3.1