工業製造
産業用モノのインターネット | 工業材料 | 機器のメンテナンスと修理 | 産業プログラミング |
home  MfgRobots >> 工業製造 >  >> Manufacturing Technology >> 製造プロセス

Arduino Amigaフロッピーディスクリーダー/ライター(V2.2)

コンポーネントと消耗品

>
Arduino UNO
× 1
SparkFun Arduino Pro Mini 328-5V / 16MHz
× 1
抵抗1kオーム
× 1
ブレッドボード(汎用)
× 1
ジャンパー線(汎用)
× 1
SparkFunFTDI基本ブレイクアウト-5V
× 1

アプリとオンラインサービス

>
Arduino IDE

このプロジェクトについて

このプロジェクトは、以前のディスクリーダープロジェクトの作業を継続します https://create.arduino.cc/projecthub/projects/485582/

詳細については、をご覧ください。 http://amiga.robsmithdev.co.uk

  • 私の目的: Windows10内からAmigaDDフロッピーディスクとの間でデータを回復および再書き込みするためのシンプルで安価なオープンソースの方法を作成するため。
  • 私の解決策: Arduinoスケッチ+ Windowsアプリケーション(他のO / Sに移植可能 )実際に機能します!
  • 理由: これらのディスクからのデータを将来のために保存するため。また、通常のPCは、書き込み方法が原因でAmigaディスクの読み取り/書き込みができません。

データの書き込み-試行1

