xyControl  0.1
Quadrotor Flight Controller on AVR Basis
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Groups
gyro.c
Go to the documentation of this file.
1 /*
2  * gyro.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 <stdlib.h>
31 #include <stdint.h>
32 #include <avr/io.h>
33 
34 #include <twi.h>
35 #include <gyro.h>
36 #include <error.h>
37 #include <config.h>
38 
48 #define GYROREG_CTRL1 0x20
49 #define GYROREG_CTRL4 0x23
50 #define GYROREG_OUTXL 0x28
52 GyroRange gyroRange;
61 Error gyroWriteByte(uint8_t reg, uint8_t val) {
63  return TWI_NO_ANSWER;
64  }
65  if (twiWrite(reg)) {
66  return TWI_WRITE_ERROR;
67  }
68  if (twiWrite(val)) {
69  return TWI_WRITE_ERROR;
70  }
71  twiStop();
72  return SUCCESS;
73 }
74 
76  uint8_t v;
77  switch (r) {
78  case r250DPS:
79  v = 0x00;
80  break;
81  case r500DPS:
82  v = 0x10;
83  break;
84  case r2000DPS:
85  v = 0x20;
86  break;
87  default:
88  return ARGUMENT_ERROR;
89  }
90  gyroRange = r;
92  if (e != SUCCESS) {
93  return e;
94  }
96  return e;
97 }
98 
100  // Simple Software Low-Pass
101  static double gyroSumX = 0, gyroSumY = 0, gyroSumZ = 0;
102  static double gyroFilterX = 0, gyroFilterY = 0, gyroFilterZ = 0;
103 
104  if (v == NULL) {
105  return ARGUMENT_ERROR;
106  }
108  return TWI_NO_ANSWER;
109  }
110  if (twiWrite(GYROREG_OUTXL | 0x80)) { // Auto Increment
111  return TWI_WRITE_ERROR;
112  }
114  return TWI_NO_ANSWER;
115  }
116 
117  uint8_t xl = twiReadAck();
118  uint8_t xh = twiReadAck();
119  uint8_t yl = twiReadAck();
120  uint8_t yh = twiReadAck();
121  uint8_t zl = twiReadAck();
122  uint8_t zh = twiReadNak();
123 
124  int16_t x = *(int8_t *)(&xh);
125  x *= (1 << 8);
126  x |= xl;
127 
128  int16_t y = *(int8_t *)(&yh);
129  y *= (1 << 8);
130  y |= yl;
131 
132  int16_t z = *(int8_t *)(&zh);
133  z *= (1 << 8);
134  z |= zl;
135 
136  switch (gyroRange) {
137  case r250DPS:
138  v->x = (((double)x) * 250 / 0x8000);
139  v->y = (((double)y) * 250 / 0x8000);
140  v->z = (((double)z) * 250 / 0x8000);
141  break;
142  case r500DPS:
143  v->x = (((double)x) * 500 / 0x8000);
144  v->y = (((double)y) * 500 / 0x8000);
145  v->z = (((double)z) * 500 / 0x8000);
146  break;
147  case r2000DPS:
148  v->x = (((double)x) * 2000 / 0x8000);
149  v->y = (((double)y) * 2000 / 0x8000);
150  v->z = (((double)z) * 2000 / 0x8000);
151  break;
152  default:
153  return ARGUMENT_ERROR;
154  }
155 
156  gyroSumX = gyroSumX - gyroFilterX + v->x;
157  gyroFilterX = gyroSumX / GYROFILTERFACTOR;
158  v->x = gyroFilterX;
159 
160  gyroSumY = gyroSumY - gyroFilterY + v->y;
161  gyroFilterY = gyroSumY / GYROFILTERFACTOR;
162  v->y = gyroFilterY;
163 
164  gyroSumZ = gyroSumZ - gyroFilterZ + v->z;
165  gyroFilterZ = gyroSumZ / GYROFILTERFACTOR;
166  v->z = gyroFilterZ;
167 
168  return SUCCESS;
169 }