Subversion Repositories MK3Mag

Rev

Rev 26 | Rev 28 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 26 Rev 27
1
/*#######################################################################################
1
/*#######################################################################################
2
MK3Mag 3D-Magnet sensor
2
MK3Mag 3D-Magnet sensor
3
!!! THIS IS NOT FREE SOFTWARE !!!
3
!!! THIS IS NOT FREE SOFTWARE !!!
4
#######################################################################################*/
4
#######################################################################################*/
5
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
5
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
6
// + Copyright (c) 05.2008 Holger Buss
6
// + Copyright (c) 05.2008 Holger Buss
7
// + Thanks to Ilja Fähnrich (P_Latzhalter)
7
// + Thanks to Ilja Fähnrich (P_Latzhalter)
8
// + Nur für den privaten Gebrauch
8
// + Nur für den privaten Gebrauch
9
// + www.MikroKopter.com
9
// + www.MikroKopter.com
10
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
10
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
11
// + Die Portierung der Software (oder Teile davon) auf andere Systeme (ausser der Hardware von www.mikrokopter.de) ist nur
11
// + Die Portierung der Software (oder Teile davon) auf andere Systeme (ausser der Hardware von www.mikrokopter.de) ist nur
12
// + mit unserer Zustimmung zulässig
12
// + mit unserer Zustimmung zulässig
13
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
13
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
14
// + Es gilt für das gesamte Projekt (Hardware, Software, Binärfiles, Sourcecode und Dokumentation),
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.
15
// + dass eine Nutzung (auch auszugsweise) nur für den privaten (nicht-kommerziellen) Gebrauch zulässig ist.
16
// + AUSNAHME: Ein bei www.mikrokopter.de erworbener vorbestückter MK3Mag darf als Baugruppe auch in kommerziellen Systemen verbaut werden
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
17
// + Im Zweifelsfall bitte anfragen bei: info@mikrokopter.de
18
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
18
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
19
// + Werden Teile des Quellcodes (mit oder ohne Modifikation) weiterverwendet oder veröffentlicht,
19
// + Werden Teile des Quellcodes (mit oder ohne Modifikation) weiterverwendet oder veröffentlicht,
20
// + unterliegen sie auch diesen Nutzungsbedingungen und diese Nutzungsbedingungen incl. Copyright müssen dann beiliegen
20
// + unterliegen sie auch diesen Nutzungsbedingungen und diese Nutzungsbedingungen incl. Copyright müssen dann beiliegen
21
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
21
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
22
// + Sollte die Software (auch auszugesweise) oder sonstige Informationen des MikroKopter-Projekts
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"
23
// + auf anderen Webseiten oder sonstigen Medien veröffentlicht werden, muss unsere Webseite "http://www.mikrokopter.de"
24
// + eindeutig als Ursprung verlinkt werden
24
// + eindeutig als Ursprung verlinkt werden
25
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
25
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
26
// + Keine Gewähr auf Fehlerfreiheit, Vollständigkeit oder Funktion
26
// + Keine Gewähr auf Fehlerfreiheit, Vollständigkeit oder Funktion
27
// + Benutzung auf eigene Gefahr
27
// + Benutzung auf eigene Gefahr
28
// + Wir übernehmen keinerlei Haftung für direkte oder indirekte Personen- oder Sachschäden
28
// + Wir übernehmen keinerlei Haftung für direkte oder indirekte Personen- oder Sachschäden
29
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
29
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
30
// + Die Funktion printf_P() unterliegt ihrer eigenen Lizenz und ist hiervon nicht betroffen
30
// + Die Funktion printf_P() unterliegt ihrer eigenen Lizenz und ist hiervon nicht betroffen
31
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
31
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
32
// + Redistributions of source code (with or without modifications) must retain the above copyright notice,
32
// + Redistributions of source code (with or without modifications) must retain the above copyright notice,
33
// + this list of conditions and the following disclaimer.
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
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
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.
36
// +     from this software without specific prior written permission.
37
// +   * The use of this project (hardware, software, binary files, sources and documentation) is only permittet
37
// +   * The use of this project (hardware, software, binary files, sources and documentation) is only permittet
38
// +     for non-commercial use (directly or indirectly)
38
// +     for non-commercial use (directly or indirectly)
39
// +     Commercial use (for excample: selling of MikroKopters, selling of PCBs, assembly, ...) is only permitted
39
// +     Commercial use (for excample: selling of MikroKopters, selling of PCBs, assembly, ...) is only permitted
40
// +     with our written permission
40
// +     with our written permission
41
// +     Exception: A preassembled MK3Mag, purchased from www.mikrokopter.de may be used as a part of commercial systems
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
42
// +     In case of doubt please contact: info@MikroKopter.de
43
// +   * If sources or documentations are redistributet on other webpages, our webpage (http://www.MikroKopter.de) must be
43
// +   * If sources or documentations are redistributet on other webpages, our webpage (http://www.MikroKopter.de) must be
44
// +     clearly linked as origin
44
// +     clearly linked as origin
45
// +  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
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
46
// +  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
47
// +  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
47
// +  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
48
// +  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
48
// +  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
49
// +  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
49
// +  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
50
// +  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
50
// +  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
51
// +  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
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
52
// +  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
53
// +  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
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
54
// +  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
55
// +  POSSIBILITY OF SUCH DAMAGE.
55
// +  POSSIBILITY OF SUCH DAMAGE.
56
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
56
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
57
#include <avr/io.h>
57
#include <avr/io.h>
58
#include <avr/interrupt.h>
58
#include <avr/interrupt.h>
59
#include <avr/wdt.h>
59
#include <avr/wdt.h>
60
#include "main.h"
60
#include "main.h"
61
#include "uart.h"
61
#include "uart.h"
62
#include "timer0.h"
62
#include "timer0.h"
63
#include "twislave.h"
63
#include "twislave.h"
64
 
