Subversion Repositories MK3Mag

Rev

Rev 4 | Rev 12 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 ingob 1
 
2
#include <avr/io.h>
3
#include <util/twi.h>
4
#include "main.h"
5
 
3 ingob 6
unsigned char I2C_RxBufferSize, I2C_TxBufferSize;
7
unsigned char *I2C_TxBuffer, *I2C_RxBuffer;
8
unsigned char Tx_Idx=0, Rx_Idx=0, I2C_Direction;
9
unsigned char I2C_Command;
10
unsigned char Tx_Idx, Rx_Idx;
1 ingob 11
 
3 ingob 12
struct str_I2C_Heading       I2C_Heading;
13
struct str_I2C_WriteNickRoll I2C_WriteNickRoll;
14
struct str_I2C_Mag           I2C_Mag;
15
struct str_I2C_EEPROM        I2C_ReadEEPROM, I2C_WriteEEPROM;
16
struct str_I2C_Version       I2C_Version;
7 hbuss 17
struct str_I2C_WriteCal      I2C_WriteCal;
3 ingob 18
 
19
 
20
 
1 ingob 21
//############################################################################
22
//I2C (TWI) Interface Init
3 ingob 23
void InitIC2_Slave(void)
1 ingob 24
//############################################################################
25
{
3 ingob 26
    TWAR = I2C_SLAVE_ADDRESS; // Eigene Adresse setzen 
1 ingob 27
    TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWIE) | (1<<TWEA);
3 ingob 28
 
29
 
30
        I2C_Version.Hauptversion = VersionInfo.Hauptversion;
31
        I2C_Version.Nebenversion = VersionInfo.Nebenversion;
32
        I2C_Version.Comp = 1;
33
 
1 ingob 34
}
3 ingob 35
#define TWCR_ACK TWCR = (1<<TWEN)|(1<<TWIE)|(1<<TWINT)|(1<<TWEA)|(0<<TWSTA)|(0<<TWSTO)|(0<<TWWC)
1 ingob 36
//############################################################################
37
//ISR, die bei einem Ereignis auf dem Bus ausgelöst wird. Im Register TWSR befindet
38
//sich dann ein Statuscode, anhand dessen die Situation festgestellt werden kann.
39
ISR (TWI_vect)
40
//############################################################################
41
{  
42
    switch (TWSR & 0xF8)
43
        {  
44
        case SR_SLA_ACK:  
3 ingob 45
            //TWCR |= (1<<TWINT);
46
            Rx_Idx = 0;
47
 
48
                        TWCR_ACK;
1 ingob 49
            return;
50
        // Daten Empfangen
51
        case SR_PREV_ACK:
3 ingob 52
 
53
                        if (Rx_Idx  == 0)
54
                        { I2C_Command = TWDR;
55
 
56
                          switch(I2C_Command)
57
                          {
58
                             case I2C_CMD_VERSION:
59
                                                I2C_TxBuffer = (unsigned char *)&I2C_Version;
60
                                                I2C_TxBufferSize = sizeof(I2C_Version);
61
                                                I2C_RxBufferSize = 0;
62
                                break;
63
                                case I2C_CMD_WRITE_EEPROM:
64
                                                I2C_TxBufferSize = 0;
65
                                                I2C_RxBuffer = (unsigned char *)&I2C_WriteEEPROM;
66
                                                I2C_RxBufferSize = sizeof(I2C_WriteEEPROM);
67
                                break;
7 hbuss 68
 
69
                                case I2C_CMD_WRITE_CAL:
70
                                                I2C_TxBufferSize = 0;
71
                                                I2C_RxBuffer = (unsigned char *)&I2C_WriteCal;
72
                                                I2C_RxBufferSize = sizeof(I2C_WriteCal);
73
                                break;
74
 
3 ingob 75
                                case I2C_CMD_READ_EEPROM:
76
                                                I2C_TxBuffer = (unsigned char *)&I2C_ReadEEPROM.Inhalt;
77
                                                I2C_TxBufferSize = 2;
78
                                                I2C_RxBuffer = (unsigned char *)&I2C_ReadEEPROM;
79
                                                I2C_RxBufferSize = 1;
80
                                break;
81
                                case I2C_CMD_READ_MAG:
82
                                                I2C_TxBuffer = (unsigned char *)&I2C_Mag;
83
                                                I2C_TxBufferSize = sizeof(I2C_Mag);
84
                                                I2C_RxBufferSize = 0;
85
 
86
                                                I2C_Mag.MagX = MagnetN;
87
                                                I2C_Mag.MagY = MagnetR;
88
                                                I2C_Mag.MagZ = MagnetZ;
89
 
90
                                break;
91
                                case I2C_CMD_READ_HEADING:
92
                                                I2C_TxBuffer = (unsigned char *)&I2C_Heading;
93
                                                I2C_TxBufferSize = sizeof(I2C_Heading);
94
                                                I2C_RxBuffer =  (unsigned char *)&I2C_WriteNickRoll;
95
                                                I2C_RxBufferSize = sizeof(I2C_WriteNickRoll);
96
 
97
                                                I2C_Heading.Heading = Heading;
7 hbuss 98
                                                ExternData.Winkel[NICK] = I2C_WriteNickRoll.Nick;
99
                                                ExternData.Winkel[ROLL] = I2C_WriteNickRoll.Roll;
3 ingob 100
                                break;
101
                          }
102
                        }
103
                        else
104
                        {
4 ingob 105
                          if ((Rx_Idx-1) < I2C_RxBufferSize) I2C_RxBuffer[Rx_Idx-1] = TWDR;
3 ingob 106
                        }
107
 
108
                        Rx_Idx++;
109
 
110
 
1 ingob 111
            I2C_Timeout = 500;
3 ingob 112
            //TWCR |= (1<<TWINT);
113
                        TWCR_ACK;
1 ingob 114
            return;
115
        // Daten Senden
3 ingob 116
 
1 ingob 117
        case SW_SLA_ACK:  
3 ingob 118
            Tx_Idx = 0;
119
 
120
                        if (I2C_TxBufferSize > 0) TWDR = I2C_TxBuffer[Tx_Idx++];
121
 
122
//            TWCR |= (1<<TWINT) | (1<< TWEA);
123
             TWCR_ACK;
1 ingob 124
            return;
125
        // Daten Senden
3 ingob 126
                case SW_DATA_ACK:
127
            if (Tx_Idx < I2C_TxBufferSize) TWDR = I2C_TxBuffer[Tx_Idx++];
128
                         else TWDR = 0x00;
129
                        //TWCR |= (1<<TWINT) | (1<< TWEA);
130
                        TWCR_ACK;
1 ingob 131
            return;
132
        // Bus-Fehler zurücksetzen
133
        case TWI_BUS_ERR_2:
134
            TWCR |=(1<<TWSTO) | (1<<TWINT);
135
        // Bus-Fehler zurücksetzen   
136
        case TWI_BUS_ERR_1:
137
            TWCR |=(1<<TWSTO) | (1<<TWINT);
138
        }
139
    TWCR =(1<<TWEA) | (1<<TWINT) | (1<<TWEN) | (1<<TWIE); // TWI Reset
140
}
141
 
142