Example #1
0
/*------------------------------------------------------------------------------------*/
static void switch_to_rx(transceiver_type_t t)
{
    switch (t) {
#if (defined(MODULE_CC110X) || defined(MODULE_CC110X_LEGACY))

        case TRANSCEIVER_CC1100:
            cc110x_switch_to_rx();
            break;
#endif
#ifdef MODULE_CC2420

        case TRANSCEIVER_CC2420:

            cc2420_switch_to_rx();
            break;
#endif
#ifdef MODULE_NATIVENET

        case TRANSCEIVER_NATIVE:
            nativenet_switch_to_rx();
            break;
#endif
#ifdef MODULE_AT86RF231

        case TRANSCEIVER_AT86RF231:
            at86rf231_switch_to_rx();
#endif

        default:
            break;
    }
}
Example #2
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();
    }
}
Example #3
0
static void finish(void)
{
    // back to idle
    cc110x_strobe(RF_SIDLE);
    radio_state = RADIO_IDLE;

    restore_conf();

    /* Have to put radio back to WOR/RX if old radio state
     * was WOR/RX, otherwise no action is necessary */
    if ((old_radio_state == RADIO_WOR) || (old_radio_state == RADIO_RX)) {
        cc110x_switch_to_rx();
    }

    radio_release();
    // restoreIRQ(cpsr);
}
Example #4
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();
	}
}
Example #5
0
char *cc110x_get_marc_state(void)
{
    uint8_t state;

    /* Save old radio state */
    uint8_t old_state = radio_state;

    /* Read content of status register */
    state = cc110x_read_status(CC1100_MARCSTATE) & MARC_STATE;

    /* Make sure in IDLE state.
     * Only goes to IDLE if state was RX/WOR */
    cc110x_wakeup_from_rx();

    /* 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();
    }

    switch(state) {
            /* Note: it is not possible to read back the SLEEP or XOFF state numbers 
             * because setting CSn low will make the chip enter the IDLE mode from the 
             * SLEEP (0) or XOFF (2) states. */
        case 1:
            return "IDLE";

        case 3:
        case 4:
        case 5:
            return "MANCAL";

        case 6:
        case 7:
            return "FS_WAKEUP";

        case 8:
        case 12:
            return "CALIBRATE";

        case 9:
        case 10:
        case 11:
            return "SETTLING";

        case 13:
        case 14:
        case 15:
            return "RX";

        case 16:
            return "TXRX_SETTLING";

        case 17:
            return "RXFIFO_OVERFLOW";

        case 18:
            return "FSTXON";

        case 19:
        case 20:
            return "TX";

        case 21:
            return "RXTX_SETTLING";

        case 22:
            return "TXFIFO_UNDERFLOW";

        default:
            return "UNKNOWN";
    }
}
Example #6
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();
}
Example #7
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();
    }
}