Date:2011-06-20 21:06:51 (9 years 1 month ago)
Author:Werner Almesberger
Commit:110ecf67a1fa43f650397936713d28fad5ec608a
Message:tools/lib/: added interrupt_wait support to atusb and atusb-spi driver

- atusb-common.c (atusb_open): claim interface, so that we can do bulk
I/O without complaints from the kernel
- atusb-common.h (atusb_interrupt_wait), atusb-common.c: blocking read
for interrupt status byte on EP1
- atusb.c (atusb_driver), atusb-spi.c (atusb_spi_driver): provide the
interrupt_wait operation
Files: tools/lib/atusb-common.c (4 diffs)
tools/lib/atusb-common.h (1 diff)
tools/lib/atusb-spi.c (1 diff)
tools/lib/atusb.c (1 diff)

Change Details

tools/lib/atusb-common.c
1515#include <stdlib.h>
1616#include <stdio.h>
1717#include <usb.h>
18#include <errno.h>
1819
1920#include "atusb/ep0.h"
2021#include "atusb/usb-ids.h"
2122
23#include "at86rf230.h"
2224#include "usbopen.h"
2325#include "driver.h"
2426#include "atusb-common.h"
...... 
5355{
5456    usb_dev_handle *dev;
5557    struct atusb_dsc *dsc;
58    int res;
5659
5760    usb_unrestrict();
5861    if (arg)
...... 
6366        return NULL;
6467    }
6568
69    res = usb_claim_interface(dev, 0);
70    if (res) {
71        fprintf(stderr, "usb_claim_interface: %d\n", res);
72        return NULL;
73    }
74
6675    dsc = malloc(sizeof(*dsc));
6776    if (!dsc) {
6877        perror("malloc");
...... 
186195}
187196
188197
198/*
199 * The logic here is a bit tricky. Assuming that we can get a lot of
200 * interrupts, system state can change as follows:
201 *
202 * Event IRQ_STATUS EP1 on atusb EP1 on host irq
203 * INT (var)
204 * -------------------- ------- --- ------------ ----------- -----
205 * interrupt A A H EP_IDLE - -
206 * INT0 handler - - EP_TX (A) - -
207 * interrupt B B H EP_TX (A) - -
208 * INT0 handler B H EP_TX (A) - -
209 * IN from host B H EP_IDLE A -
210 * interrupt C B+C H EP_IDLE A -
211 * call to atusb_interrupt_wait
212 * read IRQ_STATUS - - EP_IDLE A B+C
213 * interrupt D D H EP_IDLE A B+C
214 * INT0 handler - - EP_TX (D) A B+C
215 * IN from host - - EP_IDLE A, D B+C
216 * usb_bulk_read - - EP_IDLE - A+B+C+D
217 * usb_bulk_read -> no more data, done
218 *
219 * We therefore have to consider interrupts queued up at the host and pending
220 * in REG_IRQ_STATUS in addition to anything that may arrive while we wait.
221 */
222
223
224int atusb_interrupt_wait(void *handle, int timeout_ms)
225{
226    struct atusb_dsc *dsc = handle;
227    uint8_t irq, buf[100];
228    int res, i;
229
230    if (dsc->error)
231        return 0;
232
233    irq = atusb_driver.reg_read(handle, REG_IRQ_STATUS);
234    if (irq)
235        timeout_ms = 1;
236
237    while (1) {
238        res = usb_bulk_read(dsc->dev, 1,
239            (char *) &buf, sizeof(buf), timeout_ms);
240        if (res == -ETIMEDOUT)
241            break;
242        if (res < 0) {
243            fprintf(stderr, "usb_bulk_read: %d\n", res);
244            dsc->error = 1;
245            return 0;
246                /* < 0 is already taken by atrf_interrupt_wait */
247        }
248        timeout_ms = 1;
249        for (i = 0; i != res; i++)
250            irq |= buf[i];
251    }
252    return irq;
253}
254
255
189256/* ----- CLKM handling ----------------------------------------------------- */
190257
191258
tools/lib/atusb-common.h
3434void atusb_test_mode(void *handle);
3535void atusb_slp_tr(void *handle, int on, int pulse);
3636int atusb_interrupt(void *handle);
37int atusb_interrupt_wait(void *handle, int timeout_ms);
38
3739int atusb_set_clkm(void *handle, int mhz);
3840
3941#endif /* !ATUSB_COMMON_H */
tools/lib/atusb-spi.c
168168    .sram_write = atusb_spi_sram_write,
169169    .sram_read = atusb_spi_sram_read,
170170    .interrupt = atusb_interrupt,
171    .interrupt_wait = atusb_interrupt_wait,
171172};
tools/lib/atusb.c
162162    .sram_write = atusb_sram_write,
163163    .sram_read = atusb_sram_read,
164164    .interrupt = atusb_interrupt,
165    .interrupt_wait = atusb_interrupt_wait,
165166};

Archive Download the corresponding diff file



interactive