Beispiel #1
0
void
rf_router_init()
{
  rf_router_myid = erb(EE_RF_ROUTER_ID);
  rf_router_target = erb(EE_RF_ROUTER_ROUTER);
  if(rf_router_target) {
    tx_report = 0x21;
    set_txrestore();
  }
}
Beispiel #2
0
void
set_txreport(char *in)
{
  if(in[1] == 0) {              // Report Value
    DH2(tx_report);
    DU(credit_10ms, 5);
    DNL();
    return;
  }

  fromhex(in+1, &tx_report, 1);
  set_txrestore();
}
Beispiel #3
0
static void
rf_router_send(uint8_t addAddr)
{
#ifdef RFR_DEBUG
       if(RFR_Buffer.buf[5] == 'T') nr_t++;
  else if(RFR_Buffer.buf[5] == 'F') nr_f++;
  else if(RFR_Buffer.buf[5] == 'E') nr_e++;
  else if(RFR_Buffer.buf[5] == 'K') nr_k++;
  else if(RFR_Buffer.buf[5] == 'H') nr_h++;
  else                              nr_r++;
#endif

  uint8_t buf[7], l = 1;
  buf[0] = RF_ROUTER_PROTO_ID;
  if(addAddr) {
    tohex(rf_router_target, buf+1);
    tohex(rf_router_myid,   buf+3),
    buf[5] = 'U';
    l = 6;
  }
  rf_router_ping();           // 15ms
  ccInitChip(EE_FASTRF_CFG);  // 1.6ms
  my_delay_ms(3);             // 3ms: Found by trial and error

  CC1100_ASSERT;
  cc1100_sendbyte(CC1100_WRITE_BURST | CC1100_TXFIFO);
#ifdef RFR_USBECHO
  uint8_t nbuf = RFR_Buffer.nbytes;
#endif
  cc1100_sendbyte(RFR_Buffer.nbytes+l);
  for(uint8_t i = 0; i < l; i++)
    cc1100_sendbyte(buf[i]);
  while(RFR_Buffer.nbytes)
    cc1100_sendbyte(rb_get(&RFR_Buffer));
  CC1100_DEASSERT;
  ccTX();
  rb_reset(&RFR_Buffer); // needed by FHT_compress

  // Wait for the data to be sent
  uint8_t maxwait = 20;        // max 20ms
  while((cc1100_readReg(CC1100_TXBYTES) & 0x7f) && maxwait--)
    my_delay_ms(1);
  set_txrestore();
#ifdef RFR_USBECHO
#warning RFR USB DEBUGGING IS ACTIVE
  uint8_t odc = display_channel;
  display_channel = DISPLAY_USB;
  DC('.'); DU(nbuf, 2); DNL();
  display_channel = odc;
#endif
}
Beispiel #4
0
/* longPreamble is necessary for unsolicited messages to wakeup the receiver */
void
moritz_sendraw(uint8_t *dec, int longPreamble)
{
  uint8_t hblen = dec[0]+1;
  //1kb/s = 1 bit/ms. we send 1 sec preamble + hblen*8 bits
  uint32_t sum = (longPreamble ? 100 : 0) + (hblen*8)/10;
  if (credit_10ms < sum) {
    DS_P(PSTR("LOVF\r\n"));
    return;
  }
  credit_10ms -= sum;

  // in Moritz mode already?
  if(!moritz_on) {
    rf_moritz_init();
  }

  if(CC1100_READREG( CC1100_MARCSTATE ) != MARCSTATE_RX) { //error
    DC('Z');
    DC('E');
    DC('R');
    DC('R');
    DC('1');
    DH2(CC1100_READREG( CC1100_MARCSTATE ));
    DNL();
    rf_moritz_init();
    return;
  }

  /* We have to keep at least 20 ms of silence between two sends
   * (found out by trial and error). ticks runs at 125 Hz (8 ms per tick),
   * so we wait for 3 ticks.
   * This looks a bit cumbersome but handles overflows of ticks gracefully.
   */
  if(lastSendingTicks)
    while(ticks == lastSendingTicks || ticks == lastSendingTicks+1)
      my_delay_ms(1);

  /* Enable TX. Perform calibration first if MCSM0.FS_AUTOCAL=1 (this is the case) (takes 809μs)
   * start sending - CC1101 will send preamble continuously until TXFIFO is filled.
   * The preamble will wake up devices. See http://e2e.ti.com/support/low_power_rf/f/156/t/142864.aspx
   * It will not go into TX mode instantly if channel is not clear (see CCA_MODE), thus ccTX tries multiple times */
#ifdef CC_ID
  do {
    CCSTROBE(CC1100_STX);
  } while (CC1100_READREG(CC1100_MARCSTATE) != MARCSTATE_TX);
#else
  ccTX();
#endif
  if(CC1100_READREG( CC1100_MARCSTATE ) != MARCSTATE_TX) { //error
    DC('Z');
    DC('E');
    DC('R');
    DC('R');
    DC('2');
    DH2(CC1100_READREG( CC1100_MARCSTATE ));
    DNL();
    rf_moritz_init();
    return;
  }

  if(longPreamble) {
    /* Send preamble for 1 sec. Keep in mind that waiting for too long may trigger the watchdog (2 seconds on CUL) */
    for(int i=0;i<10;++i)
      my_delay_ms(100); //arg is uint_8, so loop
  }

  // send
  CC1100_ASSERT;
  cc1100_sendbyte(CC1100_WRITE_BURST | CC1100_TXFIFO);

  for(uint8_t i = 0; i < hblen; i++) {
    cc1100_sendbyte(dec[i]);
  }

  CC1100_DEASSERT;

  //Wait for sending to finish (CC1101 will go to RX state automatically
  //after sending
  uint8_t i;
  for(i=0; i< 200;++i) {
    if( CC1100_READREG( CC1100_MARCSTATE ) == MARCSTATE_RX)
      break; //now in RX, good
    if( CC1100_READREG( CC1100_MARCSTATE ) != MARCSTATE_TX)
      break; //neither in RX nor TX, probably some error
    my_delay_ms(1);
  }

  if(CC1100_READREG( CC1100_MARCSTATE ) != MARCSTATE_RX) { //error
    DC('Z');
    DC('E');
    DC('R');
    DC('R');
    DC('3');
    DH2(CC1100_READREG( CC1100_MARCSTATE ));
    DNL();
    rf_moritz_init();
  }

  if(!moritz_on) {
    set_txrestore();
  }
  lastSendingTicks = ticks;
}
Beispiel #5
0
void
asksin_send(char *in)
{
  uint8_t msg[MAX_ASKSIN_MSG];
  uint8_t ctl;
  uint8_t l;
  uint32_t ts1, ts2;

  uint8_t hblen = fromhex(in+1, msg, MAX_ASKSIN_MSG-1);

  if ((hblen-1) != msg[0]) {
//  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
  }

  ctl = msg[2];

  // "crypt"
  msg[1] = (~msg[1]) ^ 0x89;

  for (l = 2; l < msg[0]; l++)
    msg[l] = (msg[l-1] + 0xdc) ^ msg[l];
  
  msg[l] = msg[l] ^ ctl;

  // enable TX, wait for CCA
  get_timestamp(&ts1);
  do {
    CCSTROBE(CC1100_STX);
    if (CC1100_READREG(CC1100_MARCSTATE) != MARCSTATE_TX) {
      get_timestamp(&ts2);
      if (((ts2 > ts1) && (ts2 - ts1 > ASKSIN_WAIT_TICKS_CCA)) ||
          ((ts2 < ts1) && (ts1 + ASKSIN_WAIT_TICKS_CCA < ts2))) {
        DS_P(PSTR("ERR:CCA\r\n"));
        goto out;
      }
    }
  } while (CC1100_READREG(CC1100_MARCSTATE) != MARCSTATE_TX);

  if (ctl & (1 << 4)) { // BURST-bit set?
    // According to ELV, devices get activated every 300ms, so send burst for 360ms
    for(l = 0; l < 3; l++)
      my_delay_ms(120); // arg is uint_8, so loop
  } else {
  	my_delay_ms(10);
  }

  // send
  CC1100_ASSERT;
  cc1100_sendbyte(CC1100_WRITE_BURST | CC1100_TXFIFO);

  for(uint8_t i = 0; i < hblen; i++) {
    cc1100_sendbyte(msg[i]);
  }

  CC1100_DEASSERT;

  // wait for TX to finish
  while(CC1100_READREG( CC1100_MARCSTATE ) == MARCSTATE_TX)
    ;

out:
  if (CC1100_READREG( CC1100_MARCSTATE ) == MARCSTATE_TXFIFO_UNDERFLOW) {
      CCSTROBE( CC1100_SFTX  );
      CCSTROBE( CC1100_SIDLE );
      CCSTROBE( CC1100_SNOP  );
  }
  
  if(asksin_on) {
    do {
      CCSTROBE(CC1100_SRX);
    } while (CC1100_READREG(CC1100_MARCSTATE) != MARCSTATE_RX);
  } else {
    set_txrestore();
  }
}
Beispiel #6
0
void
rf_router_task(void)
{
  if(rf_router_status == RF_ROUTER_INACTIVE)
    return;

  uint8_t hsec = (uint8_t)ticks;

  if(rf_router_status == RF_ROUTER_GOT_DATA) {

    uint8_t len = cc1100_readReg(CC1100_RXFIFO);
    uint8_t proto = 0;

    if(len > 5) {
      rb_reset(&TTY_Rx_Buffer);
      CC1100_ASSERT;
      cc1100_sendbyte( CC1100_READ_BURST | CC1100_RXFIFO );
      proto = cc1100_sendbyte(0);
      while(--len)
        rb_put(&TTY_Rx_Buffer, cc1100_sendbyte(0));
      CC1100_DEASSERT;
    }
    set_txrestore();
    rf_router_status = RF_ROUTER_INACTIVE;

    if(proto == RF_ROUTER_PROTO_ID) {
      uint8_t id;
      if(fromhex(TTY_Rx_Buffer.buf, &id, 1) == 1 &&     // it is for us
         id == rf_router_myid) {

        if(TTY_Rx_Buffer.buf[4] == 'U') {               // "Display" the data
          while(TTY_Rx_Buffer.nbytes)                   // downlink: RFR->CUL
            DC(rb_get(&TTY_Rx_Buffer));
          DNL();

        } else {                                        // uplink: CUL->RFR
          TTY_Rx_Buffer.nbytes -= 4;                    // Skip dest/src bytes
          TTY_Rx_Buffer.getoff = 4;
          rb_put(&TTY_Rx_Buffer, '\n');
          input_handle_func(DISPLAY_RFROUTER);          // execute the command
        }

      } else {
        rb_reset(&TTY_Rx_Buffer);
      }
    }

  } else if(rf_router_status == RF_ROUTER_DATA_WAIT) {
    uint8_t diff = hsec - rf_router_hsec;
    if(diff > 7) {              // 3 (delay above) + 3 ( ((4+64)*8)/250kBaud )
      set_txrestore();
      rf_router_status = RF_ROUTER_INACTIVE;
    }

  } else if(rf_router_status == RF_ROUTER_SYNC_RCVD) {
    ccInitChip(EE_FASTRF_CFG);
    ccRX();
    rf_router_status = RF_ROUTER_DATA_WAIT;
    rf_router_hsec = hsec;

  } 
}
Beispiel #7
0
static void
it_send (char *in, uint8_t datatype) {	

    //while (rf_isreceiving()) {
      //_delay_ms(1);
    //}
	  int8_t i, j, k;

		LED_ON();

    #if defined (HAS_IRRX) || defined (HAS_IRTX) //Blockout IR_Reception for the moment
      cli(); 
    #endif
  
	// If NOT InterTechno mode
	if(!intertechno_on)  {
	#ifdef HAS_ASKSIN
		if (asksin_on) {
			restore_asksin = 1;
			asksin_on = 0;
			}
	#endif
	#ifdef HAS_MORITZ
		if(moritz_on) {
			restore_moritz = 1;
			moritz_on = 0;
		}
	#endif
	it_tunein();
	my_delay_ms(3);             // 3ms: Found by trial and error
    }
  	ccStrobe(CC1100_SIDLE);
  	ccStrobe(CC1100_SFRX );
  	ccStrobe(CC1100_SFTX );

	  ccTX();                       // Enable TX 
	
    int8_t sizeOfPackage = strlen(in)-1; // IT-V1 = 14, IT-V3 = 33, IT-V3-Dimm = 37
	  int8_t mode = 0; // IT V1
    //DU(sizeOfPackage, 3);
    if (sizeOfPackage == 33 || sizeOfPackage == 37) { 
      mode = 1; // IT V3
      
    }
		for(i = 0; i < it_repetition; i++)  {
      if (datatype == DATATYPE_IT) {
        if (mode == 1) {    
          send_IT_sync_V3();  
          send_IT_latch_V3();
        } else {
          // Sync-Bit for IT V1 send before package
          CC1100_SET_OUT;         // High
          my_delay_us(it_interval);
          CC1100_CLEAR_OUT;       // Low
          for(k = 0; k < 31; k++)  {
            my_delay_us(it_interval);
          }
        }
#ifdef HAS_HOMEEASY
      } else if (datatype == DATATYPE_HE) {
        send_IT_sync_HE(DATATYPE_HE);
      } else if (datatype == DATATYPE_HEEU) {
        send_IT_sync_HE(DATATYPE_HEEU);
#endif
      }
      uint8_t startCount = 1;
#ifdef HAS_HOMEEASY
      if (datatype == DATATYPE_HE || datatype == DATATYPE_HEEU) {
        startCount = 2;
      } 
#endif
		  for(j = startCount; j < sizeOfPackage; j++)  {
			  if(in[j+1] == '0') {
          if (datatype == DATATYPE_IT) {
            if (mode == 1) {
					    send_IT_bit_V3(0);
            } else {
					    send_IT_bit(0);
            }      
#ifdef HAS_HOMEEASY
          } else {
            send_IT_bit_HE(0, datatype);
#endif
          }
				} else if (in[j+1] == '1') {
          if (datatype == DATATYPE_IT) {
            if (mode == 1) {
					    send_IT_bit_V3(1);
            } else {
					    send_IT_bit(1);
            }
#ifdef HAS_HOMEEASY
          } else {
            send_IT_bit_HE(1, datatype);
#endif
          }
        } else if (in[j+1] == '2') {
          send_IT_bit_V3(2);
				} else {
          if (mode == 1) {
					  send_IT_bit_V3(3);
				  } else {
					  send_IT_bit(2);
				  }
			  }
			}
      //if (mode == 1) {  
      //  send_IT_sync_V3();
      //}
		} //Do it n Times
	
  	if(intertechno_on) {
			if(tx_report) {                               // Enable RX
	    	ccRX();
	  	} else {
		  	ccStrobe(CC1100_SIDLE);
			}
  	} 
  	#ifdef HAS_ASKSIN
   	  else if (restore_asksin) {
				restore_asksin = 0;
   			rf_asksin_init();
				asksin_on = 1;
   		 	ccRX();
  		}  
  	#endif
	#ifdef HAS_MORITZ
	else if (restore_moritz) {
		restore_moritz = 0;
		rf_moritz_init();
	}
	#endif
  	else {
    	set_txrestore();
  	}	

    #if defined (HAS_IRRX) || defined (HAS_IRTX) //Activate IR_Reception again
      sei(); 
    #endif		  

		LED_OFF();
	
		DC('i');DC('s');
#ifdef HAS_HOMEEASY
    if (datatype == DATATYPE_HE) {
      DC('h');
    } else if (datatype == DATATYPE_HEEU) {
      DC('e');
    }
#endif
		for(j = 1; j < sizeOfPackage; j++)  {
		 	if(in[j+1] == '0') {
				DC('0');
			} else if (in[j+1] == '1') {
				DC('1');
			} else if (in[j+1] == '2') {
				DC('2');
			} else {
        if (datatype == DATATYPE_IT) {
          if (mode == 1) {  
     				DC('D');
          } else {
				    DC('F');
          }
        }
			}
		}
		DNL();
}