[jallib] r2242 committed - added "asm nop" if > 20mhz in pata_hd_read_data(). 48mhz PIC is too fa...

9 views
Skip to first unread message

jal...@googlecode.com

unread,
Oct 5, 2010, 10:54:15 PM10/5/10
to jal...@googlegroups.com
Revision: 2242
Author: mattsc...@hotmail.com
Date: Tue Oct 5 19:53:52 2010
Log: added "asm nop" if > 20mhz in pata_hd_read_data(). 48mhz PIC is too
fast, or maybe it's my breadboard... I'll check later on PCB. Seems that
hard disk does not have time to put data onto it's bus after read line goes
active.
http://code.google.com/p/jallib/source/detail?r=2242

Modified:
/trunk/include/external/storage/pata_hard_disk/pata_hard_disk.jal

mattschinkel

unread,
Oct 5, 2010, 10:55:18 PM10/5/10
to jallib
What is the shortest delay I can make? Is there anything in JAL?

I used "asm nop"


Matt.

Joep Suijs

unread,
Oct 6, 2010, 7:51:13 AM10/6/10
to jal...@googlegroups.com
nop is one instructions (4 clock cycles on midrange iirc) and thus
clock dependent.
The compiler can create delay code in 1 us increments, independent of
the cpu clock. Of course, short delays and low clock can't be
accurate.

Joep

2010/10/6 mattschinkel <mattsc...@hotmail.com>:


> What is the shortest delay I can make? Is there anything in JAL?
>
> I used "asm nop"
>
>
> Matt.
>

> --
> You received this message because you are subscribed to the Google Groups "jallib" group.
> To post to this group, send email to jal...@googlegroups.com.
> To unsubscribe from this group, send email to jallib+un...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/jallib?hl=en.
>
>

Kiste

unread,
Oct 6, 2010, 10:19:30 AM10/6/10
to jallib

> 48mhz PIC is too
> fast, or maybe it's my breadboard...

That's what I happened to work on today ;-)

It is to fast for drives that do not support PIO modes 3 or 4. I have
a drive that works at 32MHz without the delay and one that doesn't.

However, to really use PIO modes 3 and 4, IORDY needs to be observed
to see if the disk really has valid data on the bus. Even if IORDY
indicates valid data, just the check would consume far more time than
just unconditionally executing the "nop", so it would be futile to try
to use those modes.

The PIO data transfer timings in the standard documents are somewhat
confusing, but I guess to be on the safe side, one should wait 260ns
after assertion of /DIOR.

From PIF18F4520 datasheet you can read that the time between a port
write and a port read is at minimum about 1.25Tcy.

Based on these numbers, you would need

1 nop from 16MHz
2 nop from 34MHz
3 nop from 50MHz
4 nop from 64MHz (as soon as there are PIC18 that can :-)

Greets,
Kiste

mattschinkel

unread,
Oct 6, 2010, 3:41:57 PM10/6/10
to jallib
Hey thanks Kiste. I am currently doing a review of my hard disk, sd
card and fat32 libs. I understand that there are a few things that
need to be worked on. I also plan to add some type of error
notification if a sector is bad, or whatever the case is. Any help
would be appreciated.

For others listening. A hard disk's registers get addressed via a
parallel bus. I assume this bus runs some gates and maybe a shift
register. so it would be something like the following:
1. hard disk reads a sector into a sector buffer
2. I wait till data is ready by accessing the status register
3. I switch register address to the data register
4. send a read pulse
5. get the data from the bus.
6. repeat step 4 till end of sector

The problem is at step 4/5/6.It seems that the data doesn't get put
onto the bus fast enough on the hard disk end. Maybe there logic gates
in the hard disk that shift out the data or a shift register? In any
case, it is too slow for a 48mhz PIC.

I think we will need a 100ps delay. I know it is impossible to get an
accurate 100ps delay. The point would be to get as close to 100ps as
possible. Can we add a procedure to the delay library?

procedure delay_100ps() is
pragma inline
asm nop
end procedure

Matt.

Oliver Seitz

unread,
Oct 6, 2010, 4:46:28 PM10/6/10
to jal...@googlegroups.com

> I think we will need a 100ps delay.

I'm sure your talking about nanoseconds, not picoseconds... in 100ps at the speed of light you're travelling 3cm (1 inch).

At 16MHz and below, two successing machine instructions are already 250ns apart.
From 40MHz upward, a single nop does consume less than 100ns. So my suggestion would be:

procedure delay_100ns() is
  pragma inline
if target_clock >16_000_000 then
   asm nop
end if
if target_cock >40_000_000 then
asm nop
end if
end procedure

Greets,
Kiste


Oliver Seitz

unread,
Oct 6, 2010, 5:15:47 PM10/6/10
to jal...@googlegroups.com
Ok, let's save program space:


procedure delay_100ns() is
  pragma inline
  if target_clock >40_000_000 then
   asm goto $+1
  elsif target_cock >16_000_000 then
    asm nop
  end if
