/*! 
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Copyright(c) 2012 Apogee Imaging Systems, Inc. 
* \class AltaUsbIo 
* \brief class for managing the AltaU series IO 
* 
*/ 

#include "AltaUsbIo.h" 
#include "apgHelper.h" 
#include "IUsb.h"
#include "PromFx2Io.h" 
#include "ApnUsbSys.h"
#include <sstream>
#include <cstring>  //for memset


namespace
{
    const uint32_t ALTA_U_MAX_BUFFER_SIZE = 0x1F000;
    const uint32_t ALTA_EEPROM_MAX_BANKS = 2;
    const uint32_t ALTA_EEPROM_MAX_BLOCKS = 6;
    const uint16_t ALTA_SN_EEPROM_ADDR = 0x0400;
    const uint8_t  ALTA_SN_EEPROM_BANK = 0;
    const uint8_t  ALTA_SN_EEPROM_BLOCK = 5;

    const uint16_t BUFCON_PROM_ADDR = 0;
    const uint8_t BUFCON_PROM_BLOCK  = 1;
    const uint8_t BUFCON_PROM_BANK = 0;

    const uint16_t CAMCON_PROM_ADDR = 0;
    const uint8_t CAMCON_PROM_BLOCK  = 0;
    const uint8_t CAMCON_PROM_BANK = 1;

    const uint16_t FX2_PROM_ADDR = 0;
    const uint8_t FX2_PROM_BLOCK = 0;
    const uint8_t FX2_PROM_BANK = 0;

    const uint16_t GPIF_WAVEFORM_BUFCON_PROM_ADDR = 0;
    const uint8_t GPIF_WAVEFORM_BUFCON_PROM_BLOCK = 5;
    const uint8_t GPIF_WAVEFORM_BUFCON_PROM_BANK = 0;

    const uint16_t GPIF_WAVEFORM_CAMCON_PROM_ADDR = GPIF_WAVEFORM_BUFCON_PROM_ADDR + 0x80;
    const uint8_t GPIF_WAVEFORM_CAMCON_PROM_BLOCK = 5;
    const uint8_t GPIF_WAVEFORM_CAMCON_PROM_BANK = 0;

    const uint16_t GPIF_WAVEFORM_FIFO_PROM_ADDR = GPIF_WAVEFORM_BUFCON_PROM_ADDR + 0x100;
    const uint8_t GPIF_WAVEFORM_FIFO_PROM_BLOCK = 5;
    const uint8_t GPIF_WAVEFORM_FIFO_PROM_BANK = 0;

    const uint16_t HEADER_PROM_ADDR = 0;
    const uint8_t HEADER_PROM_BLOCK  = 4;
    const uint8_t HEADER_PROM_BANK = 0;

    const uint8_t SERIAL_FLOW_MASK = 0x1;
    const uint8_t SERIAL_PARITY_ENA_MASK = 0x8;
    const uint8_t SERIAL_PARITY_ODD_MASK = 0x10;

