All times are UTC - 5 hours [ DST ]


Forum rules


Please do not post questions about data recovery cases here (use this forum instead). This forum is for topics on finding new ways to recover data. Accessing firmware, writing programs, reading bits off the platter, recovering data from dust...



Post new topic Reply to topic  [ 12 posts ] 
Author Message
 Post subject: PIC18F4550 microchip interface to a HD
PostPosted: May 27th, 2013, 23:45 
Offline

Joined: May 27th, 2013, 21:17
Posts: 5
Location: Minnesota USA
First post at HDDGURU.

I am trying to interface a Microchip PIC18F4550 to a Maxtor D540X-4K.
I have been following the guidelines at IDE Hard Disk experiments and Schematic.

Presently I can communicate with the HD by use of the following commands:
Status
Error
E0h Standby mode
E6h Sleep
E1h Spin up to Idle
3F7h Drive Address: Master or Slave
Reset

The above are 8 bit data reads and seem to work OK however so far I haven't been able to read full 16 bit data as all the highbytes read 0.
Only the lowbytes are seem to read OK.

Why doesn't the following Basic code read the upper bytes of Identify Device?

Norm
Code:
' /CS0  /CS1  A2 A1 A0  Addr.   Read Function       Write Function
'   0     1    1  1  1   1F7    Status Register     Command Register
  Low HD_CS0
  High HD_CS1
  High HD_A2
  High HD_A1
  High HD_A0
  Output PORTD
  Output PORTB
  yHD_DATA_HIGHBYTE = $1F7.HIGHBYTE
  yHD_DATA_LOWBYTE = $1F7.LOWBYTE
  GoSub subWRITE_PULSE
  yHD_DATA_HIGHBYTE = $EC.HIGHBYTE '$EC = get 255 BYTE ASCII drive info
  yHD_DATA_LOWBYTE = $EC.LOWBYTE
  GoSub subWRITE_PULSE

  DelayUS 400

  'SET PARAMETERS FOR DATA REGISTER
'  /CS0  /CS1  A2 A1 A0  Addr.   Read Function       Write Function
'    0     1    0  0  0   1F0    Data Register       Data Register
  Low HD_CS0
  High HD_CS1
  Low HD_A2
  Low HD_A1
  Low HD_A0
  Output PORTD
  Output PORTB
  yHD_DATA_HIGHBYTE = $1F0.HIGHBYTE '$1F0 = SET TO Data Register
  yHD_DATA_LOWBYTE = $1F0.LOWBYTE
  GoSub subWRITE_PULSE

  Input PORTD
  Input PORTB
'  DelayUS 400 'Delay minimum of 25 ns
  For i = 0 To 255
    GoSub subREAD_PULSE
    If i <= 49 Then
      wTEMP.HighByte = yHD_DATA_HIGHBYTE
      wTEMP.LowByte = yHD_DATA_LOWBYTE
      wBUFFER_ARRAY50[i] = wTEMP    'only 0 to 49 is used
    EndIf
  Next

  For i = 0 To 49    'only 0 to 49 is used
    wTEMP = wBUFFER_ARRAY50[i]
    HSerOut[" READ wBUFFER_ARRAY50[",Dec3 i,"] = %",Bin8 wTEMP.HighByte,"'",Bin8 wTEMP.LowByte," = ",Dec3 wTEMP,13]
    HSerOut[" READ wBUFFER_ARRAY50[",Dec3 i,"] = ",Dec3 wTEMP.HighByte,"'",DEC3 wTEMP.LowByte," = ",Dec3 wTEMP,13]
    HSerOut[" ",13]
  Next

  HSerOut[Dec3 wBUFFER_ARRAY50[0]," = Configuration/ID Word",13]
  HSerOut[Dec3 wBUFFER_ARRAY50[1]," = Number of fixed cylinders",13]
  HSerOut[Dec3 wBUFFER_ARRAY50[2]," = No. of removable cylinders",13]
  HSerOut[Dec3 wBUFFER_ARRAY50[3]," = No. of heads",13]
  HSerOut[Dec3 wBUFFER_ARRAY50[4]," = No. of unformatted bytes per physical track",13]
  HSerOut[Dec3 wBUFFER_ARRAY50[5]," = No. of unformatted bytes per sector",13]
  HSerOut[Dec3 wBUFFER_ARRAY50[6]," = No. of phyical sectors per Tracks",13]
  HSerOut[Dec3 wBUFFER_ARRAY50[7]," = No. of bytes in the inter-sector gaps",13]
  HSerOut[Dec3 wBUFFER_ARRAY50[8]," = No. of bytes in the sync fields",13]


Top
 Profile  
 
 Post subject: Re: PIC18F4550 microchip interface to a HD
PostPosted: May 28th, 2013, 20:12 
Offline

Joined: May 6th, 2008, 22:53
Posts: 2138
Location: England
Hi,

Too little info and too little time for me to write a full reply, unfortunately. Here are a couple of observations anyway...

It seems like you aren't using normal PIC chips programmed yourself from scratch, but that looks like PICAXE Basic, which I don't use (I design things using different microcontrollers, programming mainly in C). Some of the sub-routines used by your code seem to be missing from the listing which you gave (or perhaps they are PICAXE Basic intrinsics?), but it appears that you are trying to read PORTD as your high byte. That won't do anything useful with the schematic which you linked, as port D on the PIC in the schematic isn't connected to anything!