64
 
65
 
65
 
66
#define FALSE   0
66
#define FALSE   0
67
#define TRUE    1
67
#define TRUE    1
68
 
68
 
69
#define TXD_BUFFER_LEN  100
69
#define TXD_BUFFER_LEN  100
70
#define RXD_BUFFER_LEN  100
70
#define RXD_BUFFER_LEN  100
71
 
71
 
72
volatile uint8_t txd_buffer[TXD_BUFFER_LEN];
72
volatile uint8_t txd_buffer[TXD_BUFFER_LEN];
73
volatile uint8_t rxd_buffer_locked = FALSE;
73
volatile uint8_t rxd_buffer_locked = FALSE;
74
volatile uint8_t rxd_buffer[RXD_BUFFER_LEN];
74
volatile uint8_t rxd_buffer[RXD_BUFFER_LEN];
75
volatile uint8_t txd_complete = TRUE;
75
volatile uint8_t txd_complete = TRUE;
76
volatile uint8_t ReceivedBytes = 0;
76
volatile uint8_t ReceivedBytes = 0;
77
 
77
 
78
#define VERSION_INFO    0x01
78
#define VERSION_INFO    0x01
79
#define DEBUG_DATA              0x02
79
#define DEBUG_DATA              0x02
80
#define DEBUG_LABEL             0x04
80
#define DEBUG_LABEL             0x04
81
#define COMPASS_HEADING 0x08
81
#define COMPASS_HEADING 0x08
82
 
82
 
83
uint8_t RequestFlags = 0x00;
83
uint8_t RequestFlags = 0x00;
84
uint8_t RequestDebugLabel = 0;
84
uint8_t RequestDebugLabel = 0;
85
 
85
 
86
 
86
 
87
uint8_t MySlaveAddr = 0;
87
uint8_t MySlaveAddr = 0;
88
 
88
 
89
 
89
 
90
struct DebugOut_t               DebugOut;
90
struct DebugOut_t               DebugOut;
91
struct ExternData_t             ExternData;
91
struct ExternData_t             ExternData;
92
struct ExternControl_t  ExternControl;
92
struct ExternControl_t  ExternControl;
93
struct VersionInfo_t    VersionInfo;
93
struct VersionInfo_t    VersionInfo;
94
 
94
 
95
uint16_t  Debug_Timer;
95
uint16_t  Debug_Timer;
96
 
96
 
97
const uint8_t ANALOG_LABEL[32][16] =
97
const uint8_t ANALOG_LABEL[32][16] =
98
{
98
{
99
   //1234567890123456
99
   //1234567890123456
100
    "Magnet X        ", //0
100
    "Magnet X        ", //0
101
    "Magnet Y        ",
101
    "Magnet Y        ",
102
    "Magnet Z        ",
102
    "Magnet Z        ",
103
    "Raw X           ",
103
    "Raw X           ",
104
    "Raw Y           ",
104
    "Raw Y           ",
105
    "Raw Z           ", //5
105
    "Raw Z           ", //5
106
    "Attitude Nick   ",
106
    "Attitude Nick   ",
107
    "Attitude Roll   ",
107
    "Attitude Roll   ",
108
    "XOffset         ",
108
    "XOffset         ",
109
    "XRange          ",
109
    "XRange          ",
110
    "YOffset         ", //10
110
    "YOffset         ", //10
111
    "YRange          ",
111
    "YRange          ",
112
    "ZOffset         ",
112
    "ZOffset         ",
113
    "ZRange          ",
113
    "ZRange          ",
114
    "Calstate        ",
114
    "Calstate        ",
115
    "Heading         ", //15
115
    "Heading         ", //15
116
    "User0           ",
116
    "User0           ",
117
    "User1           ",
117
    "User1           ",
118
    "Analog18        ",
118
    "Analog18        ",
119
    "Analog19        ",
119
    "Analog19        ",
120
    "Analog20        ", //20
120
    "Analog20        ", //20
121
    "Analog21        ",
121
    "Analog21        ",
122
    "Analog22        ",
122
    "Analog22        ",
123
    "Analog23        ",
123
    "Analog23        ",
124
    "Analog24        ",
124
    "Analog24        ",
125
    "Analog25        ", //25
125
    "Analog25        ", //25
126
    "Analog26        ",
126
    "Analog26        ",
127
    "Analog27        ",
127
    "Analog27        ",
128
    "Analog28        ",
128
    "Analog28        ",
129
    "Analog29        ",
129
    "Analog29        ",
130
    "I2C Error       ", //30
130
    "I2C Error       ", //30
131
    "I2C Okay        "
131
    "I2C Okay        "
132
};
132
};
133
 
133
 
134
 
134
 
