Esempio n. 1
0
static void write_register(uint8_t r, uint8_t value)
{
    /* Save old radio state */
    uint8_t old_state = radio_state;

    /* Wake up from WOR/RX (if in WOR/RX, else no effect) */
    cc110x_wakeup_from_rx();
    cc110x_write_reg(r, value);

    /* Have to put radio back to WOR/RX if old radio state
     * was WOR/RX, otherwise no action is necessary */
    if((old_state == RADIO_WOR) || (old_state == RADIO_RX)) {
        cc110x_switch_to_rx();
    }
}
Esempio n. 2
0
/*---------------------------------------------------------------------------*
 * 								Radio Driver API                             *
 *---------------------------------------------------------------------------*/
void cc110x_init(int tpid)
{
    transceiver_pid = tpid;
    DEBUG("Transceiver PID: %i\n", transceiver_pid);

    rx_buffer_next = 0;

#ifdef MODULE_CC110X_SPI
    /* Initialize SPI */
    cc110x_spi_init();
#endif

    /* Load driver & reset */
    power_up_reset();

    /* Write configuration to configuration registers */
    cc110x_writeburst_reg(0x00, cc110x_conf, CC1100_CONF_SIZE);

    /* Write PATABLE (power settings) */
    cc110x_write_reg(CC1100_PATABLE, pa_table[pa_table_index]);

    /* Initialize Radio Flags */
    rflags._RSSI         = 0x00;
    rflags.LL_ACK       = 0;
    rflags.CAA          = 0;
    rflags.CRC_STATE    = 0;
    rflags.SEQ          = 0;
    rflags.MAN_WOR      = 0;
    rflags.KT_RES_ERR   = 0;
    rflags.TX           = 0;
    rflags.WOR_RST      = 0;

    /* Set default channel number */
#ifdef MODULE_CONFIG
    cc110x_set_config_channel(sysconfig.radio_channel);
#else
    cc110x_set_channel(CC1100_DEFAULT_CHANNR);
#endif
    DEBUG("CC1100 initialized and set to channel %i\n", radio_channel);

    /* Switch to desired mode (WOR or RX) */
    rd_set_mode(RADIO_MODE_ON);

#ifdef DBG_IGNORE
    cc110x_init_ignore();
#endif
}
Esempio n. 3
0
void cc110x_rx_handler(void) {
    uint8_t res = 0;

	// Possible packet received, RX -> IDLE (0.1 us)
	rflags.CAA      = 0;
	rflags.MAN_WOR  = 0;
	cc110x_statistic.packets_in++;

	res = receive_packet((uint8_t*)&(cc110x_rx_buffer[rx_buffer_next].packet), sizeof(cc110x_packet_t));
	if (res) {
        // If we are sending a burst, don't accept packets.
		// Only ACKs are processed (for stopping the burst).
		// Same if state machine is in TX lock.
		if (radio_state == RADIO_SEND_BURST || rflags.TX)
		{
			cc110x_statistic.packets_in_while_tx++;
			return;
		}

        cc110x_rx_buffer[rx_buffer_next].rssi = rflags._RSSI;
        cc110x_rx_buffer[rx_buffer_next].lqi = rflags._LQI;
		cc110x_strobe(CC1100_SFRX);		// ...for flushing the RX FIFO

		// Valid packet. After a wake-up, the radio should be in IDLE.
		// So put CC1100 to RX for WOR_TIMEOUT (have to manually put
		// the radio back to sleep/WOR).
		//cc110x_spi_write_reg(CC1100_MCSM0, 0x08);	// Turn off FS-Autocal
		cc110x_write_reg(CC1100_MCSM2, 0x07);	// Configure RX_TIME (until end of packet)
        cc110x_strobe(CC1100_SRX);
        hwtimer_wait(IDLE_TO_RX_TIME);
        radio_state = RADIO_RX;
        
#ifdef DBG_IGNORE
        if (is_ignored(cc110x_rx_buffer[rx_buffer_next].packet.phy_src)) {
            LED_RED_TOGGLE;
            return;
        }
#endif

        /* notify transceiver thread if any */
        if (transceiver_pid) {
            msg_t m;  
            m.type = (uint16_t) RCV_PKT_CC1100;
            m.content.value = rx_buffer_next;
            msg_send_int(&m, transceiver_pid);
        }

        /* shift to next buffer element */
        if (++rx_buffer_next == RX_BUF_SIZE) {
            rx_buffer_next = 0;
        }
        return;
    }
	else
	{
		// No ACK received so TOF is unpredictable
		rflags.TOF = 0;

		// CRC false or RX buffer full -> clear RX FIFO in both cases
		cc110x_strobe(CC1100_SIDLE);	// Switch to IDLE (should already be)...
		cc110x_strobe(CC1100_SFRX);		// ...for flushing the RX FIFO

		// If packet interrupted this nodes send call,
		// don't change anything after this point.
		if (radio_state == RADIO_AIR_FREE_WAITING)
		{
			cc110x_strobe(CC1100_SRX);
			hwtimer_wait(IDLE_TO_RX_TIME);
			return;
		}
		// If currently sending, exit here (don't go to RX/WOR)
		if (radio_state == RADIO_SEND_BURST)
		{
			cc110x_statistic.packets_in_while_tx++;
			return;
		}

		// No valid packet, so go back to RX/WOR as soon as possible
		cc110x_switch_to_rx();
	}
}
Esempio n. 4
0
void cc110x_setup_rx_mode(void)
{
    /* Stay in RX mode until end of packet */
    cc110x_write_reg(CC1100_MCSM2, 0x07);
    cc110x_switch_to_rx();
}
Esempio n. 5
0
void cc110x_rx_handler(void *args)
{
    uint8_t res = 0;

    /* Possible packet received, RX -> IDLE (0.1 us) */
    cc110x_statistic.packets_in++;

    res = receive_packet((uint8_t *)&(cc110x_rx_buffer[rx_buffer_next].packet),
            sizeof(cc110x_packet_t));

    if (res) {
        /* If we are sending a burst, don't accept packets.
         * Only ACKs are processed (for stopping the burst).
         * Same if state machine is in TX lock. */
        if (radio_state == RADIO_SEND_BURST) {
            cc110x_statistic.packets_in_while_tx++;
            return;
        }

        cc110x_rx_buffer[rx_buffer_next].rssi = rflags._RSSI;
        cc110x_rx_buffer[rx_buffer_next].lqi = rflags._LQI;
        cc110x_strobe(CC1100_SFRX);     /* ...for flushing the RX FIFO */

        /* Valid packet. After a wake-up, the radio should be in IDLE.
         * So put CC110x to RX for WOR_TIMEOUT (have to manually put
         * the radio back to sleep/WOR). */
        cc110x_write_reg(CC1100_MCSM2, 0x07);   /* Configure RX_TIME (until end of packet) */
        cc110x_strobe(CC1100_SRX);
        hwtimer_wait(IDLE_TO_RX_TIME);
        radio_state = RADIO_RX;

#ifdef MODULE_TRANSCEIVER
        /* notify transceiver thread if any */
        if (transceiver_pid != KERNEL_PID_UNDEF) {
            msg_t m;
            m.type = (uint16_t) RCV_PKT_CC1100;
            m.content.value = rx_buffer_next;
            msg_send_int(&m, transceiver_pid);
        }
#endif

#ifdef MODULE_NETDEV_BASE
        if (cc110x_recv_cb != NULL) {
            cc110x_packet_t p = cc110x_rx_buffer[rx_buffer_next].packet;
            cc110x_recv_cb(&cc110x_dev, &p.phy_src, sizeof(uint8_t), &p.address,
                    sizeof(uint8_t), p.data, p.length - CC1100_HEADER_LENGTH);
        }
#endif

        /* shift to next buffer element */
        if (++rx_buffer_next == RX_BUF_SIZE) {
            rx_buffer_next = 0;
        }

        return;
    }
    else {
        /* CRC false or RX buffer full -> clear RX FIFO in both cases */
        cc110x_strobe(CC1100_SIDLE);    /* Switch to IDLE (should already be)... */
        cc110x_strobe(CC1100_SFRX);     /* ...for flushing the RX FIFO */

        /* If currently sending, exit here (don't go to RX/WOR) */
        if (radio_state == RADIO_SEND_BURST) {
            cc110x_statistic.packets_in_while_tx++;
            return;
        }

        /* No valid packet, so go back to RX/WOR as soon as possible */
        cc110x_switch_to_rx();
    }
}