Ejemplo n.º 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;
}
Ejemplo n.º 2
0
void radio_set_param(radio_attribute_t attr, radio_param_t parm)
{
	switch (attr)
	{
	case phyCurrentChannel:
		if (((int)parm.channel >= TRX_MIN_CHANNEL) &&
				((int)parm.channel <= TRX_MAX_CHANNEL))
		{
#ifdef CHINABAND
			trx_reg_write(RG_CC_CTRL_1, CCBAND);
			trx_reg_write(RG_CC_CTRL_0, parm.channel*2+CCNUMBER);
#else
			trx_bit_write(SR_CHANNEL, parm.channel);
#endif
			radiostatus.channel = parm.channel;
		}
		else
		{
			radio_error(SET_PARM_FAILED);
		}
		break;

	case phyTransmitPower:
#if RADIO_TYPE == RADIO_AT86RF212
#ifdef CHINABAND
		if (parm.tx_pwr >= -11 && parm.tx_pwr <= 8)
		{
			/** @todo move this into a radio-specific header file */
			static const uint8_t pwrtable[] =
			{
					0x0A, 0x09, 0x08,             /* -11...-9 dBm */
					0x07, 0x06, 0x05,			/* -8...-6 dBm */
					0x04, 0x03, 0x25,                   /* -5...-3 dBm */
					0x46, 0xAC, 0xAB,                   /* -2...0 dBm */
					0xAA,                         /* 1 dBm */
					0xCA,                         /* 2 dBm */
					0xEA,                         /* 3 dBm */
					0xE9,                         /* 4 dBm */
					0xE8,                         /* 5 dBm */
					0xE6,                         /* 6 dBm */
					0xE5,                         /* 7 dBm */
					0xE4,                         /* 8 dBm */
			};
			radiostatus.tx_pwr = parm.tx_pwr;
			uint8_t idx = parm.tx_pwr + 11;
			uint8_t pwrval = pgm_read_byte(pwrtable[idx]);
			trx_reg_write(RG_PHY_TX_PWR, pwrval);
		}
		else
			{
				radio_error(SET_PARM_FAILED);
			}
#endif//chinaband
#else
		if (parm.tx_pwr >= -17 && parm.tx_pwr <= 3)
		{
			/** @todo move this into a radio-specific header file */
			static const uint8_t pwrtable[] =
			{
					0x0F, 0x0F, 0x0F, 0x0F, 0x0F, /* -17...-13 dBm */
					0x0E, 0x0E, 0x0E,             /* -12...-10 dBm */
					0x0D, 0x0D,                   /* -9...-8 dBm */
					0x0C, 0x0C,                   /* -7...-6 dBm */
					0x0B,                         /* -5 dBm */
					0x0A,                         /* -4 dBm */
					0x09,                         /* -3 dBm */
					0x08,                         /* -2 dBm */
					0x07,                         /* -1 dBm */
					0x06,                         /* 0 dBm */
					0x04,                         /* 1 dBm */
					0x02,                         /* 2 dBm */
					0x00                          /* 3 dBm */
			};
			radiostatus.tx_pwr = parm.tx_pwr;
			uint8_t idx = parm.tx_pwr + 17;
			uint8_t pwrval = pgm_read_byte(pwrtable[idx]);
			trx_bit_write(SR_TX_PWR, pwrval);

		}

		else
		{
			radio_error(SET_PARM_FAILED);
		}

#endif//rf212
		break;
	case phyCCAMode:
		if (parm.cca_mode <= 3)
		{
			radiostatus.cca_mode = parm.cca_mode;
			trx_bit_write(SR_CCA_MODE, radiostatus.cca_mode);
		}
		else
		{
			radio_error(SET_PARM_FAILED);
		}
		break;

        case phyIdleState:
            radiostatus.idle_state = parm.idle_state;
            radio_set_state(parm.idle_state);
            break;

        case phyChannelsSupported:
            break;

        case phyPanId:
            trx_set_panid(parm.pan_id);
            break;

        case phyShortAddr:
            trx_set_shortaddr(parm.short_addr);
            break;

        case phyLongAddr:
        {
            uint8_t regno, *ap;
            for (regno = RG_IEEE_ADDR_0, ap = (uint8_t *)parm.long_addr;
                 regno <= RG_IEEE_ADDR_7;
                 regno++, ap++)
                trx_reg_write(regno, *ap);
            break;
        }

        case phyDataRate:
            trx_set_datarate(parm.data_rate);
            break;

        default:
            radio_error(SET_PARM_FAILED);
            break;
    }
}
Ejemplo n.º 3
0
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;
}
Ejemplo n.º 4
0
void radio_set_param(radio_attribute_t attr, radio_param_t parm)
{
    switch (attr)
    {
        case phyCurrentChannel:
            if (((int)parm.channel >= TRX_MIN_CHANNEL) &&
                ((int)parm.channel <= TRX_MAX_CHANNEL))
            {
                trx_bit_write(SR_CHANNEL, parm.channel);
                radiostatus.channel = parm.channel;
            }
            else
            {
                radio_error(SET_PARM_FAILED);
            }
            break;

        case phyTransmitPower:
            if (parm.tx_pwr >= -17 && parm.tx_pwr <= 3)
            {
                /** @todo move this into a radio-specific header file */
                static const uint8_t pwrtable[] =
                {
                    0x0F, 0x0F, 0x0F, 0x0F, 0x0F, /* -17...-13 dBm */
                    0x0E, 0x0E, 0x0E,             /* -12...-10 dBm */
                    0x0D, 0x0D,                   /* -9...-8 dBm */
                    0x0C, 0x0C,                   /* -7...-6 dBm */
                    0x0B,                         /* -5 dBm */
                    0x0A,                         /* -4 dBm */
                    0x09,                         /* -3 dBm */
                    0x08,                         /* -2 dBm */
                    0x07,                         /* -1 dBm */
                    0x06,                         /* 0 dBm */
                    0x04,                         /* 1 dBm */
                    0x02,                         /* 2 dBm */
                    0x00                          /* 3 dBm */
                };
                radiostatus.tx_pwr = parm.tx_pwr;
                uint8_t idx = parm.tx_pwr + 17;
                uint8_t pwrval = pgm_read_byte(pwrtable[idx]);
                trx_bit_write(SR_TX_PWR, pwrval);
            }
            else
            {
                radio_error(SET_PARM_FAILED);
            }
            break;

        case phyCCAMode:
            if (parm.cca_mode <= 3)
            {
                radiostatus.cca_mode = parm.cca_mode;
                trx_bit_write(SR_CCA_MODE, radiostatus.cca_mode);
            }
            else
            {
                radio_error(SET_PARM_FAILED);
            }
            break;

        case phyIdleState:
            radiostatus.idle_state = parm.idle_state;
            radio_set_state(parm.idle_state);
            break;

        case phyChannelsSupported:
            break;

        case phyPanId:
            trx_set_panid(parm.pan_id);
            break;

        case phyShortAddr:
            trx_set_shortaddr(parm.short_addr);
            break;

        case phyLongAddr:
        {
            uint8_t regno, *ap;
            for (regno = RG_IEEE_ADDR_0, ap = (uint8_t *)parm.long_addr;
                 regno <= RG_IEEE_ADDR_7;
                 regno++, ap++)
                trx_reg_write(regno, *ap);
            break;
        }

        case phyDataRate:
            trx_set_datarate(parm.data_rate);
            break;

#ifdef TRX_TX_PA_EI
        case phyTxPa:
            radiostatus.tx_pa = parm.tx_pa;
            break;
#endif
#ifdef TRX_RX_LNA_EI
        case phyRxLna:
            radiostatus.rx_lna = parm.rx_lna;
            break;
#endif

        default:
            radio_error(SET_PARM_FAILED);
            break;
    }
}
Ejemplo n.º 5
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;
}