الوصول إلى إطارات Redd على FTDI Bridges

لقد أكملنا كتلة نظرية كبيرة تُظهر كيفية إنشاء نظام فرعي FPGA لمجمع Redd ؛ كيفية تنظيم الاتصالات بين FPGA والمعالج المركزي للمجمع ؛ ما مدى سهولة حفظ تدفقات البيانات عالية السرعة في ذاكرة الوصول العشوائي ، والتي تتصل مباشرة بـ FPGA ، لنقلها على مهل إلى المعالج المركزي (أو العكس ، لوضع البيانات في ذاكرة الوصول العشوائي هذه لإخراج سريع لاحق إلى القناة). استعرضنا تقنيات تتبع معالج Nios II. نحن قادرون على تحسين أداء نظام المعالج استنادًا إلى Nios II حتى يسير العمل بأكبر قدر ممكن من الكفاءة. بشكل عام ، لقد درسنا نظرية الحد الأدنى اللازمة ، وقد حان الوقت للذهاب إلى الممارسة من خلال تصميم جهاز غير معقد للغاية ، لكنه مفيد عمليًا ... ولكن هناك واحدًا ولكن.

من التعليقات على المقالات ، لاحظت أن بعض القراء يعتقدون أن ريد و FPGA مثل لينين والحزب. أن ترتبط ارتباطا وثيقا. في الواقع ، هذا ليس كذلك على الإطلاق. أردت فقط بدء محادثة حول مجمع Redd بشيء مثير للاهتمام ، ولكن ما الذي يمكن أن يكون أكثر إثارة للاهتمام من FPGA؟ حسنًا ، وبدء محادثة ، فإن المقاطعة بنظرة غبية. وأخيراً ، الكتلة المنطقية الكبيرة كاملة. ولإظهار أن FPGAs بعيدة كل البعد عن Redd ، أقترح إعداد ثلاث مقالات تقريبًا حول أشياء غير مرتبطة بها. حسنًا ، وبعد الانتهاء من هذه الكتلة ، انتقل بالفعل إلى ممارسة FPGA.



مقدمة


الأمر الأكثر إثارة للدهشة هو أنه بمجرد أن قررت أن أستنبط في مواضيع أخرى ، ألقى بي الرؤساء الجيدين في معركة صعبة على مشروع حيث يجري العمل مع لغة VHDL و Xilinx FPGA. أولاً ، لهذا السبب لم أحمل لفترة طويلة قلمًا بشكل عام ، وثانيًا ، من الواضح أن إعداد المقالات العملية يتطلب عددًا كبيرًا من التجارب. من الصعب إلى حد ما التعامل مع VHDL / Verilog و Xilinx / Altera في نفس الوقت. لذلك يجب إجراء أي استراحة في القصص حول FPGAs على أي حال.

هكذا. في المقالة الأولى من السلسلة ، درسنا بالفعل المخطط الهيكلي لمجمع Redd. دعونا نفعل ذلك مرة أخرى.



في مقال اليوم ، من غير المحتمل أن يجد خبراء Linux معلومات قيمة للغاية ، لكن من المفيد البحث عن الصور بشكل سطحي. أولئك الذين ، مثلي ، الذين اعتادوا على العمل من Windows ، سيجدون قائمة بالتقنيات الجاهزة التي تسمح لك بالعمل مع المجمع. بشكل عام ، ستجلب هذه المقالة مهارات هؤلاء ومجموعات القراء الأخرى إلى قاسم مشترك.


كتل UART (المنافذ التسلسلية)


في مخطط الكتلة ، نرى وحدة التحكم FT4232 التي تنفذ 4 منافذ تسلسلية (UART):



ولكن إذا كنت تتحدث أكثر قليلاً على مستوى العالم ، فإن مجمع Redd ليس به أربعة منافذ ، ولكن ستة منافذ تسلسلية. لقد ذكرنا للتو أربعة مستويات CMOS ، واثنان آخران ملحومان على اللوحة الأم ، لأن المجمع يعتمد على جهاز كمبيوتر عادي.



