Subversion Repositories NaviCtrl

Rev

Rev 913 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
482 killagreg 1
/*#######################################################################################*/
2
/* !!! THIS IS NOT FREE SOFTWARE !!!                                                     */
3
/*#######################################################################################*/
4
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
5
// + www.MikroKopter.com
6
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
7
// + Software Nutzungsbedingungen (english version: see below)
8
// + der Fa. HiSystems GmbH, Flachsmeerstrasse 2, 26802 Moormerland - nachfolgend Lizenzgeber genannt -
9
// + Der Lizenzgeber räumt dem Kunden ein nicht-ausschließliches, zeitlich und räumlich* unbeschränktes Recht ein, die im den
10
// + Mikrocontroller verwendete Firmware für die Hardware Flight-Ctrl, Navi-Ctrl, BL-Ctrl, MK3Mag & PC-Programm MikroKopter-Tool 
11
// + - nachfolgend Software genannt - nur für private Zwecke zu nutzen.
12
// + Der Einsatz dieser Software ist nur auf oder mit Produkten des Lizenzgebers zulässig.
13
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
14
// + Die vom Lizenzgeber gelieferte Software ist urheberrechtlich geschützt. Alle Rechte an der Software sowie an sonstigen im
15
// + Rahmen der Vertragsanbahnung und Vertragsdurchführung überlassenen Unterlagen stehen im Verhältnis der Vertragspartner ausschließlich dem Lizenzgeber zu.
16
// + Die in der Software enthaltenen Copyright-Vermerke, Markenzeichen, andere Rechtsvorbehalte, Seriennummern sowie
17
// + sonstige der Programmidentifikation dienenden Merkmale dürfen vom Kunden nicht verändert oder unkenntlich gemacht werden.
18
// + Der Kunde trifft angemessene Vorkehrungen für den sicheren Einsatz der Software. Er wird die Software gründlich auf deren
19
// + Verwendbarkeit zu dem von ihm beabsichtigten Zweck testen, bevor er diese operativ einsetzt.
20
// + Die Haftung des Lizenzgebers wird - soweit gesetzlich zulässig - begrenzt in Höhe des typischen und vorhersehbaren
21
// + Schadens. Die gesetzliche Haftung bei Personenschäden und nach dem Produkthaftungsgesetz bleibt unberührt. Dem Lizenzgeber steht jedoch der Einwand 
22
// + des Mitverschuldens offen.
23
// + Der Kunde trifft angemessene Vorkehrungen für den Fall, dass die Software ganz oder teilweise nicht ordnungsgemäß arbeitet.
24
// + Er wird die Software gründlich auf deren Verwendbarkeit zu dem von ihm beabsichtigten Zweck testen, bevor er diese operativ einsetzt.
25
// + Der Kunde wird er seine Daten vor Einsatz der Software nach dem Stand der Technik sichern.
26
// + Der Kunde ist darüber unterrichtet, dass der Lizenzgeber seine Daten im zur Vertragsdurchführung erforderlichen Umfang
27
// + und auf Grundlage der Datenschutzvorschriften erhebt, speichert, verarbeitet und, sofern notwendig, an Dritte übermittelt.
28
// + *) Die räumliche Nutzung bezieht sich nur auf den Einsatzort, nicht auf die Reichweite der programmierten Software.
29
// + #### ENDE DER NUTZUNGSBEDINGUNGEN ####'
30
// +  Hinweis: Informationen über erweiterte Nutzungsrechte (wie z.B. Nutzung für nicht-private Zwecke) sind auf Anfrage per Email an info(@)hisystems.de verfügbar.
31
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
32
// + Software LICENSING TERMS
33
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
34
// + of HiSystems GmbH, Flachsmeerstrasse 2, 26802 Moormerland, Germany - the Licensor -
35
// + The Licensor grants the customer a non-exclusive license to use the microcontroller firmware of the Flight-Ctrl, Navi-Ctrl, BL-Ctrl, and MK3Mag hardware 
36
// + (the Software) exclusively for private purposes. The License is unrestricted with respect to time and territory*.
37
// + The Software may only be used with the Licensor's products.
38
// + The Software provided by the Licensor is protected by copyright. With respect to the relationship between the parties to this
39
// + agreement, all rights pertaining to the Software and other documents provided during the preparation and execution of this
40
// + agreement shall be the property of the Licensor.
41
// + The information contained in the Software copyright notices, trademarks, other legal reservations, serial numbers and other
42
// + features that can be used to identify the program may not be altered or defaced by the customer.
43
// + The customer shall be responsible for taking reasonable precautions
44
// + for the safe use of the Software. The customer shall test the Software thoroughly regarding its suitability for the
45
// + intended purpose before implementing it for actual operation. The Licensor's liability shall be limited to the extent of typical and
46
// + foreseeable damage to the extent permitted by law, notwithstanding statutory liability for bodily injury and product
47
// + liability. However, the Licensor shall be entitled to the defense of contributory negligence.
48
// + The customer will take adequate precautions in the case, that the software is not working properly. The customer will test
49
// + the software for his purpose before any operational usage. The customer will backup his data before using the software.
50
// + The customer understands that the Licensor collects, stores and processes, and, where required, forwards, customer data
51
// + to third parties to the extent necessary for executing the agreement, subject to applicable data protection and privacy regulations.
52
// + *) The territory aspect only refers to the place where the Software is used, not its programmed range.
53
// + #### END OF LICENSING TERMS ####
54
// + Note: For information on license extensions (e.g. commercial use), please contact us at info(@)hisystems.de.
55
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
56
#include <string.h>
57
#include "i2c.h"
58
#include "uart1.h"
59
#include "timer1.h"
60
#include "config.h"
61
#include "led.h"
62
 
