Subversion Repositories NaviCtrl

Rev

Rev 791 | Go to most recent revision | 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
        u32 delay;
137
 
138
        // reconfigure I2C_CLKOUT and I2C_DOUT
139
        GPIO_StructInit(&GPIO_InitStructure);
140
        GPIO_InitStructure.GPIO_Direction = GPIO_PinOutput;
141
        GPIO_InitStructure.GPIO_Pin = SCL_Pin | SDA_Pin;
142
        GPIO_InitStructure.GPIO_Type = GPIO_Type_OpenCollector;
143
        GPIO_InitStructure.GPIO_IPInputConnected = GPIO_IPInputConnected_Enable;
144
        GPIO_InitStructure.GPIO_Alternate = GPIO_OutputAlt2; //I2C_CLKOUT, I2C_DOUT
145
        GPIO_Init(GPIO2, &GPIO_InitStructure);
146
 
147
        // enable I2C peripherie
148
        SCU_APBPeriphClockConfig(APBPeriph, ENABLE);
149
        // reset I2C peripherie
150
        SCU_APBPeriphReset(APBPeriph, ENABLE);
151
        SCU_APBPeriphReset(APBPeriph, DISABLE);
152
 
153
        I2C_DeInit(I2Cx);
154
        I2C_StructInit(&I2C_Struct);
155
        I2C_Struct.I2C_GeneralCall = I2C_GeneralCall_Disable;
156
        I2C_Struct.I2C_Ack = I2C_Ack_Enable;
157
        I2C_Struct.I2C_CLKSpeed = SCL_Clock;
158
        I2C_Struct.I2C_OwnAddress = 0x00;
159
        I2C_Init(I2Cx, &I2C_Struct);
160
 
161
        I2C_Cmd(I2Cx, ENABLE);
162
        I2C_ITConfig(I2Cx, ENABLE);
163
 
164
        VIC_Config(pBus->VIC_Source, VIC_IRQ , VIC_Priority);
165
        pBus->Timeout = SetDelay(2*I2C_TIMEOUT);
166
        I2C_GenerateSTOP(I2Cx, ENABLE);
167
        pBus->State = I2C_STATE_IDLE;
168
 
169
        // start some dummy transmissions cycles
170
        // to get the irq routine to work
171
        for(i = 0; i < 2; i++)
172
        {
173
                pBus->State = I2C_STATE_BUFFBUSY;
174
                I2CBus_Transmission(I2Cx, 0, NULL, 1, 0, 0); // transfer 1 byte in the isr
175
                if(I2CBus_WaitForEndOfTransmission(I2Cx, 2)) break;
176
        }
177
}
178
 
