كتابة وحدة فك ترميز ل sigrok

صورة



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



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



موقف تجريبي



, . TTP229-BSF. 8- 16- . Arduino, DSLogic.



صورة





, , . , . , , .



كل وحدة فك ترميز في sigrok عبارة عن حزمة منفصلة مكتوبة في Python 3 ولها دليل خاص بها في مجلد وحدات فك الترميز. مثل أي حزمة Python ، يحتوي مفكك التشفير على __init__.py ، ووفقًا لعبارات التسمية المعتمدة من قبل sigrok ، ملف pd.py يحتوي على التنفيذ نفسه.



صورة



الرمز في __init__.py قياسي ويتضمن docstring يصف البروتوكول واستيراد وحدة فك الترميز ( d28dee9 ):



'''
Protocol description.
'''

from .pd import Decoder


يحتوي ملف pd.py على تطبيق وحدة فك الترميز ( d28dee9 ):



class Decoder(srd.Decoder):
    api_version = 3
    id = 'empty'
    name = 'empty'
    longname = 'empty decoder'
    desc = 'Empty decoder that can be loaded by sigrok.'
    license = 'mit'
    inputs = ['logic']
    outputs = ['empty']
    tags = ['Embedded/industrial']
    channels = (
        {'id': 'scl', 'name': 'SCL', 'desc': 'Clock'},
        {'id': 'sdo', 'name': 'SDO', 'desc': 'Data'},
    )

    def start(self):
        pass

    def reset(self):
        pass

    def decode(self):
        pass


هذا هو الحد الأدنى من التنفيذ الذي يمكن للمكتبة تحميله ، لكنه لا يفك تشفير أي شيء. دعونا نحلل الخصائص المطلوبة:



  • api_version – Protocol decoder API, . libsigrokdecode 3- Protocol decoder API. .
  • id – , . , .
  • name, longname, desc – , , . .
  • inputs, outputs – . 'logic' . . , , SPI. SPI . , SPI . 'spi'.
  • license, tag – . DSView 1.1.1 + libsigrokdecode tags - .
  • القنوات - قائمة خطوط الإشارة التي يستخدمها مفكك التشفير. هذه الخاصية مطلوبة لأجهزة فك التشفير التي يُعرّف نسق بيانات الإدخال فيها على أنه منطق.


والطرق المطلوبة:



  • start () - الطريقة التي يتم استدعاؤها قبل بدء فك التشفير. في هذه الطريقة ، يجب إجراء إعدادات جلسة فك الترميز الحالية.
  • reset () - طريقة تسمى عند إيقاف فك التشفير. يجب إعادة وحدة فك الترميز إلى حالتها الأولية.
  • فك شفرة () - الطريقة التي تسمى فك شفرة الإشارة.


بعد التعامل مع الحد الأدنى من تنفيذ وحدة فك الترميز ، يمكنك البدء في فك تشفير الإشارة الحقيقية.



وحدة فك ترميز كاملة المواصفات



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



صورة



أولاً وقبل كل شيء ، من الضروري وصف مجموعة الخطوط الإلزامية التي سيعمل بها جهاز فك التشفير. في هذه الحالة ، يوجد اثنان منهم ، خط الساعة (SCL) وخط البيانات (SDO).



class Decoder(srd.Decoder):
    ...
    inputs = ['logic']
    channels = (
        {'id': 'scl', 'name': 'SCL', 'desc': 'Clock'},
        {'id': 'sdo', 'name': 'SDO', 'desc': 'Data'},
    )


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



sigrok , . . , , . Protocol decoder API . . wait(). . , self.samplenum .



, , – , :



  • 'l' - مستوى منخفض ، منطقي 0 ؛
  • 'h' - مستوى عالٍ ومنطقي 1 ؛
  • 'r' - ارتفاع الإشارة ، الانتقال من الحالة المنخفضة إلى الحالة المرتفعة ؛
  • 'f' - انخفاض الإشارة ، الانتقال من الأعلى إلى الأدنى ؛
  • 'e' - تغيير الإشارة أو الارتفاع أو الانخفاض التعسفي ؛
  • 's' - حالة مستقرة ، 0 أو 1.


وبالتالي ، للعثور على بداية إشارة DV ، شرط يصف أن خط SCL مرتفع ، ويحدث انحراف الإشارة على خط البيانات (SDO). نسمي وظيفة الانتظار () بالشرط ونحفظ رقم العينة:



        self.wait({0: 'h', 1: 'f'})
        self.dv_block_ss = self.samplenum


للعثور على نهاية إشارة DV ، من الضروري تعيين حالة عندما يظل خط SCL مرتفعًا ، ويرتفع خط البيانات:

        self.wait({0: 'h', 1: 'r'})


عند الانتهاء من المكالمة الأخيرة لوظيفة الانتظار () ، سيتم معرفة أرقام العينات لبداية ونهاية إشارة DV. حان الوقت لإنشاء تعليق توضيحي له. للقيام بذلك ، أضف التعليقات التوضيحية إلى مفكك التشفير وقم بتجميعها معًا (annotation_rows):



class Decoder(srd.Decoder):
    ...
    annotations = (
        ('dv', 'Data valid'),
    )
    annotation_rows = (
        ('fields', 'Fields', (0,)),
    )


حيث 0 هو فهرس التعليق التوضيحي في المجموعة. ستحتاج أيضًا إلى تسجيل إخراج التعليقات التوضيحية:



    def start(self):
        self.out_ann = self.register(srd.OUTPUT_ANN)


أنت الآن جاهز لوضع التعليق التوضيحي لإشارة DV. يتم ذلك عن طريق استدعاء دالة put () ( f613b83 ):



        self.put(self.dv_block_ss, self.samplenum,
                 self.out_ann, [0, ['Data valid', 'DV']])


