Date:2011-07-07 20:51:07 (8 years 2 months ago)
Author:Werner Almesberger
Commit:42483d67b4b8800752870c261bc340896861a1db
Message:atusb/fw/: added improved support for interrupt synchronization

At an interrupt barrier, the host must be able to ensure that no
interrupt generated before reaching the barrier is still pending and
will be delivered after crossing the barrier.

For this, we introduce the following concept:

- interrupts have a serial number. This number is sent to the host
on EP 1 (currently bulk) to signal the interrupt, instead of the
zero byte we used previously.

- the new request ATUSB_SPI_WRITE2_SYNC returns the interrupt
serial number from after the register write (the register write
itself is the interrupt barrier).

- the host can now check if the serial indicated from bulk and the
serial from ATUSB_SPI_WRITE2_SYNC are the same. If yes, interrupts
are synchronized. If not, it has to wait for the interrupt to be
signaled on EP 1.

We should also consider the case that the interrupt serial has gotten
ahead of ATUSB_SPI_WRITE2_SYNC. But that seems to happen rarely. In
any case, it's something for the host driver to worry about, not for
the firmware.

- board.h (irq_serial), board_app.c (irq_serial, INT0_vect): count
the interrupt serial number and return it when signaling the
interrupt
- include/atusb/ep0.h (ATUSB_SPI_WRITE2_SYNC), ep0.c (my_setup):
new request ATUSB_SPI_WRITE2_SYNC that does a register write, then
returns the interrupt serial
Files: atusb/fw/board.h (1 diff)
atusb/fw/board_app.c (1 diff)
atusb/fw/ep0.c (1 diff)
atusb/fw/include/atusb/ep0.h (2 diffs)

Change Details

atusb/fw/board.h
7373#define HAS_BOARD_SERNUM
7474
7575extern uint8_t board_sernum[42];
76extern uint8_t irq_serial;
7677
7778
7879void reset_rf(void);
atusb/fw/board_app.c
150150}
151151
152152
153uint8_t irq_serial;
154
155
153156ISR(INT0_vect)
154157{
155    static uint8_t buf;
156
157158    if (eps[1].state == EP_IDLE) {
158159        led(1);
159        usb_send(&eps[1], &buf, 1, done, NULL);
160        irq_serial++;
161        usb_send(&eps[1], &irq_serial, 1, done, NULL);
160162    }
161163}
162164
atusb/fw/ep0.c
217217        else
218218            do_buf_write(NULL);
219219        return 1;
220    case ATUSB_FROM_DEV(ATUSB_SPI_WRITE2_SYNC):
221        spi_begin();
222        spi_send(setup->wValue);
223        spi_send(setup->wIndex);
224        spi_end();
225        buf[0] = irq_serial;
226        if (setup->wLength)
227            usb_send(&eps[0], buf, 1, NULL, NULL);
228        return 1;
229
220230    case ATUSB_FROM_DEV(ATUSB_SPI_READ1):
221231    case ATUSB_FROM_DEV(ATUSB_SPI_READ2):
222232        spi_begin();
atusb/fw/include/atusb/ep0.h
3939 * host-> ATUSB_SPI_WRITE byte0 byte1 #bytes
4040 * ->host ATUSB_SPI_READ1 byte0 - #bytes
4141 * ->host ATUSB_SPI_READ2 byte0 byte1 #bytes
42 * ->host ATUSB_SPI_WRITE2_SYNC byte0 bute1 0/1
4243 */
4344
4445/*
...... 
9192    ATUSB_SPI_WRITE = 0x30, /* SPI group */
9293    ATUSB_SPI_READ1,
9394    ATUSB_SPI_READ2,
95    ATUSB_SPI_WRITE2_SYNC,
9496};
9597
9698

Archive Download the corresponding diff file



interactive