Forum: Mikrocontroller und Digitale Elektronik MBED IDE PATA Ansteuerung


von Martin G. (Firma: http://www.gyurma.de) (martin_g)


Lesenswert?

Hi Jungs und Mädels!

Hat irgendjemand es schon geschafft IDE PATA Festplatten (wie zum 
Beispiel Mastor 40GB Typen) direkt mit dem MBED oder ähnlichem zu 
betreiben und anzusprechen? Mir geht es eher um die direkte 
Positionierung der Leseköpfe.

Sind die Dinger sowas wie Register die man schreibt und liest, oder wie 
muß man sich das vorstellen?

Liebe Grüße,
Martin

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Lesenswert?

Hast du denn überhaupt schonmal zu diesem Thema gegoogelt?
Es gibt Massenweise infos zu IDE.
Und JA es ist nur Registergewutze!

von Martin G. (Firma: http://www.gyurma.de) (martin_g)


Lesenswert?

Ja, habe ich. Gefunden hab ich auch so manches. Aber alles nur Theorie.
Ich fände es dumm das Rad nochmal erfinden zu müssen, wenn es schon 
jemand vor mir gelöst hat.

Hier eine schöne Zusammenfassung der PIO Schnittstelle:
http://www.uni-koblenz.de/~physik/informatik/ECC/ide.pdf

Aber mehr nutzbares finde ich nicht wenn ich "ide ansteuerung" suche im 
googl.

Ich denke es gibt schon C++ oder C Libraries dafür...

von Tom (Gast)


Lesenswert?

Hallo,

dann such doch nach "IDE register" oder "IDE befehle" oder etwas in der 
Art.
Es gibt Libraries, die einem nach oben ein Filesystem bieten (z.B. 
http://ultra-embedded.com/?fat_filelib für ne FAT). Aber nach unten wird 
man für die konkrete Hardware noch den low-level Zugriff implementieren 
müssen. Bei IDE ist das allerdings nicht mehr als den Zugriff auf die 
Register zu handlen...

Tom

von Stampede (Gast)


Lesenswert?

was ist MBED ? Ich habe mal eine Ansteuerung geschrieben für IDE Platten 
für PIC32 COntroller in C.

von Rolf Magnus (Gast)


Lesenswert?

Martin G. schrieb:
> Mir geht es eher um die direkte Positionierung der Leseköpfe.

Ich kann mir nicht vorstellen, daß das geht. Um die Positionierung der 
Köpfe kümmert sich die Platte selbst. Du liest und schreibst nur 
Sektoren.

von Martin G. (Firma: http://www.gyurma.de) (martin_g)


Lesenswert?

http://mbed.org

Das ist von NXP ein niedlicher ARM, einfach über Cloud Compiler  zu 
programieren.

Mich interessiert eigentlich nicht die Logische Fileebene, sondern die 
direkte Positionierung der Schreib-Leseköpfe.
Ich hab mit den Dingern vor, Spiegel hochgenau zu bewegen.
Die Drives sind ja perfekte Servosteuerungen, mit perfektem Halten der 
Position auf einem Track. OK. Der Track hat eine geringe Exzentrizität, 
aber ich denke das winzige gezappel ist zu verkraften.
Da ich ein paar von den Platten im Keller habe, dachte ich, ich mache 
mal daraus eine Laser Direct Imaging Maschine, ohne den ganzen analogen 
Schnickschnack. Die Platte muß nicht einmal geöffnet werden, da die 
Lesekopf-Achse auch von Außen erreichbar ist wenn man das Pickerl 
runternimmt.

Mit meiner Analogen LDI Maschine hatte ich nur schlechte Ergebnisse. Sie 
ist nicht zuverlässig genug. Siehe:
http://www.gyurma.de/LDI1
Bilder könnt ihr hier sehen:
http://www.gyurma.de/LDIBilder1
Und ersten Erfolg hier:
http://www.gyurma.de/ldisuccess1

Mein Problem war mit den analogen Dingern, daß sie bei größeren 
Auslenkungen anfingen komisch zu wackeln. Total ungewohnt, als wenn die 
Regelung nicht gepasst hätte, oder die Spannung eingebrochen wäre.

von Martin G. (Firma: http://www.gyurma.de) (martin_g)


Lesenswert?

Probleme können noch die internen Cache Speicher machen, die ich bei 
Tests mit einem Linux PC auch hatte.

von Martin G. (Firma: http://www.gyurma.de) (martin_g)


Lesenswert?

Stampede schrieb:
> was ist MBED ? Ich habe mal eine Ansteuerung geschrieben für IDE Platten
> für PIC32 COntroller in C.

Darf ich das mal bitte haben?

mfg
Martin

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Martin G. schrieb:
> Mich interessiert eigentlich nicht die Logische Fileebene, sondern die
> direkte Positionierung der Schreib-Leseköpfe.
> Ich hab mit den Dingern vor, Spiegel hochgenau zu bewegen.

Das geht nicht über die IDE-Schnittstelle. Keine Chance.

Da wirst Du die Spulen der Linearantriebe selbst ansteuern müssen -- 
wobei das dann auch nicht mehr hochgenau wird, weil die zur genauen 
Positionierung erforderliche Servoinformation fehlt, die auf den 
Magnetscheiben aufgeprägt ist.

von Stampede (Gast)


Lesenswert?

Wie gesagt, für PIC32 und die FSLIB von Microchip. Die Funtkionen sind 
zum Lesen einzelner Sektoren. Damit wirst du die Spiegel aber nicht 
positionieren können.
1
/******************************************************************************
2
 *
3
 *               HDD Memory Disk Drive File System
4
 *
5
 ******************************************************************************
6
 * FileName:        HDD.c
7
 * Dependencies:    HDD.h
8
 *                  string.h
9
 *                  FSIO.h
10
 *                  FSDefs.h
11
 * Processor:       PIC32 with PMP
12
 * Compiler:        None
13
 * Author:          Stefan Dreyer
14
 * Version:         1.0.2
15
 *
16
 * Software License Agreement
17
 *
18
 * 
19
 *
20
 * THIS SOFTWARE IS PROVIDED IN AN “AS IS” CONDITION. NO WARRANTIES,
21
 * WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED
22
 * TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
23
 * PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE AUTHOR SHALL NOT,
24
 * IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
25
 * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
26
 *
27
 * Info Version 1.0.0:
28
 * This physical layer routines is intended to access a HDD by the Microchip
29
 * "Memory Disk Drive File System". 
30
 * At the moment, the routines are limited to PIC32 processers with PMP
31
 * interface. PBclock can be set to 80MHz.
32
 *
33
 * Info Version 1.0.1:
34
 *  -   added BYTE MDD_HDD_DEVICE_READY(void) to MDD_HDD_MediaInitialize(void)
35
 *     in order to wait until the disk has spin up.
36
 *  -   resolved a bug on startup in BYTE MDD_HDD_DEVICE_READY(void).
37
 *
38
 * Info Version 1.0.2:
39
 *  -  changed access to registers: Only those bit are chanced that are 
40
 *    really needed. This results in 35 word smaller code and thus a little
41
 *    speedup.
42
 *  -  minor improvements to optimize speed
43
 *
44
 * Info Version 1.0.3: (in progress)
45
 *  -  update for 48Bit LBA
46
*****************************************************************************/
47
#include "Compiler.h"
48
#include "GenericTypeDefs.h"
49
#include "MDD File System\FSIO.h"
50
#include "MDD File System\FSDefs.h"
51
#include "MDD File System\HDD.h"
52
#include "string.h"
53
#include "FSConfig.h"
54
#include "HardwareProfile.h"
55
56
/******************************************************************************
57
 * Global Variables
58
 *****************************************************************************/
59
#ifdef  SUPPORT_48_BIT_LBA
60
QWORD MDD_HDD_finalLBA;
61
#else
62
DWORD MDD_HDD_finalLBA;
63
#endif
64
static MEDIA_INFORMATION mediaInformation;
65
extern BOOL IDE_DEVICE;
66
HDD_IDENTIFY_RESPONSE identifyResponse;
67
68
/******************************************************************************
69
 * Prototypes
70
 *****************************************************************************/
71
BYTE MDD_HDD_BUSY(void);
72
BYTE MDD_HDD_DATA_READY(void);
73
BYTE MDD_HDD_DEVICE_READY(void);
74
void MDD_HDD_IDENTIFY_DEVICE(void);
75
MEDIA_INFORMATION * MDD_HDD_MediaInitialize(void);
76
77
//#define    DEBUG_MODE
78
79
/******************************************************************************
80
 * Function:        BYTE MDD_HDD_MediaDetect(void)
81
 *
82
 * PreCondition:    InitIO() function has been executed.
83
 *
84
 * Input:           void
85
 *
86
 * Output:          TRUE   - HDD detected
87
 *                  FALSE   - HDD detected
88
 *
89
 * Side Effects:    None
90
 *
91
 * Overview:        None
92
 *
93
 * Note:            This function could be changed to determine what is
94
 *          connected on the IDE bus
95
 *****************************************************************************/
96
BYTE MDD_HDD_MediaDetect()
97
{
98
  return TRUE;
99
}//end MediaDetect
100
101
102
/******************************************************************************
103
 * Function:        void MDD_HDD_InitIO(void)
104
 *
105
 * PreCondition:    None
106
 *
107
 * Input:           void
108
 *
109
 * Output:          void
110
 *
111
 * Side Effects:    None
112
 *
113
 * Overview:        None
114
 *
115
 * Note:            None
116
 *****************************************************************************/
117
void MDD_HDD_InitIO (void)
118
{
119
     IDE_WR_TRIS = OUTPUT;
120
  IDE_RESET_TRIS = OUTPUT;
121
  IDE_RESET = 1;  
122
     IDE_RD_TRIS = OUTPUT;
123
  IDE_CS0_TRIS = OUTPUT;
124
  IDE_CS1_TRIS = OUTPUT;
125
  IDE_IRQ_TRIS = INPUT;
126
  IDE_DIR_TRIS = OUTPUT;
127
  #ifdef USE_LEVELSHIFTER
128
    mIDE_SET_OUTPUT();
129
  #endif
130
  IDE_A0_TRIS = OUTPUT;
131
  IDE_A1_TRIS = OUTPUT;
132
  IDE_A2_TRIS = OUTPUT;
133
134
  IDE_CS0  = 1;        // Deselect the device
135
  IDE_CS1 = 1;
136
}
137
138
/******************************************************************************
139
 * Function:        void IDENTIFY_DEVICE(void)
140
 *
141
 * PreCondition:    None
142
 *
143
 * Input:           None
144
 *
145
 * Output:           None
146
 *
147
 * Side Effects:    None
148
 *
149
 * Overview:        None
150
 *
151
 * Note:            None
152
 *****************************************************************************/
153
void MDD_HDD_IDENTIFY_DEVICE(void)
154
{
155
  unsigned int counter = 0;
156
  BYTE i;
157
  QWORD data;
158
  
159
  #ifdef  DEBUG_MODE
160
    UART2PrintString("HDD IDENTIFY DEVICE\n\r");
161
  #endif
162
  IDE_CS0 = 0;
163
//  IDE_CS1 = 1;
164
  mPMPOpen(PMP_HDD_CONTROL, PMP_HDD_MODE, PMP_HDD_PORT, PMP_HDD_INTERRUPT);
165
  MDD_HDD_BUSY();            // Ready for command?
166
167
  #ifdef USE_LEVELSHIFTER
168
    mIDE_SET_OUTPUT();
169
  #endif  
170
171
  // TODO: LBA3 SETS MASTER / SLAVE !!!
172
  mMMD_HDD_LBA3();            // Set Device
173
  if(IDE_DEVICE == MASTER)
174
    PMDIN = 0x00;            // DEVICE 0
175
  else
176
    PMDIN = 0x10;            // DEVICE 1
177
  while(PMMODEbits.BUSY);    
178
  mMMD_HDD_COMMAND_REGISTER();      // Set READ COMMAND
179
  Nop();
180
  PMDIN = IDENTIFY_DEVICE;
181
  while(PMMODEbits.BUSY);          // Wait until PMP is free    
182
183
  MDD_HDD_DATA_READY();          // Ready for data to be received?
184
  #ifdef USE_LEVELSHIFTER
185
    mIDE_SET_INPUT();
186
  #endif    
187
  mMMD_HDD_IO_REGISTER();          // Set to IO Register to get data
188
  Nop();
189
  PMDIN;                  // dummy read to clear latches  
190
  while(PMMODEbits.BUSY);
191
  while(counter < 256)          // 256 WORDS are to be transmitted
192
  {
193
    if(27 == counter)          // here is the modelnumber
194
    {
195
      for(i=0;i<40;i=i+2)        // copy the 40Bytes
196
      {
197
        data = PMDIN;
198
        while(PMMODEbits.BUSY);
199
        identifyResponse.model_number[i+1] = (data&0xFF);
200
        identifyResponse.model_number[i] = (data>>8)&0xFF;
201
        counter++;      
202
      }
203
    }
204
    else if(100 == counter)
205
    {
206
      identifyResponse.LBA_48 = PMDIN;
207
      while(PMMODEbits.BUSY);          // Wait until PMP is free
208
      data = PMDIN;
209
      identifyResponse.LBA_48 |= (data&0xFF)<<16;
210
      while(PMMODEbits.BUSY);          // Wait until PMP is free
211
      data = PMDIN;
212
      identifyResponse.LBA_48 |= (data&0xFF)<<32;
213
      while(PMMODEbits.BUSY);          // Wait until PMP is free
214
      data = PMDIN;
215
      identifyResponse.LBA_48 |= (data&0xFF)<<48;
216
      while(PMMODEbits.BUSY);          // Wait until PMP is free
217
      counter += 4;
218
    }
219
    else if(counter == 85)
220
    {
221
      data = PMDIN&0x1;  // LSB shows if SMART is supported
222
      while(PMMODEbits.BUSY);
223
      counter++;
224
      if(data == 0x1)    //SMART supported
225
      {
226
        identifyResponse.SMART = 1;
227
        #ifdef  DEBUG_MODE
228
          UART2PrintString("SMART supported\n\r");
229
        #endif
230
      }
231
      else
232
      {
233
        identifyResponse.SMART = 0;
234
      }
235
    }
236
    else if(counter == 86)
237
    {
238
      data = PMDIN&0x400;    // Bit shows if 48Bit LBA is supported
239
      while(PMMODEbits.BUSY);
240
      counter++;
241
      if(data == 0x400)      // supported
242
      {
243
        identifyResponse.LBA_48_SUPPORT_BIT = 1;
244
        #ifdef  DEBUG_MODE
245
          UART2PrintString("Use 48 Bit LBA\n\r");
246
        #endif        
247
      }
248
      else
249
      {
250
        identifyResponse.LBA_48_SUPPORT_BIT = 0;
251
      }
252
    }
253
    else
254
    {
255
      PMDIN;              // discard data
256
      while(PMMODEbits.BUSY);
257
      counter++;
258
    }
259
  }
260
  #ifdef USE_LEVELSHIFTER
261
    mIDE_SET_OUTPUT();
262
  #endif      
263
  IDE_CS0 = 1;
264
  UART2PrintString((char*)identifyResponse.model_number );
265
//  IDE_CS1 = 1;
266
}
267
268
269
/*********************************************************
270
  Function:
271
    DWORD MDD_HDD_ReadCapacity (void)
272
  Summary:
273
    Determines the current capacity of the HDD
274
  Conditions:
275
    MDD_MediaInitialize() is complete
276
  Input:
277
    None
278
  Return:
279
    The capacity of the device
280
  Side Effects:
281
    None.
282
  Description:
283
    The MDD_HDD_ReadCapacity function is used by the
284
    USB mass storage class to return the total number
285
    of sectors on the HDD. To get the capacity, the
286
  READ_NATIVE_MAX_ADDRESS is executed, which gives
287
  the number of sectors available on the device.
288
  Remarks:
289
    None
290
  *********************************************************/
291
DWORD MDD_HDD_ReadCapacity(void)
292
{
293
  MDD_HDD_finalLBA = 0;
294
  #ifdef  DEBUG_MODE
295
    UART2PrintString("HDD READ CAPACITIY: ");
296
  #endif
297
  IDE_CS0 = 0;
298
  IDE_CS1 = 1;
299
  mPMPOpen(PMP_HDD_CONTROL, PMP_HDD_MODE, PMP_HDD_PORT, PMP_HDD_INTERRUPT);
300
  MDD_HDD_BUSY();            // Ready for command?
301
302
  #ifdef USE_LEVELSHIFTER
303
    mIDE_SET_OUTPUT();
304
  #endif
305
  
306
  IDE_CS0 = 1;
307
  IDE_CS1 = 0;
308
  MMD_HDD_DEVICE_CONTOL_REGISTER();
309
  PMDIN = 0x00;            // Set HOB Bit to 0 again
310
  while(PMMODEbits.BUSY);        // Wait until PMP is free  
311
  IDE_CS0 = 0;
312
  IDE_CS1 = 1;
313
  Nop();
314
  mMMD_HDD_LBA3();            // Set Device
315
  Nop();
316
  if(IDE_DEVICE == MASTER)
317
    PMDIN = 0x00;            // DEVICE 0
318
  else
319
    PMDIN = 0x10;            // DEVICE 1
320
  while(PMMODEbits.BUSY);    
321
  mMMD_HDD_COMMAND_REGISTER();      // Set READ COMMAND
322
  Nop();
323
  Nop();
324
325
  switch(identifyResponse.LBA_48_SUPPORT_BIT)
326
  {
327
    case (1):                // We need to use 48 Bit LBA
328
      PMDIN = READ_NATIVE_MAX_ADDRESS_EXT;
329
      while(PMMODEbits.BUSY);        // Wait until PMP is free    
330
      MDD_HDD_BUSY();            //
331
      // Device is set to HOB = 0;    
332
      mMMD_HDD_LBA0();
333
      while(PMMODEbits.BUSY);        // Wait until PMP is free
334
      PMDIN;                // Dummy to clear latches
335
      while(PMMODEbits.BUSY);        // Wait until PMP is free      
336
      MDD_HDD_finalLBA |= (PMDIN&0xFF);  // Read MAX_LBA 7:0
337
      while(PMMODEbits.BUSY);        // Wait until PMP is free
338
      mMMD_HDD_LBA1();
339
      while(PMMODEbits.BUSY);        // Wait until PMP is free
340
      PMDIN;            
341
      MDD_HDD_finalLBA |= ((PMDIN&0xFF)<<8);// Read MAX_LBA 15:8
342
      while(PMMODEbits.BUSY);        // Wait until PMP is free
343
      mMMD_HDD_LBA2();
344
      while(PMMODEbits.BUSY);        // Wait until PMP is free
345
      PMDIN;      
346
      MDD_HDD_finalLBA |= ((PMDIN&0xFF)<<16);  // Read MAX_LBA 23:16
347
      while(PMMODEbits.BUSY);        // Wait until PMP is free              
348
      // Set to HOB 1
349
      #ifdef USE_LEVELSHIFTER
350
        mIDE_SET_OUTPUT();        // Set to output again
351
      #endif        
352
      IDE_CS0 = 1;
353
      IDE_CS1 = 0;
354
      MMD_HDD_DEVICE_CONTOL_REGISTER();
355
      Nop();
356
      PMDIN = 0x80;            // Set HOB Bit to 1
357
      while(PMMODEbits.BUSY);        // Wait until PMP is free
358
      IDE_CS0 = 0;
359
      IDE_CS1 = 1;
360
      #ifdef USE_LEVELSHIFTER
361
        mIDE_SET_INPUT();        // Set to output again
362
      #endif  
363
      mMMD_HDD_LBA0();  
364
      Nop();
365
      while(PMMODEbits.BUSY);        // Wait until PMP is free
366
      PMDIN;                // Dummy to clear latches
367
      while(PMMODEbits.BUSY);        // Wait until PMP is free
368
      MDD_HDD_finalLBA |= ((PMDIN&0xFF)<<24);  // Read MAX_LBA 31:24
369
      while(PMMODEbits.BUSY);        // Wait until PMP is free
370
      // Currently, only 32 Bit sector adresses (for 2TB disks) are used
371
      // For this reason, the following LBA bytes are not used.
372
      #ifdef USE_LEVELSHIFTER
373
        mIDE_SET_OUTPUT();        // Set to output again
374
      #endif          
375
      IDE_CS0 = 1;
376
      IDE_CS1 = 0;
377
      MMD_HDD_DEVICE_CONTOL_REGISTER();
378
      PMDIN = 0x00;            // Set HOB Bit to 0 again
379
      while(PMMODEbits.BUSY);        // Wait until PMP is free                
380
      break;
381
      
382
    case (0):                // We need to use 28 Bit LBA
383
    default:
384
      PMDIN = READ_NATIVE_MAX_ADDRESS;
385
      while(PMMODEbits.BUSY);        // Wait until PMP is free    
386
      MDD_HDD_BUSY();            //
387
      mMMD_HDD_LBA3();          // Get the LBA
388
      while(PMMODEbits.BUSY);
389
      PMDIN;                //  dummy
390
      while(PMMODEbits.BUSY);        // Wait until PMP is free
391
      MDD_HDD_finalLBA |= ((PMDIN&0x0F)<<24);    // only 24Bit are used
392
      while(PMMODEbits.BUSY);        // Wait until PMP is free
393
      mMMD_HDD_LBA2();
394
      Nop();
395
      while(PMMODEbits.BUSY);        // Wait until PMP is free
396
      PMDIN;        
397
      while(PMMODEbits.BUSY);        // Wait until PMP is free
398
      MDD_HDD_finalLBA |= ((PMDIN&0xFF)<<16);
399
      while(PMMODEbits.BUSY);        // Wait until PMP is free
400
      mMMD_HDD_LBA1();
401
      Nop();
402
      while(PMMODEbits.BUSY);        // Wait until PMP is free
403
      PMDIN;        
404
      while(PMMODEbits.BUSY);        // Wait until PMP is free
405
      MDD_HDD_finalLBA |= ((PMDIN&0xFF)<<8);
406
      while(PMMODEbits.BUSY);        // Wait until PMP is free
407
      mMMD_HDD_LBA0();
408
      Nop();
409
      while(PMMODEbits.BUSY);        // Wait until PMP is free
410
      PMDIN;        
411
      while(PMMODEbits.BUSY);        // Wait until PMP is free
412
      MDD_HDD_finalLBA |= (PMDIN&0xFF);
413
      while(PMMODEbits.BUSY);        // Wait until PMP is free        
414
      break;
415
  }
416
    
417
  #ifdef USE_LEVELSHIFTER
418
    mIDE_SET_OUTPUT();
419
  #endif
420
  IDE_CS1 = 1;    // Deselect IDE Drive
421
  IDE_CS0 = 1; 
422
  #ifdef  DEBUG_MODE
423
    UART2PutHexDWord(MDD_HDD_finalLBA);
424
    UART2PrintString(" HEX\n\r");
425
  #endif  
426
    return (MDD_HDD_finalLBA);
427
}      
428
429
430
431
/*********************************************************
432
  Function:
433
    WORD MDD_SDSPI_ReadSectorSize (void)
434
  Summary:
435
    Determines the current sector size on the HDD
436
  Conditions:
437
    MDD_MediaInitialize() is complete
438
  Input:
439
    None
440
  Return:
441
    The size of the sectors for the physical media
442
  Side Effects:
443
    None.
444
  Description:
445
    The MDD_SDSPI_ReadSectorSize function is used by the
446
    USB mass storage class to return the card's sector
447
    size to the PC on request.
448
  Remarks:
449
    None
450
  *********************************************************/
451
WORD MDD_HDD_ReadSectorSize(void)
452
{
453
    return MEDIA_SECTOR_SIZE;
454
}
455
456
457
/******************************************************************************
458
 * Function:        MEDIA_INFORMATION * MMDD_HDD_MediaInitialize(void)
459
 *
460
 * PreCondition:    None
461
 *
462
 * Input:           None
463
 *
464
 * Output:          Returns TRUE if media is initialized, FALSE otherwise
465
 *
466
 * Overview:        MediaInitialize initializes the media card and supporting variables.
467
 *
468
 * Note:            None
469
 *****************************************************************************/
470
MEDIA_INFORMATION * MDD_HDD_MediaInitialize(void)
471
{
472
   // Example initialization
473
474
   // You can define error codes depending on how your device works
475
   // 0x00 (MEDIA_NO_ERRORS) indicates success
476
 //  if (result == FAILURE)
477
 //       mediaInformation.errorCode = 0x00;
478
 //  else
479
//        mediaInformation.errorCode = 0x01;
480
//  MDD_HDD_DEVICE_READY();  
481
//  MDD_HDD_IDENTIFY_DEVICE();
482
    mediaInformation.errorCode = MEDIA_NO_ERROR;
483
    mediaInformation.validityFlags.value = 0;
484
    return &mediaInformation;
485
}//end MediaInitialize
486
487
488
/******************************************************************************
489
 * Function:        BYTE MDD_HDD_SectorRead(DWORD sector_addr, BYTE *buffer, WORD blocks)
490
 *
491
 * PreCondition:    None
492
 *
493
 * Input:           sector_addr - Sector address, each sector contains 512-byte
494
 *                  buffer      - Buffer where data will be stored
495
 *
496
 * Output:          Returns TRUE if read successful, false otherwise
497
 *
498
 * Side Effects:    None
499
 *
500
 * Overview:        SectorRead reads 512 bytes of data from the disk starting
501
 *                  at the sector address specified by sector_addr and stores
502
 *                  them in the location pointed to by 'buffer'.
503
 *
504
 * Note:            At the moment, no error checking is supported.
505
 *          
506
 *          Depending on the disksize, LBA28 or LBA48 will be used:
507
 *
508
 *          Sector Count Current -
509
 *            number of sectors to be transferred low order, bits (7:0).
510
 *            Sector Count Previous -
511
 *            number of sectors to be transferred high order, bits (15:8).
512
 *            LBA Low Current -      ( = LBA0)
513
 *            LBA (7:0).
514
 *            LBA Low Previous -
515
 *            LBA (31:24).
516
 *            LBA Mid Current -      ( = LBA1)
517
 *            LBA (15:8).
518
 *            LBA Mid Previous -
519
 *            LBA (39:32).
520
 *            LBA High Current -      ( = LBA2)
521
 *            LBA (23:16).
522
 *            LBA High Previous -
523
 *            LBA (47:40).
524
 *****************************************************************************/
525
BYTE MDD_HDD_SectorRead(DWORD sector_addr, BYTE* buffer, WORD blocks)
526
{
527
  WORD data;
528
     WORD index, i;
529
     BYTE status = TRUE;
530
  BYTE *bptr;
531
532
  IDE_CS0 = 0;
533
//  IDE_CS1 = 1;
534
  mPMPOpen(PMP_HDD_CONTROL, PMP_HDD_MODE, PMP_HDD_PORT, PMP_HDD_INTERRUPT);    // This takes 30 word of program memory!!!
535
  MDD_HDD_BUSY();            // Ready for command?
536
537
  #ifdef USE_LEVELSHIFTER
538
    mIDE_SET_OUTPUT();
539
  #endif                  // Set Levelshifter to Output
540
/*  // TODO: LBA3 SETS MASTER / SLAVE !!!
541
  mMMD_HDD_LBA3();            // Set to LBA3 Register
542
  PMDIN = (((sector_addr>>24)&0x0F)|0xE0);  // Write byte
543
  while(PMMODEbits.BUSY);        // Wait until PMP is free
544
  mMMD_HDD_LBA2();            // Set to LBA2 Register
545
  PMDIN = (sector_addr>>16);      // Write byte
546
  while(PMMODEbits.BUSY);        // Wait until PMP is free  
547
  mMMD_HDD_LBA1();            // Set to LBA1 Register
548
  PMDIN = (sector_addr>>8);      // Write byte
549
  while(PMMODEbits.BUSY);        // Wait until PMP is free
550
  mMMD_HDD_LBA0();            // Set to LBA0 Register  
551
  PMDIN = sector_addr;        // Write byte
552
  while(PMMODEbits.BUSY);        // Wait until PMP is free
553
554
  // TODO CHANGE COUNT FOR HIGH BANDWIDTH
555
  mMMD_HDD_SECTOR_COUNT();        // Number of sector (512Byte) to be transfered
556
  PMDIN = 0x1;              // transfer only one sector  
557
  while(PMMODEbits.BUSY);          // Wait until PMP is free
558
559
  mMMD_HDD_COMMAND_REGISTER();      // Set READ COMMAND*/
560
561
  #ifdef  DEBUG_MODE
562
    UART2PrintString("READ10 Sector: ");
563
    UART2PutHexDWord(sector_addr);
564
    UART2PrintString("\n\r");
565
    UART2PrintString("READ10 Nr: ");
566
    UART2PutHexDWord(blocks);
567
    UART2PrintString("\n\r");    
568
  #endif
569
570
  switch(identifyResponse.LBA_48_SUPPORT_BIT)
571
  {
572
    case (1):                // We need to use 48 Bit LBA
573
      //optimized to minimize instructions on register change:
574
      mMMD_HDD_LBA1();          // LBA1 Register  (LBA Mid)
575
      PMDIN = 0x0;            // Write LBA Mid previous byte (39:32)
576
      while(PMMODEbits.BUSY);        // Wait until PMP is free      
577
      PMDIN = (sector_addr>>8)&0xFF;    // Write LBA Mid current byte (15:8)
578
      while(PMMODEbits.BUSY);        // Wait until PMP is free
579
    
580
      IDE_A0 = 1;              // LBA2  (LBA High)
581
      Nop();    
582
      PMDIN = 0x0;            // Write LBA High previous byte (47:40)
583
      while(PMMODEbits.BUSY);        // Wait until PMP is free      
584
      PMDIN = (sector_addr>>16)&0xFF;    // Write LBA High current byte (23:16)
585
      while(PMMODEbits.BUSY);        // Wait until PMP is free
586
    
587
      IDE_A1 = 1;              // LBA3 (Device)
588
      IDE_A0 = 0;              // LBA bit has to be set
589
      Nop();
590
      if(IDE_DEVICE == MASTER)      
591
        PMDIN = 0xE;          // Write byte, set to MASTER device
592
      else
593
        PMDIN = 0xF;          // Write byte, set to SLAVE device    
594
      while(PMMODEbits.BUSY);        // Wait until PMP is free
595
        
596
      IDE_A2 = 0;             // LBA0 (LBA Low)
597
      IDE_A0 = 1;
598
      Nop();
599
      PMDIN = (sector_addr>>24)&0xFF;    // Write LBA Mid previous byte (31:24)
600
      while(PMMODEbits.BUSY);        // Wait until PMP is free      
601
      PMDIN = sector_addr&0xFF;      // Write LBA Mid current byte (7:0)
602
      while(PMMODEbits.BUSY);        // Wait until PMP is free
603
    
604
      IDE_A0 = 0;              // SectorCount
605
      Nop();      
606
      PMDIN = (blocks>>8)&0xFF;      // Write sector cout (15:8)
607
      while(PMMODEbits.BUSY);        // Wait until PMP is free      
608
      PMDIN = blocks&0xFF;        // Write sector count (7:0)
609
      while(PMMODEbits.BUSY);        // Wait until PMP is free      
610
    
611
      IDE_A2 = 1;
612
      IDE_A0 = 1;
613
      Nop();
614
      PMDIN = READ_SECTOR_EXT;      //
615
      while(PMMODEbits.BUSY);        // Wait until PMP is free
616
      /*MDD_HDD_DATA_READY();        // Ready for data to be received?
617
      mMMD_HDD_IO_REGISTER();        // Set to IO Register to get data
618
      Nop();
619
      PMDIN;                // Dummy read to clear latches
620
      while(PMMODEbits.BUSY);        // Wait until PMP is free*/
621
      bptr = buffer;
622
      break;
623
    case (0):                // Use old 28 Bit LBA
624
    default:    
625
      //optimized to minimize instructions on register change:
626
      mMMD_HDD_LBA1();          // Set to LBA1 Register
627
      PMDIN = (sector_addr>>8)&0xFF;    // Write byte
628
      while(PMMODEbits.BUSY);        // Wait until PMP is free
629
    
630
      IDE_A0 = 1;              // LBA2
631
      Nop();    
632
      PMDIN = (sector_addr>>16)&0xFF;    // Write byte
633
      while(PMMODEbits.BUSY);        // Wait until PMP is free
634
    
635
      IDE_A1 = 1;              // LBA3
636
      IDE_A0 = 0;
637
      data = (((sector_addr>>24)&0x0F)|0xE0);  //
638
      if(IDE_DEVICE == MASTER)
639
        PMDIN = data;          // Write byte
640
      else
641
        PMDIN = (data | 0x10);      // Write byte    
642
      while(PMMODEbits.BUSY);        // Wait until PMP is free
643
        
644
      IDE_A2 = 0;             // LBA0 
645
      IDE_A0 = 1;
646
      PMDIN = sector_addr&0xFF;      // Write byte
647
      while(PMMODEbits.BUSY);        // Wait until PMP is free
648
    
649
      IDE_A0 = 0;              // SectorCount
650
      if(blocks == 256)
651
        PMDIN = 0;            // transfer 256 sector
652
      else
653
        PMDIN = blocks;          // transfer x sector  
654
      while(PMMODEbits.BUSY);        // Wait until PMP is free
655
    
656
      IDE_A2 = 1;
657
      IDE_A0 = 1;
658
      Nop();
659
      PMDIN = READ_SECTOR;        //
660
      while(PMMODEbits.BUSY);        // Wait until PMP is free  
661
      /*MDD_HDD_DATA_READY();        // Ready for data to be received?
662
      mMMD_HDD_IO_REGISTER();        // Set to IO Register to get data
663
      Nop();
664
      PMDIN;                // Dummy read to clear latches
665
      while(PMMODEbits.BUSY);        // Wait until PMP is free*/
666
      bptr = buffer;
667
      break;
668
  }                      // End Switch LBA Mode
669
  
670
  for  (index = 0; index < blocks; index++)  // Copy data
671
  {
672
    MDD_HDD_DATA_READY();  
673
    mMMD_HDD_IO_REGISTER();          // Set to IO Register to get data
674
    Nop();
675
    Nop();    
676
    #ifdef  DEBUG_MODE
677
      UART2PrintString("ReadSector\n\r");
678
    #endif
679
    PMDIN;                  // Dummy read to clear latches
680
    while(PMMODEbits.BUSY);          // Wait until PMP is free
681
    for(i = 0; i < (MEDIA_SECTOR_SIZE/2); i++)   //Reads in 512-byte of data
682
    {
683
      while(PMMODEbits.BUSY);        // Wait until PMP is free
684
      data = PMDIN;
685
      (*bptr++) = data;
686
      (*bptr++) = (data>>8)&0xFF;
687
                
688
    }        
689
  }    
690
    
691
  #ifdef USE_LEVELSHIFTER
692
    mIDE_SET_OUTPUT();
693
  #endif
694
  //IDE_CS1 = 1;      // Deselect IDE Drive
695
  IDE_CS0 = 1;
696
  //mPMPClose();      // Close to free for other functions (RAM, LCD, etc.)  
697
     return(status);
698
}//end SectorRead
699
700
/******************************************************************************
701
 * Function:        BYTE MDD_HDD_SectorWrite(DWORD sector_addr, BYTE *buffer, BYTE allowWriteToZero)
702
 *
703
 * PreCondition:    None
704
 *
705
 * Input:           sector_addr - Sector address, each sector contains 512-byte
706
 *                  buffer      - Buffer where data will be read
707
 *                  allowWriteToZero - If true, writes to the MBR will be valid
708
 *
709
 * Output:          Returns TRUE if write successful, FALSE otherwise
710
 *
711
 * Side Effects:    None
712
 *
713
 * Overview:        SectorWrite sends 512 bytes of data from the location
714
 *                  pointed to by 'buffer' to the card starting
715
 *                  at the sector address specified by sector_addr.
716
 *
717
 * Note:            Write to sector 0 must be allowed so that the dive can
718
 *          be formatted.
719
 *          At the moment, no error checking is supported.
720
 *****************************************************************************/
721
BYTE MDD_HDD_SectorWrite(DWORD sector_addr, BYTE* buffer, BYTE allowWriteToZero)
722
{
723
  WORD data;
724
     WORD index;
725
     BYTE status = TRUE;
726
  BYTE *bptr;
727
728
  IDE_CS0 = 0;      //
729
//  IDE_CS1 = 1;      // Select device
730
731
    mPMPOpen(PMP_HDD_CONTROL, PMP_HDD_MODE, PMP_HDD_PORT, PMP_HDD_INTERRUPT);
732
    MDD_HDD_BUSY();            // Ready for command?
733
    #ifdef USE_LEVELSHIFTER
734
      mIDE_SET_OUTPUT();
735
    #endif                  // Set Levelshifter to Output
736
    // TODO: LBA3 SETS MASTER / SLAVE !!!
737
    mMMD_HDD_LBA3();            // Set to LBA3 Register
738
    data = (((sector_addr>>24)&0x0F)|0xE0);  // Write byte
739
    if(IDE_DEVICE == MASTER)
740
      PMDIN = data;          // Write byte
741
    else
742
      PMDIN = (data | 0x10);      // Write byte      
743
    while(PMMODEbits.BUSY);        // Wait until PMP is free
744
    mMMD_HDD_LBA2();            // Set to LBA2 Register
745
    PMDIN = (sector_addr>>16);      // Write byte
746
    while(PMMODEbits.BUSY);        // Wait until PMP is free  
747
    mMMD_HDD_LBA1();            // Set to LBA1 Register
748
    PMDIN = (sector_addr>>8);      // Write byte
749
    while(PMMODEbits.BUSY);        // Wait until PMP is free
750
    mMMD_HDD_LBA0();            // Set to LBA0 Register  
751
    PMDIN = sector_addr;        // Write byte
752
    while(PMMODEbits.BUSY);        // Wait until PMP is free
753
  
754
    // TODO CHANGE COUNT FOR HIGH BANDWIDTH
755
    mMMD_HDD_SECTOR_COUNT();        // Number of sector (512Byte) to be transfered
756
    PMDIN = 0x1;            // transfer only one sector  
757
    while(PMMODEbits.BUSY);        // Wait until PMP is free
758
  
759
    mMMD_HDD_COMMAND_REGISTER();    // Set READ COMMAND
760
    
761
    PMDIN = WRITE_SECTOR;  //  
762
    while(PMMODEbits.BUSY);        // Wait until PMP is free    
763
    MDD_HDD_DATA_READY();        // Ready for data to be received?
764
    mMMD_HDD_IO_REGISTER();        // Set to IO Register
765
766
    #ifdef USE_LEVELSHIFTER
767
      mIDE_SET_OUTPUT();
768
    #endif                // Set Levelshifter to Output
769
  
770
    bptr = buffer;
771
    for(index = 0; index < MEDIA_SECTOR_SIZE/2; index++)      //Reads in 512-byte of data
772
      {
773
        data = (*bptr++);
774
        (data |= (*bptr++)<<8);
775
        PMDIN = data;  
776
        while(PMMODEbits.BUSY);    
777
      }    
778
    MDD_HDD_BUSY();      // Wait for data to be written
779
//    IDE_CS1 = 1;      // Deselect IDE Drive
780
    IDE_CS0 = 1;
781
    //mPMPClose();      // Close to free for other functions (RAM, LCD, etc.)  
782
       return(status);
783
//  }
784
} //end SectorWrite
785
786
787
/******************************************************************************
788
 * Function:        BYTE MDD_HDD_WriteProtectState(void)
789
 *
790
 * PreCondition:    None
791
 *
792
 * Input:           None
793
 *
794
 * Output:          BYTE    - Returns the status of the "write enabled" pin
795
 *
796
 * Side Effects:    None
797
 *
798
 * Overview:        Determines if the HDD is write-protected
799
 *
800
 * Note:            Here writing to the device could be prohibited
801
 *****************************************************************************/
802
BYTE MDD_HDD_WriteProtectState(void)
803
{
804
   return(FALSE);
805
}
806
807
/******************************************************************************
808
 * Function:        BYTE MDD_HDD_BUSY(void)
809
 *
810
 * PreCondition:    None
811
 *
812
 * Input:           None
813
 *
814
 * Output:          BYTE
815
 *
816
 * Side Effects:    Sets Levelshifter to INPUT !!!
817
 *
818
 * Overview:        Determines if the HDD device is busy by checking the status register
819
 *
820
 * Note:            None
821
 *****************************************************************************/
822
BYTE MDD_HDD_BUSY(void)
823
{
824
  HDD_STATUS  HDDStatus;
825
  // TODO: TEST IF MASTER OR SLAVE
826
  while(PMMODEbits.BUSY);      // Wait for all actions finished 
827
  #ifdef USE_LEVELSHIFTER
828
    mIDE_SET_INPUT();      // Set Levelshifter to Output    
829
  #endif                
830
  mMMD_HDD_STATUS_REGISTER();
831
  Nop();
832
  PMDIN;
833
  while(PMMODEbits.BUSY);      // Dummy to flush latches
834
  do
835
    {  
836
      HDDStatus._byte = (PMDIN&0xFF);  // read
837
      while(PMMODEbits.BUSY);      // Wait until PMP is free
838
    } 
839
  while(HDDStatus.BUSY==1);
840
}
841
842
843
/******************************************************************************
844
 * Function:        BYTE MDD_HDD_DATA_READY(void)
845
 *
846
 * PreCondition:    A proper command (like READ_SECTOR) has been initiated
847
 *
848
 * Input:           None
849
 *
850
 * Output:          BYTE
851
 *
852
 * Side Effects:    Sets Levelshifter to INPUT !!!
853
 *
854
 * Overview:        Determines if the HDD device is ready for data (TX or RX)
855
 *
856
 * Note:            None
857
 *****************************************************************************/
858
BYTE MDD_HDD_DATA_READY(void)
859
{
860
  HDD_STATUS  HDDStatus;
861
  // TODO: TEST IF MASTER OR SLAVE
862
  //while(PMMODEbits.BUSY);      // Wait for all actions finished 
863
  #ifdef USE_LEVELSHIFTER
864
    mIDE_SET_INPUT();      // Set Levelshifter to Input    
865
  #endif  
866
  mMMD_HDD_STATUS_REGISTER();
867
  Nop();
868
  PMDIN;
869
  while(PMMODEbits.BUSY);      // Dummy to flush latches  
870
  do
871
    {  
872
      HDDStatus._byte = (PMDIN&0xFF);  // read
873
      while(PMMODEbits.BUSY);      // Wait until PMP is free
874
    } 
875
  while(HDDStatus.DRQ==0 || HDDStatus.BUSY==1);
876
}
877
878
879
/******************************************************************************
880
 * Function:        BYTE MDD_HDD_DEVICE_READY(void)
881
 *
882
 * PreCondition:    None
883
 *
884
 * Input:           None
885
 *
886
 * Output:          void
887
 *
888
 * Side Effects:    Sets Levelshifter to INPUT !!!
889
 *
890
 * Overview:        Determines if the HDD device has spin up
891
 *
892
 * Note:            None
893
 *****************************************************************************/
894
BYTE MDD_HDD_DEVICE_READY(void)
895
{
896
  BYTE status = TRUE;
897
  BYTE Timeout = FALSE;
898
  IDE_CS0 = 0;              //
899
//  IDE_CS1 = 1;              // Select device
900
  mPMPOpen(PMP_HDD_CONTROL, PMP_HDD_MODE, PMP_HDD_PORT, PMP_HDD_INTERRUPT);
901
  HDD_STATUS  HDDStatus;
902
  // TODO: TEST IF MASTER OR SLAVE
903
  while(PMMODEbits.BUSY);          // Wait for all actions finished 
904
  #ifdef USE_LEVELSHIFTER
905
    mIDE_SET_OUTPUT();          // Set Levelshifter to Output    
906
  #endif  
907
  
908
  // TODO: LBA3 SETS MASTER / SLAVE !!!
909
  mMMD_HDD_LBA3();            // Set Device
910
  if(IDE_DEVICE == MASTER)
911
    PMDIN = 0x00;            // DEVICE 0
912
  else
913
    PMDIN = 0x10;            // DEVICE 1
914
  while(PMMODEbits.BUSY);      
915
  
916
  OpenCoreTimer(0);
917
  #ifdef USE_LEVELSHIFTER
918
    mIDE_SET_INPUT();          // Set Levelshifter to Output    
919
  #endif    
920
  mMMD_HDD_STATUS_REGISTER();
921
  PMDIN;
922
  while(PMMODEbits.BUSY);      // Dummy to flush latches  
923
  do
924
    {  
925
      HDDStatus._byte = (PMDIN&0xFF);  // read
926
      while(PMMODEbits.BUSY);      // Wait until PMP is free
927
      if(ReadCoreTimer() >= 400000000ul)
928
      {
929
        Timeout = TRUE;
930
        status = FALSE;
931
      }
932
    }
933
  while((HDDStatus.READY==0 || HDDStatus.BUSY==1) && Timeout == FALSE);  
934
  IDE_CS0 = 1;  
935
  IDE_CS1 = 0;  
936
  MMD_HDD_DEVICE_CONTOL_REGISTER();
937
  #ifdef USE_LEVELSHIFTER
938
    mIDE_SET_OUTPUT();          // Set Levelshifter to Output    
939
  #endif  
940
  Nop();
941
  PMDIN = 0x1;              // INT OFF
942
  while(PMMODEbits.BUSY);          // Wait until PMP is free  
943
  IDE_CS1 = 1;      
944
  
945
  mPMPClose();              // Close to free for other functions (RAM, LCD, etc.)
946
  #ifdef  DEBUG_MODE
947
    UART2PrintString("HDD DEVICE READY:\n\r");
948
  #endif
949
  return status;
950
}

von Martin G. (Firma: http://www.gyurma.de) (martin_g)


Lesenswert?

Danke!

Wieso sollte das unmöglich sein. Man müsste nur den Cache überlisten, 
und ihm sagen, welchen Sektor ich lesen oder schreiben will. Vielleicht 
gibts da auch irgend welche Debug modi, die man dafür verwenden kann. 
Kennt die jemand?
Wenn das mit dem direkten Sektorlesen ohne Aussetzer geht, kann ich dann 
eine Kalibrierung machen, welcher Sektor zu welchem Winkel gehört. Das 
müsste ich eh machen.
Cache überlisten ist eher das Problem...

mfg
Martin

von Stampede (Gast)


Lesenswert?

Noch den HEader
1
/******************************************************************************
2
 *
3
 *               HDD Memory Disk Drive File System
4
 *
5
 ******************************************************************************
6
 * FileName:        HDD.c
7
 * Dependencies:    HDD.h
8
 *                  string.h
9
 *                  FSIO.h
10
 *                  FSDefs.h
11
 * Processor:       PIC32 with PMP
12
 * Compiler:        C32
13
 * Author:          Stefan Dreyer
14
 * Version:         see HDD.c
15
 *
16
 * Software License Agreement
17
 *
18
 * 
19
 *
20
 * THIS SOFTWARE IS PROVIDED IN AN “AS IS” CONDITION. NO WARRANTIES,
21
 * WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED
22
 * TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
23
 * PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE AUTHOR SHALL NOT,
24
 * IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
25
 * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
26
*****************************************************************************/
27
#ifndef  HDD_H
28
#define HDD_H
29
30
31
#include "GenericTypeDefs.h"
32
#include "FSconfig.h"
33
#include "MDD File System\FSDefs.h"
34
35
36
#define  MASTER   0
37
#define SLAVE  1
38
39
#define FALSE  0
40
#define TRUE  !FALSE
41
42
#define  INPUT  1
43
#define  OUTPUT  0
44
45
#define PMP_HDD_CONTROL    (PMP_ON | PMP_IDLE_CON | PMP_MUX_OFF | PMP_READ_WRITE_EN | PMP_TTL |\
46
                         PMP_CS2_CS1_OFF | PMP_WRITE_POL_LO | PMP_READ_POL_LO | PMP_LATCH_POL_HI)
47
#define PMP_HDD_MODE        (PMP_IRQ_OFF | PMP_AUTO_ADDR_OFF | PMP_DATA_BUS_16 | PMP_MODE_MASTER2 |\
48
                         PMP_WAIT_BEG_4 | PMP_WAIT_MID_4 | PMP_WAIT_END_4 )
49
#define PMP_HDD_PORT    (PMP_PEN_OFF)
50
#define PMP_HDD_INTERRUPT  (PMP_INT_OFF)
51
52
// NOTE: MDD_HDD_InitIO() must be executed in main on INIT
53
//    Is now done by FSInit()
54
55
/***************************************************************/
56
/*                      IDE REGISTERS                         */
57
/***************************************************************/
58
/*
59
/CS0=0, /CS1=1, A2..A0=111B: command/status register. When
60
written the IDE device regards the data you write to this
61
register as a command. When read you get the status of the IDE
62
device. Reading his register also clears any interrupts from the
63
IDE device to the controller. */
64
#define  MMD_HDD_COMMAND_REGISTER()  (IDE_A2 = 1, IDE_A1 = 1, IDE_A0 = 1)  
65
#define  MMD_HDD_STATUS_REGISTER()  (IDE_A2 = 1, IDE_A1 = 1, IDE_A0 = 1)
66
67
#define  MMD_HDD_DEVICE_CONTOL_REGISTER() (IDE_A2 = 1, IDE_A1 = 1, IDE_A0 = 0)  // CHIP SELECTS !!!
68
#define  mMMD_HDD_LBA0()        (IDE_A2 = 0, IDE_A1 = 1, IDE_A0 = 1)
69
#define  mMMD_HDD_LBA1()        (IDE_A2 = 1, IDE_A1 = 0, IDE_A0 = 0)
70
#define  mMMD_HDD_LBA2()        (IDE_A2 = 1, IDE_A1 = 0, IDE_A0 = 1)
71
#define  mMMD_HDD_LBA3()        (IDE_A2 = 1, IDE_A1 = 1, IDE_A0 = 0)
72
#define  mMMD_HDD_SECTOR_COUNT()    (IDE_A2 = 0, IDE_A1 = 1, IDE_A0 = 0)
73
#define  mMMD_HDD_IO_REGISTER()    (IDE_A2 = 0, IDE_A1 = 0, IDE_A0 = 0)
74
#define  mMMD_HDD_COMMAND_REGISTER()  (IDE_A2 = 1, IDE_A1 = 1, IDE_A0 = 1)  
75
#define  mMMD_HDD_STATUS_REGISTER()  (IDE_A2 = 1, IDE_A1 = 1, IDE_A0 = 1)
76
77
#define  mMMD_HDD_2ND_STATUS_REGISTER()    (IDE_A2 = 1, IDE_A1 = 1, IDE_A0 = 0)
78
79
80
// These functions are used to change the direction of the 
81
// 74LVC245A levelshifter. This levelshifter is needed if
82
// other deviced are present on the PMP bus that do not 
83
// allow the 5V TTL levels
84
#define USE_LEVELSHIFTER
85
86
#define  mIDE_SET_OUTPUT()  IDE_DIR = 1;
87
#define  mIDE_SET_INPUT()  IDE_DIR = 0;
88
89
// Summary: The format of an HDD_STATUS response
90
/* IDE Status Register:
91
;  bit 7: Busy  1=busy, 0=not busy
92
;  bit 6: Ready 1=ready for command, 0=not ready yet
93
;  bit 5: DF  1=fault occured inside drive
94
;  bit 4: DSC  1=seek complete
95
;  bit 3: DRQ  1=data request ready, 0=not ready to xfer yet
96
;  bit 2: CORR  1=correctable error occured
97
;  bit 1: IDX  vendor specific
98
;  bit 0: ERR  1=error occured      */
99
100
typedef union
101
{
102
    BYTE _byte;                         // Byte-wise access
103
    // This structure allows bitwise access of the response
104
    struct
105
    {
106
        unsigned ERR:1;                 // 1=error occured
107
        unsigned IDX:1;             // vendor specific
108
        unsigned CORR:1;             // 1=correctable error occured
109
        unsigned DRQ:1;             // 1=data request ready, 0=not ready to xfer yet
110
        unsigned DSC:1;               // 1=seek complete
111
        unsigned DF:1;               // 1=fault occured inside drive
112
        unsigned READY:1;             // 1=ready for command, 0=not ready yet
113
        unsigned BUSY:1;             // 1=busy, 0=not busy
114
    };
115
}HDD_STATUS;
116
117
typedef union
118
{
119
  struct
120
  {
121
    CHAR   model_number[40];
122
    QWORD  LBA_48;
123
  };
124
    struct
125
    {
126
        unsigned LBA_48_SUPPORT_BIT:1;  // 1= 48Bit LBA is supported
127
    unsigned SMART:1;        // 1=SMART is supported
128
    };  
129
}HDD_IDENTIFY_RESPONSE;
130
131
132
133
/***************************************************************/
134
/*                      COMMANDS                           */
135
/***************************************************************/
136
137
#define  READ_SECTOR         0x20  // Reads Sector(s)
138
#define  READ_SECTOR_EXT         0x24  // Reads Sector(s) 48 Bit LBA
139
#define  WRITE_SECTOR         0x30  // Writes Sector(s)
140
#define  WRITE_SECTOR_EXT      0x34  // Writes Sector(s) 48 Bit LBA
141
#define  IDENTIFY_PACKET_DEVICE    0xA1  //
142
#define  STANDBY_IMMEDIATE      0xE0  //
143
#define  IDLE_IMMEDIATE        0xE1  //
144
#define  IDENTIFY_DEVICE        0xEC  //
145
#define  READ_NATIVE_MAX_ADDRESS    0xF8  //
146
#define  READ_NATIVE_MAX_ADDRESS_EXT  0x27  //
147
148
149
150
151
/*                      PROTOTYPES                             */
152
/***************************************************************/
153
void MDD_HDD_InitIO(void);
154
BYTE MDD_HDD_MediaDetect(void);
155
MEDIA_INFORMATION * MDD_HDD_MediaInitialize(void);
156
BYTE MDD_HDD_SectorRead(DWORD sector_addr, BYTE* buffer, WORD blocks);
157
BYTE MDD_HDD_SectorWrite(DWORD sector_addr, BYTE* buffer, BYTE allowWriteToZero);
158
DWORD MDD_HDD_ReadCapacity(void);
159
WORD MDD_HDD_ReadSectorSize(void);
160
BYTE MDD_HDD_WriteProtectState(void);
161
162
#endif

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Wichtige Regeln - erst lesen, dann posten!

Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

von Martin G. (Firma: http://www.gyurma.de) (martin_g)


Lesenswert?

Stimmt, trotzdem Danke! Damit kann ich vielleicht was anfangen...

von Martin G. (Firma: http://www.gyurma.de) (martin_g)


Lesenswert?

PATA Enthusiasten!

Mir ist gestern das hier über den Weg gelaufen:

http://code.google.com/p/idefat-arduino/

Ist zwar kein MBED, aber das Ziel ist ja eine funktionierende HW, und 
ich habe grade einen Arduino Mega da rumliegen und sich langweilen.

Das Kompilieren dieses Libraries macht aber beim Arduino IDE >= 1.0 
Probleme. Habe da die Include "WProgram.h" auf "Arduino.h" ändern müssen 
in den .h Dateien, und auch der Rückgabewert der virtuellen write( ) 
funktionen stimmt nicht mit dem neuen gcc oder was auch immer überein, 
wodurch ich das auch noch ändern musste.
Ausserdem passt im IDEFatUtils.h das mit dem
...Serial.print(c);
nicht. das muß jetzt
...Serial.write(c);
heißen.

Jetzt redet wenigstens der Arduino mit mir, aber ich habe noch keine HDD 
dran.

Mal sehen wie weit ich damit heute abend komme...

mfg
Martin

http://www.gyurma.de

von Dario Greggio (Gast)


Lesenswert?

Danke fuer diese :) ich hatte meine HDD-for-microchip-PIC geschreibert 
und... es schaus knapp similar zu deinen.

Hatte ich nun einen neue problem mit "STATUS=0xD0" manchmal... hoffe ich 
kann das solvieren.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.