    UsbFrmwr::INTEL_HEX_RECORD firmware[] = {
       13,
       0xeea,
       0,
       {0xef,0x24,0xff,0x92,0x07,0xa2,0x07,0xe4,0x33,0x90,0x13,0xc9,0xf0},
       1,
       0xef7,
       0,
       {0x22},
       16,
       0xbb7,
       0,
       {0xef,0x14,0x60,0x20,0x14,0x60,0x2d,0x14,0x60,0x39,0x14,0x60,0x47,0x14,0x60,0x53},
       16,
       0xbc7,
       0,
       {0x24,0x05,0x70,0x5d,0xe4,0x90,0x13,0xca,0xf0,0x90,0x14,0x0d,0x04,0xf0,0xe4,0x90},
       16,
       0xbd7,
       0,
       {0x13,0xc8,0xf0,0x22,0x90,0x13,0xca,0x74,0x01,0xf0,0x90,0x14,0x0d,0xf0,0xe4,0x90},
       16,
       0xbe7,
       0,
       {0x13,0xc8,0xf0,0x22,0xe4,0x90,0x13,0xca,0xf0,0x90,0x14,0x0d,0xf0,0x90,0x13,0xc8},
       16,
       0xbf7,
       0,
       {0x04,0xf0,0x22,0x90,0x13,0xca,0x74,0x01,0xf0,0xe4,0x90,0x14,0x0d,0xf0,0x90,0x13},
       16,
       0xc07,
       0,
       {0xc8,0x04,0xf0,0x22,0xe4,0x90,0x13,0xca,0xf0,0x90,0x14,0x0d,0x04,0xf0,0x90,0x13},
       16,
       0xc17,
       0,
       {0xc8,0xf0,0x22,0x90,0x13,0xca,0x74,0x01,0xf0,0x90,0x14,0x0d,0xf0,0x90,0x13,0xc8},
       2,
       0xc27,
       0,
       {0xf0,0x22},
       2,
       0xaca,
       0,
       {0xa9,0x05},
       16,
       0xacc,
       0,
       {0xad,0x07,0xac,0x06,0x75,0x19,0x50,0x90,0x13,0xc9,0xe0,0x60,0x03,0x43,0x19,0x04},
       16,
       0xadc,
       0,
       {0x90,0x13,0xc8,0xe0,0x60,0x03,0x43,0x19,0x02,0x90,0x14,0x0d,0xe0,0x60,0x03,0x43},
       16,
       0xaec,
       0,
       {0x19,0x01,0x53,0x04,0x7f,0x90,0x13,0xca,0xe0,0x60,0x03,0x43,0x04,0x80,0xec,0x90},
       16,
       0xafc,
       0,
       {0x13,0xcb,0xf0,0xed,0xa3,0xf0,0xe4,0xff,0xfe,0xe9,0xfd,0xc3,0xef,0x9d,0x74,0x80},
       16,
       0xb0c,
       0,
       {0xf8,0x6e,0x98,0x50,0x1e,0x8b,0x82,0x8a,0x83,0xe0,0xfd,0x74,0xcd,0x2f,0xf5,0x82},
       16,
       0xb1c,
       0,
       {0xe4,0x34,0x13,0xf5,0x83,0xed,0xf0,0x0f,0xbf,0x00,0x01,0x0e,0x0b,0xbb,0x00,0x01},
       16,
       0xb2c,
       0,
       {0x0a,0x80,0xd6,0xe9,0x24,0x02,0xfd,0x7a,0x13,0x7b,0xcb,0xaf,0x19,0x12,0x0e,0x3c},
       5,
       0xb3c,
       0,
       {0xaf,0x19,0x02,0x0d,0x0e},
       6,
       0xa48,
       0,
       {0x8d,0x19,0x8a,0x1a,0x8b,0x1b},
       16,
       0xa4e,
       0,
       {0xad,0x07,0xac,0x06,0x75,0x1c,0x50,0x90,0x13,0xc9,0xe0,0x60,0x03,0x43,0x1c,0x04},
       16,
       0xa5e,
       0,
       {0x90,0x13,0xc8,0xe0,0x60,0x03,0x43,0x1c,0x02,0x90,0x14,0x0d,0xe0,0x60,0x03,0x43},
       16,
       0xa6e,
       0,
       {0x1c,0x01,0x53,0x04,0x7f,0x90,0x13,0xca,0xe0,0x60,0x03,0x43,0x04,0x80,0xec,0x90},
       16,
       0xa7e,
       0,
       {0x13,0xcb,0xf0,0xed,0xa3,0xf0,0x7a,0x13,0x7b,0xcb,0x7d,0x02,0xaf,0x1c,0x12,0x0e},
       16,
       0xa8e,
       0,
       {0x3c,0x7a,0x13,0x7b,0xcb,0xad,0x19,0xaf,0x1c,0x12,0x0e,0x20,0xe4,0xff,0xfe,0xc3},
       16,
       0xa9e,
       0,
       {0xef,0x95,0x19,0x74,0x80,0xf8,0x6e,0x98,0x50,0x21,0x74,0xcb,0x2f,0xf5,0x82,0xe4},
       16,
       0xaae,
       0,
       {0x34,0x13,0xf5,0x83,0xe0,0x85,0x1b,0x82,0x85,0x1a,0x83,0xf0,0x0f,0xbf,0x00,0x01},
       11,
       0xabe,
       0,
       {0x0e,0x05,0x1b,0xe5,0x1b,0x70,0xd8,0x05,0x1a,0x80,0xd4},
       1,
       0xac9,
       0,
       {0x22},
       16,
       0xe02,
       0,
       {0x90,0xe6,0x00,0x74,0x10,0xf0,0xc2,0x00,0xe4,0x90,0xe6,0x70,0xf0,0x75,0x80,0x94},
       14,
       0xe12,
       0,
       {0x75,0xb2,0xd4,0x90,0xe6,0x72,0xf0,0x75,0xb1,0x10,0x75,0xb6,0x1f,0x22},
       10,
       0xf04,
       0,
       {0x90,0xe6,0x7a,0xe0,0x44,0x01,0xf0,0x02,0x0f,0x28},
       6,
       0xf30,
       0,
       {0x12,0x0e,0x02,0x02,0x0f,0x04},
       3,
       0xf3a,
       0,
       {0x02,0x0f,0x30},
       3,
       0xf3d,
       0,
       {0x02,0x0f,0x6c},
       2,
       0x7fe,
       0,
       {0xd3,0x22},
       2,
       0x8fe,
       0,
       {0xd3,0x22},
       2,
       0xf40,
       0,
       {0xd3,0x22},
       8,
       0xf18,
       0,
       {0x90,0xe6,0xba,0xe0,0xf5,0x1e,0xd3,0x22},
       16,
       0xeb4,
       0,
       {0x90,0xe7,0x40,0xe5,0x1e,0xf0,0xe4,0x90,0xe6,0x8a,0xf0,0x90,0xe6,0x8b,0x04,0xf0},
       2,
       0xec4,
       0,
       {0xd3,0x22},
       8,
       0xf20,
       0,
       {0x90,0xe6,0xba,0xe0,0xf5,0x1d,0xd3,0x22},
       16,
       0xec6,
       0,
       {0x90,0xe7,0x40,0xe5,0x1d,0xf0,0xe4,0x90,0xe6,0x8a,0xf0,0x90,0xe6,0x8b,0x04,0xf0},
       2,
       0xed6,
       0,
       {0xd3,0x22},
       2,
       0xf42,
       0,
       {0xd3,0x22},
       2,
       0xf44,
       0,
       {0xd3,0x22},
       2,
       0xf46,
       0,
       {0xd3,0x22},
       16,
       0xed8,
       0,
       {0xc2,0x04,0x90,0xe6,0xb8,0xe0,0x54,0x60,0xf5,0x09,0x12,0x0b,0x41,0x92,0x04,0xa2},
       1,
       0xee8,
       0,
       {0x04},
       1,
       0xee9,
       0,
       {0x22},
       16,
       0xe58,
       0,
       {0xc0,0xe0,0xc0,0x83,0xc0,0x82,0xd2,0x01,0x53,0x91,0xef,0x90,0xe6,0x5d,0x74,0x01},
       8,
       0xe68,
       0,
       {0xf0,0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32},
       16,
       0xe88,
       0,
       {0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x53,0x91,0xef,0x90,0xe6,0x5d,0x74,0x04,0xf0,0xd0},
       6,
       0xe98,
       0,
       {0x82,0xd0,0x83,0xd0,0xe0,0x32},
       16,
       0xe9e,
       0,
       {0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x53,0x91,0xef,0x90,0xe6,0x5d,0x74,0x02,0xf0,0xd0},
       6,
       0xeae,
       0,
       {0x82,0xd0,0x83,0xd0,0xe0,0x32},
       16,
       0xcd8,
       0,
       {0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x85,0x29,0x25,0x85,0x2a,0x26,0x85,0x26,0x82,0x85},
       16,
       0xce8,
       0,
       {0x25,0x83,0xa3,0x74,0x02,0xf0,0x85,0x21,0x27,0x85,0x22,0x28,0x85,0x28,0x82,0x85},
       16,
       0xcf8,
       0,
       {0x27,0x83,0xa3,0x74,0x07,0xf0,0x53,0x91,0xef,0x90,0xe6,0x5d,0x74,0x10,0xf0,0xd0},
       6,
       0xd08,
       0,
       {0x82,0xd0,0x83,0xd0,0xe0,0x32},
       16,
       0xe70,
       0,
       {0xc0,0xe0,0xc0,0x83,0xc0,0x82,0xd2,0x03,0x53,0x91,0xef,0x90,0xe6,0x5d,0x74,0x08},
       8,
       0xe80,
       0,
       {0xf0,0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32},
       16,
       0xc9b,
       0,
       {0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x90,0xe6,0x80,0xe0,0x30,0xe7,0x20,0x85,0x21,0x25},
       16,
       0xcab,
       0,
       {0x85,0x22,0x26,0x85,0x29,0x27,0x85,0x2a,0x28,0x85,0x26,0x82,0x85,0x25,0x83,0xa3},
       16,
       0xcbb,
       0,
       {0x74,0x07,0xf0,0x85,0x28,0x82,0x85,0x27,0x83,0xa3,0x74,0x02,0xf0,0x53,0x91,0xef},
       13,
       0xccb,
       0,
       {0x90,0xe6,0x5d,0x74,0x20,0xf0,0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32},
       1,
       0xf48,
       0,
       {0x32},
       1,
       0xf49,
       0,
       {0x32},
       1,
       0xf4a,
       0,
       {0x32},
       1,
       0xf4b,
       0,
       {0x32},
       1,
       0xf4c,
       0,
       {0x32},
       1,
       0xf4d,
       0,
       {0x32},
       1,
       0xf4e,
       0,
       {0x32},
       1,
       0xf4f,
       0,
       {0x32},
       1,
       0xf50,
       0,
       {0x32},
       1,
       0xf51,
       0,
       {0x32},
       1,
       0xf52,
       0,
       {0x32},
       1,
       0xf53,
       0,
       {0x32},
       1,
       0xf54,
       0,
       {0x32},
       1,
       0xf55,
       0,
       {0x32},
       1,
       0xf56,
       0,
       {0x32},
       1,
       0xf57,
       0,
       {0x32},
       1,
       0xf58,
       0,
       {0x32},
       1,
       0xf59,
       0,
       {0x32},
       1,
       0xf5a,
       0,
       {0x32},
       1,
       0xf5b,
       0,
       {0x32},
       1,
       0xf5c,
       0,
       {0x32},
       1,
       0xf5d,
       0,
       {0x32},
       1,
       0xf5e,
       0,
       {0x32},
       1,
       0xf5f,
       0,
       {0x32},
       1,
       0xf60,
       0,
       {0x32},
       1,
       0xf61,
       0,
       {0x32},
       1,
       0xf62,
       0,
       {0x32},
       1,
       0xf63,
       0,
       {0x32},
       1,
       0xf64,
       0,
       {0x32},
       1,
       0xf65,
       0,
       {0x32},
       1,
       0xf66,
       0,
       {0x32},
       1,
       0xf67,
       0,
       {0x32},
       1,
       0xf68,
       0,
       {0x32},
       1,
       0xf69,
       0,
       {0x32},
       1,
       0xf6a,
       0,
       {0x32},
       1,
       0xf6b,
       0,
       {0x32},
       1,
       0xf6c,
       0,
       {0x22},
       16,
       0x38c,
       0,
       {0xe4,0xf5,0x18,0x90,0x13,0x6a,0xe0,0xf5,0x0c,0xa3,0xe0,0xf5,0x0d,0xaf,0x0d,0xe5},
       16,
       0x39c,
       0,
       {0x0d,0x12,0x0b,0xb7,0xe5,0x0c,0xff,0x12,0x0e,0xea,0x53,0xb1,0xef,0x90,0x13,0x0a},
       16,
       0x3ac,
       0,
       {0xe0,0xfe,0xa3,0xe0,0xff,0xe4,0x8f,0x11,0x8e,0x10,0xf5,0x0f,0xf5,0x0e,0x90,0x13},
       16,
       0x3bc,
       0,
       {0x68,0xe0,0xf5,0x12,0xa3,0xe0,0xf5,0x13,0xaf,0x11,0xae,0x10,0xad,0x0f,0xac,0x0e},
       16,
       0x3cc,
       0,
       {0xec,0x4d,0x4e,0x4f,0x70,0x03,0x02,0x04,0xc2,0xe4,0x90,0xe6,0x8a,0xf0,0x90,0xe6},
       16,
       0x3dc,
       0,
       {0x8b,0xf0,0x00,0x00,0x00,0x90,0xe6,0xa0,0xe0,0x20,0xe1,0xf9,0x90,0xe6,0x8b,0xe0},
       16,
       0x3ec,
       0,
       {0x75,0x14,0x00,0xf5,0x15,0xe4,0xf5,0x16,0xf5,0x17,0xc3,0xe5,0x17,0x95,0x15,0xe5},
       16,
       0x3fc,
       0,
       {0x16,0x95,0x14,0x50,0x24,0xaf,0x17,0x74,0x40,0x2f,0xf5,0x82,0xe4,0x34,0xe7,0xf5},
       16,
       0x40c,
       0,
       {0x83,0xe0,0xfe,0x74,0x0c,0x2f,0xf5,0x82,0xe4,0x34,0x13,0xf5,0x83,0xee,0xf0,0x05},
       16,
       0x41c,
       0,
       {0x17,0xe5,0x17,0x70,0xd5,0x05,0x16,0x80,0xd1,0xe5,0x18,0xc3,0x94,0x03,0x50,0x5b},
       16,
       0x42c,
       0,
       {0xad,0x15,0x7a,0x13,0x7b,0x0c,0xaf,0x13,0xae,0x12,0x12,0x0a,0xca,0xad,0x15,0x7a},
       16,
       0x43c,
       0,
       {0x13,0x7b,0x6c,0xaf,0x13,0xae,0x12,0x12,0x0a,0x48,0xc2,0x06,0xe4,0xf5,0x16,0xf5},
       16,
       0x44c,
       0,
       {0x17,0xc3,0xe5,0x17,0x95,0x15,0xe5,0x16,0x95,0x14,0x50,0x28,0xaf,0x17,0x74,0x6c},
       16,
       0x45c,
       0,
       {0x2f,0xf5,0x82,0xe4,0x34,0x13,0xf5,0x83,0xe0,0xfe,0x74,0x0c,0x2f,0xf5,0x82,0xe4},
       16,
       0x46c,
       0,
       {0x34,0x13,0xf5,0x83,0xe0,0x6e,0x60,0x02,0xd2,0x06,0x05,0x17,0xe5,0x17,0x70,0xd1},
       16,
       0x47c,
       0,
       {0x05,0x16,0x80,0xcd,0x30,0x06,0x04,0x05,0x18,0x80,0x9e,0xe5,0x15,0x25,0x13,0xf5},
       16,
       0x48c,
       0,
       {0x13,0xe5,0x14,0x35,0x12,0xf5,0x12,0xae,0x14,0xaf,0x15,0xe4,0xfc,0xfd,0xaa,0x06},
       16,
       0x49c,
       0,
       {0xab,0x07,0xc3,0xe5,0x11,0x9b,0xf5,0x11,0xe5,0x10,0x9a,0xf5,0x10,0xe5,0x0f,0x94},
       16,
       0x4ac,
       0,
       {0x00,0xf5,0x0f,0xe5,0x0e,0x94,0x00,0xf5,0x0e,0x20,0x06,0x03,0x02,0x03,0xc4,0x90},
       9,
       0x4bc,
       0,
       {0xe6,0xa0,0xe0,0x44,0x01,0xf0,0x43,0xb1,0x10},
       1,
       0x4c5,
       0,
       {0x22},
       16,
       0x6f5,
       0,
       {0x90,0x13,0x0a,0xe0,0xfe,0xa3,0xe0,0xff,0xe4,0x8f,0x15,0x8e,0x14,0xf5,0x13,0xf5},
       16,
       0x705,
       0,
       {0x12,0x90,0x13,0x68,0xe0,0xf5,0x10,0xa3,0xe0,0xf5,0x11,0xa3,0xe0,0xf5,0x0c,0xa3},
       16,
       0x715,
       0,
       {0xe0,0xf5,0x0d,0xaf,0x0d,0xe5,0x0d,0x12,0x0b,0xb7,0xe5,0x0c,0xff,0x12,0x0e,0xea},
       16,
       0x725,
       0,
       {0xaf,0x15,0xae,0x14,0xad,0x13,0xac,0x12,0xec,0x4d,0x4e,0x4f,0x70,0x03,0x02,0x07},
       16,
       0x735,
       0,
       {0xd8,0xe4,0x7f,0x40,0xfe,0xfd,0xfc,0xab,0x15,0xaa,0x14,0xa9,0x13,0xa8,0x12,0xc3},
       16,
       0x745,
       0,
       {0x12,0x09,0xf9,0x50,0x06,0xae,0x14,0xaf,0x15,0x80,0x04,0x7e,0x00,0x7f,0x40,0x8e},
       16,
       0x755,
       0,
       {0x0e,0x8f,0x0f,0xad,0x0f,0x7a,0x13,0x7b,0x0c,0xaf,0x11,0xae,0x10,0x12,0x0a,0x48},
       16,
       0x765,
       0,
       {0xe4,0xff,0xfe,0xc3,0xef,0x95,0x0f,0xee,0x95,0x0e,0x50,0x1f,0x74,0x0c,0x2f,0xf5},
       16,
       0x775,
       0,
       {0x82,0xe4,0x34,0x13,0xf5,0x83,0xe0,0xfd,0x74,0x40,0x2f,0xf5,0x82,0xe4,0x34,0xe7},
       16,
       0x785,
       0,
       {0xf5,0x83,0xed,0xf0,0x0f,0xbf,0x00,0x01,0x0e,0x80,0xd8,0xe5,0x0f,0x25,0x11,0xf5},
       16,
       0x795,
       0,
       {0x11,0xe5,0x0e,0x35,0x10,0xf5,0x10,0xae,0x0e,0xaf,0x0f,0xe4,0xfc,0xfd,0xaa,0x06},
       16,
       0x7a5,
       0,
       {0xab,0x07,0xc3,0xe5,0x15,0x9b,0xf5,0x15,0xe5,0x14,0x9a,0xf5,0x14,0xe5,0x13,0x94},
       16,
       0x7b5,
       0,
       {0x00,0xf5,0x13,0xe5,0x12,0x94,0x00,0xf5,0x12,0xe5,0x0e,0x90,0xe6,0x8a,0xf0,0xef},
       16,
       0x7c5,
       0,
       {0x90,0xe6,0x8b,0xf0,0x00,0x00,0x00,0x90,0xe6,0xa0,0xe0,0x20,0xe1,0x03,0x02,0x07},
       3,
       0x7d5,
       0,
       {0x25,0x80,0xf4},
       1,
       0x7d8,
       0,
       {0x22},
       16,
       0xb41,
       0,
       {0xe4,0xf5,0x0a,0xf5,0x0b,0x90,0xe6,0xbf,0xe0,0xfe,0x90,0xe6,0xbe,0xe0,0x7c,0x00},
       16,
       0xb51,
       0,
       {0x24,0x00,0x90,0x13,0x0b,0xf0,0xec,0x3e,0x90,0x13,0x0a,0xf0,0x90,0xe6,0xbd,0xe0},
       16,
       0xb61,
       0,
       {0xfe,0x90,0xe6,0xbc,0xe0,0x24,0x00,0x90,0x13,0x69,0xf0,0xec,0x3e,0x90,0x13,0x68},
       16,
       0xb71,
       0,
       {0xf0,0x90,0xe6,0xbb,0xe0,0xfe,0x90,0xe6,0xba,0xe0,0x24,0x00,0x90,0x13,0x6b,0xf0},
       16,
       0xb81,
       0,
       {0xec,0x3e,0x90,0x13,0x6a,0xf0,0x90,0xe6,0xb8,0xe0,0x33,0x92,0x05,0xa3,0xe0,0xff},
       16,
       0xb91,
       0,
       {0x24,0x3a,0x70,0x0d,0x30,0x05,0x05,0x12,0x06,0xf5,0x80,0x0b,0x12,0x03,0x8c,0x80},
       16,
       0xba1,
       0,
       {0x06,0x74,0xff,0xf5,0x0a,0xf5,0x0b,0xae,0x0a,0xaf,0x0b,0xbe,0xff,0x06,0xbf,0xff},
       5,
       0xbb1,
       0,
       {0x03,0xd3,0x80,0x01,0xc3},
       1,
       0xbb6,
       0,
       {0x22},
       10,
       0xf0e,
       0,
       {0x00,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05},
       16,
       0x4c6,
       0,
       {0x7e,0x09,0x7f,0x00,0x8e,0x23,0x8f,0x24,0x75,0x2b,0x09,0x75,0x2c,0x12,0x75,0x21},
       16,
       0x4d6,
       0,
       {0x09,0x75,0x22,0x1c,0x75,0x29,0x09,0x75,0x2a,0x2e,0x75,0x2d,0x09,0x75,0x2e,0x40},
       16,
       0x4e6,
       0,
       {0xee,0x54,0xe0,0x70,0x03,0x02,0x05,0xb9,0x90,0x13,0x02,0x74,0x12,0xf0,0xa3,0x74},
       16,
       0x4f6,
       0,
       {0x02,0xf0,0xa3,0xee,0xf0,0xa3,0xef,0xf0,0xc3,0x74,0xa8,0x9f,0xff,0x74,0x09,0x9e},
       16,
       0x506,
       0,
       {0xcf,0x24,0x02,0xcf,0x34,0x00,0xfe,0xe4,0xfc,0xfd,0xa3,0x12,0x0a,0x16,0xe4,0xf5},
       16,
       0x516,
       0,
       {0x0b,0xf5,0x0a,0xf5,0x09,0xf5,0x08,0x90,0x13,0x06,0x12,0x0a,0x0a,0xab,0x0b,0xaa},
       16,
       0x526,
       0,
       {0x0a,0xa9,0x09,0xa8,0x08,0xc3,0x12,0x09,0xf9,0x50,0x3a,0xae,0x0a,0xaf,0x0b,0x90},
       16,
       0x536,
       0,
       {0x13,0x04,0xe0,0xfc,0xa3,0xe0,0x2f,0xf5,0x82,0xec,0x3e,0xf5,0x83,0xe4,0x93,0xfd},
       16,
       0x546,
       0,
       {0x90,0x13,0x02,0xe0,0xfa,0xa3,0xe0,0x2f,0xf5,0x82,0xea,0x3e,0xf5,0x83,0xed,0xf0},
       16,
       0x556,
       0,
       {0xef,0x24,0x01,0xf5,0x0b,0xe4,0x3e,0xf5,0x0a,0xe4,0x35,0x09,0xf5,0x09,0xe4,0x35},
       16,
       0x566,
       0,
       {0x08,0xf5,0x08,0x80,0xb2,0x90,0x13,0x02,0xe0,0xfe,0xa3,0xe0,0xff,0xc3,0x74,0x00},
       16,
       0x576,
       0,
       {0x9f,0xff,0x74,0x09,0x9e,0xfe,0x90,0x12,0x00,0xf0,0xa3,0xef,0xf0,0x90,0x13,0x02},
       16,
       0x586,
       0,
       {0xe0,0xf5,0x23,0xa3,0xe0,0xf5,0x24,0xc3,0xe5,0x2c,0x9f,0xf5,0x2c,0xe5,0x2b,0x9e},
       16,
       0x596,
       0,
       {0xf5,0x2b,0xc3,0xe5,0x22,0x9f,0xf5,0x22,0xe5,0x21,0x9e,0xf5,0x21,0xc3,0xe5,0x2a},
       16,
       0x5a6,
       0,
       {0x9f,0xf5,0x2a,0xe5,0x29,0x9e,0xf5,0x29,0xc3,0xe5,0x2e,0x9f,0xf5,0x2e,0xe5,0x2d},
       16,
       0x5b6,
       0,
       {0x9e,0xf5,0x2d,0x85,0x29,0x25,0x85,0x2a,0x26,0x85,0x21,0x27,0x85,0x22,0x28,0x90},
       16,
       0x5c6,
       0,
       {0xe6,0x80,0xe0,0x30,0xe7,0x0c,0x85,0x21,0x25,0x85,0x22,0x26,0x85,0x29,0x27,0x85},
       16,
       0x5d6,
       0,
       {0x2a,0x28,0x85,0x26,0x82,0x85,0x25,0x83,0xa3,0x74,0x02,0xf0,0x85,0x28,0x82,0x85},
       6,
       0x5e6,
       0,
       {0x27,0x83,0xa3,0x74,0x07,0xf0},
       1,
       0x5ec,
       0,
       {0x22},
       16,
       0x100,
       0,
       {0x90,0xe6,0xb8,0xe0,0x54,0x60,0xf5,0x08,0xa3,0xe0,0x12,0x0a,0x22,0x01,0xce,0x00},
       16,
       0x110,
       0,
       {0x02,0x77,0x01,0x03,0x0c,0x03,0x01,0x29,0x06,0x01,0xc8,0x08,0x01,0xc2,0x09,0x01},
       16,
       0x120,
       0,
       {0xb6,0x0a,0x01,0xbc,0x0b,0x00,0x00,0x03,0x78,0x12,0x0f,0x40,0x40,0x03,0x02,0x03},
       16,
       0x130,
       0,
       {0x84,0x90,0xe6,0xbb,0xe0,0x24,0xfe,0x60,0x2c,0x14,0x60,0x47,0x24,0xfd,0x60,0x16},
       16,
       0x140,
       0,
       {0x14,0x60,0x31,0x24,0x06,0x70,0x65,0xe5,0x23,0x90,0xe6,0xb3,0xf0,0xe5,0x24,0x90},
       16,
       0x150,
       0,
       {0xe6,0xb4,0xf0,0x02,0x03,0x84,0xe5,0x2b,0x90,0xe6,0xb3,0xf0,0xe5,0x2c,0x90,0xe6},
       16,
       0x160,
       0,
       {0xb4,0xf0,0x02,0x03,0x84,0xe5,0x25,0x90,0xe6,0xb3,0xf0,0xe5,0x26,0x90,0xe6,0xb4},
       16,
       0x170,
       0,
       {0xf0,0x02,0x03,0x84,0xe5,0x27,0x90,0xe6,0xb3,0xf0,0xe5,0x28,0x90,0xe6,0xb4,0xf0},
       16,
       0x180,
       0,
       {0x02,0x03,0x84,0x90,0xe6,0xba,0xe0,0xff,0x12,0x0d,0xd6,0xaa,0x06,0xa9,0x07,0x7b},
       16,
       0x190,
       0,
       {0x01,0xea,0x49,0x60,0x0d,0xee,0x90,0xe6,0xb3,0xf0,0xef,0x90,0xe6,0xb4,0xf0,0x02},
       16,
       0x1a0,
       0,
       {0x03,0x84,0x90,0xe6,0xa0,0xe0,0x44,0x01,0xf0,0x02,0x03,0x84,0x90,0xe6,0xa0,0xe0},
       16,
       0x1b0,
       0,
       {0x44,0x01,0xf0,0x02,0x03,0x84,0x12,0x0e,0xc6,0x02,0x03,0x84,0x12,0x0f,0x20,0x02},
       16,
       0x1c0,
       0,
       {0x03,0x84,0x12,0x0f,0x18,0x02,0x03,0x84,0x12,0x0e,0xb4,0x02,0x03,0x84,0x12,0x0f},
       16,
       0x1d0,
       0,
       {0x42,0x40,0x03,0x02,0x03,0x84,0x90,0xe6,0xb8,0xe0,0x24,0x7f,0x60,0x2b,0x14,0x60},
       16,
       0x1e0,
       0,
       {0x3c,0x24,0x02,0x60,0x03,0x02,0x02,0x6d,0xa2,0x00,0xe4,0x33,0xff,0x25,0xe0,0xff},
       16,
       0x1f0,
       0,
       {0xa2,0x02,0xe4,0x33,0x4f,0x90,0xe7,0x40,0xf0,0xe4,0xa3,0xf0,0x90,0xe6,0x8a,0xf0},
       16,
       0x200,
       0,
       {0x90,0xe6,0x8b,0x74,0x02,0xf0,0x02,0x03,0x84,0xe4,0x90,0xe7,0x40,0xf0,0xa3,0xf0},
       16,
       0x210,
       0,
       {0x90,0xe6,0x8a,0xf0,0x90,0xe6,0x8b,0x74,0x02,0xf0,0x02,0x03,0x84,0x90,0xe6,0xbc},
       16,
       0x220,
       0,
       {0xe0,0x54,0x7e,0xff,0x7e,0x00,0xe0,0xd3,0x94,0x80,0x40,0x06,0x7c,0x00,0x7d,0x01},
       16,
       0x230,
       0,
       {0x80,0x04,0x7c,0x00,0x7d,0x00,0xec,0x4e,0xfe,0xed,0x4f,0x24,0x0e,0xf5,0x82,0x74},
       16,
       0x240,
       0,
       {0x0f,0x3e,0xf5,0x83,0xe4,0x93,0xff,0x33,0x95,0xe0,0xfe,0xef,0x24,0xa1,0xff,0xee},
       16,
       0x250,
       0,
       {0x34,0xe6,0x8f,0x82,0xf5,0x83,0xe0,0x54,0x01,0x90,0xe7,0x40,0xf0,0xe4,0xa3,0xf0},
       16,
       0x260,
       0,
       {0x90,0xe6,0x8a,0xf0,0x90,0xe6,0x8b,0x74,0x02,0xf0,0x02,0x03,0x84,0x90,0xe6,0xa0},
       16,
       0x270,
       0,
       {0xe0,0x44,0x01,0xf0,0x02,0x03,0x84,0x12,0x0f,0x44,0x40,0x03,0x02,0x03,0x84,0x90},
       16,
       0x280,
       0,
       {0xe6,0xb8,0xe0,0x24,0xfe,0x60,0x1d,0x24,0x02,0x60,0x03,0x02,0x03,0x84,0x90,0xe6},
       16,
       0x290,
       0,
       {0xba,0xe0,0xb4,0x01,0x05,0xc2,0x00,0x02,0x03,0x84,0x90,0xe6,0xa0,0xe0,0x44,0x01},
       16,
       0x2a0,
       0,
       {0xf0,0x02,0x03,0x84,0x90,0xe6,0xba,0xe0,0x70,0x59,0x90,0xe6,0xbc,0xe0,0x54,0x7e},
       16,
       0x2b0,
       0,
       {0xff,0x7e,0x00,0xe0,0xd3,0x94,0x80,0x40,0x06,0x7c,0x00,0x7d,0x01,0x80,0x04,0x7c},
       16,
       0x2c0,
       0,
       {0x00,0x7d,0x00,0xec,0x4e,0xfe,0xed,0x4f,0x24,0x0e,0xf5,0x82,0x74,0x0f,0x3e,0xf5},
       16,
       0x2d0,
       0,
       {0x83,0xe4,0x93,0xff,0x33,0x95,0xe0,0xfe,0xef,0x24,0xa1,0xff,0xee,0x34,0xe6,0x8f},
       16,
       0x2e0,
       0,
       {0x82,0xf5,0x83,0xe0,0x54,0xfe,0xf0,0x90,0xe6,0xbc,0xe0,0x54,0x80,0xff,0x13,0x13},
       16,
       0x2f0,
       0,
       {0x13,0x54,0x1f,0xff,0xe0,0x54,0x0f,0x2f,0x90,0xe6,0x83,0xf0,0xe0,0x44,0x20,0xf0},
       16,
       0x300,
       0,
       {0x02,0x03,0x84,0x90,0xe6,0xa0,0xe0,0x44,0x01,0xf0,0x80,0x78,0x12,0x0f,0x46,0x50},
       16,
       0x310,
       0,
       {0x73,0x90,0xe6,0xb8,0xe0,0x24,0xfe,0x60,0x20,0x24,0x02,0x70,0x67,0x90,0xe6,0xba},
       16,
       0x320,
       0,
       {0xe0,0xb4,0x01,0x04,0xd2,0x00,0x80,0x5c,0x90,0xe6,0xba,0xe0,0x64,0x02,0x60,0x54},
       16,
       0x330,
       0,
       {0x90,0xe6,0xa0,0xe0,0x44,0x01,0xf0,0x80,0x4b,0x90,0xe6,0xbc,0xe0,0x54,0x7e,0xff},
       16,
       0x340,
       0,
       {0x7e,0x00,0xe0,0xd3,0x94,0x80,0x40,0x06,0x7c,0x00,0x7d,0x01,0x80,0x04,0x7c,0x00},
       16,
       0x350,
       0,
       {0x7d,0x00,0xec,0x4e,0xfe,0xed,0x4f,0x24,0x0e,0xf5,0x82,0x74,0x0f,0x3e,0xf5,0x83},
       16,
       0x360,
       0,
       {0xe4,0x93,0xff,0x33,0x95,0xe0,0xfe,0xef,0x24,0xa1,0xff,0xee,0x34,0xe6,0x8f,0x82},
       16,
       0x370,
       0,
       {0xf5,0x83,0xe0,0x44,0x01,0xf0,0x80,0x0c,0x12,0x0e,0xd8,0x50,0x07,0x90,0xe6,0xa0},
       11,
       0x380,
       0,
       {0xe0,0x44,0x01,0xf0,0x90,0xe6,0xa0,0xe0,0x44,0x80,0xf0},
       1,
       0x38b,
       0,
       {0x22},
       16,
       0xc29,
       0,
       {0xc2,0x03,0xc2,0x00,0xc2,0x02,0xc2,0x01,0x12,0x0f,0x3a,0x12,0x04,0xc6,0xd2,0xe8},
       16,
       0xc39,
       0,
       {0x43,0xd8,0x20,0x90,0xe6,0x68,0xe0,0x44,0x0b,0xf0,0x75,0xa2,0xff,0x90,0xe6,0x5c},
       16,
       0xc49,
       0,
       {0xe0,0x44,0x3d,0xf0,0xd2,0xaf,0x90,0xe6,0x80,0xe0,0x44,0x02,0xf0,0x00,0x00,0x00},
       16,
       0xc59,
       0,
       {0xe0,0x54,0xf7,0xf0,0x53,0x8e,0xf8,0xc2,0x03,0x30,0x01,0x05,0x12,0x01,0x00,0xc2},
       16,
       0xc69,
       0,
       {0x01,0x30,0x03,0x29,0x12,0x07,0xfe,0x50,0x24,0xc2,0x03,0x12,0x07,0xd9,0x20,0x00},
       16,
       0xc79,
       0,
       {0x16,0x90,0xe6,0x82,0xe0,0x30,0xe7,0x04,0xe0,0x20,0xe1,0xef,0x90,0xe6,0x82,0xe0},
       16,
       0xc89,
       0,
       {0x30,0xe6,0x04,0xe0,0x20,0xe0,0xe4,0x12,0x0d,0xaa,0x12,0x08,0xfe,0x12,0x0f,0x3d},
       2,
       0xc99,
       0,
       {0x80,0xc7},
       3,
       0x33,
       0,
       {0x02,0x0f,0x36},
       4,
       0xf36,
       0,
       {0x53,0xd8,0xef,0x32},
       3,
       0x43,
       0,
       {0x02,0x08,0x00},
       3,
       0x53,
       0,
       {0x02,0x08,0x00},
       16,
       0x800,
       0,
       {0x02,0x0e,0x58,0x00,0x02,0x0e,0x9e,0x00,0x02,0x0e,0x88,0x00,0x02,0x0e,0x70,0x00},
       16,
       0x810,
       0,
       {0x02,0x0c,0xd8,0x00,0x02,0x0c,0x9b,0x00,0x02,0x0f,0x48,0x00,0x02,0x0f,0x49,0x00},
       16,
       0x820,
       0,
       {0x02,0x0f,0x4a,0x00,0x02,0x0f,0x4b,0x00,0x02,0x0f,0x4c,0x00,0x02,0x0f,0x4d,0x00},
       16,
       0x830,
       0,
       {0x02,0x0f,0x4e,0x00,0x02,0x0f,0x4f,0x00,0x02,0x0f,0x50,0x00,0x02,0x0f,0x51,0x00},
       16,
       0x840,
       0,
       {0x02,0x0f,0x52,0x00,0x02,0x0f,0x49,0x00,0x02,0x0f,0x53,0x00,0x02,0x0f,0x54,0x00},
       16,
       0x850,
       0,
       {0x02,0x0f,0x55,0x00,0x02,0x0f,0x56,0x00,0x02,0x0f,0x57,0x00,0x02,0x0f,0x58,0x00},
       16,
       0x860,
       0,
       {0x02,0x0f,0x59,0x00,0x02,0x0f,0x49,0x00,0x02,0x0f,0x49,0x00,0x02,0x0f,0x49,0x00},
       16,
       0x870,
       0,
       {0x02,0x0f,0x5a,0x00,0x02,0x0f,0x5b,0x00,0x02,0x0f,0x5c,0x00,0x02,0x0f,0x5d,0x00},
       16,
       0x880,
       0,
       {0x02,0x0f,0x5e,0x00,0x02,0x0f,0x5f,0x00,0x02,0x0f,0x60,0x00,0x02,0x0f,0x61,0x00},
       16,
       0x890,
       0,
       {0x02,0x0f,0x62,0x00,0x02,0x0f,0x63,0x00,0x02,0x0f,0x64,0x00,0x02,0x0f,0x65,0x00},
       16,
       0x8a0,
       0,
       {0x02,0x0f,0x66,0x00,0x02,0x0f,0x67,0x00,0x02,0x0f,0x68,0x00,0x02,0x0f,0x69,0x00},
       8,
       0x8b0,
       0,
       {0x02,0x0f,0x6a,0x00,0x02,0x0f,0x6b,0x00},
       16,
       0x900,
       0,
       {0x12,0x01,0x00,0x02,0x00,0x00,0x00,0x40,0xb4,0x04,0x13,0x86,0x00,0x00,0x01,0x02},
       16,
       0x910,
       0,
       {0x00,0x01,0x0a,0x06,0x00,0x02,0x00,0x00,0x00,0x40,0x01,0x00,0x09,0x02,0x12,0x00},
       16,
       0x920,
       0,
       {0x01,0x01,0x00,0x60,0x32,0x09,0x04,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0x09,0x02},
       16,
       0x930,
       0,
       {0x12,0x00,0x01,0x01,0x00,0x60,0x32,0x09,0x04,0x00,0x00,0x00,0xff,0x00,0x00,0x00},
       16,
       0x940,
       0,
       {0x04,0x03,0x09,0x04,0x30,0x03,0x41,0x00,0x70,0x00,0x6f,0x00,0x67,0x00,0x65,0x00},
       16,
       0x950,
       0,
       {0x65,0x00,0x2d,0x00,0x49,0x00,0x6e,0x00,0x73,0x00,0x74,0x00,0x72,0x00,0x75,0x00},
       16,
       0x960,
       0,
       {0x6d,0x00,0x65,0x00,0x6e,0x00,0x74,0x00,0x73,0x00,0x20,0x00,0x49,0x00,0x6e,0x00},
       16,
       0x970,
       0,
       {0x63,0x00,0x2e,0x00,0x34,0x03,0x45,0x00,0x5a,0x00,0x2d,0x00,0x55,0x00,0x53,0x00},
       16,
       0x980,
       0,
       {0x42,0x00,0x20,0x00,0x46,0x00,0x58,0x00,0x32,0x00,0x2d,0x00,0x41,0x00,0x50,0x00},
       16,
       0x990,
       0,
       {0x6e,0x00,0x20,0x00,0x52,0x00,0x4f,0x00,0x4d,0x00,0x20,0x00,0x4c,0x00,0x4f,0x00},
       10,
       0x9a0,
       0,
       {0x41,0x00,0x44,0x00,0x45,0x00,0x52,0x00,0x00,0x00},
       16,
       0xdaa,
       0,
       {0x90,0xe6,0x82,0xe0,0x30,0xe0,0x04,0xe0,0x20,0xe6,0x0b,0x90,0xe6,0x82,0xe0,0x30},
       16,
       0xdba,
       0,
       {0xe1,0x19,0xe0,0x30,0xe7,0x15,0x90,0xe6,0x80,0xe0,0x44,0x01,0xf0,0x7f,0x14,0x7e},
       12,
       0xdca,
       0,
       {0x00,0x12,0x08,0xb8,0x90,0xe6,0x80,0xe0,0x54,0xfe,0xf0,0x22},
       16,
       0x7d9,
       0,
       {0x90,0xe6,0x82,0xe0,0x44,0xc0,0xf0,0x90,0xe6,0x81,0xf0,0x43,0x87,0x01,0x00,0x00},
       4,
       0x7e9,
       0,
       {0x00,0x00,0x00,0x22},
       8,
       0xf28,
       0,
       {0xe4,0xf5,0x34,0xd2,0xe9,0xd2,0xaf,0x22},
       16,
       0xd0e,
       0,
       {0x90,0xe6,0x78,0xe0,0x20,0xe6,0xf9,0xc2,0xe9,0x90,0xe6,0x78,0xe0,0x44,0x80,0xf0},
       16,
       0xd1e,
       0,
       {0xef,0x25,0xe0,0x90,0xe6,0x79,0xf0,0x90,0xe6,0x78,0xe0,0x30,0xe0,0xf9,0x90,0xe6},
       16,
       0xd2e,
       0,
       {0x78,0xe0,0x44,0x40,0xf0,0x90,0xe6,0x78,0xe0,0x20,0xe6,0xf9,0x90,0xe6,0x78,0xe0},
       6,
       0xd3e,
       0,
       {0x30,0xe1,0xd6,0xd2,0xe9,0x22},
       16,
       0xd78,
       0,
       {0xa9,0x07,0x90,0xe6,0x78,0xe0,0x20,0xe6,0xf9,0xe5,0x34,0x70,0x23,0x90,0xe6,0x78},
       16,
       0xd88,
       0,
       {0xe0,0x44,0x80,0xf0,0xe9,0x25,0xe0,0x90,0xe6,0x79,0xf0,0x8d,0x2f,0xaf,0x03,0xa9},
       16,
       0xd98,
       0,
       {0x07,0x75,0x30,0x01,0x8a,0x31,0x89,0x32,0xe4,0xf5,0x33,0x75,0x34,0x01,0xd3,0x22},
       2,
       0xda8,
       0,
       {0xc3,0x22},
       16,
       0xd44,
       0,
       {0xa9,0x07,0x90,0xe6,0x78,0xe0,0x20,0xe6,0xf9,0xe5,0x34,0x70,0x25,0x90,0xe6,0x78},
       16,
       0xd54,
       0,
       {0xe0,0x44,0x80,0xf0,0xe9,0x25,0xe0,0x44,0x01,0x90,0xe6,0x79,0xf0,0x8d,0x2f,0xaf},
       16,
       0xd64,
       0,
       {0x03,0xa9,0x07,0x75,0x30,0x01,0x8a,0x31,0x89,0x32,0xe4,0xf5,0x33,0x75,0x34,0x03},
       4,
       0xd74,
       0,
       {0xd3,0x22,0xc3,0x22},
       3,
       0x4b,
       0,
       {0x02,0x05,0xed},
       16,
       0x5ed,
       0,
       {0xc0,0xe0,0xc0,0x83,0xc0,0x82,0xc0,0x85,0xc0,0x84,0xc0,0x86,0x75,0x86,0x00,0xc0},
       16,
       0x5fd,
       0,
       {0xd0,0x75,0xd0,0x00,0xc0,0x00,0xc0,0x01,0xc0,0x02,0xc0,0x03,0xc0,0x06,0xc0,0x07},
       16,
       0x60d,
       0,
       {0x90,0xe6,0x78,0xe0,0x30,0xe2,0x06,0x75,0x34,0x06,0x02,0x06,0xd7,0x90,0xe6,0x78},
       16,
       0x61d,
       0,
       {0xe0,0x20,0xe1,0x0c,0xe5,0x34,0x64,0x02,0x60,0x06,0x75,0x34,0x07,0x02,0x06,0xd7},
       16,
       0x62d,
       0,
       {0xe5,0x34,0x24,0xfe,0x60,0x5f,0x14,0x60,0x36,0x24,0xfe,0x70,0x03,0x02,0x06,0xc8},
       16,
       0x63d,
       0,
       {0x24,0xfc,0x70,0x03,0x02,0x06,0xd4,0x24,0x08,0x60,0x03,0x02,0x06,0xd7,0xab,0x30},
       16,
       0x64d,
       0,
       {0xaa,0x31,0xa9,0x32,0xaf,0x33,0x05,0x33,0x8f,0x82,0x75,0x83,0x00,0x12,0x09,0xaa},
       16,
       0x65d,
       0,
       {0x90,0xe6,0x79,0xf0,0xe5,0x33,0x65,0x2f,0x70,0x70,0x75,0x34,0x05,0x80,0x6b,0x90},
       16,
       0x66d,
       0,
       {0xe6,0x79,0xe0,0xab,0x30,0xaa,0x31,0xa9,0x32,0xae,0x33,0x8e,0x82,0x75,0x83,0x00},
       16,
       0x67d,
       0,
       {0x12,0x09,0xd7,0x75,0x34,0x02,0xe5,0x2f,0x64,0x01,0x70,0x4e,0x90,0xe6,0x78,0xe0},
       16,
       0x68d,
       0,
       {0x44,0x20,0xf0,0x80,0x45,0xe5,0x2f,0x24,0xfe,0xb5,0x33,0x07,0x90,0xe6,0x78,0xe0},
       16,
       0x69d,
       0,
       {0x44,0x20,0xf0,0xe5,0x2f,0x14,0xb5,0x33,0x0a,0x90,0xe6,0x78,0xe0,0x44,0x40,0xf0},
       16,
       0x6ad,
       0,
       {0x75,0x34,0x00,0x90,0xe6,0x79,0xe0,0xab,0x30,0xaa,0x31,0xa9,0x32,0xae,0x33,0x8e},
       16,
       0x6bd,
       0,
       {0x82,0x75,0x83,0x00,0x12,0x09,0xd7,0x05,0x33,0x80,0x0f,0x90,0xe6,0x78,0xe0,0x44},
       16,
       0x6cd,
       0,
       {0x40,0xf0,0x75,0x34,0x00,0x80,0x03,0x75,0x34,0x00,0x53,0x91,0xdf,0xd0,0x07,0xd0},
       16,
       0x6dd,
       0,
       {0x06,0xd0,0x03,0xd0,0x02,0xd0,0x01,0xd0,0x00,0xd0,0xd0,0xd0,0x86,0xd0,0x84,0xd0},
       8,
       0x6ed,
       0,
       {0x85,0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32},
       2,
       0xdd6,
       0,
       {0xa9,0x07},
       16,
       0xdd8,
       0,
       {0xae,0x2d,0xaf,0x2e,0x8f,0x82,0x8e,0x83,0xa3,0xe0,0x64,0x03,0x70,0x17,0xad,0x01},
       16,
       0xde8,
       0,
       {0x19,0xed,0x70,0x01,0x22,0x8f,0x82,0x8e,0x83,0xe0,0x7c,0x00,0x2f,0xfd,0xec,0x3e},
       9,
       0xdf8,
       0,
       {0xfe,0xaf,0x05,0x80,0xdf,0x7e,0x00,0x7f,0x00},
       1,
       0xe01,
       0,
       {0x22},
       16,
       0xe20,
       0,
       {0x12,0x0d,0x44,0xe5,0x34,0x24,0xfa,0x60,0x0e,0x14,0x60,0x06,0x24,0x07,0x70,0xf3},
       12,
       0xe30,
       0,
       {0xd3,0x22,0xe4,0xf5,0x34,0xd3,0x22,0xe4,0xf5,0x34,0xd3,0x22},
       16,
       0xe3c,
       0,
       {0x12,0x0d,0x78,0xe5,0x34,0x24,0xfa,0x60,0x0e,0x14,0x60,0x06,0x24,0x07,0x70,0xf3},
       12,
       0xe4c,
       0,
       {0xd3,0x22,0xe4,0xf5,0x34,0xd3,0x22,0xe4,0xf5,0x34,0xd3,0x22},
       16,
       0x8b8,
       0,
       {0x8e,0x08,0x8f,0x09,0x90,0xe6,0x00,0xe0,0x54,0x18,0x70,0x12,0xe5,0x09,0x24,0x01},
       16,
       0x8c8,
       0,
       {0xff,0xe4,0x35,0x08,0xc3,0x13,0xf5,0x08,0xef,0x13,0xf5,0x09,0x80,0x15,0x90,0xe6},
       16,
       0x8d8,
       0,
       {0x00,0xe0,0x54,0x18,0xff,0xbf,0x10,0x0b,0xe5,0x09,0x25,0xe0,0xf5,0x09,0xe5,0x08},
       16,
       0x8e8,
       0,
       {0x33,0xf5,0x08,0xe5,0x09,0x15,0x09,0xae,0x08,0x70,0x02,0x15,0x08,0x4e,0x60,0x05},
       6,
       0x8f8,
       0,
       {0x12,0x07,0xed,0x80,0xee,0x22},
       16,
       0x7ed,
       0,
       {0x74,0x00,0xf5,0x86,0x90,0xfd,0xa5,0x7c,0x05,0xa3,0xe5,0x82,0x45,0x83,0x70,0xf9},
       1,
       0x7fd,
       0,
       {0x22},
       3,
       0x0,
       0,
       {0x02,0x0e,0xf8},
       12,
       0xef8,
       0,
       {0x78,0x7f,0xe4,0xf6,0xd8,0xfd,0x75,0x81,0x34,0x02,0x0c,0x29},
       16,
       0x9aa,
       0,
       {0xbb,0x01,0x0c,0xe5,0x82,0x29,0xf5,0x82,0xe5,0x83,0x3a,0xf5,0x83,0xe0,0x22,0x50},
       16,
       0x9ba,
       0,
       {0x06,0xe9,0x25,0x82,0xf8,0xe6,0x22,0xbb,0xfe,0x06,0xe9,0x25,0x82,0xf8,0xe2,0x22},
       13,
       0x9ca,
       0,
       {0xe5,0x82,0x29,0xf5,0x82,0xe5,0x83,0x3a,0xf5,0x83,0xe4,0x93,0x22},
       16,
       0x9d7,
       0,
       {0xf8,0xbb,0x01,0x0d,0xe5,0x82,0x29,0xf5,0x82,0xe5,0x83,0x3a,0xf5,0x83,0xe8,0xf0},
       16,
       0x9e7,
       0,
       {0x22,0x50,0x06,0xe9,0x25,0x82,0xc8,0xf6,0x22,0xbb,0xfe,0x05,0xe9,0x25,0x82,0xc8},
       2,
       0x9f7,
       0,
       {0xf2,0x22},
       16,
       0x9f9,
       0,
       {0xeb,0x9f,0xf5,0xf0,0xea,0x9e,0x42,0xf0,0xe9,0x9d,0x42,0xf0,0xe8,0x9c,0x45,0xf0},
       1,
       0xa09,
       0,
       {0x22},
       12,
       0xa0a,
       0,
       {0xe0,0xfc,0xa3,0xe0,0xfd,0xa3,0xe0,0xfe,0xa3,0xe0,0xff,0x22},
       12,
       0xa16,
       0,
       {0xec,0xf0,0xa3,0xed,0xf0,0xa3,0xee,0xf0,0xa3,0xef,0xf0,0x22},
       16,
       0xa22,
       0,
       {0xd0,0x83,0xd0,0x82,0xf8,0xe4,0x93,0x70,0x12,0x74,0x01,0x93,0x70,0x0d,0xa3,0xa3},
       16,
       0xa32,
       0,
       {0x93,0xf8,0x74,0x01,0x93,0xf5,0x82,0x88,0x83,0xe4,0x73,0x74,0x02,0x93,0x68,0x60},
       6,
       0xa42,
       0,
       {0xef,0xa3,0xa3,0xa3,0x80,0xdf},
       0,
       0x0,
       1,
       {0}
    };
}

