Subversion Repositories FlightCtrl

Rev

Rev 1868 | Go to most recent revision | Details | Compare with Previous | 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 "uart0.h"
59
#include "timer0.h"
60
#include "analog.h"
61
#include "attitude.h"
1645 - 62
#include "GPSControl.h"
1612 dongfang 63
#include "flight.h"
64
 
65
//-----------------------------------------
66
 
67
// for compatibility reasons gcc3.x <-> gcc4.x
2035 - 68
// dongfang: Lets try to abandon GCC3.
69
/*
1612 dongfang 70
#ifndef SPCR
71
#define SPCR   SPCR0
72
#endif
73
#ifndef SPIE
74
#define SPIE   SPIE0
75
#endif
76
#ifndef SPE
77
#define SPE    SPE0
78
#endif
79
#ifndef DORD
80
#define DORD   DORD0
81
#endif
82
#ifndef MSTR
83
#define MSTR   MSTR0
84
#endif
85
#ifndef CPOL
86
#define CPOL   CPOL0
87
#endif
88
#ifndef CPHA
89
#define CPHA   CPHA0
90
#endif
91
#ifndef SPR1
92
#define SPR1   SPR01
93
#endif
94
#ifndef SPR0
95
#define SPR0   SPR00
96
#endif
97
 
98
#ifndef SPDR
99
#define SPDR   SPDR0
100
#endif
101
 
102
#ifndef SPSR
103
#define SPSR   SPSR0
104
#endif
105
#ifndef SPIF
106
#define SPIF   SPIF0
107
#endif
108
#ifndef WCOL
109
#define WCOL   WCOL0
110
#endif
1775 - 111
#ifndef SPI2X
1612 dongfang 112
#define SPI2X  SPI2X0
1775 - 113
#endif
2035 - 114
*/
1612 dongfang 115
// -------------------------
2035 - 116
#define DDR_SPI DDRB
117
#define DD_SS   PB4
118
#define DD_SCK  PB7
119
#define DD_MOSI PB5
120
#define DD_MISO PB6
1612 dongfang 121
 
122
#define SLAVE_SELECT_DDR_PORT   DDRC
123
#define SLAVE_SELECT_PORT       PORTC
124
#define SPI_SLAVE_SELECT        PC5
125
 
126
#define SPI_TXSYNCBYTE1 0xAA
127
#define SPI_TXSYNCBYTE2 0x83
128
#define SPI_RXSYNCBYTE1 0x81
129
#define SPI_RXSYNCBYTE2 0x55
130
 
1775 - 131
typedef enum {
1821 - 132
        SPI_SYNC1, SPI_SYNC2, SPI_DATA
1775 - 133
} SPI_RXState_t;
1612 dongfang 134
 
135
// data exchange packets to and From NaviCtrl
1821 - 136
ToNaviCtrl_t toNaviCtrl;
137
FromNaviCtrl_t fromNaviCtrl;
138
SPI_VersionInfo_t SPI_VersionInfo;
1612 dongfang 139
 
140
// rx packet buffer
1775 - 141
#define SPI_RXBUFFER_LEN sizeof(fromNaviCtrl)
1612 dongfang 142
uint8_t SPI_RxBuffer[SPI_RXBUFFER_LEN];
1821 - 143
uint8_t SPI_RxBufferIndex = 0;
1612 dongfang 144
uint8_t SPI_RxBuffer_Request = 0;
145
 
146
// tx packet buffer
1775 - 147
#define SPI_TXBUFFER_LEN sizeof(toNaviCtrl)
1612 dongfang 148
uint8_t *SPI_TxBuffer;
1821 - 149
uint8_t SPI_TxBufferIndex = 0;
1612 dongfang 150
 
151
uint8_t SPITransferCompleted, SPI_ChkSum;
152
uint8_t SPI_RxDataValid = 0;
153
uint8_t NCDataOkay = 0;
154
uint8_t NCSerialDataOkay = 0;
155
 
1821 - 156
uint8_t SPI_CommandSequence[] = { SPI_CMD_USER, SPI_CMD_STICK,
157
                SPI_CMD_PARAMETER1, SPI_CMD_STICK, SPI_CMD_MISC, SPI_CMD_VERSION };
