Esempio n. 1
0
static uint16_t tx_delay(void) {
    if (delay_count==0) {
        // if first try, quick
        timerB_set_alarm_from_now(ALARM_RETRY, 2, 0);
        timerB_register_cb(ALARM_RETRY, tx_try);
    } else if (delay_count >= DELAY_COUNT_MAX) {
        // to many tries, abort
        // delete packet
        txframe.length = 0;
        // reset callback
        cc1101_gdo0_register_callback(rx_parse);

        // reset rx
        cc1101_cmd_idle();
        rx_set();
        PRINTF("too many tries\n");
        // call the error callback
        if (error_cb) {
            return error_cb();
        }
    } else {
        uint16_t delay;
        // delay randomly between 1ms and 63ms
        delay = rand();
        delay &= ((1<<11)-1);
        delay += 32;

        timerB_set_alarm_from_now(ALARM_RETRY, delay, 0);
        timerB_register_cb(ALARM_RETRY, tx_try);
    }
    delay_count ++;

    return 0;
}
Esempio n. 2
0
File: adc.c Progetto: EDAyele/wsn430
static void vADCInit(void) {
	uint16_t period;

	// Configure GPIO1 (P2.3) as output and high, as a voltage reference
	P2SEL &= ~BV(3);
	P2DIR |= BV(3);
	P2OUT |= BV(3);

	// Reset frame
	data_frame.length = 0;
	data_frame.seq = 0;

	// Start the timer
	period = MS_TO_TICKS(10);
	timerB_set_alarm_from_now(TIMERB_ALARM_CCR6, period, period);
	timerB_register_cb(TIMERB_ALARM_CCR6, measure_time);

	/* Configure ADC pins for analog input */
	P6SEL |= BV(0) | BV(1) | BV(3) | BV(4) | BV(6) | BV(7);
	P6DIR &= ~(BV(0) | BV(1) | BV(3) | BV(4) | BV(6) | BV(7));

	/* 38us sampling, internal reference 1.5V */
	ADC12CTL0 = SHT0_7 | MSC | REFON | REF2_5V | ADC12ON;

	/* Start@ADD0, ADC12SC bit source, seq. of chan. */
	ADC12CTL1 = SHP | CONSEQ_1;

	/* Channel A0, vREF */
	ADC12MCTL0 = INCH_0 | SREF_1;

	/* Channel A1, vREF */
	ADC12MCTL1 = INCH_1 | SREF_1;

	/* Channel A4, vREF */
	ADC12MCTL2 = INCH_4 | SREF_1;

	/* Channel A3, vREF */
	ADC12MCTL3 = INCH_3 | SREF_1;

	/* Channel A6, vREF */
	ADC12MCTL4 = INCH_6 | SREF_1;

	/* Channel A7, vREF, End Of Sequence */
	ADC12MCTL5 = EOS | INCH_7 | SREF_1;

	/* Interrupt on end of sequence */
	ADC12IE = BV(5);

	/* Start ADC conversions */
	ADC12CTL0 |= ENC;
}
Esempio n. 3
0
static uint16_t tx_done(void) {
    // if destination is broadcast, don't wait for ACK
    if ((txframe.dst_addr[0]==0xFF) && (txframe.dst_addr[1]==0xFF)) {
        cc1101_gdo0_register_callback(rx_parse);
        txframe.length = 0;
        rx_set();
        if (sent_cb) {
            return sent_cb();
        }
    } else {
        cc1101_gdo0_register_callback(tx_ack);
        timerB_set_alarm_from_now(ALARM_RETRY, ACK_TIMEOUT, 0);
        timerB_register_cb(ALARM_RETRY, tx_delay);
    }
    return 0;
}
Esempio n. 4
0
uint16_t next_send(void)
{
    counter++;


    if (counter >= MAX_COUNTER)
    {
        state = SM_LOOP_TX;
        counter = 0;
        return 1;
    }
    else
    {
        timerB_set_alarm_from_now(TIMERB_ALARM_CCR5, SEND_DATA_PERIOD, 0);
        timerB_register_cb(TIMERB_ALARM_CCR5, next_send);
        return 0;
    }
    return 0;
}
Esempio n. 5
0
int main(void)
{
    WDTCTL = WDTPW+WDTHOLD;

    set_mcu_speed_xt2_mclk_8MHz_smclk_1MHz();
    set_aclk_div(1);

    LEDS_INIT();
    LEDS_OFF();


    ds2411_init();
    nodeaddr = (((uint16_t)ds2411_id.serial1)<<8) + (ds2411_id.serial0);

    uart0_init(UART0_CONFIG_1MHZ_115200);
    uart0_register_callback(char_rx);
    eint();

    printf("[APP];BOOTING;%.4x\n",nodeaddr);


    //check if this node is the sink
    if (nodeaddr == sink_nodes)
    {
        type = SINK;
        level = DEFAULT_LEVEL;
    }
    else
    {
        //retrieve father
        for (idx=0; idx<NUMBER_NODES; idx++)
        {
            if (list_nodes[idx] == nodeaddr)
            {
                if(father_nodes1[idx] != 0x0000)
                {
                    parent_id = father_nodes1[idx];
                    level = 12;
                    break;
                }
            }
        }
    }
    
    //hack for mobile
    /*if(nodeaddr == 0x1f5d)
    {
        parent_id = 0x0000;
        mac_set_mobile(1);
        level = 12;
    }*/

    mac_init(10);
    mac_set_rx_cb(packet_received);
    mac_set_error_cb(packet_error);
    mac_set_sent_cb(packet_sent);

    timerB_set_alarm_from_now(TIMERB_ALARM_CCR6, 32768, 32768);
    timerB_register_cb(TIMERB_ALARM_CCR6, inc_clock);

    while (1)
    {
        LPM1;

        if (state == SM_TX)
        {
            if (level != UNDEF_LEVEL && type != SINK)
            {
                seq_max = NUM_SEQ_MAX;
                delay = rand();
                delay &= 0xCFFF;
                delay += 12000; //(369ms < delay < 1991ms)
                timerB_set_alarm_from_now(TIMERB_ALARM_CCR5, delay, 0);
                timerB_register_cb(TIMERB_ALARM_CCR5, next_send);
            }
            else
            {
                printf("[APP];NOROUTE\n");
            }

            state = SM_IDLE;
        }
        else if (state == SM_LOOP_TX)
        {
            if (level != UNDEF_LEVEL)
            {
                sprintf(sourceaddr,"%.4x",nodeaddr);
                data_txframe[0] = DATA;
                data_txframe[1] = level-1;
                data_txframe[2] = sourceaddr[0];
                data_txframe[3] = sourceaddr[1];
                data_txframe[4] = sourceaddr[2];
                data_txframe[5] = sourceaddr[3];
                data_txframe[6] = seq;	//sequence
                data_txframe[7] = 1;    //hops
                txlength = 8;

                stat_add(STAT_APP_TX);
                printf("[APP];NODE_TX;%.4x;%.4x;%u;%u-%u\n", nodeaddr, parent_id, seq, global_clock, timerB_time()/32);

                seq++;

                mac_send(data_txframe, txlength, parent_id);

                if (DEBUG_LEDS == 1)
                {
                    LED_GREEN_ON();
                }

                if (seq < seq_max)
                {
                    timerB_set_alarm_from_now(TIMERB_ALARM_CCR5, SEND_DATA_PERIOD, 0);
                    timerB_register_cb(TIMERB_ALARM_CCR5, next_send);
                }
            }
            state = SM_IDLE;
        }
     
    }

    return 0;
}
Esempio n. 6
0
void mac_init(uint8_t channel)
{
    // initialize the unique serial number chip and set node address accordingly
    ds2411_init();
    node_addr = (((uint16_t)ds2411_id.serial1)<<8) + (ds2411_id.serial0);

    // seed the random number generator
    srand(node_addr);

    // reset callbacks
    received_cb = 0x0;
    sent_cb = 0x0;
    error_cb = 0x0;

    // initialize the timerB
    timerB_init();
    timerB_start_ACLK_div(1);
    timerB_register_cb(ALARM_RETRY, tx_try);

    // configure the radio
    cc1101_init();
    cc1101_cmd_idle();

    /* configure the radio behaviour */
    cc1101_cfg_append_status(CC1101_APPEND_STATUS_ENABLE);
    cc1101_cfg_crc_autoflush(CC1101_CRC_AUTOFLUSH_DISABLE);
    cc1101_cfg_white_data(CC1101_DATA_WHITENING_ENABLE);
    cc1101_cfg_crc_en(CC1101_CRC_CALCULATION_ENABLE);
    cc1101_cfg_freq_if(0x0E);
    cc1101_cfg_fs_autocal(CC1101_AUTOCAL_IDLE_TO_TX_RX);
    cc1101_cfg_mod_format(CC1101_MODULATION_MSK);
    cc1101_cfg_sync_mode(CC1101_SYNCMODE_30_32);
    cc1101_cfg_manchester_en(CC1101_MANCHESTER_DISABLE);
    cc1101_cfg_cca_mode(CC1101_CCA_MODE_RSSI_PKT_RX);

    // freq = 860MHz
    cc1101_write_reg(CC1101_REG_FREQ2, 0x1F);
    cc1101_write_reg(CC1101_REG_FREQ1, 0xDA);
    cc1101_write_reg(CC1101_REG_FREQ0, 0x12);

    // configure the radio channel (300kHz spacing)
    cc1101_cfg_chanspc_e(0x3);
    cc1101_cfg_chanspc_m(0x6C);
    cc1101_cfg_chan(channel<<1); // channel x2 to get 600kHz spacing

    // rise CCA threshold
    cc1101_cfg_carrier_sense_abs_thr(5);

    // set channel bandwidth (560 kHz)
    cc1101_cfg_chanbw_e(0);
    cc1101_cfg_chanbw_m(2);

    // set data rate (0xD/0x2F is 250kbps)
    cc1101_cfg_drate_e(0x0D);
    cc1101_cfg_drate_m(0x2F);

    // go to RX after RX and TX
    cc1101_cfg_rxoff_mode(CC1101_RXOFF_MODE_IDLE);
    cc1101_cfg_txoff_mode(CC1101_TXOFF_MODE_RX);

    uint8_t table[1] = {CC1101_868MHz_TX_0dBm};
    // table[0] = CC1101_868MHz_TX_m30dBm;
    // table[0] = CC1101_868MHz_TX_m20dBm;
    // table[0] = CC1101_868MHz_TX_m15dBm;
    // table[0] = CC1101_868MHz_TX_m10dBm;
    // table[0] = CC1101_868MHz_TX_m6dBm;
    table[0] = CC1101_868MHz_TX_0dBm;
    // table[0] = CC1101_868MHz_TX_5dBm;
    // table[0] = CC1101_868MHz_TX_7dBm;
    // table[0] = CC1101_868MHz_TX_10dBm;
    // table[0] = CC1101_868MHz_TX_12dBm;
    cc1101_cfg_patable(table, 1);
    cc1101_cfg_pa_power(0);

    // set IDLE state, flush everything, and start rx
    cc1101_cmd_idle();
    cc1101_cmd_flush_rx();
    cc1101_cmd_flush_tx();
    cc1101_cmd_calibrate();

    // configure irq
    cc1101_cfg_gdo0(CC1101_GDOx_SYNC_WORD);
    cc1101_gdo0_int_set_falling_edge();
    cc1101_gdo0_int_clear();
    cc1101_gdo0_int_enable();
    cc1101_gdo0_register_callback(rx_parse);

    // start the machine
    rx_set();

    txframe.length = 0;
}
Esempio n. 7
0
void mac_init(uint8_t channel) {
    int16_t i;

    // initialize the unique serial number chip and set node address accordingly
    ds2411_init();
    node_addr = ds2411_id.serial0 & HEADER_ADDR_MASK;

    // seed the random number generator
    srand((ds2411_id.serial0<<8)+ds2411_id.serial1);

    // initialize the timerB, with the beacon perdiod
    timerB_init();
    timerB_start_ACLK_div(TIMERB_DIV_1);
    timerB_set_alarm_from_now(ALARM_SLOTS, SLOT_LENGTH, SLOT_LENGTH);
    timerB_register_cb(ALARM_SLOTS, slot_alarm);

    // configure the radio
    cc1101_init();
    cc1101_cmd_idle();

    /* configure the radio behaviour */
    cc1101_cfg_append_status(CC1101_APPEND_STATUS_ENABLE);
    cc1101_cfg_crc_autoflush(CC1101_CRC_AUTOFLUSH_DISABLE);
    cc1101_cfg_white_data(CC1101_DATA_WHITENING_ENABLE);
    cc1101_cfg_crc_en(CC1101_CRC_CALCULATION_ENABLE);
    cc1101_cfg_freq_if(0x0E);
    cc1101_cfg_fs_autocal(CC1101_AUTOCAL_NEVER);
    cc1101_cfg_mod_format(CC1101_MODULATION_MSK);
    cc1101_cfg_sync_mode(CC1101_SYNCMODE_30_32);
    cc1101_cfg_manchester_en(CC1101_MANCHESTER_DISABLE);
    cc1101_cfg_cca_mode(CC1101_CCA_MODE_RSSI_PKT_RX);

    // freq = 860MHz
    cc1101_write_reg(CC1101_REG_FREQ2, 0x1F);
    cc1101_write_reg(CC1101_REG_FREQ1, 0xDA);
    cc1101_write_reg(CC1101_REG_FREQ0, 0x12);

    // configure the radio channel (300kHz spacing)
    cc1101_cfg_chanspc_e(0x3);
    cc1101_cfg_chanspc_m(0x6C);
    cc1101_cfg_chan(channel<<1); // channel x2 to get 600kHz spacing

    // set channel bandwidth (560 kHz)
    cc1101_cfg_chanbw_e(0);
    cc1101_cfg_chanbw_m(2);

    // set data rate (0xD/0x2F is 250kbps)
    cc1101_cfg_drate_e(0x0D);
    cc1101_cfg_drate_m(0x2F);

    // go to RX after TX
    cc1101_cfg_rxoff_mode(CC1101_RXOFF_MODE_STAY_RX);
    cc1101_cfg_txoff_mode(CC1101_TXOFF_MODE_RX);

    uint8_t table[] = {CC1101_868MHz_TX_0dBm};
    cc1101_cfg_patable(table, 1);
    cc1101_cfg_pa_power(0);

    // set IDLE state, flush everything
    cc1101_cmd_idle();
    cc1101_cmd_flush_rx();
    cc1101_cmd_flush_tx();

    // configure irq
    cc1101_cfg_gdo0(CC1101_GDOx_SYNC_WORD);
    cc1101_gdo0_int_set_falling_edge();

    // configure the beacon frame
    beacon_msg.hdr.length = BEACON_LENGTH-1;
    HEADER_SET_ADDR(beacon_msg.hdr, node_addr);
    HEADER_SET_TYPE(beacon_msg.hdr,BEACON_TYPE);
    beacon_msg.seq=0;

    // initialize the slot management service
    tdma_mgt_init();
    // reset slot count
    slot_count = -1;

    // init the data slots
    for (i=0;i<DATA_SLOT_MAX;i++) {
        mac_slots[i].ready=0;
        mac_slots[i].addr=0;
    }

    // reset the callback
    new_data_cb = 0x0;
}
Esempio n. 8
0
void mac_init(uint8_t channel)
{
    // initialize the unique serial number chip and set node address accordingly
    ds2411_init();
    node_addr = (((uint16_t)ds2411_id.serial1)<<8) + (ds2411_id.serial0);

    // seed the random number generator
    srand(node_addr);

    // reset callbacks
    received_cb = 0x0;
    sent_cb = 0x0;
    error_cb = 0x0;

    // initialize the timerB
    timerB_init();
    timerB_start_ACLK_div(1);
    timerB_register_cb(ALARM_RETRY, check);

    // configure the radio
    cc1100_init();
    cc1100_cmd_idle();

    /* configure the radio behaviour */
    cc1100_cfg_append_status(CC1100_APPEND_STATUS_ENABLE);
    cc1100_cfg_crc_autoflush(CC1100_CRC_AUTOFLUSH_DISABLE);
    cc1100_cfg_white_data(CC1100_DATA_WHITENING_ENABLE);
    cc1100_cfg_crc_en(CC1100_CRC_CALCULATION_ENABLE);
    cc1100_cfg_freq_if(0x0E);
    cc1100_cfg_fs_autocal(CC1100_AUTOCAL_IDLE_TO_TX_RX);
    cc1100_cfg_mod_format(CC1100_MODULATION_GFSK);
    cc1100_cfg_sync_mode(CC1100_SYNCMODE_30_32);
    cc1100_cfg_manchester_en(CC1100_MANCHESTER_DISABLE);
    cc1100_cfg_cca_mode(CC1100_CCA_MODE_RSSI_PKT_RX);

    // freq = 860MHz
    cc1100_write_reg(CC1100_REG_FREQ2, 0x1F);
    cc1100_write_reg(CC1100_REG_FREQ1, 0xDA);
    cc1100_write_reg(CC1100_REG_FREQ0, 0x12);

    //packet length to 61
    cc1100_write_reg(CC1100_REG_PKTLEN, 0x3D);

    // configure the radio channel
    cc1100_cfg_chanspc_e(0x2);
    cc1100_cfg_chanspc_m(0xF8);

    cc1100_write_reg(CC1100_REG_DEVIATN, 0x47);

    // rise CCA threshold
    cc1100_cfg_carrier_sense_abs_thr(5);

    // set channel bandwidth
    cc1100_cfg_chanbw_e(1);
    cc1100_cfg_chanbw_m(3);

    // set data rate
    cc1100_cfg_drate_e(0xB);
    cc1100_cfg_drate_m(0x74);

    // go to RX after RX and TX
    cc1100_cfg_rxoff_mode(CC1100_RXOFF_MODE_IDLE);
    cc1100_cfg_txoff_mode(CC1100_TXOFF_MODE_RX);

    uint8_t table[1];
    table[0] = 0x1E;      // -15dBm   13.4mA
    cc1100_cfg_patable(table, 1);
    cc1100_cfg_pa_power(0);

    // set IDLE state, flush everything, and start rx
    cc1100_cmd_idle();
    cc1100_cmd_flush_rx();
    cc1100_cmd_flush_tx();
    cc1100_cmd_calibrate();

    // configure irq
    cc1100_cfg_gdo0(CC1100_GDOx_SYNC_WORD);
    cc1100_gdo0_int_set_falling_edge();
    cc1100_gdo0_int_clear();
    cc1100_gdo0_int_enable();
    cc1100_gdo0_register_callback(rx_parse);

    // start the machine
    rx_set();

    txframe.length = 0;
}