Subversion Repositories FlightCtrl

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1612 dongfang 1
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2
// + Copyright (c) 04.2007 Holger Buss
2035 - 3
// + Nur f�r den privaten Gebrauch
1612 dongfang 4
// + www.MikroKopter.com
5
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2035 - 6
// + Es gilt f�r das gesamte Projekt (Hardware, Software, Bin�rfiles, Sourcecode und Dokumentation),
7
// + dass eine Nutzung (auch auszugsweise) nur f�r den privaten (nicht-kommerziellen) Gebrauch zul�ssig ist.
1612 dongfang 8
// + Sollten direkte oder indirekte kommerzielle Absichten verfolgt werden, ist mit uns (info@mikrokopter.de) Kontakt
9
// + bzgl. der Nutzungsbedingungen aufzunehmen.
2035 - 10
// + Eine kommerzielle Nutzung ist z.B.Verkauf von MikroKoptern, Best�ckung und Verkauf von Platinen oder Baus�tzen,
1612 dongfang 11
// + Verkauf von Luftbildaufnahmen, usw.
12
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2035 - 13
// + Werden Teile des Quellcodes (mit oder ohne Modifikation) weiterverwendet oder ver�ffentlicht,
14
// + unterliegen sie auch diesen Nutzungsbedingungen und diese Nutzungsbedingungen incl. Copyright m�ssen dann beiliegen
1612 dongfang 15
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
16
// + Sollte die Software (auch auszugesweise) oder sonstige Informationen des MikroKopter-Projekts
2035 - 17
// + auf anderen Webseiten oder sonstigen Medien ver�ffentlicht werden, muss unsere Webseite "http://www.mikrokopter.de"
1612 dongfang 18
// + eindeutig als Ursprung verlinkt werden
19
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2035 - 20
// + Keine Gew�hr auf Fehlerfreiheit, Vollst�ndigkeit oder Funktion
1612 dongfang 21
// + Benutzung auf eigene Gefahr
2035 - 22
// + Wir �bernehmen keinerlei Haftung f�r direkte oder indirekte Personen- oder Sachsch�den
1612 dongfang 23
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
24
// + Die Portierung der Software (oder Teile davon) auf andere Systeme (ausser der Hardware von www.mikrokopter.de) ist nur
2035 - 25
// + mit unserer Zustimmung zul�ssig
1612 dongfang 26
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
27
// + Die Funktion printf_P() unterliegt ihrer eigenen Lizenz und ist hiervon nicht betroffen
28
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
29
// + Redistributions of source code (with or without modifications) must retain the above copyright notice,
30
// + this list of conditions and the following disclaimer.
31
// +   * Neither the name of the copyright holders nor the names of contributors may be used to endorse or promote products derived
32
// +     from this software without specific prior written permission.
33
// +   * The use of this project (hardware, software, binary files, sources and documentation) is only permittet
34
// +     for non-commercial use (directly or indirectly)
1868 - 35
// +     Commercial use (for example: selling of MikroKopters, selling of PCBs, assembly, ...) is only permitted
1612 dongfang 36
// +     with our written permission
37
// +   * If sources or documentations are redistributet on other webpages, out webpage (http://www.MikroKopter.de) must be
38
// +     clearly linked as origin
39
// +   * porting to systems other than hardware from www.mikrokopter.de is not allowed
40
// +  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
41
// +  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42
// +  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43
// +  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
44
// +  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
45
// +  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
46
// +  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
47
// +  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN// +  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
48
// +  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
49
// +  POSSIBILITY OF SUCH DAMAGE.
50
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
51
#include <avr/io.h>
52
#include <avr/interrupt.h>
53
#include <string.h>
54
#include <stdlib.h>
55
#include "spi.h"
56
#include "rc.h"
57
#include "eeprom.h"
58
#include "timer0.h"
59
#include "analog.h"
60
#include "attitude.h"
61
#include "flight.h"
62
 
63
//-----------------------------------------
64
 
