【DWM1000】 code 解密1一 去掉Main 函数多余内容

 蓝点DWM1000 模块已经打样测试完毕,有兴趣的可以申请购买了,更多信息参见 蓝点论坛 

 正文:

  室内定位兴起,DWM1000 作为超宽带UWB的代表,在国内用的越来越多,但是可见资料非常少。 一方面是官方代码写的实在有点太差,另一方面是现在国内普及者将自己的代码当作是商业机密,当作是卖点,很少出来分享解析的。

  我计划花一段时间来梳理DWM1000 代码,之前稍微接触过一点,感觉还能理解DWM1000 一点思路。 放在这里供大家参考。

  作为穷人,目前我淘到一块DWM1000 模块,与我老旧的STM32 还没有互连,也就是说,还没有调试。这里的代码主要是分析思路,难免有误,请大家甄别参考。

  拿到DWM1000 定位代码后发现需要CoCox编译,其实这个编译环境我试了试还是挺好的,免费的东西做成这样已经非常棒了,没有必要换成Keil 了。 另外我分析代码使用了source insight,我本人更偏向用vim 。 推荐大家用SI,有兴趣用vim。

  好了,第一节,我想主要是清理一下Main 函数,因为太多LCD相关的,我们分析code,假定没有液晶,也不考虑LED以及USB把相关代码先全部注释掉。  

