Root/tools/lib/atusb.c

Source at commit 9746205fd92dd48855d6cd297fcce2cd4188b141 created 8 years 3 months ago.
By Werner Almesberger, tools/lib/atusb.c: added missing standard #includes
1/*
2 * lib/atusb.c - ATUSB access functions library (USB version)
3 *
4 * Written 2010-2011 by Werner Almesberger
5 * Copyright 2010-2011 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 <usb.h>
18
19#include "atusb/ep0.h"
20#include "atusb/usb-ids.h"
21
22#include "usbopen.h"
23#include "driver.h"
24
25
26#define FROM_DEV ATUSB_FROM_DEV(0)
27#define TO_DEV ATUSB_TO_DEV(0)
28
29
30struct atusb_dsc {
31    usb_dev_handle *dev;
32    int error;
33};
34
35/* ----- error handling ---------------------------------------------------- */
36
37
38static int atusb_error(void *handle)
39{
40    struct atusb_dsc *dsc = handle;
41
42    return dsc->error;
43}
44
45
46static int atusb_clear_error(void *handle)
47{
48    struct atusb_dsc *dsc = handle;
49    int ret;
50
51    ret = dsc->error;
52    dsc->error = 0;
53    return ret;
54}
55
56
57/* ----- open/close -------------------------------------------------------- */
58
59
60static void *atusb_open(const char *arg)
61{
62    usb_dev_handle *dev;
63    struct atusb_dsc *dsc;
64
65    usb_unrestrict();
66    if (arg)
67        restrict_usb_path(arg);
68    dev = open_usb(USB_VENDOR, USB_PRODUCT);
69    if (!dev) {
70        fprintf(stderr, ":-(\n");
71        return NULL;
72    }
73
74    dsc = malloc(sizeof(*dsc));
75    if (!dsc) {
76        perror("malloc");
77        exit(1);
78    }
79
80    dsc->dev = dev;
81    dsc->error = 0;
82
83    return dsc;
84}
85
86
87static void atusb_close(void *handle)
88{
89    /* to do */
90}
91
92
93/* ----- device mode ------------------------------------------------------- */
94
95
96static void atusb_reset(void *handle)
97{
98    struct atusb_dsc *dsc = handle;
99    int res;
100
101    if (dsc->error)
102        return;
103
104    res =
105        usb_control_msg(dsc->dev, TO_DEV, ATUSB_RESET, 0, 0, NULL, 0, 1000);
106    if (res < 0) {
107        fprintf(stderr, "ATUSB_RESET: %d\n", res);
108        dsc->error = 1;
109    }
110}
111
112
113static void atusb_reset_rf(void *handle)
114{
115    struct atusb_dsc *dsc = handle;
116    int res;
117
118    if (dsc->error)
119        return;
120
121    res = usb_control_msg(dsc->dev, TO_DEV, ATUSB_RF_RESET, 0, 0, NULL,
122        0, 1000);
123    if (res < 0) {
124        fprintf(stderr, "ATUSB_RF_RESET: %d\n", res);
125        dsc->error = 1;
126    }
127}
128
129
130static void atusb_test_mode(void *handle)
131{
132    struct atusb_dsc *dsc = handle;
133    int res;
134
135    if (dsc->error)
136        return;
137
138    res =
139        usb_control_msg(dsc->dev, TO_DEV, ATUSB_TEST, 0, 0, NULL, 0, 1000);
140    if (res < 0) {
141        fprintf(stderr, "ATUSB_TEST: %d\n", res);
142        dsc->error = 1;
143    }
144}
145
146
147/* ----- register access --------------------------------------------------- */
148
149
150static void atusb_reg_write(void *handle, uint8_t reg, uint8_t value)
151{
152    struct atusb_dsc *dsc = handle;
153    int res;
154
155    if (dsc->error)
156        return;
157
158    res = usb_control_msg(dsc->dev, TO_DEV, ATUSB_REG_WRITE, value, reg,
159        NULL, 0, 1000);
160    if (res < 0) {
161        fprintf(stderr, "ATUSB_REG_WRITE: %d\n", res);
162        dsc->error = 1;
163    }
164}
165
166
167static uint8_t atusb_reg_read(void *handle, uint8_t reg)
168{
169    struct atusb_dsc *dsc = handle;
170    uint8_t value = 0;
171    int res;
172
173    if (dsc->error)
174        return 0;
175
176    res = usb_control_msg(dsc->dev, FROM_DEV, ATUSB_REG_READ, 0, reg,
177        (void *) &value, 1, 1000);
178    if (res < 0) {
179        fprintf(stderr, "ATUSB_REG_READ: %d\n", res);
180        dsc->error = 1;
181    }
182    return value;
183}
184
185
186/* ----- frame buffer access ----------------------------------------------- */
187
188
189static void atusb_buf_write(void *handle, const void *buf, int size)
190{
191    struct atusb_dsc *dsc = handle;
192    int res;
193
194    if (dsc->error)
195        return;
196
197    res = usb_control_msg(dsc->dev, TO_DEV, ATUSB_BUF_WRITE, 0, 0,
198        (void *) buf, size, 1000);
199    if (res < 0) {
200        fprintf(stderr, "ATUSB_BUF_WRITE: %d\n", res);
201        dsc->error = 1;
202    }
203}
204
205
206static int atusb_buf_read(void *handle, void *buf, int size)
207{
208    struct atusb_dsc *dsc = handle;
209    int res;
210
211    if (dsc->error)
212        return -1;
213
214    res = usb_control_msg(dsc->dev, FROM_DEV, ATUSB_BUF_READ, 0, 0,
215        buf, size, 1000);
216    if (res < 0) {
217        fprintf(stderr, "ATUSB_BUF_READ: %d\n", res);
218        dsc->error = 1;
219    }
220
221    return res;
222}
223
224
225/* ----- SRAM access ------------------------------------------------------- */
226
227
228static void atusb_sram_write(void *handle, uint8_t addr, uint8_t value)
229{
230    struct atusb_dsc *dsc = handle;
231    int res;
232
233    if (dsc->error)
234        return;
235
236    res = usb_control_msg(dsc->dev, TO_DEV, ATUSB_SRAM_WRITE, 0, addr,
237        &value, 1, 1000);
238    if (res < 0) {
239        fprintf(stderr, "ATUSB_SRAM_WRITE: %d\n", res);
240        dsc->error = 1;
241    }
242}
243
244
245static uint8_t atusb_sram_read(void *handle, uint8_t addr)
246{
247    struct atusb_dsc *dsc = handle;
248    uint8_t value = 0;
249    int res;
250
251    if (dsc->error)
252        return 0;
253
254    res = usb_control_msg(dsc->dev, FROM_DEV, ATUSB_SRAM_READ, 0, addr,
255        (void *) &value, 1, 1000);
256    if (res < 0) {
257        fprintf(stderr, "ATUSB_SRAM_READ: %d\n", res);
258        dsc->error = 1;
259    }
260    return value;
261}
262
263
264/* ----- SLP_TR ------------------------------------------------------------ */
265
266
267static void atusb_slp_tr(void *handle, int on, int pulse)
268{
269    struct atusb_dsc *dsc = handle;
270    int res;
271
272    if (dsc->error)
273        return;
274
275    if (!on || !pulse) {
276        fprintf(stderr,
277            "SLP_TR mode on=%d pulse=%d not supported\n", on, pulse);
278        return;
279    }
280
281    res = usb_control_msg(dsc->dev, TO_DEV, ATUSB_SLP_TR, 0, 0, NULL, 0,
282        1000);
283    if (res < 0) {
284        fprintf(stderr, "ATUSB_SLP_TR: %d\n", res);
285        dsc->error = 1;
286    }
287}
288
289
290/* ----- RF interrupt ------------------------------------------------------ */
291
292
293static int atusb_interrupt(void *handle)
294{
295    struct atusb_dsc *dsc = handle;
296    uint8_t buf;
297    int res;
298
299    if (dsc->error)
300        return -1;
301    
302    res = usb_control_msg(dsc->dev, FROM_DEV, ATUSB_POLL_INT, 0, 0,
303        (void *) &buf, 1, 1000);
304    if (res < 0) {
305        fprintf(stderr, "ATUSB_POLL_INT: %d\n", res);
306        dsc->error = 1;
307        return -1;
308    }
309
310    return buf;
311}
312
313
314/* ----- CLKM handling ----------------------------------------------------- */
315
316
317/*
318 * ATmega32U2-based boards don't allow disabling CLKM, so we keep it at 8 MHz.
319 * We could accommodate a choice between 8 MHz and 16 MHz, but that's for
320 * later.
321 */
322
323static int atusb_set_clkm(void *handle, int mhz)
324{
325    struct atusb_dsc *dsc = handle;
326    uint8_t ids[3];
327    int res;
328
329    if (dsc->error)
330        return 0;
331    res = usb_control_msg(dsc->dev, FROM_DEV, ATUSB_ID, 0, 0,
332        (void *) ids, 3, 1000);
333    if (res < 0) {
334        fprintf(stderr, "ATUSB_ID: %s\n", usb_strerror());
335        dsc->error = 1;
336        return 0;
337    }
338    switch (ids[2]) {
339    case HW_TYPE_100813:
340    case HW_TYPE_101216:
341        break;
342    case HW_TYPE_110131:
343        if (mhz == 0 || mhz == 8)
344            return 1;
345        fprintf(stderr, "this board only supports CLKM = 8 MHz\n");
346        return 0;
347    default:
348        fprintf(stderr,
349            "atusb_set_clkm: unknown hardware type 0x%02x\n", ids[2]);
350        return 0;
351    }
352    return atrf_set_clkm_generic(atusb_reg_write, dsc, mhz);
353}
354
355
356/* ----- Driver-specific hacks --------------------------------------------- */
357
358
359void *atusb_dev_handle(void *handle)
360{
361    struct atusb_dsc *dsc = handle;
362
363    return dsc->dev;
364}
365
366
367/* ----- driver interface -------------------------------------------------- */
368
369
370struct atrf_driver atusb_driver = {
371    .name = "usb",
372    .open = atusb_open,
373    .close = atusb_close,
374    .error = atusb_error,
375    .clear_error = atusb_clear_error,
376    .reset = atusb_reset,
377    .reset_rf = atusb_reset_rf,
378    .test_mode = atusb_test_mode,
379    .slp_tr = atusb_slp_tr,
380    .set_clkm = atusb_set_clkm,
381    .reg_write = atusb_reg_write,
382    .reg_read = atusb_reg_read,
383    .buf_write = atusb_buf_write,
384    .buf_read = atusb_buf_read,
385    .sram_write = atusb_sram_write,
386    .sram_read = atusb_sram_read,
387    .interrupt = atusb_interrupt,
388};
389

Archive Download this file



interactive