1612 dongfang 158
uint8_t SPI_CommandCounter = 0;
159
 
160
/*********************************************/
161
/*  Initialize SPI interface to NaviCtrl     */
162
/*********************************************/
163
void SPI_MasterInit(void) {
1821 - 164
        DDR_SPI |= (1 << DD_MOSI) | (1 << DD_SCK); // Set MOSI and SCK output, all others input
165
        SLAVE_SELECT_DDR_PORT |= (1 << SPI_SLAVE_SELECT); // set Slave select port as output port
166
 
167
        SPCR = (1 << SPE) | (1 << MSTR) | (1 << SPR1) | (0 << SPR0) | (0 << SPIE); // Enable SPI, Master, set clock rate fck/64
168
        SPSR = 0;//(1<<SPI2X);
169
 
170
        SLAVE_SELECT_PORT |= (1 << SPI_SLAVE_SELECT); // Deselect Slave
171
 
172
        SPI_TxBuffer = (uint8_t *) &toNaviCtrl; // set pointer to tx-buffer
173
        SPITransferCompleted = 1;
174
        // initialize data packet to NaviControl
2035 - 175
        toNaviCtrl.sync1 = SPI_TXSYNCBYTE1;
176
        toNaviCtrl.sync2 = SPI_TXSYNCBYTE2;
1821 - 177
 
2035 - 178
        toNaviCtrl.command = SPI_CMD_USER;
179
        toNaviCtrl.integralPitch = 0;
180
        toNaviCtrl.integralRoll = 0;
181
        naviCtrlData.serialDataOkay = 0;
182
        //NCSerialDataOkay = 0;
183
        //NCDataOkay = 0;
1821 - 184
 
185
        SPI_RxDataValid = 0;
186
 
2035 - 187
        //SPI_VersionInfo.Major = VERSION_MAJOR;
188
        //SPI_VersionInfo.Minor = VERSION_MINOR;
189
        //SPI_VersionInfo.Patch = VERSION_PATCH;
190
        //SPI_VersionInfo.Compatible = NC_SPI_COMPATIBLE;
1612 dongfang 191
}
192
 