63
// the transfer buffer
64
u8 I2C0_Buffer[I2C_BUFFER_LEN];
65
u8 I2C1_Buffer[I2C_BUFFER_LEN];
66
 
67
volatile I2C_Bus_t I2C0_Bus;
68
volatile I2C_Bus_t I2C1_Bus;
69
 
70
// Retourns pointer to data structure of the selected bus 
71
volatile I2C_Bus_t* I2CBus(I2C_TypeDef* I2Cx)
72
{
73
        volatile I2C_Bus_t *pBus = NULL;
74
 
75
        if(I2Cx == I2C0) pBus = &I2C0_Bus;
76
        if(I2Cx == I2C1) pBus = &I2C1_Bus;
77
 
78
        return(pBus);
79
}
80
 
81
//--------------------------------------------------------------
861 holgerb 82
void I2CBus_StateReset(I2C_TypeDef* I2Cx)
83
{
84
        volatile  I2C_Bus_t *pBus = NULL;
85
        I2C_InitTypeDef   I2C_Struct;
86
        GPIO_InitTypeDef  GPIO_InitStructure;
87
        u8 SCL_Pin = 0;
88
        u8 SDA_Pin = 0;
89
        u32 SCL_Clock = 0;
90
        u32 APBPeriph = 0;
91
        u8 VIC_Priority = 0;
92
 
93
        if (I2Cx == I2C0)
94
        {
95
                UART1_PutString("\r\n I2C0 Reset");
96
                SCL_Pin = GPIO_Pin_0;
97
                SDA_Pin = GPIO_Pin_1;
98
                SCL_Clock = I2C0_CLOCK;
99
                APBPeriph = __I2C0;
100
                VIC_Priority = PRIORITY_I2C0;
101
 
102
                pBus = &I2C0_Bus;
103
                pBus->pData = I2C0_Buffer;
104
                pBus->VIC_Source = I2C0_ITLine;        
105
        }
106
        if (I2Cx == I2C1)      
107
        {
108
                UART1_PutString("\r\n I2C1 Reset");
109
                SCL_Pin = GPIO_Pin_2;
110
                SDA_Pin = GPIO_Pin_3;
111
                SCL_Clock = I2C1_CLOCK;
112
                APBPeriph = __I2C1;
113
                VIC_Priority = PRIORITY_I2C1;
114
 
115
                pBus = &I2C1_Bus;
116
                pBus->pData = I2C1_Buffer;
117
                pBus->VIC_Source = I2C1_ITLine;        
118
        }
119
        if(pBus == NULL) return;
120
 
121
        pBus->State = I2C_STATE_UNDEF;
122
        pBus->Error = I2C_ERROR_UNKNOWN;
123
        pBus->Timeout = 0;
124
        pBus->TxBufferSize = 0;
125
        pBus->RxBufferSize = 0;
126
        pBus->Direction = 0;
127
        pBus->SlaveAddr = 0;
128
        pBus->pRxHandler = NULL;
129
 
130
        // enable Port 2 peripherie
131
        SCU_APBPeriphClockConfig(__GPIO2, ENABLE);
132
        // disable a reset state
133
        SCU_APBPeriphReset(__GPIO2, DISABLE);
134
 
135
        u8 i;
136
 
137
        // reconfigure I2C_CLKOUT and I2C_DOUT
138
        GPIO_StructInit(&GPIO_InitStructure);
139
        GPIO_InitStructure.GPIO_Direction = GPIO_PinOutput;
140
        GPIO_InitStructure.GPIO_Pin = SCL_Pin | SDA_Pin;
141
        GPIO_InitStructure.GPIO_Type = GPIO_Type_OpenCollector;
142
        GPIO_InitStructure.GPIO_IPInputConnected = GPIO_IPInputConnected_Enable;
143
        GPIO_InitStructure.GPIO_Alternate = GPIO_OutputAlt2; //I2C_CLKOUT, I2C_DOUT
144
        GPIO_Init(GPIO2, &GPIO_InitStructure);
145
 
146
        // enable I2C peripherie
147
        SCU_APBPeriphClockConfig(APBPeriph, ENABLE);
148
        // reset I2C peripherie
149
        SCU_APBPeriphReset(APBPeriph, ENABLE);
150
        SCU_APBPeriphReset(APBPeriph, DISABLE);
151
 
152
        I2C_DeInit(I2Cx);
153
        I2C_StructInit(&I2C_Struct);
154
        I2C_Struct.I2C_GeneralCall = I2C_GeneralCall_Disable;
155
        I2C_Struct.I2C_Ack = I2C_Ack_Enable;
156
        I2C_Struct.I2C_CLKSpeed = SCL_Clock;
157
        I2C_Struct.I2C_OwnAddress = 0x00;
158
        I2C_Init(I2Cx, &I2C_Struct);
159
 
160
        I2C_Cmd(I2Cx, ENABLE);
161
        I2C_ITConfig(I2Cx, ENABLE);
162
 
163
        VIC_Config(pBus->VIC_Source, VIC_IRQ , VIC_Priority);
164
        pBus->Timeout = SetDelay(2*I2C_TIMEOUT);
165
        I2C_GenerateSTOP(I2Cx, ENABLE);
166
        pBus->State = I2C_STATE_IDLE;
167
 
168
        // start some dummy transmissions cycles
169
        // to get the irq routine to work
170
        for(i = 0; i < 2; i++)
171
        {
172
                pBus->State = I2C_STATE_BUFFBUSY;
173
                I2CBus_Transmission(I2Cx, 0, NULL, 1, 0, 0); // transfer 1 byte in the isr
174
                if(I2CBus_WaitForEndOfTransmission(I2Cx, 2)) break;
175
        }
176
}
177
 
