Homebrew IDE driver w/ PIC -- Intermittent

Im using a PIC to read a compact flash card (8bit mode), however, it doesnt seem to be able to read the number of sectors, the model number, etc consistently.

Does anyone have any experience with the IDE interface??

Here is what Im doing:

  1. Hard Reset
  2. Read Byte from Address 0x17 until Bit 7 goes low
  3. Write a 1 at Address 0x11
  4. Read Byte from Address 0x17 until Bit 7 goes low
  5. Write a 0xEF at Address 0x17
  6. Read Byte from Address 0x17 until Bit 7 goes low
  7. Write a 0xE0 at Address 0x16
  8. Read Byte from Address 0x17 until Bit 7 goes low
  9. Write a 1 at Address 0x12
  10. Read Byte from Address 0x17 until Bit 7 goes low
  11. Write a 0xEC at Address 0x12
  12. Read Byte from Address 0x17 until Bit 7 toggles
  13. Clock in 512 bytes on the data bus for model info, etc.

The strange part is that if I randomly reset the compact flash (touching pin 1 to ground) it works, but I cant seem to find why most of the time theres no data.

Ben

Reply to
benn686
Loading thread data ...

What timings are you using for clocking in the data? There's PIO mode 0,1,2 etc timings which dictate setup and hold times for DIOR- etc and minimum cycle times for a read. You need to read the ATA spec and ensure you're not violating these timings. You generally assume PIO mode 0 and then issue IDENTIFY_DEVICE to work out what speed you can use.

The spec also gives a 'recipe' for doing read/write commands (what signals to wait on etc).

Regards,

--
|              Mark McDougall                | "Electrical Engineers do it
|     |   with less resistance!"
Reply to
Mark McDougall

I wrote this GPL library for PIC18, which works with ATA hard disks and ATAPI devices:

formatting link

--Toby

Reply to
toby

it

number,

0,1,2

minimum

you're not

issue

In my experience a 40MHz PIC18 isn't fast enough to be able to violate the slowest of these timing constraints :-) so you are effectively limited to PIO Mode 0.

signals

Even with close reference to the spec, writing and debugging such a low level driver is not trivial; and devices often have quirks which must be allowed for :-(

--Toby

do it

resistance!"

Reply to
toby

This is a bit of my code using CF in memory mode with 8051 derivative

//Registers #define CF_REG_BASE 0xD000 #define CF_data *(u8 *)(CF_REG_BASE) //Data input/output #define CF_feature *(u8 *)(CF_REG_BASE+1) //Command parameter #define CF_error *(u8 *)(CF_REG_BASE+1) //Error [BBK].[UNC].0.[IDNF].0.[ABRT].0.[AMNF] #define CF_sector_count *(u8 *)(CF_REG_BASE+2) //Sectors to process (0 =

256) #define CF_sector_number *(u8 *)(CF_REG_BASE+3) //LBA 7-0 #define CF_cylinder_low *(u8 *)(CF_REG_BASE+4) //LBA 15-8 #define CF_cylinder_high *(u8 *)(CF_REG_BASE+5) //LBA 23-16 #define CF_cdh *(u8 *)(CF_REG_BASE+6) //.x.[LBA].x.[Drive].[Head 4 - 0 / LBA 27 - 24] #define CF_command *(u8 *)(CF_REG_BASE+7) //Command argument #define CF_status *(u8 *)(CF_REG_BASE+7) //Status [BUSY].[RDY].[DWF].[DWC].[DRQ].[CORR].[IDX].[ERR]

// // CF_IdDrive - // // Retrieves the drive information and saves it into a buffer // u8 CF_IdDrive(u8 *buffer) { u16 i;

//Id command while(CF_status & 0xf0 != 0x50); CF_command = 0xEC;

//Read bytes while(CF_status & 0xf8 != 0x58); for(i = 0; i < 512; i++) { *buffer++ = CF_data; }

return CF_error; }

Those 'while' statements should be replaced by a timeout function.

Also watch for ground bounce with the compactflash card - check this by writing 0xff 0xff 0xff 0xff 0x00 0x00 0x00 0x00 to an entire sector and read it back to make sure its correct.

Ross

Reply to
Ross Marchant

You might try the feb 2001 issue of Circuit Cellar. The article "Pic a Compact Flash Card" by Mark Samuels describes use of a pic 16f877 for reading & presumably writing the compact flash's.

formatting link

Hul

snipped-for-privacy@hotmail.com wrote:

Reply to
Hul Tytus

Thanks everyone. After much probing, it turns out the model name and number of sectors in the identifcation were being returned, however, I was treating the return as an error due to the FIELD VALID byte of the return (offset of 0x53) occasionaly being set to zero. A problem, since I intend to use LBA addressing.

As I understand it, this byte indicates whether or not the CF supports LBA, is this correct? Ive initialized the LBA3 register to 0xE0 so Im not sure why it would only work occasionaly (when I randomly reset it).

Is it possible that the read/write strobes are TOO slow and that the device expects the data to be latched quicker?

Reply to
benn686

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.