65
// for compatibility reasons gcc3.x <-> gcc4.x
2035 - 66
// dongfang: Lets try to abandon GCC3.
67
/*
1612 dongfang 68
#ifndef SPCR
69
#define SPCR   SPCR0
70
#endif
71
#ifndef SPIE
72
#define SPIE   SPIE0
73
#endif
74
#ifndef SPE
75
#define SPE    SPE0
76
#endif
77
#ifndef DORD
78
#define DORD   DORD0
79
#endif
80
#ifndef MSTR
81
#define MSTR   MSTR0
82
#endif
83
#ifndef CPOL
84
#define CPOL   CPOL0
85
#endif
86
#ifndef CPHA
87
#define CPHA   CPHA0
88
#endif
89
#ifndef SPR1
90
#define SPR1   SPR01
91
#endif
92
#ifndef SPR0
93
#define SPR0   SPR00
94
#endif
95
 
96
#ifndef SPDR
97
#define SPDR   SPDR0
98
#endif
99
 
100
#ifndef SPSR
101
#define SPSR   SPSR0
102
#endif
103
#ifndef SPIF
104
#define SPIF   SPIF0
105
#endif
106
#ifndef WCOL
107
#define WCOL   WCOL0
108
#endif
1775 - 109
#ifndef SPI2X
1612 dongfang 110
#define SPI2X  SPI2X0
1775 - 111
#endif
2035 - 112
*/
1612 dongfang 113
// -------------------------
2035 - 114
#define DDR_SPI DDRB
115
#define DD_SS   PB4
116
#define DD_SCK  PB7
117
#define DD_MOSI PB5
118
#define DD_MISO PB6
1612 dongfang 119
 
120
#define SLAVE_SELECT_DDR_PORT   DDRC
121
#define SLAVE_SELECT_PORT       PORTC
122
#define SPI_SLAVE_SELECT        PC5
123
 
124
#define SPI_TXSYNCBYTE1 0xAA
125
#define SPI_TXSYNCBYTE2 0x83
126
#define SPI_RXSYNCBYTE1 0x81
127
#define SPI_RXSYNCBYTE2 0x55
128
 
1775 - 129
typedef enum {
1821 - 130
        SPI_SYNC1, SPI_SYNC2, SPI_DATA
1775 - 131
} SPI_RXState_t;
1612 dongfang 132
 
133
// data exchange packets to and From NaviCtrl
1821 - 134
ToNaviCtrl_t toNaviCtrl;
135
FromNaviCtrl_t fromNaviCtrl;
136
SPI_VersionInfo_t SPI_VersionInfo;
1612 dongfang 137
 
138
// rx packet buffer
1775 - 139
#define SPI_RXBUFFER_LEN sizeof(fromNaviCtrl)
1612 dongfang 140
uint8_t SPI_RxBuffer[SPI_RXBUFFER_LEN];
1821 - 141
uint8_t SPI_RxBufferIndex = 0;
1612 dongfang 142
uint8_t SPI_RxBuffer_Request = 0;
143
 
144
// tx packet buffer
1775 - 145
#define SPI_TXBUFFER_LEN sizeof(toNaviCtrl)
1612 dongfang 146
uint8_t *SPI_TxBuffer;
1821 - 147
uint8_t SPI_TxBufferIndex = 0;
1612 dongfang 148
 
149
uint8_t SPITransferCompleted, SPI_ChkSum;
150
uint8_t SPI_RxDataValid = 0;
151
uint8_t NCDataOkay = 0;
152
uint8_t NCSerialDataOkay = 0;
153
 
1821 - 154
uint8_t SPI_CommandSequence[] = { SPI_CMD_USER, SPI_CMD_STICK,
155
                SPI_CMD_PARAMETER1, SPI_CMD_STICK, SPI_CMD_MISC, SPI_CMD_VERSION };
1612 dongfang 156
uint8_t SPI_CommandCounter = 0;
157
 