وفقا لذلك ، لديهم مستويات - RS232 (زائد أو ناقص 12 فولت). منافذ RS232 - كل شيء واضح معهم ، يتم عرضها في شكل موصلين DB-9 قياسيين ،



وأين تبحث عن خطوط بمستويات CMOS؟ بشكل عام - على موصل مشترك. يظهر pinout الخاص به في مخطط الدائرة الكهربائية. هناك ، من بين أمور أخرى ، جهات اتصال المقابلة UART.



خارجيًا ، يبدو هذا الرابط كما يلي:



كيفية استخدامها يعتمد على المهمة. يمكنك الاستفادة من توصيل كل جهاز. هذا النهج مفيد إذا كان شخص ما يستخدم مجمع Redd لاختبار الأجهزة المصنعة بشكل دوري من نفس النوع. لكن الغرض الرئيسي من المجمع لا يزال تصحيح الأخطاء التي يجري تطويرها. وفي هذه الحالة ، من الأسهل الاتصال به بطريقة مؤقتة. يكون هذا النمط المؤقت مرئيًا على شاشات التوقف لجميع المقالات: يتم إدخال أسلاك Aruino مباشرةً في الموصل. بطبيعة الحال ، لا يزال فرز جهات الاتصال أمرًا ممتعًا ، وإذا ما تم إطلاقها عن طريق الخطأ ، فسيكون من الصعب للغاية استعادة التبديل بحيث يكون من السهل إعادة توصيل كل شيء من نقطة الصفر ؛ لذلك ، لتسهيل الحياة ، هناك لوحة صاعدة يمكنك الاتصال بها على الأقل بمساعدة موصلات من صفين ، على الأقل بنفس أسلاك Arduino.



الوصول إلى البرامج UART


يعد المنفذ التسلسلي عنصرًا راسخًا وموحدًا جيدًا ، وبالتالي فإن العمل به لا يمر ببعض مكتبات FTDI المحددة ، ولكن من خلال الوسائل القياسية. لنلقِ نظرة على كيفية ظهور هذه الأدوات في نظام Linux.

أسماء الموانئ


من عدد من المقالات والمنتديات على الشبكة ، يتبع ذلك أن أسماء المنافذ التي توفرها محولات USB التسلسلية هي بالتنسيق / dev / ttyUSB0 و / dev / ttyUSB1 وما إلى ذلك. في Linux ، يمكن عرض جميع الأجهزة باستخدام نفس الأوامر الخاصة بعرض الدلائل العادية (في الواقع ، تكون الأجهزة هي نفس الملفات). دعونا نرى ما هي الأسماء في نظامنا. نعطي الأمر:
ليرة سورية / ديف /



يتم تمييز الأسماء التي تهمنا باللون الأحمر. شيء كثير منهم. أي منفذ يتوافق مع ماذا؟ أولئك الذين هم على دراية جيدة بنظام Linux يعرفون آلاف التعويذات في جميع المناسبات. لكن بالنسبة لأولئك الذين ما زالوا يعملون مع Windows 3.1 (جيدًا ، بالتوازي مع المرأة العجوز القبيحة جدًا RT-11) ، لا يزال من الصعب تذكرها ، مع تقدم العمر ، يصعب تذكر الجديد. لذلك ، من الأسهل العثور على كل شيء في كل مرة ، باستخدام طرق بسيطة. وسلطت الضوء على مدخل هذا المسار البسيط بإطار أخضر. دليل فرعي شرطي. الآن نحن نبحث في / ديف / مساحة الاسم. ودعنا نرى الفضاء / ديف / المسلسل :



! ممتاز نحن ندخل في التسلسل الهرمي ، ونلقي نظرة على space / dev / serial / by-id . إذا نظرنا إلى الأمام ، سأقول أنه بالنسبة للعرض الصحيح ، فأنت بحاجة إلى استخدام الأمر ls مع مفتاح التبديل -l (بفضل رئيسي في التوضيح). وهذا هو ، ونحن نعطي الأمر:
ls –l / dev / serial / by-id



