示例#1
0
void radio_init(uint8_t * rxbuf, uint8_t rxbufsz)
{
trx_regval_t status;
    /* init cpu peripherals and global IRQ enable */
    radiostatus.rxframe = rxbuf;
    radiostatus.rxframesz = rxbufsz;
    //trx_set_irq_handler(radio_irq_handler);
    /* transceiver initialization */

    TRX_RESET_LOW();
    TRX_SLPTR_LOW();
    DELAY_US(TRX_RESET_TIME_US);
    #if defined(CUSTOM_RESET_TIME_MS)
        DELAY_MS(CUSTOM_RESET_TIME_MS);
    #endif
    TRX_RESET_HIGH();

    /* disable IRQ and clear any pending IRQs */
    trx_reg_write(RG_IRQ_MASK, 0);
    trx_reg_read(RG_IRQ_STATUS);
    trx_bit_write(SR_TRX_CMD, CMD_TRX_OFF);
    DELAY_US(510);
    status = trx_bit_read(SR_TRX_STATUS);
    if (status != TRX_OFF)
    {
        radio_error(STATE_SET_FAILED);
    }
    trx_bit_write(SR_TX_AUTO_CRC_ON, 1);
    trx_reg_write(RG_IRQ_MASK, TRX_IRQ_RX_START | TRX_IRQ_RX_END | TRX_IRQ_TX_END);

    radiostatus.state = STATE_OFF;
    radiostatus.idle_state = STATE_OFF;
}
示例#2
0
void radio_send_frame(uint8_t len, uint8_t *frm, uint8_t compcrc)
{
    trx_frame_write(len, frm);
//    frm[2] = frm[2]+1;
    TRX_SLPTR_HIGH();
    TRX_SLPTR_LOW();
}
示例#3
0
void radio_send_frame(uint8_t len, uint8_t *frm, uint8_t compcrc)
{
    /* this block should be made atomic */
    trx_frame_write(len, frm);
    TRX_SLPTR_HIGH();
    TRX_SLPTR_LOW();
    /***********************************/
}
void radio_init(uint8_t * rxbuf, uint8_t rxbufsz)
{
trx_regval_t status;
    /* init cpu peripherals and global IRQ enable */
    radiostatus.rxframe = rxbuf;
    radiostatus.rxframesz = rxbufsz;
    trx_io_init(DEFAULT_SPI_RATE);
    trx_set_irq_handler(radio_irq_handler);
    /* transceiver initialization */

    TRX_RESET_LOW();
    TRX_SLPTR_LOW();
    DELAY_US(TRX_RESET_TIME_US);
    #if defined(CUSTOM_RESET_TIME_MS)
        DELAY_MS(CUSTOM_RESET_TIME_MS);
    #endif
    TRX_RESET_HIGH();

    /* disable IRQ and clear any pending IRQs */
    trx_reg_write(RG_IRQ_MASK, 0);
    trx_reg_read(RG_IRQ_STATUS);

#if RADIO_TYPE == RADIO_AT86RF212
	trx_reg_write(RG_TRX_CTRL_0, 0x19);
#ifdef CHINABAND
	trx_reg_write(RG_CC_CTRL_1, CCBAND );
	trx_reg_write(RG_CC_CTRL_0, CCNUMBER);//channel 0
	trx_reg_write(RG_TRX_CTRL_2, TRX_OQPSK250);
	/*trx_bit_write(SR_OQPSK_SUB1_RC_EN,1);
	trx_bit_write(SR_BPSK_OQPSK,1);
	trx_bit_write(SR_SUB_MODE,1);
	trx_bit_write(SR_OQPSK_DATA_RATE,0);
	trx_bit_write(SR_CC_BAND,CCBAND);
	*/
	DELAY_US(510);
#endif
	trx_reg_write(RG_TRX_STATE, CMD_FORCE_TRX_OFF);
	DELAY_US(510);
#else
    trx_bit_write(SR_TRX_CMD, CMD_TRX_OFF);
    DELAY_US(510);
#endif    
    do
    {    
        status = trx_bit_read(SR_TRX_STATUS);
    }
    while (status != TRX_OFF);

    trx_bit_write(SR_TX_AUTO_CRC_ON, 1);
    trx_reg_write(RG_IRQ_MASK, TRX_IRQ_RX_START | TRX_IRQ_TRX_END);

    radiostatus.state = STATE_OFF;
    radiostatus.idle_state = STATE_OFF;
}
示例#5
0
void radio_send_frame(uint8_t len, uint8_t *frm, uint8_t compcrc)
{
#ifdef TRX_TX_PA_EI
    if (radiostatus.tx_pa)
    {
        TRX_TX_PA_EI();
    }
#endif
    /* this block should be made atomic */
    TRX_SLPTR_HIGH();
    TRX_SLPTR_LOW();
    trx_frame_write(len, frm);
    /***********************************/
}
示例#6
0
int main(void)
{
trx_regval_t rval;

    /* This will stop the application before initializing the radio transceiver
     * (ISP issue with MISO pin, see FAQ)
     */
    trap_if_key_pressed();

    /* Step 0: init MCU peripherals */
    LED_INIT();
    trx_io_init(SPI_RATE_1_2);
    LED_SET_VALUE(LED_MAX_VALUE);
    LED_SET_VALUE(0);

    /* Step 1: initialize the transceiver */
    TRX_RESET_LOW();
    TRX_SLPTR_LOW();
    DELAY_US(TRX_RESET_TIME_US);
    TRX_RESET_HIGH();
    trx_reg_write(RG_TRX_STATE,CMD_TRX_OFF);
    DELAY_US(TRX_INIT_TIME_US);
    rval = trx_bit_read(SR_TRX_STATUS);
    ERR_CHECK(TRX_OFF!=rval);
    LED_SET_VALUE(1);

    /* Step 2: setup transmitter
     * - configure radio channel
     * - go into RX state,
     * - enable "receive end" IRQ
     */
    trx_bit_write(SR_CHANNEL,CHANNEL);
    trx_reg_write(RG_TRX_STATE,CMD_RX_ON);
#if defined(TRX_IRQ_TRX_END)
    trx_reg_write(RG_IRQ_MASK,TRX_IRQ_TRX_END);
#elif defined(TRX_IRQ_RX_END)
    trx_reg_write(RG_IRQ_MASK,TRX_IRQ_RX_END);
#else
#  error "Unknown IRQ bits"
#endif
    sei();
    LED_SET_VALUE(2);

    /* Step 3: Going to receive frames */
    rxcnt = 0;

    LED_SET_VALUE(0);
    while(1);
}
示例#7
0
uint8_t wibo_run(void)
{
	uint8_t isLeave=0;
	uint8_t isStay=0;
	unsigned long timeout = WIBO_TIMEOUT;
	
	while(!isLeave) {
#if !defined(NO_LEDS)
		LED_CLR(PROGLED);
#endif
		if (!(isStay))
		{
			while(!(wibo_available()) && (timeout--))  _delay_ms(1);	// minimum frame time @ 250kbps ~ 2ms.
		
			if (!(wibo_available()))	// no packets received, bye bye!
			{
				isLeave=1;
				return isLeave;
			}			
		}
		else
		{
			while(!(wibo_available()));	// wait for next packet
		}

		trx_reg_write(RG_IRQ_STATUS, TRX_IRQ_RX_END); /* clear the flag */

		trx_frame_read(rxbuf.data, sizeof(rxbuf.data) / sizeof(rxbuf.data[0]),
				&tmp); /* dont use LQI, write into tmp variable */

#if !defined(NO_LEDS)
		LED_SET(PROGLED);
		/* light as long as actions are running */
#endif

		switch (rxbuf.hdr.cmd)
		{

		case P2P_PING_REQ:
			isStay=1;
			if (0 == deaf)
			{
				pingrep.hdr.dst = rxbuf.hdr.src;
				pingrep.hdr.seq++;
				pingrep.crc = datacrc;

				trx_reg_write(RG_TRX_STATE, CMD_TX_ARET_ON);

				/* no need to make block atomic since no IRQs are used */
				TRX_SLPTR_HIGH()
				;
				TRX_SLPTR_LOW()
				;
				trx_frame_write(sizeof(p2p_ping_cnf_t) + sizeof(BOARD_NAME) + 2,
						(uint8_t*) &pingrep);
				/*******************************************************/

#if defined(_DEBUG_SERIAL_)
				printf("Pinged by 0x%04X"EOL, rxbuf.hdr.src);
#endif

#if defined(TRX_IF_RFA1)
				while (!(trx_reg_read(RG_IRQ_STATUS) & TRX_IRQ_TX_END))
					;
				trx_reg_write(RG_IRQ_STATUS, TRX_IRQ_TX_END); /* clear the flag */
#else
				while (!(trx_reg_read(RG_IRQ_STATUS) & TRX_IRQ_TRX_END))
				;
#endif /* defined(TRX_IF_RFA1) */
				trx_reg_write(RG_TRX_STATE, CMD_RX_AACK_ON);
			} /* (0 == deaf) */
			break;

		case P2P_WIBO_TARGET:
			isStay=1;
			target = rxbuf.wibo_target.targmem;
#if defined(_DEBUG_SERIAL_)
			printf("Set Target to %c"EOL, target);
#endif
			break;

		case P2P_WIBO_RESET:
			isStay=1;
#if defined(_DEBUG_SERIAL_)
			printf("Reset"EOL);
#endif

			addr = SPM_PAGESIZE; /* misuse as counter */
			ptr = pagebuf;
			do
			{
				*ptr++ = 0xFF;
			} while (--addr);

			addr = 0;
			datacrc = 0;
			pagebufidx = 0;
			deaf = 0;
			break;

		case P2P_WIBO_ADDR:
			isStay=1;
#if defined(_DEBUG_SERIAL_)
			printf("Set address: 0x%08lX"EOL, rxbuf.wibo_addr.address);
#endif
			addr = rxbuf.wibo_addr.address;
			pagebufidx = 0;
			break;

		case P2P_WIBO_DATA:
			isStay=1;
#if defined(_DEBUG_SERIAL_)
			printf("Data[%d]", rxbuf.wibo_data.dsize);
			uint8_t len = rxbuf.wibo_data.dsize;
			if (len > 10) len = 10;
			for(uint8_t j=0;j<len;j++)
			{
				printf(" %02X", rxbuf.wibo_data.data[j]);
			}
			if (len != rxbuf.wibo_data.dsize)
				printf("...");
			printf(EOL);
#endif
			tmp = rxbuf.wibo_data.dsize;
			ptr = rxbuf.wibo_data.data;
			do
			{
				datacrc = _crc_ccitt_update(datacrc, *ptr);
				pagebuf[pagebufidx++] = *ptr;
				if (pagebufidx >= PAGEBUFSIZE)
				{
					/* LED off to save current and avoid flash corruption
					 *  because of possible voltage drops
					 */
#if !defined(NO_LEDS)
					LED_CLR(PROGLED);
#endif

					if (target == 'F') /* Flash memory */
					{
						boot_program_page(addr, pagebuf);
					}
					else if (target == 'E')
					{
						/* not implemented */
					}
					else
					{
						/* unknown target, dry run */
					}

					/* also for dry run! */
					addr += SPM_PAGESIZE;
					pagebufidx = 0;
				}
				ptr++;
			} while (--tmp);
			break;
#if defined(WIBO_FLAVOUR_BOOTLUP)
		case P2P_WIBO_BOOTLUP:
			isStay=1;
			bootlup();
		break;
#endif

		case P2P_WIBO_FINISH:
			isStay=1;
#if defined(_DEBUG_SERIAL_)
			printf("Finish"EOL);
#endif
			if (target == 'F') /* Flash memory */
			{
				boot_program_page(addr, pagebuf);
			}
			else if (target == 'E')
			{
				/* not implemented */
			}
			else
			{
				/* unknown target, dry run */
			}

			/* also for dry run! */
			addr += SPM_PAGESIZE;
			pagebufidx = 0;

			break;

		case P2P_WIBO_EXIT:
#if defined(_DEBUG_SERIAL_)
			printf("Exit"EOL);
#endif
#if !defined(NO_LEDS)
			LED_CLR(PROGLED);
#endif
			isLeave=1;
			break;

		case P2P_WIBO_DEAF:
			isStay=1;
			deaf = 1;
			break;
		default:
			/* unknown or unhandled command */
			if (!(isStay)) {
				if (!(timeout--)) {
					isLeave = 1;
				}
			}
			break;
		}; /* switch (rxbuf.hdr.cmd) */
	}

	return isLeave;
}
示例#8
0
void wibo_init(uint8_t channel, uint16_t pan_id, uint16_t short_addr, uint64_t ieee_addr)
{
#if defined(WIBO_FLAVOUR_KEYPRESS) || defined(WIBO_FLAVOUR_MAILBOX)
	uint8_t run_bootloader = 0;
#endif

	/* only stay in bootloader if key is pressed */
#if defined(WIBO_FLAVOUR_KEYPRESS)
#if defined(NO_KEYS)
#error "No Keys defined for WIBO_FLAVOUR_KEYPRESS"
#endif
	KEY_INIT();
	if(KEY_GET() != 0)
	{
		run_bootloader = 1;
	}
#endif /* defined(WIBO_FLAVOUR_KEYPRESS) */

#if defined(WIBO_FLAVOUR_MAILBOX)

#if !defined(WIBO_FLAVOUR_MAILBOX_REGISTER) || !defined(WIBO_FLAVOUR_MAILBOX_CODE)
#error "WIBO_FLAVOUR_MAILBOX not defined correctly"
#endif
	if(WIBO_FLAVOUR_MAILBOX_REGISTER == WIBO_FLAVOUR_MAILBOX_CODE)
	{
		run_bootloader = 1;
	}
	//WIBO_MAILBOX_CLR();
#endif /* defined(WIBO_FLAVOUR_MAILBOX) */

#if defined(WIBO_FLAVOUR_KEYPRESS) || defined(WIBO_FLAVOUR_MAILBOX)
	if(run_bootloader == 0)
	{
		app();
	}
#endif

#if !defined(NO_LEDS)
LED_INIT();
LED_SET(PROGLED);
#endif

	nodeconfig.channel=channel;
	nodeconfig.pan_id=pan_id;
	nodeconfig.short_addr=short_addr;
	nodeconfig.ieee_addr = ieee_addr;

	trx_io_init(DEFAULT_SPI_RATE);
	TRX_RESET_LOW();
	TRX_SLPTR_LOW();
	TRX_RESET_HIGH();

#if defined(DI_TRX_IRQ)
	DI_TRX_IRQ();
#endif
	trx_reg_write(RG_TRX_STATE, CMD_FORCE_TRX_OFF);

#if (RADIO_TYPE == RADIO_AT86RF230A) || (RADIO_TYPE == RADIO_AT86RF230B)
	trx_reg_write(RG_PHY_TX_PWR, 0x80); /* set TX_AUTO_CRC bit, and TX_PWR = max */
#else
	trx_reg_write(RG_TRX_CTRL_1, 0x20); /* set TX_AUTO_CRC bit */
#endif

	/* setup network addresses for auto modes */
	pingrep.hdr.pan = nodeconfig.pan_id;
	pingrep.hdr.src = nodeconfig.short_addr;

	trx_set_panid(nodeconfig.pan_id);
	trx_set_shortaddr(nodeconfig.short_addr);

	/* use register write to save code space, overwrites Bits CCA_REQUEST CCA_MODE[1] CCA_MODE[0]
	 * which is accepted
	 */
	trx_reg_write(RG_PHY_CC_CCA, nodeconfig.channel);

#if RADIO_TYPE == RADIO_AT86RF212

	/* reset value, BPSK-40 */
	/* trx_reg_write(RG_TRX_CTRL_2, 0x24); */

	/* +5dBm acc. to datasheet AT86RF212 table 7-15 */
	trx_reg_write(RG_PHY_TX_PWR, 0x84);
#endif /* RADIO_TYPE == RADIO_AT86RF212 */

	trx_reg_write(RG_CSMA_SEED_0, nodeconfig.short_addr); /* some seeding */
	trx_reg_write(RG_TRX_STATE, CMD_RX_AACK_ON);
	trx_reg_write(RG_IRQ_STATUS, TRX_IRQ_RX_END); /* clear the flag */

#if defined(_DEBUG_SERIAL_)
	void sendchar(char c);
	static FILE usart_stdio = FDEV_SETUP_STREAM(sendchar, NULL, _FDEV_SETUP_WRITE);

	stdout = stderr = &usart_stdio;
	printf("WIBO Bootlapp Serial Debug"EOL);
	printf("PANID=%04X SHORTADDR=%04X CHANNEL=%d"EOL,
			nodeconfig.pan_id, nodeconfig.short_addr, nodeconfig.channel);
#endif
}
void radio_set_state(volatile radio_state_t state)
{
volatile trx_regval_t cmd, expstatus, currstatus;
uint8_t retries;
bool do_sleep = false;

    switch(state)
    {
        case STATE_OFF:
            expstatus = TRX_OFF;
            cmd = CMD_TRX_OFF;
            break;

        case STATE_RX:
            expstatus = RX_ON;
            cmd = CMD_RX_ON;
            break;

        case STATE_TX:
            expstatus = PLL_ON;
            cmd = CMD_PLL_ON;
            break;

        case STATE_RXAUTO:
            expstatus = RX_AACK_ON;
            cmd = CMD_RX_AACK_ON;
            break;

        case STATE_TXAUTO:
            expstatus = TX_ARET_ON;
            cmd = CMD_TX_ARET_ON;
            break;

        case STATE_SLEEP:
            expstatus = TRX_OFF;
            cmd = CMD_FORCE_TRX_OFF;
            do_sleep = true;
            break;

        default:
            radio_error(GENERAL_ERROR);
            expstatus = TRX_OFF;
            cmd = CMD_TRX_OFF;
            break;

     }

    if (STATE_SLEEP == radiostatus.state)
    {
        if (do_sleep)
        {
            return;
        }
        TRX_SLPTR_LOW();
        /*
         * Give the xosc some time to start up.  Once it started, the
         * SPI interface is operational, and the transceiver state can
         * be polled.  The state reads as 0b0011111 ("state transition
         * in progress") while the transceiver is still in its startup
         * phase, which does not match any of the "expstatus" values,
         * so polling just continues.
         */
        DELAY_US(500);

        /*
         * The exact wake-up timing is very board-dependent.
         * Contributing parameters are the effective series resitance
         * of the crystal, and the external bypass capacitor that has
         * to be charged by the voltage regulator.  Give the crystal
         * oscillator some time to start up.  5 ms (100 * 50 us) ought
         * to be enough under all circumstances.
         */
        retries = 100;
        do
        {
            currstatus = trx_bit_read(SR_TRX_STATUS);
            /*
             * Sleep could only be entered from TRX_OFF, so that's
             * what is expected again.
             */
            if (TRX_OFF == currstatus)
            {
                break;
            }
            DELAY_US(50);
        }
        while (--retries);

        if (currstatus != TRX_OFF)
        {
            /* radio didn't wake up */
            radio_error(STATE_SET_FAILED);
        }
    }
    trx_bit_write(SR_TRX_CMD, cmd);

    retries = 140;              /* enough to await an ongoing frame
                                 * reception */
    do
    {
        currstatus = trx_bit_read(SR_TRX_STATUS);
        if (expstatus == currstatus)
        {
            break;
        }
        /** @todo must wait longer for 790/868/900 MHz radios */
        DELAY_US(32);
    }
    while (--retries);

    if (expstatus != currstatus)
    {
        radio_error(STATE_SET_FAILED);
    }

    if (do_sleep)
    {
        TRX_SLPTR_HIGH();
    }

    radiostatus.state = state;
}
示例#10
0
void radio_set_state(radio_state_t state)
{
volatile trx_regval_t cmd, expstatus, currstatus;
uint8_t retries;
bool do_sleep = false;

    switch(state)
    {
        case STATE_OFF:
            expstatus = TRX_OFF;
            cmd = CMD_TRX_OFF;
            break;

        case STATE_RX:
            expstatus = RX_ON;
            cmd = CMD_RX_ON;
            break;

        case STATE_TX:
            expstatus = PLL_ON;
            cmd = CMD_PLL_ON;
            break;

        case STATE_RXAUTO:
            expstatus = RX_AACK_ON;
            cmd = CMD_RX_AACK_ON;
            break;

        case STATE_TXAUTO:
            expstatus = TX_ARET_ON;
            cmd = CMD_TX_ARET_ON;
            break;

        case STATE_SLEEP:
            expstatus = TRX_OFF;
            cmd = CMD_FORCE_TRX_OFF;
            do_sleep = true;
            break;

        default:
            radio_error(GENERAL_ERROR);
            expstatus = TRX_OFF;
            cmd = CMD_TRX_OFF;
            break;

     }

    if (STATE_SLEEP == radiostatus.state)
    {
        if (do_sleep)
        {
            return;
        }
        TRX_SLPTR_LOW();
        /*
         * Give the xosc some time to start up.  Once it started, the
         * SPI interface is operational, and the transceiver state can
         * be polled.  The state reads as 0b0011111 ("state transition
         * in progress") while the transceiver is still in its startup
         * phase, which does not match any of the "expstatus" values,
         * so polling just continues.
         */
        DELAY_US(500);
    }
    trx_bit_write(SR_TRX_CMD, cmd);

    retries = 140;              /* enough to await an ongoing frame
                                 * reception */
    do
    {
        currstatus = trx_bit_read(SR_TRX_STATUS);
        if (expstatus == currstatus)
        {
            break;
        }
        /** @todo must wait longer for 790/868/900 MHz radios */
        DELAY_US(32);
    }
    while (--retries);

    if (expstatus != currstatus)
    {
        radio_error(STATE_SET_FAILED);
    }

    if (do_sleep)
    {
        TRX_SLPTR_HIGH();
    }

    radiostatus.state = state;
}
int main(void)
{
trx_regval_t rval;

    /* This will stop the application before initializing the radio transceiver
     * (ISP issue with MISO pin, see FAQ)
     */
    trap_if_key_pressed();

    /* Step 0: init MCU peripherals */
    LED_INIT();
    trx_io_init(SPI_RATE_1_2);
    LED_SET_VALUE(LED_MAX_VALUE);
    LED_SET_VALUE(0);

    /* Step 1: initialize the transceiver */
    TRX_RESET_LOW();
    TRX_SLPTR_LOW();
    DELAY_US(TRX_RESET_TIME_US);
    TRX_RESET_HIGH();
    trx_reg_write(RG_TRX_STATE,CMD_TRX_OFF);
    DELAY_MS(TRX_INIT_TIME_US);
    rval = trx_bit_read(SR_TRX_STATUS);
    ERR_CHECK(TRX_OFF!=rval);
    LED_SET_VALUE(1);

    /* Step 2: setup transmitter
     * - configure radio channel
     * - enable transmitters automatic crc16 generation
     * - go into RX AACK state,
     * - configure address filter
     * - enable "receive end" IRQ
     */
    trx_bit_write(SR_CHANNEL,CHANNEL);
    trx_bit_write(SR_TX_AUTO_CRC_ON,1);

    trx_reg_write(RG_PAN_ID_0,(PANID&0xff));
    trx_reg_write(RG_PAN_ID_1,(PANID>>8));

    trx_reg_write(RG_SHORT_ADDR_0,(SHORT_ADDR&0xff));
    trx_reg_write(RG_SHORT_ADDR_1,(SHORT_ADDR>>8));

    trx_reg_write(RG_TRX_STATE,CMD_RX_AACK_ON);
#if defined(TRX_IRQ_TRX_END)
    trx_reg_write(RG_IRQ_MASK,TRX_IRQ_TRX_END);
#elif defined(TRX_IRQ_RX_END)
    trx_reg_write(RG_IRQ_MASK,TRX_IRQ_RX_END);
#else
#  error "Unknown IRQ bits"
#endif
    sei();
    LED_SET_VALUE(2);

    /* Step 3: send a frame each 500ms */
    tx_cnt = 0;
    tx_in_progress = false;
    LED_SET_VALUE(0);

    while(1);

}