158
/*********************************************/
159
/*  Initialize SPI interface to NaviCtrl     */
160
/*********************************************/
161
void SPI_MasterInit(void) {
1821 - 162
        DDR_SPI |= (1 << DD_MOSI) | (1 << DD_SCK); // Set MOSI and SCK output, all others input
163
        SLAVE_SELECT_DDR_PORT |= (1 << SPI_SLAVE_SELECT); // set Slave select port as output port
164
 
165
        SPCR = (1 << SPE) | (1 << MSTR) | (1 << SPR1) | (0 << SPR0) | (0 << SPIE); // Enable SPI, Master, set clock rate fck/64
166
        SPSR = 0;//(1<<SPI2X);
167
 
168
        SLAVE_SELECT_PORT |= (1 << SPI_SLAVE_SELECT); // Deselect Slave
169
 
170
        SPI_TxBuffer = (uint8_t *) &toNaviCtrl; // set pointer to tx-buffer
171
        SPITransferCompleted = 1;
172
        // initialize data packet to NaviControl
2035 - 173
        toNaviCtrl.sync1 = SPI_TXSYNCBYTE1;
174
        toNaviCtrl.sync2 = SPI_TXSYNCBYTE2;
1821 - 175
 
2035 - 176
        toNaviCtrl.command = SPI_CMD_USER;
177
        toNaviCtrl.integralPitch = 0;
178
        toNaviCtrl.integralRoll = 0;
179
        naviCtrlData.serialDataOkay = 0;
180
        //NCSerialDataOkay = 0;
181
        //NCDataOkay = 0;
1821 - 182
 
183
        SPI_RxDataValid = 0;
184
 
2035 - 185
        //SPI_VersionInfo.Major = VERSION_MAJOR;
186
        //SPI_VersionInfo.Minor = VERSION_MINOR;
187
        //SPI_VersionInfo.Patch = VERSION_PATCH;
188
        //SPI_VersionInfo.Compatible = NC_SPI_COMPATIBLE;
1612 dongfang 189
}
190
 