//////////////////////////// 
// CTOR 
AltaUsbIo::AltaUsbIo( const std::string & DeviceEnum ) : 
                                        CamUsbIo( DeviceEnum, 
                                            ALTA_U_MAX_BUFFER_SIZE,
                                            false ),
                                        m_fileName( __FILE__)
{ 

} 

//////////////////////////// 
// DTOR 
AltaUsbIo::~AltaUsbIo() 
{ 

} 

//////////////////////////// 
// DOWNLOAD    FIRMWARE
void AltaUsbIo::DownloadFirmware()
{
    std::vector<UsbFrmwr::IntelHexRec> frmwr = 
        UsbFrmwr::MakeRecVect( firmware );

    PromFx2Io pf( m_Usb,
        ALTA_EEPROM_MAX_BLOCKS,
        ALTA_EEPROM_MAX_BANKS );

    pf.FirmwareDownload( frmwr );
}



 /////////////////////////// 
//      PROGRAM     CAMERA
void AltaUsbIo::Program(const std::string & FilenameCamCon,
            const std::string & FilenameBufCon, const std::string & FilenameFx2,
            const std::string & FilenameGpifCamCon,const std::string & FilenameGpifBufCon,
            const std::string & FilenameGpifFifo, bool Print2StdOut )
{
    m_Print2StdOut = Print2StdOut;
    //STEP 1
    //get the current product and device identifier
    uint16_t Vid = 0; 
    uint16_t Pid = 0;
    uint16_t Did = 0;
    GetUsbVendorInfo( Vid, Pid, Did );
   
    //if this programmed with apogee fx2 code
    //grab the custom serial number now, so we
    //can write it back at the end of the firmware
    //programming
    std::string serialNum;

    if ( ( UsbFrmwr::ALTA_USB_PID  == Pid ) && (UsbFrmwr::ALTA_USB_DID  <= Did) )
	{
        serialNum = GetSerialNumber();
	}
   
    Progress2StdOut( 8 );

    //STEP 2
    //download the alta firmware
    DownloadFirmware();

    Progress2StdOut( 16 );

    //STEP 3
    // initialize prom header information
	Eeprom::Header hdr;
    memset(&hdr, 0, sizeof( hdr ) );
    hdr.Size = sizeof( hdr );
    hdr.Version = Eeprom::HEADER_VERSION;

    Progress2StdOut( 24 );

    //STEP 4
    //download bufcon
    PromFx2Io pf( m_Usb,
        ALTA_EEPROM_MAX_BLOCKS,
        ALTA_EEPROM_MAX_BANKS );

    uint32_t DownloadSize = 0;
    pf.WriteFile2Eeprom( FilenameBufCon, BUFCON_PROM_BANK,
        BUFCON_PROM_BLOCK , BUFCON_PROM_ADDR, DownloadSize );

    hdr.BufConSize = DownloadSize;
    hdr.Fields |= Eeprom::HEADER_BUFCON_VALID_BIT;

    Progress2StdOut( 32 );

    //STEP 5
    //download camcon
    pf.WriteFile2Eeprom( FilenameCamCon, CAMCON_PROM_BANK,
        CAMCON_PROM_BLOCK , CAMCON_PROM_ADDR, DownloadSize );

    hdr.CamConSize = DownloadSize;
    hdr.Fields |= Eeprom::HEADER_CAMCON_VALID_BIT;

    Progress2StdOut( 40 );

    //STEP 6
    //download the fx2
    pf.WriteFile2Eeprom( FilenameFx2, FX2_PROM_BANK,
        FX2_PROM_BLOCK, FX2_PROM_ADDR, DownloadSize );

    hdr.Fields |= Eeprom::HEADER_BOOTROM_VALID_BIT;

    Progress2StdOut( 48 );

    //STEP 7
    //download the bufcon gpif waveform
    pf.WriteFile2Eeprom( FilenameGpifBufCon, 
        GPIF_WAVEFORM_BUFCON_PROM_BANK,
        GPIF_WAVEFORM_BUFCON_PROM_BLOCK, 
        GPIF_WAVEFORM_BUFCON_PROM_ADDR, 
        DownloadSize );

    Progress2StdOut( 56 );

    //STEP 8
    //download the camcon gpif waveform
    pf.WriteFile2Eeprom( FilenameGpifCamCon, 
        GPIF_WAVEFORM_CAMCON_PROM_BANK,
        GPIF_WAVEFORM_CAMCON_PROM_BLOCK, 
        GPIF_WAVEFORM_CAMCON_PROM_ADDR, 
        DownloadSize );

    Progress2StdOut( 64 );

     //STEP 9
    //download the FIFO gpif waveform
    pf.WriteFile2Eeprom( FilenameGpifFifo, 
        GPIF_WAVEFORM_FIFO_PROM_BANK,
        GPIF_WAVEFORM_FIFO_PROM_BLOCK, 
        GPIF_WAVEFORM_FIFO_PROM_ADDR, 
        DownloadSize );

    hdr.Fields |= Eeprom::HEADER_GPIF_VALID_BIT;

    Progress2StdOut( 72 );

    //STEP 10
    //set the vid, pid, and did
    hdr.VendorId = UsbFrmwr::APOGEE_VID;
    hdr.Fields |= Eeprom::HEADER_VID_VALID;
    hdr.ProductId = UsbFrmwr::ALTA_USB_PID;
    hdr.Fields |= Eeprom::HEADER_PID_VALID ;
    hdr.DeviceId = UsbFrmwr::ALTA_USB_DID;
    hdr.Fields |= Eeprom::HEADER_DID_VALID;

    Progress2StdOut( 80 );

    //STEP 11
    //write the header
    hdr.CheckSum = Eeprom::CalcHdrCheckSum( hdr );

    pf.WriteEepromHdr( hdr, HEADER_PROM_BANK,
        HEADER_PROM_BLOCK, HEADER_PROM_ADDR);
    
    Progress2StdOut( 88 );

    //STEP 12
    //write the stored serial number to the camera
    SetSerialNumber( serialNum );

    Progress2StdOut( 100 );

    //turn this off on exit
    m_Print2StdOut = false;
}

