Esempio n. 1
0
void nrf24l01p::rxMode()
{
  setCeLow();
  writeRegister(CONFIG, _BV(EN_CRC) | _BV(CRCO));	// Enable CRC (2bytes)
  delayMicroseconds(100);
  writeRegister(EN_AA, 0x00);		// Disable auto acknowledgment
  writeRegister(EN_RXADDR, 0x01);	// Enable first data pipe
  writeRegister(SETUP_AW, 0x03);	// 5 bytes address
  writeRegister(SETUP_RETR, 0xFF);	// 15 retransmit, 4000us pause
  writeRegister(RF_CH, 0x00);		// channel 8
  setBitrate(NRF24L01_BR_250K);
  setPower(mPower);
  writeRegister(STATUS, 0x70);		// Clear status register
  writeRegister(RX_PW_P0, 0x0A);	// RX payload of 10 bytes
  writeRegister(FIFO_STATUS, 0x00);	// Nothing useful for write command
  delay(50);
  flushTx();
  flushRx();
  delayMicroseconds(100);
  writeRegister(CONFIG, _BV(EN_CRC) | _BV(CRCO) | _BV(PWR_UP)  );
  delayMicroseconds(100);
  writeRegister(CONFIG, _BV(EN_CRC) | _BV(CRCO) | _BV(PWR_UP) | _BV(PRIM_RX) );
  delayMicroseconds(130);
  setCeHigh();
  delayMicroseconds(100);
}
Esempio n. 2
0
void Nrf24l::send(uint8_t * value) 
// Sends a data package to the default address. Be sure to send the correct
// amount of bytes as configured as payload on the receiver.
{
	uint8_t status;
	status = getStatus();

	while (PTX) {
		status = getStatus();

		if((status & ((1 << TX_DS)  | (1 << MAX_RT)))){
			PTX = 0;
			break;
		}
	}                  // Wait until last paket is send

	ceLow();

	powerUpTx();       // Set to transmitter mode , Power up
	flushTx();

	nrfSpiWrite(W_TX_PAYLOAD, value, false, payload);   // Write payload

	ceHi();                     // Start transmission
	ceLow();
}
Esempio n. 3
0
void Nrf24l::powerDown(){
	ceLow();

	configRegister(CONFIG, baseConfig);

	flushRx();
	flushTx();
}
Esempio n. 4
0
int nRF24L01::reset()
{
    flushTx();
    flushRx();
    uint8_t status1 = strobe(NRF24L01_FF_NOP);
    uint8_t status2 = readReg(NRF24L01_07_STATUS);
    setTxRxMode(TXRX_OFF);
#ifdef EMULATOR
    return 1;
#endif
    return (status1 == status2 && (status1 & 0x0f) == 0x0e);
}
Esempio n. 5
0
void QRF24::startListening()
{
    writeRegister(CONFIG, readRegister(CONFIG) | _BV(PWR_UP) | _BV(PRIM_RX));
    writeRegister(STATUS, _BV(RX_DR) | _BV(TX_DS) | _BV(MAX_RT) );

    // Restore the pipe0 adddress, if exists
    if (pipe0_reading_address)
        writeRegister(RX_ADDR_P0, reinterpret_cast<const quint8*>(&pipe0_reading_address), 5);

    // Flush buffers
    flushRx();
    flushTx();

    // Go!
    bcm2835_gpio_write(ce_pin, HIGH);

    // wait for the radio to come up (130us actually only needed)
    delayMicroseconds(130);
}
void Radio_TxInit() {
	SPI_MasterInit();
	DDRB|=(1<<CSN)|(1<<CE);
	PORTB|=(1<<IRQ)|(1<<CSN);
	delay_ms(5); //settling time specified in the data sheet
	unsigned char oneByte[1]={0x72};
	unsigned char threeByte[3]={0x18, 0x04, 0x96};
	writeRegister(0x00, oneByte, 1); //set config reg to power up into tx mode
	oneByte[0]=0x01;
	writeRegister(0x03, oneByte, 1); //set address length to 3 bytes
	writeRegister(0x10, threeByte, 3); //set address of transmit to random number, in this case my birthday
	oneByte[0]=76;
	writeRegister(0x05, oneByte, 1); //set to channel 76
	oneByte[0]=0x00;
	writeRegister(0x01, oneByte, 1); //turn off Auto Acknowledge, one way communication okay if a few packets get dropped
	writeRegister(0x04, oneByte, 1); //turn off retransmit, not ideal for remote control
	oneByte[0]=0x01;
	writeRegister(0x1D, oneByte, 1); //enable W_TX_PAYLOAD_NOACK
	flushTx();
	PORTB|=(1<<CE);
}
Esempio n. 7
0
void NRF::SE8R01::configure(Configuration* config)
{
    NRF::SE8R01::Config configOff = { 0 };
    configOff.b.maskDataReceived = true;
    configOff.b.maskDataSent = true;
    configOff.b.maskMaxRetrans = true;
    writeReg(Reg_Config, &configOff, sizeof(configOff));
    flushTx();
    Status status = flushRx();
    writeReg(Reg_Status, &status, sizeof(status));

    writeReg(Reg_FeatureCtl, &config->featureCtl, sizeof(config->featureCtl));
    writeReg(Reg_AutoAckCtl, &config->autoAckCtl, sizeof(config->autoAckCtl));
    writeReg(Reg_RxPipeEnable, &config->rxPipeEnable, sizeof(config->rxPipeEnable));
    writeReg(Reg_AddressCtl, &config->addressCtl, sizeof(config->addressCtl));
    writeReg(Reg_RetransCtl, &config->retransCtl, sizeof(config->retransCtl));
    writeReg(Reg_RfChannel, &config->rfChannel, sizeof(config->rfChannel));
    writeReg(Reg_RfSetup, &config->rfSetup, sizeof(config->rfSetup));
    writeReg(Reg_DynLengthCtl, &config->dynLengthCtl, sizeof(config->dynLengthCtl));
    writeReg(Reg_Tuning, &config->tuning, sizeof(config->tuning));
    writeReg(Reg_GuardCtl, &config->guardCtl, sizeof(config->guardCtl));
    writeReg(Reg_Config, &config->config, sizeof(config->config));
}
Esempio n. 8
0
bool QRF24::write( const void* buf, quint8 len )
{
    bool result = false;

    // Begin the write
    startWrite(buf,len);

    // ------------
    // At this point we could return from a non-blocking write, and then call
    // the rest after an interrupt

    // Instead, we are going to block here until we get TX_DS (transmission completed and ack'd)
    // or MAX_RT (maximum retries, transmission failed).  Also, we'll timeout in case the radio
    // is flaky and we get neither.

    // IN the end, the send should be blocking.  It comes back in 60ms worst case, or much faster
    // if I tighted up the retry logic.  (Default settings will be 1500us.
    // Monitor the send
    quint8 observe_tx;
    quint8 status;
    uint32_t sent_at = millis();
    const unsigned long timeout = 500; //ms to wait for timeout

    do
    {
        status = readRegister(OBSERVE_TX,&observe_tx,1);

        if (debug)
            printf("%02X", observe_tx);
    }
    while( ! ( status & ( _BV(TX_DS) | _BV(MAX_RT) ) ) && ( millis() - sent_at < timeout ) );


    // The part above is what you could recreate with your own interrupt handler,
    // and then call this when you got an interrupt
    // ------------

    // Call this when you get an interrupt
    // The status tells us three things
    // * The send was successful (TX_DS)
    // * The send failed, too many retries (MAX_RT)
    // * There is an ack packet waiting (RX_DR)
    bool tx_ok, tx_fail;

    whatHappened(tx_ok,tx_fail,ack_payload_available);

    //printf("%u%u%u\r\n",tx_ok,tx_fail,ack_payload_available);

    result = tx_ok;
    if (debug)
        printf(result?"...OK.":"...Failed");

    // Handle the ack packet
    if ( ack_payload_available )
    {
        ack_payload_length = getDynamicPayloadSize();
        if (debug )
            printf("[AckPacket]/%d", ack_payload_length);
    }

    // Yay, we are done.

    // Power down
    powerDown();

    // Flush buffers (Is this a relic of past experimentation, and not needed anymore??)
    flushTx();

    return result;
}
Esempio n. 9
0
void QRF24::stopListening()
{
    bcm2835_gpio_write(ce_pin, LOW);
    flushTx();
    flushRx();
}
Esempio n. 10
0
bool QRF24::begin()
{
    debug = true;

    // Init BCM2835 chipset for talking with us
    if (!bcm2835_init())
        return false;

    // Initialise the CE pin of NRF24 (chip enable)
    bcm2835_gpio_fsel(ce_pin, BCM2835_GPIO_FSEL_OUTP);
    bcm2835_gpio_write(ce_pin, LOW);

    // used to drive custom I/O to trigger my logic analyser
    // bcm2835_gpio_fsel(GPIO_CTRL_PIN , BCM2835_GPIO_FSEL_OUTP);

    // start the SPI library:
    // Note the NRF24 wants mode 0, MSB first and default to 1 Mbps
    bcm2835_spi_setBitOrder(BCM2835_SPI_BIT_ORDER_MSBFIRST);
    bcm2835_spi_setDataMode(BCM2835_SPI_MODE0);

    // Set SPI bus Speed
    bcm2835_spi_setClockSpeed(spi_speed);

    // This initialize the SPI bus with
    // csn pin as chip select (custom or not)
    bcm2835_spi_begin(csn_pin);

    // wait 100ms
    delay(100);

    // Must allow the radio time to settle else configuration bits will not necessarily stick.
    // This is actually only required following power up but some settling time also appears to
    // be required after resets too. For full coverage, we'll always assume the worst.
    // Enabling 16b CRC is by far the most obvious case if the wrong timing is used - or skipped.
    // Technically we require 4.5ms + 14us as a worst case. We'll just call it 5ms for good measure.
    // WARNING: Delay is based on P-variant whereby non-P *may* require different timing.
    delay( 5 ) ;

    // Set 1500uS (minimum for 32B payload in ESB@250KBPS) timeouts, to make testing a little easier
    // WARNING: If this is ever lowered, either 250KBS mode with AA is broken or maximum packet
    // sizes must never be used. See documentation for a more complete explanation.
    //printf("write_register(%02X, %02X)\n", SETUP_RETR, (0b0100 << ARD) | (0b1111 << ARC));
    writeRegister(SETUP_RETR,(0b0100 << ARD) | (0b1111 << ARC));

    // Restore our default PA level
    setPALevel( RF24_PA_MAX ) ;

    // Determine if this is a p or non-p RF24 module and then
    // reset our data rate back to default value. This works
    // because a non-P variant won't allow the data rate to
    // be set to 250Kbps.
    if( setDataRate( RF24_250KBPS ) )
    {
        p_variant = true ;
    }

    // Then set the data rate to the slowest (and most reliable) speed supported by all
    // hardware.
    setDataRate( RF24_1MBPS ) ;

    // Initialize CRC and request 2-byte (16bit) CRC
    setCRCLength( RF24_CRC_16 ) ;

    // Disable dynamic payloads, to match dynamic_payloads_enabled setting
    writeRegister(DYNPD,0);

    // Reset current status
    // Notice reset and flush is the last thing we do
    writeRegister(STATUS,_BV(RX_DR) | _BV(TX_DS) | _BV(MAX_RT) );

    // Set up default configuration.  Callers can always change it later.
    // This channel should be universally safe and not bleed over into adjacent
    // spectrum.
    setChannel(76);

    // Flush buffers
    flushRx();
    flushTx();

    return true;
}