Skip to content

Commit 567a152

Browse files
committed
found info on HCO =. major docs tweaks
1 parent b7dd4f3 commit 567a152

File tree

4 files changed

+103
-59
lines changed

4 files changed

+103
-59
lines changed

README.rst

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -81,16 +81,23 @@ on an `ItsyBitys M4 <https://www.adafruit.com/product/3800>`_)
8181
(when pressed) provide a path to ground, the Pinnacle touch controller will report all 3
8282
buttons' states for each touch (or even button only) events.
8383

84-
The Cirque circle trackpad models use the following labeling scheme:
85-
86-
:TMyyyxxx-202i-30o:
87-
88-
- ``yyy`` stands for the horizontal width of the trackpad
89-
- ``xxx`` stands for the vertical width of the trackpad
90-
- ``i`` stands for the hardwired interface protocol (3 = I2C, 4 = SPI). Notice, if there is a
91-
resistor populated at the R1 (470K ohm) junction (located just above the Pinnacle ASIC), it
92-
is configured for SPI, otherwise it is configured for I2C.
93-
- ``o`` stands for the overlay type (0 = none, 1 = adhesive, 2 = flat, 3 = curved)
84+
Model Labeling Scheme
85+
---------------------
86+
87+
TM\ [yyyxxx]_\ -202\ [i]_\ -\ [cc]_\ [o]_
88+
89+
.. [yyyxxx] stands for the vertical & horizontal width of the trackpad, respectively.
90+
.. [i] stands for the hardwired interface protocol (3 = I2C, 4 = SPI). Notice, if there is a
91+
resistor populated at the R1 (470K ohm) junction (located just above the Pinnacle ASIC), it
92+
is configured for SPI, otherwise it is configured for I2C.
93+
.. [cc] stands for Custom Configuration. "30" means that the hardware is configured to disable
94+
certain features despite what this library does. "00" means that the hardware is configured
95+
to allow certain features to manipulated by this library. These features include "secondary
96+
tap" (thought of as "right mouse button" in relative data mode), Intellimouse scrolling
97+
(Microsoft patented scroll wheel behavior -- a throw back to when scroll wheels were
98+
first introduced), and 180 degree orientation (your application can invert the axis
99+
data anyway).
100+
.. [o] stands for the overlay type (0 = none, 1 = adhesive, 2 = flat, 3 = curved)
94101
95102
Dependencies
96103
=============

circuitpython_cirque_pinnacle.py

Lines changed: 84 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ def __init__(self, dr_pin=None):
122122
raise OSError("Cirque Pinnacle ASIC not responding")
123123

124124
# init internal attributes w/ factory defaults after power-on-reset
125+
self._hco = bool(self._rap_read(0x1F)) # is hardware custom configured?
125126
self._sys_config = 0 # ignoring read-only reset flag (bit 0)
126127
self._feed_config1 = 1 # enables feed & sets to relative mode
127128
self._feed_config2 = 2 # disables taps in relative mode
@@ -237,25 +238,36 @@ def data_mode(self, mode):
237238
# now configure the AnyMeas mode to default values
238239
self.anymeas_mode_config()
239240

