Skip to content
This repository was archived by the owner on Jan 7, 2019. It is now read-only.

Commit 45ea976

Browse files
author
Marten Junga
committed
[feature] DW1000 Driver, 802.15.4 Frame & Ranging
Added driver for DW1000 with generic and STM32F4_disco examples Added MAC Frame for IEEE 802.15.4 with unitttests Added Ranging algorithms for UWB modules with unittests
1 parent a1b5a1b commit 45ea976

83 files changed

Lines changed: 8789 additions & 6 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.Rhistory

Whitespace-only changes.

examples/stm32f4_discovery/radio/nrf24-data/rx/SConstruct renamed to examples/generic/dw1000/double-sided_two-way_ranging/initiator/SConstruct

File renamed without changes.
Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
/* This is an Example application for one STM32 in combination with a Decawave DM1000 Chip
2+
*
3+
* Connections are the following:
4+
*
5+
* USART: STM32F4&F103 Pin
6+
* TXD -> PA2
7+
* RXD -> PA3 (not used in this example)
8+
*
9+
* DM1000 -> SPI-Master-2
10+
* SPI: STM32F4 Pin STM32F107
11+
* Miso -> PC02 PB14
12+
* Mosi -> PB15 PB15
13+
* Clock -> PB10 PB13
14+
*
15+
* RES -> PA08 PA00 (not used in this example)
16+
* Chipselect -> PE08 PB12
17+
* IRQ -> PD10 PB08(not used in this example)
18+
*
19+
*
20+
* What this program does is:
21+
* 1) Sends out a DSTW-Ranging Frame on Broadcast
22+
* 2) Waits for an Answer and Computes the Range between the both
23+
*
24+
* For 1 Ranging there will be 4 messages but this technique is more precise than SSTW
25+
*
26+
*
27+
* Init -> Resp |Payload{init DSTWR}
28+
* Resp -> Init |Payload{receive and transmittime of Resp}
29+
* Init -> Resp |Payload{receive and transmittime of Init}
30+
* Resp -> Init |Payload{Time of flight of second ranging round}
31+
*/
32+
33+
34+
#include <xpcc/architecture/platform.hpp> // include for platform
35+
#include <xpcc/debug/logger.hpp> // include for DW1000 Error/Debug Messaging
36+
#include <xpcc/driver/radio/dw1000/dw1000.hpp> // DW1000 Driver
37+
#include <xpcc/communication/Frame802154/Frame802154.hpp> // MAC Frame for IEEE 802.15.4
38+
#include <xpcc/positioning/ranging.hpp> // ranging operations
39+
#include <xpcc/processing/timer.hpp> // Timer and Timeouts
40+
41+
//-------------------------Namespaces and renaming----------------------------------
42+
// change things up for each individual board
43+
using namespace Board;
44+
using SPI = SpiMaster2;
45+
using SPISCK = GpioOutputB10;
46+
using SPIMISO = GpioInputC2;
47+
using SPIMOSI = GpioOutputB15;
48+
using RES = GpioOutputA8;
49+
using CS = GpioOutputE8;
50+
using IRQ = GpioInputD10;
51+
52+
53+
using dwm = xpcc::Dw1000 < SPI, CS, RES, IRQ >;
54+
using ranging = xpcc::Ranging < dwm >;
55+
56+
//------------------------------LOGGER----------------------------------------------
57+
#undef XPCC_LOG_LEVEL
58+
#define XPCC_LOG_LEVEL xpcc::log::INFO
59+
xpcc::IODeviceWrapper< Usart2, xpcc::IOBuffer::BlockIfFull > loggerDevice;
60+
61+
// Set all four logger streams to use the UART
62+
xpcc::log::Logger xpcc::log::debug(loggerDevice);
63+
xpcc::log::Logger xpcc::log::info(loggerDevice);
64+
xpcc::log::Logger xpcc::log::warning(loggerDevice);
65+
xpcc::log::Logger xpcc::log::error(loggerDevice);
66+
67+
//------------------------------DWM Config------------------------------------------------
68+
69+
static xpcc::dw1000::config_t config =
70+
{
71+
2, /* Channel number. */
72+
xpcc::dw1000::PRF_64M, /* Pulse repetition frequency. */
73+
xpcc::dw1000::PLEN_128, /* Preamble length. Used in TX only. */
74+
xpcc::dw1000::PAC8, /* Preamble acquisition chunk size. Used in RX only. */
75+
9, /* TX preamble code. Used in TX only. */
76+
9, /* RX preamble code. Used in RX only. */
77+
0, /* 0 to use standard SFD, 1 to use non-standard SFD. */
78+
xpcc::dw1000::BR_6M8, /* Data rate. */
79+
xpcc::dw1000::PHRMODE_STD, /* PHY header mode. */
80+
(129 + 8 - 8) /* SFD timeout (preamble length + 1 + SFD length - PAC size). Used in RX only. */
81+
};
82+
83+
static constexpr uint16_t hostaddress= 0xBBBB;
84+
85+
86+
xpcc::Frame802154 receiveframe;
87+
xpcc::ShortTimeout timeout;
88+
bool isrx = false;
89+
double distance;
90+
uint8_t buffer[1024];
91+
92+
93+
//-------------------------------MAIN-----------------------------------------------------
94+
int
95+
main()
96+
{
97+
98+
//setup USART
99+
GpioOutputA2::connect(Usart2::Tx);
100+
GpioInputA3::connect(Usart2::Rx, Gpio::InputType::PullUp);
101+
Usart2::initialize<Board::systemClock, 115200>(12);
102+
//initialize the board
103+
Board::initialize();
104+
XPCC_LOG_INFO << "GENERIC DSTW INIT v1.1"<< xpcc::endl;
105+
//activate the CS on the DW1000
106+
CS::setOutput(xpcc::Gpio::High);
107+
//setup SPI
108+
SPIMOSI::connect(SPI::Mosi);
109+
SPIMISO::connect(SPI::Miso);
110+
SPISCK::connect(SPI::Sck);
111+
SPI::initialize<Board::systemClock,2500000,xpcc::Tolerance::DontCare>();
112+
SPI::setDataMode(SPI::DataMode::Mode0);
113+
//Init with the config
114+
while (!(dwm::init(config)))
115+
{
116+
Board::Leds::toggle();
117+
xpcc::delayMilliseconds(100);
118+
}
119+
/* Apply antenna delay value.*/
120+
dwm::setRXAntennaDelay(dwm::standardAntennaDelay);
121+
dwm::setTXAntennaDelay(dwm::standardAntennaDelay);
122+
dwm::hostaddress = hostaddress;
123+
124+
while (true)
125+
{
126+
Board::Leds::toggle();
127+
128+
//--------------------------------------- Start sending init ---------------------------------------------------------------
129+
XPCC_LOG_DEBUG << "Send init"<< xpcc::endl;
130+
ranging::sendDSTWRinit();
131+
timeout.restart(5);
132+
while(not(dwm::isFrameSent()||timeout.isExpired()))
133+
{}
134+
Board::Leds::toggle();
135+
136+
//------------------------------------------------------------ Receive Message--------------------------------------------------------------------
137+
timeout.restart(200);
138+
dwm::rxEnable();
139+
while(not(dwm::checkForRXError() || (isrx = dwm::checkForRX()) || timeout.isExpired()))
140+
{}
141+
if (isrx)
142+
{
143+
Board::Leds::toggle();
144+
dwm::readrx(dwm::rxlength(),buffer);
145+
receiveframe.loadFrame(dwm::rxlength(),buffer);
146+
if (receiveframe.getDestinationAddress16() == hostaddress)
147+
{
148+
if (ranging::IsRangingFrame(receiveframe))
149+
{
150+
151+
//--------------------------------------- Start get distance and send return ---------------------------------------------------------------
152+
distance = ranging::computeSsTwrDistance(receiveframe);
153+
dwm::rxdisable();
154+
ranging::sendAnswer(receiveframe);
155+
//---------------------------------------Wait for TOF from other device---------------------------------------------------------------------
156+
timeout.restart(5);
157+
while(not(dwm::isFrameSent()||timeout.isExpired())){}
158+
dwm::rxreset();
159+
dwm::rxEnable();
160+
isrx = false;
161+
timeout.restart(150);
162+
while(not(dwm::checkForRXError() || (isrx = dwm::checkForRX()) || timeout.isExpired())){}
163+
if (isrx)
164+
{
165+
dwm::readrx(dwm::rxlength(),buffer);
166+
receiveframe.loadFrame(dwm::rxlength(),buffer);
167+
if (receiveframe.getDestinationAddress16() == hostaddress)
168+
{
169+
if (ranging::IsRangingFrame(receiveframe))
170+
{
171+
distance = ranging::computeDsTwrDistance(distance,receiveframe);
172+
XPCC_LOG_INFO.printf("DISTANCE TO %0x IS %5.3fm \n",receiveframe.getSourceAddress16(),distance);
173+
}
174+
175+
}
176+
}
177+
}
178+
Board::Leds::toggle();
179+
}
180+
else
181+
{
182+
dwm::frame_seq_nb = receiveframe.getSequenceNumber() + 1 ;
183+
XPCC_LOG_DEBUG << "Wrong Answer --- Address was wrong"<< xpcc::endl;
184+
}
185+
}
186+
187+
else if (dwm::checkForRXError())
188+
{
189+
XPCC_LOG_ERROR<< "RX--ERROR!"<< xpcc::endl;
190+
}
191+
dwm::rxdisable();
192+
while(not(timeout.isExpired())){}
193+
194+
}
195+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
[build]
2+
#board = al_avreb_can
3+
#board = arduino_uno
4+
#board = nucleo_f031k6
5+
#board = nucleo_f103rb
6+
#board = nucleo_f303k8
7+
#board = nucleo_f401re
8+
#board = nucleo_f411re
9+
#board = nucleo_f429zi
10+
#board = nucleo_l476rg
11+
#board = stm32f0_discovery
12+
#board = stm32f072_discovery
13+
#board = stm32f103c8t6_blue_pill
14+
#board = stm32f1_discovery
15+
#board = stm32f3_discovery
16+
#board = stm32f429_discovery
17+
#board = stm32f469_discovery
18+
board = stm32f4_discovery
19+
#board = stm32f746g_discovery
20+
#board = stm32f769i_discovery
21+
22+
buildpath = ${xpccpath}/build/examples/generic/${name}

examples/stm32f4_discovery/radio/nrf24-data/tx/SConstruct renamed to examples/generic/dw1000/double-sided_two-way_ranging/responder/SConstruct

File renamed without changes.
Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
/* This is an Example application for one STM32 in combination with a Decawave DM1000 Chip
2+
*
3+
* Connections are the following:
4+
*
5+
* USART: STM32F4&F103 Pin
6+
* TXD -> PA2
7+
* RXD -> PA3 (not used in this example)
8+
*
9+
* DM1000 -> SPI-Master-2
10+
* SPI: STM32F4 Pin STM32F107
11+
* Miso -> PC02 PB14
12+
* Mosi -> PB15 PB15
13+
* Clock -> PB10 PB13
14+
*
15+
* RES -> PA08 PA00 (not used in this example)
16+
* Chipselect -> PE08 PB12
17+
* IRQ -> PD10 PB08(not used in this example)
18+
*
19+
*
20+
* What this program does is:
21+
* 1) Sends out a DSTW-Ranging Frame on Broadcast
22+
* 2) Waits for an Answer and Computes the Range between the both
23+
*
24+
* For 1 Ranging there will be 4 messages but this technique is more precise than SSTW
25+
*
26+
*
27+
* Init -> Resp |Payload{init DSTWR}
28+
* Resp -> Init |Payload{receive and transmittime of Resp}
29+
* Init -> Resp |Payload{receive and transmittime of Init}
30+
* Resp -> Init |Payload{Time of flight of second ranging round}
31+
*/
32+
33+
34+
#include <xpcc/architecture/platform.hpp> // include for platform
35+
#include <xpcc/debug/logger.hpp> // include for DW1000 Error/Debug Messaging
36+
#include <xpcc/driver/radio/dw1000/dw1000.hpp> // DW1000 Driver
37+
#include <xpcc/communication/Frame802154/Frame802154.hpp> // MAC Frame for IEEE 802.15.4
38+
#include <xpcc/positioning/ranging.hpp> // ranging operations for DW1000
39+
#include <xpcc/processing/timer.hpp> // Timer and Timeouts
40+
41+
//-------------------------Namespaces and renaming----------------------------------
42+
// change things up for each individual board
43+
using namespace Board;
44+
using SPI = SpiMaster2;
45+
using SPISCK = GpioOutputB10;
46+
using SPIMISO = GpioInputC2;
47+
using SPIMOSI = GpioOutputB15;
48+
using RES = GpioOutputA8;
49+
using CS = GpioOutputE8;
50+
using IRQ = GpioInputD10;
51+
52+
53+
using dwm = xpcc::Dw1000 < SPI, CS, RES, IRQ >;
54+
using ranging = xpcc::Ranging < dwm >;
55+
56+
//------------------------------LOGGER----------------------------------------------
57+
#undef XPCC_LOG_LEVEL
58+
#define XPCC_LOG_LEVEL xpcc::log::DISABLED
59+
xpcc::IODeviceWrapper< Usart2, xpcc::IOBuffer::BlockIfFull > loggerDevice;
60+
61+
// Set all four logger streams to use the UART
62+
xpcc::log::Logger xpcc::log::debug(loggerDevice);
63+
xpcc::log::Logger xpcc::log::info(loggerDevice);
64+
xpcc::log::Logger xpcc::log::warning(loggerDevice);
65+
xpcc::log::Logger xpcc::log::error(loggerDevice);
66+
67+
//------------------------------DWM Config------------------------------------------------
68+
69+
static xpcc::dw1000::config_t config =
70+
{
71+
2, /* Channel number. */
72+
xpcc::dw1000::PRF_64M, /* Pulse repetition frequency. */
73+
xpcc::dw1000::PLEN_128, /* Preamble length. Used in TX only. */
74+
xpcc::dw1000::PAC8, /* Preamble acquisition chunk size. Used in RX only. */
75+
9, /* TX preamble code. Used in TX only. */
76+
9, /* RX preamble code. Used in RX only. */
77+
0, /* 0 to use standard SFD, 1 to use non-standard SFD. */
78+
xpcc::dw1000::BR_6M8, /* Data rate. */
79+
xpcc::dw1000::PHRMODE_STD, /* PHY header mode. */
80+
(129 + 8 - 8) /* SFD timeout (preamble length + 1 + SFD length - PAC size). Used in RX only. */
81+
};
82+
83+
static constexpr uint16_t hostaddress= 0xAAAA;
84+
85+
xpcc::Frame802154 receiveframe;
86+
xpcc::ShortTimeout timeout;
87+
uint8_t buffer[256];
88+
bool isrx = false;
89+
uint32_t length;
90+
91+
92+
//-------------------------------MAIN-----------------------------------------------------
93+
int
94+
main()
95+
{
96+
97+
//setup USART
98+
GpioOutputA2::connect(Usart2::Tx);
99+
GpioInputA3::connect(Usart2::Rx, Gpio::InputType::PullUp);
100+
Usart2::initialize<Board::systemClock, 115200>(12);
101+
//initialize the board
102+
Board::initialize();
103+
XPCC_LOG_INFO << "GENERIC DSTW RESP v1.1"<< xpcc::endl;
104+
//activate the CS on the DW1000
105+
CS::setOutput(xpcc::Gpio::High);
106+
//setup SPI
107+
SPIMOSI::connect(SPI::Mosi);
108+
SPIMISO::connect(SPI::Miso);
109+
SPISCK::connect(SPI::Sck);
110+
SPI::initialize<Board::systemClock,2500000,xpcc::Tolerance::DontCare>();
111+
SPI::setDataMode(SPI::DataMode::Mode0);
112+
//Init with the config
113+
while (!(dwm::init(config)))
114+
{
115+
Board::Leds::toggle();
116+
xpcc::delayMilliseconds(100);
117+
}
118+
/* Apply antenna delay value.*/
119+
dwm::setRXAntennaDelay(dwm::standardAntennaDelay);
120+
dwm::setTXAntennaDelay(dwm::standardAntennaDelay);
121+
dwm::hostaddress = hostaddress;
122+
123+
124+
while (true)
125+
{
126+
isrx = false;
127+
dwm::rxEnable();
128+
Leds::toggle();
129+
while(not((isrx = dwm::checkForRX()) || dwm::checkForRXError()))
130+
{}
131+
Leds::toggle();
132+
if (isrx)
133+
{
134+
length = dwm::rxlength();
135+
dwm::readrx(length, buffer);
136+
receiveframe.loadFrame(length, buffer);
137+
if (receiveframe.getDestinationAddress16() == dwm::hostaddress || receiveframe.getDestinationAddress16() == 0xFFFF)
138+
{
139+
Leds::toggle();
140+
if(ranging::IsRangingFrame(receiveframe))
141+
{
142+
ranging::sendAnswer(receiveframe);
143+
timeout.restart(5);
144+
while(not(dwm::isFrameSent() || timeout.isExpired()))
145+
{}
146+
147+
}
148+
Leds::toggle();
149+
}
150+
else
151+
{
152+
Leds::toggle();
153+
xpcc::delayMilliseconds(100);
154+
Leds::toggle();
155+
}
156+
}
157+
else
158+
{
159+
Leds::toggle();
160+
xpcc::delayMilliseconds(50);
161+
Leds::toggle();
162+
xpcc::delayMilliseconds(50);
163+
Leds::toggle();
164+
xpcc::delayMilliseconds(50);
165+
Leds::toggle();
166+
}
167+
dwm::trxdisable();
168+
dwm::rxreset();
169+
}
170+
}

0 commit comments

Comments
 (0)