135
/****************************************************************/
135
/****************************************************************/
136
/*              Initialization of the USART0                    */
136
/*              Initialization of the USART0                    */
137
/****************************************************************/
137
/****************************************************************/
138
void USART0_Init (void)
138
void USART0_Init (void)
139
{
139
{
140
        uint16_t ubrr = (uint16_t) ((uint32_t) SYSCLK/(8 * BAUD_RATE) - 1);
140
        uint16_t ubrr = (uint16_t) ((uint32_t) SYSCLK/(8 * BAUD_RATE) - 1);
141
 
141
 
142
        // disable all interrupts before configuration
142
        // disable all interrupts before configuration
143
        cli();
143
        cli();
144
 
144
 
145
        // disable RX-Interrupt
145
        // disable RX-Interrupt
146
        UCSR0B &= ~(1 << RXCIE0);
146
        UCSR0B &= ~(1 << RXCIE0);
147
        // disable TX-Interrupt
147
        // disable TX-Interrupt
148
        UCSR0B &= ~(1 << TXCIE0);
148
        UCSR0B &= ~(1 << TXCIE0);
149
 
149
 
150
        // set direction of RXD0 and TXD0 pins
150
        // set direction of RXD0 and TXD0 pins
151
 
151
 
152
        // set RXD0 (PD0) as an input pin tristate
152
        // set RXD0 (PD0) as an input pin tristate
153
        DDRD  &= ~(1 << DDD0);
153
        DDRD  &= ~(1 << DDD0);
154
        PORTD &= ~(1 << PORTD0);
154
        PORTD &= ~(1 << PORTD0);
155
        // set TXD0 (PD1) as an output pin
155
        // set TXD0 (PD1) as an output pin
156
        DDRD  |= (1 << DDD1);
156
        DDRD  |= (1 << DDD1);
157
        PORTD &= ~(1 << PORTD1);
157
        PORTD &= ~(1 << PORTD1);
158
 
158
 
159
 
159
 
160
        // USART0 Baud Rate Register
160
        // USART0 Baud Rate Register
161
        // set clock divider
161
        // set clock divider
162
        UBRR0H = (uint8_t)(ubrr >> 8);
162
        UBRR0H = (uint8_t)(ubrr >> 8);
163
        UBRR0L = (uint8_t)ubrr;
163
        UBRR0L = (uint8_t)ubrr;
164
 
164
 
165
        // USART0 Control and Status Register A, B, C
165
        // USART0 Control and Status Register A, B, C
166
 
166
 
167
        // enable double speed operation
167
        // enable double speed operation
168
        UCSR0A |= (1 << U2X0);
168
        UCSR0A |= (1 << U2X0);
169
 
169
 
170
        // set asynchronous mode
170
        // set asynchronous mode
171
        UCSR0C &= ~(1 << UMSEL01);
171
        UCSR0C &= ~(1 << UMSEL01);
172
        UCSR0C &= ~(1 << UMSEL00);
172
        UCSR0C &= ~(1 << UMSEL00);
173
        // no parity
173
        // no parity
174
        UCSR0C &= ~(1 << UPM01);
174
        UCSR0C &= ~(1 << UPM01);
175
        UCSR0C &= ~(1 << UPM00);
175
        UCSR0C &= ~(1 << UPM00);
176
        // 1 stop bit
176
        // 1 stop bit
177
        UCSR0C &= ~(1 << USBS0);
177
        UCSR0C &= ~(1 << USBS0);
178
        // 8-bit
178
        // 8-bit
179
        UCSR0B &= ~(1 << UCSZ02);
179
        UCSR0B &= ~(1 << UCSZ02);
180
        UCSR0C |=  (1 << UCSZ01);
180
        UCSR0C |=  (1 << UCSZ01);
181
        UCSR0C |=  (1 << UCSZ00);
181
        UCSR0C |=  (1 << UCSZ00);
182
 
182
 
183
        // enable receiver and transmitter
183
        // enable receiver and transmitter
184
        UCSR0B |= (1 << RXEN0);
184
        UCSR0B |= (1 << RXEN0);
185
        UCSR0B |= (1 << TXEN0);
185
        UCSR0B |= (1 << TXEN0);
186
 
186
 
187
        // flush receive buffer
187
        // flush receive buffer
188
        while ( UCSR0A & (1<<RXC0) ) UDR0;
188
        while ( UCSR0A & (1<<RXC0) ) UDR0;
189
 
189
 
190
        // enable RX-Interrupt
190
        // enable RX-Interrupt
191
        UCSR0B |= (1 << RXCIE0);
191
        UCSR0B |= (1 << RXCIE0);
192
        // enable TX-Interrupt
192
        // enable TX-Interrupt
193
        UCSR0B |= (1 << TXCIE0);
193
        UCSR0B |= (1 << TXCIE0);
194
 
194
 
195
        rxd_buffer_locked = FALSE;
195
        rxd_buffer_locked = FALSE;
196
        txd_complete = TRUE;
196
        txd_complete = TRUE;
197
 
197
 
198
 
198
 
199
        VersionInfo.Major = VERSION_MAJOR;
199
        VersionInfo.Major = VERSION_MAJOR;
200
        VersionInfo.Minor = VERSION_MINOR;
200
        VersionInfo.Minor = VERSION_MINOR;
201
    VersionInfo.PCCompatible = VERSION_COMPATIBLE;
201
    VersionInfo.PCCompatible = VERSION_COMPATIBLE;
202
 
202
 
203
 
203
 
204
    // Version beim Start ausgeben (nicht schön, aber geht... )
204
    // Version beim Start ausgeben (nicht schön, aber geht... )
205
        uart_putchar ('\n');
205
        uart_putchar ('\n');
206
        uart_putchar ('C');
206
        uart_putchar ('C');
207
        uart_putchar ('P');
207
        uart_putchar ('P');
208
        uart_putchar (':');
208
        uart_putchar (':');
209
        uart_putchar ('V');
209
        uart_putchar ('V');
210
        uart_putchar (0x30 + VERSION_MAJOR);
210
        uart_putchar (0x30 + VERSION_MAJOR);
211
        uart_putchar ('.');uart_putchar (0x30 + VERSION_MINOR/10);
211
        uart_putchar ('.');uart_putchar (0x30 + VERSION_MINOR/10);
212
        uart_putchar (0x30 + VERSION_MINOR%10);
212
        uart_putchar (0x30 + VERSION_MINOR%10);
213
    uart_putchar ('\n');
213
    uart_putchar ('\n');
214
}
214
}
215
 