//////////////////////////// 
//      READ      HEADER
void AltaUsbIo::ReadHeader( Eeprom::Header & hdr )
{
    PromFx2Io pf( m_Usb,
        ALTA_EEPROM_MAX_BLOCKS,
        ALTA_EEPROM_MAX_BANKS );

    pf.ReadEepromHdr( hdr, HEADER_PROM_BANK,
        HEADER_PROM_BLOCK, HEADER_PROM_ADDR );
}

//////////////////////////// 
// GET      SERIAL       NUMBER
std::string AltaUsbIo::GetSerialNumber()
{
    std::vector<char> data(Eeprom::MAX_SERIAL_NUM_BYTES+1, 0);

    m_Usb->GetSerialNumber( reinterpret_cast<int8_t*>(&data.at(0)), Eeprom::MAX_SERIAL_NUM_BYTES );

    std::string serialNum( &data.at(0) );

    return serialNum;
}

//////////////////////////// 
// SET      SERIAL       NUMBER
void AltaUsbIo::SetSerialNumber(const std::string & num)
{
    //download firmware into the cypress chip's RAM
    //because of hw architecture we have to run the 
    //chip out of RAM to access the EEPROMS
    DownloadFirmware();

    //write the serial number into the EEPROM
    std::vector<uint8_t> numVect( Eeprom::MAX_SERIAL_NUM_BYTES, 0); 
        
    std::copy(num.begin(), num.end(), numVect.begin() );

    PromFx2Io pf( m_Usb,
        ALTA_EEPROM_MAX_BLOCKS,
        ALTA_EEPROM_MAX_BANKS );

    pf.BufferWriteEeprom(ALTA_SN_EEPROM_BANK, ALTA_SN_EEPROM_BLOCK,
        ALTA_SN_EEPROM_ADDR, numVect);
                          
}  

