Subversion Repositories FlightCtrl

Rev

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

Rev 1657 Rev 1662
-
 
1
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
 
2
// + Copyright (c) Holger Buss, Ingo Busker
-
 
3
// + Nur für den privaten Gebrauch
-
 
4
// + www.MikroKopter.com
-
 
5
// + porting the sources to other systems or using the software on other systems (except hardware from www.mikrokopter.de) is not allowed
-
 
6
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
 
7
// + Es gilt für das gesamte Projekt (Hardware, Software, Binärfiles, Sourcecode und Dokumentation),
-
 
8
// + dass eine Nutzung (auch auszugsweise) nur für den privaten (nicht-kommerziellen) Gebrauch zulässig ist.
-
 
9
// + Sollten direkte oder indirekte kommerzielle Absichten verfolgt werden, ist mit uns (info@mikrokopter.de) Kontakt
-
 
10
// + bzgl. der Nutzungsbedingungen aufzunehmen.
-
 
11
// + Eine kommerzielle Nutzung ist z.B.Verkauf von MikroKoptern, Bestückung und Verkauf von Platinen oder Bausätzen,
-
 
12
// + Verkauf von Luftbildaufnahmen, usw.
-
 
13
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
 
14
// + Werden Teile des Quellcodes (mit oder ohne Modifikation) weiterverwendet oder veröffentlicht,
-
 
15
// + unterliegen sie auch diesen Nutzungsbedingungen und diese Nutzungsbedingungen incl. Copyright müssen dann beiliegen
-
 
16
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
 
17
// + Sollte die Software (auch auszugesweise) oder sonstige Informationen des MikroKopter-Projekts
-
 
18
// + auf anderen Webseiten oder sonstigen Medien veröffentlicht werden, muss unsere Webseite "http://www.mikrokopter.de"
-
 
19
// + eindeutig als Ursprung verlinkt werden
-
 
20
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
 
21
// + Keine Gewähr auf Fehlerfreiheit, Vollständigkeit oder Funktion
-
 
22
// + Benutzung auf eigene Gefahr
-
 
23
// + Wir übernehmen keinerlei Haftung für direkte oder indirekte Personen- oder Sachschäden
-
 
24
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
 
25
// + Die Portierung der Software (oder Teile davon) auf andere Systeme (ausser der Hardware von www.mikrokopter.de) ist nur
-
 
26
// + mit unserer Zustimmung zulässig
-
 
27
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
 
28
// + Die Funktion printf_P() unterliegt ihrer eigenen Lizenz und ist hiervon nicht betroffen
-
 
29
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
 
30
// + Redistributions of source code (with or without modifications) must retain the above copyright notice,
-
 
31
// + this list of conditions and the following disclaimer.
-
 
32
// +   * Neither the name of the copyright holders nor the names of contributors may be used to endorse or promote products derived
-
 
33
// +     from this software without specific prior written permission.
-
 
34
// +   * The use of this project (hardware, software, binary files, sources and documentation) is only permittet
-
 
35
// +     for non-commercial use (directly or indirectly)
-
 
36
// +     Commercial use (for excample: selling of MikroKopters, selling of PCBs, assembly, ...) is only permitted
-
 
37
// +     with our written permission
-
 
38
// +   * If sources or documentations are redistributet on other webpages, out webpage (http://www.MikroKopter.de) must be
-
 
39
// +     clearly linked as origin
-
 
40
// +   * porting to systems other than hardware from www.mikrokopter.de is not allowed
-
 
41
// +  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-
 
42
// +  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-
 
43
// +  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1
/*############################################################################
44
// +  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-
 
45
// +  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-
 
46
// +  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2
############################################################################*/
47
// +  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-
 
48
// +  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN// +  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-
 
49
// +  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-
 
50
// +  POSSIBILITY OF SUCH DAMAGE.
-
 
51
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
 
52
 
-
 
53
#include <avr/io.h>
-
 
54
#include <avr/interrupt.h>
-
 
55
#include <util/twi.h>
-
 
56
#include "eeprom.h"
-
 
57
#include "twimaster.h"
-
 
58
#include "fc.h"
-
 
59
#include "analog.h"
-
 
60
 
-
 
61
volatile uint8_t twi_state      = TWI_STATE_MOTOR_TX;
-
 
62
volatile uint8_t dac_channel    = 0;
-
 
63
volatile uint8_t motor_write    = 0;
-
 
64
volatile uint8_t motor_read     = 0;
3
 
-
 
4
#include "main.h"
-
 
5
 
65
 