193
/**********************************************************/
2035 - 194
/*  Update Data transfered by the SPI from/to NaviCtrl     */
1612 dongfang 195
/**********************************************************/
2035 - 196
void updateSPI_Buffer(void) {
1821 - 197
        uint8_t i;
198
        int16_t tmp;
199
        cli();
200
        // stop all interrupts to avoid writing of new data during update of that packet.
1775 - 201
 
1821 - 202
        // update content of packet to NaviCtrl
2035 - 203
        // Scaling?
204
        toNaviCtrl.integralPitch = (angle[PITCH] / (GYRO_DEG_FACTOR_PITCHROLL/10)); // convert to multiple of 0.1�
205
        // Scaling?
206
        toNaviCtrl.integralRoll =  (angle[ROLL]   / (GYRO_DEG_FACTOR_PITCHROLL/10)); // convert to multiple of 0.1�
207
        // Scaling?
208
        toNaviCtrl.gyroHeading =   (yawGyroHeading / (GYRO_DEG_FACTOR_YAW / 10));     // convert to multiple of 0.1�
209
        // Scaling?
210
        toNaviCtrl.gyroPitch = rate_ATT[PITCH];
211
        // Scaling?
212
        toNaviCtrl.gyroRoll = rate_ATT[ROLL];
213
        // Scaling?
214
        toNaviCtrl.gyroYaw = yawRate;
215
        // Scaling?
216
        toNaviCtrl.accPitch = getAngleEstimateFromAcc(PITCH) / (GYRO_DEG_FACTOR_PITCHROLL/10); // convert to multiple of 0.1�
217
        // Scaling?
218
        toNaviCtrl.AccRoll =  getAngleEstimateFromAcc(ROLL)  / (GYRO_DEG_FACTOR_PITCHROLL/10);
1612 dongfang 219
 
1821 - 220
        // TODO: What are these little bastards?
221
 
222
        averageAcc[PITCH] = averageAcc[ROLL] = averageAccCount = 0;
223
 
2035 - 224
        switch (toNaviCtrl.command) {
1821 - 225
        case SPI_CMD_USER:
2035 - 226
                for (i = 0; i < sizeof(dynamicParams.userParams); i++) {
227
                        toNaviCtrl.param.asByte[i] = dynamicParams.userParams[i];
1821 - 228
                }
229
                toNaviCtrl.Param.Byte[8] = MKFlags;
230
                MKFlags &= ~(MKFLAG_CALIBRATE | MKFLAG_START); // calibrate and start are temporal states that are cleared immediately after transmitting
2035 - 231
                toNaviCtrl.Param.Byte[9]  = getActiveParamSet();
232
                toNaviCtrl.Param.Byte[10] = 10; //EE_Parameter.ComingHomeAltitude;
233
                toNaviCtrl.Param.Byte[11] = 0;  //FC_StatusFlags2;
1821 - 234
                break;
235
 
236
        case SPI_CMD_PARAMETER1:
237
                toNaviCtrl.Param.Byte[0] = staticParams.NaviGpsModeControl; // Parameters for the Naviboard
238
                toNaviCtrl.Param.Byte[1] = staticParams.NaviGpsGain;
239
                toNaviCtrl.Param.Byte[2] = staticParams.NaviGpsP;
240
                toNaviCtrl.Param.Byte[3] = staticParams.NaviGpsI;
241
                toNaviCtrl.Param.Byte[4] = staticParams.NaviGpsD;
242
                toNaviCtrl.Param.Byte[5] = staticParams.NaviGpsACC;
243
                toNaviCtrl.Param.Byte[6] = staticParams.NaviGpsMinSat;
244
                toNaviCtrl.Param.Byte[7] = staticParams.NaviStickThreshold;
245
                toNaviCtrl.Param.Byte[8] = staticParams.NaviOperatingRadius;
246
                toNaviCtrl.Param.Byte[9] = staticParams.NaviWindCorrection;
247
                toNaviCtrl.Param.Byte[10] = staticParams.NaviSpeedCompensation;
248
                toNaviCtrl.Param.Byte[11] = staticParams.NaviAngleLimitation;
249
                break;
250
 
251
        case SPI_CMD_STICK:
252
                tmp = PPM_in[staticParams.ChannelAssignment[CH_THROTTLE]];
253
                if (tmp > 127)
254
                        tmp = 127;
255
                else if (tmp < -128)
256
                        tmp = -128;
257
                toNaviCtrl.Param.Byte[0] = (int8_t) tmp;
258
                tmp = PPM_in[staticParams.ChannelAssignment[CH_YAW]];
259
                if (tmp > 127)
260
                        tmp = 127;
261
                else if (tmp < -128)
262
                        tmp = -128;
263
                toNaviCtrl.Param.Byte[1] = (int8_t) tmp;
264
                tmp = PPM_in[staticParams.ChannelAssignment[CH_ROLL]];
265
                if (tmp > 127)
266
                        tmp = 127;
267
                else if (tmp < -128)
268
                        tmp = -128;
269
                toNaviCtrl.Param.Byte[2] = (int8_t) tmp;
270
                tmp = PPM_in[staticParams.ChannelAssignment[CH_PITCH]];
271
                if (tmp > 127)
272
                        tmp = 127;
273
                else if (tmp < -128)
274
                        tmp = -128;
275
                toNaviCtrl.Param.Byte[3] = (int8_t) tmp;
276
                toNaviCtrl.Param.Byte[4] = (uint8_t) variables[0];
277
                toNaviCtrl.Param.Byte[5] = (uint8_t) variables[1];
278
                toNaviCtrl.Param.Byte[6] = (uint8_t) variables[2];
279
                toNaviCtrl.Param.Byte[7] = (uint8_t) variables[3];
280
                toNaviCtrl.Param.Byte[8] = (uint8_t) RC_Quality;
281
                break;
282
 
283
        case SPI_CMD_MISC:
284
                toNaviCtrl.Param.Byte[0] = compassCalState;
285
                if (compassCalState > 4) { // jump from 5 to 0
286
                        compassCalState = 0;
287
                }
288
                toNaviCtrl.Param.Byte[1] = staticParams.NaviPHLoginTime;
289
                // TODO: Height and in the correct scaling...
290
                toNaviCtrl.Param.Int[1] = 0; //readingHeight; // at address of Byte 2 and 3
291
                toNaviCtrl.Param.Byte[4] = staticParams.NaviGpsPLimit;
292
                toNaviCtrl.Param.Byte[5] = staticParams.NaviGpsILimit;
293
                toNaviCtrl.Param.Byte[6] = staticParams.NaviGpsDLimit;
294
                break;
295
 
296
        case SPI_CMD_VERSION:
297
                toNaviCtrl.Param.Byte[0] = SPI_VersionInfo.Major;
298
                toNaviCtrl.Param.Byte[1] = SPI_VersionInfo.Minor;
299
                toNaviCtrl.Param.Byte[2] = SPI_VersionInfo.Patch;
300
                toNaviCtrl.Param.Byte[3] = SPI_VersionInfo.Compatible;
301
                toNaviCtrl.Param.Byte[4] = BoardRelease;
302
                break;
303
        default:
304
                break;
305
        }
306
 
307
        sei();
308
        // enable all interrupts
309
 
310
        // analyze content of packet from NaviCtrl if valid
311
        if (SPI_RxDataValid) {
312
                // update gps controls
313
                if (abs(fromNaviCtrl.GPSStickPitch) < 512 && abs(fromNaviCtrl.GPSStickRoll)
314
                                < 512 && (staticParams.GlobalConfig & CFG_GPS_ACTIVE)) {
315
                        GPSStickPitch = fromNaviCtrl.GPSStickPitch;
316
                        GPSStickRoll = fromNaviCtrl.GPSStickRoll;
317
                        NCDataOkay = 250;
318
                }
319
                // update compass readings
320
                if (fromNaviCtrl.CompassHeading <= 360) {
321
                        compassHeading = fromNaviCtrl.CompassHeading;
322
                }
323
                //if(compassHeading < 0) compassOffCourse = 0;
324
                //else compassOffCourse = ((540 + compassHeading - compassCourse) % 360) - 180;
325
                // NaviCtrl wants to beep?
326
                if (fromNaviCtrl.BeepTime > BeepTime && !compassCalState)
327
                        BeepTime = fromNaviCtrl.BeepTime;
328
 
329
                switch (fromNaviCtrl.Command) {
330
                case SPI_KALMAN:
331
                        dynamicParams.KalmanK = fromNaviCtrl.Param.Byte[0];
332
                        dynamicParams.KalmanMaxFusion = fromNaviCtrl.Param.Byte[1];
333
                        dynamicParams.KalmanMaxDrift = fromNaviCtrl.Param.Byte[2];
334
                        NCSerialDataOkay = fromNaviCtrl.Param.Byte[3];
335
                        break;
336
 
337
                default:
338
                        break;
339
                }
340
        } else { // no valid data from NaviCtrl
341
                // disable GPS control
342
                GPSStickPitch = 0;
343
                GPSStickRoll = 0;
344
        }
1612 dongfang 345
}
346
 
