[mythtv] Motorola DCT channel changes...

Tim Trampedach tim.trampedach at gmail.com
Wed Feb 1 05:46:30 UTC 2006

I found out a few interesting things on this and came up with a revamped
version of the 6200ch utility. Take a look at this web page:
http://mac_hdtv_timer.home.comcast.net/channel.html. It uses a 72-bit string
to send the command to the device in a single shot. MythTV and the utility
currently use three separate transactions with 32-bit commands to send
digits one at a time. After some digging in the code I noticed that the
Scientific Atlanta box also uses 72-bit string, except it needs it twice (a
"change" and then a "commit" if you will). So I revamped the 6200ch utility
to use the string format from that web page and it works flawlessly for me
now. No waiting with sleep, no missed channel changes and it's much quicker
than one digit at a time.

It really works well, but your mileage may vary. Therefore, if you have a
6200-series box, please compile code below and let me know how it goes. One
or two minor items of cleanup could happen in there, but I'm on my way to
sleep. Tomorrow! :-)

The actual change is quite simple as it actually makes the code less
complicated. I need some feedback on this before I'll open a ticket and
submit the patch.



 * 6200ch - an external channel changer for Motorola DCT-6200 Tuner
 * Copyright 2004,2005 by Stacey D. Son <mythdev at son.org>
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * GNU General Public License for more details.
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

#include <libavc1394/rom1394.h>
#include <libavc1394/avc1394.h>
#include <libraw1394/raw1394.h>
#include <sys/types.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h> // for usleep

// Motorola DCT-6200 IDs
// Note: there are at least three different vendor IDs for the 6200
#define DCT6200_VENDOR_ID1 0x00000ce5
#define DCT6200_VENDOR_ID2 0x00000e5c
#define DCT6200_VENDOR_ID3 0x00001225
#define DCT6200_VENDOR_ID4 0x00000f9f
#define DCT6200_VENDOR_ID5 0x00001180
#define DCT6200_VENDOR_ID6 0x000012c9
#define DCT6200_VENDOR_ID7 0x000011ae
#define DCT6200_VENDOR_ID8 0x0000152f
#define DCT6200_VENDOR_ID9 0x000014e8
#define DCT6200_SPEC_ID    0x00005068
#define DCT6200_SW_VERSION 0x00010101
#define DCT6200_MODEL_ID1  0x0000620a
#define DCT6200_MODEL_ID2  0x00006200
#define DCT6412_VENDOR_ID1 0x00000f9f
#define DCT6412_MODEL_ID1  0x000064ca

#define AVC1394_SUBUNIT_TYPE_6200 (9 << 19)  /* uses a reserved subunit type

#define AVC1394_6200_COMMAND_CHANNEL 0x000007C00   /* 6200 subunit command
#define AVC1394_6200_OPERAND_SET 0x20      /* 6200 subunit command operand

#define CTL_CMD0 AVC1394_CTYPE_CONTROL | AVC1394_SUBUNIT_TYPE_6200 | \
        AVC1394_SUBUNIT_ID_0 | AVC1394_6200_COMMAND_CHANNEL | \

#define STARTING_NODE 1  /* skip 1394 nodes to avoid error msgs */

void usage()
   fprintf(stderr, "Usage: 6200ch [-v] [-n NODE] <channel_num>\n");
   fprintf(stderr, "-v        Print additional verbose output\n");
   fprintf(stderr, "-n NODE   node to start device scanning on\n");