6
volatile unsigned char twi_state = 0;
-
 
7
volatile unsigned char motor = 0;
-
 
8
volatile unsigned char motorread = 0,MissingMotor = 0;
66
 
-
 
67
volatile uint16_t I2CTimeout = 100;
9
volatile unsigned char BLFlags = 0;
68
 
10
 
69
uint8_t MissingMotor  = 0;
-
 
70
 
11
MotorData_t Motor[MAX_MOTORS];
71
volatile uint8_t BLFlags = 0;
-
 
72
 
-
 
73
MotorData_t Motor[MAX_MOTORS];
12
 
74
 
-
 
75
// bit mask for witch BL the configuration should be sent
-
 
76
volatile uint16_t BLConfig_WriteMask = 0;
-
 
77
// bit mask for witch BL the configuration should be read
13
 
78
volatile uint16_t BLConfig_ReadMask = 0;
14
unsigned int I2CError = 0;
79
// buffer for BL Configuration
-
 
80
BLConfig_t BLConfig;
15
 
81
 
-
 
82
#define I2C_WriteByte(byte) {TWDR = byte; TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWIE);}
-
 
83
#define I2C_ReceiveByte() {TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWIE) | (1<<TWEA);}
-
 
84
#define I2C_ReceiveLastByte() {TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWIE);}
-
 
85
 
-
 
86
#define SCL_CLOCK  200000L
-
 
87
#define I2C_TIMEOUT 30000
-
 
88
#define TWI_BASE_ADDRESS 0x52
16
//############################################################################
89
 
-
 
90
/**************************************************/
-
 
91
/*   Initialize I2C (TWI)                         */
-
 
92
/**************************************************/
-
 
93
 
-
 
94
void I2C_Init(void)
-
 
95
{
-
 
96
        uint8_t i;
-
 
97
        uint8_t sreg = SREG;
-
 
98
        cli();
-
 
99
 
-
 
100
        // SDA is INPUT
-
 
101
        DDRC  &= ~(1<<DDC1);
-
 
102
        // SCL is output
-
 
103
        DDRC |= (1<<DDC0);
-
 
104
        // pull up SDA
17
//Initzialisieren der I2C (TWI) Schnittstelle
105
        PORTC |= (1<<PORTC0)|(1<<PORTC1);
-
 
106
 
-
 
107
        // TWI Status Register
-
 
108
        // prescaler 1 (TWPS1 = 0, TWPS0 = 0)
-
 
109
        TWSR &= ~((1<<TWPS1)|(1<<TWPS0));
18
void i2c_init(void)
110
 
19
//############################################################################
111
        // set TWI Bit Rate Register
20
{
112
        TWBR = ((F_CPU/SCL_CLOCK)-16)/2;
21
        unsigned char i;
113
 
22
 
114
        twi_state               = TWI_STATE_MOTOR_TX;
23
        TWSR = 0;
115
        motor_write     = 0;
24
        TWBR = ((SYSCLK/SCL_CLOCK)-16)/2;
116
        motor_read              = 0;
25
 
117
 
26
        for(i=0; i < MAX_MOTORS; i++)
118
        for(i=0; i < MAX_MOTORS; i++)
27
        {
119
        {
28
                Motor[i].Version        = 0;
120
                Motor[i].Version        = 0;
29
                Motor[i].SetPoint       = 0;
121
                Motor[i].SetPoint       = 0;
30
                Motor[i].SetPointLowerBits      = 0;
122
                Motor[i].SetPointLowerBits      = 0;
31
                Motor[i].State          = 0;
123
                Motor[i].State          = 0;
32
                Motor[i].Current        = 0;
124
                Motor[i].Current        = 0;
33
                Motor[i].MaxPWM         = 0;
125
                Motor[i].MaxPWM         = 0;
34
                BLConfig[i].SetMask =   MASK_SET_PWM_SCALING|MASK_SET_CURRENT_LIMIT|MASK_SET_TEMP_LIMIT|MASK_SET_CURRENT_SCALING|MASK_SET_BITCONFIG;
-
 
35
                BLConfig[i].PwmScaling = 255;           // MaxPWM
-
 
36
                BLConfig[i].CurrentLimit = 30;          // Current Limit in A
-
 
37
                BLConfig[i].TempLimit = 99;                     // Temperature Limit in °C
-
 
38
                BLConfig[i].CurrentScaling = 64;        // Current Scaling
-
 
39
                BLConfig[i].BitConfig = 0;                      // BitConfig
-
 
40
        }
126
        }
-
 
127
 
-
 
128
        SREG = sreg;
41
}
129
}
42
 
