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