Subversion Repositories Projects

Rev

Rev 253 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
230 dhylands 1
/****************************************************************************
2
*
3
*   Copyright (c) 2009 Dave Hylands     <dhylands@gmail.com>
4
*
5
*   This program is free software; you can redistribute it and/or modify
6
*   it under the terms of the GNU General Public License version 2 as
7
*   published by the Free Software Foundation.
8
*
9
*   Alternatively, this software may be distributed under the terms of BSD
10
*   license.
11
*
12
*   See README and COPYING for more details.
13
*
14
****************************************************************************/
15
/**
16
*
17
*   @file   BioloidCommandLine.cpp
18
*
19
*   @brief  This file implements the BioloidCommandLine class, which
20
*           parses command lines and sends the commands to devices on the
21
*   bioloid bus.
22
*
23
****************************************************************************/
24
 
25
// ---- Include Files -------------------------------------------------------
26
 
253 dhylands 27
#include <stddef.h>
230 dhylands 28
#include <string.h>
29
#include "Str.h"
30
#include "DumpMem.h"
31
#include "Log.h"
32
#include "Bioloid.h"
253 dhylands 33
#include "bioloid-reg.h"
230 dhylands 34
#include "BioloidCommandLine.h"
35
 
36
// ---- Public Variables ----------------------------------------------------
37
// ---- Private Constants and Types -----------------------------------------
38
// ---- Private Variables ---------------------------------------------------
39
 
40
static char             gDelim[] = " \r\n\t";
41
 
42
static uint8_t          gErrorBuf[ 80 ];
43
static uint8_t          gReadBuf[ 80 ];
44
 
253 dhylands 45
// We use the register data structure to parse our global data, so we
46
// need to make it look sort of like what a real device has (8 and 16-bit
47
// data types - arranged contigupously in memory)
48
 
49
struct Global_t
50
{
51
    uint8_t     m_showPackets;
52
    uint8_t     m_timeout;
53
 
54
};
55
 
56
static  Global_t    gGlobal;
57
 
58
#define GLBL_OFS(x) offsetof( Global_t, x )
59
 
60
static BLD_Reg_t   gGlobalReg[] =
61
{
62
    { GLBL_OFS( m_showPackets ),    "show-packets",     BLD_REG_FLAG_8_RW,  0,    1,  BLD_RegFmtOnOff,  BLD_RegParseOnOff },
63
    { GLBL_OFS( m_timeout ),        "timeout",          BLD_REG_FLAG_8_RW,  0,  255,  NULL,             NULL },
64
};
65
 
66
static BLD_DevType_t   gGlobalDevType =
67
{
68
    "global",                                       // devTypeStr
69
    0,                                              // model
70
    sizeof( gGlobalReg ) / sizeof( gGlobalReg[0] ), // numRegs
71
    gGlobalReg,                                     // reg
72
    sizeof( gGlobal ),                              // numRegBytes
73
};
74
 
75
class GlobalDevice : public BioloidDevice
76
{
77
public:
78
    GlobalDevice();
79
    virtual ~GlobalDevice();
80
 
81
    virtual Bioloid::Error Read( uint8_t offset, void *data, uint8_t numBytes );
82
    virtual Bioloid::Error Write( uint8_t offset, const void *data, uint8_t numBytes );
83
 
84
private:
85
 
86
};
87
 
88
GlobalDevice::GlobalDevice()
89
{
90
}
91
 
92
GlobalDevice::~GlobalDevice()
93
{
94
}
95
 
96
Bioloid::Error GlobalDevice::Read( uint8_t offset, void *data, uint8_t numBytes )
97
{
98
    if ( offset + numBytes <= sizeof( gGlobal ))
99
    {
100
        memcpy( data, (uint8_t *)&gGlobal + offset, numBytes );
101
        return Bioloid::ERROR_NONE;
102
    }
103
    return Bioloid::ERROR_RANGE;
104
}
105
 
106
Bioloid::Error GlobalDevice::Write( uint8_t offset, const void *data, uint8_t numBytes )
107
{
108
    if ( offset + numBytes <= sizeof( gGlobal ))
109
    {
110
        memcpy( (uint8_t *)&gGlobal + offset, data, numBytes );
111
        return Bioloid::ERROR_NONE;
112
    }
113
    return Bioloid::ERROR_RANGE;
114
}
115
 
116
static  GlobalDevice    gGlobalDev;
117
 