int main(void)
{
    int i = 0;
    int toggle = 1;
    double range_result = 0;
    double avg_result = 0;

    led_off(LED_ALL); //turn off all the LEDs

    peripherals_init();

    spi_peripheral_init();

    /*  Sleep(1000); //wait for LCD to power on

  initLCD();

    memset(dataseq, 0, LCD_BUFF_LEN);
    memcpy(dataseq, (const uint8 *) "DECAWAVE        ", 16);
    writetoLCD( 40, 1, dataseq); //send some data
    memcpy(dataseq, (const uint8 *) SOFTWARE_VER_STRING, 16); // Also set at line #26 (Should make this from single value !!!)
    writetoLCD( 16, 1, dataseq); //send some data

    Sleep(1000);*/
	/*
#ifdef USB_SUPPORT
    // enable the USB functionality
    usb_init();
    Sleep(1000);
#endif*/

    s1switch = is_button_low(0) << 1 // is_switch_on(TA_SW1_2) << 2
    		| is_switch_on(TA_SW1_3) << 2
    		| is_switch_on(TA_SW1_4) << 3
    		| is_switch_on(TA_SW1_5) << 4
		    | is_switch_on(TA_SW1_6) << 5
    		| is_switch_on(TA_SW1_7) << 6
    		| is_switch_on(TA_SW1_8) << 7;

    port_DisableEXT_IRQ(); //disable ScenSor IRQ until we configure the device

    //test EVB1000 - used in EVK1000 production
    if((is_button_low(0) == S1_SWITCH_ON) && (is_switch_on(TA_SW1_8) == S1_SWITCH_ON)) //using BOOT1 switch for test
    {
        test_application_run(); //does not return....
    }
    else
    if(is_switch_on(TA_SW1_3) == S1_SWITCH_OFF)
    {
       /* int j = 1000000;
        uint8 command;

        memset(dataseq, 0, LCD_BUFF_LEN);

        while(j--);
        //command = 0x1 ;  //clear screen
        //writetoLCD( 1, 0,  &command);
        command = 0x2 ;  //return cursor home
        writetoLCD( 1, 0,  &command);

        memcpy(dataseq, (const uint8 *) "DECAWAVE   ", 12);
        writetoLCD( 40, 1, dataseq); //send some data
#ifdef USB_SUPPORT //this is set in the port.h file
        memcpy(dataseq, (const uint8 *) "USB to SPI ", 12);
#else
#endif
        writetoLCD( 16, 1, dataseq); //send some data

        j = 1000000;

        while(j--);

        command = 0x2 ;  //return cursor home
        writetoLCD( 1, 0,  &command);*/
		/*
#ifdef USB_SUPPORT //this is set in the port.h file
        // enable the USB functionality
        //usb_init();

        NVIC_DisableDECAIRQ();

        // Do nothing in foreground -- allow USB application to run, I guess on the basis of USB interrupts?
        while (1)       // loop forever
        {
            usb_run();
        }
#endif*/
        return 1;
    }
    else //run DecaRanging application
    {
       /* uint8 dataseq[LCD_BUFF_LEN];
        uint8 command = 0x0;

        command = 0x2 ;  //return cursor home
        writetoLCD( 1, 0,  &command);
        memset(dataseq, ' ', LCD_BUFF_LEN);
        memcpy(dataseq, (const uint8 *) "DECAWAVE  RANGE", 15);
        writetoLCD( 15, 1, dataseq); //send some data

        led_off(LED_ALL);

#ifdef USB_SUPPORT //this is set in the port.h file
        usb_printconfig(16, (uint8 *)SOFTWARE_VER_STRING, s1switch);
#endif*/

        if(inittestapplication(s1switch) == (uint32)-1)
        {
           /* led_on(LED_ALL); //to display error....
            dataseq[0] = 0x2 ;  //return cursor home
            writetoLCD( 1, 0,  &dataseq[0]);
            memset(dataseq, ' ', LCD_BUFF_LEN);
            memcpy(dataseq, (const uint8 *) "ERROR   ", 12);
            writetoLCD( 40, 1, dataseq); //send some data
            memcpy(dataseq, (const uint8 *) "  INIT FAIL ", 12);
            writetoLCD( 40, 1, dataseq); //send some data*/
            return 0; //error
        }

        //sleep for 5 seconds displaying "Decawave"
       /* i=30;
        while(i--)
        {
            if (i & 1) led_off(LED_ALL);
            else    led_on(LED_ALL);

            Sleep(200);
        }
        i = 0;
        led_off(LED_ALL);
        command = 0x2 ;  //return cursor home
        writetoLCD( 1, 0,  &command);

        memset(dataseq, ' ', LCD_BUFF_LEN);*/

        if(s1switch & SWS1_ANC_MODE)
        {
            instance_mode = ANCHOR;

            /led_on(LED_PC6);
        }/
        else
        {
            instance_mode = TAG;
           // led_on(LED_PC7);
        }

        /*if(instance_mode == TAG)
        {
            //if TA_SW1_2 is on use fast ranging (fast 2wr)
            if(is_button_low(0) == S1_SWITCH_ON)
            {
                memcpy(&dataseq[2], (const uint8 *) " Fast Tag   ", 12);
                writetoLCD( 40, 1, dataseq); //send some data
                memcpy(&dataseq[2], (const uint8 *) "   Ranging  ", 12);
                writetoLCD( 16, 1, dataseq); //send some data
            }
            else
            {
                memcpy(&dataseq[2], (const uint8 *) " TAG BLINK  ", 12);

                writetoLCD( 40, 1, dataseq); //send some data
                sprintf((char*)&dataseq[0], "%llX", instance_get_addr());
                writetoLCD( 16, 1, dataseq); //send some data
            }
        }
        else
        {
            memcpy(&dataseq[2], (const uint8 *) "  AWAITING  ", 12);
            writetoLCD( 40, 1, dataseq); //send some data
            memcpy(&dataseq[2], (const uint8 *) "    POLL    ", 12);
            writetoLCD( 16, 1, dataseq); //send some data
        }

        command = 0x2 ;  //return cursor home
        writetoLCD( 1, 0,  &command);*/
    }
#if (DWINTERRUPT_EN == 1)//CN:define1
    port_EnableEXT_IRQ(); //enable ScenSor IRQ before starting
#endif

  /*  memset(dataseq, ' ', LCD_BUFF_LEN);
    memset(dataseq1, ' ', LCD_BUFF_LEN);

#ifdef USART_SUPPORT
    printf2(" %s
", SOFTWARE_VER_STRING);
#endif*/

    // main loop
    while(1)
    {
    /*
#if (DWINTERRUPT_EN == 0)
    	process_deca_irq(); //poll DW1000 IRQ line when using polling of interrupt line
#endif*/
        instance_run();

        //if delayed TX scheduled but did not happen after expected time then it has failed... (has to be < slot period)
        //if anchor just go into RX and wait for next message from tags/anchors
        //if tag handle as a timeout
        if((instance_data[0].monitor == 1) && ((portGetTickCnt() - instance_data[0].timeofTx) > instance_data[0].finalReplyDelay_ms))
        {
			instance_data[0].wait4ack = 0;

			if(instance_mode == TAG)
			{
				inst_processrxtimeout(&instance_data[0]);
			}
			else //if(instance_mode == ANCHOR)
			{
				dwt_forcetrxoff();	//this will clear all events
				//enable the RX
				instance_data[0].testAppState = TA_RXE_WAIT ;
			}
			instance_data[0].monitor = 0;
        }

        if(instancenewrange())
        {
        	int n, l = 0, /*txl = 0, rxl = 0,*/ aaddr, taddr, txa, rxa, rng, rng_raw;
            ranging = 1;
            //send the new range information to LCD and/or USB
            range_result = instance_get_idist();
            avg_result = instance_get_adist();
            //set_rangeresult(range_result);
          /*  dataseq[0] = 0x2 ;  //return cursor home
            writetoLCD( 1, 0,  dataseq);

            memset(dataseq, ' ', LCD_BUFF_LEN);
            memset(dataseq1, ' ', LCD_BUFF_LEN);
            sprintf((char*)&dataseq[1], "LAST: %4.2f m", range_result);
            writetoLCD( 40, 1, dataseq); //send some data

            sprintf((char*)&dataseq1[1], "AVG8: %4.2f m", avg_result);

            writetoLCD( 16, 1, dataseq1); //send some data*/

            l = instance_get_lcount();
            //txl = instance_get_txl();
            //rxl = instance_get_rxl();
            aaddr = instancenewrangeancadd();
            taddr = instancenewrangetagadd();
            txa =  instancetxantdly();
            rxa =  instancerxantdly();
            rng = (int) (range_result*1000);
            rng_raw = (int) (instance_get_idistraw()*1000);

         /*   if(instance_mode == TAG)
            {
                //n = sprintf((char*)&dataseq[0], "ia%04x t%04x %04x %04x %04x %04x %04x %02x %02x t", aaddr, taddr, rng, rng_raw, l, txa, rxa, txl, rxl);
            	n = sprintf((char*)&dataseq[0], "ia%04x t%04x %08x %08x %04x %04x %04x t", aaddr, taddr, rng, rng_raw, l, txa, rxa);
            }
            else
            {
                //n = sprintf((char*)&dataseq[0], "ia%04x t%04x %04x %04x %04x %04x %04x %02x %02x a", aaddr, taddr, rng, rng_raw, l, txa, rxa, txl, rxl);
            	//n = sprintf((char*)&dataseq[0], "ia%04x t%04x %08x %08x %04x %04x %04x %2.2f a", aaddr, taddr, rng, rng_raw, l, txa, rxa, instance_data[0].clockOffset);
            	n = sprintf((char*)&dataseq[0], "ia%04x t%04x %08x %08x %04x %04x %04x a", aaddr, taddr, rng, rng_raw, l, txa, rxa);
            }
#ifdef USB_SUPPORT //this is set in the port.h file
            send_usbmessage(&dataseq[0], n);
#endif*/
/*
#ifdef USART_SUPPORT
            {

            	//printf2("R= %i mm
",rng);
            	printf2("R= %-3.2f m
",range_result);
            }
#endif*/
        }
/*
#ifdef USART_SUPPORT
        {
        int nrm = 0;
			if(nrm = instancenorange())
			{
				if(nrm == 1)
				{
					printf2("I= No Response
");
				}
				else if(nrm == 2)
				{
					printf2("I= No Report
");
				}
				else if(nrm == 3)
				{
					printf2("I= No Final
");
				}
			}
        }
#endif*/

        if(ranging == 0)
        {
            if(instance_mode != ANCHOR)
            {
                if(instancesleeping())
                {
                    //dataseq[0] = 0x2 ;  //return cursor home
                  //  writetoLCD( 1, 0,  dataseq);
                    if(toggle)
                    {
                       /* toggle = 0;
                        memcpy(&dataseq[0], (const uint8 *) "    AWAITING    ", 16);
                        writetoLCD( 40, 1, dataseq); //send some data
                        memcpy(&dataseq[0], (const uint8 *) "    RESPONSE    ", 16);
                        writetoLCD( 16, 1, dataseq); //send some data*/
                    }
                    else
                    {
                      /*  toggle = 1;
                        memcpy(&dataseq[2], (const uint8 *) "   TAG BLINK    ", 16);

                        writetoLCD( 40, 1, dataseq); //send some data
                        sprintf((char*)&dataseq[0], "%llX", instance_get_addr());
                        writetoLCD( 16, 1, dataseq); //send some data*/
                    }
                }

                if(instanceanchorwaiting() == 2)
                {
                    ranging = 1;
                   /* dataseq[0] = 0x2 ;  //return cursor home
                    writetoLCD( 1, 0,  dataseq);
                    memcpy(&dataseq[0], (const uint8 *) "    RANGING WITH", 16);
                    writetoLCD( 40, 1, dataseq); //send some data
                    sprintf((char*)&dataseq[0], "%016llX", instance_get_anchaddr());
                    writetoLCD( 16, 1, dataseq); //send some data*/
                }
            }
            else //if(instance_mode == ANCHOR)
            {
                if(instanceanchorwaiting())
                {
                 /*   toggle+=2;

                    if(toggle > 300000)
                    {
                        dataseq[0] = 0x2 ;  //return cursor home
                        writetoLCD( 1, 0,  dataseq);
                        if(toggle & 0x1)
                        {
                            toggle = 0;
                            memcpy(&dataseq[0], (const uint8 *) "    AWAITING    ", 16);
                            writetoLCD( 40, 1, dataseq); //send some data
                            memcpy(&dataseq[0], (const uint8 *) "      POLL      ", 16);
                            writetoLCD( 16, 1, dataseq); //send some data
                        }
                        else
                        {
                            toggle = 1;
                            memcpy(&dataseq[0], (const uint8 *) " DISCOVERY MODE ", 16);
                            writetoLCD( 40, 1, dataseq); //send some data
                            sprintf((char*)&dataseq[0], "%llX", instance_get_addr());
                            writetoLCD( 16, 1, dataseq); //send some data
                        }
                    }*/

                }
                else if(instanceanchorwaiting() == 2)
                {
                 /*   dataseq[0] = 0x2 ;  //return cursor home
                    writetoLCD( 1, 0,  dataseq);
                    memcpy(&dataseq[0], (const uint8 *) "    RANGING WITH", 16);
                    writetoLCD( 40, 1, dataseq); //send some data
                    sprintf((char*)&dataseq[0], "%llX", instance_get_tagaddr());
                    writetoLCD( 16, 1, dataseq); //send some data*/
                }
            }
        }

        /*
#ifdef USB_SUPPORT //this is set in the port.h file
        usb_run();
#endif*/
    }


    return 0;
}

  上面代码不用看,如果你看了,恭喜你,帮我找一下看我注释掉的代码是否有问题, 我把注释掉的直接先删掉吧,虽然不是处女座,但是我看code 非常有洁癖的。

 