من ناحية ، كل شيء على ما يرام. الآن نعرف الأسماء الموجودة في المساحة / dev / ttyUSBX التي تتوافق مع أي جهاز. على وجه الخصوص ، المنافذ التي ينظمها الجسر FT4232 (رباعية) لها أسماء من ttyUSB3 إلى ttyUSB6 . لكن من ناحية أخرى ، عند النظر في هذا الموقع ، أدركت أنه في غرفة الأوزان والمقاييس في باريس ، يجب أن يكون هناك بالضرورة غرفة يتم فيها وضع معيار الفوضى ... لأنك تحتاج بطريقة ما إلى أن تكون قادرًا على قياس قيمتها. حسنًا ، دعنا نقول أن نقص المنافذ / dev / ttyUSB0 و / dev / ttyUSB1 يمكن تفسيرهما بسهولة. ولكن كيف يمكن توضيح أن المنافذ "الأصلية" بناءً على نسل جسر FTDI المثبت يتم ترقيمها من المراكز الثلاثة الأولى ، وأن وحدة التحكم Prolific التابعة لجهة خارجية ، والتي تم إدخالها لمشروع معين ، أخذت المنفذ رقم 2؟ كيف يمكن للمرء العمل في مثل هذه البيئة؟ غدًا سيقوم شخص ما بتوصيل وحدة تحكم أخرى بالمجمع (نظرًا لأن المجمع يسمح لمجموعات مختلفة من المطورين بالعمل مع أجهزة مختلفة في نفس الوقت) ، وتنتقل المنافذ مرة أخرى. ما المنافذ التي نحتاجها للتسجيل في ملف التكوين لتطبيق العمل؟

اتضح أن كل شيء ليس سيئا للغاية. أولاً ، الاسم الأصفر / dev / ttyUSB3 والاسم الأزرق / dev / serial / by-id / usb-FTDI_Quad_RS232-HS-if00-port0 هما اسمان مستعاران لنفس الجهاز. ويمكن أيضًا تقديم الخيار الثاني كاسم منفذ ، لكنه بالفعل أكثر دواما من الأول. صحيح ، في هذه الحالة ، كل شيء سيء إلى حد ما. يمكن توصيل وحدة تحكم خارجية قائمة على FT4232 بالمجمع ، وسيكون من الضروري بالفعل التعامل مع ترقيمها. وهنا "ثانيا" يأتي لمساعدتنا. وهي اصطلاح تسمية بديل آخر. نتذكر أن الدليل / dev / serial لا يحتوي فقط على الدليل الفرعي / by-id ، ولكن أيضًا على الدليل الفرعي / by-path . نتحقق من محتوياته (يقع في أسفل الشكل التالي ، أسفل خط أحمر).



كل شيء هنا مرتبط بالعمارة المادية. لقد سبق أن قلت عدة مرات أن جميع وحدات التحكم داخل المجمع ملحومة باللوحات ، وبالتالي فإن التسلسل الهرمي الداخلي لن يتغير. وبالتالي ، سيكون الاسم /dev/serial/by-path/pci-0000:00:15.0-usb-0:6.5:1.0-port0 هو الأصعب.

إجمالًا ، لدينا الطريقة التالية للبحث عن اسم المنفذ (يجب أن يتم ذلك مرة واحدة ، ويمكن وضع نتائج مثيل المجمع في الجدول واستخدامها باستمرار):

  1. قم بإصدار الأمر ls –l / dev / serial / by-id .
  2. لإصدار الأمر ls –l / dev / serial / by-path .
  3. من نتائج النقطة 1 ، ابحث عن اسم المنفذ المقابل للمنفذ المطلوب للجسر المطلوب. ابحث عن نفس اسم المنفذ في نتائج الفقرة 2. خذ الاسم الفعلي المطابق لهذه الفقرة.

بالنسبة إلى المنافذ التي تخدمها وحدة التحكم على اللوحة الأم ، كل شيء أكثر تعقيدًا. هنا لا يمكنك الخروج من أبسط أمر " ls / dev " ، لكن عليك أن تتذكر شيئًا (جيدًا ، أو على الأقل تذكر أنه يمكنك الاتصال هنا للحصول على المساعدة). تقول في كل مكان أن أسماء المنافذ النموذجية هي ttyS0-ttyS3 . يبقى السؤال ، ما هي أسماء المنافذ الحقيقية في نظامنا؟ لقد وجدت الإملائي التالي الإجابة على هذا السؤال:
ls / sys / class / tty / * / device / driver

