Date:2011-07-12 16:23:21 (9 years 1 month 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
3131USB_ID = 20b7:1540
3232
3333OBJS = 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
3535BOOT_OBJS = boot.o board.o sernum.o spi.o flash.o dfu.o \
3636            dfu_common.o usb.o boot-atu2.o
3737
atusb/fw/board_app.c
2222
2323#include "usb.h"
2424#include "at86rf230.h"
25#include "board.h"
2625#include "spi.h"
26#include "mac.h"
27#include "board.h"
2728
2829
2930static volatile uint32_t timer_h = 0; /* 2^(16+32) / 8 MHz = ~1.1 years */
...... 
155156
156157ISR(INT0_vect)
157158{
159    if (mac_irq) {
160        mac_irq();
161        return;
162    }
158163    if (eps[1].state == EP_IDLE) {
159164        led(1);
160165        irq_serial = (irq_serial+1) | 0x80;
atusb/fw/ep0.c
2929#include "board.h"
3030#include "sernum.h"
3131#include "spi.h"
32#include "mac.h"
3233
3334
3435#define HW_TYPE HW_TYPE_110131
...... 
239240        usb_send(&eps[0], buf, setup->wLength, NULL, NULL);
240241        return 1;
241242
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
242248    default:
243249        error("Unrecognized SETUP: 0x%02x 0x%02x ...\n",
244250            setup->bmRequestType, setup->bRequest);
atusb/fw/include/atusb/ep0.h
3939 * host-> ATUSB_SPI_WRITE byte0 byte1 #bytes
4040 * ->host ATUSB_SPI_READ1 byte0 - #bytes
4141 * ->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
4346 */
4447
4548/*
...... 
9396    ATUSB_SPI_READ1,
9497    ATUSB_SPI_READ2,
9598    ATUSB_SPI_WRITE2_SYNC,
99    ATUSB_RX_MODE = 0x40, /* HardMAC group */
100    ATUSB_TX,
96101};
97102
98103
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
23void (*mac_irq)(void) = NULL;
24
25
26static uint8_t rx_buf[MAX_PSDU+2]; /* PHDR+payload+LQ */
27static uint8_t tx_buf[MAX_PSDU];
28static uint8_t tx_size = 0;
29static int txing = 0;
30
31
32static 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
45static 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
54static 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
93int 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
108static 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
146int 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
19extern void (*mac_irq)(void);
20
21int mac_rx(int on);
22int mac_tx(uint16_t flags, uint16_t len);
23
24#endif /* !MAC_H */

Archive Download the corresponding diff file



interactive