240-
def relative_mode_config(self, rotate90=False, disable_taps=True):
241+
@property
242+
def hard_configured(self):
243+
"""This `bool` attribute provides insight to applications about factory
244+
customized hardware configuration. see note about product labeling in
245+
`Model Labeling Scheme <index.html#model-labeling-scheme>`_. (read only)"""
246+
return self._hco
247+
248+
def relative_mode_config(self, rotate90=False, glide_extend=True,
249+
secondary_tap=True, taps=False, intellimouse=False):
241250
"""Set the configuration register for features specific to relative mode (AKA mouse mode)
242-
data reporting. (write only)
243-
244-
This function only applies to Relative mode, otherwise if `data_mode` is set to
245-
:attr:`~circuitpython_cirque_pinnacle.DataModes.ANYMEAS` or
246-
:attr:`~circuitpython_cirque_pinnacle.DataModes.ABSOLUTE`, then this function will take
247-
no affect until `data_mode` is set to
248-
:attr:`~circuitpython_cirque_pinnacle.DataModes.RELATIVE`.
251+
data reporting.
249252
250253
:param bool rotate90: Specifies if the axis data is altered for 90 degree rotation before
251-
reporting it. Default is `False`.
252-
:param bool disable_taps: Specifies if all taps should be reported (`False`) or not
253-
(`True`). Default is `True`. Only button 1 (left mouse button) is emulated with a tap
254-
and will be reflected in the button data portion of the data reports.
254+
reporting it (essentially swaps the axis data). Default is `False`.
255+
:param bool glide_extend: A patended feature that allows the user to glide their finger off
256+
the edge of the sensor and continue gesture with the touch event. Default is `True`.
257+
This feature is only available if `hard_configured` is `False`.
258+
:param bool secondary_tap: Specifies if tapping in the top-left corner (depending on
259+
orientation) triggers the secondary button data. Defaults to `True`. This feature is
260+
only available if `hard_configured` is `False`.
261+
:param bool taps: Specifies if all taps should be reported (`True`) or not
262+
(`False`). Default is `True`. This affects ``secondary_tap`` option as well. The
263+
primary button (left mouse button) is emulated with a tap.
264+
:param bool intellimouse: Specifies if the data reported includes a byte about scroll data.
265+
Default is `False`. Because this flag is specific to scroll data, this feature is only
266+
available if `hard_configured` is `False`.
255267
"""
256-
self._feed_config2 = rotate90 << 7 | disable_taps << 1
257-
if self.data_mode == DataModes.RELATIVE:
258-
self._rap_write(PINNACLE_FEED_CONFIG2, self._feed_config2)
268+
self._feed_config2 = rotate90 << 7 | (not glide_extend) << 4 | (
269+
not secondary_tap) << 2 | (not taps) << 1 | intellimouse
270+
self._rap_write(PINNACLE_FEED_CONFIG2, self._feed_config2)
259271

