void cc1100_writeReg(uint8_t addr, uint8_t data) { CC1100_ASSERT; cc1100_sendbyte( addr|CC1100_WRITE_BURST ); cc1100_sendbyte( data ); CC1100_DEASSERT; }
void cc1100_writeReg2(uint8_t addr, uint8_t data, transceiver_t* device) { device->CS_base->PIO_CODR = (1<<device->CS_pin); //assert CS cc1100_sendbyte( addr|CC1100_WRITE_BURST ); cc1100_sendbyte( data ); device->CS_base->PIO_SODR = (1<<device->CS_pin); //deassert CS }
uint8_t cc1100_readReg2(uint8_t addr, transceiver_t* device) { device->CS_base->PIO_CODR = (1<<device->CS_pin); //assert CS cc1100_sendbyte( addr|CC1100_READ_BURST ); uint8_t ret = cc1100_sendbyte( 0 ); device->CS_base->PIO_SODR = (1<<device->CS_pin); //deassert CS return ret; }
//-------------------------------------------------------------------- uint8_t cc1100_readReg(uint8_t addr) { CC1100_ASSERT; cc1100_sendbyte( addr|CC1100_READ_BURST ); uint8_t ret = cc1100_sendbyte( 0 ); CC1100_DEASSERT; return ret; }
void rf_moritz_task(void) { uint8_t enc[MAX_MORITZ_MSG]; uint8_t rssi; if(!moritz_on) return; // see if a CRC OK pkt has been arrived if(bit_is_set( CC1100_IN_PORT, CC1100_IN_PIN )) { //errata #1 does not affect us, because we wait until packet is completely received enc[0] = CC1100_READREG( CC1100_RXFIFO ) & 0x7f; // read len if (enc[0]>=MAX_MORITZ_MSG) enc[0] = MAX_MORITZ_MSG-1; CC1100_ASSERT; cc1100_sendbyte( CC1100_READ_BURST | CC1100_RXFIFO ); for (uint8_t i=0; i<enc[0]; i++) { enc[i+1] = cc1100_sendbyte( 0 ); } // RSSI is appended to RXFIFO rssi = cc1100_sendbyte( 0 ); // And Link quality indicator, too /* LQI = */ cc1100_sendbyte( 0 ); CC1100_DEASSERT; moritz_handleAutoAck(enc); if (tx_report & REP_BINTIME) { DC('z'); for (uint8_t i=0; i<=enc[0]; i++) DC( enc[i] ); } else { DC('Z'); for (uint8_t i=0; i<=enc[0]; i++) DH2( enc[i] ); if (tx_report & REP_RSSI) DH2(rssi); DNL(); } return; } if(CC1100_READREG( CC1100_MARCSTATE ) == 17) { CCSTROBE( CC1100_SFRX ); CCSTROBE( CC1100_SIDLE ); CCSTROBE( CC1100_SRX ); } }
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 }
//-------------------------------------------------------------------- uint8_t ccStrobe(uint8_t strobe) { CC1100_ASSERT; uint8_t ret = cc1100_sendbyte( strobe ); CC1100_DEASSERT; return ret; }
void ccInitChip(uint8_t *cfg) { #ifdef HAS_MORITZ moritz_on = 0; //loading this configuration overwrites moritz cfg #endif #ifdef ARM AT91C_BASE_AIC->AIC_IDCR = 1 << CC1100_IN_PIO_ID; CC1100_CS_BASE->PIO_PPUER = _BV(CC1100_CS_PIN); //Enable pullup CC1100_CS_BASE->PIO_OER = _BV(CC1100_CS_PIN); //Enable output CC1100_CS_BASE->PIO_PER = _BV(CC1100_CS_PIN); //Enable PIO control #else EIMSK &= ~_BV(CC1100_INT); SET_BIT( CC1100_CS_DDR, CC1100_CS_PIN ); // CS as output #endif 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); CC1100_ASSERT; // load configuration cc1100_sendbyte( 0 | CC1100_WRITE_BURST ); for(uint8_t i = 0; i < EE_CC1100_CFG_SIZE; i++) { cc1100_sendbyte(erb(cfg++)); } CC1100_DEASSERT; uint8_t *pa = EE_CC1100_PA; CC1100_ASSERT; // setup PA table cc1100_sendbyte( CC1100_PATABLE | CC1100_WRITE_BURST ); for (uint8_t i = 0;i<8;i++) { cc1100_sendbyte(erb(pa++)); } CC1100_DEASSERT; ccStrobe( CC1100_SCAL ); my_delay_ms(1); }
uint8_t ccStrobe2(uint8_t strobe, transceiver_t* device) { device->CS_base->PIO_CODR = (1<<device->CS_pin); //assert CS uint8_t ret = cc1100_sendbyte( strobe ); CCtransceiver->CS_base->PIO_SODR = (1<<device->CS_pin); //deassert CS return ret; }
static void it_tunein(void) { int8_t i; #ifdef ARM AT91C_BASE_AIC->AIC_IDCR = 1 << AT91C_ID_PIOA; // disable INT - we'll poll... AT91C_BASE_PIOA->PIO_PPUER = _BV(CC1100_CS_PIN); //Enable pullup AT91C_BASE_PIOA->PIO_OER = _BV(CC1100_CS_PIN); //Enable output AT91C_BASE_PIOA->PIO_PER = _BV(CC1100_CS_PIN); //Enable PIO control #else EIMSK &= ~_BV(CC1100_INT); SET_BIT( CC1100_CS_DDR, CC1100_CS_PIN ); // CS as output #endif 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); CC1100_ASSERT; // load configuration cc1100_sendbyte( 0 | CC1100_WRITE_BURST ); for(uint8_t i = 0; i < 13; i++) { cc1100_sendbyte(__LPM(CC1100_ITCFG+i)); } // Tune to standard IT-Frequency cc1100_sendbyte(it_frequency[0]); // Modify Freq. for 433.92MHZ, or whatever cc1100_sendbyte(it_frequency[1]); cc1100_sendbyte(it_frequency[2]); for (i = 16; i<EE_CC1100_CFG_SIZE; i++) { cc1100_sendbyte(__LPM(CC1100_ITCFG+i)); } CC1100_DEASSERT; uint8_t *pa = EE_CC1100_PA; CC1100_ASSERT; // setup PA table cc1100_sendbyte( CC1100_PATABLE | CC1100_WRITE_BURST ); for (uint8_t i = 0;i<8;i++) { cc1100_sendbyte(erb(pa++)); } CC1100_DEASSERT; ccStrobe( CC1100_SCAL ); my_delay_ms(1); cc_on = 1; // Set CC_ON }
void it_tunein(void) { int8_t i; #ifdef USE_HAL hal_CC_GDO_init(CC_INSTANCE,INIT_MODE_OUT_CS_IN); hal_enable_CC_GDOin_int(CC_INSTANCE,FALSE); // disable INT - we'll poll... #else EIMSK &= ~_BV(CC1100_INT); SET_BIT( CC1100_CS_DDR, CC1100_CS_PIN ); // CS as output #endif 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); CC1100_ASSERT; // load configuration cc1100_sendbyte( 0 | CC1100_WRITE_BURST ); for(uint8_t i = 0; i < 13; i++) { cc1100_sendbyte(__LPM(CC1100_ITCFG+i)); } // Tune to standard IT-Frequency cc1100_sendbyte(it_frequency[0]); // Modify Freq. for 433.92MHZ, or whatever cc1100_sendbyte(it_frequency[1]); cc1100_sendbyte(it_frequency[2]); for (i = 16; i<EE_CC1100_CFG_SIZE; i++) { cc1100_sendbyte(__LPM(CC1100_ITCFG+i)); } CC1100_DEASSERT; uint8_t *pa = EE_CC1100_PA; CC1100_ASSERT; // setup PA table cc1100_sendbyte( CC1100_PATABLE | CC1100_WRITE_BURST ); for (uint8_t i = 0;i<8;i++) { cc1100_sendbyte(erb(pa++)); } CC1100_DEASSERT; ccStrobe( CC1100_SCAL ); my_delay_ms(1); #ifndef USE_RF_MODE cc_on = 1; // Set CC_ON #endif }
void ccInitChip (void) { GIMSK &= ~_BV (CC1100_INT); SET_BIT (CC1100_CS_DDR, CC1100_CS_PIN); // CS as output SET_BIT (CC1100_OUT_DDR, CC1100_OUT_PIN); // GDO0 as output CLEAR_BIT (CC1100_IN_DDR, CC1100_IN_PIN); // GDO2 as input CC1100_DEASSERT; // Toggle chip select signal _delay_us (30); CC1100_ASSERT; _delay_us (30); CC1100_DEASSERT; _delay_us (45); ccStrobe (CC1100_SRES); // Send SRES command _delay_us (100); CC1100_ASSERT; // load configuration cc1100_sendbyte (0 | CC1100_WRITE_BURST); for (uint8_t i = 0; i < EE_CC1100_CFG_SIZE; i++) { cc1100_sendbyte (CC1100_CFG[i]); } CC1100_DEASSERT; CC1100_ASSERT; // setup PA table cc1100_sendbyte (CC1100_PATABLE | CC1100_WRITE_BURST); for (uint8_t i = 0; i < CC1100_PA_SIZE; i++) { cc1100_sendbyte (CC1100_PA[i]); } CC1100_DEASSERT; ccStrobe (CC1100_SCAL); _delay_ms (1); }
/* 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; }
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; } }
void rf_moritz_init(void) { #ifdef ARM #ifndef CC_ID AT91C_BASE_AIC->AIC_IDCR = 1 << AT91C_ID_PIOA; // disable INT - we'll poll... #endif CC1100_CS_BASE->PIO_PPUER = _BV(CC1100_CS_PIN); //Enable pullup CC1100_CS_BASE->PIO_OER = _BV(CC1100_CS_PIN); //Enable output CC1100_CS_BASE->PIO_PER = _BV(CC1100_CS_PIN); //Enable PIO control #else EIMSK &= ~_BV(CC1100_INT); // disable INT - we'll poll... SET_BIT( CC1100_CS_DDR, CC1100_CS_PIN ); // CS as output #endif 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); #ifdef CC_ID CC1100_ASSERT; uint8_t *cfg = EE_CC1100_CFG; for(uint8_t i = 0; i < EE_CC1100_CFG_SIZE; i++) { cc1100_sendbyte(erb(cfg++)); } CC1100_DEASSERT; uint8_t *pa = EE_CC1100_PA; CC1100_ASSERT; // setup PA table cc1100_sendbyte( CC1100_PATABLE | CC1100_WRITE_BURST ); for (uint8_t i = 0;i<8;i++) { cc1100_sendbyte(erb(pa++)); } CC1100_DEASSERT; #endif // load configuration for (uint8_t i = 0; i<60; i += 2) { if (pgm_read_byte( &MORITZ_CFG[i] )>0x40) break; CC1100_WRITEREG( pgm_read_byte(&MORITZ_CFG[i]), pgm_read_byte(&MORITZ_CFG[i+1]) ); } CCSTROBE( CC1100_SCAL ); my_delay_ms(4); // 4ms: Found by trial and error //This is ccRx() but without enabling the interrupt uint8_t cnt = 0xff; //Enable RX. Perform calibration first if coming from IDLE and MCSM0.FS_AUTOCAL=1. //Why do it multiple times? while(cnt-- && (CCSTROBE( CC1100_SRX ) & 0x70) != 1) my_delay_us(10); moritz_on = 1; //todo check multiCC checkFrequency(); }
void rf_asksin_init(void) { #ifdef ARM #ifndef CC_ID AT91C_BASE_AIC->AIC_IDCR = 1 << CC1100_IN_PIO_ID; // disable INT - we'll poll... #endif CC1100_CS_BASE->PIO_PPUER = _BV(CC1100_CS_PIN); //Enable pullup CC1100_CS_BASE->PIO_OER = _BV(CC1100_CS_PIN); //Enable output CC1100_CS_BASE->PIO_PER = _BV(CC1100_CS_PIN); //Enable PIO control #else EIMSK &= ~_BV(CC1100_INT); // disable INT - we'll poll... SET_BIT( CC1100_CS_DDR, CC1100_CS_PIN ); // CS as output #endif 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); #ifdef CC_ID CC1100_ASSERT; uint8_t *cfg = EE_CC1100_CFG; for(uint8_t i = 0; i < EE_CC1100_CFG_SIZE; i++) { cc1100_sendbyte(erb(cfg++)); } CC1100_DEASSERT; uint8_t *pa = EE_CC1100_PA; CC1100_ASSERT; // setup PA table cc1100_sendbyte( CC1100_PATABLE | CC1100_WRITE_BURST ); for (uint8_t i = 0;i<8;i++) { cc1100_sendbyte(erb(pa++)); } CC1100_DEASSERT; #endif // 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 ); my_delay_ms(4); // enable RX, but don't enable the interrupt do { CCSTROBE(CC1100_SRX); } while (CC1100_READREG(CC1100_MARCSTATE) != MARCSTATE_RX); }
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(); } }
void rf_asksin_task(void) { uint8_t msg[MAX_ASKSIN_MSG]; uint8_t this_enc, last_enc; uint8_t rssi; uint8_t l; if(!asksin_on) return; // see if a CRC OK pkt has been arrived if (bit_is_set( CC1100_IN_PORT, CC1100_IN_PIN )) { msg[0] = CC1100_READREG( CC1100_RXFIFO ) & 0x7f; // read len if (msg[0] >= MAX_ASKSIN_MSG) { // Something went horribly wrong, out of sync? rf_asksin_reset_rx(); return; } CC1100_ASSERT; cc1100_sendbyte( CC1100_READ_BURST | CC1100_RXFIFO ); for (uint8_t i=0; i<msg[0]; i++) { msg[i+1] = cc1100_sendbyte( 0 ); } rssi = cc1100_sendbyte( 0 ); /* LQI = */ cc1100_sendbyte( 0 ); CC1100_DEASSERT; do { CCSTROBE(CC1100_SRX); } while (CC1100_READREG(CC1100_MARCSTATE) != MARCSTATE_RX); last_enc = msg[1]; msg[1] = (~msg[1]) ^ 0x89; for (l = 2; l < msg[0]; l++) { this_enc = msg[l]; msg[l] = (last_enc + 0xdc) ^ msg[l]; last_enc = this_enc; } msg[l] = msg[l] ^ msg[2]; if (tx_report & REP_BINTIME) { DC('a'); for (uint8_t i=0; i<=msg[0]; i++) DC( msg[i] ); } else { DC('A'); for (uint8_t i=0; i<=msg[0]; i++) DH2( msg[i] ); if (tx_report & REP_RSSI) DH2(rssi); DNL(); } } switch(CC1100_READREG( CC1100_MARCSTATE )) { case MARCSTATE_RXFIFO_OVERFLOW: CCSTROBE( CC1100_SFRX ); case MARCSTATE_IDLE: CCSTROBE( CC1100_SIDLE ); CCSTROBE( CC1100_SNOP ); CCSTROBE( CC1100_SRX ); break; } #ifdef HAS_CC1101_RX_PLL_LOCK_CHECK_TASK_WAIT CC1101_RX_CHECK_PLL_WAIT_TASK(); #endif }
void native_task(void) { uint8_t len, byte, i; if(!native_on) return; // wait for CC1100_FIFOTHR given bytes to arrive in FIFO: if (bit_is_set( CC1100_IN_PORT, CC1100_IN_PIN )) { // start over syncing ccStrobe( CC1100_SIDLE ); len = cc1100_readReg( CC1100_RXBYTES ) & 0x7f; // read len, transfer RX fifo if (len) { CC1100_ASSERT; cc1100_sendbyte( CC1100_READ_BURST | CC1100_RXFIFO ); DC( 'N' ); DH2(native_on); for (i=0; i<len; i++) { byte = cc1100_sendbyte( 0 ); #if defined(LACROSSE_HMS_EMU) if (i<sizeof(payload)) payload[i] = byte; #endif DH2( byte ); } CC1100_DEASSERT; DNL(); #ifdef LACROSSE_HMS_EMU if (len>=5) dec2hms_lacrosse(payload); #endif } return; } switch (cc1100_readReg( CC1100_MARCSTATE )) { // RX_OVERFLOW case 17: // IDLE case 1: ccStrobe( CC1100_SFRX ); ccStrobe( CC1100_SIDLE ); ccStrobe( CC1100_SNOP ); ccStrobe( CC1100_SRX ); break; } }
// Transmitt data block for Kopp Free Control // ------------------------------------------------------------------------------------------------------------------------------------------ void TransmittKoppBlk(uint8_t sendmsg01[15], uint8_t blkTXcode_i) { // Read Blockcounter from Config File Datei (RAMDISK) // -------------------------------------------------- uint8_t blkcks = 0x0; int count = 0; int count2 = 1; //count2 = 1; // each block / telegram will be written n times (n = 13 see below) sendmsg01[3] = blkctr; // Write BlockCounter (was incremented) and Transmitt Code (=Transmitter Key) to Array sendmsg01[4] = blkTXcode_i; // ----------------------------------------------------------------------------------- // Send Block via Transmitter Fifo // -------------------------------- do { ccTX(); // initialize CC110x TX Mode? if(cc1100_readReg( CC1100_MARCSTATE ) != MARCSTATE_TX) // If Statemachine not MARCSTATE_TX -> error { DS_P(PSTR("TX_INIT_ERR_")); DH2(cc1100_readReg( CC1100_MARCSTATE )); DNL(); kopp_fc_init(); return; } BlockStartTime = ticks; // remember Start Time (1 tick=8msec, s.o.) blkcks=0xaa; // Checksumme initialisieren count=0; // CC1100_ASSERT; // Chip Select Activ cc1100_sendbyte(CC1100_WRITE_BURST | CC1100_TXFIFO); // Burst Mode via Fifo // Now send ! do { // =========== cc1100_sendbyte(sendmsg01[count]); // write date to fifo (fifo is big enough) if (count <= 8) // { blkcks=blkcks^sendmsg01[count]; // if (count==7) sendmsg01[8]=blkcks; // write ckecksum to Buffer as soon as calculated } // // count++; // } while(count < MAX_kopp_fc_MSG); // Transmitt Byte 0 - AmountofBytes CC1100_DEASSERT; // Chip Select InActiv //Wait for sending to finish (CC1101 will go to RX state automatically uint8_t i; for(i=0; i< 200;++i) { // if( cc1100_readReg( CC1100_MARCSTATE ) == MARCSTATE_RX) // Claus: After transmission we force idle, always, so RX will not happen // 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); } // Claus: Test shows i is ~ 0x36, but why so fast??, transmission should need about 25msec (15Bytes*8Bits*4800Bit/sec) // may be reading status via SPI is also also slow? // DS_P(PSTR("variable i: ")); // For test only // DH((uint16_t) (i),4); // For test only // DS_P(PSTR("\r\n")); // For test only count2++; } while(count2 <= 13); // send same message 13x blkctr++; // increase Blockcounter }
void kopp_fc_init(void) { #ifdef ARM AT91C_BASE_AIC->AIC_IDCR = 1 << CC1100_IN_PIO_ID; // disable INT - we'll poll... CC1100_CS_BASE->PIO_PPUER = _BV(CC1100_CS_PIN); //Enable pullup CC1100_CS_BASE->PIO_OER = _BV(CC1100_CS_PIN); //Enable output CC1100_CS_BASE->PIO_PER = _BV(CC1100_CS_PIN); //Enable PIO control #else EIMSK &= ~_BV(CC1100_INT); // disable INT - we'll poll... SET_BIT( CC1100_CS_DDR, CC1100_CS_PIN ); // CS as output #endif // Toggle chip select signal (why?) CC1100_DEASSERT; // Chip Select InActiv my_delay_us(30); CC1100_ASSERT; // Chip Select Activ my_delay_us(30); CC1100_DEASSERT; // Chip Select InActiv my_delay_us(45); ccStrobe( CC1100_SRES ); // Send SRES command (Reset CC110x) my_delay_us(100); // load configuration (CC1100_Kopp_CFG[EE_CC1100_CFG_SIZE]) CC1100_ASSERT; // Chip Select Activ cc1100_sendbyte( 0 | CC1100_WRITE_BURST ); for(uint8_t i = 0; i < EE_CC1100_CFG_SIZE; i++) { cc1100_sendbyte(__LPM(CC1100_Kopp_CFG+i)); } CC1100_DEASSERT; // Chip Select InActiv // If I don't missunderstand the code, in module cc1100.c the pa table is defined as // 00 and C2 what means power off and max. power. // so following code (setup PA table) is not needed ? // did a trial, but does not work // setup PA table (-> Remove as soon as transmitting ok?), table see cc1100.c // this initializes the PA table with the table defined at EE_Prom // which table will be taken depends on command "x00 .... x09" // x00 means -10dbm pa ramping // x09 means +10dBm no pa ramping (see cc1100.c) and commandref.html #ifdef PrintOn // DS_P(PSTR("PA Table values: ")); #endif uint8_t *pa = EE_CC1100_PA; // EE_CC1100_PA+32 means max power??? CC1100_ASSERT; cc1100_sendbyte( CC1100_PATABLE | CC1100_WRITE_BURST); for (uint8_t i = 0; i < 8; i++) { #ifdef PrintOn // DU(erb(pa),0); // ### Claus, mal sehen was im PA Table steht DS_P(PSTR(" ")); #endif cc1100_sendbyte(erb(pa++)); // fncollection.c "erb()"gibt einen EEPROM Wert zurück } #ifdef PrintOn DS_P(PSTR("\r\n")); #endif CC1100_DEASSERT; // Set CC_ON ccStrobe( CC1100_SCAL); // Calibrate Synthesizer and turn it of. ##Claus brauchen wir das my_delay_ms(1); cc_on = 1; kopp_fc_on = 1; //##Claus may be not needed in future (Tx Only) checkFrequency(); }