//////////////////////////// 
//      SET     SERIAL       BAUD     RATE
void AltaUsbIo::SetSerialBaudRate( const uint16_t PortId , const uint32_t BaudRate )
{
    AltaUsbIo::SerialPortSettings settings = ReadSerialSettings( PortId );
    settings.BaudRate = BaudRate;
    WriteSerialSettings( PortId, settings );
}

//////////////////////////// 
//      GET     SERIAL       BAUD     RATE
uint32_t AltaUsbIo::GetSerialBaudRate(  const uint16_t PortId  )
{
     const AltaUsbIo::SerialPortSettings settings = ReadSerialSettings( PortId );
     return settings.BaudRate;
}

//////////////////////////// 
//   GET    SERIAL   FLOW     CONTROL
Apg::SerialFC AltaUsbIo::GetSerialFlowControl( uint16_t PortId )
{
    const AltaUsbIo::SerialPortSettings settings = ReadSerialSettings( PortId );

    return( settings.PortCtrl & SERIAL_FLOW_MASK ? Apg::SerialFC_On : Apg::SerialFC_Off );
}

//////////////////////////// 
//   SET    SERIAL   FLOW     CONTROL
void AltaUsbIo::SetSerialFlowControl( uint16_t PortId, 
            const Apg::SerialFC FlowControl )
{
    AltaUsbIo::SerialPortSettings settings = ReadSerialSettings( PortId );
    
    
    switch( FlowControl )
    {
        case Apg::SerialFC_Off:
           settings.PortCtrl &= static_cast<uint8_t>(~SERIAL_FLOW_MASK);
        break;

        case Apg::SerialFC_On:
            settings.PortCtrl |= SERIAL_FLOW_MASK;
        break;

        default:
        {
            std::stringstream msg;
            msg <<  "Invalid SerialFlowControl value = " << FlowControl;
            apgHelper::throwRuntimeException( m_fileName, msg.str(), 
                __LINE__, Apg::ErrorType_InvalidUsage );
        }
        break;
    }

    WriteSerialSettings( PortId, settings );
}