230 dhylands 118
// ---- Private Function Prototypes -----------------------------------------
119
// ---- Functions -----------------------------------------------------------
120
 
121
/**
122
 * @addtogroup bioloid
123
 * @{
124
 */
125
 
126
//***************************************************************************
127
/**
128
*   Constructor
129
*/
130
 
131
BioloidCommandLine::BioloidCommandLine()
132
    : m_bus( NULL )
133
{
134
}
135
 
136
//***************************************************************************
137
/**
138
*   Destructor
139
*
140
*   virtual
141
*/
142
 
143
BioloidCommandLine::~BioloidCommandLine()
144
{
145
}
146
 
147
//***************************************************************************
148
/**
149
*   Dumps information about the registers
150
*/
151
 
152
void BioloidCommandLine::DumpRegInfo( BLD_DevType_t *devType )
153
{
154
    BLD_Reg_t  *reg;
240 dhylands 155
    unsigned    regIdx;
230 dhylands 156
 
157
    Log( "Addr Size Min  Max Name\n" );
158
    Log( "---- ---- ---  --- --------------------\n" );
159
 
160
    for ( regIdx = 0; regIdx < devType->numRegs; regIdx++ )
161
    {
162
        reg = &devType->reg[ regIdx];
163
 
164
        if (( reg->flags & BLD_REG_FLAG_WR ) == 0 )
165
        {
166
            Log( "0x%02x ro %d          %s\n",
167
                 reg->address, reg->flags & BLD_REG_FLAG_16BIT ? 2 : 1, reg->name );
168
        }
169
        else
170
        {
171
            Log( "0x%02x rw %d %3d %4d %s\n",
172
                 reg->address, reg->flags & BLD_REG_FLAG_16BIT ? 2 : 1,
173
                 reg->minVal, reg->maxVal, reg->name );
174
        }
175
    }
176
}
177
 
178
//***************************************************************************
179
/**
180
*   Parses an offset and some data.
181
*/
182
 
183
bool BioloidCommandLine::ParseOffsetAndData( StrTokenizer &line, uint8_t *offset, uint8_t *numBytes, uint8_t *data, size_t maxLen )
184
{
185
    *numBytes = 0;
186
 
187
    if ( !line.NextNum( offset ))
188
    {
189
        LogError( "Invalid offset specified: '%s'\n", line.PrevToken() );
190
        return false;
191
    }
192
 
193
    while (( *numBytes < maxLen ) && line.NextNum( &data[ *numBytes ] ))
194
    {
195
        (*numBytes)++;
196
    }
197
 
198
    return true;
199
}
200
 
201
//***************************************************************************
202
/**
203
*   Parses a register name
204
*/
205
 
206
bool BioloidCommandLine::ParseRegisterName( StrTokenizer &line, BLD_DevType_t *devType, BLD_Reg_t **outRegp )
207
{
208
    char        *regStr;
240 dhylands 209
    unsigned     regIdx;
230 dhylands 210
 
211
    if (( regStr = line.NextToken()) == NULL )
212
    {
213
        LogError( "No register specified\n" );
214
        return false;
215
    }
216
 
217
    for ( regIdx = 0; regIdx < devType->numRegs; regIdx++ )
218
    {
219
        if ( strcmp( regStr, devType->reg[regIdx].name ) == 0 )
220
        {
221
            *outRegp = &devType->reg[regIdx];
222
            return true;
223
        }
224
    }
225
 
226
    LogError( "Unrecognized register name: '%s'\n", regStr );
227
    return false;
228
}
229
 
230
//***************************************************************************
231
/**
232
*   Parses the error code and prints the results.
233
*/
234
void BioloidCommandLine::AddErrorStr( Bioloid::Error err, Bioloid::Error mask, char *str, size_t maxLen, const char *errStr )
235
{
236
    if (( err & mask ) != 0 )
237
    {
238
        if ( str[0] != '\0' )
239
        {
240
            StrMaxCat( str, ",", maxLen );
241
        }
242
        StrMaxCat( str, errStr, maxLen );
243
    }
244
}
245
 
