next up previous
Next: A.11 vc-do.setl Up: A. WEBeye Source Code Previous: A.9 vc-cron.setl

  
A.10 vc-decode.setl

Textually #included by:
vc-do.setl     (Section A.11 [vc-do.setl])
vc-event.setl     (Section A.12 [vc-event.setl])
vc-model.setl     (Section A.27 [vc-model.setl])
vc-ptz.setl     (Section A.33 [vc-ptz.setl])

Source code: *

-- Operator to decode a low-level message from the Canon
 
op decode (frame);
 
  const camera_head = 1,
         pan_tilter = 5,
                ccu = 8;
 
  r := {};
 
  if not is_string frame or #frame = 0 then
    r.kind := `erroneous';
    r.frame := frame;
    r.detail := if is_string frame then
                  `Zero-length frame'
                else
                  if frame = om then `Frame is OM'
                  else `Frame is of type ' + type frame
                  end
                end if;
    return r;
  end if;
 
  if #frame = 1 then  -- one of my specials
    r.kind := `special';
    r.frame := frame;
    case frame(1) of
    (`*'):  r.detail := `Inter-character timeout';
    (`@'):  r.detail := `Ack timeout in multiple command sequence';
    (`+'):  r.detail := `Checksum error';
    (`!'):  r.detail := `Timeout waiting for ack/nak or response';
    end case;
    return r;
  end if;
 
  r.frame := hex frame;
 
  fid := abs frame(1);  -- Frame ID
 
  device := fid bit_and 16#0f;
 
  case device of
  (camera_head):  r.device := `Camera Head';
  (pan_tilter):   r.device := `Pan/Tilter';
  (ccu):          r.device := `CCU';
  else            r.device := `unknown device (0x'+hex char device+`)';
  end case;
 
  if (fid bit_and 16#80) = 0 then
    -- command frame
    cid := abs frame(2);  -- Command ID
    cmd := cid bit_and 16#1f;  -- Command Type bits
    r.cmd := `unknown (0x'+hex char cmd+`)';  -- default
    if (cid bit_and 16#80) = 0 then
      -- Host -> Canon message
      r.kind := `request';
      case device of
      (camera_head):
        case cmd of
        (16#04):  r.cmd := `Status';
        (16#10):  r.cmd := `Focus';
        (16#12):  r.cmd := `Zoom';
        (16#14):  r.cmd := `Exposure';
        end case;
      (pan_tilter):
        case cmd of
        (16#04):  r.cmd := `Status';
        (16#10):  r.cmd := `Set-up';
        (16#11):  r.cmd := `Home position';
        (16#12):  r.cmd := `Pan/tilt';
        (16#17):  r.cmd := `Remote controller';
        (16#19):  r.cmd := `LED';
        end case;
      (ccu):
        case cmd of
        (16#01):  r.cmd := `Software reset';
        (16#04):  r.cmd := `Status';
        (16#10):  r.cmd := `White balance';
        (16#11):  r.cmd := `Fade';
        (16#12):  r.cmd := `Mute';
        (16#17):  r.cmd := `Control mode select';
        (16#18):  r.cmd := `Preset';
        end case;
      end case;
    else
      -- Canon -> Host message
      if (cid bit_and 16#20) = 0 then
        -- Response
        if (cid bit_and 16#40) = 0 then
          r.kind := `positive response';
        else
          r.kind := `negative response';
        end if;
        case device of
        (camera_head):
          case cmd of
          (16#04):  r.cmd := `Status';
          (16#10):  r.cmd := `Focus';
          (16#12):  r.cmd := `Zoom';
          (16#14):  r.cmd := `Exposure';
          end case;
        (pan_tilter):
          case cmd of
          (16#04):  r.cmd := `Status';
          (16#10):  r.cmd := `Set-up';
          (16#11):  r.cmd := `Home position';
          (16#12):  r.cmd := `Pan/tilt';
          (16#17):  r.cmd := `Remote controller';
          (16#19):  r.cmd := `LED';
          end case;
        (ccu):
          case cmd of
          (16#01):  r.cmd := `Software reset';
          (16#04):  r.cmd := `Status';
          (16#10):  r.cmd := `White balance';
          (16#11):  r.cmd := `Fade';
          (16#12):  r.cmd := `Mute';
          (16#17):  r.cmd := `Control mode select';
          (16#18):  r.cmd := `Preset';
          end case;
        end case;
      else
        -- Notification
        r.kind := `notification';
        case device of
        (camera_head):
          case cmd of
          (16#03):  r.cmd := `Error';
          (16#11):  r.cmd := `Focus limit';
          (16#13):  r.cmd := `Zoom limit';
          (16#18):  r.cmd := `Button operation';
          end case;
        (pan_tilter):
          case cmd of
          (16#03):  r.cmd := `Error';
          (16#16):  r.cmd := `Limit';
          (16#18):  r.cmd := `Remote controller';
          (16#1b):  r.cmd := `Power';
          end case;
        (ccu):
          case cmd of
          (16#03):  r.cmd := `Error';
          end case;
        end case;
        if r.cmd = `Errorthen
          if #frame >= 3 then
            error_type := abs frame(3);
            if #frame >= 4 then
              error_cause := abs frame(4);
            else
              error_cause := om;
            end if;
            [r.error_type,
             r.error_cause] := decode_error (error_type,
                                             error_cause);
          end if;
        end if r.cmd;
      end if (cid bit_and 16#20);  -- response vs notification
    end if (cid bit_and 16#80);  -- ``command'' direction
 
  else
    -- ack/nak frame
    ack_nak_id := abs frame(2);
    if ack_nak_id = 0 then
      r.kind := `ack';
      r.detail := `Received';
    else
      r.kind := `nak';
      r.detail := decode_nak_cause (ack_nak_id);
    end if;
 
  end if (fid bit_and 16#80);  -- ``command'' vs ack/nak
 
  return r;
 
end op decode;
 
proc decode_error (error_typeerror_cause);
  r_error_type := decode_error_type (error_type);
  r_error_cause := om;
  if error_cause /= om then
    case error_type of
    (16#01):  -- Camera communication error
      -- The ``cause'' here is the raw UART(?) status byte
      r_error_cause := `Status register 0x' + hex char error_cause;
    (16#03, 16#04):  -- Pan/tilter or RS-232C comm. error
      r_error_cause := decode_comm_error_cause (error_cause);
      if error_cause = 16#00 and #frame >= 5 then  -- NAK
        r_error_cause +:= ` ('+decode_nak_cause (abs frame(5))+`)';
      end if;
    end case;
  end if;
  return [r_error_typer_error_cause];
end proc;
 
proc decode_error_type (error_type);
  return case error_type of
  (16#00):  `Camera cable is disconnected',
  (16#01):  `Camera communication error',
  (16#03):  `Pan/tilter communication error',
  (16#04):  `RS-232C communication error',
  (16#10):  `Command for unconnected device',
  (16#11):  `Undefined command',
  (16#12):  `Undefined parameter',
  (16#13):  `Status error (received command)',
  (16#14):  `Status error (received parameter)',
  (16#16):  `Timeout',
  (16#18):  `White balance correction error',
  (16#19):  `Pan/tilt, zoom, focus limit'
  else      `unknown error type (0x' + hex char error_type + `)'
  end case;
end proc;
 
proc decode_comm_error_cause (cause);
  return case cause of
  (16#00):  `NAK received',
  (16#01):  `ACK receive timeout',
  (16#02):  `Checksum error',
  (16#03):  `Pan/tilter is busy',
  (16#04):  `Fatal error',
  (16#05):  `Sequence error',
  (16#06):  `Length error',
  (16#07):  `Buffer is busy'
  else      `unknown comm. error cause code (0x' + hex char cause + `)'
  end case;
end proc;
 
proc decode_nak_cause (cause);
  return case cause of
  (16#01):  `Buffer busy',
  (16#02):  `Length error',
  (16#03):  `Sequence error',
  (16#04):  `Communication error',
  (16#10):  `Checksum error'
  else      `unknown NAK cause code (0x' + hex char cause + `)'
  end case;
end proc;


next up previous
Next: A.11 vc-do.setl Up: A. WEBeye Source Code Previous: A.9 vc-cron.setl
David Bacon
1999-12-10