215
 
216
// ---------------------------------------------------------------------------------
216
// ---------------------------------------------------------------------------------
217
void USART0_EnableTXD(void)
217
void USART0_EnableTXD(void)
218
{
218
{
219
        DDRD |= (1<<DDD1);                      // set TXD pin as output
219
        DDRD |= (1<<DDD1);                      // set TXD pin as output
220
        PORTD &= ~(1 << PORTD1);
220
        PORTD &= ~(1 << PORTD1);
221
        UCSR0B |= (1 << TXEN0);         // enable TX in USART
221
        UCSR0B |= (1 << TXEN0);         // enable TX in USART
222
        UCSR0B |= (1 << TXCIE0);        // disable TX-Interrupt
222
        UCSR0B |= (1 << TXCIE0);        // disable TX-Interrupt
223
}
223
}
224
 
224
 
225
// ---------------------------------------------------------------------------------
225
// ---------------------------------------------------------------------------------
226
void USART0_DisableTXD(void)
226
void USART0_DisableTXD(void)
227
{
227
{
228
        while(!txd_complete){ };
228
        while(!txd_complete){ };
229
 
229
 
230
        UCSR0B &= ~(1 << TXCIE0);   // disable TX-Interrupt
230
        UCSR0B &= ~(1 << TXCIE0);   // disable TX-Interrupt
231
        UCSR0B &= ~(1 << TXEN0);        // disable TXD in USART
231
        UCSR0B &= ~(1 << TXEN0);        // disable TXD in USART
232
        DDRD &= ~(1<<DDD1);             // set TXD pin as input
232
        DDRD &= ~(1<<DDD1);             // set TXD pin as input
233
        PORTD &= ~(1 << PORTD1);
233
        PORTD &= ~(1 << PORTD1);
234
}
234
}
235
 
235
 
236
/****************************************************************/
236
/****************************************************************/
237
/*               USART0 transmitter ISR                         */
237
/*               USART0 transmitter ISR                         */
238
/****************************************************************/
238
/****************************************************************/
239
ISR(USART_TX_vect)
239
ISR(USART_TX_vect)
240
{
240
{
241
        static uint16_t ptr_txd_buffer = 0;
241
        static uint16_t ptr_txd_buffer = 0;
242
        uint8_t tmp_tx;
242
        uint8_t tmp_tx;
243
        if(!txd_complete) // transmission not completed
243
        if(!txd_complete) // transmission not completed
244
        {
244
        {
245
                ptr_txd_buffer++;                    // die [0] wurde schon gesendet
245
                ptr_txd_buffer++;                    // die [0] wurde schon gesendet
246
                tmp_tx = txd_buffer[ptr_txd_buffer];
246
                tmp_tx = txd_buffer[ptr_txd_buffer];
247
                // if terminating character or end of txd buffer was reached
247
                // if terminating character or end of txd buffer was reached
248
                if((tmp_tx == '\r') || (ptr_txd_buffer == TXD_BUFFER_LEN))
248
                if((tmp_tx == '\r') || (ptr_txd_buffer == TXD_BUFFER_LEN))
249
                {
249
                {
250
                        ptr_txd_buffer = 0; // reset txd pointer
250
                        ptr_txd_buffer = 0; // reset txd pointer
251
                        txd_complete = TRUE; // stop transmission
251
                        txd_complete = TRUE; // stop transmission
252
                }
252
                }
253
                UDR0 = tmp_tx; // send current byte will trigger this ISR again
253
                UDR0 = tmp_tx; // send current byte will trigger this ISR again
254
        }
254
        }
255
        // transmission completed
255
        // transmission completed
256
        else ptr_txd_buffer = 0;
256
        else ptr_txd_buffer = 0;
257
}
257
}
258
 
258
 