482 killagreg 179
void I2CBus_Init(I2C_TypeDef* I2Cx)
180
{
181
        volatile  I2C_Bus_t *pBus = NULL;
182
        I2C_InitTypeDef   I2C_Struct;
183
        GPIO_InitTypeDef  GPIO_InitStructure;
184
        u8 SCL_Pin = 0;
185
        u8 SDA_Pin = 0;
186
        u32 SCL_Clock = 0;
187
        u32 APBPeriph = 0;
188
        u8 VIC_Priority = 0;
189
 
190
        if (I2Cx == I2C0)
191
        {
192
                UART1_PutString("\r\n I2C0 init...");
193
                SCL_Pin = GPIO_Pin_0;
194
                SDA_Pin = GPIO_Pin_1;
195
                SCL_Clock = I2C0_CLOCK;
196
                APBPeriph = __I2C0;
197
                VIC_Priority = PRIORITY_I2C0;
198
 
199
                pBus = &I2C0_Bus;
200
                pBus->pData = I2C0_Buffer;
201
                pBus->VIC_Source = I2C0_ITLine;        
202
        }
203
        if (I2Cx == I2C1)      
204
        {
205
                UART1_PutString("\r\n I2C1 init...");
206
                SCL_Pin = GPIO_Pin_2;
207
                SDA_Pin = GPIO_Pin_3;
208
                SCL_Clock = I2C1_CLOCK;
209
                APBPeriph = __I2C1;
210
                VIC_Priority = PRIORITY_I2C1;
211
 
212
                pBus = &I2C1_Bus;
213
                pBus->pData = I2C1_Buffer;
214
                pBus->VIC_Source = I2C1_ITLine;        
215
        }
216
        if(pBus == NULL) return;
217
 
218
        pBus->State = I2C_STATE_UNDEF;
219
        pBus->Error = I2C_ERROR_UNKNOWN;
220
        pBus->Timeout = 0;
221
        pBus->TxBufferSize = 0;
222
        pBus->RxBufferSize = 0;
223
        pBus->Direction = 0;
224
        pBus->SlaveAddr = 0;
225
        pBus->pRxHandler = NULL;
226
 
227
        // enable Port 2 peripherie
228
        SCU_APBPeriphClockConfig(__GPIO2, ENABLE);
229
        // disable a reset state
230
        SCU_APBPeriphReset(__GPIO2, DISABLE);
231
 
232
        // free a busy bus
233
 
234
        // At switch on I2C devices can get in a state where they
235
        // are still waiting for a command due to all the bus lines bouncing
236
        // around at startup have started clocking data into the device(s).
237
        // Enable the ports as open collector port outputs
238
        // and clock out at least 9 SCL pulses, then generate a stop
239
        // condition and then leave the clock line high.
240
 
241
        // configure I2C_CLKOUT and I2C_DOUT to normal port operation
242
        GPIO_StructInit(&GPIO_InitStructure);
243
        GPIO_InitStructure.GPIO_Direction = GPIO_PinOutput;
244
        GPIO_InitStructure.GPIO_Pin = SCL_Pin | SDA_Pin;
245
        GPIO_InitStructure.GPIO_Type = GPIO_Type_OpenCollector;
246
        GPIO_InitStructure.GPIO_IPInputConnected = GPIO_IPInputConnected_Disable;
247
        GPIO_InitStructure.GPIO_Alternate = GPIO_OutputAlt1;
248
        GPIO_Init(GPIO2, &GPIO_InitStructure);
249
 
250
        u8 i;
251
        u32 delay;
252
        // set SCL high and then SDA to low (start condition)
253
        GPIO_WriteBit(GPIO2, SCL_Pin, Bit_SET);
254
        delay = SetDelay(1);
255
        while (!CheckDelay(delay));
256
        GPIO_WriteBit(GPIO2, SDA_Pin, Bit_RESET);
257
        // toggle SCL at least 10 times from high to low to high
258
        for(i = 0; i < 10; i++)
259
        {
260
                delay = SetDelay(1);
261
                while (!CheckDelay(delay));
262
 
263
                GPIO_WriteBit(GPIO2, SCL_Pin, Bit_RESET);
264
                delay = SetDelay(1);
265
                while (!CheckDelay(delay));
266
                GPIO_WriteBit(GPIO2, SCL_Pin, Bit_SET);
267
        }
268
        delay = SetDelay(1);
269
        while (!CheckDelay(delay));
270
        // create stop condition setting SDA HIGH when SCL is HIGH
271
        GPIO_WriteBit(GPIO2, SDA_Pin, Bit_SET);
272
 
273
 
274
        // reconfigure I2C_CLKOUT and I2C_DOUT
275
        GPIO_StructInit(&GPIO_InitStructure);
276
        GPIO_InitStructure.GPIO_Direction = GPIO_PinOutput;
277
        GPIO_InitStructure.GPIO_Pin = SCL_Pin | SDA_Pin;
278
        GPIO_InitStructure.GPIO_Type = GPIO_Type_OpenCollector;
279
        GPIO_InitStructure.GPIO_IPInputConnected = GPIO_IPInputConnected_Enable;
280
        GPIO_InitStructure.GPIO_Alternate = GPIO_OutputAlt2; //I2C_CLKOUT, I2C_DOUT
281
        GPIO_Init(GPIO2, &GPIO_InitStructure);
282
 
283
        // enable I2C peripherie
284
        SCU_APBPeriphClockConfig(APBPeriph, ENABLE);
285
        // reset I2C peripherie
286
        SCU_APBPeriphReset(APBPeriph, ENABLE);
287
        SCU_APBPeriphReset(APBPeriph, DISABLE);
288
 
289
        I2C_DeInit(I2Cx);
290
        I2C_StructInit(&I2C_Struct);
291
        I2C_Struct.I2C_GeneralCall = I2C_GeneralCall_Disable;
292
        I2C_Struct.I2C_Ack = I2C_Ack_Enable;
293
        I2C_Struct.I2C_CLKSpeed = SCL_Clock;
294
        I2C_Struct.I2C_OwnAddress = 0x00;
295
        I2C_Init(I2Cx, &I2C_Struct);
296
 
297
        I2C_Cmd(I2Cx, ENABLE);
298
        I2C_ITConfig(I2Cx, ENABLE);
299
 
300
        VIC_Config(pBus->VIC_Source, VIC_IRQ , VIC_Priority);
301
        pBus->Timeout = SetDelay(2*I2C_TIMEOUT);
302
        I2C_GenerateSTOP(I2Cx, ENABLE);
303
        pBus->State = I2C_STATE_IDLE;
304
 
305
        // start some dummy transmissions cycles
306
        // to get the irq routine to work
307
        for(i = 0; i < 10; i++)
308
        {
309
                pBus->State = I2C_STATE_BUFFBUSY;
310
                I2CBus_Transmission(I2Cx, 0, NULL, 1, 0, 0); // transfer 1 byte in the isr
311
                if(I2CBus_WaitForEndOfTransmission(I2Cx, 10)) break;
312
                UART1_Putchar('.');
313
        }
314
        UART1_PutString("ok");
315
}
316
 