int main(void)
{
    int i = 0;
    int toggle = 1;
    double range_result = 0;
    double avg_result = 0;

    led_off(LED_ALL); //turn off all the LEDs
    peripherals_init();
    spi_peripheral_init();

    s1switch = is_button_low(0) << 1 // is_switch_on(TA_SW1_2) << 2
    		| is_switch_on(TA_SW1_3) << 2
    		| is_switch_on(TA_SW1_4) << 3
    		| is_switch_on(TA_SW1_5) << 4
		    | is_switch_on(TA_SW1_6) << 5
    		| is_switch_on(TA_SW1_7) << 6
    		| is_switch_on(TA_SW1_8) << 7;

    port_DisableEXT_IRQ(); //disable ScenSor IRQ until we configure the device
    //test EVB1000 - used in EVK1000 production
    if((is_button_low(0) == S1_SWITCH_ON) && (is_switch_on(TA_SW1_8) == S1_SWITCH_ON)) //using BOOT1 switch for test
    {
        test_application_run(); //does not return....
    }
    else
    if(is_switch_on(TA_SW1_3) == S1_SWITCH_OFF)
    {
        return 1;
    }
    else //run DecaRanging application
    {
        if(inittestapplication(s1switch) == (uint32)-1)
        {
            return 0; //error
        }     

        if(s1switch & SWS1_ANC_MODE)
        {
            instance_mode = ANCHOR;

            /led_on(LED_PC6);
        }/
        else
        {
            instance_mode = TAG;
          
        }     
    }
#if (DWINTERRUPT_EN == 1)//CN:define1
    port_EnableEXT_IRQ(); //enable ScenSor IRQ before starting
#endif
    // main loop
    while(1)
    {
        instance_run();
        if((instance_data[0].monitor == 1) && ((portGetTickCnt() - instance_data[0].timeofTx) > instance_data[0].finalReplyDelay_ms))
        {
			instance_data[0].wait4ack = 0;

			if(instance_mode == TAG)
			{
				inst_processrxtimeout(&instance_data[0]);
			}
			else //if(instance_mode == ANCHOR)
			{
				dwt_forcetrxoff();	//this will clear all events
				//enable the RX
				instance_data[0].testAppState = TA_RXE_WAIT ;
			}
			instance_data[0].monitor = 0;
        }
        if(instancenewrange())
        {
        	int n, l = 0, /*txl = 0, rxl = 0,*/ aaddr, taddr, txa, rxa, rng, rng_raw;
            ranging = 1;
            //send the new range information to LCD and/or USB
            range_result = instance_get_idist();
            avg_result = instance_get_adist();
            l = instance_get_lcount();
            //txl = instance_get_txl();
            //rxl = instance_get_rxl();
            aaddr = instancenewrangeancadd();
            taddr = instancenewrangetagadd();
            txa =  instancetxantdly();
            rxa =  instancerxantdly();
            rng = (int) (range_result*1000);
            rng_raw = (int) (instance_get_idistraw()*1000);      
        if(ranging == 0)
        {
            if(instance_mode != ANCHOR)
            {
                if(instancesleeping())
                {
                    if(toggle)
                    {
                    }
                    else
                    {
                    }
                }
                if(instanceanchorwaiting() == 2)
                {
                    ranging = 1;
                 
                }
            }
            else //if(instance_mode == ANCHOR)
            {
                if(instanceanchorwaiting())
                {               

                }
                else if(instanceanchorwaiting() == 2)
                {
                }
             }
        }
      
    }
    return 0;
}

  删除注释,一下清爽很多,可能删除了一些有用的code,如果后面分析不同,我们再补回来。

下面再删除一个关于test的东西, Main 函数开始通过按键选择执行,有个test函数还不返回,我们定位不执行这部分,再次删除。

删除函数: test_application_run(); //does not return....

int main(void)
{
    int i = 0;
    int toggle = 1;
    double range_result = 0;
    double avg_result = 0;

    led_off(LED_ALL); //turn off all the LEDs
    peripherals_init();
    spi_peripheral_init();

    s1switch = is_button_low(0) << 1 // is_switch_on(TA_SW1_2) << 2
    		| is_switch_on(TA_SW1_3) << 2
    		| is_switch_on(TA_SW1_4) << 3
    		| is_switch_on(TA_SW1_5) << 4
		    | is_switch_on(TA_SW1_6) << 5
    		| is_switch_on(TA_SW1_7) << 6
    		| is_switch_on(TA_SW1_8) << 7;

    port_DisableEXT_IRQ(); //disable ScenSor IRQ until we configure the device
    else //run DecaRanging application
    {
        if(inittestapplication(s1switch) == (uint32)-1)
        {
            return 0; //error
        }     

        if(s1switch & SWS1_ANC_MODE)
        {
            instance_mode = ANCHOR;

            /led_on(LED_PC6);
        }/
        else
        {
            instance_mode = TAG;
          
        }     
    }
#if (DWINTERRUPT_EN == 1)//CN:define1
    port_EnableEXT_IRQ(); //enable ScenSor IRQ before starting
#endif
    // main loop
    while(1)
    {
        instance_run();
        if((instance_data[0].monitor == 1) && ((portGetTickCnt() - instance_data[0].timeofTx) > instance_data[0].finalReplyDelay_ms))
        {
			instance_data[0].wait4ack = 0;

			if(instance_mode == TAG)
			{
				inst_processrxtimeout(&instance_data[0]);
			}
			else //if(instance_mode == ANCHOR)
			{
				dwt_forcetrxoff();	//this will clear all events
				//enable the RX
				instance_data[0].testAppState = TA_RXE_WAIT ;
			}
			instance_data[0].monitor = 0;
        }
        if(instancenewrange())
        {
        	int n, l = 0, /*txl = 0, rxl = 0,*/ aaddr, taddr, txa, rxa, rng, rng_raw;
            ranging = 1;
            //send the new range information to LCD and/or USB
            range_result = instance_get_idist();
            avg_result = instance_get_adist();
            l = instance_get_lcount();
            //txl = instance_get_txl();
            //rxl = instance_get_rxl();
            aaddr = instancenewrangeancadd();
            taddr = instancenewrangetagadd();
            txa =  instancetxantdly();
            rxa =  instancerxantdly();
            rng = (int) (range_result*1000);
            rng_raw = (int) (instance_get_idistraw()*1000);      
        if(ranging == 0)
        {
            if(instance_mode != ANCHOR)
            {
                if(instancesleeping())
                {
                    if(toggle)
                    {
                    }
                    else
                    {
                    }
                }
                if(instanceanchorwaiting() == 2)
                {
                    ranging = 1;
                 
                }
            }
            else //if(instance_mode == ANCHOR)
            {
                if(instanceanchorwaiting())
                {               

                }
                else if(instanceanchorwaiting() == 2)
                {
                }
             }
        }
      
    }
    return 0;
}  

再来看现在代码,直接从else 开始了,直奔主题。

        if(inittestapplication(s1switch) == (uint32)-1)
        {
            return 0; //error
        }     

        if(s1switch & SWS1_ANC_MODE)
        {
            instance_mode = ANCHOR;

            /led_on(LED_PC6);
        }/
        else
        {
            instance_mode = TAG;
          
        }     
    }
#if (DWINTERRUPT_EN == 1)//CN:define1
    port_EnableEXT_IRQ(); //enable ScenSor IRQ before starting
#endif
    // main loop
    while(1)
    {
        instance_run();

  上面代码中,红色字体的两个函数是整个定位中非常重要的两个函数。

第一节,就分析到这里,主要是删除多余代码

  

博客讨论一些室内定位(DWM1000/CC2431/CC2530) 以及一些随性的技术。博文可以转载,但需要注明出处!
原文地址:https://www.cnblogs.com/tuzhuke/p/7702211.html