482 killagreg 178
void I2CBus_Init(I2C_TypeDef* I2Cx)
179
{
180
        volatile  I2C_Bus_t *pBus = NULL;
181
        I2C_InitTypeDef   I2C_Struct;
182
        GPIO_InitTypeDef  GPIO_InitStructure;
183
        u8 SCL_Pin = 0;
184
        u8 SDA_Pin = 0;
185
        u32 SCL_Clock = 0;
186
        u32 APBPeriph = 0;
187
        u8 VIC_Priority = 0;
188
 
189
        if (I2Cx == I2C0)
190
        {
191
                UART1_PutString("\r\n I2C0 init...");
192
                SCL_Pin = GPIO_Pin_0;
193
                SDA_Pin = GPIO_Pin_1;
194
                SCL_Clock = I2C0_CLOCK;
195
                APBPeriph = __I2C0;
196
                VIC_Priority = PRIORITY_I2C0;
197
 
198
                pBus = &I2C0_Bus;
199
                pBus->pData = I2C0_Buffer;
200
                pBus->VIC_Source = I2C0_ITLine;        
201
        }
202
        if (I2Cx == I2C1)      
203
        {
204
                UART1_PutString("\r\n I2C1 init...");
205
                SCL_Pin = GPIO_Pin_2;
206
                SDA_Pin = GPIO_Pin_3;
207
                SCL_Clock = I2C1_CLOCK;
208
                APBPeriph = __I2C1;
209
                VIC_Priority = PRIORITY_I2C1;
210
 
211
                pBus = &I2C1_Bus;
212
                pBus->pData = I2C1_Buffer;
213
                pBus->VIC_Source = I2C1_ITLine;        
214
        }
215
        if(pBus == NULL) return;
216
 
217
        pBus->State = I2C_STATE_UNDEF;
218
        pBus->Error = I2C_ERROR_UNKNOWN;
219
        pBus->Timeout = 0;
220
        pBus->TxBufferSize = 0;
221
        pBus->RxBufferSize = 0;
222
        pBus->Direction = 0;
223
        pBus->SlaveAddr = 0;
224
        pBus->pRxHandler = NULL;
225
 
226
        // enable Port 2 peripherie
227
        SCU_APBPeriphClockConfig(__GPIO2, ENABLE);
228
        // disable a reset state
229
        SCU_APBPeriphReset(__GPIO2, DISABLE);
230
 
231
        // free a busy bus
232
 
233
        // At switch on I2C devices can get in a state where they
234
        // are still waiting for a command due to all the bus lines bouncing
235
        // around at startup have started clocking data into the device(s).
236
        // Enable the ports as open collector port outputs
237
        // and clock out at least 9 SCL pulses, then generate a stop
238
        // condition and then leave the clock line high.
239
 
240
        // configure I2C_CLKOUT and I2C_DOUT to normal port operation
241
        GPIO_StructInit(&GPIO_InitStructure);
242
        GPIO_InitStructure.GPIO_Direction = GPIO_PinOutput;
243
        GPIO_InitStructure.GPIO_Pin = SCL_Pin | SDA_Pin;
244
        GPIO_InitStructure.GPIO_Type = GPIO_Type_OpenCollector;
245
        GPIO_InitStructure.GPIO_IPInputConnected = GPIO_IPInputConnected_Disable;
246
        GPIO_InitStructure.GPIO_Alternate = GPIO_OutputAlt1;
247
        GPIO_Init(GPIO2, &GPIO_InitStructure);
248
 
249
        u8 i;
250
        u32 delay;
251
        // set SCL high and then SDA to low (start condition)
252
        GPIO_WriteBit(GPIO2, SCL_Pin, Bit_SET);
253
        delay = SetDelay(1);
254
        while (!CheckDelay(delay));
255
        GPIO_WriteBit(GPIO2, SDA_Pin, Bit_RESET);
256
        // toggle SCL at least 10 times from high to low to high
257
        for(i = 0; i < 10; i++)
258
        {
259
                delay = SetDelay(1);
260
                while (!CheckDelay(delay));
261
 
262
                GPIO_WriteBit(GPIO2, SCL_Pin, Bit_RESET);
263
                delay = SetDelay(1);
264
                while (!CheckDelay(delay));
265
                GPIO_WriteBit(GPIO2, SCL_Pin, Bit_SET);
266
        }
267
        delay = SetDelay(1);
268
        while (!CheckDelay(delay));
269
        // create stop condition setting SDA HIGH when SCL is HIGH
270
        GPIO_WriteBit(GPIO2, SDA_Pin, Bit_SET);
271
 
272
 
273
        // reconfigure I2C_CLKOUT and I2C_DOUT
274
        GPIO_StructInit(&GPIO_InitStructure);
275
        GPIO_InitStructure.GPIO_Direction = GPIO_PinOutput;
276
        GPIO_InitStructure.GPIO_Pin = SCL_Pin | SDA_Pin;
277
        GPIO_InitStructure.GPIO_Type = GPIO_Type_OpenCollector;
278
        GPIO_InitStructure.GPIO_IPInputConnected = GPIO_IPInputConnected_Enable;
279
        GPIO_InitStructure.GPIO_Alternate = GPIO_OutputAlt2; //I2C_CLKOUT, I2C_DOUT
280
        GPIO_Init(GPIO2, &GPIO_InitStructure);
281
 
282
        // enable I2C peripherie
283
        SCU_APBPeriphClockConfig(APBPeriph, ENABLE);
284
        // reset I2C peripherie
285
        SCU_APBPeriphReset(APBPeriph, ENABLE);
286
        SCU_APBPeriphReset(APBPeriph, DISABLE);
287
 
288
        I2C_DeInit(I2Cx);
289
        I2C_StructInit(&I2C_Struct);
290
        I2C_Struct.I2C_GeneralCall = I2C_GeneralCall_Disable;
291
        I2C_Struct.I2C_Ack = I2C_Ack_Enable;
292
        I2C_Struct.I2C_CLKSpeed = SCL_Clock;
293
        I2C_Struct.I2C_OwnAddress = 0x00;
294
        I2C_Init(I2Cx, &I2C_Struct);
295
 
296
        I2C_Cmd(I2Cx, ENABLE);
297
        I2C_ITConfig(I2Cx, ENABLE);
298
 
299
        VIC_Config(pBus->VIC_Source, VIC_IRQ , VIC_Priority);
300
        pBus->Timeout = SetDelay(2*I2C_TIMEOUT);
301
        I2C_GenerateSTOP(I2Cx, ENABLE);
302
        pBus->State = I2C_STATE_IDLE;
303
 
304
        // start some dummy transmissions cycles
305
        // to get the irq routine to work
306
        for(i = 0; i < 10; i++)
307
        {
308
                pBus->State = I2C_STATE_BUFFBUSY;
309
                I2CBus_Transmission(I2Cx, 0, NULL, 1, 0, 0); // transfer 1 byte in the isr
310
                if(I2CBus_WaitForEndOfTransmission(I2Cx, 10)) break;
311
                UART1_Putchar('.');
312
        }
313
        UART1_PutString("ok");
314
}
315
 
