| 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 |