
في حياة كل درج يأتي وقت تريد فيه كتابة المحمل الخاص بك لملف التكوين في FPGA. كان علي المشاركة في تطوير منصة تدريب لقسم الجامعة التقنية. تم تصميم الحامل لدراسة معالجة الإشارات الرقمية ، على الرغم من أن هذا ليس له أهمية خاصة في إطار هذه المقالة. والأهمية هي أن FPGA (Altera Cyclone IV) في قلب المدرج ، حيث يقوم الطلاب بتجميع جميع أنواع مخططات DSP ، كما تصورها مؤلف الجناح. الحامل متصل بالكمبيوتر عبر USB. تحتاج إلى تنزيل FPGA من الكمبيوتر عبر USB.
تم اتخاذ قرار بالاتصال بجهاز كمبيوتر باستخدام FTDI في تجسيد القناة المزدوجة - FT2232H. سيتم استخدام قناة واحدة لتكوين FPGA ، ويمكن استخدام القناة الأخرى لتبادل FIFO عالي السرعة.
يحتوي FTDI على لوحة تصحيح MORPH-IC-II ، حيث تومض Cyclone II FPGA عبر USB. مفاهيم في المجال العام. رمز مصدر برنامج bootloader مفتوح جزئيًا: يتوفر برنامج bootloader نفسه ، ومع ذلك ، يتم نقل كل منطق العمل مع FTDI إلى مكتبة خاصة ولا يمكن تعديله. في الحقيقة ، خططت في الأصل لاستخدام محمل الإقلاع هذا في مشروعي ، أو ، في الحالات القصوى ، جعل صدفي قائمًا على dll. يتم تحميل البرنامج الثابت في FPGA في الوضع التسلسلي السلبي (التسلسلي السلبي - PS) ، يعمل FTDI في وضع MPSSE. على اللوح ، تم تأكيد أداء حل MORPH-IC-II بشكل كامل ، لكن المشكلة ، كما تحدث غالبًا ، لم تأت من أين. اتضح أنه أثناء تشغيل dll MORPH-IC-II ، يتم حظر جميع أجهزة FTDI المتصلة ، وكجزء من مجمع التدريب هناك جهازان آخران مع محولات مماثلة: مولد ومحلل إشارة. العمل في وقت واحد معهم غير ممكن. لعنة غريبة ومزعجة.
تم تنفيذ حالة مماثلة من قبل الرجال من المريخ روفر: USB JTAG programmer MBFTDI . يتم استخدام FTDI أيضًا في وضع MPSSE ، ولكن بخلاف MORPH-IC-II ، يتم تنفيذ عمليات FPGA في وضع JTAG. المصادر متاحة مجانًا ، لكني لم أجد إشارة واضحة لحالتهم (الترخيص). لذلك ، لاستخدامها في مشروع تجاري ، لم ترتفع يدي.
سوف أصحح مثل هذا الخطأ ، كل شيء سيتم تقديمه في إطار هذه المقالة يتم نشره في مستودع مفتوح بموجب ترخيص BSD.
قم بتنزيل ملف التكوين على شريحة FPGA
بادئ ذي بدء ، يجب أن تتعامل مع وضع التمهيد FPGA. بالنسبة لأولئك الذين بدأوا للتو في التعرف على الموضوع ، سأقدم رحلة صغيرة. على الرغم من تثبيت Altera (Intel) FPGAs من عائلة Cyclone IV E على لوحتي ، فإن طرق التحميل متشابهة لمجموعة Cyclone FPGA بأكملها ، وهناك شك في أنها مناسبة بشكل أو بآخر مناسبة للعديد من العائلات الأخرى.
يستخدم هذا النوع من FPGA SRAM المتغير لتخزين بيانات التكوين. تحدد بيانات التكوين هذه وظائف الجهاز الناتج. في المصطلحات المهنية ، غالبًا ما تسمى هذه البيانات "البرامج الثابتة". وبالتالي ، يتم تخزين البرامج الثابتة في ذاكرة وصول عشوائي خاصة وفي كل مرة يتم فيها تشغيل الجهاز ، يجب تحميله في شريحة FPGA. هناك عدة طرق (مخططات التكوين) يمكن من خلالها تحميل البرنامج الثابت في SRAM (القائمة ذات صلة بـ Cyclone IV E):
- المسلسل النشط (AS).
- مواز نشط (ا ف ب)
- المسلسل السلبي (PS)
- التوازي السلبي السريع (FPP).
- JTAG.
يتم اختيار وضع التمهيد المحدد باستخدام المطاريف الخارجية لمجموعة FPGA (مجموعة MSEL). وضع JTAG متاح دائمًا. يشير الوضع النشط إلى أنه عند تطبيق الطاقة ، يقرأ FPGA بشكل مستقل البيانات من الذاكرة الخارجية (التسلسلية أو المتوازية). في الوضع السلبي ، ينتظر FPGA وسيطًا خارجيًا لنقل بيانات التكوين إليه بشكل استباقي. تتناسب هذه المخططات جيدًا مع مفهوم السيد (السيد) - الرقيق (الرقيق). في الوضع النشط ، يعمل FPGA باعتباره سيدًا ، وفي الأوضاع السلبية كسبيدة.
في هذه المشكلة ، ليست FPGA ، ولكن يجب على المستخدم أن يقرر متى يجب تحديث البرنامج الثابت ، لذلك يجب أن يكون وضع التمهيد سلبيًا. ولحفظ أرجل الشريحة ، نختار واجهة تسلسلية. وضع التسلسل السلبي (PS) و JTAG مناسبان هنا. منطق JTAG أكثر تعقيدًا إلى حد ما ، لذلك دعونا نركز على الخيار الأول.
يوضح الشكل أدناه مخطط اتصال FPGA بوحدة تحكم خارجية للتنزيل في وضع PS.