316
 
317
//--------------------------------------------------------------
318
void I2CBus_Deinit(I2C_TypeDef* I2Cx)
319
{
320
        volatile I2C_Bus_t *pBus = NULL;
321
        GPIO_InitTypeDef  GPIO_InitStructure;
322
        u32 APBPeriph = 0;
323
        u16 VIC_Source = 0;
324
        u8      SCL_Pin = 0;
325
        u8  SDA_Pin = 0;
326
 
327
        if (I2Cx == I2C0)
328
        {
329
                UART1_PutString("\r\n I2C0 deinit...");
330
                SCL_Pin = GPIO_Pin_0;
331
                SDA_Pin = GPIO_Pin_1;
332
                APBPeriph = __I2C0;
333
                VIC_Source = I2C0_ITLine;
334
                pBus = &I2C0_Bus;
335
 
336
        }
337
        if (I2Cx == I2C1)
338
        {
339
                UART1_PutString("\r\n I2C1 deinit...");
340
                SCL_Pin = GPIO_Pin_2;
341
                SDA_Pin = GPIO_Pin_3;
342
                APBPeriph = __I2C1;
343
                VIC_Source = I2C1_ITLine;
344
                pBus = &I2C1_Bus;
345
        }
346
 
347
        if(pBus == NULL) return;
348
 
349
        I2C_GenerateStart(I2Cx, DISABLE);
350
        I2C_GenerateSTOP(I2Cx, ENABLE);
351
        VIC_ITCmd(VIC_Source, DISABLE);
352
        pBus->State = I2C_STATE_UNDEF;
353
        I2C_ITConfig(I2Cx, DISABLE);
354
        I2C_Cmd(I2Cx, DISABLE);
355
        I2C_DeInit(I2Cx);
356
        SCU_APBPeriphClockConfig(APBPeriph, DISABLE);
357
 
358
        // set ports to input
359
        SCU_APBPeriphClockConfig(__GPIO2, ENABLE);
360
        GPIO_StructInit(&GPIO_InitStructure);
361
        GPIO_InitStructure.GPIO_Direction =     GPIO_PinInput;
362
        GPIO_InitStructure.GPIO_Pin =                   SCL_Pin | SDA_Pin;
363
        GPIO_InitStructure.GPIO_Type =                  GPIO_Type_PushPull;
364
        GPIO_InitStructure.GPIO_IPInputConnected =      GPIO_IPInputConnected_Disable;
365
        GPIO_InitStructure.GPIO_Alternate =     GPIO_InputAlt1;
366
        GPIO_Init(GPIO2, &GPIO_InitStructure);
367
 
368
        // empty rx and tx buffer
369
        pBus->TxBufferSize = 0;
370
        pBus->RxBufferSize = 0;
371
 
372
        pBus->Timeout = SetDelay(2*I2C_TIMEOUT);
373
 
374
        UART1_PutString("ok");
375
}
376
 
