Subversion Repositories Projects

Rev

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

Rev Author Line No. Line
771 - 1
/****************************************************************************
1437 - 2
 *   Copyright (C) 2009-2012 by Claas Anders "CaScAdE" Rathje               *
771 - 3
 *   admiralcascade@gmail.com                                               *
4
 *   Project-URL: http://www.mylifesucks.de/oss/c-strom/                    *
5
 *                                                                          *
6
 *   This program is free software; you can redistribute it and/or modify   *
7
 *   it under the terms of the GNU General Public License as published by   *
8
 *   the Free Software Foundation; either version 2 of the License.         *
9
 *                                                                          *
10
 *   This program is distributed in the hope that it will be useful,        *
11
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of         *
12
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
13
 *   GNU General Public License for more details.                           *
14
 *                                                                          *
15
 *   You should have received a copy of the GNU General Public License      *
16
 *   along with this program; if not, write to the                          *
17
 *   Free Software Foundation, Inc.,                                        *
18
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.              *
19
 ****************************************************************************/
20
 
21
 
22
/****************************************************************************
23
 *                                                                          *
24
 *  Most of the i²c/twi code is originally from                             *
25
 *  http://www.rn-wissen.de/index.php/TWI_Slave_mit_avr-gcc                 *
26
 *                                                                          *
27
 ****************************************************************************/
28
 
29
#include <avr/interrupt.h>
30
#include <util/twi.h>
31
#include "i2c_slave.h"
32
#include "spi_union.h"
33
 
34
void init_twi_slave(uint8_t address) {
35
    TWAR = address;
36
    TWCR &= ~(1 << TWSTA) | (1 << TWSTO);
37
    TWCR |= (1 << TWEA) | (1 << TWEN) | (1 << TWIE);
38
    i2c_buf_adr = 0xFF;
39
    //sei();
40
}
41
 
42
ISR(TWI_vect) {
43
    uint8_t data = 0;
44
        //PORTD ^=  (1 << PD7); // toggle LED for test
45
    switch (TW_STATUS) {
46
        case TW_SR_SLA_ACK: // 0x60 Slave Receiver, wurde adressiert    
47
            TWCR_ACK; // next byte received
48
            i2c_buf_adr = 0xFF; // buf_adr undef
49
            break;
50
        case TW_SR_DATA_ACK: // 0x80 Slave Receiver,Daten empfangen
51
            data = TWDR; //Empfangene Daten auslesen
52
            if (i2c_buf_adr == 0xFF) {//erster Zugriff, Bufferposition setzen                  
53
                if (data <= I2C_BUFFER_SIZE) { //Kontrolle ob gewünschte Adresse im erlaubten bereich
54
                    i2c_buf_adr = data; //Bufferposition wie adressiert setzen
55
                } else {
56
                    i2c_buf_adr = 0; //Adresse auf Null setzen. Ist das sinnvoll?
57
                }
58
                TWCR_ACK; // nächstes Datenbyte empfangen, ACK danach, um nächstes Byte anzufordern
59
            } else {//weiterer Zugriff, Daten empfangen            
60
                i2c_rx_buffer[i2c_buf_adr] = data; //Daten in Buffer schreiben
61
                i2c_buf_adr++; //Buffer-Adresse weiterzählen für nächsten Schreibzugriff
62
                if (i2c_buf_adr < (I2C_BUFFER_SIZE - 1)) {//im Buffer ist noch Platz für mehr als ein Byte
63
                    TWCR_ACK; // nächstes Datenbyte empfangen, ACK danach, um nächstes Byte anzufordern
64
                } else {//es kann nur noch ein Byte kommen, dann ist der Buffer voll
65
                    TWCR_NACK; //letztes Byte lesen, dann NACK, um vollen Buffer zu signaliseren
66
                }
67
            }
68
            break;
69
        case TW_ST_SLA_ACK: //?!?
70
        case TW_ST_DATA_ACK: //0xB8 Slave Transmitter, weitere Daten wurden angefordert
71
            if (i2c_buf_adr == 0xFF) {//zuvor keine Leseadresse angegeben!             
72
                i2c_buf_adr = 0;
73
            }
74
            TWDR = i2c_tx_buffer[i2c_buf_adr]; //Datenbyte senden 
75
            i2c_buf_adr++; //bufferadresse für nächstes Byte weiterzählen
76
            if (i2c_buf_adr < (I2C_BUFFER_SIZE - 1)) {//im Buffer ist mehr als ein Byte, das gesendet werden kann
77
                TWCR_ACK; //nächstes Byte senden, danach ACK erwarten
78
            } else {
79
                TWCR_NACK; //letztes Byte senden, danach NACK erwarten
80
            }
81
            break;
82
        case TW_ST_DATA_NACK: //0xC0 Keine Daten mehr gefordert 
83
        case TW_SR_DATA_NACK: //0x88 
84
        case TW_ST_LAST_DATA: //0xC8  Last data byte in TWDR has been transmitted (TWEA = “0”); ACK has been received
85
        case TW_SR_STOP: // 0xA0 STOP empfangen
86
        default:
87
            TWCR_RESET; //Übertragung beenden, warten bis zur nächsten Adressierung
88
            break;
89
    }
90
}