لبدء التكوين ، يجب أن يقوم الرئيسي الخارجي بتوليد انتقال منخفض إلى مرتفع على خط nCONFIG . بمجرد أن تصبح FPGA جاهزة لاستقبال البيانات ، ستشكل مستوى عالٍ على خط nSTATUS . بعد ذلك ، يمكن للسيد البدء في إرسال البيانات على خط البيانات [0] ، وتنبض الساعة المقابلة على خط DCLK . يجب إرسال البيانات إلى الجهاز المستهدف حتى يتم إنشاء مستوى عالٍ على خط CONF_DONE (أو لا تنتهي البيانات) ، ويتحول FPGA إلى حالة التهيئة. وتجدر الإشارة إلى أنه بعد ضبط CONF_DONE على واحد ، يجب تطبيق نبضتي ساعة أخريين حتى تبدأ تهيئة FPGA.
يتم إرسال البيانات عن طريق البت الأقل أهمية ( LSB ) إلى الأمام ، أي إذا كان ملف التكوين يحتوي على التسلسل 02 1B EE 01 FA (خذ المثال كما هو من الكتيب) ، فيجب تشكيل التسلسل على خط البيانات:
0100-0000 1101-1000 0111-0111 1000-0000 0101-1111
وبالتالي ، يتم استخدام خمسة خطوط فقط: خطوط DATA [0] و DCLK للإرسال التسلسلي ، خطوط nCONFIG ، nSTATUS ، CONF_DONE للتحكم.
في جوهرها ، لا يعد وضع PS أكثر من SPI مع معالجة إضافية للعلم.
يجب أن يكون معدل نقل البيانات أقل من الحد الأقصى للتردد المشار إليه في الوثائق ؛ بالنسبة لسلسلة Cyclone IV E المستخدمة في المشروع ، يكون 66 ميجاهرتز.
لا يوجد الحد الأدنى لتردد الإرسال ، من الناحية النظرية من الممكن تعليق التكوين لفترة غير محددة. وهذا يوفر فرصًا ممتازة لتصحيح الأخطاء خطوة بخطوة بمشاركة راسم الذبذبات ، والذي سنستخدمه بالتأكيد.
يوضح الشكل أدناه مخطط توقيت الواجهة مع أهم التوقيتات.

