1
0
mirror of git://projects.qi-hardware.com/ben-wpan.git synced 2024-11-29 13:42:47 +02:00

Cleaned up interrupt handling in atspi-txrx. Report ED. Shut down at end.

- tools/atspi-txrx/atspi-txrx.c (receive, wait_for_interrupt): moved wait
  for interrupt logic to separate function and made it more versatile
- tools/atspi-txrx/atspi-txrx.c (init_txrx, receive): clear interrupts in
  init_txrx now, so that also transmit has a clear interrupt register
- tools/atspi-txrx/atspi-txrx.c (set_channel): since we're in TRX_OFF,
  don't wait for PLL lock
- tools/atspi-txrx/atspi-txrx.c (receive): wait for PLL lock interrupt
  after activating receiver
- tools/atspi-txrx/atspi-txrx.c (transmit): wait for PLL lock interrupt
  after activating the PLL
- tools/atspi-txrx/atspi-txrx.c (transmit): wait for TRX_END interrupt
  after sending a frame
- tools/atspi-txrx/atspi-txrx.c (receive): report the Energy Density (ED)
  after receiving a frame
- tools/atspi-txrx/atspi-txrx.c (main): shut down the board with
  atspi_close, so that we can hot-swap safely
This commit is contained in:
Werner Almesberger 2010-09-09 17:23:47 -03:00
parent 6e726d1fb9
commit 9162689d3e

View File

