1 /*        $NetBSD: scmdreg.h,v 1.3 2023/04/05 21:53:56 andvar Exp $   */
2 
3 /*
4  * Copyright (c) 2021 Brad Spencer <brad@anduin.eldar.org>
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #ifndef _DEV_SCMDREG_H_
20 #define _DEV_SCMDREG_H_
21 
22 /* The device can occupy a large number of I2C addresses */
23 
24 #define SCMD_LOW_I2C_ADDR     0x58
25 #define SCMD_HIGH_I2C_ADDR    0x61
26 
27 /* The register address space for each module */
28 
29 /* Some config and info registers */
30 #define SCMD_REG_FID                              0x00 /* Firmware version */
31 #define SCMD_REG_ID                     0x01 /* ID..  always 0xA9 */
32 #define SCMD_EXPECTED_ID                0xA9 /* What is always expected from the ID register */
33 #define SCMD_REG_SLAVE_ADDR             0x02 /* If a slave module, the I2C address */
34 #define SCMD_REG_CONFIG_BITS            0x03 /* Bit pattern of the jumpters on the board */
35 /* Diagnostics and debug registers */
36 #define SCMD_REG_U_I2C_RD_ERR           0x04 /* RD_ERR bits on USER port */
37 #define SCMD_REG_U_I2C_WR_ERR           0x05 /* WR_ERR bits on USER port */
38 #define SCMD_REG_U_BUF_DUMPED           0x06 /* Count of dumped buffers */
39 #define SCMD_REG_E_I2C_RD_ERR           0x07 /* Slave I2C read errors */
40 #define SCMD_REG_E_I2C_WR_ERR           0x08 /* Slave I2C write errors */
41 #define SCMD_REG_LOOP_TIME              0x09 /* Reports time in 100us of main loop */
42 #define SCMD_REG_SLV_POLL_CNT           0x0A /* Polls looking for slave modules */
43 #define SCMD_REG_SLV_TOP_ADDR           0x0B /* Highest slave I2C address */
44 #define SCMD_REG_MST_E_ERR              0x0C /* Number of expansion port I2C errors seen
45                                                         * by the master module
46                                                         */
47 #define SCMD_REG_MST_E_STATUS           0x0D /* Status of master controller board, expansion
48                                                         * port I2C (write status)
49                                                         */
50 #define SCMD_REG_FSAFE_FAULTS           0x0E /* Number of failsafe conditions seen */
51 #define SCMD_REG_REG_OOR_CNT            0x0F /* Register access attempts outside of range */
52 #define SCMD_REG_REG_RO_WRITE_CNT       0x10 /* Write lock write attempts */
53 #define SCMD_REG_GEN_TEST_WORD                    0x11 /* Write causes data to be applied to
54                                                         * REM_DATA_RD.
55                                                         * 0x01: Read config bit pins
56                                                         */
57 /* Local configuration registers */
58 #define SCMD_REG_MOTOR_A_INVERT                   0x12 /* Invert direction of motor A on local module,
59                                                         * or both if in bridged mode
60                                                         */
61 #define SCMD_REG_MOTOR_B_INVERT                   0x13 /* Invert direction of motor B on local module */
62 #define SCMD_REG_BRIDGE                           0x14 /* Bridge motor A and B on local module */
63 #define SCMD_REG_LOCAL_MASTER_LOCK      0x15 /* Unlocked when set to 0x9B.  Allows writes to
64                                                         * nearly any and every register.
65                                                         */
66 #define SCMD_REG_LOCAL_USER_LOCK        0x16 /* Unlocked when set to 0x5C.  Allows writes to
67                                                         * registers that are marked as user lockable
68                                                         */
69 #define SCMD_REG_MST_E_IN_FN            0x17 /* Set action when master module config-in pin
70                                                         * goes high.
71                                                         * B1-0: Restarts
72                                                         * 0x00 - do nothing
73                                                         * 0x01 - reboot module
74                                                         * 0x02 - re-enumerate
75                                                         * B2: User port behavior
76                                                         * 0x00 - do nothing
77                                                         * 0x01 - reinitialize user port
78                                                         * B3: Expansion port behavior
79                                                         * 0x00 - do nothing
80                                                         * 0x01 - reinitialize expansion port
81                                                         */
82 #define SCMD_REG_U_PORT_CLKDIV_U        0x18 /* Clock divisor for the user port */
83 #define SCMD_REG_U_PORT_CLKDIV_L        0x19 /* See data sheet for more details */
84 #define SCMD_REG_U_PORT_CLKDIV_CTRL     0x1A /* See data sheet for more details */
85 #define SCMD_REG_E_PORT_CLKDIV_U        0x1B /* Clock divisor for the expansion port */
86 #define SCMD_REG_E_PORT_CLKDIV_L        0x1C /* See data sheet for more details */
87 #define SCMD_REG_E_PORT_CLKDIV_CTRL     0x1D /* See data sheet for more details */
88 #define SCMD_REG_U_BUS_UART_BAUD        0x1E /* Current baud rate when the module is
89                                                         * communicating as a UART.  This register
90                                                         * can only be read and never set directly.
91                                                         * Use the 'U' command when communicating as
92                                                         * an UART.
93                                                         */
94 #define SCMD_REG_FSAFE_CTRL             0x1F /* Configure what happens when a failsafe
95                                                         * condition happens:
96                                                         * B0: output behavior
97                                                         * 0x00 - maintain last motor drive levels
98                                                         * 0x01 - set output level to 0 drive
99                                                         * B2-1: Restart operation on master module
100                                                         * 0x00 - do nothing
101                                                         * 0x01 - reboot
102                                                         * 0x02 - re-enumerate
103                                                         * B3 - user port behavior
104                                                         * 0x00 - do nothing
105                                                         * 0x01 - reinitialize user port
106                                                         * B4 - expansion port behavior
107                                                         * 0x00 - do nothing
108                                                         * 0x01 - reinitialize expansion port
109                                                         */
110 /* Motor drive levels, local and remote */
111 #define SCMD_REG_MA_DRIVE               0x20 /* Drive level on master module motor A */
112 #define SCMD_REG_MB_DRIVE               0x21 /* Drive level on master module motor B */
113 #define SCMD_REG_S1A_DRIVE              0x22 /* Drive level on slave 1 module motor A */
114 #define SCMD_REG_S1B_DRIVE              0x23 /* Drive level on slave 1 module motor B */
115 #define SCMD_REG_S2A_DRIVE              0x24 /* Drive level on slave 2 module motor A */
116 #define SCMD_REG_S2B_DRIVE              0x25 /* Drive level on slave 2 module motor B */
117 #define SCMD_REG_S3A_DRIVE              0x26 /* Drive level on slave 3 module motor A */
118 #define SCMD_REG_S3B_DRIVE              0x27 /* Drive level on slave 3 module motor B */
119 #define SCMD_REG_S4A_DRIVE              0x28 /* Drive level on slave 4 module motor A */
120 #define SCMD_REG_S4B_DRIVE              0x29 /* Drive level on slave 4 module motor B */
121 #define SCMD_REG_S5A_DRIVE              0x2A /* Drive level on slave 5 module motor A */
122 #define SCMD_REG_S5B_DRIVE              0x2B /* Drive level on slave 5 module motor B */
123 #define SCMD_REG_S6A_DRIVE              0x2C /* Drive level on slave 6 module motor A */
124 #define SCMD_REG_S6B_DRIVE              0x2D /* Drive level on slave 6 module motor B */
125 #define SCMD_REG_S7A_DRIVE              0x2E /* Drive level on slave 7 module motor A */
126 #define SCMD_REG_S7B_DRIVE              0x2F /* Drive level on slave 7 module motor B */
127 #define SCMD_REG_S8A_DRIVE              0x30 /* Drive level on slave 8 module motor A */
128 #define SCMD_REG_S8B_DRIVE              0x31 /* Drive level on slave 8 module motor B */
129 #define SCMD_REG_S9A_DRIVE              0x32 /* Drive level on slave 9 module motor A */
130 #define SCMD_REG_S9B_DRIVE              0x33 /* Drive level on slave 9 module motor B */
131 #define SCMD_REG_S10A_DRIVE             0x34 /* Drive level on slave 10 module motor A */
132 #define SCMD_REG_S10B_DRIVE             0x35 /* Drive level on slave 10 module motor B */
133 #define SCMD_REG_S11A_DRIVE             0x36 /* Drive level on slave 11 module motor A */
134 #define SCMD_REG_S11B_DRIVE             0x37 /* Drive level on slave 11 module motor B */
135 #define SCMD_REG_S12A_DRIVE             0x38 /* Drive level on slave 12 module motor A */
136 #define SCMD_REG_S12B_DRIVE             0x39 /* Drive level on slave 12 module motor B */
137 #define SCMD_REG_S13A_DRIVE             0x3A /* Drive level on slave 13 module motor A */
138 #define SCMD_REG_S13B_DRIVE             0x3B /* Drive level on slave 13 module motor B */
139 #define SCMD_REG_S14A_DRIVE             0x3C /* Drive level on slave 14 module motor A */
140 #define SCMD_REG_S14B_DRIVE             0x3D /* Drive level on slave 14 module motor B */
141 #define SCMD_REG_S15A_DRIVE             0x3E /* Drive level on slave 15 module motor A */
142 #define SCMD_REG_S15B_DRIVE             0x3F /* Drive level on slave 15 module motor B */
143 #define SCMD_REG_S16A_DRIVE             0x40 /* Drive level on slave 16 module motor A */
144 #define SCMD_REG_S16B_DRIVE             0x41 /* Drive level on slave 16 module motor B */
145 /* A hole in the register space */
146 #define SCMD_REG_HOLE_1_LOW             0x42 /* A hole in the register space */
147 #define SCMD_REG_HOLE_1_HIGH            0x4F
148 /* Remote inversion and bridging */
149 #define SCMD_REG_INV_2_9                0x50 /* Invert the motors on the slave modules.
150                                                         * Each bit is a motor.  Bit 0 is slave 1
151                                                         * module, motor A.  Bit 8 is slave 4 module,
152                                                         * motor B.
153                                                         */
154 #define SCMD_REG_INV_10_17              0x51 /* Invert motors 10 - 17 */
155 #define SCMD_REG_INV_18_25              0x52 /* Invert motors 18 - 25 */
156 #define SCMD_REG_INV_26_33              0x53 /* Invert motors 26 - 33 */
157 #define SCMD_REG_BRIDGE_SLV_L           0x54 /* Bridge slave module outputs.  Bit 0 is slave 1
158                                                         * module.  Bit 8 is slave 8 module.
159                                                         */
160 #define SCMD_REG_BRIDGE_SLV_H           0x55 /* Brige slave module outputs.  Slave module 9 to
161                                                         * 16
162                                                         */
163 /* Another hole in the register space */
164 #define SCMD_REG_HOLE_2_LOW             0x56 /* Another hole in the register space */
165 #define SCMD_REG_PAGE_SELECT            0x6F /* Usused function to select the register space
166                                                         * for use
167                                                         */
168 #define SCMD_REG_HOLE_2_HIGH            0x6F /* End of the second hole */
169 /* System configuration registers.
170  * Most are passed to the slave modules.
171  */
172 #define SCMD_REG_DRIVER_ENABLE                    0x70 /* Enable / disable all motor drivers.
173                                                         * Set to 0x01 to enable, 0x00 to disable.
174                                                         */
175 #define SCMD_DRIVER_ENABLE              0x01 /* Enable all motors */
176 #define SCMD_DRIVER_DISABLE             0x00 /* Disable all motors */
177 #define SCMD_REG_UPDATE_RATE            0x71 /* Update motors every UPDATE_RATE ms.
178                                                         * Use 0x00 to require FORCE_UPDATE.
179                                                         */
180 #define SCMD_REG_FORCE_UPDATE           0x72 /* Set to 0x01 to force a update of the motors.
181                                                         * Auto resets to 0x00.
182                                                         */
183 #define SCMD_REG_E_BUS_SPEED            0x73 /* Expansion bus speed:
184                                                         * 0x00 - 50kHz
185                                                         * 0x01 - 100kHz
186                                                         * 0x02 - 400kHz
187                                                         */
188 #define SCMD_REG_MASTER_LOCK            0x74 /* Unlocked when set to 0x9B.  Unlocks local and
189                                                         * remote modules.
190                                                         */
191 #define SCMD_REG_USER_LOCK              0x75 /* Unlocked when set to 0x5C.  Unlocks the user lock
192                                                             on the local and remote modules.
193                                                        */
194 #define SCMD_REG_FSAFE_TIME             0x76 /* Program status, if set:
195                                                         * B0 - Enumeration complete
196                                                         * B1 - Device busy
197                                                         * B2 - Remote module read in progress
198                                                         * B3 - Remote module write in progress
199                                                         * B4 - The state of enable pin U2.5
200                                                         */
201 #define SCMD_REG_STATUS_1               0x77 /* Another way to get basic program status, if set:
202                                                         * B0 - Enumeration complete
203                                                         * B1 - Device busy
204                                                         */
205 #define SCMD_REG_CONTROL_1              0x78 /* Restart and re-enumeration control.  If set:
206                                                         * B0 - Restart module
207                                                         * B1 - Re-enumerate, look for modules (self clears)
208                                                         */
209 #define SCMD_CONTROL_1_RESTART                    0x01 /* Mask to perform a restart using CONTROL_1 */
210 #define SCMD_CONTROL_1_REENUMERATE      0x02 /* Mask to perform a re-enumeration using
211                                                         * CONTROL_1
212                                                         */
213 /* Remote module I2C bus write / read window */
214 #define SCMD_REG_REM_ADDR               0x79 /* The slave module I2C address.  This starts at 0x50 */
215 #define SCMD_REG_REM_OFFSET             0x7A /* Remote module I2C register for write / read */
216 #define SCMD_REG_REM_DATA_WR            0x7B /* Data staged for write to remote module */
217 #define SCMD_REG_REM_DATA_RD            0x7C /* Data returned from remote module */
218 #define SCMD_REG_REM_WRITE              0x7D /* Write REM_DATA_WR to REM_OFFSET on remote module */
219 #define SCMD_REG_REM_READ               0x7E /* Read from REM_OFFSET into REM_DATA_RD on remote
220                                                         * module
221                                                         */
222 
223 #define SCMD_LAST_REG                             SCMD_REG_REM_READ /* The last register address on a module */
224 #define SCMD_REG_SIZE                             0x7F /* Size of the register space including the holes */
225 #define SCMD_REMOTE_ADDR_LOW            0x50 /* The first remote I2C address */
226 #define SCMD_REMOTE_ADDR_HIGH           0x5F /* The last remote I2C address */
227 #define SCMD_HOLE_VALUE                           0x55 /* Artificial value on read for a hole register */
228 #define SCMD_IS_HOLE(r) \
229 ((r >= SCMD_REG_HOLE_1_LOW && r <= SCMD_REG_HOLE_1_HIGH) || \
230     (r >= SCMD_REG_HOLE_2_LOW && r <= SCMD_REG_HOLE_2_HIGH))
231 
232 #define SCMD_MASTER_LOCK_UNLOCKED       0x9B
233 #define SCMD_USER_LOCK_UNLOCKED                   0x5C
234 #define SCMD_ANY_LOCK_LOCKED            0x00
235 
236 #endif
237