259
/****************************************************************/
259
/****************************************************************/
260
/*               USART0 receiver ISR                            */
260
/*               USART0 receiver ISR                            */
261
/****************************************************************/
261
/****************************************************************/
262
ISR(USART_RX_vect)
262
ISR(USART_RX_vect)
263
{
263
{
264
        static uint16_t crc;
264
        static uint16_t crc;
265
        uint8_t crc1, crc2;
265
        uint8_t crc1, crc2;
266
        uint8_t c;
266
        uint8_t c;
267
        static uint8_t ptr_rxd_buffer = 0;
267
        static uint8_t ptr_rxd_buffer = 0;
268
 
268
 
269
        c = UDR0;  // catch the received byte
269
        c = UDR0;  // catch the received byte
270
 
270
 
271
        if(rxd_buffer_locked) return; // if rxd buffer is locked immediately return
271
        if(rxd_buffer_locked) return; // if rxd buffer is locked immediately return
272
 
272
 
273
        // the rxd buffer is unlocked
273
        // the rxd buffer is unlocked
274
        if((ptr_rxd_buffer == 0) && (c == '#')) // if rxd buffer is empty and syncronisation character is received
274
        if((ptr_rxd_buffer == 0) && (c == '#')) // if rxd buffer is empty and syncronisation character is received
275
        {
275
        {
276
                rxd_buffer[ptr_rxd_buffer++] = c; // copy 1st byte to buffer
276
                rxd_buffer[ptr_rxd_buffer++] = c; // copy 1st byte to buffer
277
                crc = c; // init crc
277
                crc = c; // init crc
278
        }
278
        }
279
        #if 0
279
        #if 0
280
        else if (ptr_rxd_buffer == 1) // handle address
280
        else if (ptr_rxd_buffer == 1) // handle address
281
        {
281
        {
282
                rxd_buffer[ptr_rxd_buffer++] = c; // copy byte to rxd buffer
282
                rxd_buffer[ptr_rxd_buffer++] = c; // copy byte to rxd buffer
283
                crc += c; // update crc
283
                crc += c; // update crc
284
        }
284
        }
285
        #endif
285
        #endif
286
        else if (ptr_rxd_buffer < RXD_BUFFER_LEN) // collect incomming bytes
286
        else if (ptr_rxd_buffer < RXD_BUFFER_LEN) // collect incomming bytes
287
        {
287
        {
288
                if(c != '\r') // no termination character
288
                if(c != '\r') // no termination character
289
                {
289
                {
290
                        rxd_buffer[ptr_rxd_buffer++] = c; // copy byte to rxd buffer
290
                        rxd_buffer[ptr_rxd_buffer++] = c; // copy byte to rxd buffer
291
                        crc += c; // update crc
291
                        crc += c; // update crc
292
                }
292
                }
293
                else // termination character was received
293
                else // termination character was received
294
                {
294
                {
295
                        // the last 2 bytes are no subject for checksum calculation
295
                        // the last 2 bytes are no subject for checksum calculation
296
                        // they are the checksum itself
296
                        // they are the checksum itself
297
                        crc -= rxd_buffer[ptr_rxd_buffer-2];
297
                        crc -= rxd_buffer[ptr_rxd_buffer-2];
298
                        crc -= rxd_buffer[ptr_rxd_buffer-1];
298
                        crc -= rxd_buffer[ptr_rxd_buffer-1];
299
                        // calculate checksum from transmitted data
299
                        // calculate checksum from transmitted data
300
                        crc %= 4096;
300
                        crc %= 4096;
301
                        crc1 = '=' + crc / 64;
301
                        crc1 = '=' + crc / 64;
302
                        crc2 = '=' + crc % 64;
302
                        crc2 = '=' + crc % 64;
303
                        // compare checksum to transmitted checksum bytes
303
                        // compare checksum to transmitted checksum bytes
304
                        if((crc1 == rxd_buffer[ptr_rxd_buffer-2]) && (crc2 == rxd_buffer[ptr_rxd_buffer-1]))
304
                        if((crc1 == rxd_buffer[ptr_rxd_buffer-2]) && (crc2 == rxd_buffer[ptr_rxd_buffer-1]))
305
                        {   // checksum valid
305
                        {   // checksum valid
306
                                rxd_buffer_locked = TRUE;          // lock the rxd buffer
306
                                rxd_buffer_locked = TRUE;          // lock the rxd buffer
307
                                ReceivedBytes = ptr_rxd_buffer;    // store number of received bytes
307
                                ReceivedBytes = ptr_rxd_buffer;    // store number of received bytes
308
                                rxd_buffer[ptr_rxd_buffer] = '\r'; // set termination character
308
                                rxd_buffer[ptr_rxd_buffer] = '\r'; // set termination character
309
                                // if 2nd byte is an 'R' enable watchdog that will result in an reset
309
                                // if 2nd byte is an 'R' enable watchdog that will result in an reset
310
                                if(rxd_buffer[2] == 'R') {wdt_enable(WDTO_250MS);} // Reset-Commando
310
                                if(rxd_buffer[2] == 'R') {wdt_enable(WDTO_250MS);} // Reset-Commando
311
                        }
311
                        }
312
                        else
312
                        else
313
                        {       // checksum invalid
313
                        {       // checksum invalid
314
                                rxd_buffer_locked = FALSE; // unlock rxd buffer
314
                                rxd_buffer_locked = FALSE; // unlock rxd buffer
315
                        }
315
                        }
316
                        ptr_rxd_buffer = 0; // reset rxd buffer pointer
316
                        ptr_rxd_buffer = 0; // reset rxd buffer pointer
317
                }
317
                }
318
        }
318
        }
319
        else // rxd buffer overrun
319
        else // rxd buffer overrun
320
        {
320
        {
321
                ptr_rxd_buffer = 0; // reset rxd buffer
321
                ptr_rxd_buffer = 0; // reset rxd buffer
322
                rxd_buffer_locked = FALSE; // unlock rxd buffer
322
                rxd_buffer_locked = FALSE; // unlock rxd buffer
323
        }
323
        }
324
}
324
}
325
 
