CUL > Hard- und Firmware

Firmware zu CUL, CUNX und Co. mit Timestamp Option ASKSIN tsculfw V0.30

(1/166) > >>

noansi:
*************************************************************************************************************
*************************************************************************************************************

Hier https://forum.fhem.de/index.php/topic,24436.msg891756.html#msg891756 geht es zur aktuellen Version 0.30 von TS Firmware, nun auch mit CUNX Unterstützung und FHEM Modulen.

*************************************************************************************************************
*************************************************************************************************************

Hier https://forum.fhem.de/index.php/topic,24436.msg853733.html#msg853733 geht es zu einer für tsculfw VTS 0.28 und höher angepassten Version
von Michael Gernoths flash-ota tool.

*************************************************************************************************************
*************************************************************************************************************



Hallo Rudolf,

hier mein Vorschlag zu einer Firmwareerweiterung für den CUL zur Unterstützung der TimeStamp Option. Sie bringt für das Senden zusammen mit Martins 00_CUL Änderungen eine Verbesserung.
Wenn Du es einpflegen würdest, würde ich mich freuen. Natürlich bin ich auch für Kritik offen.

Edit: Vergleichsbasis zum diff ist ein trunk culfw-code-419-trunk Stand vom 7.6.14. Meine Änderungen basieren auf culfw-code-416-trunk von Mitte Mai.

Zwei Teile für die Diffs sind notwendig wegen der Länge.


--- Code: ------ clib/cc1100.c Wed Feb 06 00:29:54 2013
+++ clib/cc1100.c Thu May 29 23:47:48 2014
@@ -310,7 +310,7 @@
       DS_P( PSTR(" = ") );
       DH2(out);                  // result, hex
       DS_P( PSTR(" / ") );
-      DU(out,2);                  // result, decimal
+      DU(out,2);  // should be DU(out,3);               // result, decimal
       DNL();
     }
 
--- clib/cdc.c Sat Apr 17 12:31:34 2010
+++ clib/cdc.c Mon Jun 09 16:55:51 2014
@@ -72,13 +72,23 @@
 
   if(!inCDC_TASK && Endpoint_ReadWriteAllowed()){ // USB -> RingBuffer
 
+    uint8_t sreg;
+
+    sreg = SREG;
+    cli();
+
     while (Endpoint_BytesInEndpoint()) {          // Discard data on buffer full
       rb_put(&TTY_Rx_Buffer, Endpoint_Read_Byte());
     }
-    Endpoint_ClearCurrentBank();
+    Endpoint_ClearCurrentBank();
+
+    SREG = sreg;
+
     inCDC_TASK = 1;
+
     output_flush_func = CDC_Task;
     input_handle_func(DISPLAY_USB);
+
     inCDC_TASK = 0;
   }
 
@@ -86,13 +96,20 @@
   Endpoint_SelectEndpoint(CDC_TX_EPNUM);          // Then data out
   if(TTY_Tx_Buffer.nbytes && Endpoint_ReadWriteAllowed()) {
 
+    uint8_t sreg;
+
+    sreg = SREG;
     cli();
     while(TTY_Tx_Buffer.nbytes &&
           (Endpoint_BytesInEndpoint() < USB_BUFSIZE))
       Endpoint_Write_Byte(rb_get(&TTY_Tx_Buffer));
-    sei();
+//    SREG = sreg;
+    //sei();
     
+//    sreg = SREG;
+//    cli();
     Endpoint_ClearCurrentBank();                  // Send the data
+    SREG = sreg;
 
   }
 }
--- clib/cdcLUFA.c Sat Apr 17 12:31:34 2010
+++ clib/cdcLUFA.c Mon Jun 09 16:55:21 2014
@@ -71,7 +71,7 @@
 void
 CDC_Task(void)
 {
-  static char inCDC_TASK = 0;
+  static uint8_t inCDC_TASK = 0;
 
   if(!USB_IsConnected)
     return;
@@ -79,14 +79,24 @@
   Endpoint_SelectEndpoint(CDC_RX_EPNUM);          // First data in
   if(!inCDC_TASK && Endpoint_IsReadWriteAllowed()){ // USB -> RingBuffer
 
+    uint8_t sreg;
+
+    sreg = SREG; // make it safer for call in an interrupt
+    cli(); // inhibit interrupts, to avoid reading an empty byte due to empty USB Buffer, emptied in interrupt
+
     while (Endpoint_BytesInEndpoint()) {          // Discard data on buffer full
       rb_put(&TTY_Rx_Buffer, Endpoint_Read_Byte());
     }
-    Endpoint_ClearOUT();
+
+    Endpoint_ClearOUT(); //better not to be disturbed here by interrupt doing the same
+
+    SREG = sreg;       // allow interrupts
 
     inCDC_TASK = 1;
+
     output_flush_func = CDC_Task;
     input_handle_func(DISPLAY_USB);
+
     inCDC_TASK = 0;
   }
 
@@ -94,17 +104,28 @@
   Endpoint_SelectEndpoint(CDC_TX_EPNUM);          // Then data out
   if(TTY_Tx_Buffer.nbytes && Endpoint_IsReadWriteAllowed()) {
 
-    cli();
+    uint8_t sreg;
+
+    sreg = SREG; // make it safer for call in an interrupt
+    cli(); // inhibit interrupts
     while(TTY_Tx_Buffer.nbytes &&
           (Endpoint_BytesInEndpoint() < USB_BUFSIZE))
       Endpoint_Write_Byte(rb_get(&TTY_Tx_Buffer));
-    sei();
+    SREG = sreg; // allow interrupts
     
-    bool IsFull = (Endpoint_BytesInEndpoint() == USB_BUFSIZE);
-    Endpoint_ClearIN();                  // Send the data
+    uint8_t IsFull = (Endpoint_BytesInEndpoint() == USB_BUFSIZE);
+
+    sreg = SREG; // make it safer for call in an interrupt
+    cli(); // inhibit interrupts
+    Endpoint_ClearIN(); // Send the data, better not to be disturbed here by interrupt doing the same
+    SREG = sreg; // allow interrupts
+
     if(IsFull) {
       Endpoint_WaitUntilReady();
-      Endpoint_ClearIN();
+      sreg = SREG; // make it safer for call in an interrupt
+      cli(); // inhibit interrupts
+      Endpoint_ClearIN(); // Send the data
+      SREG = sreg; // allow interrupts
     }
   }
 }
--- clib/clock.c Fri Feb 08 06:15:52 2013
+++ clib/clock.c Fri Jun 06 23:56:37 2014
@@ -3,6 +3,7 @@
 #include <avr/interrupt.h>
 
 #include "board.h"
+
 #include "led.h"
 #ifdef XLED
 #include "xled.h"
@@ -17,6 +18,7 @@
 #include "rf_send.h"                   // credit_10ms
 #include "mysleep.h"
 #include "pcf8833.h"
+#include "rf_asksin.h"
 #ifdef HAS_USB
 #include "cdc.h"
 #endif
@@ -35,8 +37,8 @@
 uint8_t ir_ticks_thrd = 0;
 #endif
 
-volatile uint32_t ticks;
-volatile uint8_t  clock_hsec;
+volatile uint32_t ticks = 0;
+volatile uint8_t  clock_hsec = 0;
 
 // count & compute in the interrupt, else long runnning tasks would block
 // a "minute" task too long
@@ -54,12 +56,30 @@
 #endif
 
 #if defined (HAS_IRTX) || defined (HAS_IRRX)
-     // if IRRX is compiled in, timer runs 125x faster ...
+     // if IRRX is compiled in, timer runs 125x faster ...
+     // 15625Hz
      if (++ir_ticks<125)
        return;
-       
+
      ir_ticks = 0;
-#endif
+
+     // 125Hz
+
+#if defined(HAS_MS_TIMER0) && !defined(HAS_MS_TIMER3)
+ // only 8ms increment for low additional CPU interrupt load
+ rf_asksin_ms += 8; // noansi: counter for ms, incremented by Timer 3 or Timer 0 with less granularity
+#endif //HAS_MS_TIMER0
+
+#else //HAS_IRTX || HAS_IRRX
+
+#if defined(HAS_MS_TIMER0) && !defined(HAS_MS_TIMER3)
+ // 250 Hz
+ // only 4ms increment for low additional CPU interrupt load
+ rf_asksin_ms += 4; // noansi: counter for ms, incremented by Timer 3 or Timer 0 with less granularity
+ if ((uint8_t)rf_asksin_ms & 0x04) return;
+#endif //HAS_MS_TIMER0
+
+#endif //HAS_IRTX || HAS_IRRX
 
      // 125Hz
      ticks++;
--- clib/display.c Sun Jun 30 23:01:20 2013
+++ clib/display.c Mon Jun 09 00:25:16 2014
@@ -109,6 +109,7 @@
     if((TTY_Tx_Buffer.nbytes  < TTY_BUFSIZE-2) ||
        (TTY_Tx_Buffer.nbytes  < TTY_BUFSIZE && (data == '\r' || data == '\n')))
     rb_put(&TTY_Tx_Buffer, data);
+ // what if buffer is full? better send and wait?
   }
 #endif
 
@@ -208,41 +209,101 @@
 }
 
 void
-display_udec(uint16_t d, int8_t pad, uint8_t padc)
+display_udec(uint16_t d, uint8_t pad, uint8_t padc)
 {
+  pad += 128;
+
   char buf[6];
-  int8_t i=6;
+  uint8_t i=5;
 
-  buf[--i] = 0;
+  buf[i] = 0;
   do {
-    buf[--i] = d%10 + '0';
+    buf[--i] = (d%10) + '0';
     d /= 10;
     pad--;
   } while(d && i);
 
-  while(--pad >= 0 && i > 0)
+  while(((--pad) >= 128) && (i > 0))
+    buf[--i] = padc;
+
+  DS(buf+i);
+}
+
+void
+display_hex(uint16_t h, uint8_t pad, uint8_t padc)
+{
+  pad += 128;
+
+  char buf[5];
+  int8_t i=4;
+
+  buf[i] = 0;
+  do {
+    uint8_t m = ((uint8_t)h & 0x0f);
+    buf[--i] = TO_HEX( m );
+    h >>= 4;
+    pad--;
+  } while(h);
+
+  while((i > 0) && ((--pad) >= 128))
     buf[--i] = padc;
+
   DS(buf+i);
 }
 
+/*
+void
+display_hex(uint16_t h, uint8_t pad, uint8_t padc)
+{
+  char buf[(2*sizeof(uint16_t))+1];
+  char *b = buf;
+
+  uint8_t p = sizeof(uint16_t);
+
+  while (p) {
+    *(b++) = TO_HEX( *((uint8_t *)&h + (--p)) >> 4 );
+    *(b++) = TO_HEX( *((uint8_t *)&h + p) & 0x0f );
+  }
+  *b = 0;
+
+  //if (!pad) pad++; // show zero at least
+  uint8_t padstart = (2*sizeof(uint16_t)) - pad;
+  p = 0;
+  b = buf;
+
+  while ((*b == '0') && *(b+1)) // show zero at least
+  {
+ *(b++) = padc;
+ if (p < padstart) p++;
+  }
+
+  DS(buf+p);
+}
+*/
+
+/*
 void
-display_hex(uint16_t h, int8_t pad, uint8_t padc)
+display_hex(uint16_t h, uint8_t pad, uint8_t padc)
 {
+  pad += 128;
+
   char buf[5];
-  int8_t i=5;
+  int8_t i=4;
 
-  buf[--i] = 0;
+  buf[i] = 0;
   do {
     uint8_t m = h%16;
-    buf[--i] = (m < 10 ? '0'+m : 'A'+m-10);
+    buf[--i] = (m < 10 ? '0'+m : ('A'-10)+m);
     h /= 16;
     pad--;
   } while(h);
 
-  while(--pad >= 0 && i > 0)
+  while(--pad >= 128 && i > 0)
     buf[--i] = padc;
+
   DS(buf+i);
 }
+*/
 
 void
 display_hex2(uint8_t h)
--- clib/display.h Mon Dec 10 13:21:50 2012
+++ clib/display.h Fri May 30 23:04:26 2014
@@ -8,8 +8,8 @@
 void display_char(char s);
 void display_string(char *s);
 void display_string_P(const char *s);
-void display_udec(uint16_t d, int8_t pad, uint8_t padc);
-void display_hex(uint16_t h, int8_t pad, uint8_t padc);
+void display_udec(uint16_t d, uint8_t pad, uint8_t padc);
+void display_hex(uint16_t h, uint8_t pad, uint8_t padc);
 void display_hex2(uint8_t h);
 void display_nl(void);
 
@@ -20,6 +20,7 @@
 #define DH(a,b) display_hex(a,b,'0')
 #define DH2(a) display_hex2(a)
 #define DNL display_nl
+#define TO_HEX(a) ((a)<10?(a)+'0':(a)+('A'-10))
 
 extern uint8_t display_channel;
 extern uint8_t log_enabled;
--- clib/fncollection.c Mon Sep 23 21:41:10 2013
+++ clib/fncollection.c Mon Jun 02 06:33:17 2014
@@ -276,24 +276,27 @@
   if(in)
     fromhex(in+1, &bl, 1);
 
-  if(bl)                     // Next reboot we'd like to jump to the bootloader.
-    ewb( EE_REQBL, 1 );      // Simply jumping to the bootloader from here
-                             // wont't work. Neither helps to shutdown USB
-                             // first.
+  if(bl) // Next reboot we'd like to jump to the bootloader.
+    ewb( EE_REQBL, 1 ); // Simply jumping to the bootloader from here
+ // wont't work. Neither helps to shutdown USB
+ // first.
                             
 #ifdef HAS_USB