317
 
318
//--------------------------------------------------------------
319
void I2CBus_Deinit(I2C_TypeDef* I2Cx)
320
{
321
        volatile I2C_Bus_t *pBus = NULL;
322
        GPIO_InitTypeDef  GPIO_InitStructure;
323
        u32 APBPeriph = 0;
324
        u16 VIC_Source = 0;
325
        u8      SCL_Pin = 0;
326
        u8  SDA_Pin = 0;
327
 
328
        if (I2Cx == I2C0)
329
        {
330
                UART1_PutString("\r\n I2C0 deinit...");
331
                SCL_Pin = GPIO_Pin_0;
332
                SDA_Pin = GPIO_Pin_1;
333
                APBPeriph = __I2C0;
334
                VIC_Source = I2C0_ITLine;
335
                pBus = &I2C0_Bus;
336
 
337
        }
338
        if (I2Cx == I2C1)
339
        {
340
                UART1_PutString("\r\n I2C1 deinit...");
341
                SCL_Pin = GPIO_Pin_2;
342
                SDA_Pin = GPIO_Pin_3;
343
                APBPeriph = __I2C1;
344
                VIC_Source = I2C1_ITLine;
345
                pBus = &I2C1_Bus;
346
        }
347
 
348
        if(pBus == NULL) return;
349
 
350
        I2C_GenerateStart(I2Cx, DISABLE);
351
        I2C_GenerateSTOP(I2Cx, ENABLE);
352
        VIC_ITCmd(VIC_Source, DISABLE);
353
        pBus->State = I2C_STATE_UNDEF;
354
        I2C_ITConfig(I2Cx, DISABLE);
355
        I2C_Cmd(I2Cx, DISABLE);
356
        I2C_DeInit(I2Cx);
357
        SCU_APBPeriphClockConfig(APBPeriph, DISABLE);
358
 
359
        // set ports to input
360
        SCU_APBPeriphClockConfig(__GPIO2, ENABLE);
361
        GPIO_StructInit(&GPIO_InitStructure);
362
        GPIO_InitStructure.GPIO_Direction =     GPIO_PinInput;
363
        GPIO_InitStructure.GPIO_Pin =                   SCL_Pin | SDA_Pin;
364
        GPIO_InitStructure.GPIO_Type =                  GPIO_Type_PushPull;
365
        GPIO_InitStructure.GPIO_IPInputConnected =      GPIO_IPInputConnected_Disable;
366
        GPIO_InitStructure.GPIO_Alternate =     GPIO_InputAlt1;
367
        GPIO_Init(GPIO2, &GPIO_InitStructure);
368
 
369
        // empty rx and tx buffer
370
        pBus->TxBufferSize = 0;
371
        pBus->RxBufferSize = 0;
372
 
373
        pBus->Timeout = SetDelay(2*I2C_TIMEOUT);
374
 
375
        UART1_PutString("ok");
376
}
377
 
