Logo Search packages:      
Sourcecode: qpxtool version File versions  Download package

plextor_qcheck.cpp

/*
 * This file is part of the QPxTool project.
 * Copyright (C) 2005-2006 Gennady "ShultZ" Kozlov <qpxtool@mail.ru>
 *
 *
 * Some Plextor commands got from PxScan and CDVDlib (C) Alexander Noe`
 *
 *
 * 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.
 * See the file "COPYING" for the exact licensing terms.
 */

#include <stdio.h>
#include <stdlib.h>

#include <math.h>
#include <common_functions.h>

#include <qthread.h>
#include <transport.h>
#include <qpx_mmc.h>

#include "test_threads.h"
#include "plextor_qcheck.h"
#include "qpx_const.h"

#define DEBUG 1
//#define _debug_cx
#define _debug_pi
//#define _debug_jb

//*********************************//
//
//  commands to start tests
//
//*********************************//

int   talayers;

const char PLEX_QCHECK_START  = 0x15;
const char PLEX_QCHECK_READOUT      = 0x16;
const char PLEX_QCHECK_END    = 0x17;

int plextor_start_cx(drive_info* drive) {
      drive->cmd_clear();
      drive->cmd[0] = CMP_PLEX_QCHECK; //0xEA;
      drive->cmd[1] = PLEX_QCHECK_START; //0x15;
      drive->cmd[2] = 0x00;
      drive->cmd[3] = 0x01;
      if ((drive->err=drive->cmd.transport(READ,NULL,0) ))
            {sperror ("PLEXTOR_START_CX",drive->err); return drive->err;}
#ifdef _debug_cx

      printf("00 18 01 01 00 4B |      LBA    |  BLER   E31   E21   E11   ???   E32   E22   E12 |   1 C1|   0 C2|   0 CU\n");
#endif
      return 0;
}

int plextor_start_pie(drive_info* drive) {
      drive->cmd_clear();
      drive->cmd[0] = CMP_PLEX_QCHECK; //0xEA;
      drive->cmd[1] = PLEX_QCHECK_START; //0x15;
      drive->cmd[2] = 0x00;
      drive->cmd[3] = 0x00;
      drive->cmd[8] = 0x08; // scan interval (ECC blocks)
      drive->cmd[9] = 0x10;
      if ((drive->err=drive->cmd.transport(READ,NULL,0)))
            {sperror ("PLEXTOR_START_PISUM8",drive->err);return drive->err;}
      return 0;
}

int plextor_start_pie_poe(drive_info* drive) {
      drive->cmd_clear();
      drive->cmd[0] = CMP_PLEX_QCHECK; //0xEA;
      drive->cmd[1] = PLEX_QCHECK_START; //0x15;
      drive->cmd[2] = 0x00;
      drive->cmd[3] = 0x00;
      drive->cmd[8] = 0x08; // scan interval (ECC blocks)
      drive->cmd[9] = 0x11;
      if ((drive->err=drive->cmd.transport(READ,NULL,0)))
            {sperror ("PLEXTOR_START_PISUM8_POE",drive->err);return drive->err;}
      return 0;
}

int plextor_start_pif(drive_info* drive) {
      drive->cmd_clear();
      drive->cmd[0] = CMP_PLEX_QCHECK; //0xEA;
      drive->cmd[1] = PLEX_QCHECK_START; //0x15;
      drive->cmd[2] = 0x00;
      drive->cmd[3] = 0x00;
      drive->cmd[8] = 0x01; // scan interval (ECC blocks)
      drive->cmd[9] = 0x12;
      if ((drive->err=drive->cmd.transport(READ,NULL,0)))
            {sperror ("PLEXTOR_START_PIF",drive->err); return drive->err;}
      return 0;
}

int plextor_start_jb_DVD(drive_info* drive) {
      drive->cmd_clear();
      drive->cmd[0] = CMP_PLEX_QCHECK; //0xEA;
      drive->cmd[1] = PLEX_QCHECK_START; //0x15;
      drive->cmd[2] = 0x10;
      drive->cmd[3] = 0x00; // DVD
      drive->cmd[8] = 0x10; // scan interval (ECC blocks)
      if ((drive->err=drive->cmd.transport(READ,NULL,0)))
            {sperror ("PLEXTOR_START_JB_DVD",drive->err);return drive->err;}
      return 0;
}