260272
def absolute_mode_config(self, z_idle_count=30, invert_x=False, invert_y=False):
261273
"""Set the configuration settings specific to Absolute mode (reports axis positions).
@@ -300,45 +312,64 @@ def report(self, only_new=True):
300312
301313
.. list-table::
302314
:header-rows: 1
303-
:widths: 2, 8, 8
315+
:widths: 1, 5, 5
304316
305317
* - Index
306-
- Relative (Mouse) mode as a `bytearray`
307-
- Absolute Mode as a `list`
318+
- Relative (Mouse) mode
319+
320+
as a `bytearray`
321+
- Absolute Mode
322+
323+
as a `list`
308324
* - 0
309-
- "Button Data"
310-
- "Button Data"
325+
- Button Data [1]_
326+
327+
one unsigned byte
328+
- Button Data [1]_
329+
330+
one unsigned byte
311331
* - 1
312-
- "change in x-axis"
313-
- "x-axis Position"
332+
- change in x-axis [2]_
333+
334+
-128 |LessEq| X |LessEq| 127
335+
- x-axis Position
336+
337+
128 |LessEq| X |LessEq| 1920
314338
* - 2
315-
- "change in y-axis"
316-
- "y-axis Position"
317-
* - 3
318-
- "change in scroll wheel"
319-
- "z-axis Position"
339+
- change in y-axis [2]_
320340
321-
.. important:: The axis data reported in Relative/Mouse mode is in two's
322-
comliment form. Use Python's :py:func:`struct.unpack()` to convert the
323-
data into integer form (see `Simple Test example <examples.html#simple-test>`_
324-
for how to use this function).
341+
-128 |LessEq| Y |LessEq| 127
342+
- y-axis Position
325343
326-
The axis data reported in Absolute mode is always positive as the
327-
xy-plane's origin is located to the top-left, unless ``invert_x`` or ``invert_y``
328-
parameters to `absolute_mode_config()` are manipulated to change the perspective
329-
location of the origin.
344+
64 |LessEq| Y |LessEq| 1472
345+
* - 3
346+
- change in scroll wheel
330347
331-
:Button Data: The returned button data is a byte in which each bit represents a button
332-
The bit to button order is as follows:
348+
-128 |LessEq| Y |LessEq| 127 [3]_
349+
- z-axis Position
333350
334-
0. [LSB] Button 1 (thought of as Left button in Relative/Mouse mode).
335-
If taps are enabled in Relative/Mouse mode, a single tap will be reflected here
336-
1. Button 2 (thought of as Right button in Relative/Mouse mode)
337-
2. Button 3 (thought of as Middle or scroll wheel button in Relative/Mouse mode)
351+
.. [1] The returned button data is a byte in which each bit represents a button.
352+
The bit to button order is as follows:
338353
339-
.. note:: In Relative/Mouse mode, the scroll wheel data is a zero-value byte as the
354+
0. [LSB] Button 1 (thought of as Left button in Relative/Mouse mode). If taps
355+
are enabled using `relative_mode_config()`, a single tap will be reflected here.
356+
1. Button 2 (thought of as Right button in Relative/Mouse mode)
357+
2. Button 3 (thought of as Middle or scroll wheel button in Relative/Mouse mode)
358+
.. [2] The axis data reported in Relative/Mouse mode is in two's
359+
comliment form. Use Python's :py:func:`struct.unpack()` to convert the
360+
data into integer form (see `Simple Test example <examples.html#simple-test>`_
361+
for how to use this function).
362+
363+
The axis data reported in Absolute mode is always positive as the
364+
xy-plane's origin is located to the top-left, unless ``invert_x`` or ``invert_y``
365+
parameters to `absolute_mode_config()` are manipulated to change the perspective
366+
location of the origin.
367+
.. [3] In Relative/Mouse mode the scroll wheel data is only reported if the
368+
``intellimouse`` parameter is passed as `True` to `relative_mode_config()`.
369+
Otherwise this is an empty byte as the
340370
returned `bytearray` follows the buffer structure of a mouse HID report (see
341371
`USB Mouse example <examples.html#usb-mouse-example>`_).
372+
.. |LessEq| unicode:: U+2264
342373
"""
343374
if self._mode == DataModes.ANYMEAS:
344375
return None
@@ -356,11 +387,19 @@ def report(self, only_new=True):
356387
((temp[4] & 0x0F) << 8) | temp[2], # x
357388
((temp[4] & 0xF0) << 4) | temp[3], # y
358389
temp[5] & 0x3F] # z
390+
# datasheet recommends clipping for reliability
391+
return_vals[1] = min(128, max(1920, return_vals[1]))
392+
return_vals[2] = min(64, max(1472, return_vals[2]))
359393
elif self.data_mode == DataModes.RELATIVE: # if in relative mode
394+
is_intellimouse = self._feed_config2 & 1
360395
# get relative data packets
361-
temp = self._rap_read_bytes(PINNACLE_PACKET_BYTE_0, 3)
362-
# convrert to bytearray & append empty byte to suite mouse HID reports
363-
return_vals = bytearray([temp[0] & 7, temp[1], temp[2], 0])
396+
temp = self._rap_read_bytes(
397+
PINNACLE_PACKET_BYTE_0, 3 + is_intellimouse)
398+
return_vals = bytearray([temp[0] & 7, temp[1], temp[2]])
399+
if is_intellimouse: # scroll wheel data is captured
400+
return_vals += bytes([temp[3]])
401+
else: # append empty byte to suite mouse HID reports
402+
return_vals += b'\x00'
364403
# clear flags despite if data is fresh or not (faster & reliable)
365404
self.clear_flags()
366405
return return_vals

docs/conf.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
autodoc_mock_imports = ["digitalio", "busio"]
2525
autodoc_member_order = 'bysource'
2626

27-
2827
intersphinx_mapping = {
2928
'python': ('https://docs.python.org/3.7', None),
3029
'BusDevice': ('https://circuitpython.readthedocs.io/projects/busdevice/en/latest/', None),
@@ -156,7 +155,7 @@
156155
# One entry per manual page. List of tuples
157156
# (source start file, name, description, authors, manual section).
158157
man_pages = [
159-
(master_doc, 'CircuitPythonCirquePinnaclelibrary', u'CircuitPython Cirque Pinnacle Library Documentation',
158+
(master_doc, 'CircuitPythonCirquePinnacleLibrary', u'CircuitPython Cirque Pinnacle Library Documentation',
160159
[author], 1)
161160
]
162161

docs/index.rst

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,7 @@ Table of Contents
2424
.. toctree::
2525
:caption: Related Products
2626

27-
.. todo:: Add any product links here. If there are none, then simply delete this todo and leave
28-
the toctree above for use later.
27+
Cirque Glidepoint circle trackpads <https://www.mouser.com/Search/Refine?Ntk=P_MarCom&Ntt=118816186>
2928

3029
.. toctree::
3130
:caption: Other Links

0 commit comments

Comments
 (0)