-  USB_ShutDown();            // ??? Needed?
+  USB_ShutDown(); // ??? Needed?
 #endif
 #ifdef HAS_FS
-  fs_sync(&fs);              // Sync the filesystem
+  fs_sync(&fs); // Sync the filesystem
 #endif
 
+#ifdef HAS_MS_TIMER3
+  TIMSK3 = 0; // ??? Needed?
+#endif
 
-  TIMSK0 = 0;                // Disable the clock which resets the watchdog
+  TIMSK0 = 0; // Disable the clock which resets the watchdog
   cli();
   
-  wdt_enable(WDTO_15MS);       // Make sure the watchdog is running
-  while (1);                 // go to bed, the wathchdog will take us to reset
+  wdt_enable(WDTO_15MS); // Make sure the watchdog is running
+  while (1); // go to bed, the wathchdog will take us to reset
 }
 
 void
--- clib/intertechno.c Wed Feb 06 00:29:54 2013
+++ clib/intertechno.c Mon Jun 09 17:07:36 2014
@@ -172,6 +172,8 @@
  LED_ON();
 
     #if defined (HAS_IRRX) || defined (HAS_IRTX) //Blockout IR_Reception for the moment
+      uint8_t sreg;
+      sreg = SREG;
       cli();
     #endif
 
@@ -244,7 +246,8 @@
    }
 
     #if defined (HAS_IRRX) || defined (HAS_IRTX) //Activate IR_Reception again
-      sei();
+      //sei();
+      SREG = sreg;
     #endif  
 
  LED_OFF();
--- clib/rf_asksin.c Thu Mar 13 22:49:42 2014
+++ clib/rf_asksin.c Mon Jun 09 17:28:15 2014
@@ -1,15 +1,43 @@
+
 #include "board.h"
-#ifdef HAS_ASKSIN
+
+#include "rf_asksin.h"
+
+#if defined(HAS_MS_TIMER3) || defined(HAS_MS_TIMER0) || defined(HAS_ASKSIN_PLL_HELPER) || defined(HAS_ASKSIN)
+#include <avr/io.h>
+#endif //HAS_MS_TIMER3 || HAS_MS_TIMER0 || HAS_ASKSIN_PLL_HELPER || HAS_ASKSIN
+
+#if defined(HAS_MS_TIMER3) || defined(HAS_MS_TIMER0)
+//#include <avr/wdt.h>
+#endif //HAS_MS_TIMER3 || HAS_MS_TIMER0
+
+#if defined(HAS_MS_TIMER3) || defined(HAS_MS_TIMER0)
+#include <avr/interrupt.h>
+#endif //HAS_MS_TIMER3 || HAS_MS_TIMER0
+
+#if defined(HAS_ASKSIN_PLL_HELPER) || defined(HAS_ASKSIN)
 #include <string.h>
+#endif //HAS_ASKSIN_PLL_HELPER || HAS_ASKSIN
+
+#if defined(HAS_ASKSIN)
 #include <avr/pgmspace.h>
+#endif //HAS_ASKSIN
+
+#if defined(HAS_ASKSIN_PLL_HELPER) || defined(HAS_ASKSIN)
 #include "cc1100.h"
 #include "delay.h"
+#endif //HAS_ASKSIN_PLL_HELPER || HAS_ASKSIN
+
+#if defined(HAS_ASKSIN)
 #include "rf_receive.h"
+#endif //HAS_ASKSIN
+
+#if defined(HAS_MS_TIMER3) || defined(HAS_MS_TIMER0) || defined(HAS_ASKSIN_PLL_HELPER) || defined(HAS_ASKSIN)
 #include "display.h"
+#endif //HAS_MS_TIMER3 || HAS_MS_TIMER0 || HAS_ASKSIN_PLL_HELPER || HAS_ASKSIN
 
-#include "rf_asksin.h"
 
-uint8_t asksin_on = 0;
+#ifdef HAS_ASKSIN
 
 const uint8_t PROGMEM ASKSIN_CFG[] = {
      0x00, 0x07,
@@ -55,59 +83,242 @@
 };
 
 static unsigned char asksin_update_mode = 0;
-#endif
+#endif  //HAS_ASKSIN_FUP
 
-static void rf_asksin_reset_rx(void);
+uint8_t asksin_on = 0;
+
+#if defined(HAS_MS_TIMER3) || defined(HAS_MS_TIMER0)
+static uint8_t asksin_timestamp_mode = 0; //default no Timestamp
+#endif //HAS_MS_TIMER3 || HAS_MS_TIMER0
+
+#endif //HAS_ASKSIN
+
+
+#if defined(HAS_MS_TIMER3) || defined(HAS_MS_TIMER0)
+volatile uint32_t rf_asksin_ms = 0; // counter for ms, incremented by Timer 3 or Timer 0 with less granularity
+#endif //HAS_MS_TIMER3 || HAS_MS_TIMER0
+
+
+#ifdef HAS_ASKSIN_PLL_HELPER
+uint8_t asksin_disable_PLLNOLOCK = 0;
+#endif //HAS_ASKSIN_PLL_HELPER
+
+
+
+#if defined(HAS_MS_TIMER3)
+
+// just count ms in the interrupt Timer 3
+ISR(TIMER3_COMPA_vect, ISR_BLOCK)
+{
+ rf_asksin_ms++;
+}
+
+#endif //HAS_MS_TIMER3
+
+#if defined(HAS_MS_TIMER3) || defined(HAS_MS_TIMER0)
 
 void
-rf_asksin_init(void)
+rf_asksin_get_ms_timestamp(uint32_t *ts)
 {
+ uint8_t l = SREG;
+ cli();
+ *ts = rf_asksin_ms;
+ SREG = l;
+}
 
-  EIMSK &= ~_BV(CC1100_INT);                 // disable INT - we'll poll...
-  SET_BIT( CC1100_CS_DDR, CC1100_CS_PIN );   // CS as output
+void
+rf_asksin_display_ms(uint32_t *ts)
+{
+ char buf[(2*sizeof(uint32_t)+1)];
+ uint8_t i = 255;
 
-  CC1100_DEASSERT;                           // Toggle chip select signal
-  my_delay_us(30);
-  CC1100_ASSERT;
-  my_delay_us(30);
-  CC1100_DEASSERT;
-  my_delay_us(45);
+ uint8_t p = sizeof(uint32_t);
+ while(p) {
+ uint8_t m = (*((uint8_t *)ts+(--p)) >> 4);
+ buf[++i] = TO_HEX( m );
+ m = (*((uint8_t *)ts+p) & 0x0f);
+ buf[++i] = TO_HEX( m );
+ }
+ buf[++i] = 0;
+
+ DS(buf);
+}
+
+#endif //HAS_MS_TIMER3 || HAS_MS_TIMER0
+
+
+#ifdef HAS_ASKSIN_PLL_HELPER
+
+uint8_t
+rf_asksin_wait_state(uint8_t state, uint8_t poll_us)
+{
+ uint8_t l;
+
+ l = 255;
+ do
+ {
+ if (cc1100_readReg( CC1100_MARCSTATE ) == state) return 0; // ok, state reached
+ my_delay_us( poll_us );
+ }
+ while (l--);
+
+ return 1; // error, state not reached
+}
 
-  ccStrobe( CC1100_SRES );                   // Send SRES command
-  my_delay_us(100);
+uint8_t
+rf_asksin_checkPLL(void)  // noansi: returns 0 on success
+{
+ uint8_t l;
+
+ // noansi: check PLL Lock and try to calibrate. Possibly restoring a saved calibration could be faster...
+ l = cc1100_readReg( CC1100_FSCAL1 );
+ if (l != 0x3f) return 0; // noansi: PLL in Lock as described in CC1101 doc and errata
+
+ // noansi: try to recover as no PLL Lock as described in CC1101 doc and errata
+ ccStrobe( CC1100_SIDLE );
+
+ if (!asksin_disable_PLLNOLOCK) DS_P( PSTR( "PLLNOLOCK\r\n" ) );
+
+ // noansi: wait idle state, is it needed here?
+ rf_asksin_wait_state(MARCSTATE_IDLE, 1); // give a litle bit time, normal RX to IDLE should take about 0.1us with ASK, TX to idle about 1us with ASK
+
+ ccStrobe( CC1100_SCAL ); // noansi: Try Calibration
+
+ //my_delay_ms(1); // noansi: maybe waiting gives a better calibration instead of polling the state (noise?)
+
+ // noansi: wait idle state -> calibration finished, if no idle in between is reported here as it may be possible with the state returned by command strobe
+ rf_asksin_wait_state(MARCSTATE_IDLE, 4);
+
+ l = cc1100_readReg( CC1100_FSCAL1 );
+ if (l != 0x3f) return 0; // noansi: PLL in Lock as described in CC1101 doc and errata
+
+ if (!asksin_disable_PLLNOLOCK) DS_P( PSTR( "PLLLOCKFAIL\r\n" ) );
+
+ return 1; // noansi: error, no PLL Lock
+}
+
+#ifdef HAS_ASKSIN_PLL_HELPER_RX
+uint8_t
+rf_asksin_toRX(void)
+{
+ uint8_t n;
 
-  // load configuration
-  for (uint8_t i = 0; i < sizeof(ASKSIN_CFG); i += 2) {
-    cc1100_writeReg( pgm_read_byte(&ASKSIN_CFG[i]),
-                     pgm_read_byte(&ASKSIN_CFG[i+1]) );
+ // noansi: set RX with check/try PLL is in Lock in RX
+ n = 2; // noansi: Try to set RX several times before giving up
+ do {
+ // enable RX
+ while ((ccStrobe( CC1100_SRX ) & CC1100_STATUS_STATE_BM) != 0x10); // noansi: Set RX until Status Byte indicates RX
+
+ if (!rf_asksin_checkPLL()) return 0; // everything ok
+
+ } while (--n);
+
+ //if (!asksin_disable_PLLNOLOCK) DS_P( PSTR( "NoRXErr\r\n" ) );
+
+ return 1;
+}
+#endif //HAS_ASKSIN_PLL_HELPER_RX
+
+#ifdef HAS_ASKSIN_PLL_HELPER_TX
+uint8_t
+rf_asksin_toTX(void)
+{
+ uint8_t n;
+
+ // noansi: set TX with check/try PLL is in Lock in TX
+ n = 2; // noansi: Try to set TX several times before giving up
+ do {
+ // enable TX, wait for CCA
+ while ((ccStrobe( CC1100_STX ) & CC1100_STATUS_STATE_BM) != 0x20); // noansi: Set TX until Status Byte indicates TX
+
+ if (!rf_asksin_checkPLL()) return 0; // everything ok
+
+ } while (--n);
+
+ //if (!asksin_disable_PLLNOLOCK) DS_P( PSTR( "NoTXErr\r\n" ) );
+
+ return 1;
+}
+#endif //HAS_ASKSIN_PLL_HELPER_TX
+
+// check if stuck in RX state without PLL Lock
+void
+rf_asksin_check_PLL_task(void)
+{
+  if (cc1100_readReg( CC1100_MARCSTATE ) == MARCSTATE_RX)
+  {
+ // noansi: try init or recalibration, if stuck in RX State with no PLL Lock as seen in extended read timeout logging
+ if (cc1100_readReg( CC1100_FSCAL1 ) == 0x3f) { // noansi: no PLL Lock as described in CC1101 errata
+ //rf_asksin_init(); // noansi: try init to recover
+ rf_asksin_checkPLL(); // noansi: try calibration to recover
+ //ccStrobe( CC1100_SRX ); // other tasks will give the wait time to fully switch to RX in background
+    while ((ccStrobe( CC1100_SRX ) & CC1100_STATUS_STATE_BM) != 0x10); // noansi: Set RX until Status Byte indicates RX
+ }
   }
+}
+
+#endif //HAS_ASKSIN_PLL_HELPER
+
+
+
+#ifdef HAS_ASKSIN
+
+static void rf_asksin_reset_rx(void);
+
+
+void
+rf_asksin_init(void)
+{
+ EIMSK &= ~_BV(CC1100_INT);                 // disable INT - we'll poll...
+ SET_BIT( CC1100_CS_DDR, CC1100_CS_PIN );   // CS as output
+
+ CC1100_DEASSERT;                           // Toggle chip select signal
+ my_delay_us(30);
+ CC1100_ASSERT;
+ my_delay_us(30);
+ CC1100_DEASSERT;
+ my_delay_us(45);
+
+ ccStrobe( CC1100_SRES );                   // Send SRES command
+ my_delay_us(100);
+
+ // load configuration
+ for (uint8_t i = 0; i < sizeof(ASKSIN_CFG); i += 2) {
+ cc1100_writeReg( pgm_read_byte(&ASKSIN_CFG[i]),
+ pgm_read_byte(&ASKSIN_CFG[i+1]) );
+ }
 
 #ifdef HAS_ASKSIN_FUP
-  if (asksin_update_mode) {
-    for (uint8_t i = 0; i < sizeof(ASKSIN_UPDATE_CFG); i += 2) {
-      cc1100_writeReg( pgm_read_byte(&ASKSIN_UPDATE_CFG[i]),
-                       pgm_read_byte(&ASKSIN_UPDATE_CFG[i+1]) );
-    }
-  }
-#endif

-  ccStrobe( CC1100_SCAL );
+ if (asksin_update_mode) {
+ for (uint8_t i = 0; i < sizeof(ASKSIN_UPDATE_CFG); i += 2) {
+ cc1100_writeReg( pgm_read_byte(&ASKSIN_UPDATE_CFG[i]),
+ pgm_read_byte(&ASKSIN_UPDATE_CFG[i+1]) );
+ }
+ }
+#endif  //HAS_ASKSIN_FUP
 
-  my_delay_ms(4);
+ ccStrobe( CC1100_SCAL );  // force a calibration
 
-  // enable RX, but don't enable the interrupt
-  do {
-    ccStrobe(CC1100_SRX);
-  } while (cc1100_readReg(CC1100_MARCSTATE) != MARCSTATE_RX);
+ //my_delay_ms(4); // noansi: maybe waiting gives a better calibration instead of polling the state (noise?)
+
+
+ rf_asksin_wait_state(MARCSTATE_IDLE, 15);  // noansi: wait idle state -> calibration finished -> may be
+
+ rf_asksin_checkPLL();  // noansi: check PLL Lock
+
+ // enable RX, but don't enable the interrupt
+ rf_asksin_toRX();  // noansi: and check PLL is in Lock in RX
 }
 
+
 static void
 rf_asksin_reset_rx(void)
 {
-  ccStrobe( CC1100_SFRX  );
-  ccStrobe( CC1100_SIDLE );
-  ccStrobe( CC1100_SNOP  );
-  ccStrobe( CC1100_SRX   );
+ ccStrobe( CC1100_SIDLE ); // noansi: if stuck in RX after RX OVERFLOW as described in CC1101 errata -> do SFRX only in IDLE as CC1101 doc
+ ccStrobe( CC1100_SNOP ); // give a litle bit time, normal RX to IDLE should take about 0.1us with ASK, TX to idle about 1us with ASK
+ ccStrobe( CC1100_SFRX  ); // flush RX-FIFO
+ rf_asksin_toRX(); // noansi: try to set RX with calibration
+ //DS_P( PSTR( "asksin_reset\r\n" ) );
 }
 
 void
@@ -143,9 +354,17 @@
 
     CC1100_DEASSERT;
 
-    do {
-      ccStrobe(CC1100_SRX);
-    } while (cc1100_readReg(CC1100_MARCSTATE) != MARCSTATE_RX);
+    // switch to RX again
+    //rf_asksin_toRX();  // takes just a little bit longer, if still in PLL lock
+    while ((ccStrobe( CC1100_SRX ) & CC1100_STATUS_STATE_BM) != 0x10); // noansi: Set RX until Status Byte indicates RX
+
+#if defined(HAS_MS_TIMER3) || defined(HAS_MS_TIMER0)
+
+    // get timestamp from ms timer
+    uint32_t ts;
+    rf_asksin_get_ms_timestamp(&ts);
+
+#endif //HAS_MS_TIMER3 || HAS_MS_TIMER0
 
     last_enc = msg[1];
     msg[1] = (~msg[1]) ^ 0x89;
@@ -160,32 +379,90 @@
     
     if (tx_report & REP_BINTIME) {
       
-      DC('a');
+      DC( 'a' );
       for (uint8_t i=0; i<=msg[0]; i++)
       DC( msg[i] );
         
     } else {
-      DC('A');
-     
+
+      DC( 'A' ); //Asksin Format ID
+
+#if defined(HAS_MS_TIMER3) || defined(HAS_MS_TIMER0)
+
+ if (asksin_timestamp_mode)
+ {
+ DH( 0xff01, 4 );  // TimeStamp Format ID FF01
+ rf_asksin_display_ms(&ts);
+ }
+
+#endif //HAS_MS_TIMER3 || HAS_MS_TIMER0
+
       for (uint8_t i=0; i<=msg[0]; i++)
         DH2( msg[i] );
       
       if (tx_report & REP_RSSI)
-        DH2(rssi);
-     
-      DNL();
+        DH2( rssi );
+
+      DNL( );
     }
   }
 