325
 
326
 
326
 
327
// --------------------------------------------------------------------------
327
// --------------------------------------------------------------------------
328
void AddCRC(uint16_t datalen)
328
void AddCRC(uint16_t datalen)
329
{
329
{
330
        uint16_t tmpCRC = 0, i;
330
        uint16_t tmpCRC = 0, i;
331
        for(i = 0; i < datalen; i++)
331
        for(i = 0; i < datalen; i++)
332
        {
332
        {
333
                tmpCRC += txd_buffer[i];
333
                tmpCRC += txd_buffer[i];
334
        }
334
        }
335
        tmpCRC %= 4096;
335
        tmpCRC %= 4096;
336
        txd_buffer[i++] = '=' + tmpCRC / 64;
336
        txd_buffer[i++] = '=' + tmpCRC / 64;
337
        txd_buffer[i++] = '=' + tmpCRC % 64;
337
        txd_buffer[i++] = '=' + tmpCRC % 64;
338
        txd_buffer[i++] = '\r';
338
        txd_buffer[i++] = '\r';
339
        txd_complete = FALSE;
339
        txd_complete = FALSE;
340
        UDR0 = txd_buffer[0]; // initiates the transmission (continued in the TXD ISR)
340
        UDR0 = txd_buffer[0]; // initiates the transmission (continued in the TXD ISR)
341
}
341
}
342
 
342
 
343
 
343
 
344
 
344
 
345
// --------------------------------------------------------------------------
345
// --------------------------------------------------------------------------
346
void SendOutData(uint8_t cmd,uint8_t module, uint8_t *snd, uint8_t len)
346
void SendOutData(uint8_t cmd,uint8_t module, uint8_t *snd, uint8_t len)
347
{
347
{
348
        uint16_t pt = 0;
348
        uint16_t pt = 0;
349
        uint8_t a,b,c;
349
        uint8_t a,b,c;
350
        uint8_t ptr = 0;
350
        uint8_t ptr = 0;
351
 
351
 
352
        txd_buffer[pt++] = '#';         // Start character
352
        txd_buffer[pt++] = '#';         // Start character
353
        txd_buffer[pt++] = module;      // Address (a=0; b=1,...)
353
        txd_buffer[pt++] = module;      // Address (a=0; b=1,...)
354
        txd_buffer[pt++] = cmd;         // Command
354
        txd_buffer[pt++] = cmd;         // Command
355
 
355
 
356
        while(len)
356
        while(len)
357
        {
357
        {
358
                if(len) { a = snd[ptr++]; len--;} else a = 0;
358
                if(len) { a = snd[ptr++]; len--;} else a = 0;
359
                if(len) { b = snd[ptr++]; len--;} else b = 0;
359
                if(len) { b = snd[ptr++]; len--;} else b = 0;
360
                if(len) { c = snd[ptr++]; len--;} else c = 0;
360
                if(len) { c = snd[ptr++]; len--;} else c = 0;
361
                txd_buffer[pt++] = '=' + (a >> 2);
361
                txd_buffer[pt++] = '=' + (a >> 2);
362
                txd_buffer[pt++] = '=' + (((a & 0x03) << 4) | ((b & 0xf0) >> 4));
362
                txd_buffer[pt++] = '=' + (((a & 0x03) << 4) | ((b & 0xf0) >> 4));
363
                txd_buffer[pt++] = '=' + (((b & 0x0f) << 2) | ((c & 0xc0) >> 6));
363
                txd_buffer[pt++] = '=' + (((b & 0x0f) << 2) | ((c & 0xc0) >> 6));
364
                txd_buffer[pt++] = '=' + ( c & 0x3f);
364
                txd_buffer[pt++] = '=' + ( c & 0x3f);
365
        }
365
        }
366
        AddCRC(pt); // add checksum after data block and initates the transmission
366
        AddCRC(pt); // add checksum after data block and initates the transmission
367
}
367
}
368
 
368
 
369
 
369
 