130
 
43
void i2c_reset(void)
-
 
44
//############################################################################
131
void I2C_Reset(void)
45
{
132
{
46
        I2C_Stop();
133
        // stop i2c bus
47
        twi_state = 0;
134
        I2C_Stop(TWI_STATE_MOTOR_TX);
48
        motor = TWDR;
135
        motor_write     = 0;
49
        motor = 0;
136
        motor_read              = 0;
50
        TWCR = 0x80;
137
        TWCR = (1<<TWINT); // reset to original state incl. interrupt flag reset
51
        TWAMR = 0;
138
        TWAMR = 0;
52
        TWAR = 0;
139
        TWAR = 0;
53
        TWDR = 0;
140
        TWDR = 0;
54
        TWSR = 0;
141
        TWSR = 0;
55
        TWBR = 0;
142
        TWBR = 0;
56
        i2c_init();
143
        I2C_Init();
57
        I2C_Start();
144
        I2C_WriteByte(0);
58
        i2c_write_byte(0);
145
        BLFlags |= BLFLAG_READ_VERSION;
59
}
146
}
60
 
-
 
-
 
147
 
-
 
148
/****************************************/
61
 
149
/*        I2C ISR                       */
62
//############################################################################
150
/****************************************/
63
SIGNAL (TWI_vect)
-
 