378
//--------------------------------------------------------------
379
void I2C0_IRQHandler(void)
380
{
381
        static u8 Rx_Idx = 0, Tx_Idx = 0;
382
        u16 status;
383
        u16 timeout = 500;
384
 
385
        //IENABLE;  // do not enable IRQ nesting for I2C!!!!
386
        // detemine I2C State
387
        status = I2C_GetLastEvent(I2C0);
388
 
389
        if(status & (I2C_FLAG_AF|I2C_FLAG_BERR))  // if an acknowledge failure or bus error occured
390
        {       // Set and subsequently clear the STOP bit while BTF is set.
391
                while(I2C_GetFlagStatus (I2C0, I2C_FLAG_BTF) != RESET)
392
                {
393
                        I2C_GenerateSTOP (I2C0, ENABLE);  // free the bus
394
                        I2C_GenerateSTOP (I2C0, DISABLE); // free the bus
395
                        if(--timeout == 0)
396
                        {
397
                                DebugOut.Analog[14]++; // count I2C error
398
                                break;
399
                        }
400
                }
401
                I2C0_Bus.State = I2C_STATE_IDLE;
402
                I2C0_Bus.Error = I2C_ERROR_NOACK;
403
                VIC_ITCmd(I2C0_ITLine, DISABLE);
404
                return;
405
        }
406
        else
407
        {       // depending on current i2c state
408
                switch(status)
409
                {
410
                        // the start condition was initiated on the bus
411
                        case I2C_EVENT_MASTER_MODE_SELECT:
412
                                // update current bus state variable
413
                                // jump to rx state if there is nothing to send
414
                                switch(I2C0_Bus.Direction)
415
                                {
416
                                        case I2C_MODE_TRANSMITTER:
417
                                                I2C0_Bus.State = I2C_STATE_TX_PROGRESS;
418
                                                break;
419
 
420
                                        case I2C_MODE_RECEIVER:
421
                                                if (I2C0_Bus.RxBufferSize == 0) // nothing to send?
422
                                                {
423
                                                        I2C_GenerateSTOP (I2C0, ENABLE);
424
                                                        VIC_ITCmd(I2C0_ITLine, DISABLE);
425
                                                        I2C0_Bus.State = I2C_STATE_IDLE;
791 holgerb 426
                                                        I2C0_Bus.Error = I2C_ERROR_NONE;
482 killagreg 427
                                                        return;
428
                                                }
429
                                                else
430
                                                {
431
                                                        I2C0_Bus.State = I2C_STATE_RX_PROGRESS;
432
                                                }
433
                                                break;
434
 
435
                                        default: // invalid direction
436
                                                I2C_GenerateSTOP (I2C0, ENABLE);
437
                                                VIC_ITCmd(I2C0_ITLine, DISABLE);
791 holgerb 438
                                                I2C0_Bus.State = I2C_STATE_IDLE;
439
                                                I2C0_Bus.Error = I2C_ERROR_UNKNOWN;
482 killagreg 440
                                                return;
441
                                }
442
                                // enable acknowledge
443
                                I2C_AcknowledgeConfig (I2C0, ENABLE);
444
                                // send address/direction byte on the bus
445
                                I2C_Send7bitAddress(I2C0, I2C0_Bus.SlaveAddr, I2C0_Bus.Direction);
446
                                break;
447
 
448
                        // the address byte was send
449
                        case I2C_EVENT_MASTER_MODE_SELECTED:
450
                                // Clear EV6 by set again the PE bit
451
                                I2C_Cmd(I2C0, ENABLE);
452
                                switch(I2C0_Bus.State)
453
                                {
454
                                        case I2C_STATE_TX_PROGRESS:
455
                                        // send 1st data byte
456
                                        Tx_Idx = 0;
457
                                        I2C_SendData(I2C0, I2C0_Bus.pData[Tx_Idx]);
458
                                        Tx_Idx++;
459
                                        // reset timeout
460
                                        I2C0_Bus.Timeout = SetDelay(I2C_TIMEOUT); // after inactivity the I2C1 bus will be reset
461
                                        break;
462
 
463
                                        case I2C_STATE_RX_PROGRESS:
464
                                        Rx_Idx = 0;
465
                                        // disable acknoledge if only one byte has to be read
466
                                        if(I2C0_Bus.RxBufferSize == 1) I2C_AcknowledgeConfig (I2C0, DISABLE);          
467
                                        break;
468
 
469
                                        default: // unknown I2C state
470
                                        // should never happen
471
                                        I2C_GenerateSTOP (I2C0, ENABLE);
472
                                        VIC_ITCmd(I2C0_ITLine, DISABLE);
473
                                        I2C0_Bus.State = I2C_STATE_IDLE;
474
                                        I2C0_Bus.Error = I2C_ERROR_UNKNOWN;
475
                                        return;
476
                                        break;
477
                                }
478
                                break;
479
 
480
                        // the master has transmitted a byte and slave has been acknowledged
481
                        case I2C_EVENT_MASTER_BYTE_TRANSMITTED:
482
 
483
                                // some bytes have to be transmitted
484
                                if(Tx_Idx < I2C0_Bus.TxBufferSize)
485
                                {
486
                                        I2C_SendData(I2C0, I2C0_Bus.pData[Tx_Idx]);
487
                                        Tx_Idx++;
488
                                }
489
                                else // last byte was send
490
                                {
491
                                        // generate stop or repeated start condition
492
                                        if (I2C0_Bus.RxBufferSize > 0) // is any answer byte expected?
493
                                        {
494
                                                I2C0_Bus.Direction = I2C_MODE_RECEIVER; // switch to master receiver after repeated start condition
495
                                                I2C_GenerateStart(I2C0, ENABLE);   // initiate repeated start condition on the bus
496
                                        }
497
                                        else
498
                                        {   // stop communication
499
                                                I2C_GenerateSTOP(I2C0, ENABLE); // generate stop condition to free the bus
500
                                                VIC_ITCmd(I2C0_ITLine, DISABLE);
501
                                                I2C0_Bus.State = I2C_STATE_IDLE;                        // ready for new actions
502
                                                I2C0_Bus.Error = I2C_ERROR_NONE;       
503
                                        }
504
                                }
505
                                break;
506
 
507
                        // the master has received a byte from the slave
508
                        case I2C_EVENT_MASTER_BYTE_RECEIVED:
509
                                // some bytes have to be received
510
                                if ( Rx_Idx+1 < I2C0_Bus.RxBufferSize)
511
                                {       // copy received byte  from the data register to the rx-buffer
512
                                        I2C0_Bus.pData[Rx_Idx] = I2C_ReceiveData(I2C0);
513
                                }
514
                                else // if the last byte was received
515
                                {
516
                                        // generate a STOP condition on the bus before reading data register
517
                                        I2C_GenerateSTOP(I2C0, ENABLE);
518
                                        I2C0_Bus.pData[Rx_Idx] = I2C_ReceiveData(I2C0);
519
                                        // call the rx handler function to process recieved data
520
                                        if(I2C0_Bus.pRxHandler != NULL) (*(I2C0_Bus.pRxHandler))(I2C0_Bus.pData, I2C0_Bus.RxBufferSize);
521
                                        I2C0_Bus.Timeout = SetDelay(I2C_TIMEOUT);
522
                                        DebugOut.Analog[15]++;
523
                                        VIC_ITCmd(I2C0_ITLine, DISABLE);
524
                                        I2C0_Bus.State = I2C_STATE_IDLE;
525
                                        I2C0_Bus.Error = I2C_ERROR_NONE;
526
                                        return;
527
                                }
528
                                Rx_Idx++;
529
                                // if the 2nd last byte was received disable acknowledge for the last one
530
                                if ( (Rx_Idx + 1) == I2C0_Bus.RxBufferSize )
531
                                {
532
                                        I2C_AcknowledgeConfig(I2C0, DISABLE);
533
                                }
534
                                break;
535
 
536
                        default:// unknown event
537
                                // should never happen
538
                                I2C_GenerateSTOP (I2C0, ENABLE);
539
                                VIC_ITCmd(I2C0_ITLine, DISABLE);
540
                                I2C0_Bus.State = I2C_STATE_IDLE;
541
                                I2C0_Bus.Error = I2C_ERROR_UNKNOWN;
542
                                break;
543
                }
544
        }
545
        //IDISABLE;      // do not enable IRQ nesting for I2C!!!!
546
        VIC1->VAR = 0xFF; // write any value to VIC1 Vector address register
547
}
548
 