377
//--------------------------------------------------------------
378
void I2C0_IRQHandler(void)
379
{
380
        static u8 Rx_Idx = 0, Tx_Idx = 0;
381
        u16 status;
382
        u16 timeout = 500;
383
 
384
        //IENABLE;  // do not enable IRQ nesting for I2C!!!!
385
        // detemine I2C State
386
        status = I2C_GetLastEvent(I2C0);
387
 
388
        if(status & (I2C_FLAG_AF|I2C_FLAG_BERR))  // if an acknowledge failure or bus error occured
389
        {       // Set and subsequently clear the STOP bit while BTF is set.
390
                while(I2C_GetFlagStatus (I2C0, I2C_FLAG_BTF) != RESET)
391
                {
392
                        I2C_GenerateSTOP (I2C0, ENABLE);  // free the bus
393
                        I2C_GenerateSTOP (I2C0, DISABLE); // free the bus
394
                        if(--timeout == 0)
395
                        {
396
                                DebugOut.Analog[14]++; // count I2C error
397
                                break;
398
                        }
399
                }
400
                I2C0_Bus.State = I2C_STATE_IDLE;
401
                I2C0_Bus.Error = I2C_ERROR_NOACK;
402
                VIC_ITCmd(I2C0_ITLine, DISABLE);
403
                return;
404
        }
405
        else
406
        {       // depending on current i2c state
407
                switch(status)
408
                {
409
                        // the start condition was initiated on the bus
410
                        case I2C_EVENT_MASTER_MODE_SELECT:
411
                                // update current bus state variable
412
                                // jump to rx state if there is nothing to send
413
                                switch(I2C0_Bus.Direction)
414
                                {
415
                                        case I2C_MODE_TRANSMITTER:
416
                                                I2C0_Bus.State = I2C_STATE_TX_PROGRESS;
417
                                                break;
418
 
419
                                        case I2C_MODE_RECEIVER:
420
                                                if (I2C0_Bus.RxBufferSize == 0) // nothing to send?
421
                                                {
422
                                                        I2C_GenerateSTOP (I2C0, ENABLE);
423
                                                        VIC_ITCmd(I2C0_ITLine, DISABLE);
424
                                                        I2C0_Bus.State = I2C_STATE_IDLE;
791 holgerb 425
                                                        I2C0_Bus.Error = I2C_ERROR_NONE;
482 killagreg 426
                                                        return;
427
                                                }
428
                                                else
429
                                                {
430
                                                        I2C0_Bus.State = I2C_STATE_RX_PROGRESS;
431
                                                }
432
                                                break;
433
 
434
                                        default: // invalid direction
435
                                                I2C_GenerateSTOP (I2C0, ENABLE);
436
                                                VIC_ITCmd(I2C0_ITLine, DISABLE);
791 holgerb 437
                                                I2C0_Bus.State = I2C_STATE_IDLE;
438
                                                I2C0_Bus.Error = I2C_ERROR_UNKNOWN;
482 killagreg 439
                                                return;
440
                                }
441
                                // enable acknowledge
442
                                I2C_AcknowledgeConfig (I2C0, ENABLE);
443
                                // send address/direction byte on the bus
444
                                I2C_Send7bitAddress(I2C0, I2C0_Bus.SlaveAddr, I2C0_Bus.Direction);
445
                                break;
446
 
447
                        // the address byte was send
448
                        case I2C_EVENT_MASTER_MODE_SELECTED:
449
                                // Clear EV6 by set again the PE bit
450
                                I2C_Cmd(I2C0, ENABLE);
451
                                switch(I2C0_Bus.State)
452
                                {
453
                                        case I2C_STATE_TX_PROGRESS:
454
                                        // send 1st data byte
455
                                        Tx_Idx = 0;
456
                                        I2C_SendData(I2C0, I2C0_Bus.pData[Tx_Idx]);
457
                                        Tx_Idx++;
458
                                        // reset timeout
459
                                        I2C0_Bus.Timeout = SetDelay(I2C_TIMEOUT); // after inactivity the I2C1 bus will be reset
460
                                        break;
461
 
462
                                        case I2C_STATE_RX_PROGRESS:
463
                                        Rx_Idx = 0;
464
                                        // disable acknoledge if only one byte has to be read
465
                                        if(I2C0_Bus.RxBufferSize == 1) I2C_AcknowledgeConfig (I2C0, DISABLE);          
466
                                        break;
467
 
468
                                        default: // unknown I2C state
469
                                        // should never happen
470
                                        I2C_GenerateSTOP (I2C0, ENABLE);
471
                                        VIC_ITCmd(I2C0_ITLine, DISABLE);
472
                                        I2C0_Bus.State = I2C_STATE_IDLE;
473
                                        I2C0_Bus.Error = I2C_ERROR_UNKNOWN;
474
                                        return;
475
                                        break;
476
                                }
477
                                break;
478
 
479
                        // the master has transmitted a byte and slave has been acknowledged
480
                        case I2C_EVENT_MASTER_BYTE_TRANSMITTED:
481
 
482
                                // some bytes have to be transmitted
483
                                if(Tx_Idx < I2C0_Bus.TxBufferSize)
484
                                {
485
                                        I2C_SendData(I2C0, I2C0_Bus.pData[Tx_Idx]);
486
                                        Tx_Idx++;
487
                                }
488
                                else // last byte was send
489
                                {
490
                                        // generate stop or repeated start condition
491
                                        if (I2C0_Bus.RxBufferSize > 0) // is any answer byte expected?
492
                                        {
493
                                                I2C0_Bus.Direction = I2C_MODE_RECEIVER; // switch to master receiver after repeated start condition
494
                                                I2C_GenerateStart(I2C0, ENABLE);   // initiate repeated start condition on the bus
495
                                        }
496
                                        else
497
                                        {   // stop communication
498
                                                I2C_GenerateSTOP(I2C0, ENABLE); // generate stop condition to free the bus
499
                                                VIC_ITCmd(I2C0_ITLine, DISABLE);
500
                                                I2C0_Bus.State = I2C_STATE_IDLE;                        // ready for new actions
501
                                                I2C0_Bus.Error = I2C_ERROR_NONE;       
502
                                        }
503
                                }
504
                                break;
505
 
506
                        // the master has received a byte from the slave
507
                        case I2C_EVENT_MASTER_BYTE_RECEIVED:
508
                                // some bytes have to be received
509
                                if ( Rx_Idx+1 < I2C0_Bus.RxBufferSize)
510
                                {       // copy received byte  from the data register to the rx-buffer
511
                                        I2C0_Bus.pData[Rx_Idx] = I2C_ReceiveData(I2C0);
512
                                }
513
                                else // if the last byte was received
514
                                {
515
                                        // generate a STOP condition on the bus before reading data register
516
                                        I2C_GenerateSTOP(I2C0, ENABLE);
517
                                        I2C0_Bus.pData[Rx_Idx] = I2C_ReceiveData(I2C0);
518
                                        // call the rx handler function to process recieved data
519
                                        if(I2C0_Bus.pRxHandler != NULL) (*(I2C0_Bus.pRxHandler))(I2C0_Bus.pData, I2C0_Bus.RxBufferSize);
520
                                        I2C0_Bus.Timeout = SetDelay(I2C_TIMEOUT);
521
                                        DebugOut.Analog[15]++;
522
                                        VIC_ITCmd(I2C0_ITLine, DISABLE);
523
                                        I2C0_Bus.State = I2C_STATE_IDLE;
524
                                        I2C0_Bus.Error = I2C_ERROR_NONE;
525
                                        return;
526
                                }
527
                                Rx_Idx++;
528
                                // if the 2nd last byte was received disable acknowledge for the last one
529
                                if ( (Rx_Idx + 1) == I2C0_Bus.RxBufferSize )
530
                                {
531
                                        I2C_AcknowledgeConfig(I2C0, DISABLE);
532
                                }
533
                                break;
534
 
535
                        default:// unknown event
536
                                // should never happen
537
                                I2C_GenerateSTOP (I2C0, ENABLE);
538
                                VIC_ITCmd(I2C0_ITLine, DISABLE);
539
                                I2C0_Bus.State = I2C_STATE_IDLE;
540
                                I2C0_Bus.Error = I2C_ERROR_UNKNOWN;
541
                                break;
542
                }
543
        }
544
        //IDISABLE;      // do not enable IRQ nesting for I2C!!!!
545
        VIC1->VAR = 0xFF; // write any value to VIC1 Vector address register
546
}
547
 