int main (int argc, char *argv[])
   rom1394_directory dir;
   int device = -1;
   int i;
   int verbose = 0;
   quadlet_t cmd[3];
   int dig[3];
   int chn = 550;

   /* some people experience crashes when starting on node 1 */
   int starting_node = STARTING_NODE;
   int c;
   int index;

   if (argc < 2)

   opterr = 0;
   while ((c = getopt(argc, argv, "vn:")) != -1) {
       switch (c) {
       case 'v':
           verbose = 1;
       case 'n':
           starting_node = atoi(optarg);
           fprintf(stderr, "incorrect command line arguments\n");

   /* print out usage message if not enough arguments */
   if (optind != argc-1) {
   /* the last argument is the channel number */
   chn = atoi(argv[optind]);

#ifdef RAW1394_V_0_8
   raw1394handle_t handle = raw1394_get_handle();
   raw1394handle_t handle = raw1394_new_handle();

   if (!handle) {
      if (!errno) {
         fprintf(stderr, "Not Compatable!\n");
      } else {
         perror("Couldn't get 1394 handle");
         fprintf(stderr, "Is ieee1394, driver, and raw1394 loaded?\n");

   if (raw1394_set_port(handle, 0) < 0) {
      perror("couldn't set port");

   if (verbose)
       printf("starting with node: %d\n", starting_node);

   int nc = raw1394_get_nodecount(handle);
   for (i=starting_node; i < nc; ++i) {
      if (rom1394_get_directory(handle, i, &dir) < 0) {
         fprintf(stderr,"error reading config rom directory for node %d\n",

      if (verbose)
         printf("node %d: vendor_id = 0x%08x model_id = 0x%08x\n",
                 i, dir.vendor_id, dir.model_id);

      if ( ((dir.vendor_id == DCT6200_VENDOR_ID1) ||
            (dir.vendor_id == DCT6200_VENDOR_ID2) ||
            (dir.vendor_id == DCT6200_VENDOR_ID3) ||
            (dir.vendor_id == DCT6200_VENDOR_ID4) ||
            (dir.vendor_id == DCT6200_VENDOR_ID5) ||
            (dir.vendor_id == DCT6200_VENDOR_ID6) ||
            (dir.vendor_id == DCT6200_VENDOR_ID7) ||
            (dir.vendor_id == DCT6200_VENDOR_ID8) ||
            (dir.vendor_id == DCT6200_VENDOR_ID9) ||
            (dir.vendor_id == DCT6412_VENDOR_ID1)) &&
           ((dir.model_id == DCT6200_MODEL_ID1) ||
            (dir.model_id == DCT6200_MODEL_ID2) ||
            (dir.model_id == DCT6412_MODEL_ID1)) ) {
            if (dir.unit_spec_id != DCT6200_SPEC_ID)
               fprintf(stderr, "Warning: Unit Spec ID different.\n");
            if (dir.unit_sw_version != DCT6200_SW_VERSION)
               fprintf(stderr, "Warning: Unit Software Version
            device = i;

   if (device == -1) {
        fprintf(stderr, "Could not find Motorola DCT-6200 on the 1394

   cmd[0] = CTL_CMD0 | 0x67;
   cmd[1] = (0x04 << 24) | (chn << 8) | 0x000000FF;
   cmd[2] = 0xFF << 24;

   if (verbose)
     printf("AV/C command for channel %d = 0x%08X %08X %08X\n",
        chn, cmd[0], cmd[1], cmd[2]);

   avc1394_transaction_block(handle, device, cmd, 3, 1);


On 1/31/06, Steven Adeff <adeffs.mythtv at gmail.com> wrote:
> I talked to a fellow that wrote windows software for interacting with the
> Motorola DCT via firewire. I asked him what his method is for changing
> channels to see if its any different than what 6200ch.c and mythtv are
> doing, here's his response:
> "Sorry for the delay replying, I haven't done much with firewire are a
> couple of months due to being busy at work. I did see similar issues, what
> seemed to fix the problem was this
> 1. I use a delay of 50ms between sending digits
> 2. When I do the 50ms delay, I time the actual delay (using
> QueryPerformanceCounter). If the actual delay taken is > 500ms, then I
> resend all whole channel again.
> 3. I also send each digit twice, once with the down button command and
> once with the up button command. Each command has a 50ms delay delay
> 4. I also send the enter button after sending the channel digits and dont
> send leading zeros e.g. channel 10 would be 0x21, 0xa1, 0x20, 0xa0, 0x0d,
> 0x8d as the values in the command"
> I'm going to see if I can modify 6200ch.c myself, but don't know how far
> I'll make it. If any programmers here can help in anyway please chime in.
> thanks!
> --
> Steve
> _______________________________________________
> mythtv-dev mailing list
> mythtv-dev at mythtv.org
> http://mythtv.org/cgi-bin/mailman/listinfo/mythtv-dev
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mythtv.org/pipermail/mythtv-dev/attachments/20060201/a8ef333b/attachment.htm

More information about the mythtv-dev mailing list