/* nrf_conf_inicial configura los registros del nrf para que funcione como PRX. 
 * En esta funcion se establece la velocidad, potencia y canal que se usaran en
 * el resto del programa */
void nrf_conf_inicial(void){
	desactivar_nrf();
	escribir_reg_8bits(0x00,0x0C); //PRIM_RX = 0
	escribir_reg_8bits(0x05,120); // Canal 120
	escribir_reg_8bits(0x06,0x07); // 1Mbps

	escribir_reg_8bits(0x02,0x03); // Habilitar recepcion en pipe0 y pipe1 [EN_RXADDR]
	escribir_reg_8bits(0x01,0x03); // Habilitar AutoAck en pipe0 y pipe1 [EN_AA]

	escribir_reg_8bits(0x03,0x03); // Direcciones de 5 bytes [SETUP_AW]
	escribir_reg_8bits(0x11,0x20); // pipe0 recibe payloads con 32 bytes
	escribir_reg_8bits(0x12,0x20); // pipe1 recibe payloads con 32 bytes

	escribir_reg_40bits(0x0A,0x65646f4e31); // pipe0 RX_ADDR

	escribir_reg_8bits(0x07,0x00); // Limpiar IRQs => REEMPLAZAR POR nrf_limpiar_flags();

	escribir_reg_8bits(0x00,0x0f); // Seleccionar PRIM_RX EN_CRC PWR_UP CRCO [CONFIG]
	
	// Delay de 5 ms (6.1.7 Timing Information [Tpd2stby] pag. 24).
	__delay_cycles(80000); // a 16MHz
    flush_rx();
	flush_tx();
	activar_nrf();

	// El nrf24l01+ queda como PRX activo.
}
Esempio n. 2
0
int main()
{
	uint8_t addr[5];
	uint8_t buf[32];

	WDTCTL = WDTHOLD | WDTPW;
	DCOCTL = CALDCO_16MHZ;
	BCSCTL1 = CALBC1_16MHZ;
	BCSCTL2 = DIVS_2;  // SMCLK = DCOCLK/4
	// SPI (USCI) uses SMCLK, prefer SMCLK < 10MHz (SPI speed limit for nRF24 = 10MHz)
	user = 0xFE;

	// Red LED will be our output
	P1DIR |= BIT0;
	P1OUT &= ~BIT0;

	/* Initial values for nRF24L01+ library config variables */
	rf_crc = RF24_EN_CRC; // CRC enabled, 8-bit
	rf_addr_width      = 5;
	rf_speed_power     = RF24_SPEED_MIN | RF24_POWER_MAX;
	rf_channel         = 120;
	msprf24_init();
	msprf24_set_pipe_packetsize(0, 0);
	msprf24_open_pipe(0, 1);  // Open pipe#0 with Enhanced ShockBurst

	// Set our RX address
	memcpy(addr, "\xDE\xAD\xBE\xEF\x01", 5);
	w_rx_addr(0, addr);

	// Receive mode
	if (!(RF24_QUEUE_RXEMPTY & msprf24_queue_state())) {
		flush_rx();
	}
	msprf24_activate_rx();
	LPM4;

	while (1) {
		if (rf_irq & RF24_IRQ_FLAGGED) {
			msprf24_get_irq_reason();
		}
		if (rf_irq & RF24_IRQ_RX || msprf24_rx_pending()) {
			r_rx_payload(r_rx_peek_payload_size(), buf);
			msprf24_irq_clear(RF24_IRQ_RX);
			user = buf[0];

			if (buf[0] == '0')
				P1OUT &= ~BIT0;
			if (buf[0] == '1')
				P1OUT |= BIT0;

		} else {
			user = 0xFF;
		}
		LPM4;
	}
	return 0;
}
Esempio n. 3
0
int main()
{
	uint8_t pktlen, pipeid;
	uint8_t rfbuf[32];

	WDTCTL = WDTPW | WDTHOLD;
	DCOCTL = CALDCO_16MHZ;
	BCSCTL1 = CALBC1_16MHZ;
	BCSCTL2 = DIVS_2;  // SMCLK = 8MHz

	// Initialize red LED
	P1DIR |= BIT6;
	P1OUT &= ~BIT6;

	// Initialize nRF24L01+ RF transceiver
	rf_crc = RF24_EN_CRC;
	rf_addr_width = 5;
	rf_speed_power = RF24_SPEED_MIN | RF24_POWER_MAX;
	rf_channel = 8;
	msprf24_init();
	msprf24_open_pipe(1, 1);  // Receive pipe#1 (could use #0 too, as we don't do any TX...)
	msprf24_set_pipe_packetsize(1, 0);  // Dynamic payload support

	w_rx_addr(1, (uint8_t*)ouraddr);
	msprf24_activate_rx();  // Start listening
	// Main loop
	while (1) {
		// Handle incoming nRF24 IRQs
		if (rf_irq & RF24_IRQ_FLAGGED) {
			msprf24_get_irq_reason();

			if (rf_irq & RF24_IRQ_RX || msprf24_rx_pending()) {
				pktlen = r_rx_peek_payload_size();
				if (!pktlen || pktlen > 32) {  /* Erroneous >32byte packets need to be flushed right away
							        * I have actually seen these occur, even with CRC enabled, and it 
							        * logjams the FIFOs because r_rx_payload() can't read them...
							        */
					flush_rx();
					msprf24_irq_clear(RF24_IRQ_RX);
				} else {
					pipeid = r_rx_payload(pktlen, rfbuf);
					msprf24_irq_clear(RF24_IRQ_RX);
					if (pipeid == 1) {  // Only paying attention to pipe#1 (this should always eval true)
						if (!memcmp(rfbuf, rfpayload, 3))  // Valid pushbutton packet
							P1OUT ^= BIT6;             // Toggle red LED
					}
				}
			}
		}

		LPM4;
	}
}
Esempio n. 4
0
bool Radio::setup(void) {
  HalfDuplexSPI::setup();

  csnHigh();

  // 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_ms(5);

  // Reset CONFIG and enable 16-bit CRC.
  write_register(CONFIG, 0 | _BV(EN_CRC) | _BV(CRCO));

  // 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.
  setRetries(5, 15);

  uint8_t setup = read_register(RF_SETUP);

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

  write_register(FEATURE, 0);
  write_register(DYNPD, 0);

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

  setChannel(76);

  // Flush buffers
  flush_rx();
  flush_tx();

  //Power up by default when setup() is called.
  powerUp();

  // Enable PTX, do not write CE high so radio will remain in standby I mode ( 130us max to transition to RX or TX
  // instead of 1500us from powerUp ) PTX should use only 22uA of power.
  write_register(CONFIG, (read_register(CONFIG)) & ~_BV(PRIM_RX));

  // If setup is 0 or ff then there was no response from module.
  return setup != 0 && setup != 0xff;
}
Esempio n. 5
0
void setup_nrf() {
  NRF_CE_LOW;
  NRF_CS_HIGH;

  write_register(EN_AA, 0x00);           // no shockburst
  write_register(SETUP_AW, 0x01);        // 3 byte address
  write_register(RF_CH, 53);             // channel 53   
  write_register(RF_SETUP, 0x06);        // 1Mbps - max power  
  write_register(SETUP_RETR, 0x00);      // no auto-retry
  write_register_n(RX_ADDR_P0, my_addr, 3); // my_addr 
  write_register_n(TX_ADDR, tx_addr, 3);    // where were sending to
  write_register(RX_PW_P0, 0x04);        // receiving payload size of 2
  flush_rx();
  power_up_rx();
}
Esempio n. 6
0
int main() {
  uint8_t buf[32];

  WDTCTL = WDTPW | WDTHOLD;
  DCOCTL = 0;
  BCSCTL1 = CALBC1_16MHZ;
  DCOCTL = CALDCO_16MHZ;
  BCSCTL3 |= LFXT1S_2;

  P1DIR |= BIT0;
  P1OUT &= ~BIT0;

  _BIS_SR(GIE);
#ifdef UART_DEBUG
  uart_setup();
#endif
  radio_setup();

  // flush RX just in case
  if (!(RF24_RX_EMPTY & msprf24_queue_state())) {
    flush_rx();
  }
  msprf24_activate_rx();
  LPM4;

  while (1) {
    if (rf_irq & RF24_IRQ_FLAGGED) {
      rf_irq &= ~RF24_IRQ_FLAGGED;
      msprf24_get_irq_reason();
    }
    if (rf_irq & RF24_IRQ_RX || msprf24_rx_pending()) {
      uint8_t nextPayloadSize = r_rx_peek_payload_size();
      r_rx_payload(nextPayloadSize, buf);
      msprf24_irq_clear(RF24_IRQ_MASK);
      memcpy(dht_data.bytes, buf, nextPayloadSize);
#ifdef UART_DEBUG
      int t = (((dht_data.val.th&0x7f)<<8) + dht_data.val.tl)*((dht_data.val.th&0x80)?-1:1);
      int h = (dht_data.val.hh<<8) + (dht_data.val.hl);
      uart_send(sprintf(txbuf, "%d.%1d;%d.%1d\r\n", t/10, t%10, h/10, h%10));
#endif
    }
    LPM4;
  }

  return 0;
}
/* Configura el nrf24l01+ como transmisor primario (PTX) en la direccion "dir" con AutoAck*/
void nrf_como_PTX(uint64_t dir){
	desactivar_nrf();
	nrf_limpiar_flags();
	escribir_reg_8bits(0x00,0x0C); // [CONFIG] como PTX y POWER-DOWN
	escribir_reg_40bits(0x0A,dir); // pipe0 RX_ADDR
	escribir_reg_40bits(0x10,dir); // TX_ADDR
	escribir_reg_8bits(0x04,0xFF); // 4ms y 15 ret.
    //__delay_cycles(10000); //CHECK THIS
    flush_rx();
	flush_tx();
    //__delay_cycles(10000);

	escribir_reg_8bits(0x00,0x0C | 0x02); // Power-Up

	// Delay de 5 ms (6.1.7 Timing Information [Tpd2stby] pag. 24).
	__delay_cycles(80000); // a 16MHz
	// Delay de 130 us (6.1.7 Timing Information [Tstby2a] pag. 24).
	__delay_cycles(3200); // a 16MHz
}
// Program entry point
void main()
{
  rfcon = 0x06; // enable RF clock
  rfctl = 0x10; // enable SPI
  ien0 = 0x80;  // enable interrupts
  TICKDV = 0xFF; // set the tick divider

  // Initialise and connect the USB controller
  init_usb();

  // Flush the radio FIFOs
  flush_rx();
  flush_tx();

  // Everything is triggered via interrupts, so now we wait
  while(1)
  {
    REGXH = 0xFF;
    REGXL = 0xFF;
    REGXC = 0x08;
    delay_us(1000);
  }
}
Esempio n. 9
0
File: main.c Progetto: mybays/lm3s
//*****************************************************************************
//
// This example demonstrates how to send a string of data to the UART.
//
//*****************************************************************************
int
main(void)
{
    //
    // Set the clocking to run directly from the crystal.
    //
    SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |
                   SYSCTL_XTAL_8MHZ);

    //
    // Initialize the OLED display and write status.
    //
    //
    // Enable the peripherals used by this example.
    //
    SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    //PC5,PC7 EN,CSN
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);
    GPIOPinTypeGPIOOutput(GPIO_PORTC_BASE,1<<5|1<<7);

    //SPI配置
    unsigned long ulDataTx[NUM_SSI_DATA];
    unsigned long ulDataRx[NUM_SSI_DATA];
    unsigned long ulindex;
    unsigned long ultemp=0;


    SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI0);
    //SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    GPIOPinConfigure(GPIO_PA2_SSI0CLK);
    GPIOPinConfigure(GPIO_PA3_SSI0FSS);
    GPIOPinConfigure(GPIO_PA4_SSI0RX);
    GPIOPinConfigure(GPIO_PA5_SSI0TX);
    GPIOPinTypeSSI(GPIO_PORTA_BASE, GPIO_PIN_5 | GPIO_PIN_4 | GPIO_PIN_3 |
                   GPIO_PIN_2);

    SSIConfigSetExpClk(SSI0_BASE, SysCtlClockGet(), SSI_FRF_MOTO_MODE_0,
                       SSI_MODE_MASTER, 4000000, 8);
    /*
    GPIODirModeSet(GPIO_PORTA_BASE, GPIO_PIN_3, GPIO_DIR_MODE_OUT); 
    GPIOPadConfigSet(GPIO_PORTA_BASE, GPIO_PIN_3, GPIO_STRENGTH_4MA,
                     GPIO_PIN_TYPE_STD_WPU);  
    GPIODirModeSet(GPIO_PORTB_BASE, GPIO_PIN_0, GPIO_DIR_MODE_OUT);
    GPIOPadConfigSet(GPIO_PORTB_BASE, GPIO_PIN_0 , GPIO_STRENGTH_4MA,
                     GPIO_PIN_TYPE_STD_WPU);
    */
    SSIEnable(SSI0_BASE);


    //
    // Enable processor interrupts.
    //
    IntMasterEnable();

    //
    // Set GPIO A0 and A1 as UART pins.
    //
    GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);

    //
    // Configure the UART for 115,200, 8-N-1 operation.
    //
    UARTConfigSetExpClk(UART0_BASE, SysCtlClockGet(), 115200,
                        (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
                         UART_CONFIG_PAR_NONE));

    //
    // Enable the UART interrupt.
    //
    IntEnable(INT_UART0);
    UARTIntEnable(UART0_BASE, UART_INT_RX | UART_INT_RT);

    //
    // Prompt for text to be entered.
    //
    UARTStdioInit(0);
    UARTSend((unsigned char *)"Enter text:\n\r", 12);
    UARTSend((unsigned char *)"Enter text:\n\r", 12);

    //清零接收缓冲区
    while(SSIDataGetNonBlocking(SSI0_BASE, &ulDataRx[0]))
    {
    }
    ulDataTx[0] = 's';
    ulDataTx[1] = 'p';
    ulDataTx[2] = 'i';

    set_nrf24l01_csn_l();
    /*
    for(ulindex = 0; ulindex < NUM_SSI_DATA; ulindex++)
    {
    	UARTprintf("'%c' ", ulDataTx[ulindex]);
    	SSIDataPut(SSI0_BASE, ulDataTx[ulindex]);
    }
    */
    set_nrf24l01_csn_h();
    _delay_ms(1);

    if( setDataRate( RF24_250KBPS ) )
    {
        p_variant = true ;
    }

    //初始化NRF24L01
    set_module_tx();
    nrf_write_reg(NRF_CONFIG,0x0a);
    print_byte_register("CONFIG\t",NRF_CONFIG,1);

    init_NRF24L01();
    set_module_tx();

    unsigned char transfer_value[]="EEWORLD_MSP430_00";

    //set_module_tx();

    //读不出来spi数据的原因是,原来里面有没读取完的数据,需要先清理,再读写.



    setChannel(74);
    UARTprintf("getchannel:%d\r\n",getChannel());
 //   setChannel(24);
 //   UARTprintf("getchannel:%d\r\n",getChannel());

    //写地址
    nrf_write_buf(TX_ADDR,(uint8_t*)&addresses[0],5);

    uint8_t recvbuf[5];
    nrf_read_buf(TX_ADDR,&recvbuf[0],5);

    for(int i=0;i<5;i++)
    {
        UARTprintf("%d:%d ",i,recvbuf[i]);
    }
    UARTprintf("\r\n");
    //end of test write address


    uint8_t data[32];

    for(int i=0;i<32;i++)
    {
        data[i]=i;
    }


    

    UARTprintf("\r\n");
    //while(SSIDataGetNonBlocking(SSI0_BASE, &ulDataRx[0]))
    //{
    //}

    //重新发送前,避免写缓冲区满
    flush_tx();
    spi_write_reg(STATUS, ( spi_read_reg(STATUS) ) | _BV(MAX_RT) );
    //role=role_ping_out
    openWritingPipe(addresses[0]);
    openReadingPipe(1,addresses[1]);

    nrf_write_buf(RX_ADDR_P0,(uint8_t*)&addresses[0],5);

    unsigned char test;
    //while(1)
    {
        test=spi_read_reg(0x05);
        UARTprintf("test:%d\r\n",test);
        _delay_ms(1000);
    }

    //调试关闭
    //nrf_write_reg(EN_AA,0x00);
    nrf_write_reg(EN_RXADDR,0x02);
    //nrf_write_reg(SETUP_RETR,0x00);
    nrf_write_reg(RX_PW_P1,0x20);

    //set_module_tx();
    nrf_write_reg(NRF_CONFIG,0x0b);
    nrf_write_reg(CONFIG, nrf_read_reg(CONFIG) | _BV(PRIM_RX));
    nrf_write_reg(STATUS, _BV(RX_DR) | _BV(TX_DS) | _BV(MAX_RT) );
    set_nrf24l01_ce_h();
    nrf_write_buf(RX_ADDR_P0,(uint8_t*)&addresses[0],5);
    set_nrf24l01_ce_h();
    if(nrf_read_reg(FEATURE) & _BV(EN_ACK_PAY))
    {
        flush_tx();
    }

    flush_rx();

    print_status(get_status());
    nrf_write_reg(SETUP_AW,0x03);
    print_byte_register("SETUP_AW\t",SETUP_AW,1);
    print_address_register("RX_ADDR_P0-1",RX_ADDR_P0,2);
    print_byte_register("RX_ADDR_P2-5",RX_ADDR_P2,4);

    print_address_register("TX_ADDR\t",TX_ADDR,1);

    print_byte_register("RX_PW_P0-6",RX_PW_P0,6);


    print_byte_register("EN_AA\t",EN_AA,1);
    print_byte_register("EN_RXADDR",EN_RXADDR,1);
    print_byte_register("RF_CH\t",RF_CH,1);
    print_byte_register("RF_SETUP",RF_SETUP,1);

    print_byte_register("CONFIG\t",NRF_CONFIG,1);
    print_byte_register("DYNPD/FEATURE",DYNPD,2);


    UARTprintf("Data Rate\t = %s\r\n", pgm_read_word(&rf24_datarate_e_str_P[getDataRate()]));
    UARTprintf("Model\t\t = %s\r\n",   pgm_read_word(&rf24_model_e_str_P[isPVariant()]));
    UARTprintf("CRC Length\t = %s\r\n",pgm_read_word(&rf24_crclength_e_str_P[getCRCLength()]));
    UARTprintf("PA Power\t = %s\r\n",  pgm_read_word(&rf24_pa_dbm_e_str_P[getPALevel()]));

    Init_Timer_A();

    set_nrf24l01_ce_h();
    //将业务数据写入:WR_TX_PLOAD

    uint8_t fifo_status,status,state,i;
    while(1)
    {
        fifo_status=spi_read_reg(FIFO_STATUS);
        if(fifo_status&0x02)
        {
            status=spi_read_reg(STATUS);
            if(status&_BV(RX_DR))
            {
                state=spi_send_byte(RD_RX_PLOAD);
                for(i=0;i<RX_PLOAD_WIDTH;i++)
                {
                    status=spi_send_byte(0xff);
                    //buf[i]=status;
                }
                nrf_write_reg(FLUSH_RX,0xFF);
                //UARTprintf(".");
                counter++;
            }
            if(status &0x02)
            {
                nrf_write_reg(FLUSH_RX,0xFF);
                //UARTprintf(".");
                counter++;
            }

            nrf_rx_packet(data);
        }
    }

    while(available(0))
    {
        //UARTprintf(".");
        if(nrf_rx_packet(data) == 0)
        {
            counter++;
        }
        
        //UARTprintf(".");
        //_delay_ms(50);
        /*
        set_nrf24l01_ce_l();
        nrf_write_buf(WR_TX_PLOAD,data,TX_PLOAD_WIDTH);
        set_nrf24l01_ce_h();
        _delay_ms(30);
        */
    }
}
Esempio n. 10
0
void RF24::flush_rx_buffer(void) {
    flush_rx();
}
Esempio n. 11
0
int main()
{
	uint8_t rfbuf[32], i, do_lpm, pktlen, pipeid;

	WDTCTL = WDTPW | WDTHOLD;


	// I/O ports used for status LED
	//P3DIR |= BIT6;
	P1DIR |= BIT0;
	//P1OUT &= ~BIT7;
	P1OUT &= ~BIT0;
	//P3OUT |= BIT6;  // Blue LED signifies clock startup

	/* MSP430 F5172 */
	//ucs_clockinit(16000000, 0, 0);
	/* MSP430 G-series */
	DCOCTL = CALDCO_16MHZ;
	BCSCTL1 = CALBC1_16MHZ;
	BCSCTL2 = DIVS_1;

	//P3OUT &= ~BIT6;



	// Configure Nordic nRF24L01+
	rf_crc = RF24_EN_CRC | RF24_CRCO; // CRC enabled, 16-bit
	rf_addr_width      = 5;
	rf_speed_power     = RF_SPEED | RF24_POWER_MAX;  // RF_SPEED from tcsender.h
	rf_channel         = RF_CHANNEL;  // This #define is located in tcsender.h
	msprf24_init();
	msprf24_open_pipe(0, 0);
	msprf24_set_pipe_packetsize(0, 0);

	packet_init_tasklist();
	dmx512_init();

	// Submit one color change.
	memcpy(dmx512_buffer, rgb_cust, 3);
	dmx512_output_channels(0x00, 1, dmx512_buffer, 3);

	while(1) {
		do_lpm = 1;

		// Handle RF acknowledgements
		if (rf_irq & RF24_IRQ_FLAGGED || msprf24_rx_pending()) {
			msprf24_get_irq_reason();

			// Handle TX acknowledgements
			if (rf_irq & RF24_IRQ_TX) {
				// Acknowledge
				msprf24_irq_clear(RF24_IRQ_TX);
				P1OUT &= ~BIT0;
			}

			if (rf_irq & RF24_IRQ_TXFAILED) {
				msprf24_irq_clear(RF24_IRQ_TXFAILED);
				flush_tx();
			}

			if (rf_irq & RF24_IRQ_RX || msprf24_rx_pending()) {
				pktlen = r_rx_peek_payload_size();
				if (pktlen > 0 && pktlen < 33) {
					pipeid = r_rx_payload(pktlen, (char*)rfbuf);
					if (pipeid == 1) {
						for (i=0; i < pktlen; i++) {
							if (rfbuf[i]) {
								/* Process this packet if it's valid (and payload length doesn't send us
								 *   past the end of the rfbuf buffer)
								 */
								if ( (i+rfbuf[i+1] + 1) < pktlen ) {
									packet_processor(rfbuf[i],
											 rfbuf[i+1],
											 &rfbuf[i+2]);
									i += rfbuf[i+1] + 1;
								} else {
									i = pktlen;  /* Otherwise, we're done, we assume the
										      *   the rest of the payload is corrupt.
										      */
								}
							} /* rfbuf[i] != 0x00 (i.e. valid program ID) */
						} /* for(0 .. pktlen) */
					} /* pipeid == 1 */
				} else {
					// False alarm; bad packet, nuke it.
					flush_rx();
				} /* pktlen is 1..32 */
				msprf24_irq_clear(RF24_IRQ_RX);
			} /* rf_irq & RF24_IRQ_RX */

			do_lpm = 0;
		}  /* rf_irq & RF24_IRQ_FLAGGED */

		if (packet_task_next() != NULL) {
			packet_process_txqueue();
		}

		if (do_lpm)
			LPM4;
	} /* while(1) */

	return 0;  // Should never reach here
}