//////////////////////////// 
//  GET    SERIAL    PARITY
Apg::SerialParity AltaUsbIo::GetSerialParity( uint16_t PortId )
{
    const AltaUsbIo::SerialPortSettings settings = ReadSerialSettings( PortId );

    Apg::SerialParity result = Apg::SerialParity_Unknown;
    const uint8_t PARITY_MASK = SERIAL_PARITY_ENA_MASK | SERIAL_PARITY_ODD_MASK;
    const uint8_t parityValue = settings.PortCtrl & PARITY_MASK;
    
    switch( parityValue )
    {
        case SERIAL_PARITY_ENA_MASK:
            result = Apg::SerialParity_Even;
        break;

        case SERIAL_PARITY_ENA_MASK | SERIAL_PARITY_ODD_MASK:
            result = Apg::SerialParity_Odd;
        break;

        default:
             result = Apg::SerialParity_None;
        break;
    }

    return result;
}

//////////////////////////// 
//  SET    SERIAL    PARITY
void AltaUsbIo::SetSerialParity( uint16_t PortId, Apg::SerialParity Parity )
{
    AltaUsbIo::SerialPortSettings settings = ReadSerialSettings( PortId );

    //set both bits low
    settings.PortCtrl &= static_cast<uint8_t>(~SERIAL_PARITY_ENA_MASK);
    settings.PortCtrl &= static_cast<uint8_t>(~SERIAL_PARITY_ODD_MASK);

    switch( Parity  )
    {
        case Apg::SerialParity_Even:
            settings.PortCtrl |= SERIAL_PARITY_ENA_MASK;
        break;

        case Apg::SerialParity_Odd:
            settings.PortCtrl |= SERIAL_PARITY_ENA_MASK;
            settings.PortCtrl |= SERIAL_PARITY_ODD_MASK;
        break;

        case Apg::SerialParity_None:
            settings.PortCtrl &= static_cast<uint8_t>(~SERIAL_PARITY_ENA_MASK);
        break;

        default:
        {
            std::stringstream msg;
            msg <<  "Invalid Parity value = " << Parity;
            apgHelper::throwRuntimeException( m_fileName, msg.str(), 
                __LINE__, Apg::ErrorType_InvalidUsage );
        }
        break;
    }

    WriteSerialSettings( PortId, settings );
}

