Tag - period

1
on floppy adpll, this time, my solution
2
further development on the AFP
3
heat problems
4
Intronix LA1034
5
looking at the code this a.m.
6
Parallax USR2SER
7
losing data

on floppy adpll, this time, my solution

This isn’t by any stretch finished, but it does do what I’ve expected it to do.

It responds both to differences in phase (counter is set to 0), and differences in frequency (period is adjusted in the direction of the frequency error)

I did this at 3am last night, so there could be a couple bugs in there.

With all this being said, I’m not entirely sure that PLLs are actually required for good reading of amiga floppy disks. My regular “static interval” solution works about 95%-98% of the time. I’m going to come up with a list of problem disks and see if this solution works better/worse/otherwise.

I’ve used a read data window of 1us, which starts being centered on 2us, and is automatically adjusted as data comes in. This produces windows around 2us, 4us, 6us, 8us. I output the overall error which is the deviation from the center of the window as each pulse is received. I’d like to graph this error, but it doesn’t look like Xilinx’s iSim will export a particular output as CSV or whatever.

module floppy_pll(
    input clk,
    input floppy_data,
     input reset,
    output reg window_open,
    output reg [7:0] data,
    output reg strobe,
     output reg [7:0] error
    );

// window is 1us wide
// starts at .5us before counter rollover
// ends .5us after counter rollover
// ideally, edges should be arriving right when the counter rolls over

reg [7:0] period = 100;
reg [10:0] counter = 0;

reg IN_D1, IN_D2;
wire out_negedge = ~IN_D1 & IN_D2;

always@(posedge clk or posedge out_negedge) begin

    if (reset) period <= 100;
   
    if (clk) begin
   
        counter <= counter + 1;
        if (counter == period) counter <= 0;
   
        if ( (counter > (period-25)) || (counter < 25) ) window_open <= 1;
        else window_open <= 0;
   
    end
   
    if (out_negedge) begin
   
        // if counter == 0 and we see out_negedge be positive, then we are perfectly aligned
        // so we dont need to adjust anything
        if (counter != 0) begin
   
            if (window_open) begin
           
                counter <= 0; // align counter to the phase of the incoming signal
               
                if (counter < 25) begin
               
                    //we rolled over before pulse was seen, so make period larger
                    //error values will be over 128
                    period <= period + 1;
                    error <= (128 + counter);
                   
                end
               
                if (counter > (period-25)) begin
               
                    //we haven't rolled when we saw the pulse, so make period shorter
                    //error values will be less than 128
                   
                    period <= period - 1;
                    error <= 128 - (period-counter);
                   
                end
           
            end

        end
       
    end
   
   
    // edge detection flops for data in direct from floppy
    IN_D1 <= floppy_data;
    IN_D2 <= IN_D1;
end

endmodule

further development on the AFP

I’m about to bring a new member of my family into this world.  As a new proud parent, I’m completely unsure about what this means in terms of time, dedication, and so on.  I’m sure I’ll have less free time to spend on projects like this.   As a result, updates and improvements are unlikely to happen in the short term.

Something to remember is that I’ve already achieved my goal, which was loosely, “to create a device that sits in between a PC and a floppy drive that can read amiga floppies and create emulator .ADFs in a reasonable period of time.”  You know, crossing the finish line was rather anti-climactic, mainly because (as you’ve seen) there are so many smaller, but no less important, steps that all add up to a working product.

I’ve learned a fair bit on this project, and would like to go back and identify the specific problems I faced, how I eventually solved them, and why they presented such a challenge.  There were some really fundamental mistakes I made which frustrated things, and made this task harder than it should have been.  I think other beginners can learn from my mistakes, and I’d like to make a post/(maybe a paper?) on some basic do’s and dont’s.

In any event, there are a few things I want to touch up, but then I’ll be posting a copy of the java source, compiled java with instructions on how to execute, and the SX firmware.

Note that I’m not going incommunicado — I’ll be monitoring the blog and email as usual.

Last but not least, there are a number of things I really want to do with this thing, namely build a custom circuit board.  I’d like to add the writing capability, but that is a fairly large task.  There are other minor to-do’s that eventually need done.  So I’m not finished yet here.

You know, I could never have gotten as far as I have without the help of people here, especially Tim and David, and people over at the Parallax forums(Bean, pjv, Michael C, Guenther), who I’m pretty sure are tired of my posts and my frustration.

heat problems

As I alluded in an earlier post(s), my SX28 has been pretty warm. After doing a number of different tests, I’ve now ordered an infrared thermometer from amazon for $29.99. I want to find out exactly how hot this thing is getting. It may very well be a normal operating temperature, and I’m able to keep my finger on it for an extended period of time(sort of on the comfortable side of pain.) I’m pretty sure the temperature is under 120 degrees, and the chip is rated for 185. It is running at 50mhz, and is in a small SSOP package, so who knows.

I’ll probably make a forum post over on forums.parallax.com and find out what others’ SXs are running.

Might be concern over nothing, but I’ve emailed support on Saturday, and they are checking into it.

My IR thermometer is on the free-super-saver-shipping-slow-boat-from-China, so it will probably be another
week and a half before I see this thing. It’s definitely the el-cheapo model, with a field of view of 1:1, but I don’t care. It should be accurate enough to get me in the ballpark. I just need some type of absolute reference instead of saying, “this feels hot to me.” I can also monitor it as I’m using it as well.