+  l = cc1100_readReg( CC1100_MARCSTATE );
+/*
+  if (l == MARCSTATE_RX)
+  {
+ // noansi: try init or recalibration, if stuck in RX State with no PLL Lock as seen in extended read timeout logging
+ l = cc1100_readReg( CC1100_FSCAL1 );
+ if (l == 0x3f) { // noansi: no PLL Lock as described in CC1101 errata
+ //rf_asksin_init(); // noansi: try init to recover
+ rf_asksin_checkPLL(); // noansi: try calibration to recover
+ ccStrobe( CC1100_SRX ); // other tasks will give the wait time to fully switch to RX in background
+ return;
+ }
+  }
+  else if (l == MARCSTATE_RXFIFO_OVERFLOW)
+*/
+  if (l == MARCSTATE_RXFIFO_OVERFLOW)
+  {
+ ccStrobe( CC1100_SIDLE ); // noansi: if stuck in RX after RX OVERFLOW as described in CC1101 errata -> do SFRX only in IDLE as CC1101 doc
+ ccStrobe( CC1100_SNOP  ); // give a litle bit time, normal RX to IDLE should take about 0.1us with ASK
+ ccStrobe( CC1100_SFRX  ); // flush the RX-FIFO
+ ccStrobe( CC1100_SRX   ); // other tasks will give the wait time to fully switch to RX in background
+  }
+  else
+  {
+ if (l != MARCSTATE_RX)
+ {
+ // we allways try to be on RX
+ //rf_asksin_toRX(); // noansi: try to set RX with calibration, would wait for state
+ ccStrobe( CC1100_SRX ); // other tasks will give the wait time to fully switch to RX in background
+ }
+  }
+
+/*
   switch(cc1100_readReg( CC1100_MARCSTATE )) {
+    case MARCSTATE_RX:
+ // noansi: try init or recalibration, if stuck in RX State with no PLL Lock as seen in extended read timeout logging
+ l = cc1100_readReg( CC1100_FSCAL1 );
+ if (l == 0x3f) { // noansi: no PLL Lock as described in CC1101 errata
+ //rf_asksin_init(); // noansi: try init to recover
+ rf_asksin_checkPLL(); // noansi: try calibration to recover
+ ccStrobe( CC1100_SRX ); // other tasks will give the wait time to fully switch to RX in background
+ return;
+ }
+ break;
     case MARCSTATE_RXFIFO_OVERFLOW:
-      ccStrobe( CC1100_SFRX  );
-    case MARCSTATE_IDLE:
-      ccStrobe( CC1100_SIDLE );
-      ccStrobe( CC1100_SNOP  );
-      ccStrobe( CC1100_SRX   );
-      break;
+ ccStrobe( CC1100_SIDLE ); // noansi: if stuck in RX after RX OVERFLOW as described in CC1101 errata -> do SFRX only in IDLE as CC1101 doc
+ ccStrobe( CC1100_SNOP  ); // give a litle bit time, normal RX to IDLE should take about 0.1us with ASK
+ ccStrobe( CC1100_SFRX  );
+    //case MARCSTATE_IDLE:
+    default:
+ // we allways try to be on RX
+ //rf_asksin_toRX(); // noansi: try to set RX with calibration, would wait for state
+ ccStrobe( CC1100_SRX ); // other tasks will give the wait time to fully switch to RX in background
+ break;
   }
+*/
 }
 
 void
@@ -195,17 +472,18 @@
   uint8_t ctl;
   uint8_t l;
 
-  uint8_t hblen = fromhex(in+1, msg, MAX_ASKSIN_MSG-1);
+  uint8_t hblen = fromhex(in, msg, MAX_ASKSIN_MSG-1);
 
   if ((hblen-1) != msg[0]) {
-//  DS_P(PSTR("LENERR\r\n"));
+//  DS_P( PSTR( "LENERR\r\n" ) );
     return;
   }
 
   // in AskSin mode already?
   if(!asksin_on) {
     rf_asksin_init();
-    my_delay_ms(3);             // 3ms: Found by trial and error
+    //my_delay_ms(3); // 3ms: Found by trial and error. noansi: We are in RX after init, why wait?
+    my_delay_ms(6); // noansi: removed wait 4ms in init during calib (735us so about 1ms), so 1(calib)+3+3ms should do the same
   }
 
   ctl = msg[2];
@@ -218,10 +496,9 @@
   
   msg[l] = msg[l] ^ ctl;
 
-  // enable TX, wait for CCA
-  do {
-    ccStrobe(CC1100_STX);
-  } while (cc1100_readReg(CC1100_MARCSTATE) != MARCSTATE_TX);
+  // noansi: set TX
+  //rf_asksin_toTX();  // takes just a little bit longer, if still in PLL lock
+  while ((ccStrobe( CC1100_STX ) & CC1100_STATUS_STATE_BM) != 0x20); // noansi: Set TX until Status Byte indicates TX
 
   if (ctl & (1 << 4)) { // BURST-bit set?
     // According to ELV, devices get activated every 300ms, so send burst for 360ms
@@ -233,7 +510,7 @@
 
   // send
   CC1100_ASSERT;
-  cc1100_sendbyte(CC1100_WRITE_BURST | CC1100_TXFIFO);
+  cc1100_sendbyte( CC1100_WRITE_BURST | CC1100_TXFIFO );
 
   for(uint8_t i = 0; i < hblen; i++) {
     cc1100_sendbyte(msg[i]);
@@ -242,47 +519,106 @@
   CC1100_DEASSERT;
 
   // wait for TX to finish
-  while(cc1100_readReg( CC1100_MARCSTATE ) == MARCSTATE_TX)
-    ;
+  while (((l = ccStrobe( CC1100_SNOP )) & CC1100_STATUS_STATE_BM) == 0x20); // Status Byte indicates still TX ?
 
-  if (cc1100_readReg( CC1100_MARCSTATE ) == MARCSTATE_TXFIFO_UNDERFLOW) {
-      ccStrobe( CC1100_SFTX  );
-      ccStrobe( CC1100_SIDLE );
-      ccStrobe( CC1100_SNOP  );
-  }
+  // MARCSTATE_TXFIFO_UNDERFLOW ?
+  if (l == 0x70) { // Status Byte indicates TXFIFO_UNDERFLOW
+    ccStrobe( CC1100_SFTX  ); // flush the TX-FIFO
+    // ccStrobe( CC1100_SIDLE ); // why force idle? SFTX should end in idle with respect to cc1101 documentation
+    ccStrobe( CC1100_SNOP  ); // but give a litle bit time, normal TX to IDLE should take about 1us with ASK
+ }
   
   if(asksin_on) {
-    do {
-      ccStrobe(CC1100_SRX);
-    } while (cc1100_readReg(CC1100_MARCSTATE) != MARCSTATE_RX);
+    // noansi: set RX
+    //rf_asksin_toRX();  // takes just a little bit longer, if still in PLL lock
+    while ((ccStrobe( CC1100_SRX ) & CC1100_STATUS_STATE_BM) != 0x10); // noansi: Set RX until Status Byte indicates RX
   } else {
     set_txrestore();
   }
 }
 
+
 void
 asksin_func(char *in)
 {
-#ifndef HAS_ASKSIN_FUP
-  if(in[1] == 'r') {                // Reception on
-#else
-  if((in[1] == 'r') || (in[1] == 'R')) {                // Reception on
-    if (in[1] == 'R') {
-      asksin_update_mode = 1;
-    } else {
-      asksin_update_mode = 0;
-    }
-#endif
-    rf_asksin_init();
-    asksin_on = 1;
+ uint8_t asksin_command = in[1];
 
-  } else if(in[1] == 's') {         // Send
-    asksin_send(in+1);
+ if (asksin_command == 's') { // Send
+ asksin_send(in+2);
+ }
 
-  } else {                          // Off
-    asksin_on = 0;
+#ifndef HAS_ASKSIN_FUP
+  else if (asksin_command == 'r') { // Reception on
+#else  //HAS_ASKSIN_FUP
+  else if ((asksin_command == 'r') || (asksin_command == 'R')) { // Reception on
+ asksin_update_mode = asksin_command - 'r'; //'r'=off, 'R'=on for asksin_update_mode
+#endif  //HAS_ASKSIN_FUP
+ rf_asksin_init();
+ asksin_on = 1;
+
+ }
+
+#if defined(HAS_MS_TIMER3) || defined(HAS_MS_TIMER0)
+ else if (asksin_command == 'p') { // ping Timestamp echo + PingNo 32bit
+ // we do nothing (except a little error hint), if we don't have TimeStamp, so no urgend need for Hardware Detection
+ if (asksin_timestamp_mode)
+ {
+ // get timestamp from ms timer
+ uint32_t ts;
+ rf_asksin_get_ms_timestamp(&ts);
+
+ // send timestamp Answer
+ DC( 'A' ); // Asksin message ID; 1 characters
+ DH( 0xff02, 4 ); // TimeStamp Format ID FF02 for ping answer; 4 characters
+ rf_asksin_display_ms(&ts); // TimeStamp; 8 characters
+ DH2( strlen(in+2)>>1 ); // lenght of input hex bytes to send back; 2 characters
+ DS( in+2 ); // Message contains e.g. received ping number; 8 characters at least for 00_CUL
+ DH2( 128 ); // rssi = -138; 2 characters
+ DNL( );
+ }
+ #ifndef HAS_ASKSIN_NO_COMMAND_ERROR_HINT
+ else goto unknown_ASKSIN; // little error hint, as TimeStamp mode not enabled
+ #endif //HAS_ASKSIN_NO_COMMAND_ERROR_HINT
+  }
+#endif //HAS_MS_TIMER3 || HAS_MS_TIMER0
+
+#if defined(HAS_MS_TIMER3) || defined(HAS_MS_TIMER0)
+  else if (asksin_command == 't') {          // Timestamp, t1=on, t0=off
+ // we do nothing (except a little error hint), if we don't have TimeStamp, so no urgend need for Hardware Detection
+ asksin_timestamp_mode = in[2] - '0'; // 0=deactivate timestamp from ms timer, else on
+
+ }
+#endif //HAS_MS_TIMER3 || HAS_MS_TIMER0
+
+#ifdef HAS_ASKSIN_PLL_HELPER
+  else if (asksin_command == 'P') {
+ asksin_disable_PLLNOLOCK = in[2] - '0'; //switch on/off PLLNOLOCK message, '0'=switch on, default on
+
+ }
+#endif //HAS_ASKSIN_PLL_HELPER
+
+  else if (asksin_command == 'x') { // only x should disable AskSin mode, see doc
+ asksin_on = 0; // AskSin Reception off
+
+ }
+
+// else {
+// asksin_on = 0; // AskSin Reception off, if unknown command
+// }
+
+#ifndef HAS_ASKSIN_NO_COMMAND_ERROR_HINT
+ else goto unknown_ASKSIN;
+#endif //HAS_ASKSIN_NO_COMMAND_ERROR_HINT
+
+ return;
+
+
+#ifndef HAS_ASKSIN_NO_COMMAND_ERROR_HINT
+unknown_ASKSIN:
+ DS_P( PSTR( "A?\r\n" ) ); // little error hint
 
-  }
+ return;
+#endif //HAS_ASKSIN_NO_COMMAND_ERROR_HINT
 }
 
-#endif
+#endif //HAS_ASKSIN
--- clib/rf_asksin.h Thu Mar 13 22:49:42 2014
+++ clib/rf_asksin.h Sun Jun 08 17:00:01 2014
@@ -1,6 +1,24 @@
 #ifndef _RF_ASKSIN_H
 #define _RF_ASKSIN_H
 
+#include <avr/io.h>
+
+
+#if defined(HAS_MS_TIMER3) || defined(HAS_MS_TIMER0)
+
+extern volatile uint32_t rf_asksin_ms; // noansi: counter for ms, incremented by Timer 3 or Timer 0 with less granularity
+
+extern void rf_asksin_get_ms_timestamp(uint32_t *ts); // noansi: get ms counter interrupt save
+extern void rf_asksin_display_ms(uint32_t *ts); // noansi: display as 8 digit Hex Value
+
+#endif
+
+
+#ifdef HAS_ASKSIN
+
+#define HAS_ASKSIN_PLL_HELPER
+#define HAS_ASKSIN_PLL_HELPER_RX
+
 #ifndef HAS_ASKSIN_FUP
 #define MAX_ASKSIN_MSG 30
 #else
@@ -9,8 +27,36 @@
 
 extern uint8_t asksin_on;
 
-void rf_asksin_init(void);
-void rf_asksin_task(void);
-void asksin_func(char *in);
+extern void rf_asksin_init(void);
+extern void rf_asksin_task(void);
+extern void asksin_func(char *in);
+
+#endif
+
+
+#if defined(HAS_ASKSIN_PLL_HELPER_TX) || defined(HAS_ASKSIN_PLL_HELPER_RX)
+#define HAS_ASKSIN_PLL_HELPER
+#endif
+
+
+#ifdef HAS_ASKSIN_PLL_HELPER
+
+extern uint8_t asksin_disable_PLLNOLOCK; // noansi: do not display PLLNOLOCK related errors if > 0
+
+extern uint8_t rf_asksin_wait_state(uint8_t state, uint8_t poll_us); // noansi: wait for a MARCSTATE to be reached for 256*poll_us, returns 0 on success
+extern uint8_t rf_asksin_checkPLL(void); // noansi: check CC1101 PLL lock with recalibration if necessary, returns 0 on success
+
+#ifdef HAS_ASKSIN_PLL_HELPER_RX
+extern uint8_t rf_asksin_toRX(void); // noansi: set CC1101 to RX with recalibration if necessary, returns 0 on success
+#endif
+
+#ifdef HAS_ASKSIN_PLL_HELPER_TX
+extern uint8_t rf_asksin_toTX(void); // noansi: set CC1101 to TX with recalibration if necessary, returns 0 on success
+#endif
+
+extern void rf_asksin_check_PLL_task(void); // noansi: check for PLL Lock and try recalibration, if not
+
+#endif
+
 
 #endif
--- clib/rf_send.c Sat Mar 29 07:17:22 2014
+++ clib/rf_send.c Mon Jun 09 17:11:46 2014
@@ -102,7 +102,9 @@
   LED_ON();
 
   #if defined (HAS_IRRX) || defined (HAS_IRTX) //Blockout IR_Reception for the moment
-    cli();
+  uint8_t sreg;
+  sreg = SREG;
+  cli();
   #endif
 
 #ifdef HAS_MORITZ
@@ -141,7 +143,8 @@
   }
 
   #if defined (HAS_IRRX) || defined (HAS_IRTX) //Activate IR_Reception again
-    sei();
+  //sei();
+  SREG = sreg;
   #endif
 
 #ifdef HAS_MORITZ
--- clib/ringbuffer.c Wed Mar 05 10:03:10 2014
+++ clib/ringbuffer.c Mon Jun 09 02:05:04 2014
@@ -23,28 +23,28 @@
     SREG = sreg;
     return;
   }
-  rb->nbytes++;
   rb->buf[rb->putoff++] = data;
   if(rb->putoff == TTY_BUFSIZE)
     rb->putoff = 0;
+  rb->nbytes++;
   SREG = sreg;
 }
 
 uint8_t
 rb_get(rb_t *rb)
 {
-  uint8_t sreg;
   uint8_t ret;
+  uint8_t sreg;
   sreg = SREG;
   cli();
   if(rb->nbytes == 0) {
     SREG = sreg;
     return 0;
   }
-  rb->nbytes--;
   ret = rb->buf[rb->getoff++];
   if(rb->getoff == TTY_BUFSIZE)
     rb->getoff = 0;
+  rb->nbytes--;
   SREG = sreg;
   return ret;
 }