@ -63,18 +63,55 @@ static struct atspi_dsc *init_txrx(int trim)
#endif #endif
atspi_reg_write(dsc, REG_TRX_CTRL_0, 0); /* disable CLKM */ atspi_reg_write(dsc, REG_TRX_CTRL_0, 0); /* disable CLKM */
(void) atspi_reg_read(dsc, REG_IRQ_STATUS);
return dsc; return dsc;
} }
static uint8_t wait_for_interrupt(struct atspi_dsc *dsc, uint8_t wait_for,
uint8_t ignore, int sleep_us, int timeout)
{
uint8_t irq, show;
while (1) {
while (!atspi_interrupt(dsc)) {
usleep(sleep_us);
if (timeout && !--timeout)
return 0;
}
irq = atspi_reg_read(dsc, REG_IRQ_STATUS);
if (atspi_error(dsc))
exit(1);
if (!irq)
continue;
show = irq & ~ignore;
if ((irq & wait_for) && !show)
break;
fprintf(stderr, "IRQ (0x%02x):", irq);
if (irq & IRQ_PLL_LOCK)
fprintf(stderr, " PLL_LOCK");
if (irq & IRQ_PLL_UNLOCK)
fprintf(stderr, " PLL_UNLOCK");
if (irq & IRQ_RX_START)
fprintf(stderr, " RX_START");
if (irq & IRQ_TRX_END)
fprintf(stderr, " TRX_END");
if (irq & IRQ_TRX_UR)
fprintf(stderr, " TRX_UR");
if (irq & IRQ_BAT_LOW)
fprintf(stderr, " BAT_LOW");
fprintf(stderr, "\n");
if (irq & wait_for)
break;
}
return irq;
}
static void set_channel(struct atspi_dsc *dsc, int channel) static void set_channel(struct atspi_dsc *dsc, int channel)
{ {
atspi_reg_write(dsc, REG_PHY_CC_CCA, (1 << CCA_MODE_SHIFT) | channel); atspi_reg_write(dsc, REG_PHY_CC_CCA, (1 << CCA_MODE_SHIFT) | channel);
/*
* 150 us, according to AVR2001 section 3.5. Note that we should just
* wait for the PPL_LOCK interrupt.
*/
usleep(1000);
} }
@ -91,41 +128,20 @@ static void set_power(struct atspi_dsc *dsc, double power)
static void receive(struct atspi_dsc *dsc) static void receive(struct atspi_dsc *dsc)
{ {
uint8_t irq;
uint8_t buf[MAX_PSDU+1]; /* PSDU+LQI */ uint8_t buf[MAX_PSDU+1]; /* PSDU+LQI */
int n, ok, i; int n, ok, i;
uint8_t lq; uint8_t ed, lqi;
atspi_reg_write(dsc, REG_TRX_STATE, TRX_CMD_RX_ON); atspi_reg_write(dsc, REG_TRX_STATE, TRX_CMD_RX_ON);
/*
(void) atspi_reg_read(dsc, REG_IRQ_STATUS); * 180 us, according to AVR2001 section 4.2. We time out after
* nominally 200 us.
*/
wait_for_interrupt(dsc, IRQ_PLL_LOCK, IRQ_PLL_LOCK, 10, 20);
fprintf(stderr, "Ready.\n"); fprintf(stderr, "Ready.\n");
while (1) { wait_for_interrupt(dsc, IRQ_TRX_END, IRQ_TRX_END | IRQ_RX_START,
while (!atspi_interrupt(dsc)) 10, 0);
usleep(10);
irq = atspi_reg_read(dsc, REG_IRQ_STATUS);
if (atspi_error(dsc))
exit(1);
if (!irq)
continue;
if (irq == IRQ_TRX_END)
break;
fprintf(stderr, "IRQ (0x%02x):", irq);
if (irq & IRQ_PLL_LOCK)
fprintf(stderr, " PLL_LOCK");
if (irq & IRQ_PLL_UNLOCK)
fprintf(stderr, " PLL_UNLOCK");
if (irq & IRQ_RX_START)
fprintf(stderr, " RX_START");
if (irq & IRQ_TRX_UR)
fprintf(stderr, " TRX_UR");
if (irq & IRQ_BAT_LOW)
fprintf(stderr, " BAT_LOW");
fprintf(stderr, "\n");
if (irq & IRQ_TRX_END)
break;
}
n = atspi_buf_read(dsc, buf, sizeof(buf)); n = atspi_buf_read(dsc, buf, sizeof(buf));
if (n < 0) if (n < 0)
@ -134,10 +150,11 @@ static void receive(struct atspi_dsc *dsc)
fprintf(stderr, "%d bytes received\n", n); fprintf(stderr, "%d bytes received\n", n);
exit(1); exit(1);
} }
ed = atspi_reg_read(dsc, REG_PHY_ED_LEVEL);
ok = !!(atspi_reg_read(dsc, REG_PHY_RSSI) & RX_CRC_VALID); ok = !!(atspi_reg_read(dsc, REG_PHY_RSSI) & RX_CRC_VALID);
lq = buf[n-1]; lqi = buf[n-1];
fprintf(stderr, "%d bytes payload, CRC %s, LQI %u\n", fprintf(stderr, "%d bytes payload, CRC %s, LQI %u, ED %d dBm\n",
n-3, ok ? "OK" : "BAD", lq); n-3, ok ? "OK" : "BAD", lqi, -91+ed);
for (i = 0; i != n-3; i++) for (i = 0; i != n-3; i++)
putchar(buf[i] < ' ' || buf[i] > '~' ? '?' : buf[i]); putchar(buf[i] < ' ' || buf[i] > '~' ? '?' : buf[i]);
putchar('\n'); putchar('\n');
@ -149,6 +166,11 @@ static void transmit(struct atspi_dsc *dsc, const char *msg)
uint8_t buf[MAX_PSDU]; uint8_t buf[MAX_PSDU];
atspi_reg_write(dsc, REG_TRX_STATE, TRX_CMD_PLL_ON); atspi_reg_write(dsc, REG_TRX_STATE, TRX_CMD_PLL_ON);
/*
* 180 us, according to AVR2001 section 4.3. We time out after
* nominally 200 us.
*/
wait_for_interrupt(dsc, IRQ_PLL_LOCK, IRQ_PLL_LOCK, 10, 20);
/* /*
* We need to copy the message to append the CRC placeholders. * We need to copy the message to append the CRC placeholders.
@ -158,7 +180,10 @@ static void transmit(struct atspi_dsc *dsc, const char *msg)
/* @@@ should wait for clear channel */ /* @@@ should wait for clear channel */
atspi_reg_write(dsc, REG_TRX_STATE, TRX_CMD_TX_START); atspi_reg_write(dsc, REG_TRX_STATE, TRX_CMD_TX_START);
/* @@@ should wait for TX done */
/* wait up to 10 ms (nominally) */
wait_for_interrupt(dsc, IRQ_TRX_END, IRQ_TRX_END | IRQ_PLL_LOCK,
10, 1000);
} }
@ -224,5 +249,7 @@ int main(int argc, char *const *argv)
usage(*argv); usage(*argv);
} }
atspi_close(dsc);
return 0; return 0;
} }