]> git.zerfleddert.de Git - fhem-stuff/blame_incremental - culfw/culfw-asksin-fix.diff
handle RX/TX switching and respect CCA
[fhem-stuff] / culfw / culfw-asksin-fix.diff
... / ...
CommitLineData
1Index: clib/rf_asksin.c
2===================================================================
3--- clib/rf_asksin.c (revision 377)
4+++ clib/rf_asksin.c (working copy)
5@@ -9,15 +9,18 @@
6
7 #include "rf_asksin.h"
8
9+//we receive a new byte approximately every 8 ms...
10+#define RX_TIMEOUT_MS 10
11+
12 uint8_t asksin_on = 0;
13
14 const uint8_t PROGMEM ASKSIN_CFG[] = {
15- 0x00, 0x07,
16+ 0x00, 0x01,
17 0x02, 0x2e,
18 0x03, 0x0d,
19 0x04, 0xE9,
20 0x05, 0xCA,
21- 0x07, 0x0C,
22+ 0x07, 0x04,
23 0x0B, 0x06,
24 0x0D, 0x21,
25 0x0E, 0x65,
26@@ -26,7 +29,7 @@
27 0x11, 0x93,
28 0x12, 0x03,
29 0x15, 0x34,
30- 0x17, 0x33, // go into RX after TX, CCA; EQ3 uses 0x03
31+ 0x17, 0x3F, // always go into RX, CCA; EQ3 uses 0x03
32 0x18, 0x18,
33 0x19, 0x16,
34 0x1B, 0x43,
35@@ -39,6 +42,7 @@
36 0x3e, 0xc3
37 };
38
39+static inline uint8_t read_cc1100_rxbytes(void);
40 static void rf_asksin_reset_rx(void);
41
42 void
43@@ -68,15 +72,35 @@
44
45 my_delay_ms(4);
46
47- ccRX();
48+ // enable RX, but don't enable the interrupt
49+ do {
50+ ccStrobe(CC1100_SRX);
51+ } while (cc1100_readReg(CC1100_MARCSTATE) != MARCSTATE_RX);
52 }
53
54+// Workaround for CC1101 Errata 3
55+static inline uint8_t
56+read_cc1100_rxbytes(void)
57+{
58+ uint8_t rxbytes, rxbytes2;
59+
60+ rxbytes = cc1100_readReg(CC1100_RXBYTES);
61+ while((rxbytes2 = cc1100_readReg(CC1100_RXBYTES)) != rxbytes)
62+ rxbytes = rxbytes2;
63+
64+ return rxbytes;
65+}
66+
67 static void
68 rf_asksin_reset_rx(void)
69 {
70 ccStrobe( CC1100_SFRX );
71 ccStrobe( CC1100_SIDLE );
72 ccStrobe( CC1100_SNOP );
73+
74+ while (read_cc1100_rxbytes() & 0x7f)
75+ cc1100_readReg(CC1100_RXFIFO);
76+
77 ccStrobe( CC1100_SRX );
78 }
79
80@@ -87,13 +111,29 @@
81 uint8_t dec[MAX_ASKSIN_MSG];
82 uint8_t rssi;
83 uint8_t l;
84+ uint8_t rxfifo_cnt;
85+ uint16_t timeout;
86
87 if(!asksin_on)
88 return;
89
90- // see if a CRC OK pkt has been arrived
91- if (bit_is_set( CC1100_IN_PORT, CC1100_IN_PIN )) {
92+ // see if there is data to be read
93+ while (bit_is_set( CC1100_IN_PORT, CC1100_IN_PIN )) {
94+ rxfifo_cnt = read_cc1100_rxbytes();
95+
96+ if (rxfifo_cnt & 0x80) // Overflow
97+ break;
98+
99+ rxfifo_cnt &= 0x7f;
100+
101+ // We must not read the last byte from the RX fifo while RX is in progress (Errata 1)
102+ while ((rxfifo_cnt < 2) && (cc1100_readReg(CC1100_PKTSTATUS) & (1 << 3))) {
103+ my_delay_ms(1);
104+ rxfifo_cnt = read_cc1100_rxbytes() & 0x7f;
105+ }
106+
107 enc[0] = cc1100_readReg( CC1100_RXFIFO ) & 0x7f; // read len
108+ rxfifo_cnt--;
109
110 if (enc[0] >= MAX_ASKSIN_MSG) {
111 // Something went horribly wrong, out of sync?
112@@ -101,6 +141,27 @@
113 return;
114 }
115
116+ if ((enc[0] + 2) > rxfifo_cnt) {
117+ timeout = RX_TIMEOUT_MS * ((enc[0] + 2) - rxfifo_cnt);
118+ while (timeout-- && ((enc[0] + 2) > rxfifo_cnt)) { // Wait for more data
119+ my_delay_ms(1);
120+ rxfifo_cnt = read_cc1100_rxbytes();
121+
122+ if (rxfifo_cnt & 0x80) { // Overflow
123+ rf_asksin_reset_rx();
124+ return;
125+ }
126+
127+ rxfifo_cnt &= 0x7f;
128+ }
129+
130+ if (!timeout) {
131+ // Not enough data received, out of sync?
132+ rf_asksin_reset_rx();
133+ return;
134+ }
135+ }
136+
137 CC1100_ASSERT;
138 cc1100_sendbyte( CC1100_READ_BURST | CC1100_RXFIFO );
139
140@@ -109,12 +170,19 @@
141 }
142
143 rssi = cc1100_sendbyte( 0 );
144- /* LQI = */ cc1100_sendbyte( 0 );
145
146 CC1100_DEASSERT;
147
148- ccStrobe( CC1100_SRX );
149+ // We must not read the last byte from the RX fifo while RX is in progress (Errata 1)
150+ while (((read_cc1100_rxbytes() & 0x7f) < 2) && (cc1100_readReg(CC1100_PKTSTATUS) & (1 << 3))) {
151+ my_delay_ms(1);
152+ }
153
154+ l = cc1100_readReg(CC1100_RXFIFO);
155+
156+ if (!(l & 0x80)) // CRC not ok
157+ continue;
158+
159 dec[0] = enc[0];
160 dec[1] = (~enc[1]) ^ 0x89;
161
162@@ -182,7 +250,11 @@
163
164 enc[l] = dec[l] ^ dec[2];
165
166- ccTX();
167+ // enable TX, wait for CCA
168+ while (cc1100_readReg(CC1100_MARCSTATE) != MARCSTATE_TX) {
169+ ccStrobe(CC1100_STX);
170+ }
171+
172 if (dec[2] & (1 << 4)) { // BURST-bit set?
173 // According to ELV, devices get activated every 300ms, so send burst for 360ms
174 for(l = 0; l < 3; l++)
175@@ -209,11 +281,12 @@
176 ccStrobe( CC1100_SFTX );
177 ccStrobe( CC1100_SIDLE );
178 ccStrobe( CC1100_SNOP );
179- ccStrobe( CC1100_SRX );
180 }
181
182 if(asksin_on) {
183- ccRX();
184+ do {
185+ ccStrobe(CC1100_SRX);
186+ } while (cc1100_readReg(CC1100_MARCSTATE) != MARCSTATE_RX);
187 } else {
188 set_txrestore();
189 }
Impressum, Datenschutz