--- CHANGED Tue Jun 03 17:07:38 2014
+++ CHANGED Mon Jun 09 17:23:56 2014
@@ -1,5 +1,25 @@
-- rpiaddon: initial version for Raspberry PI addon board by Damian Nelson
-
+Version 1.62 (2014-06-08)
+- stability improvements in CDC_Task (reentrance due to interrupt). by noansi
+- unknown or currently unusable AskSin command (Axx) gives little Error Feedback A?\r\n . by noansi
+- disable AskSin with Ax only, as written in doc. by noansi
+Version 1.61 (2014-06-08)
+- check of PLL lock problem generaly implemented as task (so usable for all RF modes with RX), can be configured as board option. by noansi
+- TimeStamp ms counter as configurable board option implemented, so usable with other code, too. by noansi
+- usage of Timer0 only for ms TimeStamp option, runs more stable than Timer3 (?), but only 4ms (8ms IR) increment, restored buffsizes to old value. by noansi
+Version 1.60 (2014-06-07)
+- Version number 1.60 and above needed for 00_CUL.pm to support AskSin TimeStamp mode. by noansi
+- COC: makefile changed, name COC.radio_only -> COC_radio_only. by noansi
+- COC: AskSin support of ms TimeStamp mode. 1ms increment (Timer 3). by noansi
+- CUL: AskSin support of ms TimeStamp mode. CUL_V2_HM 4ms increment (Timer 0), CUL_V4 4ms increment (Timer 0). by noansi
+- CUL: AskSin support of ms TimeStamp mode. CUL_V3 1ms increment (Timer 3). by noansi
+- all: board option HAS_ASKSIN_PLL_HELPER, HAS_ASKSIN_PLL_HELPER_TX for RX TX switching routines with PLL lock check for usage in other modules. by noansi
+- all: board option HAS_MS_TIMER0, HAS_MS_TIMER3 for ms TimeStamp support in AskSin. May be used separately in other modules, too. HAS_MS_TIMER3 with 1ms increment. HAS_MS_TIMER0 with 4ms increment without HAS_IRTX or HAS_IRRX, 8ms increment with. by noansi
+- clock.c: ms TimeStamp in Timer 0 interrupt routine. by noansi
+- AskSin: Timer 3 interrupt routine for 1ms TimeStamp support. by noansi
+- AskSin: ms TimeStamp mode support. Activate with At1 (messages AFF01ttttttttllmm*rr), deactivate with At0. Ping with Apaa* (answer AFF02ttttttttllaa*rr with rr=-138), only usable if TimeStamp mode is enabled. by noansi
+- AskSin: changes in to RX and to TX switching. by noansi
+- AskSin: robustness of AskSin-mode against missing PLL lock with recalibration. Display of respective error message. Disable messages with AP1, reenable with AP0. by noansi
+- display.c: definition and routines for HEX conversion changed. Saves some bytes in program memory. by noansi
 - SCC: inital addition of new RPi extension
 - UNIROLL send routines (currently CUL only) by C_Herrmann
 
--- version.h Fri Mar 14 19:57:58 2014
+++ version.h Mon Jun 09 16:08:00 2014
@@ -1,3 +1,3 @@
 #define VERSION_1               1
-#define VERSION_2               58
-#define VERSION                 "1.58"
+#define VERSION_2               62
+#define VERSION                 "1.62"

--- Ende Code ---

Gruß und Danke,

Ansgar.

noansi:
und der zweite Teil:


--- Code: ------ Devices/AirLinked/board.h.CSM Fri Feb 01 11:07:16 2013
+++ Devices/AirLinked/board.h.CSM Sun Jun 08 19:57:59 2014
@@ -60,10 +60,14 @@
 #define HAS_FASTRF                    // PROGMEM:  468b  RAM:  1b
 #define HAS_RF_ROUTER
 #define HAS_ASKSIN
+//#define HAS_MS_TIMER3 // RAM: +5b noansi: Timer3 for ms timestamp counter in asksin.c
+#define HAS_MS_TIMER0 // RAM: +5b noansi: Timer0 for ms timestamp counter in asksin.c, 4ms (IR 8ms) increment
+#define HAS_ASKSIN_PLL_HELPER // RAM: +1b noansi: check for PLL Lock and try recalibration, if not
 #define HAS_ESA
 #define HAS_INTERTECHNO
 
 #define BOARD_ID_STR            "CSM868"
+//#define CUL_HW_REVISION "CSM"
 
 #define TTY_BUFSIZE             132
 
--- Devices/AirLinked/board.h.HM-LC-Sw1-PI Fri Feb 01 11:07:16 2013
+++ Devices/AirLinked/board.h.HM-LC-Sw1-PI Sun Jun 08 19:58:07 2014
@@ -73,10 +73,14 @@
 #define HAS_FASTRF                    // PROGMEM:  468b  RAM:  1b
 #define HAS_RF_ROUTER
 #define HAS_ASKSIN
+//#define HAS_MS_TIMER3 // RAM: +5b noansi: Timer3 for ms timestamp counter in asksin.c
+#define HAS_MS_TIMER0 // RAM: +5b noansi: Timer0 for ms timestamp counter in asksin.c, 4ms (IR 8ms) increment
+#define HAS_ASKSIN_PLL_HELPER // RAM: +1b noansi: check for PLL Lock and try recalibration, if not
 #define HAS_ESA
 #define HAS_INTERTECHNO
 
 #define BOARD_ID_STR            "CSM868"
+//#define CUL_HW_REVISION "HM-LC-Sw1-PI"
 
 #define TTY_BUFSIZE             132
 
--- Devices/AirLinked/board.h.RWE_PSS Fri Feb 01 11:07:16 2013
+++ Devices/AirLinked/board.h.RWE_PSS Sun Jun 08 19:57:11 2014
@@ -55,10 +55,14 @@
 #define HAS_FASTRF                    // PROGMEM:  468b  RAM:  1b
 #define HAS_RF_ROUTER
 #define HAS_ASKSIN
+//#define HAS_MS_TIMER3 // RAM: +5b noansi: Timer3 for ms timestamp counter in asksin.c
+#define HAS_MS_TIMER0 // RAM: +5b noansi: Timer0 for ms timestamp counter in asksin.c, 4ms (IR 8ms) increment
+#define HAS_ASKSIN_PLL_HELPER // RAM: +1b noansi: check for PLL Lock and try recalibration, if not
 #define HAS_ESA
 #define HAS_INTERTECHNO
 
 #define BOARD_ID_STR            "CSM868"
+//#define CUL_HW_REVISION "RWE_PSS"
 
 #define TTY_BUFSIZE             132
 
--- Devices/AirLinked/board.h.zCSM Mon Jul 01 12:05:26 2013
+++ Devices/AirLinked/board.h.zCSM Sun Jun 08 19:56:30 2014
@@ -66,10 +66,14 @@
 #define HAS_FASTRF                    // PROGMEM:  468b  RAM:  1b
 #define HAS_RF_ROUTER
 #define HAS_ASKSIN
+//#define HAS_MS_TIMER3 // RAM: +5b noansi: Timer3 for ms timestamp counter in asksin.c
+#define HAS_MS_TIMER0 // RAM: +5b noansi: Timer0 for ms timestamp counter in asksin.c, 4ms (IR 8ms) increment
+#define HAS_ASKSIN_PLL_HELPER // RAM: +1b noansi: check for PLL Lock and try recalibration, if not
 #define HAS_ESA
 #define HAS_INTERTECHNO
 
 #define BOARD_ID_STR            "CSM868"
+//#define CUL_HW_REVISION "zCSM"
 
 #define TTY_BUFSIZE             132
 
--- Devices/AirLinked/culfw.c Fri Jul 05 13:03:32 2013
+++ Devices/AirLinked/culfw.c Sun Jun 08 19:54:29 2014
@@ -36,7 +36,7 @@
 #include "intertechno.h"
 #endif
 
-#ifdef HAS_ASKSIN
+#if defined(HAS_ASKSIN) || defined(HAS_ASKSIN_PLL_HELPER) || defined(HAS_MS_TIMER0) || defined(HAS_MS_TIMER3)
 #include "rf_asksin.h"
 #endif
 
@@ -134,12 +134,16 @@
 //  }
 
   // Setup the timers. Are needed for watchdog-reset
