1
0
mirror of git://projects.qi-hardware.com/ben-wpan.git synced 2024-11-05 16:15:20 +02:00
ben-wpan/tools/lib/cwtest.c

165 lines
3.8 KiB
C
Raw Normal View History

/*
* lib/cwtest.c - Set up AT86RF230/231 constant wave test mode
*
* Written 2010-2011 by Werner Almesberger
* Copyright 2010-2011 Werner Almesberger
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "at86rf230.h"
#include "atrf.h"
#include "misctxrx.h"
#include "cwtest.h"
static int last_cont_tx; /* @@@ hack for resuming on the 230 */
int cw_test_needs_reset(struct atrf_dsc *dsc)
{
if (atrf_usb_handle(dsc))
return 1;
if (atrf_identify(dsc) == artf_at86rf230)
return 1;
return 0;
}
static void enter_test_mode_230(struct atrf_dsc *dsc, uint8_t cont_tx)
{
atrf_buf_write(dsc, "", 1);
atrf_reg_write(dsc, REG_CONT_TX_0, CONT_TX_MAGIC);
atrf_reg_write(dsc, REG_CONT_TX_1, cont_tx);
if (!atrf_test_mode(dsc)) {
atrf_reset_rf(dsc);
fprintf(stderr, "device does not support test mode\n");
exit(1);
}
atrf_reg_write(dsc, REG_TRX_STATE, TRX_CMD_PLL_ON);
wait_for_interrupt(dsc, IRQ_PLL_LOCK, IRQ_PLL_LOCK, 10, 0);
atrf_reg_write(dsc, REG_TRX_STATE, TRX_CMD_TX_START);
}
static void prepare_test_mode_231(struct atrf_dsc *dsc, uint8_t cont_tx)
{
uint8_t buf[127];
uint8_t status;
switch (cont_tx) {
case CONT_TX_M2M:
fprintf(stderr,
"-2 MHz mode is not supported by the AT86RF231\n");
atrf_close(dsc);
exit(1);
case CONT_TX_M500K:
memset(buf, 0, sizeof(buf));
break;
case CONT_TX_P500K:
memset(buf, 0xff, sizeof(buf));
break;
default:
abort();
}
atrf_reg_write(dsc, REG_IRQ_MASK, IRQ_PLL_LOCK); /* 2 */
atrf_reg_write(dsc, REG_TRX_CTRL_1, 0); /* 3 */
atrf_reg_write(dsc, REG_TRX_STATE, TRX_CMD_FORCE_TRX_OFF); /* 4 */
/* deleted step 5 - we don't need to enable CLKM */
status = atrf_reg_read(dsc, REG_TRX_STATUS) & TRX_STATUS_MASK; /* 8 */
if (status != TRX_STATUS_TRX_OFF) {
fprintf(stderr, "expected status 0x%02x, got 0x%02x\n",
TRX_STATUS_TRX_OFF, status);
exit(1);
}
atrf_reg_write(dsc, REG_CONT_TX_0, CONT_TX_MAGIC); /* 9 */
atrf_reg_write(dsc, REG_TRX_CTRL_2, OQPSK_DATA_RATE_2000); /*10 */
atrf_reg_write(dsc, REG_RX_CTRL, 0xa7); /*11 */
atrf_buf_write(dsc, buf, sizeof(buf)); /*12 */
}
static void start_test_mode_231(struct atrf_dsc *dsc)
{
atrf_reg_write(dsc, REG_PART_NUM, 0x54); /*13 */
atrf_reg_write(dsc, REG_PART_NUM, 0x46); /*14 */
atrf_reg_write(dsc, REG_TRX_STATE, TRX_CMD_PLL_ON); /*15 */
wait_for_interrupt(dsc, IRQ_PLL_LOCK, IRQ_PLL_LOCK, 10, 0); /*16 */
atrf_reg_write(dsc, REG_TRX_STATE, TRX_CMD_TX_START); /*17 */
}
void cw_test_begin(struct atrf_dsc *dsc, uint8_t cont_tx)
{
switch (atrf_identify(dsc)) {
case artf_at86rf230:
enter_test_mode_230(dsc, cont_tx);
last_cont_tx = cont_tx;
break;
case artf_at86rf231:
prepare_test_mode_231(dsc, cont_tx);
start_test_mode_231(dsc);
break;
default:
abort();
}
}
void cw_test_resume(struct atrf_dsc *dsc)
{
switch (atrf_identify(dsc)) {
case artf_at86rf230:
enter_test_mode_230(dsc, last_cont_tx);
break;
case artf_at86rf231:
start_test_mode_231(dsc);
break;
default:
abort();
}
}
void cw_test_end(struct atrf_dsc *dsc)
{
if (atrf_identify(dsc) == artf_at86rf231)
atrf_reg_write(dsc, REG_PART_NUM, 0);
atrf_reg_write(dsc, REG_TRX_STATE, TRX_CMD_FORCE_TRX_OFF);
/*
* atrf_reset_rf can take a long time. I appears that at least the
* AT86RF231 also exits test mode if we send it to sleep for a
* moment.
*/
if (cw_test_needs_reset(dsc))
atrf_reset_rf(dsc);
else {
usleep(2); /* table 7-1: tTR12(typ) = 1 us */
atrf_slp_tr(dsc, 1, 0);
usleep(10); /* table 7-1: tTR3(typ) doesn't really apply */
atrf_slp_tr(dsc, 0, 0);
usleep(500); /* table 7-1: tTR2(typ) = 380 */
}
}