64
//############################################################################
151
ISR (TWI_vect)
65
{
152
{
66
        static unsigned char missing_motor = 0, byte_counter = 0, read_more = 0, motorread_temperature = 0;
153
        static uint8_t missing_motor = 0, motor_read_temperature = 0;
-
 
154
        static uint8_t *pBuff = 0;
-
 
155
        static uint8_t BuffLen = 0;
-
 
156
 
-
 
157
        #define BL_READ_STATUS  0
-
 
158
        #define BL_READ_CONFIG  16
67
        static unsigned char *pTxBuff;
159
        static uint8_t BLReadMode = BL_READ_STATUS;
68
J4High;
160
 
69
        switch(twi_state++)
161
    switch (twi_state++)
70
        {
-
 
71
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
162
        {
72
// Writing the Data
163
                // Master Transmit
-
 
164
        case 0: // TWI_STATE_MOTOR_TX
73
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
165
 
74
                case 0:
166
                        // skip motor if not used in mixer
75
                        while(Mixer.Motor[motor][MIX_GAS] <= 0 && motor < MAX_MOTORS) motor++;  // skip if not used
167
                        while((Mixer.Motor[motor_write][MIX_GAS] <= 0) && (motor_write < MAX_MOTORS)) motor_write++;
76
                        if(motor == MAX_MOTORS)  // writing finished -> now read
168
                        if(motor_write >= MAX_MOTORS) // writing finished, read now
-
 
169
                        {
77
                        {
170
                                BLConfig_WriteMask = 0; // reset configuration bitmask
78
                                motor = 0;
171
                                motor_write = 0; // reset motor write counter for next cycle
79
                                twi_state = 5;
172
                                twi_state = TWI_STATE_MOTOR_RX;
80
                                i2c_write_byte(0x53+(motorread*2));
173
                                I2C_WriteByte(TWI_BASE_ADDRESS + TW_READ + (motor_read<<1) ); // select slave address in rx mode
81
                        }
174
                        }
82
                                else i2c_write_byte(0x52+(motor*2));
175
                        else I2C_WriteByte(TWI_BASE_ADDRESS + TW_WRITE + (motor_write<<1) ); // select slave address in tx mode
83
                        break;
176
                        break;
84
                case 1:
177
        case 1: // Send Data to Slave
-
 
178
                        I2C_WriteByte(Motor[motor_write].SetPoint); // transmit setpoint
85
                        i2c_write_byte(Motor[motor].SetPoint);
179
                        // if old version has been detected
86
                        if(!(Motor[motor].Version & MOTOR_STATE_NEW_PROTOCOL_MASK))
180
                        if(!(Motor[motor_write].Version & MOTOR_STATE_NEW_PROTOCOL_MASK))
87
                        {
181
                        {
88
                                twi_state = 4; //jump over sending more data
182
                                twi_state = 4; //jump over sending more data
89
                        }
183
                        }
-
 
184
                        // the new version has been detected
90
                        else if(!( (Motor[motor].SetPointLowerBits && RequiredMotors < 7) || (BLFlags & BLFLAG_SEND_CONFIG)))
185
                        else if(!( (Motor[motor_write].SetPointLowerBits && (RequiredMotors < 7)) || BLConfig_WriteMask || BLConfig_ReadMask )  )
91
                        {
-
 
-
 
186
                        {       // or LowerBits are zero and no BlConfig should be sent (saves round trip time)
92
                                twi_state = 4; // skip state
187
                                twi_state = 4; //jump over sending more data
93
                        }
188
                        }
94
                        break;
189
                        break;
95
                case 2: // lower bits of setpoint (higher resolution)
190
        case 2: // lower bits of setpoint (higher resolution)
96
                        i2c_write_byte((Motor[motor].SetPointLowerBits << 1) & 0x07); // send the lower bits of setpoint
-
 
97
                        // transmit config only on demand and the motors are not running and only for one motor per round trip
-
 
98
                        if( (BLFlags & BLFLAG_SEND_CONFIG) && (motor == motorread))
191
                        if ((motor_write == motor_read) && ((0x0001<<motor_read) & BLConfig_ReadMask))
-
 
192
                        {
99
                        {       // prepare sending of configuration
193
                                BLReadMode = BL_READ_CONFIG; // configuration request
100
                                byte_counter = 0;       // reset send byte counter
-
 
101
                        }
194
                        }
102
                        else
195
                        else
103
                        {       // jump to state for end of transmission for that motor
-
 
104
                                twi_state = 4;
-
 
105
                        }
-
 
106
                        break;
-
 
107
                case 3:
-
 
108
                        if(!byte_counter) // first byte?
-
 
109
                        {
196
                        {
110
                                pTxBuff = (uint8_t*)&BLConfig[motor]; // select configuration for motor
-
 
111
                                i2c_write_byte(pTxBuff[byte_counter]);
-
 
112
                                twi_state = 3; // keep state 3
197
                                BLReadMode = BL_READ_STATUS; // normal status request
113
                        }
198
                        }
114
                        else if(byte_counter >= sizeof(BLConfig_t))
199
                        // send read mode and the lower bits of setpoint
-
 
200
                I2C_WriteByte((BLReadMode<<3)|(Motor[motor_write].SetPointLowerBits & 0x07));
115
                        {
201
                        // configuration tranmission request?
116
                                i2c_write_byte(0);
202
                        if((0x0001<<motor_write) & BLConfig_WriteMask)
117
                                // jump to case 4
203
                        {       // redirect tx pointer to configuration data
-
 
204
                                pBuff = (uint8_t*)&BLConfig; // select config for motor
-
 
205
                                BuffLen = sizeof(BLConfig_t);
118
                        }
206
                        }
119
            else // transmit configuration to BLs
-
 
120
                        {
207
                        else
121
                                i2c_write_byte(pTxBuff[byte_counter]);  // submit next byte
208
                        {       // jump to end of transmission for that motor
122
                                twi_state = 3;// keep state 3
209
                                twi_state = 4;
123
                        }
210
                        }
124
                        byte_counter++; // next byte
-
 
125
                        break;
211
                        break;
126
        case 4:
212
                case 3: // send configuration
127
 
-
 
128
                        if(TWSR == 0x30)
213
                        I2C_WriteByte(*pBuff);
-
 
214
                        pBuff++;
-
 
215
                        if(--BuffLen > 0) twi_state = 3; // if there are some bytes left
-
 
216
                        break;
-
 
217
        case 4: // repeat case 0-4 for all motors
-
 
218
                        if(TWSR == TW_MT_DATA_NACK) // Data transmitted, NACK received
129
                        {
219
                        {
130
                                if(!missing_motor) missing_motor = motor + 1;
220
                                if(!missing_motor) missing_motor = motor_write + 1;
131
                                if((Motor[motor].State & MOTOR_STATE_ERROR_MASK) < MOTOR_STATE_ERROR_MASK) Motor[motor].State++; // increment error counter and handle overflow
221
                                if((Motor[motor_write].State & MOTOR_STATE_ERROR_MASK) < MOTOR_STATE_ERROR_MASK) Motor[motor_write].State++; // increment error counter and handle overflow
132
                        }
222
                        }
133
                        I2C_Stop();
223
                        I2C_Stop(TWI_STATE_MOTOR_TX);
134
                        I2CTimeout = 10;
224
                        I2CTimeout = 10;
135
                        motor++;
-
 
136
                        twi_state = 0;
225
                        motor_write++; // next motor
137
                        I2C_Start();
226
                        I2C_Start(TWI_STATE_MOTOR_TX); // Repeated start -> switch slave or switch Master Transmit -> Master Receive
138
                        break;
227
                        break;
139
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
 
140
// Reading Data
228
       // Master Receive Data
141
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
 
142
        case 5:
229
        case 5: // TWI_STATE_MOTOR_RX
143
                        //Transmit 1st byte for reading
230
                        if(TWSR != TW_MR_SLA_ACK) //  SLA+R transmitted but no ACK received
144
                        if(TWSR != 0x40)  // Error?
231
                        {       // no response from the addressed slave received
145
                        {
-
 
146
                                Motor[motorread].State &= ~MOTOR_STATE_PRESENT_MASK; // clear present bit
232
                                Motor[motor_read].State &= ~MOTOR_STATE_PRESENT_MASK; // clear present bit
147
                                if(++motorread >= MAX_MOTORS)
233
                                if(++motor_read >= MAX_MOTORS)
148
                                {
234
                                {       // all motors read
149
                                        BLFlags &= ~BLFLAG_SEND_CONFIG;
235
                                        motor_read = 0;                 // restart from beginning
150
                                        motorread = 0;
236
                                        BLConfig_ReadMask = 0;  // reset read configuration bitmask
151
                                        if(++motorread_temperature >= MAX_MOTORS)
237
                                        if(++motor_read_temperature >= MAX_MOTORS)
152
                                        {
238
                                        {
153
                                                motorread_temperature = 0;
239
                                                motor_read_temperature = 0;
154
                                                BLFlags &= ~BLFLAG_READ_VERSION;
240
                                                BLFlags &= ~BLFLAG_READ_VERSION;
155
                                        }
241
                                        }
156
                                }
242
                                }
157
                                I2C_Stop();
-
 
158
                                twi_state = 0;
-
 
159
                                BLFlags |= BLFLAG_TX_COMPLETE;
243
                                BLFlags |= BLFLAG_TX_COMPLETE;
-
 
244
                                I2C_Stop(TWI_STATE_MOTOR_TX);
160
                        }
245
                        }
161
                        else
246
                        else
-
 
247
                        {       // motor successfully addressed
-
 
248
                                Motor[motor_read].State |= MOTOR_STATE_PRESENT_MASK; // set present bit
-
 
249
 
-
 
250
                                if(Motor[motor_read].Version & MOTOR_STATE_NEW_PROTOCOL_MASK)
162
                        {
251
                                {
-
 
252
                                        // new BL found
-
 
253
                                        switch(BLReadMode)
-
 
254
                                        {
-
 
255
                                                case BL_READ_CONFIG:
-
 
256
                                                        pBuff = (uint8_t*)&BLConfig;
-
 
257
                                                        BuffLen = sizeof(BLConfig_t);
-
 
258
                                                        break;
-
 
259
 
-
 
260
                                                case BL_READ_STATUS:
163
                                Motor[motorread].State |= MOTOR_STATE_PRESENT_MASK; // set present bit
261
                                                        pBuff = (uint8_t*)&(Motor[motor_read].Current);
164
                                if( (motorread == motorread_temperature) || (BLFlags & BLFLAG_READ_VERSION) )
262
                                                        if(motor_read == motor_read_temperature) BuffLen = 3; // read Current, MaxPwm & Temp
-
 
263
                                                        else BuffLen = 1;// read Current only
-
 
264
                                                        break;
-
 
265
                                        }
-
 
266
                                }
-
 
267
                                else // old BL version
165
                                {
268
                                {
-
 
269
                                        pBuff = (uint8_t*)&(Motor[motor_read].Current);
-
 
270
                                        if(BLFlags & BLFLAG_READ_VERSION) BuffLen = 2; // Current & MaxPwm
-
 
271
                                        else BuffLen = 1; // read Current only
-
 
272
                                }
166
                                        read_more = 1;
273
                                if(BuffLen == 1)
-
 
274
                                {
167
                                        I2C_ReceiveByte();
275
                                        I2C_ReceiveLastByte();  // read last byte
168
                                }
276
                                }
169
                                else
277
                                else
170
                                {
278
                                {
171
                                        read_more = 0;
-
 
172
                                        I2C_ReceiveLastByte();
279
                                        I2C_ReceiveByte();              // read next byte
173
                                }
280
                                }
174
                        }
281
                        }
175
                        MissingMotor = missing_motor;
282
                        MissingMotor = missing_motor;
176
                        missing_motor = 0;
283
                        missing_motor = 0;
177
                        break;
284
                        break;
178
        case 6: //Read 1st byte and transmit 2nd Byte
285
                case 6: // receive bytes
179
                Motor[motorread].Current = TWDR;
286
                        *pBuff = TWDR;
-
 
287
                        pBuff++;
180
                if(read_more)
288
                        BuffLen--;
181
                {
289
                        if(BuffLen>1)
-
 
290
                        {
182
                                        I2C_ReceiveByte() //ack
291
                                I2C_ReceiveByte(); // read next byte
-
 
292
                        }
-
 
293
                        else if (BuffLen == 1)
183
 
294
                        {
-
 
295
                                I2C_ReceiveLastByte();  // read last byte
184
                                }
296
                        }
-
 
297
                        else // nothing left
185
                                else
298
                        {
-
 
299
                                if(BLFlags & BLFLAG_READ_VERSION)
186
                                {
300
                                {
187
                                        if(++motorread >= MAX_MOTORS)
-
 
188
                                        {
-
 
189
                                                motorread = 0;          // restart from beginning
-
 
190
                                                BLFlags &= ~BLFLAG_SEND_CONFIG;
-
 
191
                                                if(++motorread_temperature >= MAX_MOTORS)
301
                                        if(!(FCFlags & FCFLAG_MOTOR_RUN) && (Motor[motor_read].MaxPWM == 250) ) Motor[motor_read].Version |= MOTOR_STATE_NEW_PROTOCOL_MASK;
192
                                                {
-
 
193
                                                        motorread_temperature = 0;
302
                                        else Motor[motor_read].Version = 0;
194
                                                        BLFlags &= ~BLFLAG_READ_VERSION;
-
 
195
                                                }
-
 
196
                                        }
-
 
197
                                        I2C_Stop();
-
 
198
                                        twi_state = 0;
-
 
199
                                        BLFlags |= BLFLAG_TX_COMPLETE;
-
 
200
                                }
303
                                }
201
                break;
-
 
202
        case 7:
-
 
203
                       //Read 2nd byte and transmit 3rd Byte
-
 
204
                Motor[motorread].MaxPWM = TWDR;
304
                                if(++motor_read >= MAX_MOTORS)
205
                if(BLFlags & BLFLAG_READ_VERSION)
-
 
206
                                {
305
                                {
207
                                        if(TWDR == 250)
306
                                        motor_read = 0;                 // restart from beginning
208
                                        {
-
 
209
                                                if(!MotorenEin) Motor[motorread].Version |= MOTOR_STATE_NEW_PROTOCOL_MASK;
307
                                        BLConfig_ReadMask = 0;  // reset read configuration bitmask
210
                                        }
-
 
211
                                        else
308
                                        if(++motor_read_temperature >= MAX_MOTORS)
212
                                        {
309
                                        {
213
                                                Motor[motorread].Version = 0;
310
                                                motor_read_temperature = 0;
-
 
311
                                                BLFlags &= ~BLFLAG_READ_VERSION;
214
                                        }
312
                                        }
215
                                }
313
                                }
216
                                I2C_ReceiveLastByte(); //nack
-
 
217
                break;
-
 
218
        case 8: // read next
-
 
219
                                Motor[motorread].Temperature = TWDR;
-
 
220
                                if(++motorread >= MAX_MOTORS)
314
                                I2C_Stop(TWI_STATE_MOTOR_TX);
221
                                {
-
 
222
                                        motorread = 0; // restart reading of first motor
-
 
223
                                        BLFlags &= ~BLFLAG_SEND_CONFIG;
315
                                BLFlags |= BLFLAG_TX_COMPLETE;
224
                                        if(++motorread_temperature >= MAX_MOTORS)
-
 
225
                                        {
-
 
226
                                                motorread_temperature = 0;
-
 
227
                                                BLFlags &= ~BLFLAG_READ_VERSION;
-
 
228
                                        }
316
                                return;
229
                                }
317
                        }
230
                I2C_Stop();
-
 
231
                BLFlags |= BLFLAG_TX_COMPLETE;
318
                        twi_state = 6; // if there are some bytes left
232
                twi_state = 0;
-
 
233
                                break;
319
                        break;
234
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
 
-
 
320
 
235
// writing Gyro-Offset
321
                // writing Gyro-Offsets
236
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
 
237
        case 18:
322
                case 18:
238
                i2c_write_byte(0x98); // Address of the DAC
323
                        I2C_WriteByte(0x98); // Address the DAC
239
                break;
324
                        break;
-
 
325
 
240
        case 19:
326
                case 19:
241
                i2c_write_byte(0x10); // Update Channel A
327
                        I2C_WriteByte(0x10 + (dac_channel * 2)); // Select DAC Channel (0x10 = A, 0x12 = B, 0x14 = C)
242
                break;
328
                        break;
-
 
329
 
243
        case 20:
330
                case 20:
244
                i2c_write_byte(AnalogOffsetNick); // Value
-
 
245
                break;
331
                        switch(dac_channel)
246
        case 21:
332
                        {
247
                i2c_write_byte(0x80); // Value
-
 
248
                break;
-
 
249
        case 22:
333
                                case 0:
250
                I2C_Stop();
-
 
251
                I2CTimeout = 10;
334
                                                I2C_WriteByte(AnalogOffsetNick); // 1st byte for Channel A
252
                I2C_Start();
-
 
253
                break;
335
                                                break;
254
        case 23:
336
                                case 1:
255
                i2c_write_byte(0x98); // Address of the DAC
337
                                                I2C_WriteByte(AnalogOffsetRoll); // 1st byte for Channel B
256
                break;
338
                                                break;
257
        case 24:
339
                                case 2:
258
                i2c_write_byte(0x12); // Update Channel B
340
                                                I2C_WriteByte(AnalogOffsetGier); // 1st byte for Channel C
259
                break;
341
                                                break;
260
        case 25:
342
                        }
261
                i2c_write_byte(AnalogOffsetRoll); // Value
-
 
262
                break;
343
                        break;
-
 
344
 
263
        case 26:
345
                case 21:
264
                i2c_write_byte(0x80); // Value
346
                        I2C_WriteByte(0x80); // 2nd byte for all channels is 0x80
265
                break;
347
                        break;
-
 
348
 
266
        case 27:
349
                case 22:
267
                I2C_Stop();
350
                        I2C_Stop(TWI_STATE_MOTOR_TX);
268
                I2CTimeout = 10;
351
                        I2CTimeout = 10;
269
                I2C_Start();
352
                        // repeat case 7...10 until all DAC Channels are updated
270
                break;
353
                        if(dac_channel < 2)
271
        case 28:
354
                        {
272
                i2c_write_byte(0x98); // Address of the DAC
355
                                dac_channel ++;         // jump to next channel
273
                break;
-
 
274
        case 29:
-
 
275
                i2c_write_byte(0x14); // Update Channel C
356
                                I2C_Start(TWI_STATE_GYRO_OFFSET_TX);            // start transmission for next channel
276
                break;
357
                        }
277
        case 30:
358
                        else
278
                i2c_write_byte(AnalogOffsetGier); // Value
-
 
279
                break;
359
                        {       // data to last motor send
280
        case 31:
-
 
281
                i2c_write_byte(0x80); // Value
360
                                dac_channel = 0; // reset dac channel counter
-
 
361
                        }
282
                break;
362
                        break;
-
 
363
 
283
        case 32:
364
        default:
284
                I2C_Stop();
365
                        I2C_Stop(TWI_STATE_MOTOR_TX);
285
                I2CTimeout = 10;
366
                        BLFlags |= BLFLAG_TX_COMPLETE;
286
                twi_state = 0;
367
                        I2CTimeout = 10;
287
                break;
368
                        motor_write = 0;
288
        default: twi_state = 0;
369
                        motor_read = 0;
289
                break;
370
                        break;
290
        }
371
        }
291
        TWCR |= 0x80;
-
 
292
        J4Low;
372
 
293
}
373
}
-
 
