Root/fw/rf.c

Source at commit b75570a0a863d3a922c7963cd8a513b75823665d created 10 years 11 months ago.
By Werner Almesberger, tornado/cpu/cpu.brd: include subsystem name (CPU) in text label
1/*
2 * fw/rf.c - RF interface
3 *
4 * Written 2012 by Werner Almesberger
5 * Copyright 2012 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
14#include <stdint.h>
15
16#include <avr/io.h>
17#define F_CPU 8000000UL
18#include <util/delay.h>
19
20#include <at86rf230.h>
21
22#include "io.h"
23#include "spi.h"
24#include "rf.h"
25
26
27/*
28 * According to IEEE 802.15.4-2003 section E.2.6, channel 15 is the only
29 * channel that falls into the 802.11 guard bands in North America an Europe.
30 */
31
32#define DEFAULT_CHAN 15 /* channel 15, 2425 MHz */
33
34/*
35 * Transmit power, dBm. IEEE 802.15.4-2003 section E.3.1.3 specifies a transmit
36 * power of 0 dBm for IEEE 802.15.4. We assume an antenna gain of 3 dB or
37 * better.
38 */
39
40#define DEFAULT_POWER -3.2 /* transmit power, dBm */
41
42
43static uint8_t reg_read(uint8_t reg)
44{
45    uint8_t value;
46
47    spi_begin();
48    spi_send(AT86RF230_REG_READ | reg);
49    value = spi_recv();
50    spi_end();
51
52    return value;
53}
54
55
56static void reg_write(uint8_t reg, uint8_t value)
57{
58    spi_begin();
59    spi_send(AT86RF230_REG_WRITE | reg);
60    spi_send(value);
61    spi_end();
62}
63
64
65void rf_init(void)
66{
67    spi_init();
68    CLR(RF_nRST);
69    _delay_us(10); /* tTR10 = 625 ns */
70    SET(RF_nRST);
71    _delay_us(40); /* tTR13 = 37 us */
72
73    reg_write(REG_TRX_STATE, TRX_CMD_TRX_OFF);
74    _delay_us(40); /* tTR13 = 37 us */
75    reg_write(REG_PHY_CC_CCA, DEFAULT_CHAN);
76
77    reg_write(REG_TRX_STATE, TRX_CMD_RX_ON);
78    _delay_us(200); /* tTR19(max) = 166 us */
79
80    //reg_write(REG_IRQ_MASK, IRQ_TRX_END);
81    reg_write(REG_IRQ_MASK, 0xff);
82    reg_read(REG_IRQ_STATUS);
83}
84
85
86void rf_send(const void *buf, uint8_t size)
87{
88    uint8_t i;
89
90    reg_write(REG_TRX_STATE, TRX_CMD_PLL_ON);
91    _delay_us(1); /* tTR9 = 1 us */
92
93    /* be nice to senders with long turn-around time, e.g., atusb */
94    _delay_ms(9);
95
96    spi_begin();
97    spi_send(AT86RF230_BUF_WRITE);
98    spi_send(size+2); /* CRC */
99    for (i = 0; i != size; i++)
100        spi_send(((const uint8_t *) buf)[i]);
101    spi_end();
102
103    reg_read(REG_IRQ_STATUS);
104
105    reg_write(REG_TRX_STATE, TRX_CMD_TX_START);
106    _delay_us(16); /* tTR10 = 16 us */
107
108    while (!(reg_read(REG_IRQ_STATUS) & IRQ_TRX_END)) {
109        PORTC = 1;
110        PORTC = 0;
111    }
112
113    reg_write(REG_TRX_STATE, TRX_CMD_RX_ON);
114    _delay_us(1); /* tTR8 = 1 us */
115}
116
117
118uint8_t rf_recv(void *buf, uint8_t size)
119{
120    uint8_t irq, len, i;
121
122    if (!PIN(RF_IRQ))
123        return 0;
124
125    irq = reg_read(REG_IRQ_STATUS);
126    if (!(irq & IRQ_TRX_END))
127        return 0;
128
129    if (!(reg_read(REG_PHY_RSSI) & RX_CRC_VALID))
130        return 0;
131
132    spi_begin();
133    spi_send(AT86RF230_BUF_READ);
134    len = spi_recv();
135    if (!len || (len & 0x80)) {
136        spi_end();
137        return 0;
138    }
139    if (size > len)
140        size = len;
141    for (i = 0; i != size; i++)
142        ((uint8_t *) buf)[i] = spi_recv();
143    spi_end();
144    return len;
145}
146

Archive Download this file

Branches:
master
tornado-v1



interactive