548
//--------------------------------------------------------------
549
void I2C1_IRQHandler(void)
550
{
551
        static u8 Rx_Idx = 0, Tx_Idx = 0;
552
        u16 status;
553
        u16 timeout = 500;
554
 
555
        //IENABLE;  // do not enable IRQ nesting for I2C!!!!
556
        // detemine I2C State
557
        status = I2C_GetLastEvent(I2C1);
558
 
559
        if(status & (I2C_FLAG_AF|I2C_FLAG_BERR))  // if an acknowledge failure or bus error occured
560
        {       // Set and subsequently clear the STOP bit while BTF is set.
561
                while(I2C_GetFlagStatus (I2C1, I2C_FLAG_BTF) != RESET)
562
                {
563
                        I2C_GenerateSTOP (I2C1, ENABLE);  // free the bus
564
                        I2C_GenerateSTOP (I2C1, DISABLE); // free the bus
565
                        if(--timeout == 0)
566
                        {
567
                                DebugOut.Analog[14]++; // count I2C error
568
                                break;
569
                        }
570
                }
571
                I2C1_Bus.State = I2C_STATE_IDLE;
572
                I2C1_Bus.Error = I2C_ERROR_NOACK;
573
                VIC_ITCmd(I2C1_ITLine, DISABLE);
574
                return;
575
        }
576
        else
577
        {       // depending on current i2c state
578
                switch(status)
579
                {
580
                        // the start condition was initiated on the bus
581
                        case I2C_EVENT_MASTER_MODE_SELECT:
582
                                // update current bus state variable
583
                                // jump to rx state if there is nothing to send
584
                                switch(I2C1_Bus.Direction)
585
                                {
586
                                        case I2C_MODE_TRANSMITTER:
587
                                                I2C1_Bus.State = I2C_STATE_TX_PROGRESS;
588
                                                break;
589
 
590
                                        case I2C_MODE_RECEIVER:
591
                                                if (I2C1_Bus.RxBufferSize == 0) // nothing to send?
592
                                                {
593
                                                        I2C_GenerateSTOP (I2C1, ENABLE);
594
                                                        VIC_ITCmd(I2C1_ITLine, DISABLE);
595
                                                        I2C1_Bus.State = I2C_STATE_IDLE;
596
                                                        I2C1_Bus.Error = I2C_ERROR_NONE;
597
                                                        return;
598
                                                }
599
                                                else
600
                                                {
601
                                                        I2C1_Bus.State = I2C_STATE_RX_PROGRESS;
602
                                                }
603
                                                break;
604
 
605
                                        default: // invalid direction
606
                                                I2C_GenerateSTOP (I2C1, ENABLE);
607
                                                VIC_ITCmd(I2C1_ITLine, DISABLE);
608
                                                I2C1_Bus.State = I2C_STATE_IDLE;
609
                                                I2C1_Bus.Error = I2C_ERROR_UNKNOWN;
610
                                                return;
611
                                }
612
                                // enable acknowledge
613
                                I2C_AcknowledgeConfig (I2C1, ENABLE);
614
                                // send address/direction byte on the bus
615
                                I2C_Send7bitAddress(I2C1, I2C1_Bus.SlaveAddr, I2C1_Bus.Direction);
616
                                break;
617
 
618
                        // the address byte was send
619
                        case I2C_EVENT_MASTER_MODE_SELECTED:
620
                                // Clear EV6 by set again the PE bit
621
                                I2C_Cmd(I2C1, ENABLE);
622
                                switch(I2C1_Bus.State)
623
                                {
624
                                        case I2C_STATE_TX_PROGRESS:
625
                                        // send 1st data byte
626
                                        Tx_Idx = 0;
627
                                        I2C_SendData(I2C1, I2C1_Bus.pData[Tx_Idx]);
628
                                        Tx_Idx++;
629
                                        // reset timeout
630
                                        I2C1_Bus.Timeout = SetDelay(I2C_TIMEOUT); // after inactivity the I2C1 bus will be reset
631
                                        break;
632
 
633
                                        case I2C_STATE_RX_PROGRESS:
634
                                        Rx_Idx = 0;
635
                                        // disable acknoledge if only one byte has to be read
636
                                        if(I2C1_Bus.RxBufferSize == 1) I2C_AcknowledgeConfig (I2C1, DISABLE);          
637
                                        break;
638
 
639
                                        default: // unknown I2C state
640
                                        // should never happen
641
                                        I2C_GenerateSTOP (I2C1, ENABLE);
642
                                        VIC_ITCmd(I2C1_ITLine, DISABLE);
643
                                        I2C1_Bus.State = I2C_STATE_IDLE;
644
                                        I2C1_Bus.Error = I2C_ERROR_UNKNOWN;
645
                                        return;
646
                                        break;
647
                                }
648
                                break;
649
 
650
                        // the master has transmitted a byte and slave has been acknowledged
651
                        case I2C_EVENT_MASTER_BYTE_TRANSMITTED:
652
 
653
                                // some bytes have to be transmitted
654
                                if(Tx_Idx < I2C1_Bus.TxBufferSize)
655
                                {
656
                                        I2C_SendData(I2C1, I2C1_Bus.pData[Tx_Idx]);
657
                                        Tx_Idx++;
658
                                }
659
                                else // last byte was send
660
                                {
661
                                        // generate stop or repeated start condition
662
                                        if (I2C1_Bus.RxBufferSize > 0) // is any answer byte expected?
663
                                        {
664
                                                I2C1_Bus.Direction = I2C_MODE_RECEIVER; // switch to master receiver after repeated start condition
665
                                                I2C_GenerateStart(I2C1, ENABLE);   // initiate repeated start condition on the bus
666
                                        }
667
                                        else
668
                                        {   // stop communication
669
                                                I2C_GenerateSTOP(I2C1, ENABLE); // generate stop condition to free the bus
670
                                                VIC_ITCmd(I2C1_ITLine, DISABLE);
671
                                                I2C1_Bus.State = I2C_STATE_IDLE;                        // ready for new actions
672
                                                I2C1_Bus.Error = I2C_ERROR_NONE;       
673
                                        }
674
                                }
675
                                break;
676
 
677
                        // the master has received a byte from the slave
678
                        case I2C_EVENT_MASTER_BYTE_RECEIVED:
679
                                // some bytes have to be received
680
                                if ( Rx_Idx+1 < I2C1_Bus.RxBufferSize)
681
                                {       // copy received byte  from the data register to the rx-buffer
682
                                        I2C1_Bus.pData[Rx_Idx] = I2C_ReceiveData(I2C1);
683
                                }
684
                                else // if the last byte was received
685
                                {
686
                                        // generate a STOP condition on the bus before reading data register
687
                                        I2C_GenerateSTOP(I2C1, ENABLE);
688
                                        I2C1_Bus.pData[Rx_Idx] = I2C_ReceiveData(I2C1);
689
                                        // call the rx handler function to process recieved data
690
                                        if(I2C1_Bus.pRxHandler != NULL) (*(I2C1_Bus.pRxHandler))(I2C1_Bus.pData, I2C1_Bus.RxBufferSize);
691
                                        I2C1_Bus.Timeout = SetDelay(I2C_TIMEOUT);
692
                                        DebugOut.Analog[15]++;
693
                                        VIC_ITCmd(I2C1_ITLine, DISABLE);
694
                                        I2C1_Bus.State = I2C_STATE_IDLE;
695
                                        I2C1_Bus.Error = I2C_ERROR_NONE;
696
                                        return;
697
                                }
698
                                Rx_Idx++;
699
                                // if the 2nd last byte was received disable acknowledge for the last one
700
                                if ( (Rx_Idx + 1) == I2C1_Bus.RxBufferSize )
701
                                {
702
                                        I2C_AcknowledgeConfig(I2C1, DISABLE);
703
                                }
704
                                break;
705
 
706
                        default:// unknown event
707
                                // should never happen
508 holgerb 708
                                DebugOut.Analog[14]++;
482 killagreg 709
                                I2C_GenerateSTOP (I2C1, ENABLE);
710
                                VIC_ITCmd(I2C1_ITLine, DISABLE);
711
                                I2C1_Bus.State = I2C_STATE_IDLE;
712
                                I2C1_Bus.Error = I2C_ERROR_UNKNOWN;
713
                                break;
714
                }
715
        }
716
        //IDISABLE;      // do not enable IRQ nesting for I2C!!!!
717
        VIC1->VAR = 0xFF; // write any value to VIC1 Vector address register
718
}
719
 