191
/**********************************************************/
2035 - 192
/*  Update Data transfered by the SPI from/to NaviCtrl     */
1612 dongfang 193
/**********************************************************/
2035 - 194
void updateSPI_Buffer(void) {
1821 - 195
        uint8_t i;
196
        int16_t tmp;
197
        cli();
198
        // stop all interrupts to avoid writing of new data during update of that packet.
1775 - 199
 
1821 - 200
        // update content of packet to NaviCtrl
2035 - 201
        // Scaling?
202
        toNaviCtrl.integralPitch = (angle[PITCH] / (GYRO_DEG_FACTOR_PITCHROLL/10)); // convert to multiple of 0.1�
203
        // Scaling?
204
        toNaviCtrl.integralRoll =  (angle[ROLL]   / (GYRO_DEG_FACTOR_PITCHROLL/10)); // convert to multiple of 0.1�
205
        // Scaling?
206
        toNaviCtrl.gyroHeading =   (yawGyroHeading / (GYRO_DEG_FACTOR_YAW / 10));     // convert to multiple of 0.1�
207
        // Scaling?
208
        toNaviCtrl.gyroPitch = rate_ATT[PITCH];
209
        // Scaling?
210
        toNaviCtrl.gyroRoll = rate_ATT[ROLL];
211
        // Scaling?
212
        toNaviCtrl.gyroYaw = yawRate;
213
        // Scaling?
214
        toNaviCtrl.accPitch = getAngleEstimateFromAcc(PITCH) / (GYRO_DEG_FACTOR_PITCHROLL/10); // convert to multiple of 0.1�
215
        // Scaling?
216
        toNaviCtrl.AccRoll =  getAngleEstimateFromAcc(ROLL)  / (GYRO_DEG_FACTOR_PITCHROLL/10);
1612 dongfang 217
 
1821 - 218
        // TODO: What are these little bastards?
219
 
220
        averageAcc[PITCH] = averageAcc[ROLL] = averageAccCount = 0;
221
 
2035 - 222
        switch (toNaviCtrl.command) {
1821 - 223
        case SPI_CMD_USER:
2035 - 224
                for (i = 0; i < sizeof(dynamicParams.userParams); i++) {
225
                        toNaviCtrl.param.asByte[i] = dynamicParams.userParams[i];
1821 - 226
                }
227
                toNaviCtrl.Param.Byte[8] = MKFlags;
228
                MKFlags &= ~(MKFLAG_CALIBRATE | MKFLAG_START); // calibrate and start are temporal states that are cleared immediately after transmitting
2035 - 229
                toNaviCtrl.Param.Byte[9]  = getActiveParamSet();
230
                toNaviCtrl.Param.Byte[10] = 10; //EE_Parameter.ComingHomeAltitude;
231
                toNaviCtrl.Param.Byte[11] = 0;  //FC_StatusFlags2;
1821 - 232
                break;
233
 
234
        case SPI_CMD_PARAMETER1:
235
                toNaviCtrl.Param.Byte[0] = staticParams.NaviGpsModeControl; // Parameters for the Naviboard
236
                toNaviCtrl.Param.Byte[1] = staticParams.NaviGpsGain;
237
                toNaviCtrl.Param.Byte[2] = staticParams.NaviGpsP;
238
                toNaviCtrl.Param.Byte[3] = staticParams.NaviGpsI;
239
                toNaviCtrl.Param.Byte[4] = staticParams.NaviGpsD;
240
                toNaviCtrl.Param.Byte[5] = staticParams.NaviGpsACC;
241
                toNaviCtrl.Param.Byte[6] = staticParams.NaviGpsMinSat;
242
                toNaviCtrl.Param.Byte[7] = staticParams.NaviStickThreshold;
243
                toNaviCtrl.Param.Byte[8] = staticParams.NaviOperatingRadius;
244
                toNaviCtrl.Param.Byte[9] = staticParams.NaviWindCorrection;
245
                toNaviCtrl.Param.Byte[10] = staticParams.NaviSpeedCompensation;
246
                toNaviCtrl.Param.Byte[11] = staticParams.NaviAngleLimitation;
247
                break;
248
 
249
        case SPI_CMD_STICK:
250
                tmp = PPM_in[staticParams.ChannelAssignment[CH_THROTTLE]];
251
                if (tmp > 127)
252
                        tmp = 127;
253
                else if (tmp < -128)
254
                        tmp = -128;
255
                toNaviCtrl.Param.Byte[0] = (int8_t) tmp;
256
                tmp = PPM_in[staticParams.ChannelAssignment[CH_YAW]];
257
                if (tmp > 127)
258
                        tmp = 127;
259
                else if (tmp < -128)
260
                        tmp = -128;
261
                toNaviCtrl.Param.Byte[1] = (int8_t) tmp;
262
                tmp = PPM_in[staticParams.ChannelAssignment[CH_ROLL]];
263
                if (tmp > 127)
264
                        tmp = 127;
265
                else if (tmp < -128)
266
                        tmp = -128;
267
                toNaviCtrl.Param.Byte[2] = (int8_t) tmp;
268
                tmp = PPM_in[staticParams.ChannelAssignment[CH_PITCH]];
269
                if (tmp > 127)
270
                        tmp = 127;
271
                else if (tmp < -128)
272
                        tmp = -128;
273
                toNaviCtrl.Param.Byte[3] = (int8_t) tmp;
274
                toNaviCtrl.Param.Byte[4] = (uint8_t) variables[0];
275
                toNaviCtrl.Param.Byte[5] = (uint8_t) variables[1];
276
                toNaviCtrl.Param.Byte[6] = (uint8_t) variables[2];
277
                toNaviCtrl.Param.Byte[7] = (uint8_t) variables[3];
278
                toNaviCtrl.Param.Byte[8] = (uint8_t) RC_Quality;
279
                break;
280
 
281
        case SPI_CMD_MISC:
282
                toNaviCtrl.Param.Byte[0] = compassCalState;
283
                if (compassCalState > 4) { // jump from 5 to 0
284
                        compassCalState = 0;
285
                }
286
                toNaviCtrl.Param.Byte[1] = staticParams.NaviPHLoginTime;
287
                // TODO: Height and in the correct scaling...
288
                toNaviCtrl.Param.Int[1] = 0; //readingHeight; // at address of Byte 2 and 3
289
                toNaviCtrl.Param.Byte[4] = staticParams.NaviGpsPLimit;
290
                toNaviCtrl.Param.Byte[5] = staticParams.NaviGpsILimit;
291
                toNaviCtrl.Param.Byte[6] = staticParams.NaviGpsDLimit;
292
                break;
293
 
294
        case SPI_CMD_VERSION:
295
                toNaviCtrl.Param.Byte[0] = SPI_VersionInfo.Major;
296
                toNaviCtrl.Param.Byte[1] = SPI_VersionInfo.Minor;
297
                toNaviCtrl.Param.Byte[2] = SPI_VersionInfo.Patch;
298
                toNaviCtrl.Param.Byte[3] = SPI_VersionInfo.Compatible;
299
                toNaviCtrl.Param.Byte[4] = BoardRelease;
300
                break;
301
        default:
302
                break;
303
        }
304
 
305
        sei();
306
        // enable all interrupts
307
 
308
        // analyze content of packet from NaviCtrl if valid
309
        if (SPI_RxDataValid) {
310
                // update gps controls
311
                if (abs(fromNaviCtrl.GPSStickPitch) < 512 && abs(fromNaviCtrl.GPSStickRoll)
312
                                < 512 && (staticParams.GlobalConfig & CFG_GPS_ACTIVE)) {
313
                        GPSStickPitch = fromNaviCtrl.GPSStickPitch;
314
                        GPSStickRoll = fromNaviCtrl.GPSStickRoll;
315
                        NCDataOkay = 250;
316
                }
317
                // update compass readings
318
                if (fromNaviCtrl.CompassHeading <= 360) {
319
                        compassHeading = fromNaviCtrl.CompassHeading;
320
                }
321
                //if(compassHeading < 0) compassOffCourse = 0;
322
                //else compassOffCourse = ((540 + compassHeading - compassCourse) % 360) - 180;
323
                // NaviCtrl wants to beep?
324
                if (fromNaviCtrl.BeepTime > BeepTime && !compassCalState)
325
                        BeepTime = fromNaviCtrl.BeepTime;
326
 
327
                switch (fromNaviCtrl.Command) {
328
                case SPI_KALMAN:
329
                        dynamicParams.KalmanK = fromNaviCtrl.Param.Byte[0];
330
                        dynamicParams.KalmanMaxFusion = fromNaviCtrl.Param.Byte[1];
331
                        dynamicParams.KalmanMaxDrift = fromNaviCtrl.Param.Byte[2];
332
                        NCSerialDataOkay = fromNaviCtrl.Param.Byte[3];
333
                        break;
334
 
335
                default:
336
                        break;
337
                }
338
        } else { // no valid data from NaviCtrl
339
                // disable GPS control
340
                GPSStickPitch = 0;
341
                GPSStickRoll = 0;
342
        }
1612 dongfang 343
}
344
 
