xyControl  0.1
Quadrotor Flight Controller on AVR Basis
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Groups
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();
107  adcInit(AVCC);
108 
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) {
147  } else if (l == LED_RED1) {
149  } else if (l == LED_GREEN0) {
151  } else if (l == LED_GREEN1) {
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) {
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 }