شريحة واحدة لتحويل واحد
تستخدم الكثير من المنتجات المعروفة والدوائر التطويرية شريحة FT232RL من FTDI لتحويل الاتصال بين يو اس بي USB وUAR. ان الشريحه FT232RL تحوّل الاتصال دون الحاجة إلى أي ضبط أو برمجة وتوفر واجهة افتراضية Virtual COM لتوفير الاتصال مع منفذ اليو اس بي وهذا يعني انك بحاجة الى شريحة مختلفة اذا أردت إجراء تحويل من نوع تسلسلي مختلف الى اليو اس بي، مثل تحويل من SPI إلى USB باستخدام شريحة FT220X أو تحويل من I2C إلى USB باستخدام شريحة FT201X.
شريحة واحدة لتحويلات متعددة
MPSSE أو Multi-Protocol Synchronous Serial Engine هو اسم الجزء المسؤول داخل الشرائح من شركة FTDI في الأجيال اللاحقة لتوفير ديناميكية في التحويل بين اتصال يو اس بي واتصال تسلسلي من بروتوكولات مختلفة ويقود هذا الجزء ارجل الشريحة للقيام بالتحويل وقيادة الأرجل بشكل مناسب. إن هذه الطريقة الديناميكية في تحويل اليو إس بي إلى أنواع مختلفة من الاتصال التسلسلي وأحد أشهر هذه الأمثلة هو JTAG Debugger معروف باسم OpenOCD ويمكن الاطلاع على المقال التعريفي عن هذا المشروع.
في هذا المقال سوف نتعرف على أساسيات MPSSE و كيف نقوم بإعداده وأيضا كتابة برنامج لقيادة الشريحة التي تحوي MPSSE.
سوف أستخدم الدارة التطويرية الموضّحة في الصورة والتي تحوي شريحة FT2232H أو يمكن استخدام دارة FT2232H mini module الموفّرة من FTDI.
MPSSE من عين “إدارة الأجهزة”
يتوفر MPSSE في الأجيال الحديثة من شرائح شركة FTDI على سبيل التحديد: FT232H و FT2232H و FT4232H وFT2232D. للقيام بضبط MPSSE فإن الواجهة اليو اس بي USB interface المسماة D2XX سوف تُستخدم وهي مصممة خصيصاً لشرائح شركة FTDI ويمكن استخدام التوابع المتوفرة فيها باستخدام مكتبة FTD2XX.DLL وعلى كل حال يتوفر ايضاً الواجهة النمطيّة المسمّاة Virtual COM Port أو VCP ولهذا السبب فإنّنا نرى الواجهتين عند وصل شريحة واحدة إلى الحاسب وهي في الواقع تنتميان لنفس الشريحة.
يمكن الذهاب إلى مدير الأجهزة في ويندوز بعد توصيل الشريحة وسوف ترى الشريحة في مكانين مختلفين وهما: المكان الأول COM & LPT والمكان الثاني Universal Serial Bus controllers وذلك لسبب الذي أوضحنا آنفا.
ومن تفاصيل كل جهاز يمكنه الرؤية بوضوح الاختلاف
الأرجل المتوفرة
بحسب الشريحة التي سوف تقوم باستخدامها يمكن أن يكون لديك قناة واحدة كما في شريحة FT232H او قناتين كما في FT2232H او الشريحه FT2232D او حتى 4 أقنية كما في الشريحة FT4232H.
يوجد في كل قناه مجموعة من الارجل الثابتة للقيام بالتحويل التسلسلي وهي دخل البيانات Data In وخرج البيانات Data Out وإشارة الساعة Clock وإشارة التحديد Chip Select كما يوضحه الجدول أدناه
الجدول التالي يوضح وكل رجل ومقابلها في الاتصال التسلسلي من بروتوكولات مختلفة
التحدث إلى MPSSE: الأوامر
إن الخطوة الأولى لقيادة شريحة FTDI مع MPSSE من برنامجك، هي أن تفهم صياغة أوامر MPSSE وكيفية استخدام المكتبة FTD2XX.DLL .
سنجد أن MPSSE يُقاد عبر الأوامر ولهذا يسمى معالج أوامر command processor . حيث أن استخدام كل ميزة أو وظيفة موجوده فيه يجب أن يسبقه تعليمة وهذا ينطبق على وضع البيانات على الخطوط أو قيادة دخل/خرج أو قراءة حالة دخل.
التحدث إلى MPSSE: المكتبة
للقيام بالتواصل المطلوب بين برنامجك وبين MPSEE فإن هذا يتم عبر مكتبة FTD2XX.DLL وعلى كل الأحوال لو لا تريد استخدام الأوامر المجرّدة بشكل مباشرة فإنه بالإمكان استخدام مكاتب أخرى أكثر تجريداً من طبقة أعلى توفرها شركة FTDI. هذه المكاتب متوفّرة لـ SPI و I2C و JTAG وهي على الترتيب FTCSPI.DLL و FTCI2C.DLL و FTJTAG.DLL.
بالحقيقة يمكنك البدء من هذه المكاتب الأكثر تجريداً إلا أنه من المهم أن تقوم ولو بمثال بسيط باستخدام المكتبة FTD2XX.DLL باستخدام الأوامر بشكل مباشر لترى كيف MPSSE يعمل بالحقيقة. هذا ما سوف نقوم به في المثال القادم حيث سنقوم بقيادة دخل/خرج بواسطة MPSSE.
المثال: تضمين المكتبة
في المثال القادم سوف نستخدم إطار QT C++ framework ويمكنك استخدام البيئه الاكثر مناسبة لك مثل Visual Studio ويفترض ان تكون الخطوات متشابهة.
بداية سوف نبدأ في تحميل المكتبه من صفحة التحميلات ومن ثمّ تضمين المكتبة DLL في البرنامج وهذا يتم القيام به في باضافه السطور التالية في الملف .pro في إعدادات مشروع
INCLUDEPATH += "LIBs" LIBS += -L$$_PRO_FILE_PWD_/LIBs -lftd2xx
توجد الملفات المطلوبة FTD2XX.DLL في المجلد CDM v2.12.28 WHQL Certified بعد التحميل وفك الضغط. انسخ المحتويات الموجودة في المجلد amd64 أو مجلد i386 إلى مجلد المشروع الخاص بك. لقد قمت بتخصيص مجلد يسمى LIBs لهذه الحاجة.
لاحقا قم بتضمين الملف الترويسي ftd2xx.h التالي في المكان الذي سوف تستخدم فيه التوابع من D2XX
المثال: إرسال الأوامر
توفر الشركة توثيق كامل للتوابع في دليل المبرمجين.
نبدأ بمسح للأجهزة المتصلة عبر اليو اس بي باستخدام التابع التالي لإيجاد أجهزة FT:
FT_CreateDeviceInfoList(&numDevs);
حيث أن numDevs يحتوي على عدد الاجهزه من FT المكتشفة
و ثم سوف نحصل على قائمه تفصيليه الاجهزه باستخدام التابع
FT_GetDeviceInfoList(devInfo, &numDevs);
حيث أن devInfo هو مؤشر إلى مصفوفه من نوع FT_DEVICE_LIST_INFO_NODE . إن FT_DEVICE_LIST_INFO_NODE يحتوي على العناصر التالية:
typedef struct _ft_device_list_info_node { ULONG Flags; ULONG Type; ULONG ID; DWORD LocId; char SerialNumber[16]; char Description[64]; FT_HANDLE ftHandle; } FT_DEVICE_LIST_INFO_NODE;
لاحقا سوف نقوم بفتح الاتصال مع الجهاز الهدف باستخدام التابع FT_Open:
FT_Open(device_num, &ftHandle);
حيث إن device_num هو رقم الجهاز المراد الاتصال به إن أرقام الأجهزة هنا مطابقة لترتيب الأجهزة في المصفوفة ‘devInfo’ كما أن ftHandle يشير إلي متحول من نوع FT_HANDLE وهو يحتوي على رقم مرجعي handle سوف يخزن داخل به وهذا الرقم سوف يستخدم لاحقا في البرنامج.
بعد ان يتم الاتصال يكون MPSSE على استعداد لتلقي الأوامر. تتألف كل تعليمة من رمز وبارامترات.
قبل البدء في إرسال الأوامر يجب القيام بخطوتين:
1- الاولى وهي ضبط بعض الإعدادات في الاتصال MPSSE <-> USB مثل IN and OUT transfer size و read and write timeouts و latency
ftStatus |= FT_SetUSBParameters(ftHandle, 65535, 65535); //Set USB request transfer size ftStatus |= FT_SetChars(ftHandle, false, 0, false, 0); //Disable event and error characters ftStatus |= FT_SetTimeouts(ftHandle, 3000, 3000); //Sets the read and write timeouts in 3 sec for the FT2232H ftStatus |= FT_SetLatencyTimer(ftHandle, 1); //Set the latency timer
2- ثانيا التأكد من أن MPSSE وتطبيقك على تزامن sync ولهذه الغاية يتوفّر ما يسمّى الأوامر السيئة ’bad command’ وهي أوامر عندما يجدها MPSSE فإنه يقوم بإرسال القيمة الثابتة متبوعه 0xFA بالأمر السيء Bad Command الذي تسبب بذلك.
إن إرسال الأوامر بين تطبيقك وبين MPSSE عبر اليو اس بي يتم باستخدام التابع FT_Write
ولقراءة الدخل وما يصل من بيانات عبر اليو اس بي يجب التأكد عبر FT_GetQueueStatus من الحالة لرتل الدخل Queue ويجب أن تعيد قيمة غير صفرية لرقم البايتات التي وصلت
إن الكود اللازم لإرسال امر سيء Bad Command مثل 0xAA أو 0xAB يكون على الشكل التالي:
dwNumBytesToSend = 0; OutputBuffer[dwNumBytesToSend++] = '\xAA'; //Add BAD command & xAA* ftStatus = FT_Write(ftHandle, OutputBuffer, dwNumBytesToSend, &dwNumBytesSent); // Send off the BAD commands dwNumBytesToSend = 0; //Clear output buffer do { ftStatus = FT_GetQueueStatus(ftHandle, &dwNumInputBuffer); // Get the number of bytes in the device input buffer } while ((dwNumInputBuffer == 0) && (ftStatus == FT_OK)); //or Timeout bool bCommandEchod = false; ftStatus = FT_Read(ftHandle, InputBuffer, dwNumInputBuffer, &dwNumBytesRead); //Read out the data from input buffer for (dwCount = 0; dwCount < (dwNumBytesRead - 1); dwCount++) //Checkif Bad command and echo command received { if ((InputBuffer[dwCount] == BYTE('\xFA')) && (InputBuffer[dwCount + 1] == BYTE('\xAA'))) { bCommandEchod = true; break; } }
المثال: الواجهة الرسومية
تم تصميم الواجهة التالية لإظهار الأجهزة الموصولة مع اليو اس بي ثم يقوم المستخدم بتحديد الجهاز الذي يريد الذي الاتصال به.
ملاحظة إن الشريحة FT2232H تحوي على قناتين وتُعتبر كل قناة جهاز مستقل.
ان ملفات هذه المرحلة متوفرة في مستودع المشروع.المثال: قيادة الأرجل دخل/خرج
والآن لنقوم بتطبيق حقيقي لـ MPSSE وذلك عبر ضبط مداخل/مخارج. على الرغم من أن MPSSE هو بالأساس لتحويل الاتصال USB إلى اتصال تسلسلي إلا أنه يقوم بتوفير مداخل ومخارج وهذا أمر ضروري الاستخدام في بعض الأحيان مثال في اتصال SPI قد نحتاج الى استخدام رجل إضافية كـ Chip Select
إن الأوامر المستخدمة في ضبط وقراءة المداخل والمخارج هي:
0x80 VALUE Direction
هذا الامر سوف يقوم يضبط الثمانية أرجل الأولى كدخل أو خرج حسب DIRECTION وسوف يفرض القيمه المحدده VALUE عليها عندما تكون خرج. إن القيمة 1 في DIRECTION تحدد الرجل المقابلة كخرج.
0x82 VALUE Direction
هذا الامر سوف يقوم يضبط الثمانية أرجل الثانية كدخل أو خرج حسب DIRECTION وسوف يفرض القيمه المحدده VALUE عليها عندما تكون خرج. إن القيمة 1 في DIRECTION تحدد الرجل المقابلة كخرج.
0x81
هذا الأمر يقوم بقراءة حالة دخل الأرجل الثمانية الأولى وتعيد بايت واحد.
0x83
هذا الأمر يقوم بقراءة حالة دخل الأرجل الثمانية الثانية وتعيد بايت واحد.
مثال
لضبط TCK/SK وTDI/D0 و TMS/CS كخرج ورجل TDO/DI والأرجل GPIOL0-> GPIOL3 بقيمة منخفضة سوف نقوم بارسال التعليمات التالية
0x80 0x00 0x0B
مع العلم أن 1 في بايت التوجيه direction تعني جعل الرجل المقابله خرج
لم أجد في المراجع جدول أو رسم توضيحي لترتيب البتات في البارامترات لذلك قمت بتوضيحها في اثناء التجريب العملي وهذا ما وجدته:
تم تحديث الواجهة السابقة للتحكم بالأرجل المتاحة في القناة. إن الملفات الخاصة بهذه المرحلة توجد في المستودع.
في ما يلي تجربة للواجهة الخاصّة بالمداخل والمخارج وذلك باستخدام برنامج Waveforms مع خاصية Static I/O لجهاز Analog Discovery 2 ولمعرفة عنها أكثر يمكن الرجوع الى التدوينة السابقة المتوفرة على الموقع.
اطّلع على محتوى متعلّق بـ Analog Discovery 2:
– مراجعة جهاز Analog Discovery 2.
– اختبار الدارات الإلكترونية باستخدام إطار Behave بلغة البايثون ودارة Analog Discovery 2.
– فحص مخارج شريحة FTDI باستخدام Analog Discovery 2.
في ما يلي مثال على كيفية عملية القراءة
OutputBuffer[dwNumBytesToSend++] = '\x81'; ftStatus = FT_Write(ftHandle, OutputBuffer, dwNumBytesToSend, &dwNumBytesSent); dwNumBytesToSend = 0; //Clear output buffer Sleep(10); do { ftStatus = FT_GetQueueStatus(ftHandle, &dwNumInputBuffer); } while ((dwNumInputBuffer == 0) && (ftStatus == FT_OK)); //or Timeout ftStatus = FT_Read(ftHandle, InputBuffer, dwNumInputBuffer, &dwNumBytesRead); //Read out the data from input buffer
ما التالي؟
حتى الان لقد تعرفنا على أساسيات MPSSE وكيف يعمل وأيضاً كتابة تطبيق بسيط للاتصال مع جهاز FT والتحكم في المداخل والمخارج. سنقوم في الجزء القادم بإجراء اتصال تسلسلي عبر بروتوكول SPI.