246
//***************************************************************************
247
/**
248
*   Prints the error code and prints the results.
249
*/
250
bool BioloidCommandLine::PrintError( Bioloid::Error err )
251
{
252
    char   *str = (char *)&gErrorBuf[0];
253
 
254
    str[0] = '\0';
255
 
256
    if ( err == Bioloid::ERROR_NONE )
257
    {
258
        return false;
259
    }
260
 
261
    if ( err > 0xff )
262
    {
232 dhylands 263
        const char *errStr;
230 dhylands 264
 
265
        switch ( err )
266
        {
267
            case Bioloid::ERROR_NOT_DONE:       errStr = "Not Done";        break;
268
            case Bioloid::ERROR_TIMEOUT:        errStr = "Timeout";         break;
269
            case Bioloid::ERROR_TOO_MUCH_DATA:  errStr = "Too Much Data";   break;
270
            default:                            errStr = "***Unknown***";   break;
271
        }
272
 
273
        StrMaxCpy( str, errStr, sizeof( gErrorBuf ));
274
    }
275
    else
276
    {
277
        AddErrorStr( err, Bioloid::ERROR_RESERVED,       str, sizeof( gErrorBuf ), "Reserved" );
278
        AddErrorStr( err, Bioloid::ERROR_INSTRUCTION,    str, sizeof( gErrorBuf ), "Instruction" );
279
        AddErrorStr( err, Bioloid::ERROR_OVERLOAD,       str, sizeof( gErrorBuf ), "Overload" );
280
        AddErrorStr( err, Bioloid::ERROR_CHECKSUM,       str, sizeof( gErrorBuf ), "Checksum" );
281
        AddErrorStr( err, Bioloid::ERROR_RANGE,          str, sizeof( gErrorBuf ), "Range" );
282
        AddErrorStr( err, Bioloid::ERROR_OVERHEATING,    str, sizeof( gErrorBuf ), "Over Heating" );
283
        AddErrorStr( err, Bioloid::ERROR_ANGLE_LIMIT,    str, sizeof( gErrorBuf ), "Angle Limit" );
284
        AddErrorStr( err, Bioloid::ERROR_INPUT_VOLTAGE,  str, sizeof( gErrorBuf ), "Input Voltage" );
285
    }
286
    Log( "%s\n", str );
287
 
288
    return true;
289
}
290
 
291
//***************************************************************************
292
/**
293
*   Called from the Scan command when a device is found.
294
*/
295
static bool DevFound( BioloidBus *bus, BioloidDevice *dev )
296
{
297
    uint16_t    model;
298
    uint8_t     version;
299
 
300
    dev->Read( 0, &model );
301
    dev->Read( 2, &version );
302
 
303
    Log( "ID: %3d Model: %5u Version: %5u\n", dev->ID(), model, version );
304
 
305
    return true;
306
}
307
 
308
//***************************************************************************
309
/**
310
*   Called to process the get and get-raw commands
311
*/
312
 