-#if defined (HAS_IRRX) || defined (HAS_IRTX)
+#ifdef HAS_IRRX
   ir_init();
   // IR uses highspeed TIMER0 for sampling
   OCR0A  = 1;                              // Timer0: 0.008s = 8MHz/256/2   == 15625Hz
 #else
-  OCR0A  = 249;                            // Timer0: 0.008s = 8MHz/256/250 == 125Hz
+#if defined(HAS_MS_TIMER0) && !defined(HAS_MS_TIMER3)
+  OCR0A  = 124; // Timer0: 0.004s = 8MHz/256/125 interrupt clock
+#else
+  OCR0A  = 249; // Timer0: 0.008s = 8MHz/256/250 interrupt clock
+#endif
 #endif
   TCCR0B = _BV(CS02);
   TCCR0A = _BV(WGM01);
@@ -148,6 +152,16 @@
   TCCR1A = 0;
   TCCR1B = _BV(CS11) | _BV(WGM12);         // Timer1: 1us = 8MHz/8
 
+#ifdef HAS_MS_TIMER3
+  uint8_t sreg = SREG;
+  cli();
+  OCR3A = 999; // 999 -> Timer3: 1ms = 8MHz/8/1000 interrupt clock
+  SREG = sreg;
+  TCCR3A = 0;
+  TCCR3B = _BV(CS31) | _BV(WGM32); // Timer3: 1us = 8MHz/8 base clock
+  TIMSK3 = _BV(OCIE3A);
+#endif
+
   clock_prescale_set(clock_div_1);
 
   MCUSR &= ~(1 << WDRF);                   // Enable the watchdog
@@ -202,6 +216,9 @@
 #endif
 #if defined (HAS_IRRX) || defined (HAS_IRTX)
     ir_task();
+#endif
+#ifdef HAS_ASKSIN_PLL_HELPER
+    rf_asksin_check_PLL_task();
 #endif
 
 }
--- Devices/CCD/board.h Mon Mar 17 14:45:54 2014
+++ Devices/CCD/board.h Sun Jun 08 20:00:47 2014
@@ -51,6 +51,9 @@
 #define HAS_RAWSEND                   //
 #define HAS_FASTRF                    // PROGMEM:  468b  RAM:  1b
 #define HAS_ASKSIN
+//#define HAS_MS_TIMER3 // RAM: +5b noansi: Timer3 for ms timestamp counter in asksin.c
+#define HAS_MS_TIMER0 // RAM: +5b noansi: Timer0 for ms timestamp counter in asksin.c, 4ms (IR 8ms) increment
+#define HAS_ASKSIN_PLL_HELPER // RAM: +1b noansi: check for PLL Lock and try recalibration, if not
 #define HAS_MORITZ
 #define HAS_ESA
 #define HAS_TX3
@@ -64,6 +67,9 @@
 #define BUSWARE_CSM
 #define BUSWARE_CCD
 #define RPI_TTY_FIX
+
+//#define CUL_HW_REVISION "CCD"
+
 
 #endif
 
--- Devices/CCD/CCD.c Sun Oct 06 21:08:48 2013
+++ Devices/CCD/CCD.c Sun Jun 08 20:02:11 2014
@@ -35,7 +35,7 @@
 #include "i2cmaster.h"
 #include "ds1339.h"
 
-#ifdef HAS_ASKSIN
+#if defined(HAS_ASKSIN) || defined(HAS_ASKSIN_PLL_HELPER) || defined(HAS_MS_TIMER0) || defined(HAS_MS_TIMER3)
 #include "rf_asksin.h"
 #endif
 
@@ -132,7 +132,11 @@
   // IR uses highspeed TIMER0 for sampling
   OCR0A  = 1;                              // Timer0: 0.008s = 8MHz/256/2   == 15625Hz
 #else
-  OCR0A  = 249;                            // Timer0: 0.008s = 8MHz/256/250 == 125Hz
+#if defined(HAS_MS_TIMER0) && !defined(HAS_MS_TIMER3)
+  OCR0A  = 124; // Timer0: 0.004s = 8MHz/256/125 interrupt clock
+#else
+  OCR0A  = 249; // Timer0: 0.008s = 8MHz/256/250 interrupt clock
+#endif
 #endif
   TCCR0B = _BV(CS02);
   TCCR0A = _BV(WGM01);
@@ -141,6 +145,16 @@
   TCCR1A = 0;
   TCCR1B = _BV(CS11) | _BV(WGM12);         // Timer1: 1us = 8MHz/8
 
+#ifdef HAS_MS_TIMER3
+  uint8_t sreg = SREG;
+  cli();
+  OCR3A = 999; // 999 -> Timer3: 1ms = 8MHz/8/1000 interrupt clock
+  SREG = sreg;
+  TCCR3A = 0;
+  TCCR3B = _BV(CS31) | _BV(WGM32); // Timer3: 1us = 8MHz/8 base clock
+  TIMSK3 = _BV(OCIE3A);
+#endif
+
 
   MCUSR &= ~(1 << WDRF);                   // Enable the watchdog
   wdt_enable(WDTO_2S);
@@ -185,6 +199,9 @@
 #endif
 #ifdef HAS_MORITZ
     rf_moritz_task();
+#endif
+#ifdef HAS_ASKSIN_PLL_HELPER
+    rf_asksin_check_PLL_task();
 #endif
   }
 
--- Devices/COC/board.h Mon Mar 17 14:45:54 2014
+++ Devices/COC/board.h Sun Jun 08 16:30:54 2014
@@ -45,13 +45,17 @@
 #define HAS_RF_ROUTER                 // PROGMEM: 1248b  RAM: 44b
 
 #define FHTBUF_SIZE          174      //                 RAM: 174b
+//#define FHTBUF_SIZE          168      //                 RAM: 174b -6
 #define RCV_BUCKETS            4      //                 RAM: 25b * bucket
 #define RFR_DEBUG                     // PROGMEM:  354b  RAM: 14b
 #define FULL_CC1100_PA                // PROGMEM:  108b
 #define HAS_RAWSEND                   //
 #define HAS_FASTRF                    // PROGMEM:  468b  RAM:  1b
+#define HAS_ASKSIN_PLL_HELPER // noansi: check for PLL Lock and try recalibration, if not
 #define HAS_ASKSIN
 #define HAS_ASKSIN_FUP
+//#define HAS_MS_TIMER3 // RAM: +5b Timer3 for ms timestamp counter in asksin.c
+#define HAS_MS_TIMER0 // RAM: +5b noansi: Timer0 for ms timestamp counter in asksin.c, 4ms increment
 #define HAS_MORITZ
 #define HAS_ESA
 #define HAS_TX3
--- Devices/COC/COC.c Fri Mar 14 19:57:58 2014
+++ Devices/COC/COC.c Sun Jun 08 16:52:06 2014
@@ -35,7 +35,7 @@
 #include "i2cmaster.h"
 #include "ds1339.h"
 
-#ifdef HAS_ASKSIN
+#if defined(HAS_ASKSIN) || defined(HAS_ASKSIN_PLL_HELPER) || defined(HAS_MS_TIMER0) || defined(HAS_MS_TIMER3)
 #include "rf_asksin.h"
 #endif
 
@@ -133,7 +133,11 @@
   // IR uses highspeed TIMER0 for sampling
   OCR0A  = 1;                              // Timer0: 0.008s = 8MHz/256/2   == 15625Hz
 #else
-  OCR0A  = 249;                            // Timer0: 0.008s = 8MHz/256/250 == 125Hz
+#if defined(HAS_MS_TIMER0) && !defined(HAS_MS_TIMER3)
+  OCR0A  = 124; // Timer0: 0.004s = 8MHz/256/125 interrupt clock
+#else
+  OCR0A  = 249; // Timer0: 0.008s = 8MHz/256/250 interrupt clock
+#endif
 #endif
   TCCR0B = _BV(CS02);
   TCCR0A = _BV(WGM01);
@@ -142,6 +146,16 @@
   TCCR1A = 0;
   TCCR1B = _BV(CS11) | _BV(WGM12);         // Timer1: 1us = 8MHz/8
 
+#ifdef HAS_MS_TIMER3
+  uint8_t sreg = SREG;
+  cli();
+  OCR3A = 999; // 999 -> Timer3: 1ms = 8MHz/8/1000 interrupt clock
+  SREG = sreg;
+  TCCR3A = 0;
+  TCCR3B = _BV(CS31) | _BV(WGM32); // Timer3: 1us = 8MHz/8 base clock
+  TIMSK3 = _BV(OCIE3A);
+#endif
+
 
   MCUSR &= ~(1 << WDRF);                   // Enable the watchdog
   wdt_enable(WDTO_2S);
@@ -186,6 +200,9 @@
 #endif
 #ifdef HAS_MORITZ
     rf_moritz_task();
+#endif
+#ifdef HAS_ASKSIN_PLL_HELPER
+    rf_asksin_check_PLL_task();
 #endif
   }
 
--- Devices/COC/makefile Tue Jun 25 08:38:20 2013
+++ Devices/COC/makefile Sat Jun 07 15:52:46 2014
@@ -100,7 +100,7 @@
 
 all:
  make TARGET=COC COCVERS=FULL mostly_clean build size
- make TARGET=COC.radio_only COCVERS=RADIO_ONLY mostly_clean build size
+ make TARGET=COC_radio_only COCVERS=RADIO_ONLY mostly_clean build size
 
 build: elf hex eep lss sym
 
@@ -125,7 +125,7 @@
 program_full: COCVERS=FULL
 program_full: do_program
 
-program_radio_only: TARGET=COC.radio_only
+program_radio_only: TARGET=COC_radio_only
 program_radio_only: COCVERS=RADIO_ONLY
 program_radio_only: do_program
 
--- Devices/CSM/board.h Fri Mar 14 19:57:58 2014
+++ Devices/CSM/board.h Sun Jun 08 20:11:17 2014
@@ -64,6 +64,9 @@
 #define HAS_RF_ROUTER                 // PROGMEM:  920b  RAM: 38b
 #define HAS_ASKSIN
 #define HAS_ASKSIN_FUP
+//#define HAS_MS_TIMER3 // RAM: +5b noansi: Timer3 for ms timestamp counter in asksin.c
+#define HAS_MS_TIMER0 // RAM: +5b noansi: Timer0 for ms timestamp counter in asksin.c, 4ms (IR 8ms) increment
+#define HAS_ASKSIN_PLL_HELPER // RAM: +1b noansi: check for PLL Lock and try recalibration, if not
 #define HAS_MORITZ
 #define HAS_ESA
 #define HAS_INTERTECHNO
@@ -142,6 +145,26 @@
 
 #define BOARD_ID_STR            "CSM868"
 #define BOARD_ID_STR433         "CSM433"
+
+#ifdef CSMV2
+//#define CUL_HW_REVISION "CSM_V2"
+#endif
+
+#ifdef CSMV3
+//#define CUL_HW_REVISION "CSM_V3"
+#endif
+
+#ifdef CSMV4
+//#define CUL_HW_REVISION "CSM_V4"
+#endif
+
+#ifdef TUXRAIL
+//#define CUL_HW_REVISION "TUXRAIL"
+#endif
+
+#ifdef TUXRADIO
+//#define CUL_HW_REVISION "TUXRADIO"
+#endif
 
 #define HAS_UART                1
 #define UART_BAUD_RATE          38400
--- Devices/CSM/CSM.c Fri Mar 14 19:57:58 2014
+++ Devices/CSM/CSM.c Sun Jun 08 20:13:52 2014
@@ -36,7 +36,7 @@
 #include "intertechno.h"
 #endif
 
-#ifdef HAS_ASKSIN
+#if defined(HAS_ASKSIN) || defined(HAS_ASKSIN_PLL_HELPER) || defined(HAS_MS_TIMER0) || defined(HAS_MS_TIMER3)
 #include "rf_asksin.h"
 #endif
 
@@ -149,7 +149,11 @@
   // IR uses highspeed TIMER0 for sampling
   OCR0A  = 1;                              // Timer0: 0.008s = 8MHz/256/2   == 15625Hz
 #else
-  OCR0A  = 249;                            // Timer0: 0.008s = 8MHz/256/250 == 125Hz
+#if defined(HAS_MS_TIMER0) && !defined(HAS_MS_TIMER3)
+  OCR0A  = 124; // Timer0: 0.004s = 8MHz/256/125 interrupt clock
+#else
+  OCR0A  = 249; // Timer0: 0.008s = 8MHz/256/250 interrupt clock
+#endif
 #endif
   TCCR0B = _BV(CS02);
   TCCR0A = _BV(WGM01);
@@ -158,6 +162,16 @@
   TCCR1A = 0;
   TCCR1B = _BV(CS11) | _BV(WGM12);         // Timer1: 1us = 8MHz/8
 
+#ifdef HAS_MS_TIMER3
+  uint8_t sreg = SREG;
+  cli();
+  OCR3A = 999; // 999 -> Timer3: 1ms = 8MHz/8/1000 interrupt clock
+  SREG = sreg;
+  TCCR3A = 0;
+  TCCR3B = _BV(CS31) | _BV(WGM32); // Timer3: 1us = 8MHz/8 base clock
+  TIMSK3 = _BV(OCIE3A);
+#endif
+
   clock_prescale_set(clock_div_1);
 
   MCUSR &= ~(1 << WDRF);                   // Enable the watchdog
@@ -206,6 +220,9 @@
 #endif
 #ifdef HAS_IRRX
     ir_task();
+#endif
+#ifdef HAS_ASKSIN_PLL_HELPER
+    rf_asksin_check_PLL_task();
 #endif
   }
 