معلمات الوظيفة: رقم عينة بدء التعليق التوضيحي (self.dv_block_ss) ، رقم نموذج نهاية التعليق التوضيحي (self.samplenum) ، معرف إخراج التعليق التوضيحي (self.out_ann) وبيانات التعليق التوضيحي. يتم تقديم البيانات في شكل قائمة من فهرس التعليقات التوضيحية (0) وقائمة متداخلة من الأسطر ، من الأطول إلى الأقصر ، لعرضها في الوصف. إذا تم تحديد أكثر من سطر واحد ، يمكن للواجهة تحديد الخط المعروض بشكل مستقل ، على سبيل المثال ، اعتمادًا على المقياس المستخدم:







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



TTP229-BSF ، اعتمادًا على الوضع المحدد ، يمكن أن يعمل مع 8 أو 16 زرًا باللمس. في هذه الحالة ، لا تحتوي البيانات المرسلة على معلومات حول وضع تشغيل الدائرة المصغرة. لذلك ، بالنسبة لفك الشفرة ، يجدر إضافة خيار يحدد الوضع الذي تعمل فيه الدائرة المصغرة.



class Decoder(srd.Decoder):
    ...
    options = (
        {'id': 'key_num', 'desc': 'Key number', 'default': 8,
         'values': (8, 16)},
    )
    def start(self):
        ...
        self.key_num = self.options['key_num']


سيكون هذا الخيار متاحًا لتعيين قيمة في واجهة المستخدم عند تحديد وحدة فك الترميز.



كما ترى من الرسم البياني للتوقيت ، يتم الكشف عن البيانات الموجودة على خط SDO عندما تنتقل SCL إلى المستوى النشط (منخفض) ويتم حفظها عندما تعود الإشارة إلى المستوى السلبي. في هذه اللحظة ، يمكن لكل من وحدة التحكم الدقيقة ومفكك الشفرة تسجيل مجموعة البيانات على خط SDL. يمكن اعتبار انتقال SCL إلى الطبقة النشطة كبداية لإرسال البيانات التالي. في هذه الحالة ، ستبدو وظيفة فك التشفير ( ca9a370 ):



    def decode(self):
        self.wait({0: 'h', 1: 'f'})
        self.dv_block_ss = self.samplenum

        self.wait({0: 'h', 1: 'r'})
        self.put(self.dv_block_ss, self.samplenum,
                 self.out_ann, [0, ['Data valid', 'DV']])
        self.tw_block_ss = self.samplenum

        self.wait([{0: 'f', 1: 'h'}, {0: 'f', 1: 'f'}])
        self.put(self.tw_block_ss, self.samplenum,
                 self.out_ann, [1, ['Tw', 'Tw']])
        self.bt_block_ss = self.samplenum

        for i in range(self.key_num):
            (scl, sdo) = self.wait({0: 'r'})
            sdo = 0 if sdo else 1

            self.wait({0: 'f'})
            self.put(self.bt_block_ss, self.samplenum,
                     self.out_ann, [2, ['Bit: %d' % sdo, '%d' % sdo]])
            self.bt_block_ss = self.samplenum


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







. . , SCL . , SCL 2 ., . 'skip', , , . , . metadata(). Hz.



    def metadata(self, key, value):
        if key == srd.SRD_CONF_SAMPLERATE:
            self.timeout_samples_num = int(2 * (value / 1000.0))


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



    def decode(self):
        ...
        for i in range(self.key_num):
            ...
            self.wait([{0: 'f'}, {'skip': self.timeout_samples_num}])
            self.put(self.bt_block_ss, self.samplenum,
                     self.out_ann, [2, ['Bit: %d' % sdo, '%d' % sdo]])
            if (self.matched & 0b10) and i != (self.key_num - 1):
                break


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



class Decoder(srd.Decoder):
    ...
    annotations = (
        ('dv', 'Data valid'),
        ('tw', 'Tw'),
        ('bit', 'Bit'),
        ('key', 'Key press status'),
    )
    annotation_rows = (
        ('fields', 'Fields', (0, 1, 2)),
        ('keymsg', 'Key message', (3,)),
    )
    def decode(self):
        ...
        keys_pressed = list()

        for i in range(self.key_num):
            ...
        else:
            key_msg = \
                'Key: %s' % (','.join(keys_pressed)) if keys_pressed else 'Key unpressed'
            key_msg_short = \
                'K: %s' % (','.join(keys_pressed)) if keys_pressed else 'KU'

            self.put(self.dv_block_ss, self.samplenum,
                     self.out_ann, [3, [key_msg, key_msg_short]])






حتى تلك اللحظة ، كانت جميع الشفرات تعمل فقط مع الحزمة الأولى. هل لاحظت 19٪ بجوار اسم وحدة فك الترميز؟ هذه هي النسبة المئوية للعينات التي تمت معالجتها قبل خروج وظيفة فك التشفير (). لمعالجة جميع العينات ، يبقى إضافة حلقة لا نهائية حول الكود لفك تشفير حزمة بيانات منفصلة ( 48f95fb ).



    def decode(self):
        ...
        while True:
            self.wait({Pin.SCL: self.passive_signal, Pin.SDO: self.front_edge})
            self.dv_block_ss = self.samplenum
            ...


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



تبقى اللمسة الأخيرة لإضافة القدرة على تحديد مستوى الإشارة النشطة وجهاز فك تشفير كامل لـ TTP229-BSF جاهزًا. رمز المصدر النهائي متاح أيضًا على GitHub .




All Articles