mirror of
git://projects.qi-hardware.com/ben-wpan.git
synced 2024-11-25 20:56:00 +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:
parent
6e726d1fb9
commit
9162689d3e
@ -63,18 +63,55 @@ static struct atspi_dsc *init_txrx(int trim)
|
||||
#endif
|
||||
atspi_reg_write(dsc, REG_TRX_CTRL_0, 0); /* disable CLKM */
|
||||
|
||||
(void) atspi_reg_read(dsc, REG_IRQ_STATUS);
|
||||
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
uint8_t irq;
|
||||
uint8_t buf[MAX_PSDU+1]; /* PSDU+LQI */
|
||||
int n, ok, i;
|
||||
uint8_t lq;
|
||||
uint8_t ed, lqi;
|
||||
|
||||
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");
|
||||
while (1) {
|
||||
while (!atspi_interrupt(dsc))
|
||||
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;
|
||||
}
|
||||
wait_for_interrupt(dsc, IRQ_TRX_END, IRQ_TRX_END | IRQ_RX_START,
|
||||
10, 0);
|
||||
|
||||
n = atspi_buf_read(dsc, buf, sizeof(buf));
|
||||
if (n < 0)
|
||||
@ -134,10 +150,11 @@ static void receive(struct atspi_dsc *dsc)
|
||||
fprintf(stderr, "%d bytes received\n", n);
|
||||
exit(1);
|
||||
}
|
||||
ed = atspi_reg_read(dsc, REG_PHY_ED_LEVEL);
|
||||
ok = !!(atspi_reg_read(dsc, REG_PHY_RSSI) & RX_CRC_VALID);
|
||||
lq = buf[n-1];
|
||||
fprintf(stderr, "%d bytes payload, CRC %s, LQI %u\n",
|
||||
n-3, ok ? "OK" : "BAD", lq);
|
||||
lqi = buf[n-1];
|
||||
fprintf(stderr, "%d bytes payload, CRC %s, LQI %u, ED %d dBm\n",
|
||||
n-3, ok ? "OK" : "BAD", lqi, -91+ed);
|
||||
for (i = 0; i != n-3; i++)
|
||||
putchar(buf[i] < ' ' || buf[i] > '~' ? '?' : buf[i]);
|
||||
putchar('\n');
|
||||
@ -149,6 +166,11 @@ static void transmit(struct atspi_dsc *dsc, const char *msg)
|
||||
uint8_t buf[MAX_PSDU];
|
||||
|
||||
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.
|
||||
@ -158,7 +180,10 @@ static void transmit(struct atspi_dsc *dsc, const char *msg)
|
||||
|
||||
/* @@@ should wait for clear channel */
|
||||
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);
|
||||
}
|
||||
|
||||
atspi_close(dsc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user