2013年5月4日土曜日

USBトークン、データCRCの計算

CRCの理論はよくわかってないが、テストが通るからたぶん計算方法はあっていると思う。

8.3.5.1 Token CRCs
8.3.5.2 Data CRCs


# coding:utf-8
# test_crc5usb.py 2013/5/3
#
import unittest

def crc5usb(data):
    assert(data >= 0 and data <= 0x3ff)
    r = data ^ 0x1f
    for _ in range(11): # 11bit
        if r & 1:
            r = (r>>1) ^ 0x14
        else:
            r = r>>1
    return r ^ 0x1f


class Test_crc5usb(unittest.TestCase):
    def setUp(self):
        pass

    def tearDown(self):
        pass

    def test_80_2d_00_10(self): # SYNC SETUP
        u16 = 0x00 | 0x10<<8
        self.assertEqual(u16&0x7f, 0)     # ADDR=0x0
        self.assertEqual((u16>>7)&0xf, 0) # ENDP=0x0
        self.assertEqual(u16>>11, 0x02)   # CRC5=0x02
        r = crc5usb(u16&0x3ff)
        self.assertEqual(r, 0x02)   # CRC5

    def test_80_69_87_d8(self): # SYNC IN
        u16 = 0x87 | 0xd8<<8
        self.assertEqual(u16&0x7f, 7)     # ADDR=0x7
        self.assertEqual((u16>>7)&0xf, 1) # ENDP=0x1
        self.assertEqual(u16>>11, 0x1b)   # CRC5=0x1b
        r = crc5usb(u16&0x3ff)
        self.assertEqual(r, 0x1b)   # CRC5

    def test_80_00_10(self):
        u16 = 0x00 | 0x10<<8
        self.assertEqual(u16&0x7f, 0)     # ADDR=0x0
        self.assertEqual((u16>>7)&0xf, 0) # ENDP=0x0
        self.assertEqual(u16>>11, 0x02)   # CRC5=0x02
        r = crc5usb(u16&0x3ff)
        self.assertEqual(r, 0x02)   # CRC5

if __name__=="__main__":
    unittest.main()

# coding:utf-8
# test_crc16usb.py 2013/5/3
#
import unittest

def crc16usb(data):
    r = 0xffff
    for d in data:
        r ^= d
        for _ in range(8):
            if r & 1:
                r = (r>>1) ^ 0xa001
            else:
                r = (r>>1)
    return r ^ 0xffff

class Test_crc16usb(unittest.TestCase):
    def setUp(self):
        pass

    def tearDown(self):
        pass

    def test_00_00_ff_00_2bbe(self):
        data = [0x00, 0x00, 0xff, 0x00]
        r = crc16usb(data)
        self.assertEqual(r, 0x2bbe)

    def test_00_ff_00_00_ebcf(self):
        data = [0x00, 0xff, 0x00, 0x00]
        r = crc16usb(data)
        self.assertEqual(r, 0xebcf)

    def test_None_0000(self):
        data = []
        r = crc16usb(data)
        self.assertEqual(r, 0x0000)

    def test_80_06_00_01_00_00_40_00_94dd(self):
        data = [0x80, 0x06, 0x00, 0x01, 0x00, 0x00, 0x40, 0x00]
        r = crc16usb(data)
        self.assertEqual(r, 0x94dd)

    def test_12_01_10_01_00_00_00_08_7711(self):
        data = [0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08]
        r = crc16usb(data)
        self.assertEqual(r, 0x7711)

    def test_58_04_07_00_00_00_01_02_487f(self):
        data = [0x58, 0x04, 0x07, 0x00, 0x00, 0x00, 0x01, 0x02]
        r = crc16usb(data)
        self.assertEqual(r, 0x487f)

    def test_00_01_8f3f(self):
        data = [0x00, 0x01]
        r = crc16usb(data)
        self.assertEqual(r, 0x8f3f)

if __name__=="__main__":
    unittest.main()


(2013/5/4)
---

0 件のコメント: