IEEE 802.15.4 subsystem
Sign in or create your account | Project List | Help
IEEE 802.15.4 subsystem Commit Details
Date: | 2010-09-09 22:23:47 (13 years 6 months ago) |
---|---|
Author: | Werner Almesberger |
Commit: | 9162689d3e913fc105dca7e04288e2f8f52e7a95 |
Message: | 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 |
Files: |
tools/atspi-txrx/atspi-txrx.c (6 diffs) |
Change Details
tools/atspi-txrx/atspi-txrx.c | ||
---|---|---|
63 | 63 | #endif |
64 | 64 | atspi_reg_write(dsc, REG_TRX_CTRL_0, 0); /* disable CLKM */ |
65 | 65 | |
66 | (void) atspi_reg_read(dsc, REG_IRQ_STATUS); | |
67 | ||
66 | 68 | return dsc; |
67 | 69 | } |
68 | 70 | |
69 | 71 | |
72 | static uint8_t wait_for_interrupt(struct atspi_dsc *dsc, uint8_t wait_for, | |
73 | uint8_t ignore, int sleep_us, int timeout) | |
74 | { | |
75 | uint8_t irq, show; | |
76 | ||
77 | while (1) { | |
78 | while (!atspi_interrupt(dsc)) { | |
79 | usleep(sleep_us); | |
80 | if (timeout && !--timeout) | |
81 | return 0; | |
82 | } | |
83 | irq = atspi_reg_read(dsc, REG_IRQ_STATUS); | |
84 | if (atspi_error(dsc)) | |
85 | exit(1); | |
86 | if (!irq) | |
87 | continue; | |
88 | show = irq & ~ignore; | |
89 | if ((irq & wait_for) && !show) | |
90 | break; | |
91 | fprintf(stderr, "IRQ (0x%02x):", irq); | |
92 | if (irq & IRQ_PLL_LOCK) | |
93 | fprintf(stderr, " PLL_LOCK"); | |
94 | if (irq & IRQ_PLL_UNLOCK) | |
95 | fprintf(stderr, " PLL_UNLOCK"); | |
96 | if (irq & IRQ_RX_START) | |
97 | fprintf(stderr, " RX_START"); | |
98 | if (irq & IRQ_TRX_END) | |
99 | fprintf(stderr, " TRX_END"); | |
100 | if (irq & IRQ_TRX_UR) | |
101 | fprintf(stderr, " TRX_UR"); | |
102 | if (irq & IRQ_BAT_LOW) | |
103 | fprintf(stderr, " BAT_LOW"); | |
104 | fprintf(stderr, "\n"); | |
105 | if (irq & wait_for) | |
106 | break; | |
107 | } | |
108 | return irq; | |
109 | } | |
110 | ||
111 | ||
70 | 112 | static void set_channel(struct atspi_dsc *dsc, int channel) |
71 | 113 | { |
72 | 114 | atspi_reg_write(dsc, REG_PHY_CC_CCA, (1 << CCA_MODE_SHIFT) | channel); |
73 | /* | |
74 | * 150 us, according to AVR2001 section 3.5. Note that we should just | |
75 | * wait for the PPL_LOCK interrupt. | |
76 | */ | |
77 | usleep(1000); | |
78 | 115 | } |
79 | 116 | |
80 | 117 | |
... | ... | |
91 | 128 | |
92 | 129 | static void receive(struct atspi_dsc *dsc) |
93 | 130 | { |
94 | uint8_t irq; | |
95 | 131 | uint8_t buf[MAX_PSDU+1]; /* PSDU+LQI */ |
96 | 132 | int n, ok, i; |
97 | uint8_t lq; | |
133 | uint8_t ed, lqi; | |
98 | 134 | |
99 | 135 | atspi_reg_write(dsc, REG_TRX_STATE, TRX_CMD_RX_ON); |
100 | ||
101 | (void) atspi_reg_read(dsc, REG_IRQ_STATUS); | |
136 | /* | |
137 | * 180 us, according to AVR2001 section 4.2. We time out after | |
138 | * nominally 200 us. | |
139 | */ | |
140 | wait_for_interrupt(dsc, IRQ_PLL_LOCK, IRQ_PLL_LOCK, 10, 20); | |
102 | 141 | |
103 | 142 | fprintf(stderr, "Ready.\n"); |
104 | while (1) { | |
105 | while (!atspi_interrupt(dsc)) | |
106 | usleep(10); | |
107 | irq = atspi_reg_read(dsc, REG_IRQ_STATUS); | |
108 | if (atspi_error(dsc)) | |
109 | exit(1); | |
110 | if (!irq) | |
111 | continue; | |
112 | if (irq == IRQ_TRX_END) | |
113 | break; | |
114 | fprintf(stderr, "IRQ (0x%02x):", irq); | |
115 | if (irq & IRQ_PLL_LOCK) | |
116 | fprintf(stderr, " PLL_LOCK"); | |
117 | if (irq & IRQ_PLL_UNLOCK) | |
118 | fprintf(stderr, " PLL_UNLOCK"); | |
119 | if (irq & IRQ_RX_START) | |
120 | fprintf(stderr, " RX_START"); | |
121 | if (irq & IRQ_TRX_UR) | |
122 | fprintf(stderr, " TRX_UR"); | |
123 | if (irq & IRQ_BAT_LOW) | |
124 | fprintf(stderr, " BAT_LOW"); | |
125 | fprintf(stderr, "\n"); | |
126 | if (irq & IRQ_TRX_END) | |
127 | break; | |
128 | } | |
143 | wait_for_interrupt(dsc, IRQ_TRX_END, IRQ_TRX_END | IRQ_RX_START, | |
144 | 10, 0); | |
129 | 145 | |
130 | 146 | n = atspi_buf_read(dsc, buf, sizeof(buf)); |
131 | 147 | if (n < 0) |
... | ... | |
134 | 150 | fprintf(stderr, "%d bytes received\n", n); |
135 | 151 | exit(1); |
136 | 152 | } |
153 | ed = atspi_reg_read(dsc, REG_PHY_ED_LEVEL); | |
137 | 154 | ok = !!(atspi_reg_read(dsc, REG_PHY_RSSI) & RX_CRC_VALID); |
138 | lq = buf[n-1]; | |
139 | fprintf(stderr, "%d bytes payload, CRC %s, LQI %u\n", | |
140 | n-3, ok ? "OK" : "BAD", lq); | |
155 | lqi = buf[n-1]; | |
156 | fprintf(stderr, "%d bytes payload, CRC %s, LQI %u, ED %d dBm\n", | |
157 | n-3, ok ? "OK" : "BAD", lqi, -91+ed); | |
141 | 158 | for (i = 0; i != n-3; i++) |
142 | 159 | putchar(buf[i] < ' ' || buf[i] > '~' ? '?' : buf[i]); |
143 | 160 | putchar('\n'); |
... | ... | |
149 | 166 | uint8_t buf[MAX_PSDU]; |
150 | 167 | |
151 | 168 | atspi_reg_write(dsc, REG_TRX_STATE, TRX_CMD_PLL_ON); |
169 | /* | |
170 | * 180 us, according to AVR2001 section 4.3. We time out after | |
171 | * nominally 200 us. | |
172 | */ | |
173 | wait_for_interrupt(dsc, IRQ_PLL_LOCK, IRQ_PLL_LOCK, 10, 20); | |
152 | 174 | |
153 | 175 | /* |
154 | 176 | * We need to copy the message to append the CRC placeholders. |
... | ... | |
158 | 180 | |
159 | 181 | /* @@@ should wait for clear channel */ |
160 | 182 | atspi_reg_write(dsc, REG_TRX_STATE, TRX_CMD_TX_START); |
161 | /* @@@ should wait for TX done */ | |
183 | ||
184 | /* wait up to 10 ms (nominally) */ | |
185 | wait_for_interrupt(dsc, IRQ_TRX_END, IRQ_TRX_END | IRQ_PLL_LOCK, | |
186 | 10, 1000); | |
162 | 187 | } |
163 | 188 | |
164 | 189 | |
... | ... | |
224 | 249 | usage(*argv); |
225 | 250 | } |
226 | 251 | |
252 | atspi_close(dsc); | |
253 | ||
227 | 254 | return 0; |
228 | 255 | } |