374
 
294
 
375
 
295
void I2C_SendBLConfig(void)
376
uint8_t I2C_WriteBLConfig(uint8_t motor)
296
{
377
{
-
 
378
        uint8_t i;
-
 
379
 
-
 
380
        if(MotorenEin) return(0);       // not when motors are running!
297
        unsigned char i;
381
        if(motor > MAX_MOTORS) return (0);                      // motor does not exist!
-
 
382
        if(motor)
-
 
383
        {
-
 
384
                if(!(Motor[motor-1].State & MOTOR_STATE_PRESENT_MASK)) return(0); // motor does not exist!
-
 
385
                if(!(Motor[motor-1].Version & MOTOR_STATE_NEW_PROTOCOL_MASK)) return(0); // not a new BL!
-
 
386
        }
-
 
387
        // check BL configuration to send
-
 
388
        if(BLConfig.Revision != BLCONFIG_REVISION) return (0); // bad revison
-
 
389
        i = RAM_Checksum((uint8_t*)&BLConfig, sizeof(BLConfig_t) - 1);
-
 
390
        if(i != BLConfig.crc) return(0); // bad checksum
298
        if(MotorenEin) return;
391
 
-
 
392
        while(!(BLFlags & BLFLAG_TX_COMPLETE));         //wait for complete transfer
-
 
393
 
-
 
394
        // prepare the bitmask
-
 
395
        if(!motor) // 0 means all
299
        while(!(BLFlags & BLFLAG_TX_COMPLETE)); //wait for complete transfer
396
        {
-
 
397
                BLConfig_WriteMask = 0xFF; // all motors at once with the same configuration
300
        BLFlags |= BLFLAG_SEND_CONFIG; // enable sending of BL config
398
        }
-
 
399
        else //only one specific motor
-
 
400
        {
-
 
401
                BLConfig_WriteMask = 0x0001<<(motor-1);
-
 
402
        }
301
        // setpoints should be zero
403
 
302
        for(i = 0; i < MAX_MOTORS; i++)
404
        for(i = 0; i < MAX_MOTORS; i++)
-
 
405
        {
-
 
406
                if((0x0001<<i) & BLConfig_WriteMask)
303
        {
407
                {
304
                Motor[i].SetPoint = 0;
408
                        Motor[i].SetPoint = 0;
-
 
409
                        Motor[i].SetPointLowerBits = 0;
305
                Motor[i].SetPointLowerBits = 0;
410
                }
306
        }
411
        }
307
        motorread = 0;
412
        motor_write = 0;
308
        // needs at least MAX_MOTORS loops of 2 ms (12*2ms = 24ms)
413
        // needs at least MAX_MOTORS loops of 2 ms (12*2ms = 24ms)
309
        do
414
        do
310
        {
415
        {
311
                twi_state = 0;
-
 
312
                I2C_Start(); // start an i2c transmission
416
                I2C_Start(TWI_STATE_MOTOR_TX); // start an i2c transmission
313
                while(!(BLFlags & BLFLAG_TX_COMPLETE)); //wait for complete transfer
417
                while(!(BLFlags & BLFLAG_TX_COMPLETE)); //wait for complete transfer
314
        }while(BLFlags & BLFLAG_SEND_CONFIG); // repeat until the BL config has been send to all motors
418
        }while(BLConfig_WriteMask); // repeat until the BL config has been sent
-
 
419
        return(1);
315
}
420
}
-
 
