Root/tools/lib/atrf.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/atrf.c - ATRF access functions library
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 <stdlib.h>
15#include <stdio.h>
16#include <string.h>
17
18#include "at86rf230.h"
19
20#include "driver.h"
21#include "atrf.h"
22
23
24struct atrf_dsc {
25    const struct atrf_driver *driver;
26    void *handle;
27    char *spec;
28    enum atrf_chip_id chip_id;
29};
30
31
32static const struct atrf_driver *drivers[] = {
33#ifdef HAVE_BEN
34    &atben_driver,
35#endif
36#ifdef HAVE_USB
37    &atusb_driver,
38    &atusb_spi_driver,
39#endif
40    &atnet_driver,
41    NULL
42};
43
44
45void *atrf_usb_handle(struct atrf_dsc *dsc)
46{
47#ifdef HAVE_USB
48    if (dsc->driver == &atusb_driver || dsc->driver == &atusb_spi_driver)
49        return atusb_dev_handle(dsc->handle);
50#endif
51    return NULL;
52}
53
54
55void *atrf_ben_regs(struct atrf_dsc *dsc)
56{
57#ifdef HAVE_BEN
58    if (dsc->driver == &atben_driver)
59        return atben_regs(dsc->handle);
60#endif
61    return NULL;
62}
63
64
65int atrf_error(struct atrf_dsc *dsc)
66{
67    return dsc->driver->error ? dsc->driver->error(dsc->handle) : 0;
68}
69
70
71int atrf_clear_error(struct atrf_dsc *dsc)
72{
73    return dsc->driver->clear_error ?
74        dsc->driver->clear_error(dsc->handle) : 0;
75}
76
77
78static enum atrf_chip_id identify(struct atrf_dsc *dsc)
79{
80    uint8_t part, version;
81
82    part = atrf_reg_read(dsc, REG_PART_NUM);
83    version = atrf_reg_read(dsc, REG_VERSION_NUM);
84    switch (part) {
85    case 2: /* AT86RF230 */
86        switch (version) {
87        case 1: /* rev A */
88        case 2: /* rev B */
89            return atrf_at86rf230;
90        default:
91            return atrf_unknown_chip;
92        }
93        break;
94    case 3: /* AT86RF231 */
95        switch (version) {
96        case 2: /* rev A */
97            return atrf_at86rf231;
98        default:
99            return atrf_unknown_chip;
100        }
101        break;
102    default:
103        return atrf_unknown_chip;
104    }
105    return atrf_unknown_chip;
106}
107
108
109const char *atrf_default_driver_name(void)
110{
111    return drivers[0] ? drivers[0]->name : "none";
112}
113
114
115static const struct atrf_driver *select_driver(const char *spec,
116    const char **opt)
117{
118    const struct atrf_driver **drv;
119    const char *end;
120    size_t len;
121
122    if (!*drivers) {
123        fprintf(stderr, "no drivers defined\n");
124        return NULL;
125    }
126
127    *opt = NULL;
128    if (!spec || !strcmp(spec, "default"))
129        return *drivers;
130    
131    end = strchr(spec, ':');
132    if (!end)
133        end = strchr(spec, 0);
134    len = end-spec;
135    for (drv = drivers; *drv; drv++)
136        if (!strncmp((*drv)->name, spec, len) &&
137            strlen((*drv)->name) == len)
138            break;
139    if (!*drv) {
140        fprintf(stderr, "no driver \"%.*s\" found\n", (int) len, spec);
141        return NULL;
142    }
143    if (*end)
144        *opt = end+1;
145    return *drv;
146}
147
148
149struct atrf_dsc *atrf_open(const char *spec)
150{
151    struct atrf_dsc *dsc;
152    const struct atrf_driver *driver;
153    const char *opt;
154    void *handle;
155
156    driver = select_driver(spec, &opt);
157    if (!driver)
158        return NULL;
159    handle = driver->open(opt);
160    if (!handle)
161        return NULL;
162    dsc = malloc(sizeof(*dsc));
163    if (!dsc) {
164        perror("malloc");
165        exit(1);
166    }
167    dsc->driver = driver;
168    dsc->handle = handle;
169    if (spec) {
170        dsc->spec = strdup(spec);
171        if (!dsc->spec) {
172            perror("strdup");
173            exit(1);
174        }
175    } else {
176        dsc->spec= NULL;
177    }
178    dsc->chip_id = identify(dsc);
179    return dsc;
180}
181
182
183void atrf_close(struct atrf_dsc *dsc)
184{
185    if (dsc->driver->close)
186        dsc->driver->close(dsc->handle);
187    free(dsc->spec);
188    free(dsc);
189}
190
191
192const char *atrf_driver_spec(struct atrf_dsc *dsc, int last)
193{
194    if (!dsc->spec)
195        return dsc->driver->name;
196    if (!last || !dsc->driver->driver_spec)
197        return dsc->spec;
198    return dsc->driver->driver_spec(dsc->handle);
199}
200
201
202void atrf_reset(struct atrf_dsc *dsc)
203{
204    if (dsc->driver->reset)
205        dsc->driver->reset(dsc->handle);
206}
207
208
209void atrf_reset_rf(struct atrf_dsc *dsc)
210{
211    dsc->driver->reset_rf(dsc->handle);
212}
213
214
215enum atrf_chip_id atrf_identify(struct atrf_dsc *dsc)
216{
217    return dsc->chip_id;
218}
219
220
221int atrf_test_mode(struct atrf_dsc *dsc)
222{
223    if (!dsc->driver->test_mode)
224        return 0;
225    dsc->driver->test_mode(dsc->handle);
226    return 1;
227}
228
229
230int atrf_slp_tr(struct atrf_dsc *dsc, int on, int pulse)
231{
232    if (!dsc->driver->slp_tr)
233        return 0;
234    dsc->driver->slp_tr(dsc->handle, on, pulse);
235    return 1;
236}
237
238
239int atrf_set_clkm_generic(
240    void (*reg_write)(void *dsc, uint8_t reg, uint8_t value),
241    void *handle, int mhz)
242{
243    uint8_t clkm;
244
245    if (!mhz) {
246        reg_write(handle, REG_TRX_CTRL_0, 0); /* disable CLKM */
247        return 1;
248    }
249    switch (mhz) {
250    case 1:
251        clkm = CLKM_CTRL_1MHz;
252        break;
253    case 2:
254        clkm = CLKM_CTRL_2MHz;
255        break;
256    case 4:
257        clkm = CLKM_CTRL_4MHz;
258        break;
259    case 8:
260        clkm = CLKM_CTRL_8MHz;
261        break;
262    case 16:
263        clkm = CLKM_CTRL_16MHz;
264        break;
265    default:
266        fprintf(stderr, "unsupported CLKM frequency %d MHz\n", mhz);
267        return 0;
268    }
269    reg_write(handle, REG_TRX_CTRL_0,
270        (PAD_IO_8mA << PAD_IO_CLKM_SHIFT) | clkm);
271    return 1;
272}
273
274
275int atrf_set_clkm(struct atrf_dsc *dsc, int mhz)
276{
277    if (dsc->driver->set_clkm)
278        return dsc->driver->set_clkm(dsc->handle, mhz);
279    else
280        return atrf_set_clkm_generic(dsc->driver->reg_write,
281            dsc->handle, mhz);
282}
283
284
285void atrf_reg_write(struct atrf_dsc *dsc, uint8_t reg, uint8_t value)
286{
287    dsc->driver->reg_write(dsc->handle, reg, value);
288}
289
290
291uint8_t atrf_reg_read(struct atrf_dsc *dsc, uint8_t reg)
292{
293    return dsc->driver->reg_read(dsc->handle, reg);
294}
295
296
297void atrf_buf_write(struct atrf_dsc *dsc, const void *buf, int size)
298{
299    dsc->driver->buf_write(dsc->handle, buf, size);
300}
301
302
303int atrf_buf_read(struct atrf_dsc *dsc, void *buf, int size)
304{
305    return dsc->driver->buf_read(dsc->handle, buf, size);
306}
307
308
309void atrf_sram_write(struct atrf_dsc *dsc, uint8_t addr, uint8_t value)
310{
311    dsc->driver->sram_write(dsc->handle, addr, value);
312}
313
314
315uint8_t atrf_sram_read(struct atrf_dsc *dsc, uint8_t addr)
316{
317    return dsc->driver->sram_read(dsc->handle, addr);
318}
319
320
321int atrf_interrupt_wait(struct atrf_dsc *dsc, int timeout_ms)
322{
323    return dsc->driver->interrupt_wait(dsc->handle, timeout_ms);
324}
325
326
327void atrf_rx_mode(struct atrf_dsc *dsc, int on)
328{
329    if (dsc->driver->rx_mode)
330        dsc->driver->rx_mode(dsc->handle, on);
331}
332
333
334int atrf_rx(struct atrf_dsc *dsc, void *buf, int size, int timeout_ms,
335    uint8_t *lqi)
336{
337    if (!dsc->driver->rx)
338        return 0;
339    return dsc->driver->rx(dsc->handle, buf, size, timeout_ms, lqi);
340}
341
342
343void atrf_tx(struct atrf_dsc *dsc, const void *buf, int size)
344{
345    if (dsc->driver->tx)
346        dsc->driver->tx(dsc->handle, buf, size);
347}
348

Archive Download this file



interactive