1 | //#################################################################################################*/
|
2 |
|
3 | #include <util/twi.h> // Bezeichnungen für Statuscodes in TWSR
|
4 | #include <avr/interrupt.h> // behandlung der Interrupts
|
5 | #include <stdint.h> // definiert Datentyp uint8_t
|
6 | #include "twislave.h"
|
7 |
|
8 |
|
9 |
|
10 | //########################################################################################## init_twi_slave
|
11 |
|
12 | void init_twi_slave(uint8_t adr)
|
13 | {
|
14 | cli();
|
15 | TWAR= adr; //Adresse setzen
|
16 | TWCR &= ~(1<<TWSTA)|(1<<TWSTO);
|
17 | TWCR|= (1<<TWEA) | (1<<TWEN)|(1<<TWIE);
|
18 | buffer_adr=0xFF;
|
19 | sei();
|
20 | }
|
21 | //********************************************************************************************
|
22 |
|
23 | void Set_Sensor1(uint8_t *A1, uint8_t *B1, uint8_t *C1, uint8_t *D1, uint8_t *E1)
|
24 | {
|
25 | if (rxbuffer[0] == 0x11)
|
26 | {
|
27 | txbuffer[2]=*A1;
|
28 | txbuffer[3]=*B1;
|
29 | txbuffer[4]=*C1;
|
30 | txbuffer[5]=*D1;
|
31 | txbuffer[6]=*E1;
|
32 | }
|
33 | }
|
34 | //#################################### Macros
|
35 | //ACK nach empfangenen Daten senden/ ACK nach gesendeten Daten erwarten
|
36 | #define TWCR_ACK TWCR = (1<<TWEN)|(1<<TWIE)|(1<<TWINT)|(1<<TWEA)|(0<<TWSTA)|(0<<TWSTO)|(0<<TWWC);
|
37 |
|
38 | //NACK nach empfangenen Daten senden/ NACK nach gesendeten Daten erwarten
|
39 | #define TWCR_NACK TWCR = (1<<TWEN)|(1<<TWIE)|(1<<TWINT)|(0<<TWEA)|(0<<TWSTA)|(0<<TWSTO)|(0<<TWWC);
|
40 |
|
41 | //switched to the non adressed slave mode...
|
42 | #define TWCR_RESET TWCR = (1<<TWEN)|(1<<TWIE)|(1<<TWINT)|(1<<TWEA)|(0<<TWSTA)|(0<<TWSTO)|(0<<TWWC);
|
43 | //########################################################################################## ISR (TWI_vect)
|
44 | //ISR, die bei einem Ereignis auf dem Bus ausgelöst wird. Im Register TWSR befindet sich dann
|
45 | //ein Statuscode, anhand dessen die Situation festgestellt werden kann.
|
46 | ISR (TWI_vect)
|
47 | {
|
48 | uint8_t data=0;
|
49 | switch (TW_STATUS) // TWI-Statusregister prüfen und nötige Aktion bestimmen
|
50 | {
|
51 | case TW_SR_SLA_ACK: // 0x60 Slave Receiver, wurde adressiert
|
52 | TWCR_ACK; // nächstes Datenbyte empfangen, ACK danach
|
53 | buffer_adr=0xFF; // Bufferposition ist undefiniert
|
54 | break;
|
55 |
|
56 | case TW_SR_DATA_ACK: // 0x80 Slave Receiver,Daten empfangen
|
57 | data=TWDR; // Empfangene Daten auslesen
|
58 | if (buffer_adr == 0xFF) // erster Zugriff, Bufferposition setzen
|
59 | {
|
60 | if(data<=buffer_size) // Kontrolle ob gewünschte Adresse im erlaubten bereich
|
61 | {
|
62 | buffer_adr= data; // Bufferposition wie adressiert setzen
|
63 | }
|
64 | else
|
65 | {
|
66 | buffer_adr=0; // Adresse auf Null setzen. Ist das sinnvoll?
|
67 | }
|
68 | TWCR_ACK; // nächstes Datenbyte empfangen, ACK danach, um nächstes Byte anzufordern
|
69 | }
|
70 | else // weiterer Zugriff, Daten empfangen
|
71 | {
|
72 | rxbuffer[buffer_adr]=data; // Daten in Buffer schreiben
|
73 | buffer_adr++; // Buffer-Adresse weiterzählen für nächsten Schreibzugriff
|
74 | if(buffer_adr<(buffer_size-1)) // im Buffer ist noch Platz für mehr als ein Byte
|
75 | {
|
76 | TWCR_ACK; // nächstes Datenbyte empfangen, ACK danach, um nächstes Byte anzufordern
|
77 | }
|
78 | else // es kann nur noch ein Byte kommen, dann ist der Buffer voll
|
79 | {
|
80 | TWCR_NACK; // letztes Byte lesen, dann NACK, um vollen Buffer zu signaliseren
|
81 | }
|
82 | }
|
83 | break;
|
84 |
|
85 | case TW_ST_SLA_ACK: //
|
86 | case TW_ST_DATA_ACK: // 0xB8 Slave Transmitter, weitere Daten wurden angefordert
|
87 |
|
88 | if (buffer_adr == 0xFF) // zuvor keine Leseadresse angegeben!
|
89 | {
|
90 | buffer_adr=0;
|
91 | }
|
92 | TWDR = txbuffer[buffer_adr]; // Datenbyte senden
|
93 | buffer_adr++; // bufferadresse für nächstes Byte weiterzählen
|
94 | if(buffer_adr<(buffer_size-1)) // im Buffer ist mehr als ein Byte, das gesendet werden kann
|
95 | {
|
96 | TWCR_ACK; // nächstes Byte senden, danach ACK erwarten
|
97 | }
|
98 | else
|
99 | {
|
100 | TWCR_NACK; // letztes Byte senden, danach NACK erwarten
|
101 | }
|
102 | break;
|
103 |
|
104 | case TW_ST_DATA_NACK: // 0xC0 Keine Daten mehr gefordert
|
105 | case TW_SR_DATA_NACK: // 0x88
|
106 | case TW_ST_LAST_DATA: // 0xC8 Last data byte in TWDR has been transmitted (TWEA = “0”); ACK has been received
|
107 | case TW_SR_STOP: // 0xA0 STOP empfangen
|
108 | default:
|
109 | TWCR_RESET; // Übertragung beenden, warten bis zur nächsten Adressierung
|
110 | break;
|
111 |
|
112 | } //end.switch (TW_STATUS)
|
113 |
|
114 | //*!*!*!*! Hier soll die Funktion nur ausgeführt werden!!!***!!!
|
115 |
|
116 |
|
117 | } //end.ISR(TWI_vect)
|