diagradio.c

Go to the documentation of this file.
00001 /* Copyright (c) 2007 Axel Wachtler
00002    All rights reserved.
00003 
00004    Redistribution and use in source and binary forms, with or without
00005    modification, are permitted provided that the following conditions
00006    are met:
00007 
00008    * Redistributions of source code must retain the above copyright
00009      notice, this list of conditions and the following disclaimer.
00010    * Redistributions in binary form must reproduce the above copyright
00011      notice, this list of conditions and the following disclaimer in the
00012      documentation and/or other materials provided with the distribution.
00013    * Neither the name of the authors nor the names of its contributors
00014      may be used to endorse or promote products derived from this software
00015      without specific prior written permission.
00016 
00017    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00018    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00019    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00020    ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00021    LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00022    CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00023    SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00024    INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00025    CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00026    ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00027    POSSIBILITY OF SUCH DAMAGE. */
00028 
00029 /* $Id: diagradio.c,v 1.8 2010/04/26 19:33:39 awachtler Exp $ */
00040 #include <string.h>
00041 #include "radio.h"
00042 #include "transceiver.h"
00043 #include "ioutil.h"
00044 #include "timer.h"
00045 /* === Types ===============================================*/
00046 
00047 typedef struct
00048 {
00049     uint8_t new;
00050     uint8_t len;
00051     uint8_t crc;
00052     uint8_t lqi;
00053     uint8_t ed;
00054     uint8_t seq;
00055 } rx_frame_t;
00056 
00057 
00058 typedef struct
00059 {
00060     uint32_t rxcnt;
00061     uint32_t crcerr;
00062     uint32_t ed;
00063     uint32_t lqi;
00064 
00065     uint32_t txcnt;
00066     time_t   start;
00067 } statistic_t;
00068 
00069 
00070 typedef struct
00071 {
00072     channel_t channel;
00073     txpwr_t   txpwr;
00074     ccamode_t ccamode;
00075     rxidle_t  rxidle;
00076 } rdiag_ctx_t;
00077 
00078 /* === Prototypes ==========================================*/
00079 void rdiag_init(void);
00080 void set_next_channel(channel_t chaninc);
00081 void set_next_pwr(int8_t pwrinc);
00082 void set_next_cca(void);
00083 
00084 void toggle_rxon_idle(void);
00085 void send_frame(uint8_t seq);
00086 void send_continous(void);
00087 void show_statistic(bool reset);
00088 void help(void);
00089 time_t blink(timer_arg_t t);
00090 
00091 /* === Globals =============================================*/
00092 static uint8_t RxBuf[MAX_FRAME_SIZE];
00093 static uint8_t TxBuf[MAX_FRAME_SIZE];
00094 static rx_frame_t rxfrm;
00095 
00096 statistic_t RdiagStat;
00097 static rdiag_ctx_t RdiagCtx;
00098 
00099 
00100 
00101 int8_t verbose;
00102 bool   conttx;
00103 uint8_t tx_length = 42;
00104 #define TBLINK_PERIOD (500)
00105 #define NL "\n\r"
00106 timer_hdl_t  th_blink;
00107 
00109 trx_param_t PROGMEM trxp_flash = {chan: 13, txp: 0, cca: 1, edt: 11, clkm: 0};
00110 
00119 int main(void)
00120 {
00121 
00122 uint16_t inchar;
00123 uint8_t tmp, seq, *p;
00124 trx_param_t trxp;
00125 #if 0
00126 trx_cfg_t cfgt;
00127 #endif
00128 
00129     rdiag_init();
00130 
00131     PRINT(NL"Radio Diag 0.20"NL);
00132     tmp = trx_reg_read(RG_TRX_STATUS);
00133     PRINTF(">RADIO INIT[%s]: %s (status=0x%02x)"NL, BOARD_NAME, (tmp == 8 ? "OK" : "FAIL"), tmp );
00134     PRINTF("Timer-Tick %lx"NL, TIMER_TICK);
00135     tmp = trx_reg_read(RG_PART_NUM);
00136     PRINTF("RADIO_PART_NUM = 0x%02x, RG_PART_NUM = 0x%02x"NL,
00137        RADIO_PART_NUM, tmp);
00138     tmp = trx_reg_read(RG_VERSION_NUM);
00139     PRINTF("RADIO_VERSION_NUM = 0x%02x, RG_VERSION_NUM = 0x%02x"NL,
00140        RADIO_VERSION_NUM, tmp);
00141     PRINT("Config: ");
00142 
00143     /* CONFIG */
00144 #if 0
00145     cfgt = radio_config_recall();
00146     if (cfgt != CFG_NONE)
00147     {
00148         PRINTF("use settings from %s"NL, (cfgt == CFG_EEPROM ? "eeprom" : "flash"));
00149     }
00150 #else
00151 #warning "no radio_config_recall()"
00152 #endif
00153     th_blink = timer_start(blink,TBLINK_PERIOD,0);
00154     seq = 0;
00155 
00156     while(1)
00157     {
00158         inchar = hif_getc();
00159         if(inchar<0x100)
00160         {
00161             switch ((char)inchar)
00162             {
00163 
00164                 case '+':
00165                     set_next_channel(+1);
00166                     break;
00167                 case '-':
00168                     set_next_channel(-1);
00169                     break;
00170 
00171                 case 'p':
00172                     set_next_pwr(-1);
00173                     break;
00174                 case 'P':
00175                     set_next_pwr(1);
00176                     break;
00177 
00178                 case 'c':
00179                     tmp = radio_do_cca();
00180                     PRINTF(">CCA: status=%d"NL, tmp);
00181                     break;
00182                 case 'C':
00183                     set_next_cca();
00184                     break;
00185 
00186                 case 'R':
00187                     toggle_rxon_idle();
00188                     break;
00189 
00190                 case 'r':
00191                     radio_set_state(STATE_RX);
00192                     PRINT(">SATE_RX"NL);
00193                     break;
00194 
00195                 case 't':
00196                     radio_set_state(STATE_TX);
00197                     PRINT(">SATE_TX"NL);
00198                     break;
00199 
00200                 case 'o':
00201                     radio_set_state(STATE_OFF);
00202                     PRINT(">SATE_OFF"NL);
00203                     break;
00204 
00205                 case 'l':
00206                     tx_length += 1;
00207                     tx_length &= 0x7f;
00208                     PRINTF(">TX LEN = %d"NL,tx_length);
00209                     break;
00210 
00211                 case 'L':
00212                     tx_length += 10;
00213                     tx_length &= 0x7f;
00214                     PRINTF(">TX LEN = %d"NL,tx_length);
00215                     break;
00216 
00217                 case 's':
00218                     send_frame(tx_length);
00219                     break;
00220 
00221                 case 'S':
00222                     send_continous();
00223                     break;
00224 
00225                 case 'i':
00226                     show_statistic(0);
00227                     break;
00228 
00229                 case 'I':
00230                     show_statistic(1);
00231                     break;
00232 
00233                 case 'h':
00234                     help();
00235                     break;
00236 
00237                 case 'v':
00238                     if(verbose>0) verbose --;
00239                     PRINTF(">VERBOSE: %d"NL,verbose);
00240                     break;
00241 
00242                 case 'V':
00243                     if(verbose<2) verbose ++;
00244                     PRINTF(">VERBOSE: %d"NL,verbose);
00245                     break;
00246 
00247                 case 'g':
00248                     trx_parms_get(&trxp);
00249                     PRINTF("{"\
00250                            "chan: %d, txp: %d,"\
00251                            " cca: %d,\n\r edt: %d,"\
00252                            " clkm: %d}"NL,
00253                             trxp.chan, trxp.txp, trxp.cca,
00254                             trxp.edt, trxp.clkm);
00255                     p = (uint8_t*)&trxp;
00256                     PRINTF("avrdude: w ee 8 0x%x 0x%x 0x%x 0x%x 0x%x"NL,
00257                            p[0],p[1],p[2],p[3],p[4]);
00258                     break;
00259 
00260 #if 0
00261                 case 'G':
00262                     radio_config_store();
00263                     PRINT("params stored in EEPROM"NL);
00264                     break;
00265 
00266 
00267                 case 'b':
00268                     JUMP_BOOT_LOADER();
00269                     PRINT("There is no BootLoader defined"NL);
00270                     break;
00271 #endif
00272             default:
00273                     PRINTF("unsuppored command: %s"NL, inchar);
00274 
00275             }
00276         }
00277 
00278         if(rxfrm.new == 1)
00279         {
00280             if (verbose > 0)
00281             {
00282                 PRINTF("++FRAME len=%d, crc=%3s, lqi=%d ed=%d seq=%d"NL,
00283                     rxfrm.len, rxfrm.crc ? "ERR" : "OK",
00284                     rxfrm.lqi, rxfrm.ed, rxfrm.seq);
00285             }
00286             if (verbose > 1)
00287             {
00288                 DUMP(rxfrm.len, RxBuf);
00289             }
00290             rxfrm.new = 0;
00291         }
00292 
00293     }
00294     return 0;
00295 
00296 }
00297 
00298 
00299 void rdiag_init(void)
00300 {
00301     memset(TxBuf, 0x55, sizeof(TxBuf));
00302     memset(RxBuf, 0xff, sizeof(RxBuf));
00303     /* reset ressource  radio parameter */
00304     LED_INIT();
00305     KEY_INIT();
00306     timer_init();
00307     hif_init(9600);
00308     radio_init(RxBuf, MAX_FRAME_SIZE);
00309 
00310     sei();
00311 
00312     /* init radio parameter */
00313 
00314     RdiagCtx.channel = TRX_MIN_CHANNEL;
00315     radio_set_param(RP_CHANNEL(RdiagCtx.channel));
00316 
00317     RdiagCtx.txpwr = 0;
00318     radio_set_param(RP_TXPWR(RdiagCtx.txpwr));
00319 
00320     RdiagCtx.ccamode = 1;
00321     radio_set_param(RP_CCAMODE(RdiagCtx.ccamode));
00322 
00323     RdiagCtx.rxidle = false;
00324     radio_set_param(RP_IDLESTATE(STATE_OFF));
00325 }
00326 
00330 void set_next_channel(int8_t chaninc)
00331 {
00332 
00333     if (chaninc > 0)
00334     {
00335         RdiagCtx.channel = TRX_NEXT_CHANNEL_WRAP(RdiagCtx.channel);
00336     }
00337     else if (chaninc < 0)
00338     {
00339         RdiagCtx.channel = TRX_PREV_CHANNEL_WRAP(RdiagCtx.channel);
00340     }
00341 
00342     radio_set_param(RP_CHANNEL(RdiagCtx.channel));
00343     PRINTF(">CHAN: %d"NL, RdiagCtx.channel);
00344 }
00345 
00349 void toggle_rxon_idle(void)
00350 {
00351     RdiagCtx.rxidle ^= 1;
00352     if (RdiagCtx.rxidle == 1)
00353     {
00354         radio_set_param(RP_IDLESTATE(STATE_RX));
00355     }
00356     else
00357     {
00358         radio_set_param(RP_IDLESTATE(STATE_OFF));
00359     }
00360     PRINTF(">RXON_IDLE: %d"NL, RdiagCtx.rxidle);
00361 }
00362 
00366 void set_next_pwr(int8_t pwrinc)
00367 {
00368 
00369     RdiagCtx.txpwr +=  pwrinc;
00370     if (RdiagCtx.txpwr > 15)
00371     {
00372         RdiagCtx.txpwr = 0;
00373     }
00374     else if (RdiagCtx.txpwr < 0)
00375     {
00376         RdiagCtx.txpwr = 15;
00377     }
00378     radio_set_param(RP_TXPWR(RdiagCtx.txpwr));
00379     PRINTF(">PWR: %d"NL, RdiagCtx.txpwr);
00380 }
00381 
00382 
00386 void set_next_cca(void)
00387 {
00388 
00389 char *pcca[] = {"?","ED","CS","CS&ED"};
00390 
00391     RdiagCtx.ccamode += 1;
00392     if (RdiagCtx.ccamode > 3)
00393     {
00394         RdiagCtx.ccamode = 1;
00395     }
00396 
00397     radio_set_param(RP_CCAMODE(RdiagCtx.ccamode));
00398 
00399     PRINTF(">CCA: mode=%d (%s)"NL, RdiagCtx.ccamode, pcca[RdiagCtx.ccamode]);
00400 }
00401 
00402 
00406 void send_frame(uint8_t frmlen)
00407 {
00408     static uint8_t seqnb;
00409 
00410     seqnb ++;
00411     if (frmlen < 5)
00412     {
00413         frmlen = 5;
00414     }
00415     if (frmlen > MAX_FRAME_SIZE)
00416     {
00417         frmlen = MAX_FRAME_SIZE;
00418     }
00419     TxBuf[0] = 1;
00420     TxBuf[1] = 0;
00421     TxBuf[2] = seqnb;
00422     TxBuf[frmlen - 2] = 0;
00423     TxBuf[frmlen - 1] = 0;
00424     radio_set_state(STATE_TX);
00425     radio_send_frame(frmlen, TxBuf, 0);
00426 
00427     PRINTF(">SEND len=%d"NL,frmlen);
00428     if (verbose > 1)
00429     {
00430         DUMP(frmlen, TxBuf);
00431     }
00432 }
00433 
00437 void send_continous(void)
00438 {
00439 static bool active = 0;
00440 
00441     active  ^= 1;
00442 
00443     if(active)
00444     {
00445         RdiagCtx.rxidle = 2;
00446         radio_set_param(RP_IDLESTATE(STATE_TX));
00447     }
00448     else
00449     {
00450         RdiagCtx.rxidle = 0;
00451         radio_set_param(RP_IDLESTATE(STATE_OFF));
00452 
00453     }
00454     PRINTF(">SEND CONTINOUS %s"NL, (RdiagCtx.rxidle ? "START":"STOP"));
00455     if(RdiagCtx.rxidle)
00456     {
00457         send_frame(tx_length);
00458     }
00459 }
00460 
00461 
00462 
00466 uint8_t * usr_radio_receive_frame(uint8_t len, uint8_t *frm, uint8_t lqi,
00467                                   int8_t ed, uint8_t crc)
00468 {
00469     rxfrm.new = 1;
00470     rxfrm.len = len;
00471     rxfrm.crc = crc;
00472     rxfrm.lqi = lqi;
00473     rxfrm.ed = ed;
00474     if (rxfrm.len > 3)
00475     {
00476         rxfrm.seq = frm[2];
00477     }
00478 
00479     RdiagStat.crcerr += ( (crc != 0)||(len==0) ? 1 : 0);
00480     RdiagStat.rxcnt ++;
00481     RdiagStat.lqi += lqi;
00482     RdiagStat.ed += ed;
00483     return frm;
00484 }
00485 
00489 void usr_radio_tx_done(radio_tx_done_t status)
00490 {
00491 static uint8_t sn;
00492    RdiagStat.txcnt++;
00493    if(conttx)
00494    {
00495         /* force next frame sending */
00496         TRX_SLPTR_HIGH();
00497         TRX_SLPTR_LOW();
00498         trx_sram_write(3, 1, &sn);
00499         sn ++;
00500    }
00501 }
00502 
00506 void show_statistic(bool reset)
00507 {
00508 
00509 time_t now;
00510 
00511     now = timer_systime();
00512     PRINTF(
00513         ">STAT"
00514         " duration: %ld ticks"NL,
00515             now - RdiagStat.start);
00516 
00517     PRINTF(
00518         " RX:"
00519         " frames: %ld"
00520         " crcerr: %ld"NL,
00521             RdiagStat.rxcnt, RdiagStat.crcerr);
00522     PRINTF(
00523         " RX: channel %d"
00524         " avg ed: %ld"
00525         " avg lqi:  %ld"NL,
00526             RdiagCtx.channel,
00527             RdiagStat.ed/RdiagStat.rxcnt, RdiagStat.lqi/RdiagStat.rxcnt);
00528 
00529     PRINTF(
00530         " TX:"
00531         " frames: %ld"NL,
00532             RdiagStat.txcnt);
00533     if (reset)
00534     {
00535         memset(&RdiagStat, 0, sizeof(RdiagStat));
00536         RdiagStat.start = timer_systime();
00537     }
00538 }
00539 
00540 
00544 void usr_radio_error(radio_error_t err)
00545 {
00546 uint8_t regval, r2, r3;
00547 uint16_t t;
00548     regval = trx_reg_read(RG_TRX_STATUS);
00549     r2 = trx_reg_read(0x30);
00550     r3 = trx_reg_read(RG_VREG_CTRL);
00551     while(1)
00552     {
00553 
00554         PRINTF("\n\rRADIO ERROR : %d radio status : 0x%02x:0x%02x:0x%02x\n\r",
00555                 err, regval, r2, r3);
00556         t = 2000;
00557         while(t--)
00558         {
00559             DELAY_US(1000);
00560         }
00561     }
00562 }
00563 
00564 
00565 
00569 void help(void)
00570 {
00571     PRINT("i/I : show / show and reset statistic"NL);
00572     PRINT("o   : set state OFF"NL);
00573     PRINT("r   : set state RX"NL);
00574     PRINT("t   : set state TX"NL);
00575     PRINT("+/- : incr./decr. channel"NL);
00576     PRINT("s   : send a test frame"NL);
00577     PRINT("S   : start/stop continous sending frames"NL);
00578     PRINT("R   : toggle RXON_IDLE parameter"NL);
00579     PRINT("P/p : incr./decr. power"NL);
00580     PRINT("c   : do CCA measurement"NL);
00581     PRINT("C   : change CCA mode"NL);
00582     PRINT("V/v : incr./decr. verbosity (0...2)"NL);
00583     PRINT("G/g : store/show seetings"NL);
00584 }
00585 
00586 
00587 
00588 
00592 time_t blink(timer_arg_t t)
00593 {
00594 #if LED_NUMBER > 0
00595 static volatile uint8_t btick;
00596 #endif
00597     LED_SET_VALUE(btick++);
00598     /* restart the timer again */
00599     return  TBLINK_PERIOD;
00600 }
00601 

This documentation for µracoli was generated on Wed Feb 2 2011 by  doxygen 1.7.1