549
//--------------------------------------------------------------
550
void I2C1_IRQHandler(void)
551
{
552
        static u8 Rx_Idx = 0, Tx_Idx = 0;
553
        u16 status;
554
        u16 timeout = 500;
555
 
556
        //IENABLE;  // do not enable IRQ nesting for I2C!!!!
557
        // detemine I2C State
558
        status = I2C_GetLastEvent(I2C1);
559
 
560
        if(status & (I2C_FLAG_AF|I2C_FLAG_BERR))  // if an acknowledge failure or bus error occured
561
        {       // Set and subsequently clear the STOP bit while BTF is set.
562
                while(I2C_GetFlagStatus (I2C1, I2C_FLAG_BTF) != RESET)
563
                {
564
                        I2C_GenerateSTOP (I2C1, ENABLE);  // free the bus
565
                        I2C_GenerateSTOP (I2C1, DISABLE); // free the bus
566
                        if(--timeout == 0)
567
                        {
568
                                DebugOut.Analog[14]++; // count I2C error
569
                                break;
570
                        }
571
                }
572
                I2C1_Bus.State = I2C_STATE_IDLE;
573
                I2C1_Bus.Error = I2C_ERROR_NOACK;
574
                VIC_ITCmd(I2C1_ITLine, DISABLE);
575
                return;
576
        }
577
        else
578
        {       // depending on current i2c state
579
                switch(status)
580
                {
581
                        // the start condition was initiated on the bus
582
                        case I2C_EVENT_MASTER_MODE_SELECT:
583
                                // update current bus state variable
584
                                // jump to rx state if there is nothing to send
585
                                switch(I2C1_Bus.Direction)
586
                                {
587
                                        case I2C_MODE_TRANSMITTER:
588
                                                I2C1_Bus.State = I2C_STATE_TX_PROGRESS;
589
                                                break;
590
 
591
                                        case I2C_MODE_RECEIVER:
592
                                                if (I2C1_Bus.RxBufferSize == 0) // nothing to send?
593
                                                {
594
                                                        I2C_GenerateSTOP (I2C1, ENABLE);
595
                                                        VIC_ITCmd(I2C1_ITLine, DISABLE);
596
                                                        I2C1_Bus.State = I2C_STATE_IDLE;
597
                                                        I2C1_Bus.Error = I2C_ERROR_NONE;
598
                                                        return;
599
                                                }
600
                                                else
601
                                                {
602
                                                        I2C1_Bus.State = I2C_STATE_RX_PROGRESS;
603
                                                }
604
                                                break;
605
 
606
                                        default: // invalid direction
607
                                                I2C_GenerateSTOP (I2C1, ENABLE);
608
                                                VIC_ITCmd(I2C1_ITLine, DISABLE);
609
                                                I2C1_Bus.State = I2C_STATE_IDLE;
610
                                                I2C1_Bus.Error = I2C_ERROR_UNKNOWN;
611
                                                return;
612
                                }
613
                                // enable acknowledge
614
                                I2C_AcknowledgeConfig (I2C1, ENABLE);
615
                                // send address/direction byte on the bus
616
                                I2C_Send7bitAddress(I2C1, I2C1_Bus.SlaveAddr, I2C1_Bus.Direction);
617
                                break;
618
 
619
                        // the address byte was send
620
                        case I2C_EVENT_MASTER_MODE_SELECTED:
621
                                // Clear EV6 by set again the PE bit
622
                                I2C_Cmd(I2C1, ENABLE);
623
                                switch(I2C1_Bus.State)
624
                                {
625
                                        case I2C_STATE_TX_PROGRESS:
626
                                        // send 1st data byte
627
                                        Tx_Idx = 0;
628
                                        I2C_SendData(I2C1, I2C1_Bus.pData[Tx_Idx]);
629
                                        Tx_Idx++;
630
                                        // reset timeout
631
                                        I2C1_Bus.Timeout = SetDelay(I2C_TIMEOUT); // after inactivity the I2C1 bus will be reset
632
                                        break;
633
 
634
                                        case I2C_STATE_RX_PROGRESS:
635
                                        Rx_Idx = 0;
636
                                        // disable acknoledge if only one byte has to be read
637
                                        if(I2C1_Bus.RxBufferSize == 1) I2C_AcknowledgeConfig (I2C1, DISABLE);          
638
                                        break;
639
 
640
                                        default: // unknown I2C state
641
                                        // should never happen
642
                                        I2C_GenerateSTOP (I2C1, ENABLE);
643
                                        VIC_ITCmd(I2C1_ITLine, DISABLE);
644
                                        I2C1_Bus.State = I2C_STATE_IDLE;
645
                                        I2C1_Bus.Error = I2C_ERROR_UNKNOWN;
646
                                        return;
647
                                        break;
648
                                }
649
                                break;
650
 
651
                        // the master has transmitted a byte and slave has been acknowledged
652
                        case I2C_EVENT_MASTER_BYTE_TRANSMITTED:
653
 
654
                                // some bytes have to be transmitted
655
                                if(Tx_Idx < I2C1_Bus.TxBufferSize)
656
                                {
657
                                        I2C_SendData(I2C1, I2C1_Bus.pData[Tx_Idx]);
658
                                        Tx_Idx++;
659
                                }
660
                                else // last byte was send
661
                                {
662
                                        // generate stop or repeated start condition
663
                                        if (I2C1_Bus.RxBufferSize > 0) // is any answer byte expected?
664
                                        {
665
                                                I2C1_Bus.Direction = I2C_MODE_RECEIVER; // switch to master receiver after repeated start condition
666
                                                I2C_GenerateStart(I2C1, ENABLE);   // initiate repeated start condition on the bus
667
                                        }
668
                                        else
669
                                        {   // stop communication
670
                                                I2C_GenerateSTOP(I2C1, ENABLE); // generate stop condition to free the bus
671
                                                VIC_ITCmd(I2C1_ITLine, DISABLE);
672
                                                I2C1_Bus.State = I2C_STATE_IDLE;                        // ready for new actions
673
                                                I2C1_Bus.Error = I2C_ERROR_NONE;       
674
                                        }
675
                                }
676
                                break;
677
 
678
                        // the master has received a byte from the slave
679
                        case I2C_EVENT_MASTER_BYTE_RECEIVED:
680
                                // some bytes have to be received
681
                                if ( Rx_Idx+1 < I2C1_Bus.RxBufferSize)
682
                                {       // copy received byte  from the data register to the rx-buffer
683
                                        I2C1_Bus.pData[Rx_Idx] = I2C_ReceiveData(I2C1);
684
                                }
685
                                else // if the last byte was received
686
                                {
687
                                        // generate a STOP condition on the bus before reading data register
688
                                        I2C_GenerateSTOP(I2C1, ENABLE);
689
                                        I2C1_Bus.pData[Rx_Idx] = I2C_ReceiveData(I2C1);
690
                                        // call the rx handler function to process recieved data
691
                                        if(I2C1_Bus.pRxHandler != NULL) (*(I2C1_Bus.pRxHandler))(I2C1_Bus.pData, I2C1_Bus.RxBufferSize);
692
                                        I2C1_Bus.Timeout = SetDelay(I2C_TIMEOUT);
693
                                        DebugOut.Analog[15]++;
694
                                        VIC_ITCmd(I2C1_ITLine, DISABLE);
695
                                        I2C1_Bus.State = I2C_STATE_IDLE;
696
                                        I2C1_Bus.Error = I2C_ERROR_NONE;
697
                                        return;
698
                                }
699
                                Rx_Idx++;
700
                                // if the 2nd last byte was received disable acknowledge for the last one
701
                                if ( (Rx_Idx + 1) == I2C1_Bus.RxBufferSize )
702
                                {
703
                                        I2C_AcknowledgeConfig(I2C1, DISABLE);
704
                                }
705
                                break;
706
 
707
                        default:// unknown event
708
                                // should never happen
508 holgerb 709
                                DebugOut.Analog[14]++;
482 killagreg 710
                                I2C_GenerateSTOP (I2C1, ENABLE);
711
                                VIC_ITCmd(I2C1_ITLine, DISABLE);
712
                                I2C1_Bus.State = I2C_STATE_IDLE;
713
                                I2C1_Bus.Error = I2C_ERROR_UNKNOWN;
714
                                break;
715
                }
716
        }
717
        //IDISABLE;      // do not enable IRQ nesting for I2C!!!!
718
        VIC1->VAR = 0xFF; // write any value to VIC1 Vector address register
719
}
720
 