خبيث الوحش مبس
خذ بعين الاعتبار تشغيل FTDI في وضع MPSSE. في رأيي ، يعد وضع MPSSE (محرك تسلسلي متزامن متعدد البروتوكولات) محاولة ناجحة إلى حد ما لإنشاء مصمم واجهة تسلسلية معينة ، لإعطاء المطور الفرصة لتنفيذ بروتوكولات نقل البيانات واسعة النطاق ، مثل SPI و I2C و JTAG وسلك واحد والعديد من الآخرون على أساسهم.
يتوفر الوضع حاليًا للدوائر المصغرة: FT232H و FT2232D و FT2232H و FT4232H. في مشروعي ، أستخدم FT2232H ، لذلك نتحدث عنه إلى حد كبير. بالنسبة لوضع MPSSE ، يتم تخصيص 16 أرجل ، مقسمة إلى وحدتي بايت: يمكن قراءة أو خفض كل حرف L العلوي و H. تتميز الأرجل السفلية الأربعة للبايت L بوظائف خاصة - يمكن أن يحدث نقل البيانات التسلسلي من خلالها. يمكن تكوين كل رجل كمدخل أو إخراج ، يمكن تعيين قيمة افتراضية للإخراج. بالنسبة للإرسال التسلسلي ، وترتيب البتات ( MSB / LSB ) ، وطول الكلمة المرسلة ، وتكرار نبضات الساعة ، والتزامن الأمامي - الأمامي (الصاعد) أو الخلفي (السقوط) ، يمكنك اختيار إرسال نبضات الساعة فقط بدون بيانات ، أو اختيار تسجيل الوقت ثلاثي المراحل (ذات الصلة بـ I2C) وأكثر من ذلك بكثير.
انتقل بسلاسة إلى البرمجة. هناك طريقتان بديلتان لتفاعل البرنامج مع شرائح FTDI: الأولى ، دعنا نسميها كلاسيكية ، في هذه الحالة ، عند توصيلها بمنفذ USB ، يتم تعريف الشريحة في النظام كمنفذ تسلسلي افتراضي (COM) ، ويستخدم نظام التشغيل برنامج تشغيل VCP (منفذ COM الظاهري). لا تختلف جميع البرمجة الإضافية عن برمجة منفذ COM الكلاسيكي: مفتوح - مرسل / محسوب - مغلق. وينطبق هذا على أنظمة التشغيل المختلفة ، بما في ذلك Linux و Mac OS. ومع ذلك ، مع هذا النهج ، لن يكون من الممكن تحقيق جميع ميزات وحدة تحكم FTDI - ستعمل الشريحة كمحول USB-UART. يتم توفير الطريقة الثانية من قبل مكتبة الملكية FTD2XX ، توفر هذه الواجهة وظائف خاصة غير متوفرة في واجهة برمجة التطبيقات لمنفذ COM القياسي ، على وجه الخصوص ، من الممكن تكوين واستخدام أوضاع تشغيل خاصة ، مثل MPSSE و 245 FIFO و Bit-bang. مكتبة FTD2XX API موثقة جيدًا بواسطة دليل مبرمج تطوير تطبيقات البرامج D2XX ، والمعروف على نطاق واسع لفترة طويلة في الدوائر الضيقة. ونعم ، FTD2XX متاح أيضًا لأنظمة التشغيل المختلفة.
واجه مطورو FTDI مهمة دمج MPSSE الجديد نسبيًا في نموذج التفاعل البرمجي D2XX الحالي. ونجحوا ، للعمل في وضع MPSSE يتم استخدام نفس المجموعة من الوظائف كما هو الحال مع الأوضاع "الكلاسيكية" الأخرى ، يتم استخدام نفس مكتبة FTD2XX API.
باختصار ، يمكن وصف خوارزمية العمل في وضع MPSSE على النحو التالي:
- ابحث عن الجهاز في النظام وافتحه.
- قم بتهيئة الشريحة ووضعها في وضع MPSSE.
- اضبط وضع تشغيل MPSEE.
- العمل المباشر باستخدام البيانات: إرسال واستقبال وإدارة GPIO - ننفذ بروتوكول التبادل المستهدف.
- أغلق الجهاز.
كتابة محمل إقلاع
دعونا ننزل إلى الجزء العملي. في تجاربي ، سأستخدم إصدار Eclipse من Oxygen.3a Release (4.7.3a) مثل IDE ، و mingw32-gcc (6.3.0) كمترجم. نظام التشغيل Win7.
من موقع FTDI الإلكتروني نقوم بتنزيل أحدث إصدار حالي من برنامج التشغيل لنظام التشغيل الخاص بنا. في الأرشيف نجد ملف الرأس ftd2xx.h مع وصف لجميع وظائف API. يتم تنفيذ واجهة برمجة التطبيقات نفسها كملف ftd2xx.dll ، لكننا سنترك الاستيراد الديناميكي لوقت لاحق ، وسنستخدم الرابط الثابت: نحتاج إلى ملف المكتبة ftd2xx.lib. بالنسبة لحالتي ، ftd2xx.lib موجود في دليل i386.
في Eclipse ، قم بإنشاء مشروع C جديد. يمكن الوثوق بإنشاء ملف makefile باستخدام IDE. في إعدادات الرابط ، حدد مسار واسم مكتبة ftd2xx (قمت بنقل الملفات المطلوبة إلى دليل المشروع في مجلد ftdi). لن أركز على ميزات إعداد مشروع لـ Eclipse ، لأنني أشك في أن معظمهم يستخدمون بيئات ومجمعين آخرين لبرمجة Win.
النقطة الأولى. ابحث عن جهاز وافتحه
يتيح لك FTD2XX API فتح الشريحة باستخدام معلومات معروفة أو أخرى عنها. قد يكون هذا الرقم التسلسلي الخاص به في النظام: ستأخذ أول شريحة FTDI المتصلة الرقم 0 والرقم التالي وما إلى ذلك. يتم تحديد الرقم في النظام بالترتيب الذي يتم توصيل الدوائر المصغرة به ، وبصورة معتدلة ، فإن هذا ليس مناسبًا دائمًا. لفتح الشريحة بالرقم ، يتم FT_Open
وظيفة FT_Open
. يمكنك فتح الشريحة عن طريق FT_OPEN_BY_SERIAL_NUMBER
التسلسلي ( FT_OPEN_BY_SERIAL_NUMBER
) أو الوصف ( FT_OPEN_BY_DESCRIPTION
) أو حسب الموقع ( FT_OPEN_BY_LOCATION
) ، لذلك يتم FT_OpenEx
وظيفة FT_OpenEx
. يتم تخزين الرقم التسلسلي والوصف في الذاكرة الداخلية للرقاقة ويمكن تسجيله هناك أثناء تصنيع الجهاز مع تثبيت FTDI. يصف الوصف ، كقاعدة عامة ، نوع الجهاز أو العائلة ، ويجب أن يكون الرقم التسلسلي فريدًا لكل منتج. لذلك ، فإن الطريقة الأكثر ملاءمة لتحديد الأجهزة التي يدعمها البرنامج الذي يتم تطويره هي وصفه. سنفتح شريحة FTDI حسب الوصف (الواصف). في الواقع ، إذا علمنا في البداية بسلسلة واصف الرقائق ، فلن نحتاج إلى البحث عن الجهاز في النظام ، ولكن كتجربة ، سنعرض جميع الأجهزة المتصلة بالكمبيوتر باستخدام FTDI. باستخدام وظيفة FT_CreateDeviceInfoList
، FT_CreateDeviceInfoList
قائمة مفصلة بالرقائق المتصلة ، وباستخدام وظيفة FT_GetDeviceInfoList
، FT_GetDeviceInfoList
فيها.
قائمة الأجهزة المتصلة. قائمة: ftStatus = FT_CreateDeviceInfoList(&numDevs); if (ftStatus == FT_OK) { printf("Number of devices is %d\n",numDevs); } if (numDevs == 0) return -1;
مرحبا بحديقتي D:\workspace\ftdi-mpsse-ps\Debug>ftdi-mpsse-ps.exe Number of devices is 4 Dev 0: Flags = 0x0 Type = 0x5 ID = 0x4036001 LocId = 0x214 SerialNumber = AI043NNV Description = FT232R USB UART Dev 1: Flags = 0x2 Type = 0x6 ID = 0x4036010 LocId = 0x2121 SerialNumber = L731T70OA Description = LESO7 A Dev 2: Flags = 0x2 Type = 0x6 ID = 0x4036010 LocId = 0x2122 SerialNumber = L731T70OB Description = LESO7 B Dev 3: Flags = 0x2 Type = 0x8 ID = 0x4036014 LocId = 0x213 SerialNumber = FTYZ92L6 Description = LESO4.1_ER
هناك ثلاثة أجهزة مزودة بشرائح FTDI متصلة بجهاز الكمبيوتر الخاص بي: FT232RL (النوع 0x5) ، FT2232H (النوع 0x6) و FT232H (المرحلة 0x8). تم عرض شريحة FT2232H في النظام كجهازين مستقلين (Dev 1 و Dev 2). واجهة FPGA PS متصلة بـ Dev 2 ، واصفها هو "LESO7 B". افتحه:
تعرض معظم وظائف واجهة برمجة التطبيقات حالة المكالمة من النوع FT_STATUS
، ويتم وصف جميع القيم الممكنة على أنها تعداد في ملف الرأس. هناك العديد منها ، ولكن يكفي أن تعرف أن قيمة FT_OK
هي عدم وجود خطأ ، وجميع القيم الأخرى هي رموز خطأ. أسلوب البرمجة الجيد هو التحقق من قيمة الحالة بعد كل استدعاء لوظيفة API.
إذا تم فتح الجهاز بنجاح ، فعندئذٍ يظهر في متغير ftHandle
قيمة أخرى غير الصفر ، بعض واصفات الملفات المكافئة ، والتي يتم استخدامها عند العمل مع الملفات. يقوم المقبض الناتج بإنشاء اتصال بواجهة الأجهزة ويجب استخدامه عند استدعاء جميع وظائف المكتبة التي تتطلب الوصول إلى الشريحة.
من أجل التأكيد عمليًا على تشغيل النظام للمرحلة الحالية ، يجب أن ننتقل فورًا إلى الخطوة الخامسة من الخوارزمية.
بعد الانتهاء من العمل مع الشريحة ، يجب إغلاقها. للقيام بذلك ، استخدم الدالة FT_Close
:
FT_Close(ftHandle);
النقطة 2. تهيئة الشريحة وتشغيل MPSSE
يعد الإعداد نموذجيًا لمعظم الأوضاع وقد تم وصفه جيدًا في وثائق أساسيات AN_135 FTDI MPSSE .
- نقوم بإعادة ضبط الشريحة. دالة
FT_ResetDevice
. - في حالة وجود أي قمامة في المخزن المؤقت للاستلام ، نقوم بمسحها. وظيفة
FT_Purge
. - اضبط حجم المخازن المؤقتة للقراءة والكتابة. دالة
FT_SetUSBParameters
. - قم بإيقاف التكافؤ.
FT_SetChars
. - وضعنا مهلات للقراءة والكتابة. بشكل افتراضي ، يتم تعطيل المهلات ، وتمكين مهلة الإرسال.
FT_SetTimeouts
. - نقوم بتكوين وقت الانتظار لإرسال حزمة من الشريحة إلى المضيف. افتراضيًا ، تسارع 16 مللي ثانية إلى 1 مللي ثانية.
FT_SetLatencyTimer
. - قم بتشغيل التحكم في التدفق لمزامنة الطلبات الواردة.
FT_SetFlowControl
. - كل شيء جاهز لتنشيط وضع MPSSE. إعادة تعيين وحدة تحكم MPSSE. نستخدم الدالة
FT_SetBitMode
، اضبط الوضع على 0 (mode = 0 ، mask = 0). - قم بتشغيل وضع MPSSE. الوظيفة
FT_SetBitMode
- الوضع = 2 ، القناع = 0.
نقوم بتوحيد وتهيئة الشريحة في وظيفة MPSSE_open
، كمعلمة نقوم بتمرير خط بمقبض الجهاز المراد فتحه:
قائمة MPSSE_open static FT_STATUS MPSSE_open (char *description) { FT_STATUS ftStatus; ftStatus = FT_OpenEx(description, FT_OPEN_BY_DESCRIPTION, &ftHandle); if (ftStatus != FT_OK) { printf ("open failure\r\n"); return FT_DEVICE_NOT_OPENED; } printf ("open OK, %d\r\n", ftHandle); printf("\nConfiguring port for MPSSE use...\n"); ftStatus |= FT_ResetDevice(ftHandle);
البند 3. تكوين وضع MPSEE العملية
في الواقع ، في هذه المرحلة يتم تنشيط معالج MPSSE وجاهز لتلقي الأوامر. الأوامر عبارة عن تتابعات بايت ، أولها بايت "op-code" ، متبوعة بمعلمات الأمر. قد لا يحتوي الأمر على معلمات ويتكون من "op-code" واحد. يتم إرسال الأوامر باستخدام وظيفة FT_Write
، ويمكن الحصول على استجابة من معالج MPSSE باستخدام وظيفة FT_Read
.
بعد إرسال كل أمر ، من المفيد قراءة استجابة المعالج ، لأنه في حالة وجود أمر غير صحيح ، قد تحتوي الاستجابة على رسالة خطأ - الحرف 0xFA. يمكن استخدام آلية "الأمر السيئ - استجابة 0xFA" لمزامنة برنامج التطبيق مع معالج MPSSE. إذا كان كل شيء على ما يرام ، فستعيد الشريحة حرف 0xFA في أمر خاطئ عن عمد. يتم وصف رموز التشغيل في Command Processor (معالج المعالج) لـ MPSSE و MCU Host Emulation Mode .
يأتي تكوين MPSSE في تعيين معدل البيانات والاتجاه والحالات الأولية لخطوط الإدخال / الإخراج.
ضع في اعتبارك تعيين معدل بيانات معالج MPSSE. تختلف إعدادات الرقائق التي تدعم وضع السرعة الكاملة فقط (FT2232 D ) والرقائق ذات السرعة العالية (FT2232 H و FT232H و FT4232H) إلى حد ما. يستخدم الطراز FT2232D القديم ساعة 12 ميجاهرتز ، بينما تستخدم الأجهزة الحديثة 60 ميجاهرتز. ومن هنا صيغة حساب معدل نقل البيانات:
حيث f core هو التردد الأساسي لـ FTDI ، فإن Divisor هو مقسم ثنائي البايت ، والذي ، في الواقع ، يضبط تردد ساعة البيانات.
ونتيجة لذلك ، إذا كان الفاصل يساوي صفرًا ، فسيكون الحد الأقصى لمعدل نقل البيانات 30 ميجابت في الثانية ، وسيكون الحد الأدنى لمعدل نقل البيانات عند فاصل 65535 - 458 بت / ثانية.
سوف نعهد بحساب المقسم إلى المعالج الأولي. يعيد الماكرو المقسوم:
#define FCORE 60000000ul #define MPSSE_DATA_SPEED_DIV(data_speed) ((FCORE/(2*data_speed)) -1)
ويعيد هذان الماكرو وحدات البايت العالية والمنخفضة للمقسّم ، على التوالي:
#define MPSSE_DATA_SPEED_DIV_H(data_speed) ((MPSSE_DATA_SPEED_DIV(data_speed)) >> 8) #define MPSSE_DATA_SPEED_DIV_L(data_speed) \ (MPSSE_DATA_SPEED_DIV(data_speed) - (MPSSE_DATA_SPEED_DIV_H(data_speed)<< 8))
بالإضافة إلى ذلك ، تجدر الإشارة إلى أنه في الرقائق الحديثة للتوافق مع FT2232D القديم هناك 5 مقسم إضافي ، والذي يحول 60 ميجاهرتز إلى 12 ميجاهرتز. يتم تنشيط هذا الحاجز افتراضيًا ، وفي حالتنا يجب إيقاف تشغيله.
نجد كود التشفير المقابل (0x8A) وأمر الخوذة للمعالج:
قائمة تقديم الفريق BYTE byOutputBuffer[8], byInputBuffer[8]; DWORD dwNumBytesToRead, dwNumBytesSent = 0, dwNumBytesRead = 0; byOutputBuffer[0] = 0x8A; ftStatus = FT_Write(ftHandle, byOutputBuffer, 1, &dwNumBytesSent); Sleep(2);
كتجربة ، بدلاً من الأمر الفعلي 0x8A ، سنرسل القيمة 0xFE ، التي لا تتوافق مع أي كود تشغيلي ، ناتج وحدة التحكم:
dwNumBytesToRead = 2: FAh FEh
قام المعالج بإرجاع وحدتي بايت ، بايت بايت الأمر 0xFA وقيمة هذا الأمر غير صحيح. وبالتالي ، من خلال إرسال عدة أوامر في وقت واحد ، لا يمكننا تتبع حقيقة الخطأ فقط ، ولكن أيضًا فهم أي فريق حدث هذا الخطأ.
حتى لا يتم التعامل مع "الأرقام السحرية" في المستقبل ، سنقوم بتنسيق جميع رموز المرجع في شكل ثوابت ونضعها في ملف رأس منفصل.
لتكوين الوضع بالكامل ، تحتاج إلى تحديد اتجاه خطوط الإدخال / الإخراج وقيمتها الافتراضية. دعونا ننتقل إلى مخطط الاتصال. حتى لا تفسد مقالة منتفخة بالفعل ، لقد رسمت جزءًا مثيرًا من المخطط:

يجب تكوين خطوط DCLK و DATA [0] و nCONFIG كمخرجات وخطوط nSTATUS و CONF_DONE كمدخلات. باستخدام الرسم البياني ، نحدد الحالات الأولية التي يجب أن تحتوي عليها الخطوط. للتوضيح ، يتم تلخيص pinout للدائرة في الجدول:
دبوس FPGA | اسم الدبوس | دبوس | MPSSE | الاتجاه | افتراضي |
---|
DCLK | BDBUS0 | 38 | TCK / SK | خارج | 0 |
البيانات [0] | BDBUS1 | 39 | TDI / DO | خارج | 1 |
nconfig | BDBUS2 | 40 | TDO / DI | خارج | 1 |
نستاتوس | BDBUS3 | 41 | TMS / CS | في | 1 |
CONF_DONE | BDBUS4 | 43 | GPIOL0 | في | 1 |
تقع جميع الخطوط المستخدمة في البايت المنخفض لمنفذ MPSSE. لتعيين القيمة ، استخدم كود المرجع 0x80. يفترض هذا الأمر وسيطتين: البايت الأول الذي يتبع شفرة المرجع هو قيمة بتة بت ، والثاني هو الاتجاه (الأول هو منفذ الإخراج ، والصفر هو منفذ الإدخال).
كجزء من مكافحة "الرقم السحري" ، سيتم تنسيق جميع أرقام السلاسل التسلسلية وقيمها الافتراضية على أنها ثوابت:
تحديد المنافذ #define PORT_DIRECTION (0x07) #define DCLK (0) #define DATA0 (1) #define N_CONFIG (2) #define N_STATUS (3) #define CONF_DONE (4)
يبقى فقط للتأكد من تعطيل حلقة TDI - TDO (يمكن تنشيطها للاختبار) ووضعها في وظيفة منفصلة:
سرد وظيفة MPSSE_setup static FT_STATUS MPSSE_setup () { DWORD dwNumBytesToSend, dwNumBytesSent, dwNumBytesToRead, dwNumBytesRead; BYTE byOutputBuffer[8], byInputBuffer[8]; FT_STATUS ftStatus;
النقطة 4. ننفذ بروتوكول التحميل
يبدو أن كل شيء جاهز للتجارب العملية. أولاً ، تحقق من تنفيذ التهيئة بشكل صحيح ، في الجزء الرئيسي من البرنامج ، اتصل MPSSE_open()
و MPSSE_setup()
، وقبل إغلاق الجهاز ( FT_Close
) ، نضع getchar()
فارغًا. قم بتشغيل البرنامج واستخدام الذبذبات للتأكد من تعيين جميع خطوط PS إلى المستويات الافتراضية. تغيير قيمة هذه المستويات في التهيئة (لن يحدث شيء سيئ مع FPGA) ، نتأكد من أن معالج MPSSE يعطي النتيجة المرجوة على أنها صالحة - كل شيء يعمل بشكل كاف ويمكنك المضي قدما في نقل البيانات.
يتم إرسال البيانات واستلامها بشكل متسلسل في وضع الأوامر باستخدام نفس كود التشغيل. البايت الأول من الأمر هو كود التشفير ، الذي يحدد نوع العملية ، متبوعًا بطول التسلسل المرسل أو المستلم ، وإذا كان الإرسال ، البيانات الفعلية. يمكن لمعالج MPSSE إرسال البيانات واستقبالها ، وكذلك القيام بذلك في نفس الوقت. يمكن أن يكون الإرسال إما أقل بتات إلى الأمام (LSB) أو الأكثر أهمية (MSB). يمكن أن يحدث نقل البيانات إما على الحواف الأمامية أو اللاحقة لنبضات الساعة. تحتوي كل مجموعة من الخيارات على شفرة تشغيل خاصة بها ، وتصف كل بتة شفرة تشغيل وضع التشغيل:
بت | الوظيفة |
---|
0 | تزامن الكتابة الأمامية: 0 - موجب ، 1 - سلبي |
1 | 1 - العمل بالبايت 0 - العمل بالبتات |
2 | الحافة الأمامية للقراءة: 0 - إيجابي ، 1 - سلبي |
3 | وضع الإرسال: 1 - LSB ، 0 - MSB أولاً |
4 | نقل بيانات TDI |
5 | قراءة البيانات من خط TDO |
6 | نقل بيانات TMS |
7 | يجب أن تكون 0 ، وإلا فهذه مجموعة أخرى من الأوامر |
عند تكوين FPGAs وفقًا لمخطط PS ، يتم إرسال البيانات على الحافة الأمامية في وضع LSB.إنه أكثر ملاءمة بالنسبة لنا للعمل بالبايت بدلاً من البتات ، وفي هذه الحالة سيأخذ كود المرجع القيمة 0001_1000b أو 0x18 في تمثيل سداسي عشري. وسيطات الأمر ستكون طول التسلسل المرسل (وحدتان بايتتان ، تبدأ بأدنى دلالة) ، وتسلسل البيانات نفسه. يجب أن تؤخذ في الاعتبار ميزة صغيرة: يتم ترميز الطول ناقص واحد. أي إذا أردنا إرسال بايت واحد ، فسيكون الطول 0 ، إذا أردنا إرسال 65536 ، فإننا بحاجة إلى تحديد طول 65535. أعتقد أنه من الواضح سبب القيام بذلك. دعنا نرسل كتلة البيانات كدالة MPSSE_send
.
سرد وظيفة MPSSE_send static BYTE byBuffer[65536 + 3]; static FT_STATUS MPSSE_send(BYTE * buff, DWORD dwBytesToWrite) { DWORD dwNumBytesToSend = 0, dwNumBytesSent, bytes; FT_STATUS ftStatus;
— 65 , - , op-code . byBuffer
, buff
, , op-code . , , .
, "" , 25 , , , 1 ( , #define DATA_SPEED 1000000ul
). :
BYTE byOutputBuffer[] = {0x02, 0x1B, 0xEE, 0x01, 0xFA}; MPSSE_send(byOutputBuffer, sizeof(byOutputBuffer));
( ):

— DATA[0] , — DCLK . . , , .
, SPI ( ). , PS, . nCONFIG , nSTATUS , CONF_DONE . — , , — , .
MPSSE_get_lbyte
, , .
MPSSE_get_lbyte static FT_STATUS MPSSE_get_lbyte(BYTE *lbyte) { DWORD dwNumBytesToSend, dwNumBytesSent, dwNumBytesToRead, dwNumBytesRead; BYTE byOutputBuffer[8]; FT_STATUS ftStatus; dwNumBytesToSend = 0; byOutputBuffer[dwNumBytesToSend++] = MPSSE_CMD_GET_DATA_BITS_LOWBYTE; ftStatus = FT_Write(ftHandle, byOutputBuffer, dwNumBytesToSend, &dwNumBytesSent); Sleep(2);
, op-code , . , - , , . , . MPSSE_set_lbyte
:
MPSSE_set_lbyte static FT_STATUS MPSSE_set_lbyte(BYTE lb, BYTE mask) { DWORD dwNumBytesToSend, dwNumBytesSent; BYTE byOutputBuffer[8], lbyte; FT_STATUS ftStatus; ftStatus = MPSSE_get_lbyte(&lbyte); if ( ftStatus != FT_OK) return ftStatus;
, . : FTDI; MPSSE; rbf- , nCONFIG , N_STATUS ; rbf- ; , , CONF_DONE . , MPSSE FTDI . , nCONFIG "" , , , .
main int main(int argc, char *argv[]) { FT_STATUS ftStatus; BYTE lowByte; DWORD numDevs;
مثال على بدء برنامج:
pen "LESO7 B" OK nConfig -> 0 nConfig -> 1 ** Load complete Configuration complete
rbf- . . 30 / .
, - JTAG.
- FTDI-MPSSE-Altera PS . .
- . . .
- Software Application Development D2XX Programmer's Guide . FTDI. API D2XX.
- FTDI MPSSE Basics. Application Note AN_135 . . FTDI MPSSE. .
- Command Processor for MPSSE and MCU Host Bus Emulation Modes. Application Note AN_108 . op-code. .
- D2XX Drivers . FTDI.