したがって、ディスクの読み取りに成功した後、元の物理メディアを保持したい場合は、ディスクを再度書き戻すことをお勧めします。私はこれを逆に解決することを考えました。ソフトウェアから始めます(つまり、ADFディスクファイルをMFMデータに変換して、インターフェイスが何らかの方法で書き込むようにします。 。

そこで、ADFディスクを読み取るクラスを追加し、すべてのセクターを1つのトラックとしてエンコードすることから始めました。作成したデータをデコード部分にフィードバックすることでテストできる可能性があることを知って、これに取り組み始めました。これに取り組んでいる間、私は自分のAmigaの何が悪いのかを見つけようと決心しました。結局のところ、実際のものがないと、作成したディスクをテストできません。 それらをテストします。

A500 +を分解すると、最も一般的な問題の1つである、時計のバッテリーがいたるところに漏れていることに気づきました。そこで、これをボードからはんだ除去し、ボードのクリーンアップに取り掛かりました。その間、私は機械全体を引き出し、20年間のほこりや汚れの掃除に取り掛かりました。フロッピードライブを分解して掃除しました。

掃除をしていると、黄ばみを取り除く時期だと思ったので、Retr0briteの情報に従って試してみました。

次に、メインマザーボードのすべてのジョイントをチェックしたところ、電源コネクタによる接続が緩んでいて、はんだごてを数回修正しただけで、新品同様であることがわかりました。 Retr0briteプロセスに満足するまで待ってから、コンピューターを再組み立てしました。

その間、私はディスクを書き込むためのコードの作業を続けました。ライトプロテクトラインの状態を読みたかったのですが、何を設定しても電圧が変化しなかったようです。そこで、ドライブを引き離し、書き込み保護ステータスを検出する小さなスイッチから小さなICまでのトレースをたどりました。この時点で、出力はおそらく実際にデータを書き込みたいときにのみ利用できると思いました。

たくさんの後 実験の結果、 / WRITE_GATE をプルする必要があることがわかりました。 ドライブをスピンアップして書き込みを有効にする前に、ピンをLOWにします。この時点で、書き込み保護ステータスを取得できます。 / WRITE_GATE ローの場合、そのピンがデフォルトのHIGH状態に戻るまで、ドライブは以前のようにオフに戻りませんでした。

Amigaはトラック全体を一度に書き込みます。メモリ内のトラックは11 * 512バイト(5638バイト)ですが、MFMエンコードして正しいAmigaDOS形式にすると、トラックは14848バイトとして機能します。ええと、Arduinoの2kのメモリにも1kのEEPROMにも収まる方法はありません。別の方法が必要でした。

優先度の高いスレッドで一度に1バイトずつデータを送信し、Arduinoからの応答バイトを待ってから次のスレッドを送信することにしました。キャラクター間のラグを減らすために、ボーレートを2Mに変更しました。つまり、各文字を送信するのに約5.5 uSec、1文字を受信するのに5.5uSecかかりました。 Arduinoは500kHzで8ビットを書き出す必要があるため、16uSecごとに新しいバイトが必要になります。したがって、コードループが十分にタイトで、オペレーティングシステムが送受信をあまり遅らせないと仮定すると、時間が必要です。

これは完全な、完全な失敗でした。読み取り/書き込みサイクル全体が非常に長くかかり、ディスクの1回転をはるかに超えていました。 Arduino側はおそらく十分に高速でしたが、OSは十分に応答しませんでした。 OS(私の場合はWindows)が入ってくるデータをバッファリングするため、ディスクの読み取りは機能しますが、書き込みでは、Windowsはすべてを一度に送信しますが、送信する速度はArduinoが必要とする速度よりもはるかに速いため、データが失われます。これが、私がこの双方向の確認プロセスを決定した理由です。

データの書き込み-試行2

このアプリケーションのソフトウェアフロー制御は、十分な速度ではありませんでした。ハードウェアフロー制御を調査することにしました。 FTDIブレークアウトボードにCTSピンとDTRピンがあることに気づきました。これらは Clear To Send の略です およびデータターミナル対応 。ブレイクアウトボードが接続されているときに、ArduinoボードがCTSをGNDに接続していることに気づきました。

<図>

また、これらのピンが実際にどちらの方向を向いているかもわかりませんでしたが、いくつかの実験の結果、CTSピンがArduinoから信号を送られ、PCがフローを制御するために使用できることがわかりました。通常、これは循環バッファを使用して行われますが、私の場合はこれを許可できなかったため、データが必要ない場合は「1」に設定し、必要な場合は「0」に設定します。

<図>

これは、OSにバイトを1つのチャンクとして一括送信するように依頼できることを意味し、中断されないようにすべてがカーネルレベルで処理されることを期待しています。

8ビットから各ビットを出力する内部ループがありましたが、代わりに8セットのコマンドに分解する方がタイミング的にはおそらく良いと判断しました。

これはうまくいきませんでした。ディスク書き込み部分を実際に実行せずにコードの実行を許可した場合、すべてのバイトが正しく受信されましたが、コードを実行すると、コードは実行されず、受信されたバイトは失われていました。

CTX回線のステータスを変更しても、データの流れがすぐに止まらず、コンピュータが1文字か2文字を送信する可能性があるのではないかと思いました。おそらく私がCTX回線に信号を送ったときまでに、それはすでに次の文字を送信する過程にありました。

データの書き込み-試行3

書き込みタイミングを歪めたくなかったので、シリアル割り込みはしたくありませんでした。フロッピードライブに各ビットを書き込む間に、次のwhileループに多数のCPUサイクルが存在することに気づきました。 CTXがハイになった後に別のバイトが受信されたかどうかを各ビット書き込みの間にチェックして保存することにしました。

私の理論では、CTXを上げたとき、コンピューターはおそらくすでに次のバイトを送信している途中であり、途中で停止できないため、このバイトの半分後になります。つまり、ループ中に余分な1バイトをチェックし、見つかった場合は、シリアルポートを再度確認する代わりに、それを使用するだけで済みます。

したがって、これは機能しているように見え、Arduinoはコンピューターからデータを失うことなく書き込みを完了しました。現在の唯一の質問は、実際にデータを書き込んだかどうか、もしそうなら、そのいずれかが有効かどうかということでした。

この時点では、1つのトラックしかエンコードしていなかったため、アルゴリズム全体を実行して80トラックすべてをエンコードすることにしました。何か奇妙なことが起こっていました。ドライブヘッドはまったく動いていませんでした。読むときはまだそうだったが、書くときはそうではなかった。

ドライブヘッドを前後に動かすには、最初に/ WRITE GATEピンを上げる必要があることがわかりました。これは、サーフェスを変更するためにも必要であると思われます。これを行うためのコードを追加すると、ドライブヘッドが期待どおりに移動しました。これは理にかなっており、頭を動かしているときに誤ってトラックを書き込むのを防ぐことができます。

そのため、この時点で、以前に作成したディスクイメージを書き出して、それを読み戻そうとしました。何も検出できませんでした。私が書いたデータが無効であったか、私が書いた方法が間違っていました。

作成していたエンコードされたMFMセクターデータを、リーダーが使用するセクターデコードアルゴリズムにフィードして、生成したものが正しく有効であることを検証することにしました。ディスクへのデータの書き込み方法に明らかに問題がありました。

データの書き込み-試行4

データが正しく読み取られていなかったため、いくつかの異なるアプローチを試してみることにしました。 / WRITE DATAピンをパルス化する必要があるのか​​(そうであれば、どのくらいの時間で)、トグルするのか、または単に生データ値に設定するのかがわかりませんでした。私の現在の実装はピンをパルスしました。書き込み時に書き込みピンが物理的にどのように操作されると想定されているかについて、オンラインで情報を見つけることができませんでした。

読み取りヘッドは、磁束が反転するたびにパルスを送信します。 WRITE DATAがビットの値に設定されるように、実装を変更することにしました。それもうまくいきませんでした。そこで、ピンの現在の状態を切り替えるようにコードを変更しました。まだ運がない。

明らかに、これらのアプローチの1つが正しいものであったに違いありません。そこで、信頼できるオシロスコープをもう一度取り出して、何が起こっているのかを確認することにしました。トラックのすべてのバイトにMFMパターン0xAAを連続して書き込むことにしました。バイナリの0xAAはB10101010であるため、これにより、必要な周波数を監視できる完全な方形波が得られます。

目的の周波数で完全な方形波が見られなかった場合は、何らかのタイミングの問題があるはずです。

スコープを接続しましたが、タイミングが であることに驚きました。 完全。しかし、古いスコープであるため、数パルスしか見ることができませんでした。スコープには、この素晴らしいx10「mag」モードがありました。押すと、タイムベースが10増加しましたが、さらに重要なことに、最新のデジタルスコープと同じようにすべてのデータをスクロールできるようになりました。

ここで何かが正しくありませんでした。 12ビットごとのように見えたので、「高」の期間になりました。 。

<図>

送信したデータが何らかの形で無効であったか、12ビット程度ごとに書き込みプロセスが一時停止する原因となったものがありました。 1バイトに8ビットしかないことを考えると、12は奇妙な数です。

これを考えた後、フロー制御の問題に戻ったのではないかと思いました。私がループを設計した方法は、1つを待った後に受け取った余分なバイトをすくい上げることでした。しかし、1バイトおきに待機するのを防ぐほどインテリジェントではありませんでした。 何かを移動するという2つの選択肢がありました 割り込みに入れるか、ループにパッチを当てます。

私は、ループが最初に機能する方法を修正することにしました。この問題は、コンピューターからの次のバイトを待機することによって引き起こされた遅延の結果でした。 CTXを下げてバイトを待つと、CTXを再び上げるまでに、別のバイトがすでに進行中でした。

受信した2番目のバイトが使用されたときに、Arduinoが一時的にCTSをローに引き、次に再びハイに引き、別の文字を送信できるようにループを変更します。これは、次のループですでに次のバイトを受信して​​いるため、待機する必要がないことを意味します。

これをテストすると、完全な方形波が生成されました:

<図>

これは、トラックを作成するためのすべてのタイミングが完璧であったことを意味し、実際のにかかっていました。 書き込まれていたデータ。私はこれをいくつかのトラックとサイドで実行し、それを読み返して正しく書き込まれたかどうかを確認することにしました。 / WRITE_DATAピンを受信したデータの対応するビット値に設定していました。

データを読み戻すと、何もエンコードされていないように見えましたが、ディスクの反対側にスキップしました。案の定、私のパターンがありました。なぜディスクの片面にしか書き込まれなかったのかわかりませんでした。

少し考えた後、/ WRITEGATEピンが実際に思ったように機能しないのではないかと思い始めました。ピンを低くすることにより、ドライブの消去ヘッドが有効になっている可能性があります。この場合、実際に書き込みを行っているときにのみこれを行う必要があります。そうしないと、ディスクが回転して消去されるときにディスクにノイズが発生する可能性があります。

/ WRITE GATEが最初にドライブを起動したときにのみ使用され、後で文字通り書き込みループ中にのみ使用されるように、すべてのコードを変更しました。それはうまくいきました!ディスクの両面にデータを書き込んでいました!

そこで、実際のADFディスクイメージで再試行して、完成させました。次に、リーダー部分を使用して、読み戻すことができるかどうかを確認しました。動いた!しかし、何らかの理由で、このディスクを読み戻すのにかなりの時間がかかりました。 MFMエラーは発生していませんが、すべてのセクターを見つけるのに苦労していました。

私が今見ている可能性は2つあります。1つは、データが実際に十分にタイムリーに書き込まれたことです。次に、ディスクは実際に実際のAmigaで機能しますか?

実際にディスクを作成した可能性があるという考えに興奮しすぎて、現在動作中を起動しました。 A500 +でディスクを挿入します。しばらくすると、ディスクの起動が開始され、有名なチェックサムエラーメッセージが表示されました。だから私は何かを書いていました 有効ですが、一貫性がありませんでした。

より正確な速度でデータを読み戻すことができなければ、ディスクに書き込むことは無意味であると判断しました。

データの読み取り(再度)

現在の実装に満足できなかったので、読みの質を向上させたかったのです。現在の実装では、パルスがわずかに奇数の時間に到着するのに十分な柔軟性がありませんでした。新しいアプローチが必要でした。

まず、読み取り値を/ INDEXパルスに同期させることにしました。 Amigaでは必須ではありませんが、後でテスト、書き込み、読み取りに役立つ場合があります。

このプロジェクトの前半へのコメントの何人かの人々は、私が実装した方法ではなく、パルス間のタイミングを記録するべきであると提案しました。これに関する唯一の問題は、このデータをPCに十分に速く取得することでした。ビットごとに1バイトを送信すると、最大2Mボーを簡単に超える可能性があります。

私は、データを少し理解することを試みるのが最善であると判断しました。そこで、元々使用していたカウンターを最大255までフリーランさせることにしました。次に、コードをループに入れてパルスを待機し、この時点でどれだけの時間が経過したかを確認しました。

理想的な状況では、可能な最小値は32(2 uSecに相当)です。 MFMでは、連続して最大3つの0しか持てないため、この値に達する最大値は128でした。これは、連続して最大4つの可能な組み合わせがあったことを意味します。

これらの周波数の大部分がどこにあるかを確認するためにいくつかのディスクをサンプリングしました。結果は以下のとおりです。

<図>

これを見ると、52、89、120のカウンターの周りのポイントの大部分が見つかります。しかし、これらは私のドライブにいくらか固有のものであり、したがって良いガイドラインではありません。いくつかの実験の後、次の式を使用しました: value =(COUNTER-16)/ 32 。 0と3の間でクリップすると、必要な出力が得られました。これらの4つごとに、1バイトを書き出すことができました。

MFMでエンコードされたビットストリームに2つの「1」を一緒に含めることができないため、最初の値のすべてが無効であり、別の「01」シーケンスとして扱われる可能性があると安全に推測できました。次の部分は、PCが受信したこのデータを解凍し、MFMデータに戻すことでした。これは単純で、00は発生しなかったため、01は書き込み「01」を意味し、10は書き込み「001」を意味し、11は書き込み「0001」を意味しました。私はこれを試してみましたが、驚いたことに、私の結果は100%成功しました。私ももう少しディスクを使ってみました、100%!非常に信頼性の高いディスクリーダーができました。

この新しいアプローチにより、ディスクからのデータに対する耐性が大幅に向上したため、フェーズ分析や再試行は不要になりました。私のディスクのほとんどは今完全に読んでいます。いくつかの再試行が必要でしたが、最終的にそこに到達しました。最後の部分は、データを統計的に分析して修復できるかどうかを確認することでしたが、99%の確率で、入ってくる不良データは完全に認識できなかったため、ほとんど役に立ちませんでした。

データの書き込み-試行5

自分が書いたものを高精度で確認できるようになったので、ライターのテストがはるかに簡単になりました。

コードを分析して、何が問題になっているのかを確認しました。トラック全体に0x55シーケンスを書き込んでから、それを読み戻しました。時々、戻ってくるデータが少しずれていました。つまり、書き込みに何らかのタイミングの問題があったことを意味します。

これは、シリアルポートの処理方法と、タイマーの使用によるものであることが判明しました。タイマーが値32に達するのを待って、ビットを書き込んでからリセットしました。タイマーカウンターの値を変更する必要がないように変更しました。

カウンターが16に達したときに最初のビットを書き込み、次に48(16 + 32)に達したときに次のビットを書き込み、80(16 + 32 + 32)に達したときに次のビットを書き込みます。たった8ビットのTimer2は、8ビット目以降、必要なときにゼロにロールオーバーします。これは、必要なタイマー値でビットを書き込んでいる限り、正確に500kbpsになることを意味します。

また、シリアルポートからデータを読み取る方法も確認しました。これは各ビット間で読み取られていましたが、これもできるだけ短くする必要がありました。少し実験した後、最短の作業ブロックを達成しました。

検証をサポートするようにWindowsコードを変更した後、再試行する準備が整いました。今回は、ディスクが正しく検証されれば、Amigaで正しく動作するはずだとわかりました。

そこで、別のディスクを書き出してみました。確認すると、時間がかかりました。新しいアルゴリズムでは、トラックの約95%が最初に検証に合格し、残りの5%だけをもう一度書き直す必要があります。私はこれに満足し、ディスクをAmigaに挿入しました。完璧に機能しました!

データの書き込み-試行6

これを使用している一部の人々からのフィードバックの結果、ドライブで検証を行っても、完全に読み取り可能なディスクが常に生成されるとは限らないことが明らかになりました。ソフトウェアはそれらを完全に読み戻すことができましたが、Amigaコンピューターはあちこちでいくつかのチェックサムエラーを報告しました。

私はコードをもう一度見て、それがタイミングの問題であるかどうか疑問に思い、それを割り込み駆動にすることができるかどうかを調べましたが、悲しいことに、各ビット間の時間が短いため、割り込みをかけるのに十分な時間がありません変更するレジスタなどを保持することでこれを実現します。

次に、書き込みコードを振り返りました。フルバイトが書き込まれた後、タイマーがオーバーフローして0に戻る前に、コードがループバックして次のバイトの書き込みを開始し、最初のビットを早期に書き込むことができる可能性がわずかにあります。

これが起こらないように小さなループを追加しました。これにより、この問題が発生した場合にこれが修正されることを願っています。

データの書き込み-試行7

書き込まれたディスクのチェックサムエラーのレポートをたくさん受け取った後、私は調査を開始しました。最初は、ディスクからMFMデータを確認する必要があると思っていましたが、実際には問題ははるかに単純でした。

XCopy Proを見てチェックサムエラーを確認すると、セクターヘッダーとデータ領域のチェックサムエラーを意味するコード4と6が報告されました。それがデータ領域だったとしたら、それは純粋にトラックの最後の数ビットを書き込むことと関係があると思いましたが、そうではありませんでした。

時々トラックの先頭を上書きしているかどうか疑問に思って、各トラックの周りにある書き込みコードとパディングを調べ始めたので、トラック後のパディングを256バイトから8バイトに大幅に減らしました。驚いたことに、検証しました。その後、大量のエラーを発生させました。

これは、実際の問題は私が十分なデータを書き込んでいないことであるかどうか疑問に思いました。 ArduinoにTrackEraseコマンドを追加して、トラック全体に0xAAパターンを書き込み、その後トラックを書き込むことにしました。驚いたことに、XCopyはそれに100%親指を立てました。うまくいけば、それでその問題は解決しました。

診断

このプロジェクトを成功させた人々から、完全に機能している場合と機能していない場合の両方で、多くのフィードバックがありました。診断モジュールをコードに組み込んで、自分の診断モジュールを機能させることができない人を支援することにしました。

診断オプションは、Arduinoが処理するためのいくつかの追加コマンドと、すべてが正しく配線されていることを確認するために実行される一連のイベント全体で構成されています。

では、次は何ですか?

プロジェクト全体がGNUGeneral Public LicenseV3の下で無料でオープンソースになっています。 Amigaを維持したいのであれば、特権のためにお互いを引き裂いてはいけません。その上、私は今まで取り組んだ中で最高のプラットフォームに恩返ししたいと思います。また、人々がこれを開発し、さらに発展させ、共有し続けることを望んでいます。

別のFTDI /シリアルブレークアウトボードを使用しない限り、現在の書き込みソリューションはArduino UNOのオプションではないため、次のタスクはそれを動作させることです(おそらく、23K256 ICを使用して、トラックに書き込む前にトラックをバッファリングします。ディスク)。

私はまだ他のフォーマットを見たいです。 ADFファイルは優れていますが、AmigaDOS形式のディスクでのみ機能します。カスタムコピー防止機能と非標準セクター形式のタイトルがたくさんありますが、この形式ではサポートできません。これに関して非常に役立つ情報をいくつか受け取りましたが、現在、テストするディスクが多くありません。

ウィキペディアによると、別のディスクファイル形式であるFDI形式があります。十分に文書化されているユニバーサルフォーマット。この形式の利点は、トラックデータをできるだけ元のデータに近づけて保存しようとするため、上記の問題が修正されることを願っています。

また、Software Preservation Society、特にCAPS(正式には Classic Amiga Preservation Society )にも出くわしました。 )およびそれらのIPF形式。少し読んだ後、私はとてもがっかりしました。すべて閉鎖されており、ディスク読み取りハードウェアを販売するためにこのフォーマットを使用しているように感じました。

ですから、私の焦点はFDIフォーマットになります。ここでの私の唯一の懸念は、データの整合性です。読み取りが有効かどうかを確認するためのチェックサムはありませんが、それを解決するためのアイデアがいくつかあります。

コード

スケッチとWindowsアプリケーションのソース
Arduino Sketch、およびWindowsアプリケーションのソースコードの例https://github.com/RobSmithDev/ArduinoFloppyDiskReader

回路図

Arduino ProMiniの回路 ArduinoUNOの回路

製造プロセス

  1. アニメーション
  2. フロッピーディスク
  3. NeoPixelリングでジャイロスコープを楽しむ
  4. Arduino Spybot
  5. FlickMote
  6. 自家製テレビB-Gone
  7. Arduinoゲームコントローラー
  8. クラウドコスチューム
  9. マスタークロック
  10. Pixie:ArduinoベースのNeoPixel腕時計
  11. Arduino Amigaフロッピーディスクリーダー(V1)