int plextor_start_jb_CD(drive_info* drive) {
      drive->cmd_clear();
      drive->cmd[0] = CMP_PLEX_QCHECK; //0xEA;
      drive->cmd[1] = PLEX_QCHECK_START; //0x15;
      drive->cmd[2] = 0x10;
      drive->cmd[3] = 0x01; // CD
      if ((drive->err=drive->cmd.transport(READ,NULL,0)))
            {sperror ("PLEXTOR_START_JB_CD",drive->err);return drive->err;}
      return 0;
}

int plextor_start_fete(drive_info* drive) {
      drive->cmd[0] = CMD_PLEX_SCAN_TA_FETE; // 0xF3;
      drive->cmd[1] = 0x1F;
      drive->cmd[2] = 0x03;
      drive->cmd[3] = 0x01;
      if (drive->media.disc_type & DISC_CD) {
            int sect;
            msf sect_msf;
//    start address
            drive->cmd[4] = 0x00;
            drive->cmd[5] = 0x00;
            drive->cmd[6] = 0x00;
//    end address
            sect = drive->media.capacity_total-1;
            lba2msf(&sect,&sect_msf);
            drive->cmd[7] = sect_msf.m;
            drive->cmd[8] = sect_msf.s;
            drive->cmd[9] = sect_msf.f;
      } else {
//    start address
            drive->cmd[4] = 0x00;
            drive->cmd[5] = 0x00;
            drive->cmd[6] = 0x00;
//    end address
            drive->cmd[7] = ((drive->media.capacity_total-1) >> 16) & 0xFF;
            drive->cmd[8] = ((drive->media.capacity_total-1) >> 8) & 0xFF;
            drive->cmd[9] = (drive->media.capacity_total-1) & 0xFF;
      }
      if ((drive->err=drive->cmd.transport(READ,NULL,0)))
            {sperror ("PLEXTOR_START_FETE",drive->err);return drive->err;}
      return 0;
}

//*********************************//
//
//  end scan commands
//
//*********************************//

int plextor_end_scan(drive_info* drive) {
      drive->cmd_clear();
      drive->cmd[0] = CMP_PLEX_QCHECK; //0xEA;
      drive->cmd[1] = PLEX_QCHECK_END; //0x17;
      if ((drive->err=drive->cmd.transport(READ,NULL,0)))
            {sperror ("PLEXTOR_END_SCAN",drive->err); return drive->err;}
      return 0;
}

int plextor_end_fete(drive_info* drive) {
      drive->cmd_clear();
      drive->cmd[0] = CMD_PLEX_SCAN_TA_FETE; // 0xF3;
      drive->cmd[1] = 0x1F;
      drive->cmd[2] = 0x04;
      if ((drive->err=drive->cmd.transport(READ,NULL,0)))
            {sperror ("PLEXTOR_END_FETE",drive->err); return drive->err;}
      return 0;
}

//*********************************//
//
//  test data readout commands 
//
//*********************************//