إليك استجابة النظام لذلك:



اتضح أننا بحاجة إلى استخدام الأسماء / dev / ttyS2 و / dev / ttyS3 . لماذا - أنا لا أعرف. لكن هناك شيئًا واحدًا يرضي: هنا لا توجد تغييرات خاصة متوقعة ، وبالتالي يمكن تذكر هذه الثوابت واستخدامها دون خوف من أن تتغير.

تطوير التعليمات البرمجية


عند التطوير ، يجب عليك استخدام دليل البرمجة التسلسلي الرائع لأنظمة التشغيل POSIX (أول رابط مباشر تحصل عليه هو https://www.cmrr.umn.edu/~strupp/serial.html ، ولكن لا أحد يعرف كم من الوقت سيعيش). من المهم بشكل خاص أن توضح كيفية التعامل مع مجموعة كاملة من الإشارات ، لأن المنافذ في المجمع يتم تنفيذها بالكامل. صحيح ، اليوم سوف نستخدم فقط خطوط Tx و Rx.

عادةً ما أعطي نتائج رسم الذبذبات ، لكن اتضح الآن أنني في ظروف حقيقية تقريبًا: المجمع يقع حيث لا تصل يدي ، لذلك لا يمكنني توصيل مجس الذبذبات. لرؤية بعض النتائج على الأقل ، بناءً على طلبي ، أضاف الزملاء بضع منشورات إلى المجمع وفقًا للنظام الكلاسيكي التالي:



دعنا نحاول نقل من منفذ إلى آخر. في حالتنا ، يتم توصيل المنافذ /dev/serial/by-path/pci-0000:00:15.0-usb-0:6.5:1.2-port0 و /dev/serial/by-path/pci-0000:00:15.0- usb-0: 6.5: 1.3-port0 .

لقد ناقشنا بالفعل كيفية كتابة برامج المعالج المركزي Redd في إحدى المقالات السابقة ، لذلك سنقتصر اليوم على نص البرنامج المكتوب فقط تحت تأثير وثيقة Serial Programming Guide for POSIX Systems Systems . في الواقع ، فإن النقطة المثيرة للاهتمام الرئيسية هي تحويل إستراتيجية الاستقبال إلى قراءة غير مانعة ، والباقي تافه. ومع ذلك ، وبالنظر إلى الفوضى في الأمثلة على الشبكة حول هذا الموضوع ، من الأفضل أن يكون لديك عينة تافهة في متناول اليد (سيظهر لاحقًا أنه حتى مثال على هذا المستند الرائع لم ينجح بنسبة 100 ٪ ، فإن الكود أدناه يختلف عن الشرائع الموصوفة به في سطر واحد ، ولكن يختلف عن ذلك أدناه).

نفس رمز العينة
#include <cstdio> #include <unistd.h> /* UNIX standard function definitions */ #include <fcntl.h> /* File control definitions */ #include <errno.h> /* Error number definitions */ #include <termios.h> /* POSIX terminal control definitions */ int OpenUART(const char* portName, speed_t baudRate) { //   int fd = open(portName, O_RDWR | O_NOCTTY | O_NDELAY); //     if (fd == -1) { return fd; } //     fcntl(fd, F_SETFL, FNDELAY); //    termios options; tcgetattr(fd, &options); // ,       // ,   .  ... cfsetspeed(&options, baudRate); //    ... // 1  ,   , 8    options.c_cflag &= ~PARENB; options.c_cflag &= ~CSTOPB; options.c_cflag &= ~CSIZE; options.c_cflag |= CS8; options.c_cflag |= (CLOCAL | CREAD); // , ... tcsetattr(fd, TCSANOW, &options); return fd; } int main() { printf("hello from ReddUARTTest!\n"); int fd1 = OpenUART("/dev/serial/by-path/pci-0000:00:15.0-usb-0:6.5:1.3-port0", 9600); int fd2 = OpenUART("/dev/serial/by-path/pci-0000:00:15.0-usb-0:6.5:1.2-port0", 9600); if ((fd1 != -1) && (fd2 != -1)) { static const unsigned char dataForSend[] = {0xff,0xfe,0xfd,0xfb}; //      write(fd1, dataForSend, sizeof(dataForSend)); unsigned char dataForReceive[128]; ssize_t cnt = 0; //     ,  , //         int readSteps = 0; //      ,   while (cnt < (ssize_t)sizeof(dataForSend)) { readSteps += 1; ssize_t rd = read(fd2, dataForReceive + cnt, sizeof(dataForReceive) - cnt); //   - ,     if (rd <= 0) { usleep(1000); } else //  -   { cnt += rd; } } //   printf("%d read operations\n", readSteps); printf("Read Data: "); for (unsigned int i = 0; i < cnt; i++) { printf("%X ", dataForReceive[i]); } printf("\n"); } else { printf("Error with any port open!\n"); } //   if (fd1 != -1) { close(fd1); } if (fd2 != -1) { close(fd2); } return 0; } 


Run - نحصل على النتيجة المتوقعة:

 hello from ReddUARTTest! 14 read operations Read Data: FF FE FD FB 

يمكن ملاحظة أن 4 بايت استغرق 14 محاولة ، أي أن القراءة لم تمنع. في بعض الأحيان ، قام النظام بإرجاع حالة "عدم وجود بيانات جديدة" ، وذهب البرنامج للنوم لمدة مللي ثانية واحدة.

بشكل عام ، كل شيء على ما يرام ، لكن بدون وجود مرسمة الذبذبات ، لا يمكنني التأكد من أن اثنين من المنافذ القائمة على الشريحة نفسها يحددان السرعة بالفعل. لقد قفزت بالفعل إلى حقيقة أن السرعة كانت هي نفسها (لأنه كان لديه وحدة تحكم واحدة) ، ولكن ليس تلك التي طلبتها. دعونا نتحقق بطريقة أو بأخرى على الأقل من التحكم فيه على الأقل. للقيام بذلك ، سأقوم بتعيين سرعة منفذ الاستقبال لمضاعفة سرعة منفذ الإرسال. ومعرفة فيزياء عملية نقل البيانات ، يمكنك التنبؤ بكيفية تشويه هذه البيانات أثناء الاستقبال. دعونا ننظر في نقل 0xff بايت في شكل رسوم بيانية. بت S - بدء (هناك دائمًا صفر) بت ، بت بت توقف (هناك دائمًا) ، بت 0- 0 - بت (لل 0xFF ثابت - كافة الوحدات).



الآن ، دعنا نتراكب هذا العرض مع عرض كيف سيتم عرض كل شيء بواسطة جهاز استقبال يعمل بسرعة مضاعفة:



غرامة. يجب قبول القيمة "1111 1110" (البيانات تنتقل إلى الأمام الأقل أهمية) ، أي 0xFE. لا يؤثر النصف الثاني من القيمة المرسلة على الاستقبال ، حيث تتوافق الوحدات مع الصمت في الخط. هذا هو ، أرسلنا بايت واحد ، سوف يأتي أيضا بايت واحد.

سنبني نفس الرسم البياني للتحقق ، والذي يتوافق مع قيمة 0xFE المنقولة:



توقع القيمة "1111 1000" أو 0xF8. حسنًا ، دعنا نتحقق مما يجب توقعه من خلال القيمة التي تم تمريرها 0xFD:



نحصل على القيمة 0xE6. حسنًا ، بالنسبة للقيمة المرسلة 0xFB ، نحصل على 0x9E المستلمة (يمكنك رسم الرسم البياني وانظر بنفسك). ! رائع نقوم بتغيير سطر واحد في تطبيق الاختبار ، مع استبدال سرعة 9600 بـ 19200:

  int fd2 = OpenUART("/dev/serial/by-path/pci-0000:00:15.0-usb-0:6.5:1.2-port0", 19200); 

نبدأ ونحصل على نتيجة العمل هذه:

 hello from ReddUARTTest! 9 read operations Read Data: FE F8 E6 9E 

بالمناسبة ، أنا لم أذهب عبثا هذا الاختيار. في البداية ، استخدمت وظائف ضبط السرعة الأخرى (زوج cfsetispeed / cfsetospeed) ، ولم يعملوا! بفضل هذا الاختبار ، تم تحديد المشكلة وحلها في الوقت المناسب. عند العمل مع المعدات ، لا يمكنك أبدًا الوثوق في الحدس. يجب فحص كل شيء!

إدارة خط الطاقة 220 فولت


بشكل عام ، لا ترتبط 220 من خطوط الكهرباء بموضوع المقال (جسور FTDI) ، لكنها مرتبطة بموضوع هذا القسم (المنافذ التسلسلية). دعنا نلقي نظرة سريعة عليهم.



عندما أدرجنا الموانئ ، رأينا هذا الاسم:



هذا هو المنفذ التسلسلي الظاهري. إنه ظاهري لدرجة أنه لا يهم المعلمات التي لديه (سرعة المنفذ ، عدد البتات ، تنسيق التماثل ، إلخ). بغض النظر عن المعلمات التي تم تعيينها ، سيظل قادرًا على التعامل مع الأوامر تمامًا. وهذه الفرق هي التي تتحكم في منافذ الطاقة في المجمع.



عند تطوير نظام القيادة ، تقرر التخلي عن واجهات الأوامر المعقدة. تأخذ الإدارة بايت واحد ، دون تأطير الجمل وغيرها من الرتوش ، على الرغم من أن البايت نصية (بحيث يمكن نقلها بسهولة من الجهاز عند تصحيح الأخطاء). يتم شرح هذا الإيجاز بسهولة: تتيح لك واجهة السلسلة التعامل مع التداخل في قناة UART غير الآمنة. ولكن في حالتنا ، جسديا ، يمر العمل عبر قناة USB ، والتي تحميها رموز التحكم الدورية. تتطلب معالجة دفق الإرجاع إما كتابة تعليمات برمجية إضافية أو تخزين مؤقت للمخازن المؤقتة ، وهو أمر غير مناسب دائمًا. هذا هو السبب في عدم وجود معايير للسلاسل ، لا توجد إجابات. ويعتقد أن القناة مستقرة. إذا كنت تريد استجابة ، يمكنك طلب ذلك صراحة. أي أنه يمكن دائمًا التحقق من أداء الكتلة بسهولة عن طريق إرسال بايت إضافي بعد الأمر.

النظر في الأوامر التي يمكن إرسالها:
الفريقموعد
'A'قم بتشغيل المنفذ الأول
'A'أطفئ المخرج الأول
'B'قم بتشغيل المنفذ الثاني
'B'قم بإيقاف تشغيل المنفذ الثاني
'C'قم بتشغيل المنفذ الثالث (إن وجد)
'C'أغلق المنفذ الثالث (إن وجد)
استعادة حالة المخرج

القيادة؟ (علامة الاستفهام) هي الوحيدة التي تُرجع استجابة. استجابة لذلك ، تأتي 3 بايت دائمًا ، كل منها يتوافق مع حالة أحد المنافذ. في الواقع ، تتوافق الولايات مع الأوامر. على سبيل المثال ، "abc" - جميع المنافذ الثلاثة مغلقة الآن ، "Abc" - الأول في وضع التشغيل ، والثاني والثالث في وضع إيقاف التشغيل ، إلخ.

بالنسبة للتجارب مع هذا النظام الفرعي ، أقترح عدم كتابة برنامج خاص (لا يختلف عن البرنامج المذكور سابقًا ، فقط البيانات المرسلة إلى المنافذ ستكون مختلفة) ، ولكن باستخدام أدوات نظام التشغيل واللعب بشكل تفاعلي مع المقابس.

بعد الكثير من التجارب على تتبع المنفذ من خلال أمر cat وإرسال الأوامر في نافذة متوازية باستخدام برنامج echo ، أدركت أنه لسبب ما لا أستطيع تحقيق النتائج في زوج من المحطات الطرفية المعيارية على أساس المعجون (حتى اللعب مع تلك المنافذ التي لا تستخدمها إلا انه جرب تماما مع برنامجه). لذلك ، اضطررت إلى تثبيت برنامج minicom القياسي. دعني أذكرك بأمر التثبيت:
سودو عرضة الحصول على minicom

بعد ذلك ، قم بتشغيله باستخدام الأمر:
minicom –D / dev / ttyACM0

اسم المنفذ قصير ، لأنه من السهل إدخال التجارب باستخدام التجارب اليدوية. في عمل البرامج ، كما هو الحال دائمًا ، من الأفضل استخدام اسم مرتبط بالتسلسل الهرمي للجهاز. مرة أخرى ، ألاحظ أنني لا أقوم بتكوين أي معلمات منفذ أخرى لأنها ظاهرية. سوف تعمل مع أي إعدادات.

ثم نضغط على علامة الاستفهام في الجهاز وعلى الفور (بدون تغذية السطر) نحصل على استجابة



هذا يعني أن جميع المنافذ مغلقة حاليا. دعنا نقول أننا نريد تشغيل المنفذ الثاني. اضغط على العاصمة "ب". لا يوجد رد فعل على الشاشة. اضغط على "؟" مرة أخرى ، حصلنا على سطر جديد مع الإجابة:



كل شيء يعمل. لا تنسى إيقاف تشغيل 220 فولت (الأمر "ب"). يمكنك الخروج من المحطة عن طريق الضغط على ctrl + A على التوالي ، ثم X. اكتمال التجربة.

SPI و I 2 C الإطارات


يتم تنفيذ حافلات SPI (التي يمكن أن تعمل أيضًا في وضع Quad-SPI) و I 2 C بالاقتران مع الجسور العالمية. وهذا بشكل عام ، يحتوي المجمع على جسرين ، يمكن تشغيل كل منهما إما في وضع SPI أو في I 2 C. في المخطط الهيكلي ، يبدو القسم المقابل كما يلي:



يمكن رؤية جوهر تشغيل الحافلات النهائية من مخطط الدائرة الكهربائية. النظر في واحد فقط من اثنين من وحدات التحكم:



وبالتالي ، لا تتقاطع حافلات SPI و I 2 C بأي شكل من الأشكال. يتم تحديد القيود المفروضة على استخدامها المشترك فقط من خلال القيود التي تفرضها FTDI في وحدة تحكم FT4222H. لسوء الحظ ، تنص الوثائق على أن واجهة واحدة فقط يمكن أن تكون نشطة في وقت واحد:



كيفية إدارة الخطوط CFG1_0..CFG1_1 و CFG2_0..CFG2_1 ، سنلتقي في المقالة التالية. الآن نحن نعتقد أنهم جميعا ألغي.

بشكل عام ، يتم وصف العمل بجهاز التحكم جيدًا في الوثيقة FT4222H USB2.0 إلى QUADSPI / I2C BRIDGE IC ، وبالتالي ، فإننا لن نفكر في ميزات أوضاع تشغيل وحدات التحكم. كل شيء واضح جدا من الوثيقة المذكورة.

أما بالنسبة لدعم البرامج ، فيمكن العثور على الوصف الخاص به في الوثيقة AN_329 التي لا تقل أهمية عن دليل المستخدم لـ LibFT4222 . لقد عملنا بالفعل مع جسر FTDI مرتين: في النصف الثاني من هذه المقالة وفي النصف الثاني من هذا . لذلك ، وبمقارنة هذا المستند بهذه المقالات ، يمكنك اكتشافها بسرعة والبدء في كتابة التعليمات البرمجية الخاصة بك. اسمحوا لي أن أريك فقط رمز المرجع الذي يرسل البيانات إلى ناقل SPI ، دون الخوض في تفاصيل تنفيذه ، يبدو مؤلمًا أنه قد تم تحليله بالفعل باستخدام FT2232.

رمز يرسل البيانات إلى ناقل SPI.
 #include "../ftd2xx/ftd2xx.h" #include "../LibFT4222/inc/LibFT4222.h" void SpiTest (int pos) { FT_HANDLE ftHandle = NULL; FT_STATUS ftStatus; FT4222_STATUS ft4222Status; //   ftStatus = FT_Open(pos, &ftHandle); if (FT_OK != ftStatus) { // open failed printf ("error: Cannot Open FTDI Device\n"); return; } ft4222Status = FT4222_SPIMaster_Init(ftHandle, SPI_IO_SINGLE, CLK_DIV_4, CLK_IDLE_LOW, CLK_LEADING, 0x01); if (FT4222_OK != ft4222Status) { printf ("error: Cannot switch to SPI Master Mode\n"); // spi master init failed return; } uint8 wrBuf [] = {0x9f,0xff,0xff,0xff,0xff,0xff,0xff}; uint8 rdBuf [sizeof (wrBuf)]; uint16 dwRead; ft4222Status = FT4222_SPIMaster_SingleReadWrite (ftHandle,rdBuf,wrBuf,sizeof (wrBuf),&dwRead,TRUE); if (FT4222_OK != ft4222Status) { printf ("error: Error on ReadWrite\n"); } else { printf ("received: "); for (int i=0;i<6;i++) { printf ("0x%X ",rdBuf[i]); } printf ("\n"); } FT4222_UnInitialize(ftHandle); FT_Close(ftHandle); } 


أجزاء حافلة SPI


غالبًا ما يستخدم مطورو الأكواد الخاصة بالميكروكونترولر ناقل SPI كمولد لتردد محدد مسبقًا. في الواقع ، تعتمد البقول المتولدة برمجياً بحتة عبر خطوط GPIO على العديد من العوامل. أولاً ، يتطلب تفرع حلقة الغزل دورات المعالج. ثانياً ، قد تتداخل الانقطاعات و DMA وغيرها من العوامل غير المتوقعة مع المعالج. SPI هو أكثر أو أقل استقرارا ، تعرف نفسك إدارة لوضع بايت في المخزن المؤقت. تطبيق نموذجي لكتلة SPI ، التي ليس لها علاقة مباشرة بـ SPI نفسها ، هو التحكم في LED RGB ، والتي تعد دقة تحديد مدة النبضات مهمة للغاية.

لسوء الحظ ، هذا غير مقبول لجسور FTDI. جزء الشفرة أعلاه سيولد هذه النبضات على الحافلة:



في هذه الحالة ، لا تنتهك قواعد التشغيل SPI ، من وجهة نظر هذه الحافلة ، كل شيء يعمل بشكل صحيح. فقط ضع في اعتبارك أن الحلول المخصصة المعتادة على وحدات التحكم لن تعمل هنا. صحيح أن المجمع لديه الكثير من موصلات USB المجانية. يمكن تطوير جميع الكتل غير القياسية بشكل منفصل وتوصيلها.

أجزاء الإطارات I 2 C


الشيء الوحيد المنطقي هو الإشارة إلى عدم وجود مقاومات سحب لحافلة I 2 C على جانب المجمع. لكن هذا طبيعي: على جانب جهاز العمل ، لا يزال هناك مصعد. في الوقت الحاضر ، يمكن أن يكون السحب لأية جهد ، لذلك من المنطقي أن يتم ضبطه على الجهاز المستهدف.

استنتاج


اليوم اكتسبنا مهارات عملية في العمل مع الإطارات التي تنفذها جسور FTDI. بشكل عام ، يعد العمل معهم أمرًا قياسيًا ، حيث يتم تلخيص كل المعرفة في مقالة واحدة ، حتى لا يتم البحث عنها شيئًا فشيئًا. في المرة القادمة سننظر في وحدة نمطية تتحكم في الأجهزة غير القياسية ، والتي يتم تنفيذها على أساس وحدة التحكم STM32. في المخطط الهيكلي ، يتوافق هذا القسم مع:



ولكن في الحقيقة ، كل شيء أكثر إثارة للاهتمام هناك ...

Source: https://habr.com/ru/post/ar477662/


All Articles