]> git.zerfleddert.de Git - fhem-stuff/blame - culfw/culfw-asksin-fix.diff
no need for inline
[fhem-stuff] / culfw / culfw-asksin-fix.diff
CommitLineData
b2720844
MG
1Index: clib/rf_asksin.c
2===================================================================
3--- clib/rf_asksin.c (revision 373)
4+++ clib/rf_asksin.c (working copy)
1bfa61a8 5@@ -9,15 +9,18 @@
b2720844 6
1bfa61a8
MG
7 #include "rf_asksin.h"
8
9+//we receive a new byte approximately every 7 ms...
10+#define RX_TIMEOUT_MS 10
11+
b2720844
MG
12 uint8_t asksin_on = 0;
13
14-const uint8_t PROGMEM ASKSIN_CFG[50] = {
532a7bf0 15- 0x00, 0x07,
b2720844 16+const uint8_t PROGMEM ASKSIN_CFG[] = {
532a7bf0 17+ 0x00, 0x01,
b2720844
MG
18 0x02, 0x2e,
19 0x03, 0x0d,
532a7bf0
MG
20 0x04, 0xE9,
21 0x05, 0xCA,
22- 0x07, 0x0C,
23+ 0x07, 0x04,
24 0x0B, 0x06,
25 0x0D, 0x21,
26 0x0E, 0x65,
1bfa61a8 27@@ -26,18 +29,22 @@
b2720844
MG
28 0x11, 0x93,
29 0x12, 0x03,
30 0x15, 0x34,
31- 0x17, 0x30, // always go into IDLE
cf4474a9 32+ 0x17, 0x3F, // always go into RX after TX, CCA, ELV uses 0x03
b2720844
MG
33 0x18, 0x18,
34 0x19, 0x16,
35 0x1B, 0x43,
36 0x21, 0x56,
37 0x25, 0x00,
38 0x26, 0x11,
39+ 0x29, 0x59,
40+ 0x2c, 0x81,
41 0x2D, 0x35,
777ef621 42- 0x3e, 0xc3,
b2720844 43- 0xff
777ef621 44+ 0x3e, 0xc3
b2720844
MG
45 };
46
b74270d7 47+static inline uint8_t read_cc1100_rxbytes(void);
ee6c84c4 48+static void rf_asksin_reset_rx(void);
532a7bf0 49+
b2720844 50 void
532a7bf0
MG
51 rf_asksin_init(void)
52 {
1bfa61a8 53@@ -56,20 +63,44 @@
b2720844
MG
54 my_delay_us(100);
55
56 // load configuration
57- for (uint8_t i = 0; i<50; i += 2) {
777ef621
MG
58-
59- if (pgm_read_byte( &ASKSIN_CFG[i] )>0x40)
60- break;
61-
b2720844 62+ for (uint8_t i = 0; i < sizeof(ASKSIN_CFG); i += 2) {
777ef621
MG
63 cc1100_writeReg( pgm_read_byte(&ASKSIN_CFG[i]),
64 pgm_read_byte(&ASKSIN_CFG[i+1]) );
65 }
b2720844
MG
66
67 ccStrobe( CC1100_SCAL );
68
69- my_delay_ms(1);
70+ my_delay_ms(4);
71+
72+ ccRX();
73 }
74
532a7bf0 75+// Workaround for CC1101 Errata 3
b74270d7
MG
76+static inline uint8_t
77+read_cc1100_rxbytes(void)
532a7bf0
MG
78+{
79+ uint8_t rxbytes, rxbytes2;
80+
81+ rxbytes = cc1100_readReg(CC1100_RXBYTES);
82+ while((rxbytes2 = cc1100_readReg(CC1100_RXBYTES)) != rxbytes)
83+ rxbytes = rxbytes2;
84+
85+ return rxbytes;
86+}
b74270d7 87+
ee6c84c4 88+static void
b74270d7
MG
89+rf_asksin_reset_rx(void)
90+{
91+ ccStrobe( CC1100_SFRX );
92+ ccStrobe( CC1100_SIDLE );
93+ ccStrobe( CC1100_SNOP );
94+
95+ while (read_cc1100_rxbytes() & 0x7f)
96+ cc1100_readReg(CC1100_RXFIFO);
97+
98+ ccStrobe( CC1100_SRX );
99+}
532a7bf0 100+
b2720844 101 void
532a7bf0
MG
102 rf_asksin_task(void)
103 {
1bfa61a8 104@@ -77,18 +108,51 @@
cf4474a9
MG
105 uint8_t dec[MAX_ASKSIN_MSG];
106 uint8_t rssi;
107 uint8_t l;
108+ uint8_t rxfifo_cnt;
1bfa61a8 109+ uint16_t timeout;
cf4474a9
MG
110
111 if(!asksin_on)
112 return;
113
532a7bf0
MG
114- // see if a CRC OK pkt has been arrived
115- if (bit_is_set( CC1100_IN_PORT, CC1100_IN_PIN )) {
116+ // see if there is data to be read
117+ while (bit_is_set( CC1100_IN_PORT, CC1100_IN_PIN )) {
118+ rxfifo_cnt = read_cc1100_rxbytes();
cf4474a9 119
532a7bf0
MG
120+ if (rxfifo_cnt & 0x80) // Overflow
121+ break;
122+
123+ rxfifo_cnt &= 0x7f;
124+
125 enc[0] = cc1100_readReg( CC1100_RXFIFO ) & 0x7f; // read len
b74270d7 126+ rxfifo_cnt--;
cf4474a9 127
b74270d7
MG
128- if (enc[0]>=MAX_ASKSIN_MSG)
129- enc[0] = MAX_ASKSIN_MSG-1;
db4f8119 130-
b74270d7
MG
131+ if (enc[0] >= MAX_ASKSIN_MSG) {
132+ // Something went horribly wrong, out of sync?
133+ rf_asksin_reset_rx();
134+ return;
135+ }
db4f8119 136+
1bfa61a8
MG
137+ if ((enc[0] + 2) > rxfifo_cnt) {
138+ timeout = RX_TIMEOUT_MS * ((enc[0] + 2) - rxfifo_cnt);
139+ while (timeout-- && ((enc[0] + 2) > rxfifo_cnt)) { // Wait for more data
140+ my_delay_ms(1);
141+ rxfifo_cnt = read_cc1100_rxbytes();
b74270d7 142+
1bfa61a8
MG
143+ if (rxfifo_cnt & 0x80) { // Overflow
144+ rf_asksin_reset_rx();
145+ return;
146+ }
147+
148+ rxfifo_cnt &= 0x7f;
149+ }
150+
151+ if (!timeout) {
152+ // Not enough data received, out of sync?
153+ rf_asksin_reset_rx();
154+ return;
155+ }
532a7bf0
MG
156+ }
157+
db4f8119
MG
158 CC1100_ASSERT;
159 cc1100_sendbyte( CC1100_READ_BURST | CC1100_RXFIFO );
532a7bf0 160
1bfa61a8 161@@ -97,14 +161,19 @@
532a7bf0
MG
162 }
163
164 rssi = cc1100_sendbyte( 0 );
cf4474a9 165-
532a7bf0
MG
166+
167 CC1100_DEASSERT;
b2720844
MG
168
169- ccStrobe( CC1100_SFRX );
170- ccStrobe( CC1100_SIDLE );
171- ccStrobe( CC1100_SNOP );
172- ccStrobe( CC1100_SRX );
b74270d7
MG
173+ // We must not read the last byte from the RX fifo while RX is in progress (Errata 1)
174+ while (((read_cc1100_rxbytes() & 0x7f) == 1) && (cc1100_readReg(CC1100_PKTSTATUS) & (1 << 3))) {
175+ my_delay_ms(1);
176+ }
177
178+ l = cc1100_readReg(CC1100_RXFIFO);
179+
532a7bf0
MG
180+ if (!(l & 0x80)) // CRC not ok
181+ continue;
b74270d7 182+
532a7bf0
MG
183 dec[0] = enc[0];
184 dec[1] = (~enc[1]) ^ 0x89;
b74270d7 185
1bfa61a8 186@@ -113,7 +182,6 @@
532a7bf0
MG
187
188 dec[l] = enc[l] ^ dec[2];
189
b2720844 190-
532a7bf0 191 if (tx_report & REP_BINTIME) {
cf4474a9 192
532a7bf0 193 DC('a');
1bfa61a8 194@@ -131,26 +199,17 @@
cf4474a9 195
532a7bf0 196 DNL();
b2720844 197 }
532a7bf0
MG
198+ }
199
cf4474a9 200- return;
b2720844 201-
532a7bf0
MG
202+ switch(cc1100_readReg( CC1100_MARCSTATE )) {
203+ case MARCSTATE_RXFIFO_OVERFLOW:
204+ ccStrobe( CC1100_SFRX );
205+ case MARCSTATE_IDLE:
206+ ccStrobe( CC1100_SIDLE );
207+ ccStrobe( CC1100_SNOP );
208+ ccStrobe( CC1100_SRX );
209+ break;
b2720844
MG
210 }
211-
212-
213- switch (cc1100_readReg( CC1100_MARCSTATE )) {
214-
215- // RX_OVERFLOW
216- case 17:
217- // IDLE
218- case 1:
219- ccStrobe( CC1100_SFRX );
220- ccStrobe( CC1100_SIDLE );
221- ccStrobe( CC1100_SNOP );
222- ccStrobe( CC1100_SRX );
223- break;
224-
225- }
532a7bf0 226-
b2720844
MG
227 }
228
229 void
1bfa61a8 230@@ -173,20 +232,7 @@
b2720844
MG
231 my_delay_ms(3); // 3ms: Found by trial and error
232 }
233
234- ccStrobe(CC1100_SIDLE);
235- ccStrobe(CC1100_SFRX );
236- ccStrobe(CC1100_SFTX );
237-
238- if (dec[2] & (1 << 4)) { //BURST-bit set?
239- ccStrobe(CC1100_STX ); //We need to send a burst
240-
241- //According to ELV, devices get activated every 300ms, so send burst for 360ms
242- for(l = 0; l < 3; l++)
243- my_delay_ms(120); //arg is uint_8, so loop
244- }
245-
246 // "crypt"
247-
248 enc[0] = dec[0];
249 enc[1] = (~dec[1]) ^ 0x89;
250
1bfa61a8 251@@ -195,6 +241,15 @@
b2720844
MG
252
253 enc[l] = dec[l] ^ dec[2];
254
255+ ccTX();
256+ if (dec[2] & (1 << 4)) { // BURST-bit set?
257+ // According to ELV, devices get activated every 300ms, so send burst for 360ms
258+ for(l = 0; l < 3; l++)
259+ my_delay_ms(120); // arg is uint_8, so loop
5f2228fc
MG
260+ } else {
261+ my_delay_ms(10);
b2720844
MG
262+ }
263+
264 // send
265 CC1100_ASSERT;
266 cc1100_sendbyte(CC1100_WRITE_BURST | CC1100_TXFIFO);
1bfa61a8 267@@ -205,12 +260,17 @@
b2720844
MG
268
269 CC1100_DEASSERT;
270
271- ccStrobe( CC1100_SFRX );
272- ccStrobe( CC1100_STX );
273+ // wait for TX to finish
274+ while(cc1100_readReg( CC1100_MARCSTATE ) == MARCSTATE_TX)
275+ ;
777ef621
MG
276+
277+ if (cc1100_readReg( CC1100_MARCSTATE ) == MARCSTATE_TXFIFO_UNDERFLOW) {
278+ ccStrobe( CC1100_SFTX );
279+ ccStrobe( CC1100_SIDLE );
280+ ccStrobe( CC1100_SNOP );
281+ ccStrobe( CC1100_SRX );
282+ }
b2720844
MG
283
284- while( cc1100_readReg( CC1100_MARCSTATE ) != 1 )
285- my_delay_ms(5);
286-
287 if(asksin_on) {
288 ccRX();
289 } else {
Impressum, Datenschutz