--- Devices/CUL/board.h Fri Apr 18 20:06:04 2014
+++ Devices/CUL/board.h Mon Jun 09 15:46:40 2014
@@ -15,16 +15,18 @@
 #define HAS_FHT_80b                     // PROGMEM: 1374b, RAM: 90b
 #define HAS_FHT_8v                      // PROGMEM:  586b  RAM: 23b
 #define HAS_RF_ROUTER                   // PROGMEM: 1248b  RAM: 44b
+#define HAS_ASKSIN_PLL_HELPER // RAM: +1b noansi: check for PLL Lock and try recalibration, if not
 
 #if defined(CUL_V3) || defined(CUL_V4)
 #  define FHTBUF_SIZE          174      //                 RAM: 174b
+//#  define FHTBUF_SIZE          168      //                 RAM: 174b -6
 #  define RCV_BUCKETS            4      //                 RAM: 25b * bucket
 #  define RFR_DEBUG                     // PROGMEM:  354b  RAM: 14b
 #  define FULL_CC1100_PA                // PROGMEM:  108b
 #  define HAS_RAWSEND                   //
 #  define HAS_FASTRF                    // PROGMEM:  468b  RAM:  1b
-#  define HAS_ASKSIN
-#  define HAS_ASKSIN_FUP
+#  define HAS_ASKSIN //                 RAM:  1b +1b
+#  define HAS_ASKSIN_FUP //                 RAM:  1b
 #  define HAS_MORITZ
 #  define HAS_RWE
 #  define HAS_ESA
@@ -36,11 +38,15 @@
 #endif
 
 #if defined(CUL_V4)
+#  define HAS_MS_TIMER0 // RAM: +5b noansi: Timer0 for ms timestamp counter in asksin.c, 4ms increment
 #  define TTY_BUFSIZE           64      // RAM: TTY_BUFSIZE*4
 #endif
 
 #if defined(CUL_V3)
+//#  define HAS_MS_TIMER3 // RAM: +5b noansi: Timer3 for ms timestamp counter in asksin.c
+#  define HAS_MS_TIMER0 // RAM: +5b noansi: Timer0 for ms timestamp counter in asksin.c, 4ms increment
 #  define TTY_BUFSIZE          128      // RAM: TTY_BUFSIZE*4
+//#  define TTY_BUFSIZE          152     // RAM: TTY_BUFSIZE*4
 #endif
 
 
@@ -53,12 +59,15 @@
 #  define HAS_TX3
 #  define HAS_HOERMANN
 #  undef  HAS_FHT_8v
+#  undef  HAS_ASKSIN_PLL_HELPER // RAM: +1b noansi: check for PLL Lock and try recalibration, if not. Not enough free Flash
 #endif
 
 #ifdef CUL_V2_HM
 #  define CUL_V2
 #  define HAS_ASKSIN
+#  define HAS_MS_TIMER0 // RAM: +5b noansi: Timer0 for ms timestamp counter in asksin.c, 4ms resolution
 #  define TTY_BUFSIZE           64
+//#  define TTY_BUFSIZE           62 // RAM: -8b
 #  define RCV_BUCKETS            2
 #  undef  HAS_RF_ROUTER
 #  undef  HAS_FHT_80b
@@ -90,6 +99,7 @@
 // No features to define below
 
 #include <avr/io.h>
+
 #include <avr/power.h>
 
 #if !defined(clock_prescale_set) && __AVR_LIBC_VERSION__  < 10701UL
--- Devices/CUL/CUL.c Sat Mar 29 07:17:22 2014
+++ Devices/CUL/CUL.c Sun Jun 08 16:51:26 2014
@@ -3,11 +3,16 @@
    Inpired by the MyUSB USBtoSerial demo, Copyright (C) Dean Camera, 2008.
 */
 
+#include <avr/io.h>
+
 #include <avr/boot.h>
 #include <avr/power.h>
 #include <avr/eeprom.h>
 #include <avr/interrupt.h>
-#include <avr/io.h>
+
+//#include <avr/io.h>
+
+
 #include <avr/pgmspace.h>
 #include <avr/wdt.h>
 
@@ -34,7 +39,7 @@
 #ifdef HAS_MEMFN
 #include "memory.h" // getfreemem
 #endif
-#ifdef HAS_ASKSIN
+#if defined(HAS_ASKSIN) || defined(HAS_ASKSIN_PLL_HELPER) || defined(HAS_MS_TIMER0) || defined(HAS_MS_TIMER3)
 #include "rf_asksin.h"
 #endif
 #ifdef HAS_MORITZ
@@ -132,13 +137,33 @@
 
 
   // Setup the timers. Are needed for watchdog-reset
-  OCR0A  = 249;                            // Timer0: 0.008s = 8MHz/256/250
+#ifdef HAS_IRRX
+  ir_init();
+  // IR uses highspeed TIMER0 for sampling
+  OCR0A  = 1;                              // Timer0: 0.008s = 8MHz/256/2   == 15625Hz
+#else
+#if defined(HAS_MS_TIMER0) && !defined(HAS_MS_TIMER3)
+  OCR0A  = 124; // Timer0: 0.004s = 8MHz/256/125 interrupt clock
+#else
+  OCR0A  = 249; // Timer0: 0.008s = 8MHz/256/250 interrupt clock
+#endif
+#endif
   TCCR0B = _BV(CS02);       
   TCCR0A = _BV(WGM01);
   TIMSK0 = _BV(OCIE0A);
 
   TCCR1A = 0;
-  TCCR1B = _BV(CS11) | _BV(WGM12);         // Timer1: 1us = 8MHz/8
+  TCCR1B = _BV(CS11) | _BV(WGM12); // Timer1: 1us = 8MHz/8
+
+#ifdef HAS_MS_TIMER3
+  uint8_t sreg = SREG;
+  cli();
+  OCR3A = 999; // 999 -> Timer3: 1ms = 8MHz/8/1000 interrupt clock
+  SREG = sreg;
+  TCCR3A = 0;
+  TCCR3B = _BV(CS31) | _BV(WGM32); // Timer3: 1us = 8MHz/8 base clock
+  TIMSK3 = _BV(OCIE3A);
+#endif
 
   MCUSR &= ~(1 << WDRF);                   // Enable the watchdog
 
@@ -178,5 +203,9 @@
 #ifdef HAS_RWE
     rf_rwe_task();
 #endif
+#ifdef HAS_ASKSIN_PLL_HELPER
+    rf_asksin_check_PLL_task();
+#endif
+
   }
 }
--- Devices/CUN/board.h Wed Jul 11 15:19:20 2012
+++ Devices/CUN/board.h Sat Jun 07 17:21:32 2014
@@ -102,6 +102,8 @@
 #define HAS_RAWSEND                     // PROGMEM:  198b     RAM:  4b
 #define HAS_FASTRF                      // PROGMEM:  362+106  RAM:  1b
 #define HAS_ASKSIN
+//#define HAS_MS_TIMER0 // noansi: Timer0 for ms timestamp counter in asksin.c, 4ms resolution
+//#define HAS_MS_TIMER3 // noansi: Timer3 for ms timestamp counter in asksin.c, only if supported by CPU
 #define HAS_ESA
 #define HAS_TX3
 #define HAS_INTERTECHNO
--- Devices/CUN/CUN.c Tue Nov 27 22:12:52 2012
+++ Devices/CUN/CUN.c Sat Jun 07 18:06:15 2014
@@ -153,13 +153,33 @@
   while(tx_report);                     // reboot if the bss is not initialized
 
   // Setup the timers. Are needed for watchdog-reset
-  OCR0A  = 249;                            // Timer0: 0.008s = 8MHz/256/250
+#ifdef HAS_IRRX
+  ir_init();
+  // IR uses highspeed TIMER0 for sampling
+  OCR0A  = 1;                              // Timer0: 0.008s = 8MHz/256/2   == 15625Hz
+#else
+#if defined(HAS_MS_TIMER0) && !defined(HAS_MS_TIMER3)
+  OCR0A  = 124; // Timer0: 0.004s = 8MHz/256/125 interrupt clock
+#else
+  OCR0A  = 249; // Timer0: 0.008s = 8MHz/256/250 interrupt clock
+#endif
+#endif
   TCCR0B = _BV(CS02);       
   TCCR0A = _BV(WGM01);
   TIMSK0 = _BV(OCIE0A);
 
   TCCR1A = 0;
   TCCR1B = _BV(CS11) | _BV(WGM12);         // Timer1: 1us = 8MHz/8
+
+#ifdef HAS_MS_TIMER3
+  uint8_t sreg = SREG;
+  cli();
+  OCR3A = 999; // 999 -> Timer3: 1ms = 8MHz/8/1000 interrupt clock
+  SREG = sreg;
+  TCCR3A = 0;
+  TCCR3B = _BV(CS31) | _BV(WGM32); // Timer3: 1us = 8MHz/8 base clock
+  TIMSK3 = _BV(OCIE3A);
+#endif
 
   MCUSR &= ~(1 << WDRF);                   // Enable the watchdog
 
--- Devices/CUNO/board.h Fri Mar 14 19:57:58 2014
+++ Devices/CUNO/board.h Sun Jun 08 20:20:07 2014
@@ -69,6 +69,9 @@
 #define HAS_FASTRF                    // PROGMEM:  468b  RAM:  1b
 #define HAS_ASKSIN
 #define HAS_ASKSIN_FUP
+//#define HAS_MS_TIMER3 // RAM: +5b noansi: Timer3 for ms timestamp counter in asksin.c
+#define HAS_MS_TIMER0 // RAM: +5b noansi: Timer0 for ms timestamp counter in asksin.c, 4ms (IR 8ms) increment
+#define HAS_ASKSIN_PLL_HELPER // RAM: +1b noansi: check for PLL Lock and try recalibration, if not
 #define HAS_ESA
 #define HAS_TX3
 #define HAS_INTERTECHNO
@@ -80,6 +83,7 @@
 
 #define BOARD_ID_STR            "CUNO868"
 #define BOARD_ID_STR433         "CUNO433"
+//#define CUL_HW_REVISION "CUNO"
 
 #define HAS_UART                1
 #define UART_BAUD_RATE          38400
--- Devices/CUNO/CUNO.c Tue Nov 27 22:12:52 2012
+++ Devices/CUNO/CUNO.c Sun Jun 08 20:21:50 2014
@@ -37,7 +37,7 @@
 
 #include "i2cmaster.h"
 
-#ifdef HAS_ASKSIN
+#if defined(HAS_ASKSIN) || defined(HAS_ASKSIN_PLL_HELPER) || defined(HAS_MS_TIMER0) || defined(HAS_MS_TIMER3)
 #include "rf_asksin.h"
 #endif
 
@@ -147,7 +147,17 @@
 
   // Setup the timers. Are needed for watchdog-reset
 
-  OCR0A  = 249;                            // Timer0: 0.008s = 8MHz/256/250 == 125Hz
+#ifdef HAS_IRRX
+  ir_init();
+  // IR uses highspeed TIMER0 for sampling
+  OCR0A  = 1;                              // Timer0: 0.008s = 8MHz/256/2   == 15625Hz
+#else
+#if defined(HAS_MS_TIMER0) && !defined(HAS_MS_TIMER3)
+  OCR0A  = 124; // Timer0: 0.004s = 8MHz/256/125 interrupt clock
+#else
+  OCR0A  = 249; // Timer0: 0.008s = 8MHz/256/250 interrupt clock
+#endif
+#endif
   TCCR0B = _BV(CS02);
   TCCR0A = _BV(WGM01);
   TIMSK0 = _BV(OCIE0A);
@@ -155,6 +165,16 @@
   TCCR1A = 0;
   TCCR1B = _BV(CS11) | _BV(WGM12);         // Timer1: 1us = 8MHz/8
 
+#ifdef HAS_MS_TIMER3
+  uint8_t sreg = SREG;
+  cli();
+  OCR3A = 999; // 999 -> Timer3: 1ms = 8MHz/8/1000 interrupt clock
+  SREG = sreg;
+  TCCR3A = 0;
+  TCCR3B = _BV(CS31) | _BV(WGM32); // Timer3: 1us = 8MHz/8 base clock
+  TIMSK3 = _BV(OCIE3A);
+#endif
+
   clock_prescale_set(clock_div_1);
 
   MCUSR &= ~(1 << WDRF);                   // Enable the watchdog
@@ -196,6 +216,9 @@
 #endif
 #ifdef HAS_ETHERNET
     Ethernet_Task();
+#endif
+#ifdef HAS_ASKSIN_PLL_HELPER
+    rf_asksin_check_PLL_task();
 #endif
   }
 
--- Devices/CUNO2/board.h Fri Mar 14 19:57:58 2014
+++ Devices/CUNO2/board.h Sun Jun 08 20:25:49 2014
@@ -66,6 +66,9 @@
 #define HAS_FASTRF                    // PROGMEM:  468b  RAM:  1b
 #define HAS_ASKSIN
 #define HAS_ASKSIN_FUP
+//#define HAS_MS_TIMER3 // RAM: +5b noansi: Timer3 for ms timestamp counter in asksin.c
+#define HAS_MS_TIMER0 // RAM: +5b noansi: Timer0 for ms timestamp counter in asksin.c, 4ms (IR 8ms) increment
+#define HAS_ASKSIN_PLL_HELPER // RAM: +1b noansi: check for PLL Lock and try recalibration, if not
 #define HAS_ESA
 #define HAS_TX3
 #define HAS_INTERTECHNO
@@ -138,6 +141,8 @@
 #define TTY_BUFSIZE             1024
 
 #define BUSWARE_CUNO2
+
+//#define CUL_HW_REVISION "CUNO2"
 
 #ifndef eeprom_update_byte
 #define eeprom_update_byte eeprom_write_byte