345
/*********************************************/
346
/*  Start Transmission of packet to NaviCtrl */
347
/*********************************************/
1821 - 348
void SPI_StartTransmitPacket(void) {
349
        if (!SPITransferCompleted)
350
                return; // return immediately if transfer is in progress
351
        else // transmission was completed
352
        {
353
                SLAVE_SELECT_PORT &= ~(1 << SPI_SLAVE_SELECT); // Select slave
354
 
355
                // cyclic commands
356
                toNaviCtrl.Command = SPI_CommandSequence[SPI_CommandCounter++];
357
                if (SPI_CommandCounter >= sizeof(SPI_CommandSequence))
358
                        SPI_CommandCounter = 0;
359
 
360
                SPITransferCompleted = 0; // transfer is in progress
361
                UpdateSPI_Buffer(); // update data in toNaviCtrl
362
 
363
                SPI_TxBufferIndex = 1; //proceed with 2nd byte
364
 
365
                // -- Debug-Output ---
366
                //----
367
                asm volatile ("nop");
368
                asm volatile ("nop");
369
                asm volatile ("nop");
370
                asm volatile ("nop");
371
                asm volatile ("nop");
372
                asm volatile ("nop");
373
                asm volatile ("nop");
374
                asm volatile ("nop");
375
                asm volatile ("nop");
376
                asm volatile ("nop");
377
                asm volatile ("nop");
378
                asm volatile ("nop");
379
                asm volatile ("nop");
380
                asm volatile ("nop");
381
                asm volatile ("nop");
382
                asm volatile ("nop");
383
                asm volatile ("nop");
384
                asm volatile ("nop");
385
                asm volatile ("nop");
386
                asm volatile ("nop");
387
                asm volatile ("nop");
388
                asm volatile ("nop");
389
                asm volatile ("nop");
390
                asm volatile ("nop");
391
                toNaviCtrl.Chksum = toNaviCtrl.Sync1; // init checksum
392
                SPDR = toNaviCtrl.Sync1; // send first byte
393
        }
1612 dongfang 394
}
395
 
396
//------------------------------------------------------
397
// This is the spi data transfer between FlightCtrl and NaviCtrl
398
// Every time this routine is called within the mainloop one byte of the packet to
399
// the NaviCtrl and one byte of the packet from the NaviCtrl is possible transfered
400
 
