1
0
mirror of git://projects.qi-hardware.com/ben-wpan.git synced 2024-12-23 03:45:11 +02:00

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
This commit is contained in:
Werner Almesberger 2011-07-07 15:51:07 -03:00
parent 50595979f5
commit 42483d67b4
4 changed files with 18 additions and 3 deletions

View File

@ -73,6 +73,7 @@
#define HAS_BOARD_SERNUM
extern uint8_t board_sernum[42];
extern uint8_t irq_serial;
void reset_rf(void);

View File

@ -150,13 +150,15 @@ static void done(void *user)
}
uint8_t irq_serial;
ISR(INT0_vect)
{
static uint8_t buf;
if (eps[1].state == EP_IDLE) {
led(1);
usb_send(&eps[1], &buf, 1, done, NULL);
irq_serial++;
usb_send(&eps[1], &irq_serial, 1, done, NULL);
}
}

View File

@ -217,6 +217,16 @@ static int my_setup(const struct setup_request *setup)
else
do_buf_write(NULL);
return 1;
case ATUSB_FROM_DEV(ATUSB_SPI_WRITE2_SYNC):
spi_begin();
spi_send(setup->wValue);
spi_send(setup->wIndex);
spi_end();
buf[0] = irq_serial;
if (setup->wLength)
usb_send(&eps[0], buf, 1, NULL, NULL);
return 1;
case ATUSB_FROM_DEV(ATUSB_SPI_READ1):
case ATUSB_FROM_DEV(ATUSB_SPI_READ2):
spi_begin();

View File

@ -39,6 +39,7 @@
* host-> ATUSB_SPI_WRITE byte0 byte1 #bytes
* ->host ATUSB_SPI_READ1 byte0 - #bytes
* ->host ATUSB_SPI_READ2 byte0 byte1 #bytes
* ->host ATUSB_SPI_WRITE2_SYNC byte0 bute1 0/1
*/
/*
@ -91,6 +92,7 @@ enum atspi_requests {
ATUSB_SPI_WRITE = 0x30, /* SPI group */
ATUSB_SPI_READ1,
ATUSB_SPI_READ2,
ATUSB_SPI_WRITE2_SYNC,
};