--- Devices/CUNO2/CUNO2.c Sun Nov 03 00:01:38 2013
+++ Devices/CUNO2/CUNO2.c Sun Jun 08 20:23:40 2014
@@ -52,7 +52,7 @@
 
 #include "i2cmaster.h"
 
-#ifdef HAS_ASKSIN
+#if defined(HAS_ASKSIN) || defined(HAS_ASKSIN_PLL_HELPER) || defined(HAS_MS_TIMER0) || defined(HAS_MS_TIMER3)
 #include "rf_asksin.h"
 #endif
 
@@ -156,12 +156,16 @@
 
   // Setup the timers. Are needed for watchdog-reset
 
-#if defined (HAS_IRRX) || defined (HAS_IRTX)
+#ifdef HAS_IRRX
   ir_init();
   // IR uses highspeed TIMER0 for sampling
-  OCR0A  = 1;                              // Timer0: 0.008s = 8MHz/256/2   == 15625Hz Fac: 125
+  OCR0A  = 1;                              // Timer0: 0.008s = 8MHz/256/2   == 15625Hz
+#else
+#if defined(HAS_MS_TIMER0) && !defined(HAS_MS_TIMER3)
+  OCR0A  = 124; // Timer0: 0.004s = 8MHz/256/125 interrupt clock
 #else
-  OCR0A  = 249;                            // Timer0: 0.008s = 8MHz/256/250 == 125Hz
+  OCR0A  = 249; // Timer0: 0.008s = 8MHz/256/250 interrupt clock
+#endif
 #endif
 
   TCCR0B = _BV(CS02);
@@ -171,6 +175,16 @@
   TCCR1A = 0;
   TCCR1B = _BV(CS11) | _BV(WGM12);         // Timer1: 1us = 8MHz/8
 
+#ifdef HAS_MS_TIMER3
+  uint8_t sreg = SREG;
+  cli();
+  OCR3A = 999; // 999 -> Timer3: 1ms = 8MHz/8/1000 interrupt clock
+  SREG = sreg;
+  TCCR3A = 0;
+  TCCR3B = _BV(CS31) | _BV(WGM32); // Timer3: 1us = 8MHz/8 base clock
+  TIMSK3 = _BV(OCIE3A);
+#endif
+
   clock_prescale_set(clock_div_1);
 
   MCUSR &= ~(1 << WDRF);                   // Enable the watchdog
@@ -249,6 +263,9 @@
 #ifdef HAS_HELIOS
     helios_task();
 #endif   
+#ifdef HAS_ASKSIN_PLL_HELPER
+    rf_asksin_check_PLL_task();
+#endif
   }
 
 }
--- Devices/CUR/board.h Wed Jul 11 15:19:20 2012
+++ Devices/CUR/board.h Sun Jun 08 20:46:24 2014
@@ -25,15 +25,19 @@
 #define FULL_CC1100_PA                  // PROGMEM:  100b
 #define HAS_FASTRF                      // PROGMEM:  362b  RAM:  1b
 #define HAS_RAWSEND                     // PROGMEM:   90b  RAM:  6b
-#define HAS_ASKSIN
+//#define HAS_ASKSIN // why is it here?
+//#define HAS_MS_TIMER0 // RAM: +5b noansi: Timer0 for ms timestamp counter in asksin.c, 4ms (IR 8ms) increment
+#define HAS_ASKSIN_PLL_HELPER // RAM: +1b noansi: check for PLL Lock and try recalibration, if not
 #define HAS_ESA
 #define HAS_TX3
 #define HAS_HOERMANN
 
 #ifdef CURV3
 #  include "board_v3.h"
+//#define CUL_HW_REVISION "CUR_V3"
 #else
 #  include "board_v2.h"
+//#define CUL_HW_REVISION "CUR_V2"
 #endif
 
 #endif
--- Devices/CUR/CUR.c Tue Nov 27 22:12:52 2012
+++ Devices/CUR/CUR.c Sun Jun 08 20:37:01 2014
@@ -40,6 +40,10 @@
 #include "fastrf.h"
 #include "rf_router.h"
 
+#if defined(HAS_ASKSIN) || defined(HAS_ASKSIN_PLL_HELPER) || defined(HAS_MS_TIMER0) || defined(HAS_MS_TIMER3)
+#include "rf_asksin.h"
+#endif
+
 df_chip_t df;
 
 const PROGMEM t_fntab fntab[] = {
@@ -106,7 +110,17 @@
   }
 
   // Setup the timers. Are needed for watchdog-reset
-  OCR0A  = 249;                            // Timer0: 0.008s = 8MHz/256/250
+#ifdef HAS_IRRX
+  ir_init();
+  // IR uses highspeed TIMER0 for sampling
+  OCR0A  = 1;                              // Timer0: 0.008s = 8MHz/256/2   == 15625Hz
+#else
+#if defined(HAS_MS_TIMER0) && !defined(HAS_MS_TIMER3)
+  OCR0A  = 124; // Timer0: 0.004s = 8MHz/256/125 interrupt clock
+#else
+  OCR0A  = 249; // Timer0: 0.008s = 8MHz/256/250 interrupt clock
+#endif
+#endif
   TCCR0B = _BV(CS02);       
   TCCR0A = _BV(WGM01);
   TIMSK0 = _BV(OCIE0A);
@@ -150,5 +164,8 @@
     FastRF_Task();
     rf_router_task();
     JOY_Task();
+#ifdef HAS_ASKSIN_PLL_HELPER
+    rf_asksin_check_PLL_task();
+#endif
   }
 }
--- Devices/CUR/makefile Sun Nov 13 21:23:08 2011
+++ Devices/CUR/makefile Sun Jun 08 20:42:00 2014
@@ -22,6 +22,7 @@
  ../../clib/rf_send.c                                  \
  ../../clib/rf_receive.c                               \
  ../../clib/fht.c                                      \
+ ../../clib/rf_asksin.c                                \
  ../../clib/ttydata.c                                  \
  ../../clib/pcf8833.c                                  \
  ../../clib/menu.c                                     \
--- Devices/CUR/makefile.myusb Sun Nov 01 08:37:40 2009
+++ Devices/CUR/makefile.myusb Sun Jun 08 20:42:47 2014
@@ -22,6 +22,7 @@
  ../../clib/rf_send.c                                  \
  ../../clib/rf_receive.c                               \
  ../../clib/fht.c                                      \
+ ../../clib/rf_asksin.c                                \
  ../../clib/ttydata.c                                  \
  ../../clib/pcf8833.c                                  \
  ../../clib/menu.c                                     \
--- Devices/RFbee/board.h Thu Mar 13 23:05:46 2014
+++ Devices/RFbee/board.h Sun Jun 08 20:50:21 2014
@@ -11,6 +11,9 @@
 #define HAS_FASTRF // PROGMEM:  468b  RAM:  1b
 #define HAS_ASKSIN
 #define HAS_ASKSIN_FUP
+//#define HAS_MS_TIMER3 // RAM: +5b noansi: Timer3 for ms timestamp counter in asksin.c
+#define HAS_MS_TIMER0 // RAM: +5b noansi: Timer0 for ms timestamp counter in asksin.c, 4ms (IR 8ms) increment
+#define HAS_ASKSIN_PLL_HELPER // RAM: +1b noansi: check for PLL Lock and try recalibration, if not
 #undef  HAS_ESA
 #define HAS_INTERTECHNO
 #define HAS_MORITZ
@@ -53,6 +56,7 @@
 #define LED_PIN 6
 
 #define BOARD_ID_STR "RFbee"
+//#define CUL_HW_REVISION "RFbee"
 
 #define HAS_UART 1
 #define UART_BAUD_RATE 38400
--- Devices/RFbee/RFbee.c Thu Mar 13 23:05:46 2014
+++ Devices/RFbee/RFbee.c Sun Jun 08 20:48:41 2014
@@ -40,7 +40,7 @@
 #include "intertechno.h"
 #endif
 
-#ifdef HAS_ASKSIN
+#if defined(HAS_ASKSIN) || defined(HAS_ASKSIN_PLL_HELPER) || defined(HAS_MS_TIMER0) || defined(HAS_MS_TIMER3)
 #include "rf_asksin.h"
 #endif
 
@@ -107,7 +107,17 @@
  eeprom_init();
 
  // Setup the timers. Are needed for watchdog-reset
- OCR0A  = 249;                            // Timer0: 0.008s = 8MHz/256/250 == 125Hz
+#ifdef HAS_IRRX
+ ir_init();
+ // IR uses highspeed TIMER0 for sampling
+ OCR0A  = 1;                              // Timer0: 0.008s = 8MHz/256/2   == 15625Hz
+#else
+#if defined(HAS_MS_TIMER0) && !defined(HAS_MS_TIMER3)
+ OCR0A  = 124; // Timer0: 0.004s = 8MHz/256/125 interrupt clock
+#else
+ OCR0A  = 249; // Timer0: 0.008s = 8MHz/256/250 interrupt clock
+#endif
+#endif
  TCCR0B = _BV(CS02);
  TCCR0A = _BV(WGM01);
  TIMSK0 = _BV(OCIE0A);
@@ -115,6 +125,16 @@
  TCCR1A = 0;
  TCCR1B = _BV(CS11) | _BV(WGM12);         // Timer1: 1us = 8MHz/8
 
+#ifdef HAS_MS_TIMER3
+ uint8_t sreg = SREG;
+ cli();
+ OCR3A = 999; // 999 -> Timer3: 1ms = 8MHz/8/1000 interrupt clock
+ SREG = sreg;
+ TCCR3A = 0;
+ TCCR3B = _BV(CS31) | _BV(WGM32); // Timer3: 1us = 8MHz/8 base clock
+ TIMSK3 = _BV(OCIE3A);
+#endif
+
  clock_prescale_set(clock_div_1);
 
  MCUSR &= ~(1 << WDRF);                   // Enable the watchdog
@@ -153,6 +173,9 @@
 #endif
 #ifdef HAS_RWE
  rf_rwe_task();
+#endif
+#ifdef HAS_ASKSIN_PLL_HELPER
+    rf_asksin_check_PLL_task();
 #endif
  }
 }
--- Devices/SCC/board.h Mon Mar 17 14:50:20 2014
+++ Devices/SCC/board.h Sun Jun 08 20:52:46 2014
@@ -49,6 +49,9 @@
 #define HAS_FASTRF                    // PROGMEM:  468b  RAM:  1b
 #define HAS_RF_ROUTER                 // PROGMEM:  920b  RAM: 38b
 #define HAS_ASKSIN
+//#define HAS_MS_TIMER3 // RAM: +5b noansi: Timer3 for ms timestamp counter in asksin.c
+#define HAS_MS_TIMER0 // RAM: +5b noansi: Timer0 for ms timestamp counter in asksin.c, 4ms (IR 8ms) increment
+#define HAS_ASKSIN_PLL_HELPER // RAM: +1b noansi: check for PLL Lock and try recalibration, if not
 #define HAS_MORITZ
 #define HAS_ESA
 #define HAS_INTERTECHNO
@@ -77,5 +80,7 @@
 #define BUSWARE_CSM
 #define BUSWARE_SCC
 #define RPI_TTY_FIX
+
+//#define CUL_HW_REVISION "SCC"
 
 #endif
--- Devices/SCC/SCC.c Mon Mar 17 14:50:20 2014
+++ Devices/SCC/SCC.c Sun Jun 08 20:54:05 2014
@@ -36,7 +36,7 @@
 #include "intertechno.h"
 #endif
 
-#ifdef HAS_ASKSIN
+#if defined(HAS_ASKSIN) || defined(HAS_ASKSIN_PLL_HELPER) || defined(HAS_MS_TIMER0) || defined(HAS_MS_TIMER3)
 #include "rf_asksin.h"
 #endif
 
@@ -132,7 +132,17 @@
 //  }
 
   // Setup the timers. Are needed for watchdog-reset
-  OCR0A  = 249;                            // Timer0: 0.008s = 8MHz/256/250 == 125Hz
+#ifdef HAS_IRRX
+  ir_init();
+  // IR uses highspeed TIMER0 for sampling
+  OCR0A  = 1;                              // Timer0: 0.008s = 8MHz/256/2   == 15625Hz
+#else
+#if defined(HAS_MS_TIMER0) && !defined(HAS_MS_TIMER3)
+  OCR0A  = 124; // Timer0: 0.004s = 8MHz/256/125 interrupt clock
+#else
+  OCR0A  = 249; // Timer0: 0.008s = 8MHz/256/250 interrupt clock
+#endif
+#endif
   TCCR0B = _BV(CS02);
   TCCR0A = _BV(WGM01);
   TIMSK0 = _BV(OCIE0A);
@@ -140,6 +150,16 @@
   TCCR1A = 0;
   TCCR1B = _BV(CS11) | _BV(WGM12);         // Timer1: 1us = 8MHz/8
 
+#ifdef HAS_MS_TIMER3
+  uint8_t sreg = SREG;
+  cli();
+  OCR3A = 999; // 999 -> Timer3: 1ms = 8MHz/8/1000 interrupt clock
+  SREG = sreg;
+  TCCR3A = 0;
+  TCCR3B = _BV(CS31) | _BV(WGM32); // Timer3: 1us = 8MHz/8 base clock
+  TIMSK3 = _BV(OCIE3A);
+#endif
+
   clock_prescale_set(clock_div_1);
 
   MCUSR &= ~(1 << WDRF);                   // Enable the watchdog
@@ -189,6 +209,9 @@
 #endif
 #ifdef HAS_STACKING
   stacking_task();
+#endif
+#ifdef HAS_ASKSIN_PLL_HELPER
+    rf_asksin_check_PLL_task();
 #endif
 
   }
