IEEE 802.15.4 subsystem
Sign in or create your account | Project List | Help
IEEE 802.15.4 subsystem Commit Details
Date: | 2011-07-12 16:23:21 (12 years 8 months ago) |
---|---|
Author: | Werner Almesberger |
Commit: | c1071309d8b2909cb479afd4e6a89496e11e59d3 |
Message: | atusb/fw/: added "HardMAC" support (not yet using the
TRX's MAC) - include/atusb/ep0.h (enum atspi_requests), ep0.c (my_setup): added new "HardMAC" requests ATUSB_RX_MODE and ATUSB_TX - mac.h, mac.c: basic "HardMAC" procedure - board_app.c (INT0_vect): call MAC-specific interrupt handler if provided - Makefile (OBJS): added mac.o |
Files: |
atusb/fw/Makefile (1 diff) atusb/fw/board_app.c (2 diffs) atusb/fw/ep0.c (2 diffs) atusb/fw/include/atusb/ep0.h (2 diffs) atusb/fw/mac.c (1 diff) atusb/fw/mac.h (1 diff) |
Change Details
atusb/fw/Makefile | ||
---|---|---|
31 | 31 | USB_ID = 20b7:1540 |
32 | 32 | |
33 | 33 | OBJS = atusb.o board.o board_app.o sernum.o spi.o descr.o ep0.o \ |
34 | dfu_common.o usb.o app-atu2.o | |
34 | dfu_common.o usb.o app-atu2.o mac.o | |
35 | 35 | BOOT_OBJS = boot.o board.o sernum.o spi.o flash.o dfu.o \ |
36 | 36 | dfu_common.o usb.o boot-atu2.o |
37 | 37 |
atusb/fw/board_app.c | ||
---|---|---|
22 | 22 | |
23 | 23 | #include "usb.h" |
24 | 24 | #include "at86rf230.h" |
25 | #include "board.h" | |
26 | 25 | #include "spi.h" |
26 | #include "mac.h" | |
27 | #include "board.h" | |
27 | 28 | |
28 | 29 | |
29 | 30 | static volatile uint32_t timer_h = 0; /* 2^(16+32) / 8 MHz = ~1.1 years */ |
... | ... | |
155 | 156 | |
156 | 157 | ISR(INT0_vect) |
157 | 158 | { |
159 | if (mac_irq) { | |
160 | mac_irq(); | |
161 | return; | |
162 | } | |
158 | 163 | if (eps[1].state == EP_IDLE) { |
159 | 164 | led(1); |
160 | 165 | irq_serial = (irq_serial+1) | 0x80; |
atusb/fw/ep0.c | ||
---|---|---|
29 | 29 | #include "board.h" |
30 | 30 | #include "sernum.h" |
31 | 31 | #include "spi.h" |
32 | #include "mac.h" | |
32 | 33 | |
33 | 34 | |
34 | 35 | #define HW_TYPE HW_TYPE_110131 |
... | ... | |
239 | 240 | usb_send(&eps[0], buf, setup->wLength, NULL, NULL); |
240 | 241 | return 1; |
241 | 242 | |
243 | case ATUSB_TO_DEV(ATUSB_RX_MODE): | |
244 | return mac_rx(setup->wValue); | |
245 | case ATUSB_TO_DEV(ATUSB_TX): | |
246 | return mac_tx(setup->wValue, setup->wLength); | |
247 | ||
242 | 248 | default: |
243 | 249 | error("Unrecognized SETUP: 0x%02x 0x%02x ...\n", |
244 | 250 | setup->bmRequestType, setup->bRequest); |
atusb/fw/include/atusb/ep0.h | ||
---|---|---|
39 | 39 | * host-> ATUSB_SPI_WRITE byte0 byte1 #bytes |
40 | 40 | * ->host ATUSB_SPI_READ1 byte0 - #bytes |
41 | 41 | * ->host ATUSB_SPI_READ2 byte0 byte1 #bytes |
42 | * ->host ATUSB_SPI_WRITE2_SYNC byte0 bute1 0/1 | |
42 | * ->host ATUSB_SPI_WRITE2_SYNC byte0 byte1 0/1 | |
43 | * | |
44 | * host-> ATUSB_RX_MODE on - 0 | |
45 | * host-> ATUSB_TX flags 0 #bytes | |
43 | 46 | */ |
44 | 47 | |
45 | 48 | /* |
... | ... | |
93 | 96 | ATUSB_SPI_READ1, |
94 | 97 | ATUSB_SPI_READ2, |
95 | 98 | ATUSB_SPI_WRITE2_SYNC, |
99 | ATUSB_RX_MODE = 0x40, /* HardMAC group */ | |
100 | ATUSB_TX, | |
96 | 101 | }; |
97 | 102 | |
98 | 103 |
atusb/fw/mac.c | ||
---|---|---|
1 | /* | |
2 | * fw/mac.c - HardMAC functions | |
3 | * | |
4 | * Written 2011 by Werner Almesberger | |
5 | * Copyright 2011 Werner Almesberger | |
6 | * | |
7 | * This program is free software; you can redistribute it and/or modify | |
8 | * it under the terms of the GNU General Public License as published by | |
9 | * the Free Software Foundation; either version 2 of the License, or | |
10 | * (at your option) any later version. | |
11 | */ | |
12 | ||
13 | #include <stddef.h> | |
14 | #include <stdint.h> | |
15 | ||
16 | #include "usb.h" | |
17 | ||
18 | #include "at86rf230.h" | |
19 | #include "spi.h" | |
20 | #include "mac.h" | |
21 | ||
22 | ||
23 | void (*mac_irq)(void) = NULL; | |
24 | ||
25 | ||
26 | static uint8_t rx_buf[MAX_PSDU+2]; /* PHDR+payload+LQ */ | |
27 | static uint8_t tx_buf[MAX_PSDU]; | |
28 | static uint8_t tx_size = 0; | |
29 | static int txing = 0; | |
30 | ||
31 | ||
32 | static uint8_t reg_read(uint8_t reg) | |
33 | { | |
34 | uint8_t value; | |
35 | ||
36 | spi_begin(); | |
37 | spi_send(AT86RF230_REG_READ | reg); | |
38 | value= spi_recv(); | |
39 | spi_end(); | |
40 | ||
41 | return value; | |
42 | } | |
43 | ||
44 | ||
45 | static void reg_write(uint8_t reg, uint8_t value) | |
46 | { | |
47 | spi_begin(); | |
48 | spi_send(AT86RF230_REG_WRITE | reg); | |
49 | spi_send(value); | |
50 | spi_end(); | |
51 | } | |
52 | ||
53 | ||
54 | static void handle_irq(void) | |
55 | { | |
56 | uint8_t irq; | |
57 | uint8_t size, i; | |
58 | ||
59 | irq = reg_read(REG_IRQ_STATUS); | |
60 | if (!(irq & IRQ_TRX_END)) | |
61 | return; | |
62 | ||
63 | /* | |
64 | * @@@ we probably also have to handle at least IRQ_PLL_UNLOCK, because | |
65 | * a PLL unlock should cause a transition out of BUSY_TX without | |
66 | * TRX_END. | |
67 | */ | |
68 | if (txing) { | |
69 | txing = 0; | |
70 | return; | |
71 | } | |
72 | ||
73 | /* unlikely */ | |
74 | if (eps[1].state != EP_IDLE) | |
75 | return; | |
76 | ||
77 | spi_begin(); | |
78 | spi_send(AT86RF230_BUF_READ); | |
79 | size = spi_recv(); | |
80 | if (size & 0x80) { | |
81 | spi_end(); | |
82 | return; | |
83 | } | |
84 | ||
85 | rx_buf[0] = size; | |
86 | for (i = 0; i != size+1; i++) | |
87 | rx_buf[i+1] = spi_recv(); | |
88 | spi_end(); | |
89 | usb_send(&eps[1], rx_buf, size+2, NULL, NULL); | |
90 | } | |
91 | ||
92 | ||
93 | int mac_rx(int on) | |
94 | { | |
95 | if (on) { | |
96 | mac_irq = handle_irq; | |
97 | reg_read(REG_IRQ_STATUS); | |
98 | reg_write(REG_TRX_STATE, TRX_CMD_RX_ON); | |
99 | } else { | |
100 | mac_irq = NULL; | |
101 | reg_write(REG_TRX_STATE, TRX_CMD_FORCE_TRX_OFF); | |
102 | txing = 0; | |
103 | } | |
104 | return 1; | |
105 | } | |
106 | ||
107 | ||
108 | static void do_tx(void *user) | |
109 | { | |
110 | uint8_t status; | |
111 | uint8_t i; | |
112 | ||
113 | do status = reg_read(REG_TRX_STATUS) & TRX_STATUS_MASK; | |
114 | while (status != TRX_STATUS_RX_ON && status != TRX_STATUS_RX_AACK_ON); | |
115 | ||
116 | /* | |
117 | * We use TRX_CMD_FORCE_PLL_ON instead of TRX_CMD_PLL_ON because a new | |
118 | * reception may have begun while we were still working on the previous | |
119 | * one. | |
120 | */ | |
121 | reg_write(REG_TRX_STATE, TRX_CMD_FORCE_PLL_ON); | |
122 | ||
123 | handle_irq(); | |
124 | ||
125 | spi_begin(); | |
126 | spi_send(AT86RF230_BUF_WRITE); | |
127 | spi_send(tx_size); | |
128 | for (i = 0; i != tx_size; i++) | |
129 | spi_send(tx_buf[i]); | |
130 | spi_end(); | |
131 | ||
132 | reg_write(REG_TRX_STATE, TRX_CMD_TX_START); | |
133 | ||
134 | txing = 1; | |
135 | ||
136 | /* | |
137 | * Wait until we reach BUSY_TX, so that we command the transition to | |
138 | * RX_ON which will be executed upon TX completion. | |
139 | */ | |
140 | while ((reg_read(REG_TRX_STATUS) & TRX_STATUS_MASK) == | |
141 | TRX_STATUS_TRANSITION); | |
142 | reg_write(REG_TRX_STATE, TRX_CMD_RX_ON); | |
143 | } | |
144 | ||
145 | ||
146 | int mac_tx(uint16_t flags, uint16_t len) | |
147 | { | |
148 | if (len > MAX_PSDU) | |
149 | return 0; | |
150 | tx_size = len; | |
151 | usb_recv(&eps[0], tx_buf, len, do_tx, NULL); | |
152 | return 1; | |
153 | ||
154 | } |
atusb/fw/mac.h | ||
---|---|---|
1 | /* | |
2 | * fw/mac.h - HardMAC functions | |
3 | * | |
4 | * Written 2011 by Werner Almesberger | |
5 | * Copyright 2011 Werner Almesberger | |
6 | * | |
7 | * This program is free software; you can redistribute it and/or modify | |
8 | * it under the terms of the GNU General Public License as published by | |
9 | * the Free Software Foundation; either version 2 of the License, or | |
10 | * (at your option) any later version. | |
11 | */ | |
12 | ||
13 | #ifndef MAC_H | |
14 | #define MAC_H | |
15 | ||
16 | #include <stdint.h> | |
17 | ||
18 | ||
19 | extern void (*mac_irq)(void); | |
20 | ||
21 | int mac_rx(int on); | |
22 | int mac_tx(uint16_t flags, uint16_t len); | |
23 | ||
24 | #endif /* !MAC_H */ |