347
/*********************************************/
348
/*  Start Transmission of packet to NaviCtrl */
349
/*********************************************/
1821 - 350
void SPI_StartTransmitPacket(void) {
351
        if (!SPITransferCompleted)
352
                return; // return immediately if transfer is in progress
353
        else // transmission was completed
354
        {
355
                SLAVE_SELECT_PORT &= ~(1 << SPI_SLAVE_SELECT); // Select slave
356
 
357
                // cyclic commands
358
                toNaviCtrl.Command = SPI_CommandSequence[SPI_CommandCounter++];
359
                if (SPI_CommandCounter >= sizeof(SPI_CommandSequence))
360
                        SPI_CommandCounter = 0;
361
 
362
                SPITransferCompleted = 0; // transfer is in progress
363
                UpdateSPI_Buffer(); // update data in toNaviCtrl
364
 
365
                SPI_TxBufferIndex = 1; //proceed with 2nd byte
366
 
367
                // -- Debug-Output ---
368
                //----
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
                asm volatile ("nop");
392
                asm volatile ("nop");
393
                toNaviCtrl.Chksum = toNaviCtrl.Sync1; // init checksum
394
                SPDR = toNaviCtrl.Sync1; // send first byte
395
        }
1612 dongfang 396
}
397
 
398
//------------------------------------------------------
399
// This is the spi data transfer between FlightCtrl and NaviCtrl
400
// Every time this routine is called within the mainloop one byte of the packet to
401
// the NaviCtrl and one byte of the packet from the NaviCtrl is possible transfered
402
 