--- Devices/TuxRadio/board.h Wed Jul 11 15:19:20 2012
+++ Devices/TuxRadio/board.h Sun Jun 08 20:59:48 2014
@@ -67,8 +67,12 @@
 #define HAS_RAWSEND                   //
 #define HAS_FASTRF                    // PROGMEM:  468b  RAM:  1b
 //#define HAS_ASKSIN
+//#define HAS_MS_TIMER3 // RAM: +5b noansi: Timer3 for ms timestamp counter in asksin.c
+//#define HAS_MS_TIMER0 // RAM: +5b noansi: Timer0 for ms timestamp counter in asksin.c, 4ms (IR 8ms) increment
+#define HAS_ASKSIN_PLL_HELPER // RAM: +1b noansi: check for PLL Lock and try recalibration, if not
 //#define HAS_ESA
 
 #define BUSWARE_CSM
+//#define CUL_HW_REVISION "TuxRadio"
 
 #endif
--- Devices/TuxRadio/CSM.c Tue Nov 27 22:12:52 2012
+++ Devices/TuxRadio/CSM.c Sun Jun 08 21:01:19 2014
@@ -32,7 +32,7 @@
 #include "rf_router.h"
 #include "memory.h"
 
-#ifdef HAS_ASKSIN
+#if defined(HAS_ASKSIN) || defined(HAS_ASKSIN_PLL_HELPER) || defined(HAS_MS_TIMER0) || defined(HAS_MS_TIMER3)
 #include "rf_asksin.h"
 #endif
 
@@ -108,7 +108,11 @@
   // IR uses highspeed TIMER0 for sampling
   OCR0A  = 1;                              // Timer0: 0.008s = 8MHz/256/2   == 15625Hz
 #else
-  OCR0A  = 249;                            // Timer0: 0.008s = 8MHz/256/250 == 125Hz
+#if defined(HAS_MS_TIMER0) && !defined(HAS_MS_TIMER3)
+  OCR0A  = 124; // Timer0: 0.004s = 8MHz/256/125 interrupt clock
+#else
+  OCR0A  = 249; // Timer0: 0.008s = 8MHz/256/250 interrupt clock
+#endif
 #endif
   TCCR0B = _BV(CS02);
   TCCR0A = _BV(WGM01);
@@ -117,6 +121,16 @@
   TCCR1A = 0;
   TCCR1B = _BV(CS11) | _BV(WGM12);         // Timer1: 1us = 8MHz/8
 
+#ifdef HAS_MS_TIMER3
+  uint8_t sreg = SREG;
+  cli();
+  OCR3A = 999; // 999 -> Timer3: 1ms = 8MHz/8/1000 interrupt clock
+  SREG = sreg;
+  TCCR3A = 0;
+  TCCR3B = _BV(CS31) | _BV(WGM32); // Timer3: 1us = 8MHz/8 base clock
+  TIMSK3 = _BV(OCIE3A);
+#endif
+
 
   MCUSR &= ~(1 << WDRF);                   // Enable the watchdog
   wdt_enable(WDTO_2S);
@@ -161,6 +175,9 @@
 #endif
 #ifdef HAS_IRRX
     ir_task();
+#endif
+#ifdef HAS_ASKSIN_PLL_HELPER
+    rf_asksin_check_PLL_task();
 #endif
   }
 
--- Devices/TuxRadio2/board.h Fri Jan 11 14:08:54 2013
+++ Devices/TuxRadio2/board.h Sun Jun 08 21:04:11 2014
@@ -51,6 +51,9 @@
 #define HAS_RAWSEND                   //
 #define HAS_FASTRF                    // PROGMEM:  468b  RAM:  1b
 #define HAS_ASKSIN
+//#define HAS_MS_TIMER3 // RAM: +5b noansi: Timer3 for ms timestamp counter in asksin.c
+#define HAS_MS_TIMER0 // RAM: +5b noansi: Timer0 for ms timestamp counter in asksin.c, 4ms (IR 8ms) increment
+#define HAS_ASKSIN_PLL_HELPER // RAM: +1b noansi: check for PLL Lock and try recalibration, if not
 #define HAS_ESA
 #define HAS_TX3
 #define HAS_INTERTECHNO
@@ -59,6 +62,8 @@
 #define HAS_MORITZ
 
 #define BUSWARE_CSM
+
+//#define CUL_HW_REVISION "TuxRadio2"
 
 #endif
 
--- Devices/TuxRadio2/CSM.c Sat Sep 21 18:10:34 2013
+++ Devices/TuxRadio2/CSM.c Sun Jun 08 21:02:41 2014
@@ -36,7 +36,7 @@
 #include "rf_moritz.h"
 #endif
 
-#ifdef HAS_ASKSIN
+#if defined(HAS_ASKSIN) || defined(HAS_ASKSIN_PLL_HELPER) || defined(HAS_MS_TIMER0) || defined(HAS_MS_TIMER3)
 #include "rf_asksin.h"
 #endif
 
@@ -112,7 +112,11 @@
   // IR uses highspeed TIMER0 for sampling
   OCR0A  = 1;                              // Timer0: 0.008s = 8MHz/256/2   == 15625Hz
 #else
-  OCR0A  = 249;                            // Timer0: 0.008s = 8MHz/256/250 == 125Hz
+#if defined(HAS_MS_TIMER0) && !defined(HAS_MS_TIMER3)
+  OCR0A  = 124; // Timer0: 0.004s = 8MHz/256/125 interrupt clock
+#else
+  OCR0A  = 249; // Timer0: 0.008s = 8MHz/256/250 interrupt clock
+#endif
 #endif
   TCCR0B = _BV(CS02);
   TCCR0A = _BV(WGM01);
@@ -121,6 +125,16 @@
   TCCR1A = 0;
   TCCR1B = _BV(CS11) | _BV(WGM12);         // Timer1: 1us = 8MHz/8
 
+#ifdef HAS_MS_TIMER3
+  uint8_t sreg = SREG;
+  cli();
+  OCR3A = 999; // 999 -> Timer3: 1ms = 8MHz/8/1000 interrupt clock
+  SREG = sreg;
+  TCCR3A = 0;
+  TCCR3B = _BV(CS31) | _BV(WGM32); // Timer3: 1us = 8MHz/8 base clock
+  TIMSK3 = _BV(OCIE3A);
+#endif
+
 
   MCUSR &= ~(1 << WDRF);                   // Enable the watchdog
   wdt_enable(WDTO_2S);
@@ -168,6 +182,9 @@
 #endif
 #ifdef HAS_MORITZ
     rf_moritz_task();
+#endif
+#ifdef HAS_ASKSIN_PLL_HELPER
+    rf_asksin_check_PLL_task();
 #endif
 
   }
--- Devices/zCSM/board.h Fri Apr 12 16:03:32 2013
+++ Devices/zCSM/board.h Sun Jun 08 20:55:54 2014
@@ -51,6 +51,9 @@
 #define HAS_RAWSEND                   //
 #define HAS_FASTRF                    // PROGMEM:  468b  RAM:  1b
 #define HAS_ASKSIN
+//#define HAS_MS_TIMER3 // RAM: +5b noansi: Timer3 for ms timestamp counter in asksin.c
+#define HAS_MS_TIMER0 // RAM: +5b noansi: Timer0 for ms timestamp counter in asksin.c, 4ms (IR 8ms) increment
+#define HAS_ASKSIN_PLL_HELPER // RAM: +1b noansi: check for PLL Lock and try recalibration, if not
 #define HAS_MORITZ
 #define HAS_ESA
 #define HAS_INTERTECHNO
@@ -64,5 +67,7 @@
 #define TTY_BUFSIZE             128
 
 #define BUSWARE_CSM
+
+//#define CUL_HW_REVISION "zCSM"
 
 #endif
--- Devices/zCSM/CSM.c Fri Apr 12 16:03:32 2013
+++ Devices/zCSM/CSM.c Sun Jun 08 20:56:56 2014
@@ -40,7 +40,7 @@
 #include "intertechno.h"
 #endif
 
-#ifdef HAS_ASKSIN
+#if defined(HAS_ASKSIN) || defined(HAS_ASKSIN_PLL_HELPER) || defined(HAS_MS_TIMER0) || defined(HAS_MS_TIMER3)
 #include "rf_asksin.h"
 #endif
 
@@ -148,7 +148,11 @@
   // IR uses highspeed TIMER0 for sampling
   OCR0A  = 1;                              // Timer0: 0.008s = 8MHz/256/2   == 15625Hz
 #else
-  OCR0A  = 249;                            // Timer0: 0.008s = 8MHz/256/250 == 125Hz
+#if defined(HAS_MS_TIMER0) && !defined(HAS_MS_TIMER3)
+  OCR0A  = 124; // Timer0: 0.004s = 8MHz/256/125 interrupt clock
+#else
+  OCR0A  = 249; // Timer0: 0.008s = 8MHz/256/250 interrupt clock
+#endif
 #endif
   TCCR0B = _BV(CS02);
   TCCR0A = _BV(WGM01);
@@ -157,6 +161,16 @@
   TCCR1A = 0;
   TCCR1B = _BV(CS11) | _BV(WGM12);         // Timer1: 1us = 8MHz/8
 
+#ifdef HAS_MS_TIMER3
+  uint8_t sreg = SREG;
+  cli();
+  OCR3A = 999; // 999 -> Timer3: 1ms = 8MHz/8/1000 interrupt clock
+  SREG = sreg;
+  TCCR3A = 0;
+  TCCR3B = _BV(CS31) | _BV(WGM32); // Timer3: 1us = 8MHz/8 base clock
+  TIMSK3 = _BV(OCIE3A);
+#endif
+
   clock_prescale_set(clock_div_1);
 
   MCUSR &= ~(1 << WDRF);                   // Enable the watchdog
@@ -205,6 +219,9 @@
 #endif
 #ifdef HAS_MORITZ
     rf_moritz_task();
+#endif
+#ifdef HAS_ASKSIN_PLL_HELPER
+    rf_asksin_check_PLL_task();
 #endif
 
   }

--- Ende Code ---

noansi:
Hallo Rudolf,


wie Du vermutlich bemerkst, habe ich nicht nur die TimeStamp Option eingebaut, sondern auch meinen PLL lock check und recover als Task (so weit er in den Speicher passt). Den ms TimeStamp counter habe ich als board Option ebenfalls allgemein eingebaut, falls es jemand brauchen kann.

Außerdem habe ich Änderungen am cdcLUFA CDC_Task vorgenommen. Irgenwas ist meinem Gefühl nach da noch nicht richtig mit dem USB Handling oder TTY Buffer Handling.
Ich sehe es doch richtig, dass der auch im USB Interrupt ausgeführt wird? Daher einige Bemühungen, es sicherer gegen eine zweiten Interrupt bedingten Aufruf zumachen. Da hat auch schon jemand in der Richtung gearbeitet.
Zur Stabilität hat es beigetragen und hoffentlich keine Nebenwirkungen beim Empfang.
Allerdings kommt es immer noch vor, dass "unknown command" vom CUL kommt. Ich hatte in vorherigen Versionen auch den Zustand, dass merkwürdige Zeitstempel oder ganz falsche Zeichen zurück kamen, was sich alles danach anfühlt, als ob sich da irgend was überholt.

Vielleicht hat ja jemand noch einen Tip für mich. Ich sehe jedenfalls spontan nicht, was das mit der Timestamp Option zu tun haben soll, außer, dass mit jedem Empfangstelegramm 12 Bytes mehr an den USB-Host (Zentrale) gesendet werden müssen.

Die Änderung in display.c bezügich der HEX Wandlung und Wechsel von int8_t zu uint8_t hat noch ein paar bytes gebracht, was für CUL_V2 interessant sein kann.

Ich habe die Änderungen in alle Hardwarezweige mit HAS_ASKSIN eingebaut, allerdings bisher nur CUL und COC compiliert und mit CUL_V3 und COC im Test.


Gruß, Ansgar.

noansi:
Hallo Rudolf,

und hier noch die Kurzbeschreibung zu den zusätzlichen A Befehlen:

- t<x>   Enable (x=1) or disable (x=0) TimeStamp mode. Messages ar sent in the form: iiiittttttttaa*

    iiii - ID= FF01
    tttttttt - TimeStamp of reception in ms (but 4ms / 8ms)
    aa* - a normal AskSin message like if TimeStamp mode is disabled

- pmm*   Request a ping answer in TimeStamp mode. mm* is send back in the message.

    The Ping puts FF02 as ID in front of the message. So the form is: iiiittttttttllmm*rr

    iiii - ID= FF02
    tttttttt - TimeStamp of reception in ms (but 4ms / 8ms)
    ll - length of mm* in bytes (so half the number of digits sent). Be carefull not to flood the buffers!
    mm* - the message sent with the ping
    rr - fixed rssi value of (-138)

   Ping is only valid, if TimeStamp mode is switched on (once with At1).

- P<x>   Disable (x=1) or enable (x=0) PLL Lock error messages.

Bei einem unbekannten A Kommando, oder wenn es gerade nicht zulässig ist, wird A?\r\n zurück geliefert. Es wird nur noch mit Ax der AskSin Modus abgeschaltet.

Gruß, Ansgar.

tpm88:
Hallo,

ich habe in meiner Installation (FritzBox 7390 mit CUL) die Erweiterungen der CUL Firmware von noansi / Ansgar  (Register PLLNOLOCK und Timing für CUL) zusammen mit der für das Timing erweiterteten 00_CUL.pm von Martin getestet.

Beide Features haben bei mir die Stabilität HM Kommunikation deutlich verbessert - Details siehe hier: http://forum.fhem.de/index.php/topic,23223.msg175978.html#msg175978

Ich würde mich freuen, wenn die Erweiterungen in den Standard einfliessen würden.

Tobias

Navigation

[0] Themen-Index

[#] Nächste Seite

Zur normalen Ansicht wechseln