401
void SPI_TransmitByte(void) {
1821 - 402
        static SPI_RXState_t SPI_RXState = SPI_SYNC1;
403
        uint8_t rxdata;
404
        static uint8_t rxchksum;
405
 
406
        if (SPITransferCompleted)
407
                return; // return immediatly if transfer was completed
408
        if (!(SPSR & (1 << SPIF)))
409
                return; // return if no SPI-IRQ pending
410
        SendSPI = 4; // mait 4 * 0.102 ms for the next call of SPI_TransmitByte() in the main loop
411
 
412
        SLAVE_SELECT_PORT |= (1 << SPI_SLAVE_SELECT); // DeselectSlave
413
 
414
        rxdata = SPDR; // save spi data register
415
 
416
        switch (SPI_RXState) {
417
        case SPI_SYNC1: // first sync byte
418
                SPI_RxBufferIndex = 0; // set pointer to start of rx buffer
419
                rxchksum = rxdata; // initialize checksum
420
                if (rxdata == SPI_RXSYNCBYTE1) { // 1st Syncbyte found
421
                        SPI_RXState = SPI_SYNC2; // trigger to state for second sync byte
422
                }
423
                break;
424
 
425
        case SPI_SYNC2: // second sync byte
426
                if (rxdata == SPI_RXSYNCBYTE2) { // 2nd Syncbyte found
427
                        rxchksum += rxdata; // update checksum
428
                        SPI_RXState = SPI_DATA; // trigger to state for second sync byte
429
                } else // 2nd Syncbyte not found
430
                {
431
                        SPI_RXState = SPI_SYNC1; // jump back to 1st sync byte
432
                }
433
                break;
434
 
435
        case SPI_DATA: // data bytes
436
                SPI_RxBuffer[SPI_RxBufferIndex++] = rxdata; // copy data byte to spi buffer
437
                // if all bytes are received of a packet from the NaviCtrl
438
                if (SPI_RxBufferIndex >= SPI_RXBUFFER_LEN) { // last byte transfered is the checksum of the packet
439
                        if (rxdata == rxchksum) { // checksum matching?
440
                                // copy SPI_RxBuffer -> FromFlightCtrl
441
                                uint8_t *ptr = (uint8_t *) &fromNaviCtrl;
442
                                cli();
443
                                memcpy(ptr, (uint8_t *) SPI_RxBuffer, sizeof(fromNaviCtrl));
444
                                sei();
445
                                SPI_RxDataValid = 1;
446
                        } else { // checksum does not match
447
                                SPI_RxDataValid = 0; // reset valid flag
448
                        }
449
                        SPI_RXState = SPI_SYNC1; // reset state sync
450
                } else { // not all bytes transfered
451
                        rxchksum += rxdata; // update checksum
452
                }
453
                break;
454
        }// eof switch(SPI_RXState)
455
 
456
        // if still some bytes left for transmission to NaviCtrl
457
        if (SPI_TxBufferIndex < SPI_TXBUFFER_LEN) {
458
                SLAVE_SELECT_PORT &= ~(1 << SPI_SLAVE_SELECT); // SelectSlave
459
                asm volatile ("nop");
460
                asm volatile ("nop");
461
                asm volatile ("nop");
462
                asm volatile ("nop");
463
                asm volatile ("nop");
464
                asm volatile ("nop");
465
                asm volatile ("nop");
466
                asm volatile ("nop");
467
                asm volatile ("nop");
468
                asm volatile ("nop");
469
                asm volatile ("nop");
470
                asm volatile ("nop");
471
                asm volatile ("nop");
472
                asm volatile ("nop");
473
                asm volatile ("nop");
474
                asm volatile ("nop");
475
                asm volatile ("nop");
476
                asm volatile ("nop");
477
                asm volatile ("nop");
478
                asm volatile ("nop");
479
                asm volatile ("nop");
480
                asm volatile ("nop");
481
                asm volatile ("nop");
482
                asm volatile ("nop");
483
 
484
                SPDR = SPI_TxBuffer[SPI_TxBufferIndex]; // transmit byte
485
                toNaviCtrl.Chksum += SPI_TxBuffer[SPI_TxBufferIndex]; // update checksum for everey byte that was sent
486
                SPI_TxBufferIndex++;
487
        } else {
488
                //Transfer of all bytes of the packet to NaviCtrl completed
489
                SPITransferCompleted = 1;
490
        }
1612 dongfang 491
}