Root/tools/lib/misctxrx.c

Source at commit 49e7c83796bc04941e9dbcec69bc0751563ff4d4 created 2 years 6 months ago.
By Werner Almesberger, atusb/: use ""VDD" symbol from kicad-libs
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 > 0) {
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 > 0) {
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,
82                timeout_ms < 0 ? -1 : ms);
83            if (irq)
84                break;
85        }
86
87        if (atrf_error(dsc))
88            exit(1);
89
90        show = irq & ~ignore;
91        if (show) {
92            fprintf(stderr, "IRQ (0x%02x):", irq);
93            if (irq & IRQ_PLL_LOCK)
94                fprintf(stderr, " PLL_LOCK");
95            if (irq & IRQ_PLL_UNLOCK)
96                fprintf(stderr, " PLL_UNLOCK");
97            if (irq & IRQ_RX_START)
98                fprintf(stderr, " RX_START");
99            if (irq & IRQ_TRX_END)
100                fprintf(stderr, " TRX_END");
101            if (irq & IRQ_CCA_ED_DONE)
102                fprintf(stderr, " CCA_ED_DONE");
103            if (irq & IRQ_AMI)
104                fprintf(stderr, " AMI");
105            if (irq & IRQ_TRX_UR)
106                fprintf(stderr, " TRX_UR");
107            if (irq & IRQ_BAT_LOW)
108                fprintf(stderr, " BAT_LOW");
109            fprintf(stderr, "\n");
110        }
111
112        if (irq & wait_for)
113            break;
114    }
115out:
116    signal(SIGINT, old_sig);
117    if (sigint)
118        raise(SIGINT);
119    return irq;
120}
121
122
123/* ----- Transmit power ---------------------------------------------------- */
124
125
126static const double tx_pwr_230[] = {
127     3.0, 2.6, 2.1, 1.6,
128     1.1, 0.5, -0.2, -1.2,
129    -2.2, -3.2, -4.2, -5.2,
130    -7.2, -9.2, -12.2, -17.2
131};
132
133
134static const double tx_pwr_231[] = {
135     3.0, 2.8, 2.3, 1.8,
136     1.3, 0.7, 0.0, -1,
137    -2, -3, -4, -5,
138    -7, -9, -12, -17
139};
140
141
142#define POWER_TABLE_SIZE (sizeof(tx_pwr_230)/sizeof(*tx_pwr_230))
143
144
145void set_power_step(struct atrf_dsc *dsc, int power, int crc)
146{
147    uint8_t tmp;
148
149    switch (atrf_identify(dsc)) {
150    case atrf_at86rf230:
151        atrf_reg_write(dsc, REG_PHY_TX_PWR,
152            (crc ? TX_AUTO_CRC_ON_230 : 0) | power);
153        break;
154    case atrf_at86rf231:
155        tmp = atrf_reg_read(dsc, REG_PHY_TX_PWR);
156        tmp = (tmp & ~TX_PWR_MASK) | power;
157        atrf_reg_write(dsc, REG_PHY_TX_PWR, tmp);
158        atrf_reg_write(dsc, REG_TRX_CTRL_1,
159            (crc ? TX_AUTO_CRC_ON : 0) |
160            SPI_CMD_MODE_PHY_RSSI << SPI_CMD_MODE_SHIFT);
161        break;
162    default:
163        abort();
164    }
165}
166
167
168static const double *tx_power_table(struct atrf_dsc *dsc)
169{
170    switch (atrf_identify(dsc)) {
171    case atrf_at86rf230:
172        return tx_pwr_230;
173    case atrf_at86rf231:
174        return tx_pwr_231;
175        break;
176    default:
177        abort();
178    }
179}
180
181
182int tx_power_dBm2step(struct atrf_dsc *dsc, double power)
183{
184    const double *tx_pwr = tx_power_table(dsc);
185    int n;
186
187    for (n = 0; n != POWER_TABLE_SIZE-1; n++)
188        if (tx_pwr[n] <= power)
189            break;
190    return n;
191}
192
193
194double tx_power_step2dBm(struct atrf_dsc *dsc, int step)
195{
196    const double *tx_pwr = tx_power_table(dsc);
197
198    if (step < 0 || step >= POWER_TABLE_SIZE)
199        abort();
200    return tx_pwr[step];
201}
202
203
204void set_power_dBm(struct atrf_dsc *dsc, double power, int crc)
205{
206    int step;
207    double got;
208
209    step = tx_power_dBm2step(dsc, power);
210    got = tx_power_step2dBm(dsc, step);
211
212    if (fabs(got-power) > 0.01)
213        fprintf(stderr, "TX power %.1f dBm\n", got);
214
215    set_power_step(dsc, step, crc);
216}
217

Archive Download this file



interactive