My biggest concern is that I fry the SX28, which is surface-mount, and not easily replaceable. Either soldering a new SX28 on there or re-doing my circuit board does not sound like fun to me. So, it’s better to be safe than sorry.

Intronix LA1034

I’m seriously looking at the Intronix LA1034 logic analyzer.

It’s a USB PC-based logic analyzer.  34 channels, samples up to 500mhz, and has nice trigger options, etc.  I’ve downloaded the software, and tried it out in demo mode, and it looks pretty powerful.

I could monitor multiple pins, namely the floppy data lead, the debug ISR pin, and the memory output.  By comparing the floppy data lead and the memory output pin, I could actually see if the correct bits are being written for each.

It will store at least 1023 transitions (more if they happen inside the same sample period) and with rough numbers, this looks like I could probably store upwards of 150 – 200 bytes of data.

What I’m missing now is visibility.  I know something’s going wrong, but I can’t see it.  Sure, double 1’s are being written, but WHY.  What’s the status of the various leads when that happens?
The trigger options look nice, I’m not sure if I can trigger on a “11” written in memory mode, but they have a pre-trigger buffer.  So you can see what leads up to something happening.

They also have interpreters for displaying real data, like decoding 232 into values, etc.

looking at the code this a.m.

Welp,

I decided to take a look at my code today, although I can’t actually implement anything until after I get home from work. 🙂

Not sure if I mentioned this eariler, but I’m now padding the data sent from the SX back to the PC with a pair of 0xFF’s.  So <0xFF> <0xFF> <13,824 bytes of data> <0xFF><0xFF><8bit-checksum>.

This padding mainly helps me find the start of the data, because I now echo command characters, there is normally a garbage character or so.  It also helps me find the end of the data, and makes the checksum be the very last byte transmitted.

I’m still using SX/B’s built-in UART commands instead of my own, because I found a small issue with my UART bit-banging code, where the bit period varies with the actual data sent due to how MOVB actually operates.

I’ve tacked on a simple 8-bit (% 255, mod 255)  checksum so that I’m sure that data sent = data received.  I’ve got enough problems than to worry if there was a transfer error.

My checksum routine on the PC was kinda screwed up, and I found the problem this morning.  I was including the final FF’s and checksum into the actual checksum, so that’s why it was consistently off.

I’ll put those changes into effect within the next couple days, although between Christmas, New Years, putting a new Bamboo floor in, etc things have been hectic.

The progress has been particularly slow, which is mainly reflective of the fact that I haven’t spent much time on it.  I’m beginning to worry that my project may be undermined by the delay, in that the floppies continue to deteriorate while I’m screwing around.  I do, however, expect to be able to fine tune my SX code to deal with the actual media problems — as long as the data is SOMEWHAT recognizable.  Perhaps I should find a paper that talks about things like “bit rot” etc with floppies, and see how the actual media changes, etc.

Parallax USR2SER

So I got my Parallax USR2SER in yesterday. Man is this thing tiny!! About the same width of my finger, and about 1/3 the length! And its mostly surface mount stuff…..

It works like a charm. Easy installation, I was just using hyperterminal which will accept up to 921600 baud, so that’s what I was trying. I was bit-banging a port with the “pauseus” SX/B command just for some quick tests. It’s LSB just like RS-232, but not inverted, and is 0-5v. Its ASYNC and so you need start/stop bits which are exactly the same length as a data bit. The start/stop is also inverted from 232 too, which I guessed. The normal idle condition is HIGH, and so the start bit is low, 0’s are low, 1’s are high, and stop bis are high just like the idle condition. So you have to remember to separate your bytes by an extra idle period, but that’s easy enough.

The green RX activity LED on the unit stays on solid when xmitting at 921,600.

I really like the nature of USB and serial vs using a parallel port. I can’t quite explain it, but it feels more solid and reliable to me. I guess the ASYNC nature of it means there are no goofy clocking issues to deal with. And although I’m not sure how windows handles this at any level, but I’ll bet there’s some buffering going on someplace to ensure data doesn’t get dropped.

I haven’t tried receiving the data through my own windows software, but that’s the next step.

losing data

I’ve been thinking more and more about how exactly I’ve been losing data.

It’s alot of data. The worst case I’ve seen is about 140 bytes. This is 1120 bits, or 2240us. This is a LONG time for my SX to really be doing nothing — especially during an active transfer — this is 2.24 milliseconds!

This means my clock is rolling over 1120 times with no activity.

The only thing I can think this means is that I’m not seeing any edges within that timeframe. But why not? What’s different about this dead-period than before and after?

And why does this almost always happen DURING the data-portion of the sector, and not usually during the sector header? The sector headers almost always checksum right.

And if this isn’t obvious, the sector headers are almost always the perfect length. So we don’t drop bits during a sector header. Now not all sector headers are perfect, but 95% of the time, they are. So the length is perfect, and the checksum is perfect.

It sounds like something is losing sync, but the sync occurs with every edge, not just the ones at the beginning of the sector.

The header is 32 bytes, 64 RAW MFM bytes. So this is 512 mfm bits without error. Without dropping a bit, or adding a bit. Or losing data.

This is the question of the week.