421
 
-
 
422
uint8_t I2C_ReadBLConfig(uint8_t motor)
-
 
423
{
-
 
424
        uint8_t i;
-
 
425
 
-
 
426
        if(MotorenEin) return(0);                                       // not when motors are running!
-
 
427
        if((motor == 0) || (motor > MAX_MOTORS)) return (0);            // motor does not exist!
-
 
428
        if(!(Motor[motor-1].State & MOTOR_STATE_PRESENT_MASK)) return(0); // motor does not exist!
-
 
429
        if(!(Motor[motor-1].Version & MOTOR_STATE_NEW_PROTOCOL_MASK)) return(0); // not a new BL!
-
 
430
        while(!(BLFlags & BLFLAG_TX_COMPLETE));                                 //wait for complete transfer
-
 
431
 
-
 
432
        // prepare the bitmask
-
 
433
        BLConfig_ReadMask = 0x0001<<(motor-1);
-
 
434
        for(i = 0; i < MAX_MOTORS; i++)
-
 
435
        {
-
 
436
                if((0x0001<<i) & BLConfig_ReadMask)
-
 
437
                {
-
 
438
                        Motor[i].SetPoint = 0;
-
 
439
                        Motor[i].SetPointLowerBits = 0;
-
 
440
                }
-
 
441
        }
-
 
442
        motor_read = 0;
-
 
443
        BLConfig.Revision = 0; // bad revision
-
 
444
        BLConfig.crc = 0;          // bad checksum
-
 
445
        // needs at least MAX_MOTORS loops of 2 ms (12*2ms = 24ms)
-
 
446
        do
-
 
447
        {
-
 
448
                I2C_Start(TWI_STATE_MOTOR_TX); // start an i2c transmission
-
 
449
                while(!(BLFlags & BLFLAG_TX_COMPLETE)); //wait for complete transfer
-
 
450
        }while(BLConfig_ReadMask); // repeat until the BL config has been received from all motors
-
 
451
        // validate result
-
 
452
        if(BLConfig.Revision != BLCONFIG_REVISION) return (0); // bad revison
-
 
453
        i = RAM_Checksum((uint8_t*)&BLConfig, sizeof(BLConfig_t) - 1);
316
 
454
        if(i != BLConfig.crc) return(0); // bad checksum
317
 
455
        return(1);
318
 
456
}
319
 
457