int plextor_read_cd_error_info(drive_info* drive, int* BLER,
      int* E11, int* E21, int* E31, int* E12, int* E22, int* E32)
{
      drive->cmd_clear();
      drive->cmd[0] = CMP_PLEX_QCHECK; //0xEA;
      drive->cmd[1] = PLEX_QCHECK_READOUT; // 0x16;
      drive->cmd[2] = 0x01;
      drive->cmd[10]= 0x1A;
      if ((drive->err=drive->cmd.transport(READ,drive->rd_buf,0x1A)))
            {sperror ("PLEXTOR_READ_CD_ERROR_INFO", drive->err);return drive->err;}

//    int E11, E21, E31, E12, E22, E32, BLER;
      *BLER = swap2(drive->rd_buf+10);
      *E31 = swap2(drive->rd_buf+12);
      *E21 = swap2(drive->rd_buf+14);
      *E11 = swap2(drive->rd_buf+16);
      // ??? swap2(drive->rd_buf+18);
      *E32 = swap2(drive->rd_buf+20);
      *E22 = swap2(drive->rd_buf+22);
      *E12 = swap2(drive->rd_buf+24);

      int C1,C2,CU;
      C1 = *BLER;
      C2 = *E22;
      CU = *E32;

#ifdef _debug_cx
      int i;
      for (i=0x00; i<0x06; i++) printf("%02X ", drive->rd_buf[i] & 0xFF); printf("| ");
      for (i=0x06; i<0x0A; i++) printf("%02X ", drive->rd_buf[i] & 0xFF); printf("| ");
      for (i=0x0A; i<0x1A; i+=2) { if (swap2(drive->rd_buf+i)) printf("%5d ", swap2(drive->rd_buf+i)); else printf("_____ "); }
      printf("| ");
      printf("%3d C1| %3d C2| %3d CU\n", C1, C2, CU);
#endif
      return 0;
}

int plextor_read_pi_info(drive_info* drive) {
      drive->cmd_clear();
      drive->cmd[0] = CMP_PLEX_QCHECK; //0xEA;
      drive->cmd[1] = PLEX_QCHECK_READOUT; // 0x16;
      drive->cmd[2] = 0x00;
      drive->cmd[10]= 0x34;
      if ((drive->err=drive->cmd.transport(READ,drive->rd_buf,0x34)))
            {sperror ("PLEXTOR_READ_PI",drive->err); return drive->err;}
/*
      printf("READ PI:");
      for (int i=0; i<0x34; i++) {
            if (!(i%0x10)) printf("\n");
            printf(" %02X",drive->rd_buf[i] & 0xFF);
      }
      printf("\n");

*/
#ifdef _debug_pi
      int i;
/*
//    printf("\n| ");
      for (i=0x00; i<0x34; i++) {
            if (!(i%0x20))printf("\n| ");
            printf("%02X ", drive->rd_buf[i] & 0xFF);
      }
*/
      for (i=0x10; i<0x34; i+=4) {
            if (!(i%0x10))printf("|");
            if (swap4(drive->rd_buf+i))
                  printf(" %8d ", swap4(drive->rd_buf+i));
            else
                  printf(" ________ ");
      }
      printf("\n");
#endif
      return 0;
}

int plextor_read_jb_info(drive_info* drive) {
      drive->cmd_clear();
      drive->cmd[0] = CMP_PLEX_QCHECK; //0xEA;
      drive->cmd[1] = PLEX_QCHECK_READOUT; // 0x16;
      drive->cmd[2] = 0x10;
      drive->cmd[10] = 0x10;
      if ((drive->err=drive->cmd.transport(READ,drive->rd_buf,0x10)))
            {sperror ("PLEXTOR_READ_JB",drive->err); return drive->err;}
#ifdef _debug_jb
      int i;
      printf("\n| J/B data: | ");
      for (i=0x00; i<0x10; i++) printf("%02X ", drive->rd_buf[i] & 0xFF);
      printf("|\n");
#endif
      return 0;
}


int plextor_cx_do_one_interval(drive_info* drive, int* lba, int* BLER,
      int* E11, int* E21, int* E31, int* E12, int* E22, int* E32)
{
      for (int i=0; (i<5) && *lba<drive->media.capacity; i++) {
            if (*lba + 15 < drive->media.capacity)
                  read_cd(drive, *lba, 15);
            else
                  read_cd(drive, *lba, drive->media.capacity - *lba - 1);
            *lba+=15;
      }
      plextor_read_cd_error_info(drive, BLER, E11, E21, E31, E12, E22, E32);
//    *lba = 
      return 0;
}

int plextor_pif_do_one_ecc_block(drive_info* drive, int* lba, int* pif) {
      read_one_ecc_block(drive, *lba);
      *lba+= 0x10;
      plextor_read_pi_info(drive);
//    *lba = swap4(drive->rd_buf+0x06) - 0x00030000;
      *pif = swap4(drive->rd_buf+0x24);
      return 0;
}