721
// ----------------------------------------------------------------------------------------
722
// wait for end of transmission
723
// returns 1 on success or 0 on timeout
724
u8 I2CBus_WaitForEndOfTransmission(I2C_TypeDef* I2Cx, u32 timeout)
725
{
726
        volatile I2C_Bus_t *pBus = NULL;
727
        u32 time = SetDelay(timeout);
728
 
729
        if(I2Cx == I2C0) pBus = &I2C0_Bus;
730
        if(I2Cx == I2C1) pBus = &I2C1_Bus;
731
        if(pBus == NULL) return(0);
732
        while(pBus->State != I2C_STATE_IDLE)
733
        {
508 holgerb 734
                if(CheckDelay(time))  // Timeout
735
                 {
736
                  return(0);
737
                 }
482 killagreg 738
        }
739
        return(1);
740
}
741
 
742
// ----------------------------------------------------------------------------------------
743
// try to get access to the transfer buffer      within a timeout limit
744
// returs 1 on success and 0 on error/timeout
745
u8 I2CBus_LockBuffer(I2C_TypeDef* I2Cx, u32 timeout)
746
{
747
        volatile I2C_Bus_t *pBus = NULL;       
748
 
749
        if(I2Cx == I2C0) pBus = &I2C0_Bus;
750
        if(I2Cx == I2C1) pBus = &I2C1_Bus;
751
        if(pBus == NULL) return(0);
752
 
753
        if(I2CBus_WaitForEndOfTransmission(I2Cx, timeout))
754
        {
861 holgerb 755
                pBus->State = I2C_STATE_BUFFBUSY;
482 killagreg 756
                pBus->Error = I2C_ERROR_UNKNOWN;
757
                return(1);
758
        }
759
        else return(0);
760
}
761
// ----------------------------------------------------------------------------------------
762
// initate an i2c transmission
763
// before that function is called, the application has to call I2CBus_LockBuffer and has to fill the Buffer with data to be send
764
u8 I2CBus_Transmission(I2C_TypeDef* I2Cx, u8 SlaveAddr, u8* pTxData, u8 TxBytes, I2C_pRxHandler_t pRxHandler, u8 RxBytes)
765
{
766
        u8 retval = 0;
767
 
768
        volatile I2C_Bus_t *pBus = NULL;       
769
 
770
        if(I2Cx == I2C0) pBus = &I2C0_Bus;
771
        if(I2Cx == I2C1) pBus = &I2C1_Bus;
772
        if(pBus == NULL) return(0);
773
 
774
 
775
        if(pBus->State == I2C_STATE_BUFFBUSY)  // check for locked buffer
776
        {
777
                if((RxBytes > I2C_BUFFER_LEN) || (TxBytes > I2C_BUFFER_LEN))
778
                {
779
                        pBus->State = I2C_STATE_IDLE;
780
                        return(retval);
781
                }      
782
                pBus->RxBufferSize = RxBytes;
783
                pBus->TxBufferSize = TxBytes;
784
                // set direction to master transmitter
785
                if( (pBus->TxBufferSize > 0) && (pBus->TxBufferSize < I2C_BUFFER_LEN) )
786
                {
787
                        pBus->Direction = I2C_MODE_TRANSMITTER;
788
                        // copy data to send from source to tansfer buffer
789
                        if(pTxData) memcpy(pBus->pData, pTxData, pBus->TxBufferSize);
790
                }
791
                else if (( pBus->RxBufferSize > 0 ) && (pBus->RxBufferSize < I2C_BUFFER_LEN) )
792
                {
793
                        pBus->Direction = I2C_MODE_RECEIVER;
794
                }
795
                else // nothing to send or receive
796
                {
797
                        pBus->State = I2C_STATE_IDLE;
798
                        pBus->Error = I2C_ERROR_NONE;
799
                        pBus->TxBufferSize = 0;
800
                        pBus->RxBufferSize = 0;
801
                        return(retval);
802
                }
803
                // update slave address and rx data handler     function pointer
804
                pBus->SlaveAddr = SlaveAddr;
805
                pBus->pRxHandler = pRxHandler;
806
                // test on busy flag and clear it
807
                I2C_ClearFlag(I2Cx, I2C_FLAG_BUSY);
808
                // enable I2C IRQ
809
                VIC_ITCmd(pBus->VIC_Source, ENABLE);
810
                // initiate start condition on the bus
811
                I2C_GenerateStart(I2Cx, ENABLE);
812
                retval = 1;
813
         }
814
         return(retval);
815
}