-
Notifications
You must be signed in to change notification settings - Fork 0
/
m_rf.c
153 lines (120 loc) · 3.8 KB
/
m_rf.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
// -----------------------------------------------------------------------------
// M2 RF communication subsystem
// version: 2.0
// date: June 30, 2011
// author: J. Fiene
// -----------------------------------------------------------------------------
#include "m_rf.h"
#define MRFTWIADDR 0x28
#define MRFINIT 0x01
#define MRFREAD 0x02
#define MRFSEND 0x03
char m_rf_open(char channel, char RXaddress, char packet_length)
{
// START | MRFTWIADDR | MRFINIT | channel | RXaddress | packet_length | STOP
m_bus_init();
// START
TWCR = (1<<TWEN)|(1<<TWSTA)|(1<<TWINT);
while(!(TWCR & (1<<TWINT))){};
// ADDRESS
TWDR = MRFTWIADDR<<1;
TWCR = (1<<TWINT) | (1<<TWEN);
while(!(TWCR & (1<<TWINT))){};
if((TWSR & 0xF8)== 0x20){ // ACK was not received - may not be connected/listening
TWCR = (1<<TWINT)|(1<<TWEN)| (1<<TWSTO); // let go of the line (STOP)
return 0;
}
// SEND THE DESIRED MRF MODE
TWDR = MRFINIT;
TWCR = (1<<TWINT) | (1<<TWEN);
while(!(TWCR & (1<<TWINT))){};
// SEND DATA
TWDR = channel;
TWCR = (1<<TWINT) | (1<<TWEN);
while(!(TWCR & (1<<TWINT))){};
TWDR = RXaddress;
TWCR = (1<<TWINT) | (1<<TWEN);
while(!(TWCR & (1<<TWINT))){};
TWDR = packet_length;
TWCR = (1<<TWINT) | (1<<TWEN);
while(!(TWCR & (1<<TWINT))){};
// STOP
TWCR = (1<<TWINT)|(1<<TWEN)| (1<<TWSTO);
return 1;
}
char m_rf_read(char* buffer, char packet_length)
{
// START | MRFTWIADDR (in MR mode) | (BYTES) | (DATA_0) | ... | (DATA_N) | STOP
char bytes;
int i;
// START
TWCR = (1<<TWEN)|(1<<TWSTA)|(1<<TWINT);
while(!(TWCR & (1<<TWINT))){};
// ADDRESS (in Master-Receiver Mode)
TWDR = ((MRFTWIADDR<<1)|1);
TWCR = (1<<TWINT) | (1<<TWEN);
while(!(TWCR & (1<<TWINT))){}; // wait until finished sending address
if((TWSR & 0xF8)== 0x48){ // ACK was not received
TWCR = (1<<TWINT)|(1<<TWEN)| (1<<TWSTO); // let go of the line (STOP)
return 0; // not connected/listening
}
// (BYTES)
TWCR = (1<<TWINT) | (1<<TWEA) | (1<<TWEN); // clear the flag, enable ACKs, and wait for another byte
while(!(TWCR & (1<<TWINT))){}; // wait for an interrupt to signal that a new byte is available
bytes = TWDR;
if(bytes != packet_length){
TWCR = (1<<TWINT)|(1<<TWEN)| (1<<TWSTO); // let go of the line (STOP)
return 0; // indicate length mismatch
}
// (DATA_0 ... DATA_N)
for(i=0;i<(bytes-1);i++)
{
TWCR = (1<<TWINT) | (1<<TWEA) | (1<<TWEN); // clear the flag, enable ACKs, and wait for another byte
while(!(TWCR & (1<<TWINT))){}; // wait for an interrupt to signal that a new byte is available
buffer[i] = TWDR;
}
TWCR = (1<<TWINT) | (1<<TWEN); // clear the flag, no ACK, and wait for another byte
while(!(TWCR & (1<<TWINT))){}; // wait for an interrupt to signal that a new byte is available
buffer[i++] = TWDR;
// STOP
TWCR = (1<<TWINT)|(1<<TWEN)| (1<<TWSTO);
return 1;
}
char m_rf_send(char TXaddress, char* buffer, char packet_length)
{
// START | MRFTWIADDR | MRFSEND | TXaddress | DATA_0 | ... | DATA_N | STOP
int i;
// DISABLE INTERRUPTS
cli();
// START
TWCR = (1<<TWEN)|(1<<TWSTA)|(1<<TWINT);
while(!(TWCR & (1<<TWINT))){};
// ADDRESS
TWDR = MRFTWIADDR<<1;
TWCR = (1<<TWINT) | (1<<TWEN);
while(!(TWCR & (1<<TWINT))){};
if((TWSR & 0xF8)== 0x20){ // ACK was not received - may not be connected/listening
TWCR = (1<<TWINT)|(1<<TWEN)| (1<<TWSTO); // let go of the line (STOP)
sei(); // re-enable interrupts
return 0;
}
// SEND THE DESIRED MRF MODE (SEND)
TWDR = MRFSEND;
TWCR = (1<<TWINT) | (1<<TWEN);
while(!(TWCR & (1<<TWINT))){};
// SEND THE DESIRED MRF MODE (SEND)
TWDR = TXaddress;
TWCR = (1<<TWINT) | (1<<TWEN);
while(!(TWCR & (1<<TWINT))){};
// SEND DATA
for(i=0;i<packet_length;i++){
TWDR = buffer[i];
TWCR = (1<<TWINT) | (1<<TWEN);
while(!(TWCR & (1<<TWINT))){};
}
// STOP
TWCR = (1<<TWINT)|(1<<TWEN)| (1<<TWSTO);
// RE-ENABLE INTERRUPTS
sei();
return 1;
}