//int plextor_pisum8_do_eight_ecc_blocks(drive_info* drive, int* lba, int* pie, int* pif) {
int plextor_pisum8_do_eight_ecc_blocks(drive_info* drive, int* lba, int* pie) {
      for (int i=0;i<8;i++) {
            if ((drive->err = read_one_ecc_block(drive, *lba))) i = 8;
            *lba+= 0x10;
      }
      plextor_read_pi_info(drive);
//    *lba = swap4(drive->rd_buf+0x06) - 0x00030000;
      *pie = swap4(drive->rd_buf+0x24);
//    *poe = swap4(drive->rd_buf+0x28);
//    *pif = 0;
      return 0;
}

int plextor_jitterbeta_DVD_do_16_ecc_blocks(drive_info* drive, int* lba, int* jitter, short int* beta) {
      short int*  i16_beta;
      char c;
      for (int i=0;i<16;i++) {
            int j = read_one_ecc_block(drive, *lba);
            if (j == COMMAND_FAILED) i=16;
            *lba+= 0x10;
      }
      plextor_read_jb_info(drive);
      c = drive->rd_buf[10]; drive->rd_buf[10] = drive->rd_buf[11]; drive->rd_buf[11] = c;
      i16_beta = (short int*)(drive->rd_buf+10);
      if (drive->dev_ID == PLEXTOR_760) {
            *beta = *i16_beta;
            *jitter = 3200 - 2*swap2(drive->rd_buf+12);
      } else {
            *beta = *i16_beta;
//          *jitter = 3000 - 2*swap2(drive->rd_buf+12);
            *jitter = 3200 - (int)(2.4*swap2(drive->rd_buf+12));
      }
      return (!(drive->rd_buf[2]));
}

int plextor_jitterbeta_do_one_cd_interval(drive_info* drive, int* lba, int* jitter, short int* beta, int int_len) {
      short int*  i16_beta;
      char c;
      int blocks = int_len / 15;
      int rest = int_len % 15;
      for (int i=0;i<blocks;i++) {
            int j = read_cd(drive, *lba, 15);
            *lba+= 0x0F;
            if (j == COMMAND_FAILED) i++;
      }
      if (rest) {
            read_cd(drive, *lba, rest);
      }
      plextor_read_jb_info(drive);
      c = drive->rd_buf[10]; drive->rd_buf[10] = drive->rd_buf[11]; drive->rd_buf[11] = c;
      i16_beta = (short int*)(drive->rd_buf+10);
      if (drive->dev_ID == PLEXTOR_760) {
            *beta = *i16_beta;
            *jitter = 4800 - 2*swap2(drive->rd_buf+12);
      } else {
            *beta = *i16_beta;
//          *jitter = 3200 - 2*swap2(drive->rd_buf+12);
            *jitter = 3600 - (int)(2.4*swap2(drive->rd_buf+12));
      }
      return (!(drive->rd_buf[2]));
}

int plextor_read_fete(drive_info* drive) {
      drive->cmd_clear();
      drive->cmd[0] = CMD_PLEX_FETE_READOUT; // 0xF5;
      drive->cmd[3] = 0x0C;
      drive->cmd[9] = 0xCE;
      if ((drive->err=drive->cmd.transport(READ,drive->rd_buf,0xCE)))
            {sperror ("PLEXTOR_FETE_READOUT",drive->err); return drive->err;}
/*
      for (int i=0; i<0xCE; i++) {
            if (!(i % 0x20)) printf("\n");
            printf("%02X ",drive->rd_buf[i] & 0xFF);
      }
      printf("\n");
*/
      return 0;
}
//*********************************//
//
//  tests' algorythms 
//
//*********************************//

int init_TA_response_analysis(int* dest_pit, int* dest_land, int len) {
      memset(dest_pit, 0, 4*len);
      memset(dest_land, 0, 4*len);
      return 0;
}

int build_TA_histogram_px716(char* response_data, int* dest_pit, int* dest_land, int len) {
      int* dest[] = { dest_land, dest_pit };
      int count = swap2(response_data+2);
//    printf("PX-716 Histogram... %d\n",count);
      int idx=28;
      int v, pit;
      for (int i=0;i<count;i++) {
            v = swap2u(response_data+idx);
            pit = !!(v & 0x8000);
            v &=~0x8000;
            dest[pit][min(v, len-1)]++;
            idx+=2;
      }
      return 0;
}

