Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
main_minimal.cpp
- Committer:
- aungriah
- Date:
- 2017-12-06
- Revision:
- 0:3333b6066adf
File content as of revision 0:3333b6066adf:
#include "mbed.h" #include "SMConfig.h" #include "DecaWave.h" // DW1000 functions //#include "LMMN2WR.h" // 2-Way-Ranging #include "PC.h" // Serial Port via USB for debugging with Terminal #include "Watchdog.h" // Resets Program if it gets stuck #include "nodes.h" // Function Prototypes void dwCallbackTx(const dwt_cb_data_t *rxd); void dwCallbackRx(const dwt_cb_data_t *rxd); int min (int a, int b); void configureDW1000(uint8_t dwMode); void rangeAndDisplayOne(uint8_t addr); void rangeAndDisplayAll(); void executeOrder(char* command); // PA_7 MOSI, PA_6 MISO, PA_5 SCLK, PB_6 CS, PB_9 IRQ SPI decaWaveSpi(PA_7, PA_6, PA_5); // Instance of SPI connection to DW1000 DigitalOut decaWaveCs(PB_6); InterruptIn decaWaveIrq(PB_9); DecaWave decaWave = DecaWave(); // Instance of the DW1000 BusIn addressInput(PA_10, PB_3, PB_5, PB_4); // Bit 0-3 of Switches to set the adress. PC pc(USBTX, USBRX, 921600); // USB UART Terminal DigitalIn anchorInput(PB_10); // Bit 4 of Switches to set the Anchor. BusIn modeInput(PA_8, PA_9, PC_7); // Bit 5-7 Bits of Switches to set the mode. Watchdog wdt = Watchdog(); BeaconNode beaconNode(decaWave); AnchorNode anchorNode(decaWave); BaseStationNode baseStationNode(decaWave); Node *node; int main() { decaWaveSpi.frequency(20000000); // Crank up the SPI frequency from 1Mhz to 3Mhz (maybe more?) // Check if Reset was from Watchdog or externally if(RCC->CSR&0x20000000) pc.printf("\r\n\r\n --- !!!!WATCHDOG RESET!!!! --- \r\n\r\n", RCC->CSR); else if(RCC->CSR&0x4000000) pc.printf("\r\n\r\n --- External Reset --- \r\n\r\n", RCC->CSR); __HAL_RCC_CLEAR_RESET_FLAGS(); // Set all Switches Pull-Down so that it is zero if Switch is not set addressInput.mode(PullDown); anchorInput.mode(PullDown); modeInput.mode(PullDown); wait_ms(50); baseStationNode.setAddress(addressInput & addressInput.mask()); anchorNode.setAddress(addressInput & addressInput.mask()); beaconNode.setAddress(addressInput & addressInput.mask()); uint8_t roomadress = modeInput & modeInput.mask()); if((addressInput & addressInput.mask()) == BASE_STATION_ADDR){ node = &baseStationNode; pc.printf("This node is the Base Station, Adress: %d \r\n \r\n \r\n", node->getAddress()); } else if(anchorInput){ node = &anchorNode; pc.printf("This node is an Anchor node, Adress: %d \r\n \r\n \r\n", node->getAddress()); pc.printf("The room id of the anchor is %d", roomadress); wdt.kick(2); // Set up WatchDog } else{ node = &beaconNode; pc.printf("This node is a Beacon, Adress: %d \r\n \r\n \r\n", node->getAddress()); wdt.kick(2); // Set up WatchDog } //pc.printf(" Adress: %d \r\n \r\n \r\n", node->getAddress()); configureDW1000(7); // TODO turn on RXMode regularly (every couple seconds) while(1) { // Choose between what to execte based on whether this device is a: // BEACON // BASESTATION // ANCHOR if (!node->isAnchor() && !node->isBaseStation()){ // THE BEACON EXECUTES THIS if(beaconNode.getRepetitions() > 0){ switch(beaconNode.getMode()){ case RANGE_ALL: rangeAndDisplayAll(); break; case RANGE_ONE: rangeAndDisplayOne(beaconNode.getDestination()); break; default: break; } beaconNode.decreaseRepetitions(); } else{ beaconNode.clearRec(); wait_ms(8); } wdt.kick(); } else if (node->isBaseStation()){ pc.printf("Debug Point 1\r\n"); // EXECUTE THIS IF A BASE STATION pc.readcommand(executeOrder); } else { // All Anchor Action is in the Interrupt functions! // EXECUTE THIS IF AN ANCHOR wait_ms(10); wdt.kick(); } } } void executeOrder(char* command){ int repetitions = command[3]*100 + command[4]*10 + command[5] - 5328; uint8_t dest1 = command[7] - 48; uint8_t dest2 = command[8] - 48; uint8_t dest3 = command[9] - 48; pc.printf("Debug Point 2 to destination 1: %d, repetitions: %d \r\n", dest1, repetitions); if (strncmp(command, "all", 3) == 0){ baseStationNode.sendOrder(0, NOT_USED, RANGE_ALL, repetitions, Node::BASE_ORDER); // pc.printf("Mode: Range all \r\n"); } else if (strncmp(command, "one", 3) == 0){ pc.printf("Debug Point 3\r\n"); if(dest1 < 15) { pc.printf("Debug Point 6\r\n"); baseStationNode.sendOrder(0, dest1, RANGE_ONE, repetitions, Node::BASE_ORDER); } else { baseStationNode.sendOrder(0, 1, RANGE_ONE, repetitions, Node::BASE_ORDER); } } else if (strncmp(command, "bea", 3) == 0){ if(dest1 < 15) baseStationNode.sendOrder(dest1, NOT_USED, BECOME_BEACON, NOT_USED, Node::SWITCH_TYPE); else baseStationNode.sendOrder(0, NOT_USED, BECOME_BEACON, NOT_USED, Node::SWITCH_TYPE); } else if (strncmp(command, "anc", 3) == 0){ if(dest1 < 15) baseStationNode.sendOrder(dest1, NOT_USED, BECOME_ANCHOR, NOT_USED, Node::SWITCH_TYPE); else baseStationNode.sendOrder(0, NOT_USED, BECOME_ANCHOR, NOT_USED, Node::SWITCH_TYPE); } else if (strncmp(command, "tri", 3) == 0){ // Switch them in correct modes (should already be the case) baseStationNode.sendOrder(dest1, NOT_USED, BECOME_BEACON, NOT_USED, Node::SWITCH_TYPE); baseStationNode.sendOrder(dest2, NOT_USED, BECOME_ANCHOR, NOT_USED, Node::SWITCH_TYPE); baseStationNode.sendOrder(dest3, NOT_USED, BECOME_ANCHOR, NOT_USED, Node::SWITCH_TYPE); // Ranging from first node baseStationNode.sendOrder(dest1, dest2, RANGE_ONE, repetitions, Node::BASE_ORDER); wait_ms(10*repetitions); baseStationNode.sendOrder(dest1, dest3, RANGE_ONE, repetitions, Node::BASE_ORDER); wait_ms(10*repetitions); // Mode Switches baseStationNode.sendOrder(dest2, NOT_USED, BECOME_BEACON, NOT_USED, Node::SWITCH_TYPE); baseStationNode.sendOrder(dest1, NOT_USED, BECOME_ANCHOR, NOT_USED, Node::SWITCH_TYPE); // Rangings baseStationNode.sendOrder(dest2, dest1, RANGE_ONE, repetitions, Node::BASE_ORDER); wait_ms(10*repetitions); baseStationNode.sendOrder(dest2, dest3, RANGE_ONE, repetitions, Node::BASE_ORDER); wait_ms(10*repetitions); // Mode Switches baseStationNode.sendOrder(dest3, NOT_USED, BECOME_BEACON, NOT_USED, Node::SWITCH_TYPE); baseStationNode.sendOrder(dest2, NOT_USED, BECOME_ANCHOR, NOT_USED, Node::SWITCH_TYPE); // Rangings baseStationNode.sendOrder(dest3, dest1, RANGE_ONE, repetitions, Node::BASE_ORDER); wait_ms(10*repetitions); baseStationNode.sendOrder(dest3, dest2, RANGE_ONE, repetitions, Node::BASE_ORDER); wait_ms(10*repetitions); // Back to original modes baseStationNode.sendOrder(dest1, NOT_USED, BECOME_BEACON, NOT_USED, Node::SWITCH_TYPE); baseStationNode.sendOrder(dest2, NOT_USED, BECOME_ANCHOR, NOT_USED, Node::SWITCH_TYPE); baseStationNode.sendOrder(dest3, NOT_USED, BECOME_ANCHOR, NOT_USED, Node::SWITCH_TYPE); } } #pragma Otime // Compiler optimize Runtime at the cost of image size // Called after Frame was received void dwCallbackRx(const dwt_cb_data_t *rxd) { int64_t rxTimeStamp = 0; dwt_readrxdata(node->getRecFrameRef(), min(node->getRecFrameLength(), rxd->datalength), 0); // Read Data Frame from Registers dwt_readrxtimestamp((uint8_t*) &rxTimeStamp); // Read Timestamp when the frame was received exactly rxTimeStamp &= MASK_40BIT; //Mask the 40 Bits of the timestamp node->callbackRX(rxTimeStamp); // Two Way Ranging Function } #pragma Otime // Compiler optimize Runtime at the cost of image size // Called after Frame was transmitted void dwCallbackTx(const dwt_cb_data_t *txd) { int64_t txTimeStamp = 0; dwt_readtxtimestamp((uint8_t*) &txTimeStamp); // Read Timestamp when the frame was transmitted exactly txTimeStamp &= MASK_40BIT; // Delete the most significant 8 Bits because the timestamp has only 40 Bits node->callbackTX(txTimeStamp); // Two Way Ranging Function } int min (int a, int b){ if(a<=b) return a; return b; } void configureDW1000(uint8_t dwMode){ dwt_config_t dwConfig; dwt_txconfig_t dwConfigTx; SMsetconfig(dwMode, &dwConfig, &dwConfigTx); decaWave.setup(dwConfig, dwConfigTx, rfDelays[dwConfig.prf - DWT_PRF_16M], dwCallbackTx, dwCallbackRx); pc.printf("%s\r\n", DW1000_DEVICE_DRIVER_VER_STRING); { uint16_t tempvbat = dwt_readtempvbat(1); if (tempvbat>0) { float tempC = 1.13f * (float) (tempvbat >> 8) - 113.0f; float vbatV = 0.0057f * (float) (tempvbat & 0xFF) + 2.3f; pc.printf(" Voltage: %f, Temperature: %f\r\n", vbatV, tempC); } else { pc.printf("ERROR: Cannot read voltage/temperature\r\n"); } } pc.printf(" Device Lot ID %lu, Part ID %lu\r\n", dwt_getlotid(), dwt_getpartid()); uint16_t DWID = (dwt_getpartid() & 0xFFFF); pc.printf( " Settings %i: \r\n Channel %u (%1.3f GHz w/ %1.3f GHz BW), Datarate %s, \r\n PRF %s, Preamble Code %u, PreambleLength %u symbols, \r\n PAC Size %u, %s SFD, SDF timeout %ul symbols\r\n", dwMode, dwConfig.chan, ChannelFrequency[dwConfig.chan], ChannelBandwidth[dwConfig.chan], ChannelBitrate[dwConfig.dataRate], ChannelPRF[dwConfig.prf], dwConfig.txCode, ChannelPLEN(dwConfig.txPreambLength), ChannelPAC[dwConfig.rxPAC], dwConfig.nsSFD==0?"standard":"non-standard", dwConfig.sfdTO); pc.printf(" Power: NORM %2.1f dB, BOOST: 0.125ms %2.1f dB, 0.25ms %2.1f dB, 0.5ms %2.1f dB\r\n", SMgain(dwConfigTx.power& 0xFF), SMgain((dwConfigTx.power>>24)& 0xFF), SMgain((dwConfigTx.power>>16)& 0xFF), SMgain((dwConfigTx.power>>8)& 0xFF)); pc.printf(" Frame length: %d us\r\n", decaWave.computeFrameLength_us()); pc.printf(" Antenna Delay set to: %d \r\n", decaWave.getAntennaDelay()); decaWave.turnonrx(); // start listening } void rangeAndDisplayOne(uint8_t addr){ beaconNode.requestRanging(addr); pc.printf("%f(%f) \r\n", beaconNode.getDistance(addr), beaconNode.getSignalStrength(addr)); } void rangeAndDisplayAll(){ beaconNode.requestRangingAll(); for(int i = 0; i < ADRESSES_COUNT; i++){ /*if(beaconNode.getDistance(i) > -10){ pc.printf("#%d %f(%f), ", i, beaconNode.getDistance(i), beaconNode.getSignalStrength(i)); }*/ } pc.printf("\r\n"); }