Root/tools/lib/misctxrx.c

Source at commit 1de233a7c7fb2eca6f61682805aec0dda195a307 created 6 years 4 months ago.
By Werner Almesberger, tools/: fix artf_at86rf23[01] (should be atrf...) typo
1/*
2 * lib/misctxrx.c - Miscellaenous transceiver helper functions
3 *
4 * Written 2010-2011, 2013 by Werner Almesberger
5 * Copyright 2010-2011, 2013 Werner Almesberger
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13
14#include <stdint.h>
15#include <stdlib.h>
16#include <stdio.h>
17#include <unistd.h>
18#include <signal.h>
19#include <math.h>
20
21#include "at86rf230.h"
22#include "atrf.h"
23#include "timeout.h"
24#include "misctxrx.h"
25
26
27#define MIN_TIMEOUT_MS 10
28
29
30/* ----- Interrupts -------------------------------------------------------- */
31
32
33static volatile int sigint;
34
35
36static void die(int sig)
37{
38    sigint = 1;
39}
40
41
42void flush_interrupts(struct atrf_dsc *dsc)
43{
44    int res;
45
46    res = atrf_interrupt_wait(dsc, 1);
47    if (res < 0) {
48        fprintf(stderr, "atrf_interrupt_wait returns %d\n", res);
49        exit(1);
50    }
51}
52
53
54uint8_t wait_for_interrupt(struct atrf_dsc *dsc, uint8_t wait_for,
55    uint8_t ignore, int timeout_ms)
56{
57    struct timeout to;
58    uint8_t irq = 0, show;
59    void (*old_sig)(int);
60    int ms;
61    int timedout = 0;
62
63    sigint = 0;
64    old_sig = signal(SIGINT, die);
65    if (timeout_ms) {
66        if (timeout_ms < MIN_TIMEOUT_MS)
67            timeout_ms = MIN_TIMEOUT_MS;
68        timeout_start(&to, timeout_ms);
69    }
70    while (!sigint && !timedout) {
71        while (!sigint && !timedout) {
72            if (timeout_ms) {
73                ms = timeout_left_ms(&to);
74                if (ms <= 0) {
75                    timedout = 1;
76                    ms = 1;
77                }
78            } else {
79                ms = 0;
80            }
81            irq = atrf_interrupt_wait(dsc, ms);
82            if (irq)
83                break;
84        }
85
86        if (atrf_error(dsc))
87            exit(1);
88
89        show = irq & ~ignore;
90        if (show) {
91            fprintf(stderr, "IRQ (0x%02x):", irq);
92            if (irq & IRQ_PLL_LOCK)
93                fprintf(stderr, " PLL_LOCK");
94            if (irq & IRQ_PLL_UNLOCK)
95                fprintf(stderr, " PLL_UNLOCK");
96            if (irq & IRQ_RX_START)
97                fprintf(stderr, " RX_START");
98            if (irq & IRQ_TRX_END)
99                fprintf(stderr, " TRX_END");
100            if (irq & IRQ_CCA_ED_DONE)
101                fprintf(stderr, " CCA_ED_DONE");
102            if (irq & IRQ_AMI)
103                fprintf(stderr, " AMI");
104            if (irq & IRQ_TRX_UR)
105                fprintf(stderr, " TRX_UR");
106            if (irq & IRQ_BAT_LOW)
107                fprintf(stderr, " BAT_LOW");
108            fprintf(stderr, "\n");
109        }
110
111        if (irq & wait_for)
112            break;
113    }
114out:
115    signal(SIGINT, old_sig);
116    if (sigint)
117        raise(SIGINT);
118    return irq;
119}
120
121
122/* ----- Transmit power ---------------------------------------------------- */
123
124
125static const double tx_pwr_230[] = {
126     3.0, 2.6, 2.1, 1.6,
127     1.1, 0.5, -0.2, -1.2,
128    -2.2, -3.2, -4.2, -5.2,
129    -7.2, -9.2, -12.2, -17.2
130};
131
132
133static const double tx_pwr_231[] = {
134     3.0, 2.8, 2.3, 1.8,
135     1.3, 0.7, 0.0, -1,
136    -2, -3, -4, -5,
137    -7, -9, -12, -17
138};
139
140
141#define POWER_TABLE_SIZE (sizeof(tx_pwr_230)/sizeof(*tx_pwr_230))
142
143
144void set_power_step(struct atrf_dsc *dsc, int power, int crc)
145{
146    uint8_t tmp;
147
148    switch (atrf_identify(dsc)) {
149    case atrf_at86rf230:
150        atrf_reg_write(dsc, REG_PHY_TX_PWR,
151            (crc ? TX_AUTO_CRC_ON_230 : 0) | power);
152        break;
153    case atrf_at86rf231:
154        tmp = atrf_reg_read(dsc, REG_PHY_TX_PWR);
155        tmp = (tmp & ~TX_PWR_MASK) | power;
156        atrf_reg_write(dsc, REG_PHY_TX_PWR, tmp);
157        atrf_reg_write(dsc, REG_TRX_CTRL_1,
158            crc ? TX_AUTO_CRC_ON : 0);
159        break;
160    default:
161        abort();
162    }
163}
164
165
166static const double *tx_power_table(struct atrf_dsc *dsc)
167{
168    switch (atrf_identify(dsc)) {
169    case atrf_at86rf230:
170        return tx_pwr_230;
171    case atrf_at86rf231:
172        return tx_pwr_231;
173        break;
174    default:
175        abort();
176    }
177}
178
179
180int tx_power_dBm2step(struct atrf_dsc *dsc, double power)
181{
182    const double *tx_pwr = tx_power_table(dsc);
183    int n;
184
185    for (n = 0; n != POWER_TABLE_SIZE-1; n++)
186        if (tx_pwr[n] <= power)
187            break;
188    return n;
189}
190
191
192double tx_power_step2dBm(struct atrf_dsc *dsc, int step)
193{
194    const double *tx_pwr = tx_power_table(dsc);
195
196    if (step < 0 || step >= POWER_TABLE_SIZE)
197        abort();
198    return tx_pwr[step];
199}
200
201
202void set_power_dBm(struct atrf_dsc *dsc, double power, int crc)
203{
204    int step;
205    double got;
206
207    step = tx_power_dBm2step(dsc, power);
208    got = tx_power_step2dBm(dsc, step);
209
210    if (fabs(got-power) > 0.01)
211        fprintf(stderr, "TX power %.1f dBm\n", got);
212
213    set_power_step(dsc, step, crc);
214}
215

Archive Download this file



interactive