int build_TA_histogram_px755(char* response_data, int* dest_pit, int* dest_land, int len, int dt) { //, int spd) {
      int* dest[] = { dest_land, dest_pit };
      int count = swap2(response_data+2);
//    printf("PX-755+ Histogram... %d\n", count);
      int idx=28;
      int v, pit;
      for (int i=0;i<count;i++) {
            v = swap2u(response_data+idx);
            pit = !!(v & 0x8000);
            v &=~0x8000;
            if (dt & DISC_DVDplus)
                  dest[pit][min( (int)(v*1.45), len-1)]++; // DVD+R(W)
            else
                  dest[pit][min( (int)(v*1.21), len-1)]++; // DVD-R(W)
            idx+=2;
      }
      return 0;
}

int evaluate_histogramme(int* src_pit, int* src_land, int** peaks, int** mins) {
      int i, j1, j2;
      int local_max = 0;
      int next_peak = 0;
      int peak_found= 0;
      int* src[] = { src_pit, src_land };

      for (int k=0;k<2;k++) {
            j1=0; j2=0; local_max = 0;
            for (i=40;i<330;i++) {
                  if (src[k][i-1] <= src[k][i] && src[k][i+1] <= src[k][i] && src[k][i] > 20 && src[k][i] > local_max) {
                        peaks[k][j1] = i;
                        local_max = src[k][i];
                        next_peak = 1;
                  } else if (peak_found)
                  if (/*src[k][i-3] >= src[k][i-1] && src[k][i-2] > src[k][i-1] && */
                      src[k][i-1] > src[k][i] && src[k][i+1] >= src[k][i]) {
                        mins[k][j2] = i;
                        if (j2<13) j2++;
                        peak_found = 0;
                  }

                  if (local_max > 2*src[k][i]) {
                        local_max = 2*src[k][i];
                        if (next_peak) {
                              next_peak = 0;
                              if (j1<13) {
                                    j1++;
                                    peak_found=1;
                              //    printf("%4d",i);
                              }
                        }
                  }
            }

            int min_count = j2;
            for (i=0;i<min_count;i++) {
                  int start = (i?mins[k][i-1]:0);
                  int end   = mins[k][i];
                  int sum   = 0;
                  int partsum=0;
                  int j;
                  for (j=start;j<end;sum+=src[k][j++]);
                  for (j=start;partsum<sum/2;partsum+=src[k][j++]);
                  peaks[k][i] = (peaks[k][i] + j-1)/2;
            }
      }
      return 0;
}