403
void SPI_TransmitByte(void) {
1821 - 404
        static SPI_RXState_t SPI_RXState = SPI_SYNC1;
405
        uint8_t rxdata;
406
        static uint8_t rxchksum;
407
 
408
        if (SPITransferCompleted)
409
                return; // return immediatly if transfer was completed
410
        if (!(SPSR & (1 << SPIF)))
411
                return; // return if no SPI-IRQ pending
412
        SendSPI = 4; // mait 4 * 0.102 ms for the next call of SPI_TransmitByte() in the main loop
413
 
414
        SLAVE_SELECT_PORT |= (1 << SPI_SLAVE_SELECT); // DeselectSlave
415
 
416
        rxdata = SPDR; // save spi data register
417
 
418
        switch (SPI_RXState) {
419
        case SPI_SYNC1: // first sync byte
420
                SPI_RxBufferIndex = 0; // set pointer to start of rx buffer
421
                rxchksum = rxdata; // initialize checksum
422
                if (rxdata == SPI_RXSYNCBYTE1) { // 1st Syncbyte found
423
                        SPI_RXState = SPI_SYNC2; // trigger to state for second sync byte
424
                }
425
                break;
426
 
427
        case SPI_SYNC2: // second sync byte
428
                if (rxdata == SPI_RXSYNCBYTE2) { // 2nd Syncbyte found
429
                        rxchksum += rxdata; // update checksum
430
                        SPI_RXState = SPI_DATA; // trigger to state for second sync byte
431
                } else // 2nd Syncbyte not found
432
                {
433
                        SPI_RXState = SPI_SYNC1; // jump back to 1st sync byte
434
                }
435
                break;
436
 
437
        case SPI_DATA: // data bytes
438
                SPI_RxBuffer[SPI_RxBufferIndex++] = rxdata; // copy data byte to spi buffer
439
                // if all bytes are received of a packet from the NaviCtrl
440
                if (SPI_RxBufferIndex >= SPI_RXBUFFER_LEN) { // last byte transfered is the checksum of the packet
441
                        if (rxdata == rxchksum) { // checksum matching?
442
                                // copy SPI_RxBuffer -> FromFlightCtrl
443
                                uint8_t *ptr = (uint8_t *) &fromNaviCtrl;
444
                                cli();
445
                                memcpy(ptr, (uint8_t *) SPI_RxBuffer, sizeof(fromNaviCtrl));
446
                                sei();
447
                                SPI_RxDataValid = 1;
448
                        } else { // checksum does not match
449
                                SPI_RxDataValid = 0; // reset valid flag
450
                        }
451
                        SPI_RXState = SPI_SYNC1; // reset state sync
452
                } else { // not all bytes transfered
453
                        rxchksum += rxdata; // update checksum
454
                }
455
                break;
456
        }// eof switch(SPI_RXState)
457
 
458
        // if still some bytes left for transmission to NaviCtrl
459
        if (SPI_TxBufferIndex < SPI_TXBUFFER_LEN) {
460
                SLAVE_SELECT_PORT &= ~(1 << SPI_SLAVE_SELECT); // SelectSlave
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
                asm volatile ("nop");
484
                asm volatile ("nop");
485
 
486
                SPDR = SPI_TxBuffer[SPI_TxBufferIndex]; // transmit byte
487
                toNaviCtrl.Chksum += SPI_TxBuffer[SPI_TxBufferIndex]; // update checksum for everey byte that was sent
488
                SPI_TxBufferIndex++;
489
        } else {
490
                //Transfer of all bytes of the packet to NaviCtrl completed
491
                SPITransferCompleted = 1;
492
        }
1612 dongfang 493
}