972227e96c93a3c05b1493817ae844179833e131
[libsigrokdecode.git] / decoders / adns5020 / pd.py
1 ##
2 ## This file is part of the libsigrokdecode project.
3 ##
4 ## Copyright (C) 2015 Karl Palsson <karlp@tweak.net.au>
5 ##
6 ## This program is free software; you can redistribute it and/or modify
7 ## it under the terms of the GNU General Public License as published by
8 ## the Free Software Foundation; either version 2 of the License, or
9 ## (at your option) any later version.
10 ##
11 ## This program is distributed in the hope that it will be useful,
12 ## but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 ## GNU General Public License for more details.
15 ##
16 ## You should have received a copy of the GNU General Public License
17 ## along with this program; if not, write to the Free Software
18 ## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
19 ##
20
21 import sigrokdecode as srd
22
23 regs = {
24         0: 'Product_ID',
25         1: 'Revision_ID',
26         2: 'Motion',
27         3: 'Delta_X',
28         4: 'Delta_Y',
29         5: 'SQUAL',
30         6: 'Shutter_Upper',
31         7: 'Shutter_Lower',
32         8: 'Maximum_Pixel',
33         9: 'Pixel_Sum',
34         0xa: 'Minimum_Pixel',
35         0xb: 'Pixel_Grab',
36         0xd: 'Mouse_Control',
37         0x3a: 'Chip_Reset',
38         0x3f: 'Inv_Rev_ID',
39         0x63: 'Motion_Burst',
40 }
41
42 class Decoder(srd.Decoder):
43     api_version = 2
44     id = 'adns5020'
45     name = 'ADNS-5020'
46     longname = 'Avago ADNS-5020 optical mouse sensor'
47     desc = 'Bidirectional command and data over an SPI-like protocol.'
48     license = 'gplv2+'
49     inputs = ['spi']
50     outputs = ['adns5020']
51     annotations = (
52         ('read', 'Register read commands'),
53         ('write', 'Register write commands'),
54         ('warning', 'Warnings'),
55     )
56     annotation_rows = (
57         ('read', 'Read', (0,)),
58         ('write', 'Write', (1,)),
59         ('warnings', 'Warnings', (2,)),
60     )
61
62     def __init__(self):
63         self.ss_cmd, self.es_cmd = 0, 0
64         self.mosi_bytes = []
65
66     def start(self):
67         self.out_ann = self.register(srd.OUTPUT_ANN)
68
69     def putx(self, data):
70         self.put(self.ss_cmd, self.es_cmd, self.out_ann, data)
71
72     def put_warn(self, pos, msg):
73         self.put(pos[0], pos[1], self.out_ann, [2, [msg]])
74
75     def decode(self, ss, es, data):
76         ptype = data[0]
77         if ptype == 'CS-CHANGE':
78             # If we transition high mid-stream, toss out our data and restart.
79             cs_old, cs_new = data[1:]
80             if cs_old is not None and cs_old == 0 and cs_new == 1:
81                 if len(self.mosi_bytes) not in [0, 2]:
82                     self.put_warn([self.ss_cmd, es], 'Misplaced CS#!')
83                     self.mosi_bytes = []
84             return
85
86         # Don't care about anything else.
87         if ptype != 'DATA':
88             return
89         mosi, miso = data[1:]
90
91         self.ss, self.es = ss, es
92
93         if len(self.mosi_bytes) == 0:
94             self.ss_cmd = ss
95         self.mosi_bytes.append(mosi)
96
97         # Writes/reads are mostly two transfers (burst mode is different).
98         if len(self.mosi_bytes) != 2:
99             return
100
101         self.es_cmd = es
102         cmd, arg = self.mosi_bytes
103         write = cmd & 0x80
104         reg = cmd & 0x7f
105         reg_desc = regs.get(reg, 'Reserved %#x' % reg)
106         if reg > 0x63:
107             reg_desc = 'Unknown'
108         if write:
109             self.putx([1, ['%s: %#x' % (reg_desc, arg)]])
110         else:
111             self.putx([0, ['%s: %d' % (reg_desc, arg)]])
112
113         self.mosi_bytes = []