If you are using exactly that schematic which you linked, then make sure you understand the behaviour of that 4014 shift register, and how you need to use it, since that is how you access the high byte to/from the IDE interface, and that is the part which you say is not working as you expect. (As shown in that diagram it's not a very robust design and the schematic is missing several components to improve its reliability, but that's a whole different discussion.)

If you have an oscilloscope or logic analyser, then you can use that to increase your speed of understanding how to control that 4014 from the PIC using (PICAXE?) Basic, by monitoring the relevant signals. Use some simple code to control that component first, before trying to interface to the drive.

If your chosen model of PIC (which is different from the one in the schematic) has got 8 more unused GPIO pins, in addition to PortB (which is currently being used for the low byte of the interface), then you may find it easier to change your schematic (and your code) to eliminate the use of the 4014 and drive the high byte directly from the PIC.

That's all I can suggest with the code as given, and with limited time. If I had it in front of me with time to work on it, I'd be looking at the full code, looking at how you are driving the 4014 (probably attach a little logic analyser), but actually try to eliminate that chip from the design completely - strictly it is not compatible with the signal levels used by the IDE interface. A different shift register could be used, but you'd still need to understand (and likely change) whatever Basic code you use to drive that replacement part.

Good luck with your project :)

[P.S. I asked for this thread to be moved to the R&D section of the forum, as I think it fits better there than in the usual data recovery section - if the moderator agrees with me, don't be surprised if it magically moves. :) ]

[P.P.S. I have a dim memory that some (older?) drives can be switched into 8-bit mode via a Set Features command. If you can't fix your design to get the high byte working, that might be a temporary solution for you to investigate, depending on what you are trying to achieve.]


Top
 Profile  
 
 Post subject: Re: PIC18F4550 microchip interface to a HD
PostPosted: May 28th, 2013, 22:36 
Offline

Joined: May 27th, 2013, 21:17
Posts: 5
Location: Minnesota USA
The Basic code provided above is Proton PICBASIC.
I am using a 40 pin PIC18F4550 for use of PORTD in place of the 4014 shift register.
The PIC18f4550 is also 5 volt as required to interface to the HD.

A bit lengthy but the following is full Proton PICBASIC code used for HD command Identify Device:
Code:
  Device = 18F4550

  Config_Start
    PLLDIV = 1   ;No prescale (4 MHz oscillator input drives PLL directly)
    CPUDIV = OSC1_PLL2   ;[Primary Oscillator Src: /1][96 MHz PLL Src: /2]
    USBDIV = 1   ;USB clock source comes directly from the primary oscillator block with no postscale
    FOSC = XT_XT   ;XT oscillator (XT)
    FCMEN = OFF   ;Fail-Safe Clock Monitor disabled
    IESO = OFF   ;Oscillator Switchover mode disabled
    PWRT = On   ;PWRT enabled
    BOR = On   ;Brown-out Reset enabled in hardware only (SBOREN is disabled)
    BORV = 3   ;Minimum setting
    VREGEN = OFF   ;USB voltage regulator disabled
    WDT = OFF   ;WDT disabled (control is placed on the SWDTEN bit)
    WDTPS = 32768   ;1:32768
    CCP2MX = On   ;CCP2 input/output is multiplexed with RC1
    PBADEN = OFF   ;PORTB<4:0> pins are configured as digital I/O on Reset
    LPT1OSC = OFF   ;Timer1 configured for higher power operation
    MCLRE = On   ;MCLR pin enabled; RE3 input pin disabled
    STVREN = On   ;Stack full/underflow will cause Reset
    LVP = OFF   ;Single-Supply ICSP disabled
    ICPRT = OFF   ;ICPORT disabled
    XINST = OFF   ;Instruction set extension and Indexed Addressing mode disabled (Legacy mode)
    Debug = OFF   ;Background debugger disabled, RB6 and RB7 configured as general purpose I/O pins
    CP0 = OFF   ;Block 0 (000800-001FFFh) is not code-protected
    CP1 = OFF   ;Block 1 (002000-003FFFh) is not code-protected
    CP2 = OFF   ;Block 2 (004000-005FFFh) is not code-protected
    CP3 = OFF   ;Block 3 (006000-007FFFh) is not code-protected
    CPB = OFF   ;Boot block (000000-0007FFh) is not code-protected
    CPD = OFF   ;Data EEPROM is not code-protected
    WRT0 = OFF   ;Block 0 (000800-001FFFh) is not write-protected
    WRT1 = OFF   ;Block 1 (002000-003FFFh) is not write-protected
    WRT2 = OFF   ;Block 2 (004000-005FFFh) is not write-protected
    WRT3 = OFF   ;Block 3 (006000-007FFFh) is not write-protected
    WRTC = OFF   ;Configuration registers (300000-3000FFh) are not write-protected
    WRTB = OFF   ;Boot block (000000-0007FFh) is not write-protected
    WRTD = OFF   ;Data EEPROM is not write-protected
    EBTR0 = OFF   ;Block 0 (000800-001FFFh) is not protected from table reads executed in other blocks
    EBTR1 = OFF   ;Block 1 (002000-003FFFh) is not protected from table reads executed in other blocks
    EBTR2 = OFF   ;Block 2 (004000-005FFFh) is not protected from table reads executed in other blocks
    EBTR3 = OFF   ;Block 3 (006000-007FFFh) is not protected from table reads executed in other blocks
    EBTRB = OFF   ;Boot block (000000-0007FFh) is not protected from table reads executed in other blocks
  Config_End

  Optimiser_Level = 3
  Xtal = 4

  'PIC18F4550
'  Digital input  RC5 and RC4 are only available as port pins when the USB module is disabled (UCON<3> = 0)
'  Unlike other PORTC pins, RC4 And RC5 do Not have
'  TRISC bits associated with them. As digital ports, they
'  can only function As digital inputs.

  Clear

  VARS_BOOKMARK_START:
  Symbol TRUE = 1
  Symbol FALSE = 0
  Symbol sLED = PORTE.2

  Symbol HD_RESET_LOW = PORTA.3
  High HD_RESET_LOW

  'ADDRESS LINES
  Symbol HD_A0 = PORTC.1
  Symbol HD_A1 = PORTC.0
  Symbol HD_A2 = PORTA.5

  'SELECTION SIGNALS
'  Symbol HD_CS0 = PORTC.3  'C.3 NOT OK CAUSE USB PIC18F4550
  Symbol HD_CS0 = PORTE.0
  Symbol HD_CS1 = PORTC.2

'  Symbol HD_IOWRITE = PORTC.5   C.5 NOT OK CAUSE USB PIC18F4550
  Symbol HD_IOWRITE = PORTA.1   'PORTA.1 = PIC 3 = YELL = IDE 23
  Low HD_IOWRITE

'  Symbol HD_IOREAD = PORTC.4   C.4 NOT OK CAUSE USB PIC18F4550
  Symbol HD_IOREAD = PORTA.0
  High HD_IOREAD

  Symbol yHD_DATA_LOWBYTE = PORTB
  Symbol yHD_DATA_HIGHBYTE = PORTD

  Dim wBUFFER_ARRAY50[50] As Byte
  Dim yRX_ARRAY100[100] As Byte
  Dim yREAD_PT As Byte
  yREAD_PT = 0
  Dim yWRITE_PT As Byte
  yWRITE_PT = 0
  Dim yRX As Byte
  Dim i As Byte
  Dim x As Byte
  Dim y As Byte
  Dim yCNT1 As Byte
  Dim ySTATUS As Byte
  Dim yERROR As Byte
  Dim yACTIVE As Byte
  Dim wTEMP As Word
  Dim yTEMP As Byte
  Dim iERRORS As Bit
  Dim sSTRING40 As STRING * 40
  Dim SERIAL_NO_ARRAY21[21] As Byte ' Create a 5 element array

  VARS_BOOKMARK_END:

  ADCON1 = %00001111 'A0-A12 DIGITAL
  PIE1.7 = 0 'Disables the Streaming Parallel Port Interrupt PIC18F4550 PORTD

  '********************
  Declare Hserial_Baud 2400  'INVERT PIC TX WITH A P CHANNEL,  INVERT PIC RX WITH AN N CHANNEL
  INTCON = %11000000 'Enables all unmasked interrupts
  PIE1.5 = 1 'Enables the USART receive interrupt
  TXSTA = %00100100 '%xx1xxxxx = Transmit Enabled  '%xxxxx1xx = BRGH HIGH SPEED
  RCSTA = %10010000 '%1xxxxxxx = Enable serial   '%xxx1xxxx = Enables continuous receive
'  SPBRG = 103 '103 = 2400 AT 4 MHz AT BRGH HIGH SPEED
  SPBRG = 128 '128=AVG 123=MIN/134=MAX = 2400 AT 4.9152 MHz AT BRGH HIGH SPEED
  PIR1.5 = 0  'CLEAR UART RX INTERRUPT

  On_Hardware_Interrupt GoTo HIGH_INTERRUPT_ROUTINE

  TRISA.5 = 0
  TRISA.4 = 0
  TRISA.3 = 0
  TRISA.2 = 0
  TRISA.1 = 0
  TRISA.0 = 0
  TRISB=%00000000 'DATA BUS BOTH READ AND WRITE
  TRISC=%10000000 'C.7 USART RX    NO C.3 CAUSE USB PIC18F4550
  TRISD=%11111111
  TRISE.0 = 0
  TRISE.1 = 0
  TRISE.2 = 0

  GoTo START

  '********** ASSEMBLY HARDWARE Interrupt **********
  HIGH_INTERRUPT_ROUTINE:
  Repeat
    If yWRITE_PT < 99 Then
      Inc yWRITE_PT
    Else
      yWRITE_PT = 0
    EndIf
    yRX_ARRAY100[yWRITE_PT] = RCREG   'Get a character from the USART receiver
'    HSerOut[" INT = ",yRX_ARRAY100[yWRITE_PT],13]
  Until PIR1.5 = 0  'RX BUFFER IS EMPTY
  Retfie Fast
  '********** END ASSEMBLY HARDWARE Interrupt **********

  '**************************
  subWRITE_PULSE:
  DelayUS 400 '200 OK 100 NOT 'Delay minimum of 25 ns
  High HD_IOWRITE 'RISING EDGE CLOCKS DATA TO THE DRIVE
  DelayUS 800 'Delay minimum of 80 ns
  Low HD_IOWRITE
  Return

  '**************************
  subREAD_PULSE:
  Input PORTB
  Input PORTD
  DelayUS 400  'Delay minimum of 25 ns
  Low HD_IOREAD 'FALLING EDGE CLOCKS DATA TO THE DRIVE
  DelayUS 800 'Delay minimum of 80 ns
  High HD_IOREAD
  Return

  '**************************
  subREAD_STATUS:
' /CS0  /CS1  A2 A1 A0  Addr.   Read Function       Write Function
'   0     1    1  1  1   1F7    Status Register     Command Register
  Low HD_CS0
  High HD_CS1
  High HD_A2
  High HD_A1
  High HD_A0
  Output PORTD
  Output PORTB
  yHD_DATA_HIGHBYTE = $1F7.HIGHBYTE '$1F7 = Status Register / Command Register
  yHD_DATA_LOWBYTE = $1F7.LOWBYTE           'READ PULSE         'WRITE PULSE
  GoSub subWRITE_PULSE

  GoSub subREAD_PULSE 'Status Register
  ySTATUS = yHD_DATA_LOWBYTE

  HSerOut["DO subREAD_STATUS %",Bin8 ySTATUS," ",Dec ySTATUS,":",13]
  iERRORS = FALSE 'PRESET
  If ySTATUS.7 = 1 Then
    HSerOut["BIT 7 = DRIVE BUSY, IGNORING ALL OTHER ERROR ROUTINES ***",13]
    iERRORS = TRUE
  Else
    If ySTATUS.6 = 0 Then
      HSerOut[" BIT 6 = DRIVE NOT UP TO SPEED AND READY FOR CMD ***",13]
      iERRORS = TRUE
    EndIf
    If ySTATUS.5 = 1 Then
      HSerOut[" BIT 5 = DRIVE WRITE FAULT ***",13]
      iERRORS = TRUE
    EndIf
    If ySTATUS.4 = 0 Then
      HSerOut[" BIT 4 = DRIVE SEEK NOT COMPLETE ***",13]
      iERRORS = TRUE
    EndIf
    If ySTATUS.3 = 0 Then
      HSerOut[" BIT 3 = DRIVE NOT READY FOR DATA TRANSFER ***",13]
      iERRORS = TRUE
    EndIf
    If ySTATUS.2 = 1 Then
      HSerOut[" BIT 2 = DRIVE CORRECTED DATA ***",13]
      iERRORS = TRUE
    EndIf
    If ySTATUS.1 = 1 Then
      HSerOut[" BIT 1 = DRIVE RPM TICK ***",13]
      iERRORS = TRUE
    EndIf
    If ySTATUS.0 = 1 Then
      HSerOut[" BIT 0 = ERROR. DO subREAD_ERROR ***",13]
      iERRORS = TRUE
      GoSub subREAD_ERROR
    EndIf
  EndIf
  If iERRORS = FALSE Then
    HSerOut[" NO ERRORS",13]
  EndIf
  HSerOut["  DID subREAD_STATUS",13]
  HSerOut[" ",13]
  Return

  '**************************
  subREAD_ERROR:
' /CS0  /CS1  A2 A1 A0  Addr.   Read Function       Write Function
'   0     1    0  0  1   1F1    Error Register      (Write Precomp Reg.)
  Low HD_CS0
  High HD_CS1
  Low HD_A2
  Low HD_A1
  High HD_A0
  Output PORTD
  Output PORTB
  yHD_DATA_HIGHBYTE = $1F1.HIGHBYTE '$1F1 = Error Register
  yHD_DATA_LOWBYTE = $1F1.LOWBYTE
  GoSub subWRITE_PULSE
  GoSub subREAD_PULSE
  yERROR = yHD_DATA_LOWBYTE
  HSerOut["DO subREAD_ERROR %",Bin8 yERROR," ",Dec yERROR,":",13]
  iERRORS = FALSE 'PRESET
  If yERROR.7 = 1 Then
    HSerOut[" BIT 7 = BAD BLOCK ***",13]
    iERRORS = TRUE
  EndIf
  If yERROR.6 = 1 Then
    HSerOut[" BIT 6 = UNCORRECTABLE DATA ERROR ***",13]
    iERRORS = TRUE
  EndIf
  If yERROR.4 = 1 Then
    HSerOut[" BIT 4 = SECTOR ID NOT FOUND ***",13]
    iERRORS = TRUE
  EndIf
  If yERROR.2 = 1 Then
    HSerOut[" BIT 2 = DRIVE STATUS ERROR OR INVALID COMMAND ***",13]
    iERRORS = TRUE
  EndIf
  If yERROR.1 = 1 Then
    HSerOut[" BIT 1 = TRACK 0 NOT FOUND WHEN RECALIBRATING ***",13]
    iERRORS = TRUE
  EndIf
  If iERRORS = FALSE Then
    HSerOut[" NO ERRORS !!!",13]
  EndIf
  HSerOut["  DID subREAD_ERROR",13]
  HSerOut[" ",13]
  Return

  '**************************
  subWAIT_TILL_STATUS_LESS_THAN128:
  yCNT1 = 5
  HSerOut["DO subWAIT_TILL_STATUS_LESS_THAN128",13]
  Repeat
    GoSub subREAD_STATUS
    Dec yCNT1
    If ySTATUS < 128 Then
      yCNT1 = 100 'ESCAPE
    Else
      HSerOut["DOING subWAIT_TILL_STATUS_LESS_THAN128 ",Dec yCNT1,13]
    EndIf
    DelayMS 100
  Until  yCNT1 = 0  Or yCNT1 = 100
  If yCNT1 = 0 Then
    HSerOut[" subWAIT_TILL_STATUS_LESS_THAN128 TIMED OUT ***",13]
  Else
    HSerOut[" subWAIT_TILL_STATUS_LESS_THAN128 OK !!!",13]
  EndIf
  HSerOut["  DID subWAIT_TILL_STATUS_LESS_THAN128",13]
  HSerOut[" ",13]
  Return

  '**************************
  subGET_DRIV_INFO:
  HSerOut["DO subGET_DRIV_INFO",13] 'DRIVE CAN BE IN SLEEP MODE?
' /CS0  /CS1  A2 A1 A0  Addr.   Read Function       Write Function
'   0     1    1  1  1   1F7    Status Register     Command Register
  Low HD_CS0
  High HD_CS1
  High HD_A2
  High HD_A1
  High HD_A0
  Output PORTD
  Output PORTB
  yHD_DATA_HIGHBYTE = $1F7.HIGHBYTE
  yHD_DATA_LOWBYTE = $1F7.LOWBYTE
  GoSub subWRITE_PULSE
  yHD_DATA_HIGHBYTE = $EC.HIGHBYTE '$EC = get 255 BYTE ASCII drive info
  yHD_DATA_LOWBYTE = $EC.LOWBYTE
  GoSub subWRITE_PULSE

  DelayUS 400

  'SET PARAMETERS FOR DATA REGISTER
'  /CS0  /CS1  A2 A1 A0  Addr.   Read Function       Write Function
'    0     1    0  0  0   1F0    Data Register       Data Register
  Low HD_CS0
  High HD_CS1
  Low HD_A2
  Low HD_A1
  Low HD_A0
  Output PORTD
  Output PORTB
  yHD_DATA_HIGHBYTE = $1F0.HIGHBYTE '$1F0 = SET TO Data Register
  yHD_DATA_LOWBYTE = $1F0.LOWBYTE
  GoSub subWRITE_PULSE

  Input PORTD
  Input PORTB
'  DelayUS 400 'Delay minimum of 25 ns
  For i = 0 To 255
    GoSub subREAD_PULSE
    If i <= 49 Then    'only 0 to 49 is used
      wTEMP.HighByte = yHD_DATA_HIGHBYTE
      wTEMP.LowByte = yHD_DATA_LOWBYTE
      wBUFFER_ARRAY50[i] = wTEMP
    EndIf
  Next

  For i = 0 To 49    'only 0 to 49 is used
    wTEMP = wBUFFER_ARRAY50[i]
    HSerOut[" READ wBUFFER_ARRAY50[",Dec3 i,"] = ",Dec3 wTEMP.HighByte,"'",DEC3 wTEMP.LowByte," = ",Dec3 wTEMP,13]
  Next

  HSerOut[Dec3 wBUFFER_ARRAY50[0]," = Configuration/ID Word",13]
  HSerOut[Dec3 wBUFFER_ARRAY50[1]," = Number of fixed cylinders",13]
  HSerOut[Dec3 wBUFFER_ARRAY50[2]," = No. of removable cylinders",13]
  HSerOut[Dec3 wBUFFER_ARRAY50[3]," = No. of heads",13]
  HSerOut[Dec3 wBUFFER_ARRAY50[4]," = No. of unformatted bytes per physical track",13]
  HSerOut[Dec3 wBUFFER_ARRAY50[5]," = No. of unformatted bytes per sector",13]
  HSerOut[Dec3 wBUFFER_ARRAY50[6]," = No. of phyical sectors per Tracks",13]
  HSerOut[Dec3 wBUFFER_ARRAY50[7]," = No. of bytes in the inter-sector gaps",13]
  HSerOut[Dec3 wBUFFER_ARRAY50[8]," = No. of bytes in the sync fields",13]

  sSTRING40 = ""
  For i = 10 To 19
    wTEMP = wBUFFER_ARRAY50[i]
    yTEMP = wTEMP.HighByte
'    yTEMP = yTEMP + 48
    sSTRING40 = sSTRING40 + Str$(Dec yTEMP)
    yTEMP = wTEMP.LowByte
'    yTEMP = yTEMP + 48
    sSTRING40 = sSTRING40 + Str$(Dec yTEMP)
  Next
  HSerOut[sSTRING40," = Serial number1",13]

  sSTRING40 = ""
  For i = 10 To 19
    wTEMP = wBUFFER_ARRAY50[i]

    yTEMP = wTEMP.HighByte
    yTEMP = yTEMP + 48
    sSTRING40 = sSTRING40 + yTEMP

    yTEMP = wTEMP.LowByte
    yTEMP = yTEMP + 48
    sSTRING40 = sSTRING40 + yTEMP
  Next
  HSerOut[sSTRING40," = Serial number2a",13]

  sSTRING40 = ""
  For i = 10 To 19
    wTEMP = wBUFFER_ARRAY50[i]

    yTEMP = wTEMP.LowByte
    yTEMP = yTEMP + 48
    sSTRING40 = sSTRING40 + yTEMP

    yTEMP = wTEMP.HighByte
    yTEMP = yTEMP + 48
    sSTRING40 = sSTRING40 + yTEMP
  Next
  HSerOut[sSTRING40," = Serial number2b",13]

  y = 0
  For x = 10 To 19
    wTEMP = wBUFFER_ARRAY50[x]
    SERIAL_NO_ARRAY21[y] = wTEMP.HighByte + 48
    Inc y
    SERIAL_NO_ARRAY21[y] = wTEMP.LowByte + 48
    Inc y
  Next
  SERIAL_NO_ARRAY21[y] = 0 ' Add the null Terminator
  HSerOut[Str SERIAL_NO_ARRAY21," = Serial number3",13]

  HSerOut[Dec3 wBUFFER_ARRAY50[20]," = Controller type",13]
  HSerOut[Dec3 wBUFFER_ARRAY50[21]," = Controller buffer size (in sectors)",13]
  HSerOut[Dec3 wBUFFER_ARRAY50[22]," = No. of ECC bytes on 'long' commands",13]

  sSTRING40 = ""
  For i = 23 To 26
    wTEMP = wBUFFER_ARRAY50[i]

    yTEMP = wTEMP.HighByte
    yTEMP = yTEMP + 48
    sSTRING40 = sSTRING40 + yTEMP

    yTEMP = wTEMP.LowByte
    yTEMP = yTEMP + 48
    sSTRING40 = sSTRING40 + yTEMP
  Next
  HSerOut[sSTRING40," = Controller firmware revision",13]

  sSTRING40 = ""
  For i = 27 To 46
    wTEMP = wBUFFER_ARRAY50[i]

    yTEMP = wTEMP.HighByte
    yTEMP = yTEMP + 48
    sSTRING40 = sSTRING40 + yTEMP

    yTEMP = wTEMP.LowByte
    yTEMP = yTEMP + 48
    sSTRING40 = sSTRING40 + yTEMP
  Next
  HSerOut[sSTRING40," = Model number",13]

  HSerOut[Dec3 wBUFFER_ARRAY50[47]," = No. of sectors/interrupt, (0 = no support)",13]
  HSerOut[Dec3 wBUFFER_ARRAY50[48]," = Double word transfer flag, (1 = capable)",13]
  HSerOut[Dec3 wBUFFER_ARRAY50[49]," = Write protected",13]

  HSerOut["  DID subGET_DRIV_INFO",13]
  HSerOut[" ",13]
  Return

  '**************************
  '**************************
  START:
  DelayMS 1000
  HSerOut[" ",13]
  HSerOut["START:",13]

  GoSub subWAIT_TILL_STATUS_LESS_THAN128

  MAIN:

  DelayMS 1000
  Toggle sLED

  If yREAD_PT <> yWRITE_PT Then
    Repeat
      If yREAD_PT < 99 Then
        Inc yREAD_PT
      Else
        yREAD_PT = 0
      EndIf

      yRX = yRX_ARRAY100[yREAD_PT]

      Select yRX
      Case "1"
        GoSub subGET_DRIV_INFO
      Case "2"
        GoSub subREAD_STATUS
      Case Else
        HSerOut[" '",yRX_ARRAY100[yREAD_PT],"' IS AN INVALID CMD",13]
      End Select

    Until yREAD_PT = yWRITE_PT
  EndIf

  GoTo MAIN

  End

I am using Hperterminal to send command 1 to start subGET_DRIV_INFO or 2 to start the PIC subroutines and subREAD_STATUS.
The subREAD_STATUS always returns a "BIT 6 = DRIVE NOT UP TO SPEED AND READY FOR CMD ***" and a subREAD_ERROR " BIT 2 = DRIVE STATUS ERROR OR INVALID COMMAND ***".
The following is the Hperterminal display of readouts from subroutines called 2DO subREAD_STATUS followed by 1DO subGET_DRIV_INFO.
Code:
START:
DO subWAIT_TILL_STATUS_LESS_THAN128
DO subREAD_STATUS %00010001 17:
BIT 6 = DRIVE NOT UP TO SPEED AND READY FOR CMD ***
BIT 3 = DRIVE NOT READY FOR DATA TRANSFER ***
BIT 0 = ERROR. DO subREAD_ERROR ***
DO subREAD_ERROR %00000100 4:
BIT 2 = DRIVE STATUS ERROR OR INVALID COMMAND ***
  DID subREAD_ERROR

  DID subREAD_STATUS

subWAIT_TILL_STATUS_LESS_THAN128 OK !!!
  DID subWAIT_TILL_STATUS_LESS_THAN128

2DO subREAD_STATUS %00010001 17:
BIT 6 = DRIVE NOT UP TO SPEED AND READY FOR CMD ***
BIT 3 = DRIVE NOT READY FOR DATA TRANSFER ***
BIT 0 = ERROR. DO subREAD_ERROR ***
DO subREAD_ERROR %00000100 4:
BIT 2 = DRIVE STATUS ERROR OR INVALID COMMAND ***
  DID subREAD_ERROR

  DID subREAD_STATUS

1DO subGET_DRIV_INFO
READ wBUFFER_ARRAY50[000] = 000'001 = 001
READ wBUFFER_ARRAY50[001] = 000'001 = 001
READ wBUFFER_ARRAY50[002] = 000'026 = 026
READ wBUFFER_ARRAY50[003] = 000'063 = 063
READ wBUFFER_ARRAY50[004] = 000'000 = 000
READ wBUFFER_ARRAY50[005] = 000'016 = 016
READ wBUFFER_ARRAY50[006] = 000'000 = 000
READ wBUFFER_ARRAY50[007] = 000'050 = 050
READ wBUFFER_ARRAY50[008] = 000'063 = 063
READ wBUFFER_ARRAY50[009] = 000'000 = 000
READ wBUFFER_ARRAY50[010] = 000'000 = 000
READ wBUFFER_ARRAY50[011] = 000'020 = 020
READ wBUFFER_ARRAY50[012] = 000'055 = 055
READ wBUFFER_ARRAY50[013] = 000'049 = 049
READ wBUFFER_ARRAY50[014] = 000'049 = 049
READ wBUFFER_ARRAY50[015] = 000'053 = 053
READ wBUFFER_ARRAY50[016] = 000'050 = 050
READ wBUFFER_ARRAY50[017] = 000'056 = 056
READ wBUFFER_ARRAY50[018] = 000'032 = 032
READ wBUFFER_ARRAY50[019] = 000'032 = 032
READ wBUFFER_ARRAY50[020] = 000'032 = 032
READ wBUFFER_ARRAY50[021] = 000'032 = 032
READ wBUFFER_ARRAY50[022] = 000'003 = 003
READ wBUFFER_ARRAY50[023] = 000'032 = 032
READ wBUFFER_ARRAY50[024] = 000'004 = 004
READ wBUFFER_ARRAY50[025] = 000'048 = 048
READ wBUFFER_ARRAY50[026] = 000'046 = 046
READ wBUFFER_ARRAY50[027] = 000'053 = 053
READ wBUFFER_ARRAY50[028] = 000'048 = 048
READ wBUFFER_ARRAY50[029] = 000'001 = 001
READ wBUFFER_ARRAY50[030] = 000'020 = 020
READ wBUFFER_ARRAY50[031] = 000'018 = 018
READ wBUFFER_ARRAY50[032] = 000'052 = 052
READ wBUFFER_ARRAY50[033] = 000'048 = 048
READ wBUFFER_ARRAY50[034] = 000'048 = 048
READ wBUFFER_ARRAY50[035] = 000'049 = 049
READ wBUFFER_ARRAY50[036] = 000'032 = 032
READ wBUFFER_ARRAY50[037] = 000'032 = 032
READ wBUFFER_ARRAY50[038] = 000'032 = 032
READ wBUFFER_ARRAY50[039] = 000'032 = 032
READ wBUFFER_ARRAY50[040] = 000'032 = 032
READ wBUFFER_ARRAY50[041] = 000'032 = 032
READ wBUFFER_ARRAY50[042] = 000'032 = 032
READ wBUFFER_ARRAY50[043] = 000'032 = 032
READ wBUFFER_ARRAY50[044] = 000'032 = 032
READ wBUFFER_ARRAY50[045] = 000'032 = 032
READ wBUFFER_ARRAY50[046] = 000'032 = 032
READ wBUFFER_ARRAY50[047] = 000'032 = 032
READ wBUFFER_ARRAY50[048] = 000'032 = 032
READ wBUFFER_ARRAY50[049] = 000'016 = 016
001 = Configuration/ID Word
001 = Number of fixed cylinders
026 = No. of removable cylinders
063 = No. of heads
000 = No. of unformatted bytes per physical track
016 = No. of unformatted bytes per sector
000 = No. of phyical sectors per Tracks
050 = No. of bytes in the inter-sector gaps
063 = No. of bytes in the sync fields
00020055049049053050056032032 = Serial number1
000D0g0a0a0e0b0h0P0P = Serial number2a
00D0g0a0a0e0b0h0P0P0 = Serial number2b
000D0g0a0a0e0b0h0P0P = Serial number3
032 = Controller type
032 = Controller buffer size (in sectors)
003 = No. of ECC bytes on 'long' commands
0P040`0^ = Controller firmware revision
0e0`010D0B0d0`0`0a0P0P0P0P0P0P0P0P0P0P0P = Model number
032 = No. of sectors/interrupt, (0 = no support)
032 = Double word transfer flag, (1 = capable)
016 = Write protected
  DID subGET_DRIV_INFO


Top
 Profile  
 
 Post subject: Re: PIC18F4550 microchip interface to a HD
PostPosted: May 29th, 2013, 15:58 
Offline

Joined: May 6th, 2008, 22:53
Posts: 2138
Location: England
Thanks for the full code - that helps with understanding it. Just got time for a partial reply at the moment:

normnet wrote:
I am using a 40 pin PIC18F4550 for use of PORTD in place of the 4014 shift register.

Oh. Those are exactly some of the changes I suggested to the schematic which you linked. I'm disappointed that this vital information wasn't mentioned originally, and so I wasted my time commenting on this before, as that schematic which you linked does not match your actual design. :(

normnet wrote:
The PIC18f4550 is also 5 volt as required to interface to the HD.

I haven't checked all of the relevant electrical details of that PIC, but using that device to provide an extra 8-bit port for the IDE interface high-byte obviously removes my concern about the 4014. Note that just because something is 5 volt doesn't necessarily mean that it is compatible with the IDE interface - the 4014 was powered from 5V in the original schematic, but that device is not compatible (although it would probably work often enough for people to be misled that its use is OK). There are also some 3.3V MCUs which could be used with an IDE interface, so 5V devices are not necessarily required. Anyway, without having time to do a full review, I agree that your chosen PIC is not an immediate concern.

So far I've found what seems to be one (perhaps the main?) repeated problem with the algorithm used in your code, but a better review will take longer than I have right now. Perhaps another reader who has more time than me, will be able to reply to you more quickly.


Top
 Profile  
 
 Post subject: Re: PIC18F4550 microchip interface to a HD
PostPosted: May 29th, 2013, 18:39 
Offline
User avatar

Joined: September 8th, 2009, 18:21
Posts: 15463
Location: Australia
wBUFFER_ARRAY50 is defined as a byte variable, but you have attempted to fill the array with words. Shouldn't that have resulted in a runtime error?

Code:
Dim wBUFFER_ARRAY50[50] As Byte
...
Dim wTEMP As Word


Code:
    If i <= 49 Then
      wTEMP.HighByte = yHD_DATA_HIGHBYTE
      wTEMP.LowByte = yHD_DATA_LOWBYTE
      wBUFFER_ARRAY50[i] = wTEMP    'only 0 to 49 is used
    EndIf

_________________
A backup a day keeps DR away.


Top
 Profile  
 
 Post subject: Re: PIC18F4550 microchip interface to a HD
PostPosted: May 30th, 2013, 4:22 
Offline

Joined: May 27th, 2013, 21:17
Posts: 5
Location: Minnesota USA
fzabkar wrote:
wBUFFER_ARRAY50 is defined as a byte variable, but you have attempted to fill the array with words. Shouldn't that have resulted in a runtime error?

Code:
Dim wBUFFER_ARRAY50[50] As Byte
...
Dim wTEMP As Word


Code:
    If i <= 49 Then
      wTEMP.HighByte = yHD_DATA_HIGHBYTE
      wTEMP.LowByte = yHD_DATA_LOWBYTE
      wBUFFER_ARRAY50[i] = wTEMP    'only 0 to 49 is used
    EndIf

Good catch! I now have both lower and upper byte data.
It may or may not be correct at this point but I have data.

Thanks
Norm


Top
 Profile  
 
 Post subject: Re: PIC18F4550 microchip interface to a HD
PostPosted: May 30th, 2013, 5:03 
Offline
User avatar

Joined: September 8th, 2009, 18:21
Posts: 15463
Location: Australia
normnet wrote:
I now have both lower and upper byte data.
It may or may not be correct at this point but I have data.

The Identify Device information block has a checksum. That should tell you whether the data are correct.

_________________
A backup a day keeps DR away.


Top
 Profile  
 
 Post subject: Re: PIC18F4550 microchip interface to a HD
PostPosted: May 30th, 2013, 8:50 
Offline

Joined: May 6th, 2008, 22:53
Posts: 2138
Location: England
@fzabkar - Nice spot on the array; that is additional to the issue which I've identified, and as it looks like the OP now has what he needs, that saves me spending any more time on this.

@normnet - remember that the various strings in the raw Identify Device response are byte-swapped, but if you're getting valid 16-bit data then the byte-swapped names of the drive manufacturer and drive model should be obvious.


Top
 Profile  
 
 Post subject: Re: PIC18F4550 microchip interface to a HD
PostPosted: June 2nd, 2013, 1:21 
Offline

Joined: May 27th, 2013, 21:17
Posts: 5
Location: Minnesota USA
The following "Identify Device" info appears to be correct but could persons with more HD experience look it over for correct HD information?
The attached file is for the Maxtor 20G drive.

Norm
Code:
Configuration/ID Word:
Data transfer rate > 10 MB/s
Head switching time > 15 us
Not MFM encoded
Hard sectored

15935 = Number of fixed cylinders
0 = No. of removable cylinders
16 = No. of heads
32256 = No. of unformatted bytes per physical track
21298 = No. of unformatted bytes per sector
63 = No. of physical sectors per Tracks
0 = No. of bytes in the inter-sector gaps
0 = No. of bytes in the sync fields
671121052228 = Serial number
3 = Controller type
3872 = Controller buffer size (in sectors)
4 = No. of ECC bytes on 'long' commands
A08.1500 = Controller firmware revision
MXO 4K020H1 = Model number
32784 = No. of sectors/interrupt, (0 = no support)
0 = Double word transfer flag, (1 = capable)
3840 = Write protected


Attachments:
d540x_datasheet.pdf [55.93 KiB]
Downloaded 753 times
Top
 Profile  
 
 Post subject: Re: PIC18F4550 microchip interface to a HD
PostPosted: June 2nd, 2013, 2:58 
Offline
User avatar

Joined: September 8th, 2009, 18:21
Posts: 15463
Location: Australia
See page 6-5:
http://www.bvg-group.ru/pdf/quantum/d54 ... manual.pdf

I suggest you compare your data against another utility, eg CrystalDiskInfo.

_________________
A backup a day keeps DR away.


Top
 Profile  
 
 Post subject: Re: PIC18F4550 microchip interface to a HD
PostPosted: June 4th, 2013, 8:01 
Offline

Joined: May 27th, 2013, 21:17
Posts: 5
Location: Minnesota USA
I am going through the "Identify Device" data found starting on page 67 of above posted manual for my Maxtor HD (thanks fzabkar).
It includes much more data than listed on my original post and I would like to know which version ATAPI is utilized?
Does "Identify Device" list the ATAPI version?
I have downloaded ATAPI versions 1-8 from this site.

Norm


Top
 Profile  
 
 Post subject: Re: PIC18F4550 microchip interface to a HD
PostPosted: June 4th, 2013, 8:37 
Offline

Joined: May 6th, 2008, 22:53
Posts: 2138
Location: England
normnet wrote:
I would like to know which version ATAPI is utilized?

To clarify - disk drives of this type use the ATA protocol, not ATAPI (if the device responds to the Identify Device command with 256 words of data, then it is an ATA and not an ATAPI device), so you should be looking at the ATA-related parts of the combined ATA/ATAPI specification documents. A disk drive does not support any version of ATAPI (i.e. packet commands).

According to the document kindly linked by fzabkar, page 63 says that the drive supports ATA/ATAPI-6 (i.e. ATA-6, as I explain above). However...

normnet wrote:
Does "Identify Device" list the ATAPI version?

See above re: ATAPI. For its claimed ATA version, see Identify Device response word 80. For that drive, that document seems to suggest it reports compliance with ATA-5. It could be the document is out of date, or it could be that the drive supports most, but not all, of ATA-6 and hence only reports full compliance with ATA-5 (this sort of situation is quite common). Have a look at what your drive actually reports...

Have fun :)


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 12 posts ] 

All times are UTC - 5 hours [ DST ]


Who is online

Users browsing this forum: No registered users and 12 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group