A51 MACRO ASSEMBLER I2C 22/07/99 12:36:44 PAGE 1 DOS MACRO ASSEMBLER A51 V5.28m OBJECT MODULE PLACED IN I2C.OBJ ASSEMBLER INVOKED BY: C:\ANCHOR\KEIL2K\BIN\A51.EXE I2C.A51 RB(0) DB EP LOC OBJ LINE SOURCE 1 NAME I2Cbridge 2 3 $INCLUDE(../Declare.A51) =1 4 ; This module declares the variables and constants used in the examples =1 5 ; It is common to all of the examples =1 6 ; =1 7 ; Declare Special Function Registers used 00A8 =1 8 EI DATA 0A8H 00E8 =1 9 EIE DATA 0E8H ; EZ-USB specific 0091 =1 10 EXIF DATA 091H ; EZ-USB specific 00D8 =1 11 EICON DATA 0D8H ; EZ-USB specific 0092 =1 12 PageReg DATA 092H ; EZ-USB specific, used with MOVX @Ri 0086 =1 13 DPS DATA 086H ; EZ-USB specific, used with dual data pointers =1 14 ; =1 15 ; "External" memory locations used, EZ-USB specific =1 16 ; Note that most of these variables are in Page 7FH 7FE8 =1 17 SETUPDAT EQU 07FE8H 7FD4 =1 18 SUDPTR EQU 07FD4H 7FB4 =1 19 EP0Control EQU 07FB4H 7F00 =1 20 EP0InBuffer EQU 07F00H 7EC0 =1 21 EP0OutBuffer EQU 07EC0H ; Not in Page 7FH 7E80 =1 22 EP1InBuffer EQU 07E80H ; Not in Page 7FH 7FB5 =1 23 IN0ByteCount EQU 07FB5H 7FC5 =1 24 Out0ByteCount EQU 07FC5H 7FB7 =1 25 IN1ByteCount EQU 07FB7H 7FAC =1 26 IN07IEN EQU 07FACH 7FA9 =1 27 IN07IRQ EQU 07FA9H 7FAD =1 28 OUT07IEN EQU 07FADH 7FAA =1 29 OUT07IRQ EQU 07FAAH 7FAE =1 30 USBIEN EQU 07FAEH 7FAB =1 31 USBIRQ EQU 07FABH 7FD6 =1 32 USBControl EQU 07FD6H 7FA6 =1 33 I2CData EQU 07FA6H 7FA5 =1 34 I2CControl EQU 07FA5H 7F99 =1 35 PortA_PINS EQU 07F99H 7F9A =1 36 PortB_PINS EQU 07F9AH 7F93 =1 37 PortA_Config EQU 07F93H 7F94 =1 38 PortB_Config EQU 07F94H 7F96 =1 39 PortA_OUT EQU 07F96H 7F9C =1 40 PortA_OE EQU 07F9CH 7F9D =1 41 PortB_OE EQU 07F9DH =1 42 ; =1 43 ; Byte Variables =1 44 ---- =1 45 DSEG AT 20H 0020 =1 46 FLAGS: DS 1 ; This register is bit-addressable =1 47 ; Bit Variables 0000 =1 48 Configured EQU FLAGS.0 ; Is this device configured 0001 =1 49 STALL EQU FLAGS.1 ; Need to STALL endpoint 0 0002 =1 50 SendData EQU FLAGS.2 ; Need to send data to PC Host 0003 =1 51 IsDescriptor EQU FLAGS.3 ; Enable a shortcut reply =1 52 ; 0021 =1 53 MonitorSpace: DS 1FH ; Used by Dscope 0040 =1 54 Temp: DS 1 ; A temporary working register 0041 =1 55 Idle_Time: DS 1 ; The time the PC host wants us to wait 0042 =1 56 Expired_Time: DS 1 ; A downcounter for timed Reports 0043 =1 57 ReplyBuffer: DS 3 ; First byte is Count =1 58 ; A51 MACRO ASSEMBLER I2C 22/07/99 12:36:44 PAGE 2 =1 59 ; Declare the specific variables used by each of the examples 0046 =1 60 Overlay EQU $ 0046 =1 61 Old_Buttons: DS 1 ; Used by BAL: stores current button position 0047 =1 62 LEDstrobe: DS 1 ; Used by BAL: strobe one LED on at a time 0048 =1 63 LEDvalue: DS 1 ; Used by BAL: stores current LED value 0049 =1 64 Msec_Counter: DS 1 ; Used by BAL: counts up to 4 msec =1 65 0046 =1 66 ORG Overlay ; Overlay the variables (only one set in use at any one tim e) 0046 =1 67 I2CDataByte: DS 1 ; Used by I2C: keep a local copy of data read from I2C bus =1 68 0046 =1 69 ORG Overlay 0046 =1 70 LightValues: DS 6 ; Used by LP: local buffer for light brightness =1 71 0046 =1 72 ORG Overlay 0046 =1 73 LimitValues: DS 12 ; Used by Temps: local buffer for limits =1 74 0046 =1 75 ORG Overlay 0046 =1 76 LEDBuffer: DS 42 ; Used by RB: local buffer for reader board =1 77 ; 78 $INCLUDE(../Vectors.A51) =1 79 ; This module is common to all of the examples. =1 80 ; It contains all of the interrupt vector declarations and =1 81 ; the first level interrupt servicing (register save, call subroutine, =1 82 ; clear interrupt source, restore registers, return) =1 83 ; Suspend and Resume are handled totally in this module =1 84 ; =1 85 ; A Reset sends us to Program space location 0 ---- =1 86 CSEG AT 0 ; Code space =1 87 USING 0 ; Reset forces Register Bank 0 0000 020360 =1 88 LJMP Reset =1 89 ; =1 90 ; The interrupt vector table is also located here =1 91 ; EZ-USB has two levels of USB interrupts: =1 92 ; 1-the main level is described in this table (at ORG 43H) =1 93 ; 2-there are 21 sources of USB interrupts and these are described in USB_ISR =1 94 ; This means that two levels of acknowledgement and clearing will be required =1 95 ; LJMP INT0_ISR ; Features not used are commented out =1 96 ; ORG 0BH =1 97 ; LJMP Timer0_ISR =1 98 ; ORG 13H =1 99 ; LJMP INT1_ISR =1 100 ; ORG 1BH =1 101 ; LJMP Timer1_ISR =1 102 ; ORG 23H =1 103 ; LJMP UART0_ISR =1 104 ; ORG 2BH =1 105 ; LJMP Timer2_ISR =1 106 ; ORG 33H =1 107 ; LJMP WakeUp_ISR =1 108 ; ORG 3BH =1 109 ; LJMP UART1_ISR 0043 =1 110 ORG 43H 0043 020100 =1 111 LJMP USB_ISR ; Auto Vector will replace byte 45H =1 112 ; ORG 4BH =1 113 ; LJMP I2C_ISR =1 114 ; ORG 53H =1 115 ; LJMP INT4_ISR =1 116 ; ORG 5BH =1 117 ; LJMP INT5_ISR =1 118 ; ORG 63H =1 119 ; LJMP INT6_ISR =1 120 00E0 =1 121 ORG 0E0H ; Keep out of the way of dScope monitor =1 122 ; If you are not using dScope then this memory hole =1 123 ; may be used for useful routines. A51 MACRO ASSEMBLER I2C 22/07/99 12:36:44 PAGE 3 0100 =1 124 ORG 100H 0100 02013C =1 125 USB_ISR:LJMP SUDAV_ISR 0103 00 =1 126 DB 0 ; Pad entries to 4 bytes 0104 020158 =1 127 LJMP SOF_ISR 0107 00 =1 128 DB 0 0108 020118 =1 129 LJMP SUTOK_ISR 010B 00 =1 130 DB 0 010C 020129 =1 131 LJMP Suspend_ISR 010F 00 =1 132 DB 0 0110 020120 =1 133 LJMP USBReset_ISR 0113 00 =1 134 DB 0 0114 020118 =1 135 LJMP Reserved 0117 00 =1 136 DB 0 =1 137 ; LJMP EP0In_ISR ; Endpoint Interrupts are not used in these examples =1 138 ; DB 0 ; Comment out features not used =1 139 ; LJMP EP0Out_ISR =1 140 ; DB 0 =1 141 ; LJMP EP1In_ISR =1 142 ; DB 0 =1 143 ; LJMP EP1Out_ISR =1 144 ; DB 0 =1 145 ; LJMP EP2In_ISR =1 146 ; DB 0 =1 147 ; LJMP EP2Out_ISR =1 148 ; DB 0 =1 149 ; LJMP EP3In_ISR =1 150 ; DB 0 =1 151 ; LJMP EP3Out_ISR =1 152 ; DB 0 =1 153 ; LJMP EP4In_ISR =1 154 ; DB 0 =1 155 ; LJMP EP4Out_ISR =1 156 ; DB 0 =1 157 ; LJMP EP5In_ISR =1 158 ; DB 0 =1 159 ; LJMP EP5Out_ISR =1 160 ; DB 0 =1 161 ; LJMP EP6In_ISR =1 162 ; DB 0 =1 163 ; LJMP EP6Out_ISR =1 164 ; DB 0 =1 165 ; LJMP EP7In_ISR =1 166 ; DB 0 =1 167 ; LJMP EP7Out_ISR =1 168 ; End of Interrupt Vector tables =1 169 =1 170 ; When a feature is used insert the required interrupt processing here =1 171 ; The example use only used Endpoints 0 and 1 and also SOF for timing 0118 =1 172 Reserved: 0118 =1 173 INT0_ISR: 0118 =1 174 Timer0_ISR: 0118 =1 175 INT1_ISR: 0118 =1 176 Timer1_ISR: 0118 =1 177 UART0_ISR: 0118 =1 178 Timer2_ISR: 0118 =1 179 UART1_ISR: 0118 =1 180 I2C_ISR: 0118 =1 181 INT4_ISR: 0118 =1 182 INT5_ISR: 0118 =1 183 INT6_ISR: 0118 =1 184 SUTOK_ISR: 0118 =1 185 EP0In_ISR: 0118 =1 186 EP0Out_ISR: 0118 =1 187 EP1In_ISR: 0118 =1 188 EP1Out_ISR: 0118 =1 189 EP2In_ISR: A51 MACRO ASSEMBLER I2C 22/07/99 12:36:44 PAGE 4 0118 =1 190 EP2Out_ISR: 0118 =1 191 EP3In_ISR: 0118 =1 192 EP3Out_ISR: 0118 =1 193 EP4In_ISR: 0118 =1 194 EP4Out_ISR: 0118 =1 195 EP5In_ISR: 0118 =1 196 EP5Out_ISR: 0118 =1 197 EP6In_ISR: 0118 =1 198 EP6Out_ISR: 0118 =1 199 EP7In_ISR : 0118 =1 200 EP7Out_ISR: 0118 =1 201 Not_Used: ; Should not get any of these 0118 32 =1 202 RETI =1 203 0119 =1 204 ClearINT2: ; Tell the hardware that we're done 0119 E591 =1 205 MOV A, EXIF 011B C2E4 =1 206 CLR ACC.4 ; Clear the Interrupt 2 bit 011D F591 =1 207 MOV EXIF, A 011F 22 =1 208 RET =1 209 0120 =1 210 USBReset_ISR: ; Bus has been Reset, move to DEFAULT state 0120 C0E0 =1 211 PUSH ACC 0122 C200 =1 212 CLR Configured 0124 3119 =1 213 CALL ClearINT2 =1 214 ; No need to clear source of interrupt 0126 D0E0 =1 215 POP ACC 0128 32 =1 216 RETI =1 217 0129 =1 218 Suspend_ISR: ; SIE detected an Idle bus 0129 C0E0 =1 219 PUSH ACC 012B E587 =1 220 MOV A, PCON 012D 4401 =1 221 ORL A, #1 012F F587 =1 222 MOV PCON, A ; Go to sleep! 0131 00 =1 223 NOP 0132 00 =1 224 NOP ; Wake up here due to a USBResume 0133 00 =1 225 NOP 0134 3119 =1 226 CALL ClearINT2 0136 D0E0 =1 227 POP ACC 0138 32 =1 228 RETI =1 229 0139 =1 230 WakeUp_ISR: ; Not using external WAKEUP in these examples =1 231 ; So this must be due to a USBResume 0139 C2DC =1 232 CLR EICON.4 ; Clear the wakeup interrupt source 013B 32 =1 233 RETI =1 234 013C =1 235 SUDAV_ISR: ; A Setup packet has been received 013C C0D0 =1 236 PUSH PSW ; Save Registers before the service routine 013E C0E0 =1 237 PUSH ACC 0140 C082 =1 238 PUSH DPL 0142 C083 =1 239 PUSH DPH 0144 120169 =1 240 CALL ServiceSetupPacket 0147 3119 =1 241 CALL ClearINT2 =1 242 ; Clear the source of the interrupt 0149 7401 =1 243 MOV A, #00000001b 014B 907FAB =1 244 ExitISR:MOV DPTR, #USBIRQ 014E F0 =1 245 MOVX @DPTR, A 014F D083 =1 246 POP DPH ; Restore Registers 0151 D082 =1 247 POP DPL 0153 D0E0 =1 248 POP ACC 0155 D0D0 =1 249 POP PSW 0157 32 =1 250 RETI =1 251 0158 =1 252 SOF_ISR: ; A Start-Of-Frame packet has been received 0158 C0D0 =1 253 PUSH PSW ; Save Registers before the service routine 015A C0E0 =1 254 PUSH ACC 015C C082 =1 255 PUSH DPL A51 MACRO ASSEMBLER I2C 22/07/99 12:36:44 PAGE 5 015E C083 =1 256 PUSH DPH 0160 1203DC =1 257 CALL ServiceTimerRoutine 0163 3119 =1 258 CALL ClearINT2 =1 259 ; Clear the source of the interrupt 0165 7402 =1 260 MOV A, #00000010b 0167 80E2 =1 261 JMP ExitISR =1 262 =1 263 264 $INCLUDE(../USB_INT.A51) =1 265 ; This module is common to all of the examples. =1 266 ; It services USB Requests from the SIE. =1 267 ; Interpretation of the Output Reports is handled by MAIN =1 268 ; ---- =1 269 CSEG 0169 =1 270 ServiceSetupPacket: 0169 907FE8 =1 271 MOV DPTR, #SETUPDAT ; Point to Setup Packet data 016C E0 =1 272 MOVX A, @DPTR ; Get the RequestType 016D A2E7 =1 273 MOV C, ACC.7 ; Bit 7 = 1 means IO device needs to send data to P C Host 016F 9202 =1 274 MOV SendData, C 0171 545C =1 275 ANL A, #01011100b ; IF RequestType[6.4.3.2] = 1 THEN goto BadRequest 0173 7051 =1 276 JNZ BadRequest 0175 E0 =1 277 MOVX A, @DPTR ; IF RequestType[1&0] = 1 THEN goto BadRequest 0176 A2E0 =1 278 MOV C, ACC.0 0178 82E1 =1 279 ANL C, ACC.1 017A 404A =1 280 JC BadRequest 017C 30E502 =1 281 JNB ACC.5, NotB5 ; IF RequestType[5] = 1 THEN RequestType[1,0] = [1, 1] 017F 7403 =1 282 MOV A, #00000011b 0181 5403 =1 283 NotB5: ANL A, #00000011b ; Set CommandIndex[5,4] = RequestType[1,0] 0183 C4 =1 284 SWAP A 0184 F540 =1 285 MOV Temp, A ; Save HI nibble of CommandIndex =1 286 ; Set CommandIndex[3,0] = Request[3,0] 0186 A3 =1 287 INC DPTR ; Point to Request 0187 E0 =1 288 MOVX A, @DPTR 0188 540F =1 289 ANL A, #00001111b ; Only 13 are defined today, handle in table 018A 4540 =1 290 ORL A, Temp 018C 1201D5 =1 291 CALL CorrectSubroutine ; goto CommandTable(CommandIndex) =1 292 ; Returns STALL=1 if a stall is required 018F 200134 =1 293 JB STALL, BadRequest 0192 300218 =1 294 JNB SendData, HandShake 0195 200320 =1 295 JB IsDescriptor, LoadSUDPTR; EZ-USB has a short cut for descriptors =1 296 ; Send data in ReplyBuffer 0198 907F02 =1 297 MOV DPTR, #EP0InBuffer+2 019B 7846 =1 298 MOV R0, #ReplyBuffer+3 019D 754003 =1 299 MOV Temp, #3 ; Copy maximum byte count 01A0 E6 =1 300 CopyRB: MOV A, @R0 01A1 F0 =1 301 MOVX @DPTR, A 01A2 1582 =1 302 DEC DPL 01A4 18 =1 303 DEC R0 01A5 D540F8 =1 304 DJNZ Temp, CopyRB 01A8 E6 =1 305 MOV A, @R0 ; Get real byte count 01A9 =1 306 SendEP0InBuffer: 01A9 907FB5 =1 307 MOV DPTR, #In0ByteCount 01AC =1 308 StartXfer: 01AC F0 =1 309 MOVX @DPTR, A ; This write initiates the transfer 01AD =1 310 HandShake: ; Handshake with host 01AD 754002 =1 311 MOV Temp, #00000010b ; Set HSNAK to tell the SIE that we're done 01B0 =1 312 SetEP0Control: 01B0 907FB4 =1 313 MOV DPTR, #EP0Control 01B3 E0 =1 314 MOVX A, @DPTR 01B4 4540 =1 315 ORL A, Temp 01B6 F0 =1 316 MOVX @DPTR, A 01B7 22 =1 317 RET 01B8 =1 318 LoadSUDPTR: ; Send the data pointed to by DPTR 01B8 858240 =1 319 MOV Temp, DPL A51 MACRO ASSEMBLER I2C 22/07/99 12:36:44 PAGE 6 01BB E583 =1 320 MOV A, DPH 01BD 907FD4 =1 321 MOV DPTR, #SUDPTR 01C0 F0 =1 322 MOVX @DPTR, A 01C1 E540 =1 323 MOV A, Temp 01C3 A3 =1 324 INC DPTR 01C4 80E6 =1 325 JMP StartXfer 01C6 =1 326 BadRequest: ; Invalid Request was received 01C6 754003 =1 327 MOV Temp, #00000011b ; Set EP0STALL and HSNAK 01C9 80E5 =1 328 JMP SetEP0Control =1 329 01CB =1 330 NextDPTR: ; Returns (DPTR + byte DPTR is pointing to) 01CB E0 =1 331 MOVX A, @DPTR 01CC =1 332 BumpDPTR: ; Returns (DPTR + ACC) 01CC 2582 =1 333 ADD A, DPL 01CE F582 =1 334 MOV DPL, A 01D0 5002 =1 335 JNC Skip 01D2 0583 =1 336 INC DPH ; Need 16 bit arithmetic here 01D4 22 =1 337 Skip: RET =1 338 01D5 =1 339 CorrectSubroutine: ; Jump to the subroutine that DPTR is pointing to 01D5 9001FA =1 340 MOV DPTR, #CommandTable 01D8 31CC =1 341 CALL BumpDPTR ; Point to entry 01DA E0 =1 342 MOVX A, @DPTR ; Get the offset 01DB 9001FA =1 343 MOV DPTR, #CommandTable 01DE 31CC =1 344 CALL BumpDPTR ; Get the routine address 01E0 C082 =1 345 PUSH DPL ; Create a RETURN address on stack 01E2 C083 =1 346 PUSH DPH ; Note: JMP @A+DPTR not used since A, DPTR needed 01E4 7845 =1 347 MOV R0, #ReplyBuffer+2 01E6 E4 =1 348 CLR A 01E7 F6 =1 349 MOV @R0, A ; Clear ReplyBuffer 01E8 18 =1 350 DEC R0 01E9 F6 =1 351 MOV @R0, A 01EA 18 =1 352 DEC R0 01EB 7601 =1 353 MOV @R0, #1 ; Default non-descriptor reply 01ED 907FEA =1 354 MOV DPTR, #SETUPDAT+2 ; Point to LOW(wValue) 01F0 E0 =1 355 MOVX A, @DPTR ; Many of the routines need these 01F1 F5F0 =1 356 MOV B, A ; LOW(wValue) in B 01F3 A3 =1 357 INC DPTR 01F4 E0 =1 358 MOVX A, @DPTR ; HIGH(wValue) in A 01F5 C201 =1 359 CLR STALL 01F7 C203 =1 360 CLR IsDescriptor 01F9 22 =1 361 RET ; Go to service routine =1 362 =1 363 ; Since the table only contains byte offsets, it is important that all these routines are =1 364 ; within one page (100H) of CommandTable =1 365 ; 01FA =1 366 CommandTable: =1 367 ; First 16 commands are for the Device 01FA 6D =1 368 DB Device_Get_Status - CommandTable 01FB 40 =1 369 DB Device_Clear_Feature - CommandTable 01FC 40 =1 370 DB Invalid - CommandTable 01FD 40 =1 371 DB Device_Set_Feature - CommandTable 01FE 40 =1 372 DB Invalid - CommandTable 01FF 40 =1 373 DB Invalid - CommandTable ; SIE implements Device_Set_Address 0200 81 =1 374 DB Get_Descriptor - CommandTable 0201 40 =1 375 DB Set_Descriptor - CommandTable 0202 6A =1 376 DB Get_Configuration - CommandTable 0203 74 =1 377 DB Set_Configuration - CommandTable 0204 40 =1 378 DB Invalid - CommandTable 0205 40 =1 379 DB Invalid - CommandTable 0206 40 =1 380 DB Invalid - CommandTable 0207 40 =1 381 DB Invalid - CommandTable 0208 40 =1 382 DB Invalid - CommandTable 0209 40 =1 383 DB Invalid - CommandTable =1 384 ; Next 16 commands are for the Interface 020A 71 =1 385 DB Interface_Get_Status - CommandTable A51 MACRO ASSEMBLER I2C 22/07/99 12:36:44 PAGE 7 020B 40 =1 386 DB Interface_Clear_Feature - CommandTable 020C 40 =1 387 DB Invalid - CommandTable 020D 40 =1 388 DB Interface_Set_Feature - CommandTable 020E 40 =1 389 DB Invalid - CommandTable 020F 40 =1 390 DB Invalid - CommandTable 0210 A5 =1 391 DB Get_Class_Descriptor - CommandTable 0211 40 =1 392 DB Set_Class_Descriptor - CommandTable 0212 40 =1 393 DB Invalid - CommandTable 0213 40 =1 394 DB Invalid - CommandTable 0214 40 =1 395 DB Get_Interface - CommandTable 0215 40 =1 396 DB Set_Interface - CommandTable 0216 40 =1 397 DB Invalid - CommandTable 0217 40 =1 398 DB Invalid - CommandTable 0218 40 =1 399 DB Invalid - CommandTable 0219 40 =1 400 DB Invalid - CommandTable =1 401 ; Next 16 commands are for the Endpoint 021A 71 =1 402 DB Endpoint_Get_Status - CommandTable 021B 42 =1 403 DB Endpoint_Clear_Feature - CommandTable 021C 40 =1 404 DB Invalid - CommandTable 021D 40 =1 405 DB Endpoint_Set_Feature - CommandTable 021E 40 =1 406 DB Invalid - CommandTable 021F 40 =1 407 DB Invalid - CommandTable 0220 40 =1 408 DB Invalid - CommandTable 0221 40 =1 409 DB Invalid - CommandTable 0222 40 =1 410 DB Invalid - CommandTable 0223 40 =1 411 DB Invalid - CommandTable 0224 40 =1 412 DB Invalid - CommandTable 0225 40 =1 413 DB Invalid - CommandTable 0226 40 =1 414 DB Endpoint_Sync_Frame - CommandTable 0227 40 =1 415 DB Invalid - CommandTable 0228 40 =1 416 DB Invalid - CommandTable 0229 40 =1 417 DB Invalid - CommandTable =1 418 ; Next 16 commands are Class Requests 022A 40 =1 419 DB Invalid - CommandTable 022B 56 =1 420 DB Get_Report - CommandTable 022C 63 =1 421 DB Get_Idle - CommandTable 022D 40 =1 422 DB Get_Protocol - CommandTable 022E 40 =1 423 DB Invalid - CommandTable 022F 40 =1 424 DB Invalid - CommandTable 0230 40 =1 425 DB Invalid - CommandTable 0231 40 =1 426 DB Invalid - CommandTable 0232 40 =1 427 DB Invalid - CommandTable 0233 43 =1 428 DB Set_Report - CommandTable 0234 5D =1 429 DB Set_Idle - CommandTable 0235 40 =1 430 DB Set_Protocol - CommandTable 0236 40 =1 431 DB Invalid - CommandTable 0237 40 =1 432 DB Invalid - CommandTable 0238 40 =1 433 DB Invalid - CommandTable 0239 40 =1 434 DB Invalid - CommandTable =1 435 ; =1 436 ; Many requests are INVALID for this example 023A =1 437 Get_Protocol: ; We are not a Boot device 023A =1 438 Set_Protocol: ; We are not a Boot device 023A =1 439 Set_Descriptor: ; Our Descriptors are static 023A =1 440 Set_Class_Descriptor: ; Our Descriptors are static 023A =1 441 Set_Interface: ; We only have one Interface 023A =1 442 Get_Interface: ; We do not have an Alternate setting 023A =1 443 Device_Set_Feature: ; We have no features that can be set or cleared 023A =1 444 Interface_Set_Feature: ; We have no features that can be set or cleared 023A =1 445 Endpoint_Set_Feature: ; We have no features that can be set or cleared 023A =1 446 Device_Clear_Feature: ; We have no features that can be set or cleared 023A =1 447 Interface_Clear_Feature: ; We have no features that can be set or cleared 023A =1 448 Endpoint_Sync_Frame: ; We are not an Isonchronous device =1 449 023A =1 450 Invalid: ; Invalid Request made, STALL the Endpoint 023A D201 =1 451 SETB STALL A51 MACRO ASSEMBLER I2C 22/07/99 12:36:44 PAGE 8 =1 452 ; 023C =1 453 Endpoint_Clear_Feature: ; We have no features that can be set or cleared =1 454 ; 023C 22 =1 455 Reply: RET =1 456 023D =1 457 Set_Report: ; Host wants to sent us a Report. =1 458 ; The ONLY case in this example where host sends data to us 023D 3000FA =1 459 JNB Configured, Invalid ; Need to be Configured to do this command 0240 907FC5 =1 460 MOV DPTR, #Out0ByteCount ; Enable EP0OutBuffer to receive data 0243 F0 =1 461 MOVX @DPTR, A ; Any value will do 0244 907FAA =1 462 MOV DPTR, #OUT07IRQ ; Wait for valid data in EP0OutBuffer 0247 E0 =1 463 Wait4D: MOVX A, @DPTR 0248 5401 =1 464 ANL A, #00000001b 024A 60FB =1 465 JZ Wait4D 024C F0 =1 466 MOVX @DPTR, A ; Clear the interrupt 024D 0203B3 =1 467 JMP ProcessOutputReport ; RETurn via this subroutine 0250 =1 468 Get_Report: ; Host wants a Report 0250 3000E7 =1 469 JNB Configured, Invalid ; Need to be Configured to do this command 0253 08 =1 470 INC R0 ; Point to ReplyBuffer(1) 0254 7618 =1 471 MOV @R0, #18H ; Reply with a recognizable (arbitary) value 0256 22 =1 472 RET 0257 =1 473 Set_Idle: ; Host wants to tell us how often we should talk 0257 3000E0 =1 474 JNB Configured, Invalid ; Need to be Configured to do this command 025A F541 =1 475 MOV Idle_Time, A 025C 22 =1 476 RET ; Handshake with host 025D =1 477 Get_Idle: ; Host must have forgotten what he told us to do 025D 3000DA =1 478 JNB Configured, Invalid ; Need to be Configured to do this command 0260 08 =1 479 INC R0 ; Point to ReplyBuffer(1) 0261 A641 =1 480 MOV @R0, Idle_Time 0263 22 =1 481 RET 0264 =1 482 Get_Configuration: 0264 3000D5 =1 483 JNB Configured, Reply =1 484 ; If configured return a 1 (via Device_Get_Status) 0267 =1 485 Device_Get_Status: ; Only two bits of Device Status are defined 0267 08 =1 486 INC R0 ; Point to ReplyBuffer(1) 0268 7601 =1 487 MOV @R0, #1 ; Bit 1=Remote Wakeup(=0), Bit 0=Self Powered(=1) 026A 22 =1 488 RET =1 489 026B =1 490 Interface_Get_Status: ; Interface Status is currently defined as 0 026B =1 491 Endpoint_Get_Status: 026B 7602 =1 492 MOV @R0, #2 026D 22 =1 493 RET 026E =1 494 Set_Configuration: ; Valid values are 0 and 1 026E E5F0 =1 495 MOV A, B ; Get LOW(wValue) 0270 6006 =1 496 JZ Deconfigured 0272 14 =1 497 DEC A 0273 70C5 =1 498 JNZ Invalid 0275 D200 =1 499 SETB Configured 0277 22 =1 500 RET 0278 =1 501 Deconfigured: 0278 C200 =1 502 CLR Configured 027A 22 =1 503 RET 027B =1 504 Get_Descriptor: ; Host wants to know who/what we are 027B D203 =1 505 SETB IsDescriptor 027D 14 =1 506 DEC A ; Valid Values are 1, 2 and 3 027E 9002C5 =1 507 MOV DPTR, #DeviceDescriptor 0281 60B9 =1 508 JZ Reply 0283 14 =1 509 DEC A 0284 9002D7 =1 510 MOV DPTR, #ConfigurationDescriptor 0287 60B3 =1 511 JZ Reply 0289 14 =1 512 DEC A 028A 70AE =1 513 JNZ Invalid =1 514 ; Request is for a String Descriptor 028C 900318 =1 515 MOV DPTR, #String0 ; Point to String 0 028F E5F0 =1 516 MOV A, B ; Get String Index 0291 =1 517 NextString: A51 MACRO ASSEMBLER I2C 22/07/99 12:36:44 PAGE 9 0291 601E =1 518 JZ FixUpthenReply 0293 F540 =1 519 MOV Temp, A ; Save String Index 0295 31CB =1 520 CALL NextDPTR 0297 E0 =1 521 MOVX A, @DPTR ; Get the String Length (= 0 means we're at Backsto p) 0298 60A0 =1 522 JZ Invalid ; Asked for a string I don't have 029A E540 =1 523 MOV A, Temp 029C 14 =1 524 DEC A 029D 80F2 =1 525 JMP NextString ; Check if we are there yet 029F =1 526 Get_Class_Descriptor: ; Valid values are 21H, 22H, 23H for Class Request 029F D203 =1 527 SETB IsDescriptor 02A1 C3 =1 528 CLR C 02A2 9421 =1 529 SUBB A, #21H 02A4 9002E9 =1 530 MOV DPTR, #HIDDescriptor 02A7 6093 =1 531 JZ Reply 02A9 14 =1 532 DEC A 02AA 9002F9 =1 533 MOV DPTR, #ReportDescriptor 02AD 608D =1 534 JZ Reply =1 535 ; DEC A ; This example does not use Physical Descriptors =1 536 ; JZ Send_Physical_Descriptor 02AF 8089 =1 537 JMP Invalid =1 538 ; =1 539 ; Error check: this MUST be on within a page of CommandTable 00B7 =1 540 WithinSamePage EQU $ - CommandTable =1 541 ; 02B1 =1 542 FixUpthenReply: ; EZ-USB Rev D has a String Descriptor bug =1 543 ; Need to fill the IN0BUF (@ 7F00H) myself 02B1 E0 =1 544 MOVX A, @DPTR ; Get the string length 02B2 FF =1 545 MOV R7, A ; Save counter 02B3 F5F0 =1 546 MOV B, A 02B5 7800 =1 547 MOV R0, #LOW(EP0InBuffer) ; PageReg = 7FH = HIGH(EP0InBuffer) 02B7 F2 =1 548 CopySD: MOVX @R0, A 02B8 08 =1 549 INC R0 02B9 A3 =1 550 INC DPTR 02BA E0 =1 551 MOVX A, @DPTR 02BB DFFA =1 552 DJNZ R7, CopySD =1 553 ; Fixup complete, get back to the program flow 02BD D0E0 =1 554 POP ACC ; Get rid of the return address 02BF D0E0 =1 555 POP ACC 02C1 E5F0 =1 556 MOV A, B ; Retrieve byte count 02C3 21A9 =1 557 JMP SendEP0InBuffer 558 $INCLUDE(DTables.A51) =1 559 ; This module declares the descriptors =1 560 ; =1 561 ; This example has one Device Descriptor with: =1 562 ; One Configuration - single IN port and single OUT port =1 563 ; One Interface - there is only one method of accessing the ports =1 564 ; One HID Descriptor - to make PC host software simpler =1 565 ; One Endpoint Descriptor - for HID Input Reports =1 566 ; One Report Descriptor - one byte IN and one byte OUT reports =1 567 ; Multiple Sting Descriptors - to aid the user =1 568 ; ---- =1 569 CSEG 02C5 =1 570 DeviceDescriptor: 02C5 1201 =1 571 DB 18, 1 ; Length, Type 02C7 0101 =1 572 DW 101H ; USB Rev 1.1 02C9 000000 =1 573 DB 0, 0, 0 ; Class, Subclass and Protocol 02CC 40 =1 574 DB 64 ; EP0 size 02CD 4242 =1 575 DW 4242H, 1, 1 ; Vendor ID, Product ID and Version 02CF 0001 02D1 0001 02D3 010200 =1 576 DB 1, 2, 0 ; Manufacturer, Product & Serial# Names 02D6 01 =1 577 DB 1 ; #Configs 02D7 =1 578 ConfigurationDescriptor: 02D7 0902 =1 579 DB 9, 2 ; Length, Type 02D9 2200 =1 580 DB LOW(ConfigLength), HIGH(ConfigLength) A51 MACRO ASSEMBLER I2C 22/07/99 12:36:44 PAGE 10 02DB 010100 =1 581 DB 1, 1, 0 ; #Interfaces, Configuration#, Config. Name 02DE 80 =1 582 DB 10000000b ; Attributes = Bus Powered 02DF 32 =1 583 DB 50 ; Max. Power is 50x2 = 100mA 02E0 =1 584 InterfaceDescriptor: 02E0 0904 =1 585 DB 9, 4 ; Length, Type 02E2 000001 =1 586 DB 0, 0, 1 ; No alternate setting, HID uses EP1 02E5 03 =1 587 DB 3 ; Class = Human Interface Device 02E6 0000 =1 588 DB 0, 0 ; Subclass and Protocol 02E8 00 =1 589 DB 0 ; Interface Name 02E9 =1 590 HIDDescriptor: 02E9 0921 =1 591 DB 9, 21H ; Length, Type 02EB 0001 =1 592 DB 0, 1 ; HID Class Specification compliance 02ED 00 =1 593 DB 0 ; Country localization (=none) 02EE 01 =1 594 DB 1 ; Number of descriptors to follow 02EF 22 =1 595 DB 22H ; And it's a Report descriptor 02F0 1F00 =1 596 DB LOW(ReportLength), HIGH(ReportLength) 02F2 =1 597 EndpointDescriptor: 02F2 0705 =1 598 DB 7, 5 ; Length, Type 02F4 81 =1 599 DB 10000001b ; Address = IN 1 02F5 03 =1 600 DB 00000011b ; Interrupt 02F6 4000 =1 601 DB 64, 0 ; Maximum packet size (this example only uses 1) 02F8 64 =1 602 DB 100 ; Poll every 0.1 seconds 0022 =1 603 ConfigLength EQU $ - ConfigurationDescriptor =1 604 02F9 =1 605 ReportDescriptor: ; Generated with HID Tool, copied to here 02F9 0600FF =1 606 DB 6, 0, 0FFH ; Usage_Page (Vendor Defined) 02FC 0901 =1 607 DB 9, 1 ; Usage (I/O Device) 02FE A101 =1 608 DB 0A1H, 1 ; Collection (Application) 0300 1901 =1 609 DB 19H, 1 ; Usage_Minimum 0302 2902 =1 610 DB 29H, 2 ; Usage_Maximum 0304 1500 =1 611 DB 15H, 0 ; Logical_Minimum (0) 0306 26FF00 =1 612 DB 26H, 255, 0 ; Logical_Maximum (255) 0309 7508 =1 613 DB 75H, 8 ; Report_Size (8) 030B 9501 =1 614 DB 95H, 1 ; Report_Count (1) = Read Address 030D 8102 =1 615 DB 81H, 2 ; Input (Data,Var,Abs) 030F 1901 =1 616 DB 19H, 1 ; Usage_Minimum 0311 2902 =1 617 DB 29H, 2 ; Usage_Maximum 0313 9502 =1 618 DB 95H, 2 ; Report_Count (2) = Write Address + Data 0315 9102 =1 619 DB 91H, 2 ; Output (Data,Var,Abs) 0317 C0 =1 620 DB 0C0H ; End_Collection 001F =1 621 ReportLength EQU $-ReportDescriptor =1 622 0318 =1 623 String0: ; Declare the UNICODE strings 0318 04030904 =1 624 DB 4, 3, 9, 4 ; Only English language strings supported 031C =1 625 String1: ; Manufacturer 031C 2C03 =1 626 DB (String2-String1),3 ; Length, Type 031E 55005300 =1 627 DB "U",0,"S",0,"B",0," ",0,"D",0,"e",0,"s",0,"i",0,"g",0,"n",0," ", 0 0322 42002000 0326 44006500 032A 73006900 032E 67006E00 0332 2000 0334 42007900 =1 628 DB "B",0,"y",0," ",0,"E",0,"x",0,"a",0,"m",0,"p",0,"l",0,"e",0 0338 20004500 033C 78006100 0340 6D007000 0344 6C006500 0348 =1 629 String2: ; Product Name 0348 1603 =1 630 DB (EndOfDescriptors-String2),3 034A 49003200 =1 631 DB "I",0,"2",0,"C",0," ",0 034E 43002000 0352 42007200 =1 632 DB "B",0,"r",0,"i",0,"d",0,"g",0,"e",0 0356 69006400 035A 67006500 035E =1 633 EndOfDescriptors: 035E 0000 =1 634 DW 0 ; Backstop for String Descriptors A51 MACRO ASSEMBLER I2C 22/07/99 12:36:44 PAGE 11 =1 635 =1 636 =1 637 638 $INCLUDE(Main.A51) =1 639 ; This module initializes the microcontroller then executes MAIN forever =1 640 ; =1 641 0360 =1 642 Reset: 0360 7581EB =1 643 MOV SP, #235 ; Initialize the Stack at top of internal memory 0363 75927F =1 644 MOV PageReg, #7FH ; Needed to use MOVX @Ri =1 645 0366 78D6 =1 646 MOV R0, #LOW(USBControl) ; Simulate a disconnect 0368 E2 =1 647 MOVX A, @R0 0369 54F3 =1 648 ANL A, #11110011b ; Clear DISCON, DISCOE 036B F2 =1 649 MOVX @R0, A 036C 120391 =1 650 CALL Wait100msec ; Give the host time to react 036F E2 =1 651 MOVX A, @R0 ; Reconnect with this new identity 0370 4406 =1 652 ORL A, #00000110b ; Set DISCOE to enable pullup resistor 0372 F2 =1 653 MOVX @R0, A ; Set RENUM so that 8051 handles USB requests 0373 E4 =1 654 CLR A 0374 F520 =1 655 MOV FLAGS, A ; Start in Default state 0376 =1 656 InitializeIOSystem: ; This example uses only I2C signals =1 657 ; No initialization is required 0376 =1 658 InitializeInterruptSystem: ; First initialize the USB level 0376 78AC =1 659 MOV R0, #LOW(IN07IEN) 0378 F2 =1 660 MOVX @R0, A ; Disable interrupts from IN Endpoints 0-7 0379 08 =1 661 INC R0 037A F2 =1 662 MOVX @R0, A ; Disable interrupts from OUT Endpoints 0-7 037B 08 =1 663 INC R0 037C 7403 =1 664 MOV A, #00000011b 037E F2 =1 665 MOVX @R0, A ; Enable (Resume, Suspend,) SOF and SUDAV INTs 037F 08 =1 666 INC R0 0380 7401 =1 667 MOV A, #00000001b 0382 F2 =1 668 MOVX @R0, A ; Enable Auto Vectoring for USB interrupts 0383 78AA =1 669 MOV R0, #LOW(OUT07IRQ) 0385 74FF =1 670 MOV A, #0FFH 0387 F2 =1 671 MOVX @R0, A ; Clear out any pending interrupts =1 672 ; Now enable the main level 0388 75E801 =1 673 MOV EIE, #00000001b ; Enable INT2 = USB Interrupt (only) 038B 75A8C0 =1 674 MOV EI, #11000000b ; Enable interrupt subsystem (and Ser1 for Dscope) =1 675 =1 676 ; Initialization Complete. =1 677 ; 038E =1 678 MAIN: 038E 00 =1 679 NOP ; Not much of a main loop for this example 038F 80FD =1 680 JMP MAIN ; All actions are initiated by interrupts =1 681 ; We are a slave, we wait to be told what to do =1 682 0391 =1 683 Wait100msec: 0391 754064 =1 684 MOV Temp, #100 0394 =1 685 Wait1msec: ; A delay loop 0394 90FB50 =1 686 MOV DPTR, #-1200 0397 A3 =1 687 More: INC DPTR ; 3 cycles 0398 E582 =1 688 MOV A, DPL ; + 2 039A 4583 =1 689 ORL A, DPH ; + 2 039C 70F9 =1 690 JNZ More ; + 3 = 10 cycles x 1200 = 1msec 039E D540F3 =1 691 DJNZ Temp, Wait1msec 03A1 22 =1 692 RET =1 693 03A2 =1 694 Wait4Stop: ; Make sure the STOP from a previous 03A2 E2 =1 695 MOVX A, @R0 ; I2C transaction has completed 03A3 20E6FC =1 696 JB ACC.6, Wait4Stop 03A6 22 =1 697 RET 03A7 =1 698 SendI2Caddress: ; Send the first byte to I2C bus 03A7 71A2 =1 699 CALL Wait4Stop 03A9 7480 =1 700 MOV A, #10000000b ; Set the START bit A51 MACRO ASSEMBLER I2C 22/07/99 12:36:44 PAGE 12 03AB F2 =1 701 MOVX @R0, A ; I2C engine now primed 03AC =1 702 SendI2Cdatabyte: 03AC E0 =1 703 MOVX A, @DPTR ; Get data and . . . 03AD F3 =1 704 MOVX @R1, A ; . . . send using I2C engine 03AE =1 705 Wait4Done: 03AE E2 =1 706 MOVX A, @R0 03AF 30E0FC =1 707 JNB ACC.0, Wait4Done ; Wait for the data to be transmitted 03B2 22 =1 708 RET =1 709 03B3 =1 710 ProcessOutputReport: ; A Report has just been received =1 711 ; The report is two bytes long =1 712 ; Byte 1, Bits[7:1] = an I2C Address, Bit[0] = direction (0 = Write) =1 713 ; Byte 2 = DataByte if byte 1 specifies a write 03B3 78A5 =1 714 MOV R0, #LOW(I2CControl) ; Initialize the pointers to be used 03B5 79A6 =1 715 MOV R1, #LOW(I2CData) 03B7 907EC0 =1 716 MOV DPTR, #EP0OutBuffer ; Point to the Report 03BA 71A7 =1 717 CALL SendI2Caddress 03BC E0 =1 718 MOVX A, @DPTR ; Retrieve Report Byte 1 03BD 20E007 =1 719 JB ACC.0, I2C_Read 03C0 =1 720 I2C_Write: 03C0 A3 =1 721 INC DPTR ; Point to data byte to write 03C1 71AC =1 722 CALL SendI2Cdatabyte 03C3 7440 =1 723 MOV A, #01000000b ; Set the STOP bit 03C5 F2 =1 724 MOVX @R0, A 03C6 22 =1 725 RET 03C7 =1 726 I2C_Read: 03C7 7420 =1 727 MOV A, #00100000b ; Set the LASTRD bit 03C9 F2 =1 728 MOVX @R0, A 03CA E3 =1 729 MOVX A, @R1 ; Dummy read of I2C_Data 03CB 71AE =1 730 CALL Wait4Done 03CD 7440 =1 731 MOV A, #01000000b ; Set the STOP bit 03CF F2 =1 732 MOVX @R0, A ; Immediately follow with . . . 03D0 E3 =1 733 MOVX A, @R1 ; . . . read the I2C bus data =1 734 ; Fall into CreateInputReport 03D1 =1 735 CreateInputReport: =1 736 ; The report is only one byte long in this example =1 737 ; It contains the byte read from the I2C bus 03D1 907E80 =1 738 MOV DPTR, #EP1InBuffer ; Point to the buffer 03D4 F0 =1 739 MOVX @DPTR, A ; Update the Report 03D5 907FB7 =1 740 MOV DPTR, #IN1ByteCount 03D8 7401 =1 741 MOV A, #1 03DA F0 =1 742 MOVX @DPTR, A ; Endpoint 1 now 'armed', next IN will get data 03DB 22 =1 743 RET =1 744 745 $INCLUDE(Timer.A51) =1 746 ; This module services the real time interrupt =1 747 ; =1 748 ; Get a Real Time interrupt every One millisecond (using SOF interrupt) =1 749 ; =1 750 ; HID devices work on a 4 millisecond timer =1 751 ; =1 752 ; There is nothing to do in this example! 03DC =1 753 ServiceTimerRoutine: 03DC 22 =1 754 Ret =1 755 756 757 END A51 MACRO ASSEMBLER I2C 22/07/99 12:36:44 PAGE 13 SYMBOL TABLE LISTING ------ ----- ------- N A M E T Y P E V A L U E ATTRIBUTES ACC . . . . . . . . . . . D ADDR 00E0H A B . . . . . . . . . . . . D ADDR 00F0H A BADREQUEST. . . . . . . . C ADDR 01C6H A BUMPDPTR. . . . . . . . . C ADDR 01CCH A CLEARINT2 . . . . . . . . C ADDR 0119H A COMMANDTABLE. . . . . . . C ADDR 01FAH A CONFIGLENGTH. . . . . . . N NUMB 0022H A CONFIGURATIONDESCRIPTOR . C ADDR 02D7H A CONFIGURED. . . . . . . . B ADDR 0020H.0 A COPYRB. . . . . . . . . . C ADDR 01A0H A COPYSD. . . . . . . . . . C ADDR 02B7H A CORRECTSUBROUTINE . . . . C ADDR 01D5H A CREATEINPUTREPORT . . . . C ADDR 03D1H A DECONFIGURED. . . . . . . C ADDR 0278H A DEVICEDESCRIPTOR. . . . . C ADDR 02C5H A DEVICE_CLEAR_FEATURE. . . C ADDR 023AH A DEVICE_GET_STATUS . . . . C ADDR 0267H A DEVICE_SET_FEATURE. . . . C ADDR 023AH A DPH . . . . . . . . . . . D ADDR 0083H A DPL . . . . . . . . . . . D ADDR 0082H A DPS . . . . . . . . . . . D ADDR 0086H A EI. . . . . . . . . . . . D ADDR 00A8H A EICON . . . . . . . . . . D ADDR 00D8H A EIE . . . . . . . . . . . D ADDR 00E8H A ENDOFDESCRIPTORS. . . . . C ADDR 035EH A ENDPOINTDESCRIPTOR. . . . C ADDR 02F2H A ENDPOINT_CLEAR_FEATURE. . C ADDR 023CH A ENDPOINT_GET_STATUS . . . C ADDR 026BH A ENDPOINT_SET_FEATURE. . . C ADDR 023AH A ENDPOINT_SYNC_FRAME . . . C ADDR 023AH A EP0CONTROL. . . . . . . . N NUMB 7FB4H A EP0INBUFFER . . . . . . . N NUMB 7F00H A EP0IN_ISR . . . . . . . . C ADDR 0118H A EP0OUTBUFFER. . . . . . . N NUMB 7EC0H A EP0OUT_ISR. . . . . . . . C ADDR 0118H A EP1INBUFFER . . . . . . . N NUMB 7E80H A EP1IN_ISR . . . . . . . . C ADDR 0118H A EP1OUT_ISR. . . . . . . . C ADDR 0118H A EP2IN_ISR . . . . . . . . C ADDR 0118H A EP2OUT_ISR. . . . . . . . C ADDR 0118H A EP3IN_ISR . . . . . . . . C ADDR 0118H A EP3OUT_ISR. . . . . . . . C ADDR 0118H A EP4IN_ISR . . . . . . . . C ADDR 0118H A EP4OUT_ISR. . . . . . . . C ADDR 0118H A EP5IN_ISR . . . . . . . . C ADDR 0118H A EP5OUT_ISR. . . . . . . . C ADDR 0118H A EP6IN_ISR . . . . . . . . C ADDR 0118H A EP6OUT_ISR. . . . . . . . C ADDR 0118H A EP7IN_ISR . . . . . . . . C ADDR 0118H A EP7OUT_ISR. . . . . . . . C ADDR 0118H A EXIF. . . . . . . . . . . D ADDR 0091H A EXITISR . . . . . . . . . C ADDR 014BH A EXPIRED_TIME. . . . . . . D ADDR 0042H A FIXUPTHENREPLY. . . . . . C ADDR 02B1H A FLAGS . . . . . . . . . . D ADDR 0020H A GET_CLASS_DESCRIPTOR. . . C ADDR 029FH A GET_CONFIGURATION . . . . C ADDR 0264H A GET_DESCRIPTOR. . . . . . C ADDR 027BH A GET_IDLE. . . . . . . . . C ADDR 025DH A GET_INTERFACE . . . . . . C ADDR 023AH A A51 MACRO ASSEMBLER I2C 22/07/99 12:36:44 PAGE 14 GET_PROTOCOL. . . . . . . C ADDR 023AH A GET_REPORT. . . . . . . . C ADDR 0250H A HANDSHAKE . . . . . . . . C ADDR 01ADH A HIDDESCRIPTOR . . . . . . C ADDR 02E9H A I2CBRIDGE . . . . . . . . N NUMB ----- I2CCONTROL. . . . . . . . N NUMB 7FA5H A I2CDATA . . . . . . . . . N NUMB 7FA6H A I2CDATABYTE . . . . . . . D ADDR 0046H A I2C_ISR . . . . . . . . . C ADDR 0118H A I2C_READ. . . . . . . . . C ADDR 03C7H A I2C_WRITE . . . . . . . . C ADDR 03C0H A IDLE_TIME . . . . . . . . D ADDR 0041H A IN07IEN . . . . . . . . . N NUMB 7FACH A IN07IRQ . . . . . . . . . N NUMB 7FA9H A IN0BYTECOUNT. . . . . . . N NUMB 7FB5H A IN1BYTECOUNT. . . . . . . N NUMB 7FB7H A INITIALIZEINTERRUPTSYSTEM C ADDR 0376H A INITIALIZEIOSYSTEM. . . . C ADDR 0376H A INT0_ISR. . . . . . . . . C ADDR 0118H A INT1_ISR. . . . . . . . . C ADDR 0118H A INT4_ISR. . . . . . . . . C ADDR 0118H A INT5_ISR. . . . . . . . . C ADDR 0118H A INT6_ISR. . . . . . . . . C ADDR 0118H A INTERFACEDESCRIPTOR . . . C ADDR 02E0H A INTERFACE_CLEAR_FEATURE . C ADDR 023AH A INTERFACE_GET_STATUS. . . C ADDR 026BH A INTERFACE_SET_FEATURE . . C ADDR 023AH A INVALID . . . . . . . . . C ADDR 023AH A ISDESCRIPTOR. . . . . . . B ADDR 0020H.3 A LEDBUFFER . . . . . . . . D ADDR 0046H A LEDSTROBE . . . . . . . . D ADDR 0047H A LEDVALUE. . . . . . . . . D ADDR 0048H A LIGHTVALUES . . . . . . . D ADDR 0046H A LIMITVALUES . . . . . . . D ADDR 0046H A LOADSUDPTR. . . . . . . . C ADDR 01B8H A MAIN. . . . . . . . . . . C ADDR 038EH A MONITORSPACE. . . . . . . D ADDR 0021H A MORE. . . . . . . . . . . C ADDR 0397H A MSEC_COUNTER. . . . . . . D ADDR 0049H A NEXTDPTR. . . . . . . . . C ADDR 01CBH A NEXTSTRING. . . . . . . . C ADDR 0291H A NOTB5 . . . . . . . . . . C ADDR 0181H A NOT_USED. . . . . . . . . C ADDR 0118H A OLD_BUTTONS . . . . . . . D ADDR 0046H A OUT07IEN. . . . . . . . . N NUMB 7FADH A OUT07IRQ. . . . . . . . . N NUMB 7FAAH A OUT0BYTECOUNT . . . . . . N NUMB 7FC5H A OVERLAY . . . . . . . . . D ADDR 0046H A PAGEREG . . . . . . . . . D ADDR 0092H A PCON. . . . . . . . . . . D ADDR 0087H A PORTA_CONFIG. . . . . . . N NUMB 7F93H A PORTA_OE. . . . . . . . . N NUMB 7F9CH A PORTA_OUT . . . . . . . . N NUMB 7F96H A PORTA_PINS. . . . . . . . N NUMB 7F99H A PORTB_CONFIG. . . . . . . N NUMB 7F94H A PORTB_OE. . . . . . . . . N NUMB 7F9DH A PORTB_PINS. . . . . . . . N NUMB 7F9AH A PROCESSOUTPUTREPORT . . . C ADDR 03B3H A PSW . . . . . . . . . . . D ADDR 00D0H A REPLY . . . . . . . . . . C ADDR 023CH A REPLYBUFFER . . . . . . . D ADDR 0043H A REPORTDESCRIPTOR. . . . . C ADDR 02F9H A REPORTLENGTH. . . . . . . N NUMB 001FH A RESERVED. . . . . . . . . C ADDR 0118H A RESET . . . . . . . . . . C ADDR 0360H A SENDDATA. . . . . . . . . B ADDR 0020H.2 A A51 MACRO ASSEMBLER I2C 22/07/99 12:36:44 PAGE 15 SENDEP0INBUFFER . . . . . C ADDR 01A9H A SENDI2CADDRESS. . . . . . C ADDR 03A7H A SENDI2CDATABYTE . . . . . C ADDR 03ACH A SERVICESETUPPACKET. . . . C ADDR 0169H A SERVICETIMERROUTINE . . . C ADDR 03DCH A SETEP0CONTROL . . . . . . C ADDR 01B0H A SETUPDAT. . . . . . . . . N NUMB 7FE8H A SET_CLASS_DESCRIPTOR. . . C ADDR 023AH A SET_CONFIGURATION . . . . C ADDR 026EH A SET_DESCRIPTOR. . . . . . C ADDR 023AH A SET_IDLE. . . . . . . . . C ADDR 0257H A SET_INTERFACE . . . . . . C ADDR 023AH A SET_PROTOCOL. . . . . . . C ADDR 023AH A SET_REPORT. . . . . . . . C ADDR 023DH A SKIP. . . . . . . . . . . C ADDR 01D4H A SOF_ISR . . . . . . . . . C ADDR 0158H A SP. . . . . . . . . . . . D ADDR 0081H A STALL . . . . . . . . . . B ADDR 0020H.1 A STARTXFER . . . . . . . . C ADDR 01ACH A STRING0 . . . . . . . . . C ADDR 0318H A STRING1 . . . . . . . . . C ADDR 031CH A STRING2 . . . . . . . . . C ADDR 0348H A SUDAV_ISR . . . . . . . . C ADDR 013CH A SUDPTR. . . . . . . . . . N NUMB 7FD4H A SUSPEND_ISR . . . . . . . C ADDR 0129H A SUTOK_ISR . . . . . . . . C ADDR 0118H A TEMP. . . . . . . . . . . D ADDR 0040H A TIMER0_ISR. . . . . . . . C ADDR 0118H A TIMER1_ISR. . . . . . . . C ADDR 0118H A TIMER2_ISR. . . . . . . . C ADDR 0118H A UART0_ISR . . . . . . . . C ADDR 0118H A UART1_ISR . . . . . . . . C ADDR 0118H A USBCONTROL. . . . . . . . N NUMB 7FD6H A USBIEN. . . . . . . . . . N NUMB 7FAEH A USBIRQ. . . . . . . . . . N NUMB 7FABH A USBRESET_ISR. . . . . . . C ADDR 0120H A USB_ISR . . . . . . . . . C ADDR 0100H A WAIT100MSEC . . . . . . . C ADDR 0391H A WAIT1MSEC . . . . . . . . C ADDR 0394H A WAIT4D. . . . . . . . . . C ADDR 0247H A WAIT4DONE . . . . . . . . C ADDR 03AEH A WAIT4STOP . . . . . . . . C ADDR 03A2H A WAKEUP_ISR. . . . . . . . C ADDR 0139H A WITHINSAMEPAGE. . . . . . N NUMB 00B7H A REGISTER BANK(S) USED: 0 ASSEMBLY COMPLETE. 0 WARNING(S), 0 ERROR(S)