253 dhylands 313
void BioloidCommandLine::ProcessDeviceGetCommand( BLD_DevType_t  *devType, Bioloid::ID_t id, StrTokenizer &line, bool raw )
230 dhylands 314
{
315
    BLD_Reg_t  *reg;
316
    char        str[ 40 ];
317
    unsigned    val;
318
    int         strWidth;
319
    int         i;
240 dhylands 320
    unsigned    regIdx;
230 dhylands 321
 
322
    if ( id == Bioloid::BROADCAST_ID )
323
    {
324
        LogError( "Broadcast ID not valid with get command\n" );
325
        return;
326
    }
327
 
328
    if ( strncmp( line.Remainder(), "all", 3 ) == 0 )
329
    {
330
        uint8_t numBytes;
331
 
332
        reg = devType->reg;
333
 
334
        numBytes = devType->numRegBytes;
335
        if ( numBytes > sizeof( gReadBuf ))
336
        {
337
            LogError( "gReadBuf is only %d bytes, numRegBytes is %d\n",
338
                      sizeof( gReadBuf ), devType->numRegBytes );
339
            return;
340
        }
341
 
342
        if ( PrintError( m_device.Read( 0, gReadBuf, numBytes )))
343
        {
344
            return;
345
        }
346
 
347
        if ( raw )
348
        {
349
            strWidth = 5;
350
        }
351
        else
352
        {
353
            strWidth = 15;
354
        }
355
        for ( i = 0; i < strWidth; i++ )
356
        {
357
            str[i] = '-';
358
        }
359
        str[i] = '\0';
360
 
361
        Log( "Addr Size %-*s Name\n", strWidth, "Value" );
362
        Log( "---- ---- %s --------------------\n", str );
363
 
364
        for ( regIdx = 0; regIdx < devType->numRegs; regIdx++ )
365
        {
366
            reg = &devType->reg[ regIdx ];
367
 
368
            if ( reg->flags & BLD_REG_FLAG_16BIT )
369
            {
320 dhylands 370
                val =  (uint16_t)gReadBuf[ reg->address ]
371
                    | ((uint16_t)gReadBuf[ reg->address ] << 8 );
230 dhylands 372
            }
373
            else
374
            {
375
                val = gReadBuf[ reg->address ];
376
            }
377
 
378
            if ( raw )
379
            {
380
                snprintf( str, sizeof( str ), "%5u", val );
381
                strWidth = 5;
382
            }
383
            else
384
            if ( reg->fmtFunc == NULL )
385
            {
386
                snprintf( str, sizeof( str ), "%u", val );
387
            }
388
            else
389
            {
390
                reg->fmtFunc( reg, val, str, sizeof( str ));
391
            }
392
 
393
            Log( "0x%02x %s %d %-*s %s\n",
394
                reg->address,
395
                reg->flags & BLD_REG_FLAG_WR ? "rw" : "ro",
396
                reg->flags & BLD_REG_FLAG_16BIT ? 2 : 1,
397
                strWidth, str,
398
                reg->name );
399
 
400
            reg++;
401
        }
402
    }
403
    else
404
    {
405
        if ( !ParseRegisterName( line, devType, &reg ))
406
        {
407
            return;
408
        }
409
 
410
        if (( reg->flags & BLD_REG_FLAG_16BIT ) != 0 )
411
        {
412
            uint16_t    val16;
413
 
414
            if ( PrintError( m_device.Read( reg->address, &val16, sizeof( val16 ))))
415
            {
416
                return;
417
            }
418
 
419
            val = val16;
420
        }
421
        else
422
        {
423
            uint8_t    val8;
424
 
425
            if (PrintError( m_device.Read( reg->address, &val8, sizeof( val8 ))))
426
            {
427
                return;
428
            }
429
 
430
            val = val8;
431
        }
432
 
433
        if (( reg->fmtFunc == NULL ) || raw )
434
        {
435
            snprintf( str, sizeof( str ), "%5u", val );
436
        }
437
        else
438
        {
439
            reg->fmtFunc( reg, val, str, sizeof( str ));
440
        }
441
 
442
        Log( "Read: %s\n", str );
443
    }
444
}
445
 
446
//***************************************************************************
447
/**
448
*   Called to process the set and set-raw commands
449
*/
450
 
253 dhylands 451
void BioloidCommandLine::ProcessDeviceSetCommand( BLD_DevType_t  *devType, Bioloid::ID_t id, StrTokenizer &line, bool raw )
230 dhylands 452
{
453
    BLD_Reg_t  *reg;
454
    uint16_t    val16;
455
 
456
    if ( !ParseRegisterName( line, devType, &reg ))
457
    {
458
        return;
459
    }
460
    if (( reg->flags & BLD_REG_FLAG_WR ) == 0 )
461
    {
462
        LogError( "Register %s is read-only\n", reg->name );
463
        return;
464
    }
465
 
466
    if ( raw || ( reg->parseFunc == NULL ))
467
    {
468
        if ( !line.NextNum( &val16 ))
469
        {
470
            LogError( "Invalid value specified: '%s'\n", line.PrevToken() );
471
            return;
472
        }
473
 
474
        if (( val16 < reg->minVal  ) || ( val16 > reg->maxVal ))
475
        {
476
            LogError( "Value %u is out of range (%u - %u)\n", val16, reg->minVal, reg->maxVal );
477
            return;
478
        }
479
    }
480
    else
481
    {
482
        if ( !reg->parseFunc( reg, line, &val16 ))
483
        {
484
            return;
485
        }
486
    }
487
 
488
    PrintError( m_device.Write( reg->address, &val16, reg->flags & BLD_REG_FLAG_16BIT ? 2 : 1 ));
489
}
490
 
491
//***************************************************************************
492
/**
253 dhylands 493
*   Processes the global get command.
494
*/
495
 
496
void ProcessGlobalGetCommand( StrTokenizer &line )
497
{
498
    (void)line;
499
}
500
 
501
//***************************************************************************
502
/**
503
*   Processes the global set command.
504
*/
505
 
506
void ProcessGlobalSetCommand( StrTokenizer &line )
507
{
508
    (void)line;
509
}
510
 