370
// --------------------------------------------------------------------------
370
// --------------------------------------------------------------------------
371
void Decode64(uint8_t *ptrOut, uint8_t len, uint8_t ptrIn, uint8_t max)
371
void Decode64(uint8_t *ptrOut, uint8_t len, uint8_t ptrIn, uint8_t max)
372
{
372
{
373
        uint8_t a,b,c,d;
373
        uint8_t a,b,c,d;
374
        uint8_t ptr = 0;
374
        uint8_t ptr = 0;
375
        uint8_t x,y,z;
375
        uint8_t x,y,z;
376
        while(len)
376
        while(len)
377
        {
377
        {
378
                a = rxd_buffer[ptrIn++] - '=';
378
                a = rxd_buffer[ptrIn++] - '=';
379
                b = rxd_buffer[ptrIn++] - '=';
379
                b = rxd_buffer[ptrIn++] - '=';
380
                c = rxd_buffer[ptrIn++] - '=';
380
                c = rxd_buffer[ptrIn++] - '=';
381
                d = rxd_buffer[ptrIn++] - '=';
381
                d = rxd_buffer[ptrIn++] - '=';
382
                if(ptrIn > max - 2) break;
382
                if(ptrIn > max - 2) break;
383
 
383
 
384
                x = (a << 2) | (b >> 4);
384
                x = (a << 2) | (b >> 4);
385
                y = ((b & 0x0f) << 4) | (c >> 2);
385
                y = ((b & 0x0f) << 4) | (c >> 2);
386
                z = ((c & 0x03) << 6) | d;
386
                z = ((c & 0x03) << 6) | d;
387
 
387
 
388
                if(len--) ptrOut[ptr++] = x; else break;
388
                if(len--) ptrOut[ptr++] = x; else break;
389
                if(len--) ptrOut[ptr++] = y; else break;
389
                if(len--) ptrOut[ptr++] = y; else break;
390
                if(len--) ptrOut[ptr++] = z; else break;
390
                if(len--) ptrOut[ptr++] = z; else break;
391
        }
391
        }
392
}
392
}
393
 
393
 
394
 
394
 
395
// --------------------------------------------------------------------------
395
// --------------------------------------------------------------------------
396
int uart_putchar (int8_t c)
396
int uart_putchar (int8_t c)
397
{
397
{
398
        // if tx is not enabled return immediatly
398
        // if tx is not enabled return immediatly
399
        if(!(UCSR0B & (1 << TXEN0))) return (0);
399
        if(!(UCSR0B & (1 << TXEN0))) return (0);
400
        if (c == '\n') uart_putchar('\r');
400
        if (c == '\n') uart_putchar('\r');
401
        // wait until previous character was send
401
        // wait until previous character was send
402
        loop_until_bit_is_set(UCSR0A, UDRE0);
402
        loop_until_bit_is_set(UCSR0A, UDRE0);
403
        // send character
403
        // send character
404
        UDR0 = c;
404
        UDR0 = c;
405
        return (0);
405
        return (0);
406
}
406
}
407
 
407
 
408
 
408
 
409
// --------------------------------------------------------------------------
409
// --------------------------------------------------------------------------
410
void USART0_ProcessRxData(void)
410
void USART0_ProcessRxData(void)
411
{
411
{
412
        // if data in the rxd buffer are not locked immediately return
412
        // if data in the rxd buffer are not locked immediately return
413
        if(!rxd_buffer_locked) return;
413
        if(!rxd_buffer_locked) return;
414
 
414
 
415
        uint8_t tmp_char_arr2[2]; // local char buffer
415
        uint8_t tmp_char_arr2[2]; // local char buffer
416
 
416
 
417
        switch(rxd_buffer[2])
417
        switch(rxd_buffer[2])
418
        {
418
        {
419
           case 'w':// Attitude
419
           case 'w':// Attitude
420
                        Decode64((uint8_t *) &ExternData, sizeof(ExternData), 3, ReceivedBytes);
420
                        Decode64((uint8_t *) &ExternData, sizeof(ExternData), 3, ReceivedBytes);
-
 
421
                        I2C_WriteAttitude.Nick = ExternData.Attitude[NICK];
-
 
422
                        I2C_WriteAttitude.Nick = ExternData.Attitude[ROLL];
421
                        RequestFlags |= COMPASS_HEADING;
423
                        RequestFlags |= COMPASS_HEADING;
422
                        break;
424
                        break;
423
 
425
 
424
                case 'b': // extern control
426
                case 'b': // extern control
425
                case 'c': // extern control with debug request
427
                case 'c': // extern control with debug request
426
                        Decode64((uint8_t *) &ExternControl,sizeof(ExternControl), 3,ReceivedBytes);
428
                        Decode64((uint8_t *) &ExternControl,sizeof(ExternControl), 3,ReceivedBytes);
427
                        #define KEY1    0x01
429
                        #define KEY1    0x01
428
                        #define KEY2    0x02
430
                        #define KEY2    0x02
429
                        #define KEY3    0x04
431
                        #define KEY3    0x04
430
                        #define KEY4    0x08
432
                        #define KEY4    0x08
431
                        #define KEY5    0x10
433
                        #define KEY5    0x10
432
                        // use right arrow at display for switching the calstate
434
                        // use right arrow at display for switching the calstate
433
                        if(ExternControl.RemoteButtons & KEY2)
435
                        if(ExternControl.RemoteButtons & KEY2)
434
                        {
436
                        {
435
                                ExternData.CalState++;
437
                                ExternData.CalState++;
436
                                if(ExternData.CalState == 6) ExternData.CalState = 0;
438
                                if(ExternData.CalState == 6) ExternData.CalState = 0;
437
                        }
439
                        }
438
                        //ExternData.Attitude[0] = ExternControl.Par1;
440
                        //ExternData.Attitude[0] = ExternControl.Par1;
439
            //ExternData.Attitude[1] = ExternControl.Par2;
441
            //ExternData.Attitude[1] = ExternControl.Par2;
440
            PC_Connected = 255;
442
            PC_Connected = 255;
441
                        break;
443
                        break;
442
 
444
 
443
                case 'h':// x-1 display columns
445
                case 'h':// x-1 display columns
444
                        PC_Connected = 255;
446
                        PC_Connected = 255;
445
                        break;
447
                        break;
446
 
448
 
447
                case 'v': // get version and board release
449
                case 'v': // get version and board release
448
                        RequestFlags |= VERSION_INFO;
450
                        RequestFlags |= VERSION_INFO;
449
                        PC_Connected = 255;
451
                        PC_Connected = 255;
450
                        break;
452
                        break;
451
 
453
 
452
                case 'a':// Labels of the Analog Debug outputs
454
                case 'a':// Labels of the Analog Debug outputs
453
                        Decode64((uint8_t *) &tmp_char_arr2[0], sizeof(tmp_char_arr2), 3, ReceivedBytes);
455
                        Decode64((uint8_t *) &tmp_char_arr2[0], sizeof(tmp_char_arr2), 3, ReceivedBytes);
454
                        RequestDebugLabel = tmp_char_arr2[0];
456
                        RequestDebugLabel = tmp_char_arr2[0];
455
                        RequestFlags |= DEBUG_LABEL;
457
                        RequestFlags |= DEBUG_LABEL;
456
                        PC_Connected = 255;
458
                        PC_Connected = 255;
457
                        break;
459
                        break;
458
 
460
 
459
                case 'g':// get debug data
461
                case 'g':// get debug data
460
                        RequestFlags |= DEBUG_DATA;
462
                        RequestFlags |= DEBUG_DATA;
461
                        PC_Connected = 255;
463
                        PC_Connected = 255;
462
                        break;
464
                        break;
463
        }
465
        }
464
        // unlock the rxd buffer after processing
466
        // unlock the rxd buffer after processing
465
        rxd_buffer_locked = FALSE;
467
        rxd_buffer_locked = FALSE;
466
}
468
}
467
 