end procedure

To give an idea of the times we are talking about: A PATA cable may be up to 80cm (3 feet) long afaik. To just travel along that length the signal needs about 4ns!

Greets,
Kiste

mattschinkel

unread,
Oct 6, 2010, 7:58:21 PM10/6/10
to jallib
Sorry yes... nanoseconds... I wasn't thinking :)

Matt.

mattschinkel

unread,
Oct 6, 2010, 11:03:45 PM10/6/10
to jallib
Kiste,

Just so you know. One of the issues I am working on with hard disk and
sd card lib is that the pata_hd_read_data() procedure reads two bytes
at a time. This is correct for hard drives, but it is not user
friendly since it is hard to see which byte is first. I will be adding
a pata_hd_read_byte() procedure for reading only one byte at a time.

SD card lib also reads two bytes at a time with sd_read_data(), but
it is SPI, so only one byte should be read at a time. I will leave the
old procedures in place and add new ones. For faster reading/writing,
you should use read_sector()

I have done many modifications already to the hard disk/sd card
libraries, so let me know what suggestions you have so I may add them
as well.

As for fat32, it needs a lot more work to be more user friendly, and
also should be able to read one byte at a time. It is lib beta at the
moment. I also currently have a fat32_small library that I have not
uploaded yet. This will be a tiny fat32 for smaller processors and
will support only one file.

Matt.

Oliver Seitz

unread,
Oct 7, 2010, 1:43:40 AM10/7/10
to jal...@googlegroups.com
Thanks for the clarification!


> For faster
> reading/writing,
> you should use read_sector()

Err, not yet... on 32MHz, pata_hd_read_data() gave me about 320kbytes/s, while read_sector() gave about 130kbyte/s. When large_array is not used, read_sector() yields about 520kbytes/s. (Didn't write that numbers down, so it's very approximately.) My measurements showed me, that read_sector() indeed uses much RAM to be even slower than read_data().

> I have done many modifications already to the hard disk/sd
> card
> libraries,

Ok, time to svn up :-)

> so let me know what suggestions you have

You'll regret that one ;-)

> As for fat32, it needs a lot more work to be more user
> friendly,

yes... I've tried the sample program on a 18F4520. It did not work. Why it didn't work will stay fat32's secret :-)

We'll get it fixed sooner or later.

Greets,
Kiste


mattschinkel

unread,
Oct 7, 2010, 6:55:15 PM10/7/10
to jallib
> pata_hd_read_data() gave me about 320kbytes/s, while read_sector() gave about 130kbyte/s.
I haven't done actual speed tests, so you are more correct then me.
But I also don't like calling a procedure 256 or 512 times, when read
sector could be used.

One thing you must keep in mind is that SD Card uses the same port as
23k256 (spi ram), or other things the user may want. With SD Card, you
must watch the chip select line, so read sector is better. Mostly
because I like the usage of storing file name locations in an external
ram such as 23k256. Internal PIC ram works fine too, but you are
limited to the number of files per directory.

do you have a 23k256?

>When large_array is not used, read_sector() yields about 520kbytes/s
Ok, how. Are you suggesting to use two normal arrays of 512 bytes?

>Ok, time to svn up :-)
I'll get my stuff up on SVN asap.

>You'll regret that one ;-)
all suggestions are welcome. I won't regret it. Hopefully you have
lots. We can start a list of issues.

Matt.

mattschinkel

unread,
Oct 8, 2010, 12:27:38 AM10/8/10
to jallib
I uploaded my files to svn
\project\fat32_new\

I don't want to overwrite the existing files since they where tested
and work correctly. When these new files are ok, I'll overwrite the
old ones. Read my notes in fat32_pata_hard_disk.jal

Sector reading should be faster then before now. There is a
pata_hd_read_sector2() procedure. I actually made these files a few
months ago but stopped working on them for a bit. In the older files,
I had the hard disk go to each sector with start_read and do stop read
at the end of the sector. Now if you read one sector, the drive is
already at the next sector so there is no reason to do start_read() or
stop_read(). If you have time, you can check the speed for me and
compare to your other results.

The stop_read procedure was quite slow before as well, so that was
fixed. That would explain your slow sector read.

Some of these files may actually be worse then before due to more
procedures. I am trying to add better procedures before I remove the
old ones. I think the two byte read procedures in pata_hard_disk and
sd_card libs may become obsolete.

Matt.

mattschinkel

unread,
Oct 8, 2010, 10:19:18 AM10/8/10
to jallib
So, reading by sector may always be slower then read_data(a,b) because
of using a array. This must be due to the speed PIC can process that
array. However, the read sector is required because of sd card using
the same bus. I'm still not sure what your doing with large_array or
why you are not using it.

In the end, a user can choose to read data with pata_read_sector,
pata_read_data, or fat32_read_file_sector. fat32_read_file will take
care of fragmented files for the user. You get into more code when
fat32 is added.

Matt.
Reply all
Reply to author
Forward
0 new messages