void ScanThread::plextor_scan_TA () {
      char* TEST="DVD TA";
      post_signal(event_test_init,(void*)TEST);

      block_data block;
      block.test=TEST_DVD_TA;
      block.err_total=0; block.err_max=0; block.err_cur=0; block.err_avg=0.0;
      block.blocks = drive->media.capacity; block.idx=0;

      talayers = drive->media.layers;
      printf("Start PLEXTOR TA test on %d layers\n",drive->media.layers);
      int i, r, m,j;
      float sum;
      unsigned char scan_cmd[6][2] = {
            { 0x04, 0x00 }, { 0x10, 0x00 }, { 0x20, 0x00 },
            { 0xFA, 0x28 }, { 0xEA, 0x28 }, { 0xDE, 0x28 }};
      char* scan_txt[] = {
            "#running TA on L0 inner zone ", "#running TA on L0 middle zone", "#running TA on L0 outer zone ",
            "#running TA on L1 inner zone ", "#running TA on L1 middle zone", "#running TA on L1 outer zone "
      };
      int ta_response_pit[6][512]; int ta_response_land[6][512];
      int peaks_lands[15], peaks_pits[15]; int mins_lands[15], mins_pits[15];
      int* peaks[] = { peaks_pits, peaks_lands };
      int* mins[]  = { mins_pits+1, mins_lands+1 };
      for (int pass=0;(pass<3*drive->media.layers) && (!skip());pass++) {
            printf(scan_txt[pass]);
            init_TA_response_analysis(ta_response_pit[pass], ta_response_land[pass], 512);
            for (i=0;i<9;i++) {
                  drive->cmd_clear();
                  drive->cmd[0] = CMD_PLEX_SCAN_TA_FETE; // 0xF3;
                  drive->cmd[1] = 0x1F;
                  drive->cmd[2] = 0x23;
                  drive->cmd[3] = 0x00;
                  drive->cmd[4] = 0x00;
                  drive->cmd[5] = scan_cmd[pass][0];
                  drive->cmd[6] = scan_cmd[pass][1];
                  drive->cmd[7] = i<<4;
                  drive->cmd[8] = 0xFF;
                  drive->cmd[9] = 0xFE;
                  drive->cmd[10] = 0x04*!i;
                  drive->cmd[11] = 0x00;
                  drive->cmd.transport(READ, drive->rd_buf, 65534);
                  printf(".");
                  if (drive->dev_ID == PLEXTOR_716)
                        build_TA_histogram_px716(drive->rd_buf, ta_response_pit[pass], ta_response_land[pass], 512);
                  else
                        build_TA_histogram_px755(drive->rd_buf, ta_response_pit[pass], ta_response_land[pass], 512, drive->media.disc_type);
                        // drive->parms.scan_speed_dvd);
            }  //////
            printf("#\n");
            mins_lands[0] = 0; mins_pits[0]=0;

            int p0,p1;
            int l0,l1;
            for  (j=0;j<400;j++) {
                  block.block=pass;
                  block.idx=j;
                  if ((j>40) && (j<360)) {
                        p0=ta_response_pit[pass][j-1]; p1=ta_response_pit[pass][j+1];
                        l0=ta_response_land[pass][j-1]; l1=ta_response_land[pass][j+1];
                        if ( ta_response_pit[pass][j] == 0 )
                              if ((p0>0) && (p1>0)) ta_response_pit[pass][j] = (p0+p1)/2;
                        if ( ta_response_land[pass][j] == 0 )
                              if ((l0>0) && (l1>0)) ta_response_land[pass][j] = (l0+l1)/2;
                  }
                  block.pit=ta_response_pit[pass][j];
                  block.land=ta_response_land[pass][j];
                  event_block_done(event_block_done_ta, block);
            }

//          }  /////

            evaluate_histogramme(ta_response_pit[pass], ta_response_land[pass], peaks, mins);

            printf("#\n#  peak shift pits : ");
            sum=0;
            for (m=0;m<10;m++) {
                  r = (int)((float)peaks_pits[m] - 21.5454 * ((m<9)?m:11) - 64); sum+=sqrt(abs(r));
                  printf("%4d", r);
            }
            printf("# sum %f \n",sum);
            printf("#  peak shift lands: ");

            sum=0;
            for (m=0;m<10;m++) {
                  r = (int)((float)peaks_lands[m] - 21.5454 * ((m<9)?m:11) - 64); sum+=sqrt(abs(r));
                  printf("%4d", r);
            }
            printf("# sum %f \n",sum);
      }
      printf("TA test finished\n");
        plextor_end_scan(drive);
}

scan_commands commands_plextor_list = {
      plextor_start_cx,    plextor_cx_do_one_interval,                plextor_end_scan,
      plextor_start_jb_CD,       plextor_jitterbeta_do_one_cd_interval,   plextor_end_scan,
      plextor_start_pie_poe,     plextor_pisum8_do_eight_ecc_blocks,        plextor_end_scan,
      plextor_start_pif,         plextor_pif_do_one_ecc_block,        plextor_end_scan,
      plextor_start_pie_poe,     plextor_pisum8_do_eight_ecc_blocks,        plextor_end_scan,
      plextor_start_jb_DVD,      plextor_jitterbeta_DVD_do_16_ecc_blocks, plextor_end_scan,
};

scan_commands commands_plextor() { return commands_plextor_list; }

Generated by  Doxygen 1.6.0   Back to index