469
 
468
 
470
 
469
 
471
 
470
//---------------------------------------------------------------------------------------------
472
//---------------------------------------------------------------------------------------------
471
void USART0_TransmitTxData(void)
473
void USART0_TransmitTxData(void)
472
{
474
{
473
        if(!(UCSR0B & (1 << TXEN0))) return;
475
        if(!(UCSR0B & (1 << TXEN0))) return;
474
 
476
 
475
        if(!txd_complete) return;
477
        if(!txd_complete) return;
476
 
478
 
477
    if(CheckDelay(Debug_Timer))
479
    if(CheckDelay(Debug_Timer))
478
    {
480
    {
479
                SetDebugValues();
481
                SetDebugValues();
480
                SendOutData('D',MySlaveAddr,(uint8_t *) &DebugOut,sizeof(DebugOut));
482
                SendOutData('D',MySlaveAddr,(uint8_t *) &DebugOut,sizeof(DebugOut));
481
                Debug_Timer = SetDelay(250);
483
                Debug_Timer = SetDelay(250);
482
    }
484
    }
483
 
485
 
484
    if(RequestFlags & DEBUG_LABEL)
486
    if(RequestFlags & DEBUG_LABEL)
485
    {
487
    {
486
                SendOutData('A',RequestDebugLabel + '0',(uint8_t *) ANALOG_LABEL[RequestDebugLabel],16);
488
                SendOutData('A',RequestDebugLabel + '0',(uint8_t *) ANALOG_LABEL[RequestDebugLabel],16);
487
                RequestDebugLabel = 255;
489
                RequestDebugLabel = 255;
488
                RequestFlags &= ~DEBUG_LABEL;
490
                RequestFlags &= ~DEBUG_LABEL;
489
        }
491
        }
490
 
492
 
491
        if(RequestFlags & VERSION_INFO)
493
        if(RequestFlags & VERSION_INFO)
492
    {
494
    {
493
                SendOutData('V',MySlaveAddr,(uint8_t *) &VersionInfo, sizeof(VersionInfo));
495
                SendOutData('V',MySlaveAddr,(uint8_t *) &VersionInfo, sizeof(VersionInfo));
494
                RequestFlags &= ~VERSION_INFO;
496
                RequestFlags &= ~VERSION_INFO;
495
    }
497
    }
496
 
498
 
497
        if(RequestFlags & DEBUG_DATA)
499
        if(RequestFlags & DEBUG_DATA)
498
        {
500
        {
499
                SetDebugValues();
501
                SetDebugValues();
500
                SendOutData('G',MySlaveAddr,(uint8_t *) &ExternControl,sizeof(ExternControl));
502
                SendOutData('G',MySlaveAddr,(uint8_t *) &ExternControl,sizeof(ExternControl));
501
                RequestFlags &= ~DEBUG_DATA;
503
                RequestFlags &= ~DEBUG_DATA;
502
        }
504
        }
503
 
505
 
504
    if(RequestFlags & COMPASS_HEADING)
506
    if(RequestFlags & COMPASS_HEADING)
505
        {
507
        {
506
                SendOutData('K',MySlaveAddr,(uint8_t *) &I2C_Heading, sizeof(I2C_Heading));
508
                SendOutData('K',MySlaveAddr,(uint8_t *) &I2C_Heading, sizeof(I2C_Heading));
507
                RequestFlags &= ~COMPASS_HEADING;
509
                RequestFlags &= ~COMPASS_HEADING;
508
        }
510
        }
509
}
511
}
510
 
512