Rev 18 | Rev 22 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
12 | hbuss | 1 | /*####################################################################################### |
2 | MK3Mag 3D-Magnet sensor |
||
19 | killagreg | 3 | !!! THIS IS NOT FREE SOFTWARE !!! |
12 | hbuss | 4 | #######################################################################################*/ |
5 | // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
||
6 | // + Copyright (c) 05.2008 Holger Buss |
||
7 | // + Thanks to Ilja Fähnrich (P_Latzhalter) |
||
8 | // + Nur für den privaten Gebrauch |
||
9 | // + www.MikroKopter.com |
||
10 | // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
||
19 | killagreg | 11 | // + Die Portierung der Software (oder Teile davon) auf andere Systeme (ausser der Hardware von www.mikrokopter.de) ist nur |
12 | hbuss | 12 | // + mit unserer Zustimmung zulässig |
13 | // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
||
19 | killagreg | 14 | // + Es gilt für das gesamte Projekt (Hardware, Software, Binärfiles, Sourcecode und Dokumentation), |
15 | // + dass eine Nutzung (auch auszugsweise) nur für den privaten (nicht-kommerziellen) Gebrauch zulässig ist. |
||
12 | hbuss | 16 | // + AUSNAHME: Ein bei www.mikrokopter.de erworbener vorbestückter MK3Mag darf als Baugruppe auch in kommerziellen Systemen verbaut werden |
17 | // + Im Zweifelsfall bitte anfragen bei: info@mikrokopter.de |
||
18 | // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
||
19 | killagreg | 19 | // + Werden Teile des Quellcodes (mit oder ohne Modifikation) weiterverwendet oder veröffentlicht, |
12 | hbuss | 20 | // + unterliegen sie auch diesen Nutzungsbedingungen und diese Nutzungsbedingungen incl. Copyright müssen dann beiliegen |
21 | // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
||
22 | // + Sollte die Software (auch auszugesweise) oder sonstige Informationen des MikroKopter-Projekts |
||
23 | // + auf anderen Webseiten oder sonstigen Medien veröffentlicht werden, muss unsere Webseite "http://www.mikrokopter.de" |
||
24 | // + eindeutig als Ursprung verlinkt werden |
||
25 | // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
||
26 | // + Keine Gewähr auf Fehlerfreiheit, Vollständigkeit oder Funktion |
||
27 | // + Benutzung auf eigene Gefahr |
||
28 | // + Wir übernehmen keinerlei Haftung für direkte oder indirekte Personen- oder Sachschäden |
||
29 | // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
||
30 | // + Die Funktion printf_P() unterliegt ihrer eigenen Lizenz und ist hiervon nicht betroffen |
||
31 | // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
||
19 | killagreg | 32 | // + Redistributions of source code (with or without modifications) must retain the above copyright notice, |
12 | hbuss | 33 | // + this list of conditions and the following disclaimer. |
34 | // + * PORTING this software (or parts of it) to systems (other than hardware from www.mikrokopter.de) is NOT allowed |
||
35 | // + * Neither the name of the copyright holders nor the names of contributors may be used to endorse or promote products derived |
||
36 | // + from this software without specific prior written permission. |
||
19 | killagreg | 37 | // + * The use of this project (hardware, software, binary files, sources and documentation) is only permittet |
12 | hbuss | 38 | // + for non-commercial use (directly or indirectly) |
19 | killagreg | 39 | // + Commercial use (for excample: selling of MikroKopters, selling of PCBs, assembly, ...) is only permitted |
12 | hbuss | 40 | // + with our written permission |
41 | // + Exception: A preassembled MK3Mag, purchased from www.mikrokopter.de may be used as a part of commercial systems |
||
42 | // + In case of doubt please contact: info@MikroKopter.de |
||
19 | killagreg | 43 | // + * If sources or documentations are redistributet on other webpages, our webpage (http://www.MikroKopter.de) must be |
44 | // + clearly linked as origin |
||
12 | hbuss | 45 | // + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
46 | // + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
||
47 | // + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
||
48 | // + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
||
49 | // + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
||
50 | // + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
||
51 | // + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
||
52 | // + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
||
53 | // + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
||
54 | // + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
||
19 | killagreg | 55 | // + POSSIBILITY OF SUCH DAMAGE. |
12 | hbuss | 56 | // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
1 | ingob | 57 | #include <avr/io.h> |
19 | killagreg | 58 | #include <avr/interrupt.h> |
1 | ingob | 59 | #include <util/twi.h> |
19 | killagreg | 60 | #include "twislave.h" |
61 | #include "uart.h" |
||
1 | ingob | 62 | #include "main.h" |
19 | killagreg | 63 | #include "timer0.h" |
1 | ingob | 64 | |
19 | killagreg | 65 | #define TWI_BUS_ERR_1 0x00 |
66 | #define TWI_BUS_ERR_2 0xF8 |
||
1 | ingob | 67 | |
19 | killagreg | 68 | // Status Slave RX Mode |
69 | #define SR_SLA_ACK 0x60 |
||
70 | #define SR_LOST_ACK 0x68 |
||
71 | #define SR_GEN_CALL_ACK 0x70 |
||
72 | #define GEN_LOST_ACK 0x78 |
||
73 | #define SR_PREV_ACK 0x80 |
||
74 | #define SR_PREV_NACK 0x88 |
||
75 | #define GEN_PREV_ACK 0x90 |
||
76 | #define GEN_PREV_NACK 0x98 |
||
77 | #define STOP_CONDITION 0xA0 |
||
78 | #define REPEATED_START 0xA0 |
||
3 | ingob | 79 | |
19 | killagreg | 80 | // Status Slave TX mode |
81 | #define SW_SLA_ACK 0xA8 |
||
82 | #define SW_LOST_ACK 0xB0 |
||
83 | #define SW_DATA_ACK 0xB8 |
||
84 | #define SW_DATA_NACK 0xC0 |
||
85 | #define SW_LAST_ACK 0xC8 |
||
3 | ingob | 86 | |
87 | |||
19 | killagreg | 88 | uint8_t I2C_RxBufferSize, I2C_TxBufferSize; |
89 | uint8_t *I2C_TxBuffer, *I2C_RxBuffer; |
||
90 | uint8_t Tx_Idx = 0, Rx_Idx = 0, I2C_Direction; |
||
91 | uint8_t I2C_Command; |
||
92 | |||
93 | |||
94 | I2C_Heading_t I2C_Heading; |
||
95 | I2C_WriteAttitude_t I2C_WriteAttitude; |
||
96 | I2C_Mag_t I2C_Mag; |
||
97 | I2C_EEPROM_t I2C_ReadEEPROM, I2C_WriteEEPROM; |
||
98 | I2C_Version_t I2C_Version; |
||
99 | I2C_WriteCal_t I2C_WriteCal; |
||
100 | |||
101 | |||
102 | void I2C_Init(void) |
||
103 | { |
||
104 | uint8_t sreg = SREG; |
||
105 | cli(); |
||
106 | |||
107 | //SPI SCK/SCL and MISO/SDA are at put together on the same connector pin in the schematic |
||
108 | |||
109 | // set PB4 (SCK) and PB5 (MISO) as input pull up |
||
110 | DDRB &= ~((1<<DDB4)|(1<<DDB5)); |
||
111 | PORTB |= ((1<<PORTB4)|(1<<PORTB5)); |
||
112 | |||
113 | // set PC4 (SDA) and PC5 (SCL) as input pull up |
||
114 | DDRC &= ~((1<<DDC4)|(1<<DDC5)); |
||
115 | PORTC |= ((1<<PORTC4)|(1<<PORTC5)); |
||
116 | |||
117 | // set own address |
||
118 | TWAR = I2C_SLAVE_ADDRESS; // set own address |
||
119 | // TWI Control Register |
||
120 | // clear TWI interrupt flag (TWINT=1) |
||
121 | // enable TWI Acknowledge Bit (TWEA = 1) |
||
122 | // disable TWI START Condition Bit (TWSTA = 0), SLAVE |
||
123 | // disable TWI STOP Condition Bit (TWSTO = 0), SLAVE |
||
124 | // disable TWI Write Collision Flag (TWWC = 0) |
||
125 | // enable i2c (TWEN = 1) |
||
126 | // enable TWI Interrupt (TWIE = 1) |
||
1 | ingob | 127 | TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWIE) | (1<<TWEA); |
19 | killagreg | 128 | // update version info |
129 | I2C_Version.Major = VERSION_MAJOR; |
||
130 | I2C_Version.Minor = VERSION_MINOR; |
||
131 | I2C_Version.Compatible = I2C_PROTOCOL_COMP; |
||
132 | |||
133 | SREG = sreg; |
||
1 | ingob | 134 | } |
19 | killagreg | 135 | |
136 | |||
137 | |||
3 | ingob | 138 | #define TWCR_ACK TWCR = (1<<TWEN)|(1<<TWIE)|(1<<TWINT)|(1<<TWEA)|(0<<TWSTA)|(0<<TWSTO)|(0<<TWWC) |
19 | killagreg | 139 | |
1 | ingob | 140 | ISR (TWI_vect) |
19 | killagreg | 141 | { |
142 | // check event |
||
143 | switch (TWSR & 0xF8) |
||
144 | { |
||
145 | case SR_SLA_ACK: |
||
3 | ingob | 146 | Rx_Idx = 0; |
147 | TWCR_ACK; |
||
1 | ingob | 148 | return; |
19 | killagreg | 149 | |
150 | case SR_PREV_ACK: // data byte received |
||
151 | |||
152 | if (Rx_Idx == 0) |
||
153 | { |
||
154 | I2C_Command = TWDR; |
||
155 | |||
156 | switch(I2C_Command) |
||
157 | { |
||
158 | case I2C_CMD_VERSION: |
||
159 | I2C_TxBuffer = (uint8_t *)&I2C_Version; |
||
3 | ingob | 160 | I2C_TxBufferSize = sizeof(I2C_Version); |
161 | I2C_RxBufferSize = 0; |
||
19 | killagreg | 162 | break; |
163 | |||
164 | case I2C_CMD_WRITE_EEPROM: |
||
3 | ingob | 165 | I2C_TxBufferSize = 0; |
19 | killagreg | 166 | I2C_RxBuffer = (uint8_t *)&I2C_WriteEEPROM; |
3 | ingob | 167 | I2C_RxBufferSize = sizeof(I2C_WriteEEPROM); |
19 | killagreg | 168 | break; |
7 | hbuss | 169 | |
19 | killagreg | 170 | case I2C_CMD_WRITE_CAL: |
7 | hbuss | 171 | I2C_TxBufferSize = 0; |
19 | killagreg | 172 | I2C_RxBuffer = (uint8_t *)&I2C_WriteCal; |
7 | hbuss | 173 | I2C_RxBufferSize = sizeof(I2C_WriteCal); |
19 | killagreg | 174 | break; |
7 | hbuss | 175 | |
19 | killagreg | 176 | case I2C_CMD_READ_EEPROM: |
177 | I2C_TxBuffer = (uint8_t *)&I2C_ReadEEPROM.Content; |
||
3 | ingob | 178 | I2C_TxBufferSize = 2; |
19 | killagreg | 179 | I2C_RxBuffer = (uint8_t *)&I2C_ReadEEPROM; |
3 | ingob | 180 | I2C_RxBufferSize = 1; |
19 | killagreg | 181 | break; |
182 | |||
183 | case I2C_CMD_READ_MAG: |
||
184 | I2C_TxBuffer = (uint8_t *)&I2C_Mag; |
||
3 | ingob | 185 | I2C_TxBufferSize = sizeof(I2C_Mag); |
186 | I2C_RxBufferSize = 0; |
||
19 | killagreg | 187 | |
188 | I2C_Mag.MagX = MagnetX; |
||
189 | I2C_Mag.MagY = MagnetY; |
||
3 | ingob | 190 | I2C_Mag.MagZ = MagnetZ; |
19 | killagreg | 191 | break; |
192 | |||
193 | case I2C_CMD_READ_HEADING: |
||
194 | I2C_TxBuffer = (uint8_t *)&I2C_Heading; |
||
3 | ingob | 195 | I2C_TxBufferSize = sizeof(I2C_Heading); |
19 | killagreg | 196 | I2C_RxBuffer = (uint8_t *)&I2C_WriteAttitude; |
197 | I2C_RxBufferSize = sizeof(I2C_WriteAttitude); |
||
198 | // update heading from global variable |
||
3 | ingob | 199 | I2C_Heading.Heading = Heading; |
19 | killagreg | 200 | // copy current attitude from I2C rx buffer to uart rx buffer (this is used for the calulation of the heading) |
201 | ExternData.Attitude[NICK] = I2C_WriteAttitude.Nick; |
||
202 | ExternData.Attitude[ROLL] = I2C_WriteAttitude.Roll; |
||
203 | break; |
||
204 | } |
||
3 | ingob | 205 | } |
19 | killagreg | 206 | else // Rx_Idx != 0 |
3 | ingob | 207 | { |
19 | killagreg | 208 | // fill receiver buffer |
209 | if ((Rx_Idx - 1) < I2C_RxBufferSize) I2C_RxBuffer[Rx_Idx - 1] = TWDR; |
||
3 | ingob | 210 | } |
19 | killagreg | 211 | // next byte |
3 | ingob | 212 | Rx_Idx++; |
19 | killagreg | 213 | |
1 | ingob | 214 | I2C_Timeout = 500; |
19 | killagreg | 215 | TWCR_ACK; // send acknowledge |
1 | ingob | 216 | return; |
19 | killagreg | 217 | |
218 | case SW_SLA_ACK: // slave transmitter selected |
||
219 | // reset position in tx buffer |
||
3 | ingob | 220 | Tx_Idx = 0; |
19 | killagreg | 221 | // write first bte o tx buffer to the twi data register |
3 | ingob | 222 | if (I2C_TxBufferSize > 0) TWDR = I2C_TxBuffer[Tx_Idx++]; |
19 | killagreg | 223 | // send acknowledge |
224 | TWCR_ACK; |
||
225 | return; |
||
226 | |||
227 | case SW_DATA_ACK: // send data byte |
||
228 | // put next byte from tx buffer to twi data register |
||
3 | ingob | 229 | if (Tx_Idx < I2C_TxBufferSize) TWDR = I2C_TxBuffer[Tx_Idx++]; |
19 | killagreg | 230 | else TWDR = 0x00; |
231 | TWCR_ACK; // send acknowledge |
||
232 | return; |
||
233 | |||
234 | // clear Bus-Error |
||
1 | ingob | 235 | case TWI_BUS_ERR_2: |
19 | killagreg | 236 | TWCR |=(1<<TWSTO) | (1<<TWINT); |
237 | // clear Bus-Error |
||
1 | ingob | 238 | case TWI_BUS_ERR_1: |
19 | killagreg | 239 | TWCR |=(1<<TWSTO) | (1<<TWINT); |
240 | } |
||
241 | // clear interrupt flag (TWINT = 1) |
||
242 | // enable TWI Acknowledge Bit (TWEA = 1) |
||
243 | // enable TWI (TWEN = 1) |
||
244 | // enable TWI interrpt (TWIE = 1) |
||
245 | TWCR = (1<<TWEA) | (1<<TWINT) | (1<<TWEN) | (1<<TWIE); // TWI Reset |
||
1 | ingob | 246 | } |
247 | |||
248 |