]> git.zerfleddert.de Git - fhem-stuff/blame - culfw/culfw-asksin-fix.diff
handle RX/TX switching and respect CCA
[fhem-stuff] / culfw / culfw-asksin-fix.diff
CommitLineData
b2720844
MG
1Index: clib/rf_asksin.c
2===================================================================
82f42c48 3--- clib/rf_asksin.c (revision 377)
b2720844 4+++ clib/rf_asksin.c (working copy)
f59d1d47 5@@ -9,15 +9,18 @@
b2720844 6
f59d1d47
MG
7 #include "rf_asksin.h"
8
9+//we receive a new byte approximately every 8 ms...
10+#define RX_TIMEOUT_MS 10
11+
b2720844
MG
12 uint8_t asksin_on = 0;
13
82f42c48 14 const uint8_t PROGMEM ASKSIN_CFG[] = {
532a7bf0 15- 0x00, 0x07,
532a7bf0 16+ 0x00, 0x01,
b2720844
MG
17 0x02, 0x2e,
18 0x03, 0x0d,
532a7bf0 19 0x04, 0xE9,
f59d1d47
MG
20 0x05, 0xCA,
21- 0x07, 0x0C,
22+ 0x07, 0x04,
23 0x0B, 0x06,
24 0x0D, 0x21,
25 0x0E, 0x65,
82f42c48 26@@ -26,7 +29,7 @@
b2720844
MG
27 0x11, 0x93,
28 0x12, 0x03,
29 0x15, 0x34,
82f42c48
MG
30- 0x17, 0x33, // go into RX after TX, CCA; EQ3 uses 0x03
31+ 0x17, 0x3F, // always go into RX, CCA; EQ3 uses 0x03
b2720844
MG
32 0x18, 0x18,
33 0x19, 0x16,
34 0x1B, 0x43,
82f42c48
MG
35@@ -39,6 +42,7 @@
36 0x3e, 0xc3
b2720844
MG
37 };
38
f59d1d47 39+static inline uint8_t read_cc1100_rxbytes(void);
82f42c48 40 static void rf_asksin_reset_rx(void);
b2720844 41
82f42c48 42 void
54f699f3
MG
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);
b2720844
MG
52 }
53
f59d1d47
MG
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+
82f42c48
MG
67 static void
68 rf_asksin_reset_rx(void)
69 {
70 ccStrobe( CC1100_SFRX );
71 ccStrobe( CC1100_SIDLE );
72 ccStrobe( CC1100_SNOP );
f59d1d47
MG
73+
74+ while (read_cc1100_rxbytes() & 0x7f)
75+ cc1100_readReg(CC1100_RXFIFO);
76+
82f42c48
MG
77 ccStrobe( CC1100_SRX );
78 }
79
54f699f3 80@@ -87,13 +111,29 @@
f59d1d47
MG
81 uint8_t dec[MAX_ASKSIN_MSG];
82 uint8_t rssi;
83 uint8_t l;
84+ uint8_t rxfifo_cnt;
85+ uint16_t timeout;
cf4474a9 86
f59d1d47
MG
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();
82f42c48 95+
f59d1d47
MG
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)
82f42c48 102+ while ((rxfifo_cnt < 2) && (cc1100_readReg(CC1100_PKTSTATUS) & (1 << 3))) {
f59d1d47
MG
103+ my_delay_ms(1);
104+ rxfifo_cnt = read_cc1100_rxbytes() & 0x7f;
105+ }
106+
532a7bf0 107 enc[0] = cc1100_readReg( CC1100_RXFIFO ) & 0x7f; // read len
f59d1d47 108+ rxfifo_cnt--;
cf4474a9 109
82f42c48
MG
110 if (enc[0] >= MAX_ASKSIN_MSG) {
111 // Something went horribly wrong, out of sync?
54f699f3 112@@ -101,6 +141,27 @@
82f42c48
MG
113 return;
114 }
115
f59d1d47
MG
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+ }
532a7bf0 136+
db4f8119
MG
137 CC1100_ASSERT;
138 cc1100_sendbyte( CC1100_READ_BURST | CC1100_RXFIFO );
532a7bf0 139
54f699f3 140@@ -109,12 +170,19 @@
532a7bf0
MG
141 }
142
143 rssi = cc1100_sendbyte( 0 );
82f42c48
MG
144- /* LQI = */ cc1100_sendbyte( 0 );
145
532a7bf0 146 CC1100_DEASSERT;
b2720844 147
f59d1d47
MG
148- ccStrobe( CC1100_SRX );
149+ // We must not read the last byte from the RX fifo while RX is in progress (Errata 1)
82f42c48 150+ while (((read_cc1100_rxbytes() & 0x7f) < 2) && (cc1100_readReg(CC1100_PKTSTATUS) & (1 << 3))) {
f59d1d47
MG
151+ my_delay_ms(1);
152+ }
b74270d7 153
f59d1d47
MG
154+ l = cc1100_readReg(CC1100_RXFIFO);
155+
156+ if (!(l & 0x80)) // CRC not ok
157+ continue;
158+
532a7bf0 159 dec[0] = enc[0];
f59d1d47
MG
160 dec[1] = (~enc[1]) ^ 0x89;
161
54f699f3
MG
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