//////////////////////////// 
//      READ       SERIAL         
void AltaUsbIo::ReadSerial( uint16_t PortId, std::string & buffer )
{
    // camera sends us 64byte buffers
    const size_t SERIAL_BUF_SIZE = 64;
    std::vector<char> data(SERIAL_BUF_SIZE +1, 0);

    m_Usb->ReadSerialPort( PortId,
        reinterpret_cast<uint8_t*>( &data.at(0) ), 
        apgHelper::SizeT2Uint16( SERIAL_BUF_SIZE) );

    buffer.clear();
    buffer.append( &data.at(0) );
}

//////////////////////////// 
//      WRITE       SERIAL   
void AltaUsbIo::WriteSerial( uint16_t PortId, const std::string & buffer )
{
     
    std::vector<uint8_t> data( buffer.size(), 0); 
        
    std::copy(buffer.begin(), buffer.end(), data.begin() );

    m_Usb->UsbRequestOut( VND_APOGEE_SERIAL, PortId, 0, 
        &(*data.begin()), apgHelper::SizeT2Uint32( buffer.size() ) );
}

//////////////////////////// 
//      READ       SERIAL           SETTINGS
AltaUsbIo::SerialPortSettings AltaUsbIo::ReadSerialSettings( const uint16_t PortId )
{
    AltaUsbIo::SerialPortSettings settings;

    m_Usb->UsbRequestIn( VND_APOGEE_SET_SERIAL, 
            PortId, 0, reinterpret_cast<uint8_t*>(&settings), sizeof(settings) );

    return settings;
}
 
//////////////////////////// 
//      WRITE        SERIAL           SETTINGS
void AltaUsbIo::WriteSerialSettings( const uint16_t PortId, 
    AltaUsbIo::SerialPortSettings & settings)
{
    m_Usb->UsbRequestOut( VND_APOGEE_SET_SERIAL, 
        PortId, 0, reinterpret_cast<uint8_t*>(&settings), sizeof(settings) );
}