720
// ----------------------------------------------------------------------------------------
721
// wait for end of transmission
722
// returns 1 on success or 0 on timeout
723
u8 I2CBus_WaitForEndOfTransmission(I2C_TypeDef* I2Cx, u32 timeout)
724
{
725
        volatile I2C_Bus_t *pBus = NULL;
726
        u32 time = SetDelay(timeout);
727
 
728
        if(I2Cx == I2C0) pBus = &I2C0_Bus;
729
        if(I2Cx == I2C1) pBus = &I2C1_Bus;
730
        if(pBus == NULL) return(0);
731
        while(pBus->State != I2C_STATE_IDLE)
732
        {
508 holgerb 733
                if(CheckDelay(time))  // Timeout
734
                 {
735
                  return(0);
736
                 }
482 killagreg 737
        }
738
        return(1);
739
}
740
 
741
// ----------------------------------------------------------------------------------------
742
// try to get access to the transfer buffer      within a timeout limit
743
// returs 1 on success and 0 on error/timeout
744
u8 I2CBus_LockBuffer(I2C_TypeDef* I2Cx, u32 timeout)
745
{
746
        volatile I2C_Bus_t *pBus = NULL;       
747
 
748
        if(I2Cx == I2C0) pBus = &I2C0_Bus;
749
        if(I2Cx == I2C1) pBus = &I2C1_Bus;
750
        if(pBus == NULL) return(0);
751
 
752
        if(I2CBus_WaitForEndOfTransmission(I2Cx, timeout))
753
        {
861 holgerb 754
                pBus->State = I2C_STATE_BUFFBUSY;
482 killagreg 755
                pBus->Error = I2C_ERROR_UNKNOWN;
756
                return(1);
757
        }
758
        else return(0);
759
}
760
// ----------------------------------------------------------------------------------------
761
// initate an i2c transmission
762
// before that function is called, the application has to call I2CBus_LockBuffer and has to fill the Buffer with data to be send
763
u8 I2CBus_Transmission(I2C_TypeDef* I2Cx, u8 SlaveAddr, u8* pTxData, u8 TxBytes, I2C_pRxHandler_t pRxHandler, u8 RxBytes)
764
{
765
        u8 retval = 0;
766
 
767
        volatile I2C_Bus_t *pBus = NULL;       
768
 
769
        if(I2Cx == I2C0) pBus = &I2C0_Bus;
770
        if(I2Cx == I2C1) pBus = &I2C1_Bus;
771
        if(pBus == NULL) return(0);
772
 
773
 
774
        if(pBus->State == I2C_STATE_BUFFBUSY)  // check for locked buffer
775
        {
776
                if((RxBytes > I2C_BUFFER_LEN) || (TxBytes > I2C_BUFFER_LEN))
777
                {
778
                        pBus->State = I2C_STATE_IDLE;
779
                        return(retval);
780
                }      
781
                pBus->RxBufferSize = RxBytes;
782
                pBus->TxBufferSize = TxBytes;
783
                // set direction to master transmitter
784
                if( (pBus->TxBufferSize > 0) && (pBus->TxBufferSize < I2C_BUFFER_LEN) )
785
                {
786
                        pBus->Direction = I2C_MODE_TRANSMITTER;
787
                        // copy data to send from source to tansfer buffer
788
                        if(pTxData) memcpy(pBus->pData, pTxData, pBus->TxBufferSize);
789
                }
790
                else if (( pBus->RxBufferSize > 0 ) && (pBus->RxBufferSize < I2C_BUFFER_LEN) )
791
                {
792
                        pBus->Direction = I2C_MODE_RECEIVER;
793
                }
794
                else // nothing to send or receive
795
                {
796
                        pBus->State = I2C_STATE_IDLE;
797
                        pBus->Error = I2C_ERROR_NONE;
798
                        pBus->TxBufferSize = 0;
799
                        pBus->RxBufferSize = 0;
800
                        return(retval);
801
                }
802
                // update slave address and rx data handler     function pointer
803
                pBus->SlaveAddr = SlaveAddr;
804
                pBus->pRxHandler = pRxHandler;
805
                // test on busy flag and clear it
806
                I2C_ClearFlag(I2Cx, I2C_FLAG_BUSY);
807
                // enable I2C IRQ
808
                VIC_ITCmd(pBus->VIC_Source, ENABLE);
809
                // initiate start condition on the bus
810
                I2C_GenerateStart(I2Cx, ENABLE);
811
                retval = 1;
812
         }
813
         return(retval);
814
}