511
//***************************************************************************
512
/**
230 dhylands 513
*   Processes one line of data
514
*/
515
 
516
bool BioloidCommandLine::ProcessLine( char *lineStr )
517
{
518
    char           *devTypeStr;
519
    BLD_DevType_t  *devType;
520
    char            token[ 20 ];
521
    StrTokenizer    line( lineStr, token, sizeof( token ));
240 dhylands 522
    unsigned        devTypeIdx;
230 dhylands 523
 
524
    if ( m_bus == NULL )
525
    {
526
        LogError( "SetBus not called\n" );
527
        return false;
528
    }
529
 
530
    // Pull out the device type
531
 
532
    if (( devTypeStr = line.NextToken( gDelim )) == NULL )
533
    {
534
        // Empty line - ignore
535
 
536
        return true;
537
    }
538
 
539
    // Check for special non-device type commands
540
 
541
    if ( strcmp( devTypeStr, "action" ) == 0 )
542
    {
543
        m_bus->SendAction();
544
 
545
        // The action command is sent as a broadcast, so no response
546
        // is expected.
547
 
548
        return true;
549
    }
550
    if ( strcmp( devTypeStr, "scan" ) == 0 )
551
    {
552
        uint8_t numIds;
553
 
554
        if ( !line.NextNum( &numIds ))
555
        {
556
            numIds = 32;
557
        }
558
 
559
        if ( numIds < 100 )
560
        {
561
            bool    servoIdFound    = m_bus->Scan( DevFound, 0, numIds );
562
            bool    sensorIdFound   = m_bus->Scan( DevFound, 100, numIds );
563
 
564
            if ( !servoIdFound && !sensorIdFound )
565
            {
566
                Log( "No devices found\n" );
567
            }
568
        }
569
        else
570
        {
571
            if ( !m_bus->Scan( DevFound, 0 , numIds ))
572
            {
573
                Log( "No devices found\n" );
574
            }
575
        }
576
 
577
        return true;
578
    }
579
 
580
    if ( strcmp( devTypeStr, "dev-types" ) == 0 )
581
    {
582
        for ( devTypeIdx = 0; devTypeIdx < m_numDevTypes; devTypeIdx++ )
583
        {
240 dhylands 584
            devType = m_devType[devTypeIdx];
230 dhylands 585
 
586
            Log( "%-10s Model: %5u %2d registers\n",
587
                 devType->devTypeStr, devType->model, devType->numRegs );
588
        }
589
        return true;
590
    }
591
 
592
    if ( strcmp( devTypeStr, "quit" ) == 0 )
593
    {
594
        return false;
595
    }
596
 
597
    // Since it's not one of those - assume it's a device type
598
 
599
    devType = NULL;
600
    for ( devTypeIdx = 0; devTypeIdx < m_numDevTypes; devTypeIdx++ )
601
    {
602
        if ( strcmp( m_devType[ devTypeIdx ]->devTypeStr, devTypeStr ) == 0 )
603
        {
604
            devType = m_devType[ devTypeIdx ];
605
            break;
606
        }
607
    }
608
 
609
    if ( devTypeIdx >= m_numDevTypes )
610
    {
611
        LogError( "Unrecognized device type: '%s'\n", devTypeStr );
612
        return true;
613
    }
614
 
615
    Bioloid::ID_t id;
616
 
617
    if ( !line.NextNum( &id ))
618
    {
619
        if ( strcmp( line.PrevToken(), "reg" ) == 0 )
620
        {
621
            DumpRegInfo( devType );
622
            return true;
623
        }
624
        LogError( "Invalid ID: '%s'\n", line.PrevToken() );
625
        return true;
626
    }
627
    if ( id >= Bioloid::INVALID_ID )
628
    {
629
        LogError( "IDs must be 254 (0xFE) or less\n" );
630
        return true;
631
    }
632
    m_device.SetBusAndID( m_bus, id );
633
 
634
    char *cmdStr;
635
 
636
    if (( cmdStr = line.NextToken()) == NULL )
637
    {
638
        LogError( "No command specified for %s %u\n", devType->devTypeStr, id );
639
        return true;
640
    }
641
 
642
    LogVerbose( "DevType: %s ID: %d Cmd: %s\n", devType->devTypeStr, id, cmdStr );
643
 
644
    if ( strcmp( cmdStr, "ping" ) == 0 )
645
    {
646
        Bioloid::Error err;
647
 
648
        if ( id == Bioloid::BROADCAST_ID )
649
        {
650
            LogError( "Broadcast ID not valid with ping command\n" );
651
            return true;
652
        }
653
 
654
        if (( err = m_device.Ping()) == Bioloid::ERROR_NONE )
655
        {
656
            Log( "%s %d Response Received\n", devType->devTypeStr, id );
657
        }
658
        else
659
        {
660
            Log( "%s %d ", devType->devTypeStr, id );
661
            PrintError( err );
662
        }
663
    }
664
    else
665
    if (( strcmp( cmdStr, "read-data" ) == 0 )
666
    ||  ( strcmp( cmdStr, "rd" ) == 0 ))
667
    {
668
        uint8_t offset;
669
        uint8_t numBytes;
670
 
671
        if ( id == Bioloid::BROADCAST_ID )
672
        {
673
            LogError( "Broadcast ID not valid with read-data command\n" );
674
            return true;
675
        }
676
 
677
        if ( !line.NextNum( &offset ))
678
        {
679
            LogError( "Invalid offset specified: '%s'\n", line.PrevToken() );
680
            return true;
681
        }
682
        if ( !line.NextNum( &numBytes ))
683
        {
684
            LogError( "Invalid numBytes specified: '%s'\n", line.PrevToken() );
685
            return true;
686
        }
687
        if ( numBytes > sizeof( gReadBuf ))
688
        {
689
            LogError( "Only able to a maximum of %d bytes\n", sizeof( gReadBuf ));
690
            return true;
691
        }
692
 
693
        if ( PrintError( m_device.Read( offset, gReadBuf, numBytes )))
694
        {
695
            return true;
696
        }
697
 
698
        DumpMem( "Read", offset, gReadBuf, numBytes );
699
    }
700
    else
701
    if (( strcmp( cmdStr, "write-data" ) == 0 )
702
    ||  ( strcmp( cmdStr, "wd" ) == 0 ))
703
    {
704
        uint8_t offset;
705
        uint8_t numBytes;
706
        uint8_t data[ 20 ];
707
 
708
        if ( !ParseOffsetAndData( line, &offset, &numBytes, data, sizeof( data )))
709
        {
710
            return true;
711
        }
712
        PrintError( m_device.Write( offset, data, numBytes ));
713
    }
714
    else
715
    if (( strcmp( cmdStr, "reg-write" ) == 0 )
716
    ||  ( strcmp( cmdStr, "rw" ) == 0 ))
717
    {
718
        uint8_t offset;
719
        uint8_t numBytes;
720
        uint8_t data[ 20 ];
721
 
722
        if ( !ParseOffsetAndData( line, &offset, &numBytes, data, sizeof( data )))
723
        {
724
            return true;
725
        }
726
        m_device.SendDeferredWrite( offset, data, numBytes );
727
    }
728
    else
729
    if ( strcmp( cmdStr, "get" ) == 0 )
730
    {
253 dhylands 731
        ProcessDeviceGetCommand( devType, id, line, false );
230 dhylands 732
    }
733
    else
734
    if ( strcmp( cmdStr, "get-raw" ) == 0 )
735
    {
253 dhylands 736
        ProcessDeviceGetCommand( devType, id, line, true );
230 dhylands 737
    }
738
    else
739
    if ( strcmp( cmdStr, "set" ) == 0 )
740
    {
253 dhylands 741
        ProcessDeviceSetCommand( devType, id, line, false );
230 dhylands 742
    }
743
    else
744
    if ( strcmp( cmdStr, "set-raw" ) == 0 )
745
    {
253 dhylands 746
        ProcessDeviceSetCommand( devType, id, line, true );
230 dhylands 747
    }
748
    else
749
    if ( strcmp( cmdStr, "reset" ) == 0 )
750
    {
751
        m_device.Reset();
752
    }
753
    else
754
    {
755
        LogError( "Unrecognized command: '%s'\n", cmdStr );
756
    }
757
 
758
    return true;
759
}
760
 
761
//***************************************************************************
762
/**
763
*   Register the devices that we'll recognize
764
*/
765
 
766
void BioloidCommandLine::RegisterDeviceTypes( unsigned numDevTypes, BLD_DevType_t **devType )
767
{
768
    m_numDevTypes = numDevTypes;
769
    m_devType = devType;
770
}
771