USB18.asm
Upload User: wang202020
Upload Date: 2021-02-07
Package Size: 182k
Code Size: 62k
Category:

SCM

Development Platform:

HTML/CSS

  1. ; USB18.ASM
  2. ; Put Address into source pointer
  3. mSetSourcePointer macro Address
  4. movlw low (Address)
  5. movwf pSrc
  6. movlw high (Address)
  7. movwf pSrc + 1
  8. endm
  9. ; Put Address into destination pointer
  10. mSetDestinationPointer macro Address
  11. movlw low (Address)
  12. movwf pDst
  13. movlw high (Address)
  14. movwf pDst + 1
  15. endm
  16. ; Get count from first location of ROM table pointed to by pSrc
  17. mGetRomTableCount macro
  18. movff pSrc, TBLPTRL ; Set source address
  19. movff pSrc + 1, TBLPTRH
  20. clrf TBLPTRU
  21.         tblrd   * ; Read count
  22. movff TABLAT, wCount
  23. clrf wCount + 1
  24. endm
  25. ; From usb9.c  line 70
  26. ;/******************************************************************************
  27. ; * Function:        void USBCheckStdRequest(void)
  28. ; *
  29. ; * PreCondition:    None
  30. ; *
  31. ; * Input:           None
  32. ; *
  33. ; * Output:          None
  34. ; *
  35. ; * Side Effects:    None
  36. ; *
  37. ; * Overview:        This routine checks the setup data packet to see if it
  38. ; *                  knows how to handle it
  39. ; *
  40. ; * Note:            None
  41. ; *****************************************************************************/
  42. USBCheckStdRequest
  43. movlb high 0x400 ; Point to proper bank
  44. movf SetupPkt, W ; RequestType = STANDARD?
  45. andlw 0x60 ; Mask to proper bits
  46. sublw (STANDARD) << 5
  47. bnz USBCheckStdRequestExit ; No
  48. movlw SET_ADR ; Handle request
  49. cpfseq SetupPkt + bRequest
  50. bra USBCheckStdRequest1
  51. movlw ADR_PENDING_STATE
  52. movwf usb_device_state
  53. bra USBStdSetSessionOwnerUSB9
  54. ; GET_DESCRIPTOR request?
  55. USBCheckStdRequest1
  56. movlw GET_DSC
  57. cpfseq SetupPkt + bRequest
  58. bra USBCheckStdRequest2
  59. bra USBStdGetDscHandler
  60. ; GET_CONFIGURATION request?
  61. USBCheckStdRequest2
  62. movlw GET_CFG
  63. cpfseq SetupPkt + bRequest
  64. bra USBCheckStdRequest3
  65. mSetSourcePointer usb_active_cfg
  66. movlw 1
  67. movwf wCount
  68. clrf wCount + 1
  69. bcf usb_stat, ctrl_trf_mem ; Indicate RAM
  70. bra USBStdSetSessionOwnerUSB9
  71. ; SET_CONFIGURATION request?
  72. USBCheckStdRequest3
  73. movlw SET_CFG
  74. cpfseq SetupPkt + bRequest
  75. bra USBCheckStdRequest4
  76. bra USBStdSetCfgHandler
  77. ; GET_STATUS request?
  78. USBCheckStdRequest4
  79. movlw GET_STATUS
  80. cpfseq SetupPkt + bRequest
  81. bra USBCheckStdRequest5
  82. bra USBStdGetStatusHandler
  83. ; CLEAR_FEATURE request?
  84. USBCheckStdRequest5
  85. movlw CLR_FEATURE
  86. cpfseq SetupPkt + bRequest
  87. bra USBCheckStdRequest6
  88. bra USBStdFeatureReqHandler
  89. ; SET_FEATURE request?
  90. USBCheckStdRequest6
  91. movlw SET_FEATURE
  92. cpfseq SetupPkt + bRequest
  93. bra USBCheckStdRequest7
  94. bra USBStdFeatureReqHandler
  95. ; GET_INTERFACE request?
  96. USBCheckStdRequest7
  97. movlw GET_INTF
  98. cpfseq SetupPkt + bRequest
  99. bra USBCheckStdRequest8
  100. mSetSourcePointer usb_alt_intf
  101. movf SetupPkt + bIntfID, W
  102. addwf pSrc, F
  103. movlw 1
  104. movwf wCount
  105. clrf wCount + 1
  106. bcf usb_stat, ctrl_trf_mem ; Indicate RAM
  107. bra USBStdSetSessionOwnerUSB9
  108. ; SET_INTERFACE request?
  109. USBCheckStdRequest8
  110. movlw SET_INTF
  111. cpfseq SetupPkt + bRequest
  112. return
  113. lfsr 2, usb_alt_intf
  114. movf SetupPkt + bIntfID, W
  115. movff SetupPkt + bAltID, PLUSW2
  116. ; Branch here after decoding one of the above USB standard requests.
  117. ; Assign a value to ctrl_trf_session_owner, to prevent stalling
  118. USBStdSetSessionOwnerUSB9
  119. movlw MUID_USB9
  120. movwf ctrl_trf_session_owner
  121. USBCheckStdRequestExit
  122. return
  123. ; From usb9.c  line 136
  124. ;/******************************************************************************
  125. ; * Function:        void USBStdGetDscHandler(void)
  126. ; *
  127. ; * PreCondition:    None
  128. ; *
  129. ; * Input:           None
  130. ; *
  131. ; * Output:          None
  132. ; *
  133. ; * Side Effects:    None
  134. ; *
  135. ; * Overview:        This routine handles the standard GET_DESCRIPTOR request.
  136. ; *                  It utilizes tables dynamically looks up descriptor size.
  137. ; *                  This routine should never have to be modified if the tables
  138. ; *                  in usbdsc.c are declared correctly.
  139. ; *
  140. ; * Note:            None
  141. ; *****************************************************************************/
  142. USBStdGetDscHandler
  143. ; movlb high 0x400 ; Point to proper bank
  144. movlw 0x80
  145. cpfseq SetupPkt + bmRequestType
  146. return
  147. movlw DSC_DEV
  148. cpfseq SetupPkt + bDscType
  149. bra USBStdGetDscHandler1
  150. mSetSourcePointer DeviceDescriptor
  151. mGetRomTableCount ; Set wCount
  152. bsf usb_stat, ctrl_trf_mem ; Indicate ROM
  153. bra USBStdSetSessionOwnerUSB9
  154. USBStdGetDscHandler1
  155. movlw DSC_CFG
  156. cpfseq SetupPkt + bDscType
  157. bra USBStdGetDscHandler2
  158. mSetSourcePointer Config1
  159. movlw low Config1Len ; Set wCount to total length
  160. movwf TBLPTRL
  161. movlw high Config1Len
  162. movwf TBLPTRH
  163. clrf TBLPTRU
  164. tblrd *+ ; Read count low
  165. movff TABLAT, wCount
  166. tblrd *+ ; Ignore RETLW opcode
  167. tblrd *+ ; Read count high
  168. movff TABLAT, wCount + 1
  169. bsf usb_stat, ctrl_trf_mem ; Indicate ROM
  170. bra USBStdSetSessionOwnerUSB9
  171. USBStdGetDscHandler2
  172. movlw DSC_STR
  173. cpfseq SetupPkt + bDscType
  174. return
  175. clrf TBLPTRU
  176. clrf TBLPTRH
  177. rlncf SetupPkt + bDscIndex, W ; Index * 2
  178. addlw low (USB_SD_Ptr) ; Add element offset to low address
  179. movwf TBLPTRL
  180. movlw high (USB_SD_Ptr)
  181. addwfc TBLPTRH, F
  182.         tblrd   *+ ; Get the data to TABLAT and move pointer forward
  183. movff TABLAT, pSrc ; Get low source address
  184.         tblrd   *
  185. movff TABLAT, pSrc + 1 ; Get high source address
  186. mGetRomTableCount ; Set wCount
  187. bsf usb_stat, ctrl_trf_mem ; Indicate ROM
  188. bra USBStdSetSessionOwnerUSB9
  189. ; From usb9.c  line 180
  190. ;/******************************************************************************
  191. ; * Function:        void USBStdSetCfgHandler(void)
  192. ; *
  193. ; * PreCondition:    None
  194. ; *
  195. ; * Input:           None
  196. ; *
  197. ; * Output:          None
  198. ; *
  199. ; * Side Effects:    None
  200. ; *
  201. ; * Overview:        This routine first disables all endpoints by clearing
  202. ; *                  UEP registers. It then configures (initializes) endpoints
  203. ; *                  specified in the modifiable section.
  204. ; *
  205. ; * Note:            None
  206. ; *****************************************************************************/
  207. USBStdSetCfgHandler
  208. ; movlb high 0x400 ; Point to proper bank
  209. movlw MUID_USB9
  210. movwf ctrl_trf_session_owner
  211. lfsr 2, UEP1 ; Reset all non-EP0 UEPn registers
  212. movlw 15
  213. USBStdSetCfgHandlerClearEPLoop
  214. clrf POSTINC2
  215. decfsz WREG, F
  216. bra USBStdSetCfgHandlerClearEPLoop
  217. lfsr 2, usb_alt_intf ; Clear usb_alt_intf array
  218. movlw MAX_NUM_INT
  219. USBStdSetCfgHandlerClearAltLoop
  220. clrf POSTINC2
  221. decfsz WREG, F
  222. bra USBStdSetCfgHandlerClearAltLoop
  223. movf SetupPkt + bCfgValue, W
  224. movwf usb_active_cfg
  225. bnz USBStdSetCfgHandler1
  226. movlw ADDRESS_STATE ; SetupPkt + bCfgValue = 0
  227. movwf usb_device_state
  228. return
  229. USBStdSetCfgHandler1
  230. movlw CONFIGURED_STATE
  231. movwf usb_device_state
  232. #ifdef USB_USE_HID
  233. rcall HIDInitEP
  234. #endif
  235. #ifdef USB_USE_CDC
  236. rcall CDCInitEP
  237. #endif
  238. return
  239. ; From usb9.c  line 224
  240. ;/******************************************************************************
  241. ; * Function:        void USBStdGetStatusHandler(void)
  242. ; *
  243. ; * PreCondition:    None
  244. ; *
  245. ; * Input:           None
  246. ; *
  247. ; * Output:          None
  248. ; *
  249. ; * Side Effects:    None
  250. ; *
  251. ; * Overview:        This routine handles the standard GET_STATUS request
  252. ; *
  253. ; * Note:            None
  254. ; *****************************************************************************/
  255. USBStdGetStatusHandler
  256. ; movlb high 0x400 ; Point to proper bank
  257. clrf CtrlTrfData ; Initialize content
  258. clrf CtrlTrfData + 1
  259. movf SetupPkt, W ; Recipient = RCPT_DEV?
  260. andlw 0x1f ; Mask to lower 5 bits
  261. sublw RCPT_DEV
  262. bnz USBStdGetStatusHandler1 ; No
  263. ;
  264. ; Recipient of this Setup packet was "Device": set bits to indicate power & remote wakeup
  265. ; Decoding of "Self-powered" & "Remote Wakeup"
  266. ; _byte0: bit0: Self-Powered Status [0] Bus-Powered [1] Self-Powered
  267. ;         bit1: RemoteWakeup        [0] Disabled    [1] Enabled
  268. ;
  269. #ifdef USB_SELF_POWER
  270. bsf CtrlTrfData, 0
  271. #endif
  272. btfsc usb_stat, RemoteWakeup
  273. bsf CtrlTrfData, 1
  274. bra USBStdGetStatusSetSessionOwner
  275. ;
  276. USBStdGetStatusHandler1
  277. movf SetupPkt, W ; Recipient = RCPT_INTF?
  278. andlw 0x1f ; Mask to lower 5 bits
  279. sublw RCPT_INTF
  280. bnz USBStdGetStatusHandler2 ; No
  281. ;
  282. ; Recipient of this Setup packet was "Interface": No data to update
  283. bra USBStdGetStatusSetSessionOwner
  284. ;
  285. USBStdGetStatusHandler2
  286. movf SetupPkt, W ; Recipient = RCPT_EP?
  287. andlw 0x1f ; Mask to lower 5 bits
  288. sublw RCPT_EP
  289. bnz USBStdGetStatusHandler3 ; No
  290. ;
  291. ; Recipient of this Setup packet was "Endpoint"
  292. rcall USBCalcEPAddress ; Put endpoint buffer address in FSR2
  293. movf INDF2, W
  294. andlw _BSTALL
  295. bz USBStdGetStatusSetSessionOwner
  296. bsf CtrlTrfData, 0
  297. USBStdGetStatusSetSessionOwner
  298. movlw MUID_USB9
  299. movwf ctrl_trf_session_owner
  300. USBStdGetStatusHandler3
  301. movlw MUID_USB9
  302. cpfseq ctrl_trf_session_owner
  303. return
  304. mSetSourcePointer CtrlTrfData
  305. movlw 2 ; Set count
  306. movwf wCount
  307. clrf wCount + 1
  308. bcf usb_stat, ctrl_trf_mem ; Indicate RAM
  309. return
  310. ; From usb9.c  line 281
  311. ;/******************************************************************************
  312. ; * Function:        void USBStdFeatureReqHandler(void)
  313. ; *
  314. ; * PreCondition:    None
  315. ; *
  316. ; * Input:           None
  317. ; *
  318. ; * Output:          None
  319. ; *
  320. ; * Side Effects:    None
  321. ; *
  322. ; * Overview:        This routine handles the standard SET & CLEAR FEATURES
  323. ; *                  requests
  324. ; *
  325. ; * Note:            None
  326. ; *****************************************************************************/
  327. USBStdFeatureReqHandler
  328. ; movlb high 0x400 ; Point to proper bank
  329. movlw DEVICE_REMOTE_WAKEUP ; If Feature = DEVICE_REMOTE_WAKEUP &
  330. cpfseq SetupPkt + bFeature
  331. bra USBStdFeatureReqHandler1
  332. movf SetupPkt, W ; Recipient = RCPT_DEV?
  333. andlw 0x1f ; Mask to lower 5 bits
  334. sublw RCPT_DEV
  335. bnz USBStdFeatureReqHandler1 ; No
  336. bsf usb_stat, RemoteWakeup ; Preset RemoteWakeup to 1
  337. movlw SET_FEATURE ; Request = SET_FEATURE?
  338. cpfseq SetupPkt + bRequest
  339. bcf usb_stat, RemoteWakeup ; No, RemoteWakeup = 0
  340. bra USBStdSetSessionOwnerUSB9
  341. USBStdFeatureReqHandler1
  342. movlw ENDPOINT_HALT ; If Feature = ENDPOINT_HALT &
  343. cpfseq SetupPkt + bFeature
  344. USBStdFeatureReqHandlerExit
  345. return
  346. movf SetupPkt, W ; Recepient = RCPT_EP &
  347. andlw 0x1f ; Mask to lower 5 bits
  348. sublw RCPT_EP
  349. bnz USBStdFeatureReqHandlerExit
  350. movf SetupPkt + bEPID, W ; EPNum != 0
  351. andlw 0x0f ; Mask to EPNum
  352. bz USBStdFeatureReqHandlerExit
  353. rcall USBCalcEPAddress ; Put endpoint buffer address in FSR2
  354. movlw SET_FEATURE ; Request = SET_FEATURE?
  355. cpfseq SetupPkt + bRequest
  356. bra USBStdFeatureReqHandler2 ; No
  357. movlw _USIE|_BSTALL
  358. movwf INDF2 ; Put in endpoint buffer
  359. bra USBStdSetSessionOwnerUSB9
  360. USBStdFeatureReqHandler2
  361. movlw _UCPU ; IN
  362. btfss SetupPkt + bEPID, EPDir ; EPDir = 1 (IN)?
  363. movlw _USIE|_DAT0|_DTSEN ; No - OUT
  364. movwf INDF2 ; Put in endpoint buffer
  365. bra USBStdSetSessionOwnerUSB9
  366. ; Put endpoint buffer address in FSR2 (ep0Bo+(EPNum*8)+(EPDir*4))
  367. USBCalcEPAddress
  368. lfsr 2, ep0Bo ; Point FSR2 to beginning of buffer area
  369. rlncf SetupPkt + bEPID, W ; Move endpoint direction to C
  370. rlcf SetupPkt + bEPID, W ; Endpoint number * 8 (roll in ep direction)
  371. rlncf WREG, F
  372. rlncf WREG, F
  373. addwf FSR2L, F ; Add to FSR2 (can't overflow to FSR2H)
  374. return
  375. ; From usbctrltrf.c line 78
  376. ;/******************************************************************************
  377. ; * Function:        void USBCtrlEPService(void)
  378. ; *
  379. ; * PreCondition:    USTAT is loaded with a valid endpoint address.
  380. ; *
  381. ; * Input:           None
  382. ; *
  383. ; * Output:          None
  384. ; *
  385. ; * Side Effects:    None
  386. ; *
  387. ; * Overview:        USBCtrlEPService checks for three transaction types that
  388. ; *                  it knows how to service and services them:
  389. ; *                  1. EP0 SETUP
  390. ; *                  2. EP0 OUT
  391. ; *                  3. EP0 IN
  392. ; *                  It ignores all other types (i.e. EP1, EP2, etc.)
  393. ; *
  394. ; * Note:            None
  395. ; *****************************************************************************/
  396. USBCtrlEPService
  397. ; movlb high 0x400 ; Point to proper bank
  398. movlw EP00_OUT
  399. cpfseq USTAT
  400. bra USBCtrlEPService1
  401. movf ep0Bo + Stat, W
  402. andlw 0x3c ; Mask to PID
  403. sublw (SETUP_TOKEN) << 2
  404. bz USBCtrlTrfSetupHandler
  405. bra USBCtrlTrfOutHandler
  406. USBCtrlEPService1
  407. movlw EP00_IN
  408. cpfseq USTAT
  409. return
  410. bra USBCtrlTrfInHandler
  411. ; From usbctrltrf.c line 133
  412. ;/******************************************************************************
  413. ; * Function:        void USBCtrlTrfSetupHandler(void)
  414. ; *
  415. ; * PreCondition:    SetupPkt buffer is loaded with valid USB Setup Data
  416. ; *
  417. ; * Input:           None
  418. ; *
  419. ; * Output:          None
  420. ; *
  421. ; * Side Effects:    None
  422. ; *
  423. ; * Overview:        This routine is a task dispatcher and has 3 stages.
  424. ; *                  1. It initializes the control transfer state machine.
  425. ; *                  2. It calls on each of the module that may know how to
  426. ; *                     service the Setup Request from the host.
  427. ; *                     Module Example: USB9, HID, CDC, MSD, ...
  428. ; *                     As new classes are added, ClassReqHandler table in
  429. ; *                     usbdsc.c should be updated to call all available
  430. ; *                     class handlers.
  431. ; *                  3. Once each of the modules has had a chance to check if
  432. ; *                     it is responsible for servicing the request, stage 3
  433. ; *                     then checks direction of the transfer to determine how
  434. ; *                     to prepare EP0 for the control transfer.
  435. ; *                     Refer to USBCtrlEPServiceComplete() for more details.
  436. ; *
  437. ; * Note:            Microchip USB Firmware has three different states for
  438. ; *                  the control transfer state machine:
  439. ; *                  1. WAIT_SETUP
  440. ; *                  2. CTRL_TRF_TX
  441. ; *                  3. CTRL_TRF_RX
  442. ; *                  Refer to firmware manual to find out how one state
  443. ; *                  is transitioned to another.
  444. ; *
  445. ; *                  A Control Transfer is composed of many USB transactions.
  446. ; *                  When transferring data over multiple transactions,
  447. ; *                  it is important to keep track of data source, data
  448. ; *                  destination, and data count. These three parameters are
  449. ; *                  stored in pSrc,pDst, and wCount. A flag is used to
  450. ; *                  note if the data source is from ROM or RAM.
  451. ; *
  452. ; *****************************************************************************/
  453. USBCtrlTrfSetupHandler
  454. ; movlb high 0x400 ; Point to proper bank
  455. movlw WAIT_SETUP
  456. movwf ctrl_trf_state
  457. movlw MUID_NULL ; Set owner to NULL
  458. movwf ctrl_trf_session_owner
  459. clrf wCount
  460. clrf wCount + 1
  461. rcall USBCheckStdRequest
  462. movlw MUID_NULL
  463. cpfseq ctrl_trf_session_owner
  464. bra USBCtrlEPServiceComplete
  465. #ifdef USB_USE_HID
  466. rcall USBCheckHIDRequest
  467. #endif ; USB_USE_HID
  468. #ifdef USB_USE_CDC
  469. rcall USBCheckCDCRequest
  470. #endif ; USB_USE_CDC
  471. bra USBCtrlEPServiceComplete
  472. ; From usbctrltrf.c line 176
  473. ;/******************************************************************************
  474. ; * Function:        void USBCtrlTrfOutHandler(void)
  475. ; *
  476. ; * PreCondition:    None
  477. ; *
  478. ; * Input:           None
  479. ; *
  480. ; * Output:          None
  481. ; *
  482. ; * Side Effects:    None
  483. ; *
  484. ; * Overview:        This routine handles an OUT transaction according to
  485. ; *                  which control transfer state is currently active.
  486. ; *
  487. ; * Note:            Note that if the the control transfer was from
  488. ; *                  host to device, the session owner should be notified
  489. ; *                  at the end of each OUT transaction to service the
  490. ; *                  received data.
  491. ; *
  492. ; *****************************************************************************/
  493. USBCtrlTrfOutHandler
  494. ; movlb high 0x400 ; Point to proper bank
  495. movlw CTRL_TRF_RX
  496. cpfseq ctrl_trf_state
  497. bra USBPrepareForNextSetupTrf
  498. rcall USBCtrlTrfRxService
  499. movlw _USIE|_DAT1|_DTSEN
  500. btfsc ep0Bo + Stat, DTS
  501. movlw _USIE|_DAT0|_DTSEN
  502. movwf ep0Bo + Stat
  503. return
  504. ; From usbctrltrf.c line 221
  505. ;/******************************************************************************
  506. ; * Function:        void USBCtrlTrfInHandler(void)
  507. ; *
  508. ; * PreCondition:    None
  509. ; *
  510. ; * Input:           None
  511. ; *
  512. ; * Output:          None
  513. ; *
  514. ; * Side Effects:    None
  515. ; *
  516. ; * Overview:        This routine handles an IN transaction according to
  517. ; *                  which control transfer state is currently active.
  518. ; *
  519. ; *
  520. ; * Note:            A Set Address Request must not change the acutal address
  521. ; *                  of the device until the completion of the control
  522. ; *                  transfer. The end of the control transfer for Set Address
  523. ; *                  Request is an IN transaction. Therefore it is necessary
  524. ; *                  to service this unique situation when the condition is
  525. ; *                  right. Macro mUSBCheckAdrPendingState is defined in
  526. ; *                  usb9.h and its function is to specifically service this
  527. ; *                  event.
  528. ; *****************************************************************************/
  529. USBCtrlTrfInHandler
  530. ; movlb high 0x400 ; Point to proper bank
  531. movlw ADR_PENDING_STATE ; Must check if in ADR_PENDING_STATE
  532. cpfseq usb_device_state
  533. bra USBCtrlTrfInHandler1
  534. movf SetupPkt + bDevADR, W
  535. movwf UADDR
  536. movlw ADDRESS_STATE ; If UADDR > 0
  537. btfsc STATUS, Z
  538. movlw DEFAULT_STATE
  539. movwf usb_device_state
  540. USBCtrlTrfInHandler1
  541. movlw CTRL_TRF_TX
  542. cpfseq ctrl_trf_state
  543. bra USBPrepareForNextSetupTrf
  544. rcall USBCtrlTrfTxService
  545. movlw _USIE|_DAT1|_DTSEN
  546. btfsc ep0Bi + Stat, DTS
  547. movlw _USIE|_DAT0|_DTSEN
  548. movwf ep0Bi + Stat
  549. return
  550. ; From usbctrltrf.c line 260
  551. ;/******************************************************************************
  552. ; * Function:        void USBCtrlTrfTxService(void)
  553. ; *
  554. ; * PreCondition:    pSrc, wCount, and usb_stat.ctrl_trf_mem are setup properly.
  555. ; *
  556. ; * Input:           None
  557. ; *
  558. ; * Output:          None
  559. ; *
  560. ; * Side Effects:    None
  561. ; *
  562. ; * Overview:        This routine should be called from only two places.
  563. ; *                  One from USBCtrlEPServiceComplete() and one from
  564. ; *                  USBCtrlTrfInHandler(). It takes care of managing a
  565. ; *                  transfer over multiple USB transactions.
  566. ; *
  567. ; * Note:            Copies one packet-ful of data pSrc (either ROM or RAM) to
  568. ; *                  EP0 IN buffer. It then updates pSrc to be ready for next
  569. ; *                  piece.
  570. ; *                  This routine works with isochronous endpoint larger than
  571. ; *                  256 bytes and is shown here as an example of how to deal
  572. ; *                  with BC9 and BC8. In reality, a control endpoint can never
  573. ; *                  be larger than 64 bytes.
  574. ; *****************************************************************************/
  575. USBCtrlTrfTxService
  576. ; movlb high 0x400 ; Point to proper bank
  577. movf wCount, W ; Preset wCount bytes to send
  578. movwf usb_temp
  579. movf wCount + 1, W
  580. movwf usb_temp + 1
  581. sublw high EP0_BUFF_SIZE ; Make sure count does not exceed maximium length
  582. bnc USBCtrlTrfTxServiceCopy
  583. bnz USBCtrlTrfTxServiceSub
  584. movf wCount, W
  585. sublw low EP0_BUFF_SIZE
  586. bc USBCtrlTrfTxServiceSub
  587. USBCtrlTrfTxServiceCopy
  588. movlw low EP0_BUFF_SIZE ; Send buffer full of bytes
  589. movwf usb_temp
  590. movlw high EP0_BUFF_SIZE
  591. movwf usb_temp + 1
  592. USBCtrlTrfTxServiceSub
  593. movf usb_temp, W ; Subtract actual bytes to be sent from the buffer
  594. movwf ep0Bi + Cnt ; Save low number of bytes to send while we're here
  595. subwf wCount, F
  596. movf usb_temp + 1, W
  597. subwfb wCount + 1, F
  598. movf ep0Bi + Stat, W ; Get full Stat byte
  599. andlw 0xfc ; Clear bottom bits
  600. iorwf usb_temp + 1, W ; Put in high bits of bytes to send
  601. movwf ep0Bi + Stat ; Save it out
  602. lfsr 2, CtrlTrfData ; Set destination pointer
  603. movf usb_temp + 1, W ; Check high byte for 0
  604. bnz USBCtrlTrfTxServiceRomRam ; High byte not 0, must have something to do
  605. movf usb_temp, W ; Check low byte for 0
  606. bz USBCtrlTrfTxServiceExit ; If both 0 then nothing to send this time
  607. USBCtrlTrfTxServiceRomRam
  608. btfss usb_stat, ctrl_trf_mem ; ROM or RAM?
  609. bra USBCtrlTrfTxServiceRam ; RAM
  610. movff pSrc, TBLPTRL ; Move source pointer to TBLPTR
  611. movff pSrc + 1, TBLPTRH
  612. clrf TBLPTRU
  613. USBCtrlTrfTxServiceRomLoop
  614. tblrd *+
  615. movff TABLAT, POSTINC2 ; Copy one buffer to the other
  616. tblrd *+ ; Skip high location
  617. decf usb_temp, F ; Count down number of bytes
  618. bnz USBCtrlTrfTxServiceRomLoop
  619. decf usb_temp + 1, F
  620. bc USBCtrlTrfTxServiceRomLoop
  621. movff TBLPTRL, pSrc ; Update source pointer
  622. movff TBLPTRH, pSrc + 1
  623. return
  624. USBCtrlTrfTxServiceRam
  625. movff pSrc, FSR1L ; Move source pointer to FSR1
  626. movff pSrc + 1, FSR1H
  627. USBCtrlTrfTxServiceRamLoop
  628. movff POSTINC1, POSTINC2 ; Copy one buffer to the other
  629. decf usb_temp, F ; Count down number of bytes
  630. bnz USBCtrlTrfTxServiceRamLoop
  631. decf usb_temp + 1, F
  632. bc USBCtrlTrfTxServiceRamLoop
  633. movff FSR1L, pSrc ; Update source pointer
  634. movff FSR1H, pSrc + 1
  635. USBCtrlTrfTxServiceExit
  636. return
  637. ; From usbctrltrf.c line 330
  638. ;/******************************************************************************
  639. ; * Function:        void USBCtrlTrfRxService(void)
  640. ; *
  641. ; * PreCondition:    pDst and wCount are setup properly.
  642. ; *                  pSrc is always &CtrlTrfData
  643. ; *                  usb_stat.ctrl_trf_mem is always _RAM.
  644. ; *                  wCount should be set to 0 at the start of each control
  645. ; *                  transfer.
  646. ; *
  647. ; * Input:           None
  648. ; *
  649. ; * Output:          None
  650. ; *
  651. ; * Side Effects:    None
  652. ; *
  653. ; * Overview:        Transfers bytes received, at EP0 OUT buffer CtrlTrfData,
  654. ; *                  to user's buffer pointed by pDst.
  655. ; *                  This routine only knows how to handle raw byte data.
  656. ; *                  HIDmaker handles transferring and unpacking by a callback
  657. ; *                  function in the generated main program, called from here.
  658. ; *
  659. ; * Note:            None
  660. ; *****************************************************************************/
  661. USBCtrlTrfRxService
  662. ; movlb high 0x400 ; Point to proper bank
  663. movf ep0Bo + Cnt, W ; Get low number of bytes to read
  664. movwf usb_temp ; usb_temp & usb_temp + 1 are bytes to read
  665. addwf wCount, F ; Accumulate total number of bytes read
  666. movf ep0Bo + Stat, W ; Get high bits to read
  667. andlw 0x03 ; Mask to the count
  668. movwf usb_temp + 1 ; Save to high byte of bytes to read
  669. addwfc wCount + 1, F ; Add overflow from low byte (C) and high byte to total number
  670. lfsr 1, CtrlTrfData ; Point FSR1 to source
  671. movff pDst, FSR2L ; Move destination pointer to FSR2
  672. movff pDst + 1, FSR2H
  673. movf usb_temp + 1, W ; Check high byte for 0
  674. bnz USBCtrlTrfRxServiceLoop ; High byte not 0, must have something to do
  675. movf usb_temp, W ; Check low byte for 0
  676. bz USBCtrlTrfRxServiceExit ; If both 0 then nothing to send this time
  677. USBCtrlTrfRxServiceLoop
  678. movff POSTINC1, POSTINC2 ; Copy one buffer to the other
  679. decf usb_temp, F ; Count down number of bytes
  680. bnz USBCtrlTrfRxServiceLoop
  681. decf usb_temp + 1, F
  682. bc USBCtrlTrfRxServiceLoop
  683. movff FSR2L, pDst ; Update destination pointer
  684. movff FSR2H, pDst + 1
  685. USBCtrlTrfRxServiceExit
  686. return
  687. ; From usbctrltrf.c line 382
  688. ;/******************************************************************************
  689. ; * Function:        void USBCtrlEPServiceComplete(void)
  690. ; *
  691. ; * PreCondition:    None
  692. ; *
  693. ; * Input:           None
  694. ; *
  695. ; * Output:          None
  696. ; *
  697. ; * Side Effects:    None
  698. ; *
  699. ; * Overview:        This routine wrap up the ramaining tasks in servicing
  700. ; *                  a Setup Request. Its main task is to set the endpoint
  701. ; *                  controls appropriately for a given situation. See code
  702. ; *                  below.
  703. ; *                  There are three main scenarios:
  704. ; *                  a) There was no handler for the Request, in this case
  705. ; *                     a STALL should be sent out.
  706. ; *                  b) The host has requested a read control transfer,
  707. ; *                     endpoints are required to be setup in a specific way.
  708. ; *                  c) The host has requested a write control transfer, or
  709. ; *                     a control data stage is not required, endpoints are
  710. ; *                     required to be setup in a specific way.
  711. ; *
  712. ; *                  Packet processing is resumed by clearing PKTDIS bit.
  713. ; *
  714. ; * Note:            None
  715. ; *****************************************************************************/
  716. USBCtrlEPServiceComplete
  717. ; movlb high 0x400 ; Point to proper bank
  718. movlw MUID_NULL
  719. cpfseq ctrl_trf_session_owner
  720. bra USBCtrlEPServiceComplete1
  721. ;
  722. ; No handlers claimed ownership of this Setup packet.
  723. ; If no one knows how to service this request then stall.
  724. ; Must also prepare EP0 to receive the next SETUP transaction.
  725. movlw EP0_BUFF_SIZE
  726. movwf ep0Bo + Cnt
  727. movlw low SetupPkt
  728. movwf ep0Bo + ADRL
  729. movlw high SetupPkt
  730. movwf ep0Bo + ADRH
  731. movlw _USIE|_BSTALL
  732. movwf ep0Bo + Stat
  733. ; movlw _USIE|_BSTALL
  734. movwf ep0Bi + Stat
  735. bra USBCtrlEPServiceCompleteExit
  736. ;
  737. ; A module has claimed ownership of the control transfer session.
  738. USBCtrlEPServiceComplete1
  739. btfss SetupPkt, DataDir
  740. bra USBCtrlEPServiceComplete2
  741. movf wCount + 1, W ; Make sure count does not exceed max length requested by Host
  742. subwf SetupPkt + wLength + 1, W
  743. bnc USBCtrlEPServiceCompleteCopy
  744. bnz USBCtrlEPServiceComplete11
  745. movf wCount, W
  746. subwf SetupPkt + wLength, W
  747. bc USBCtrlEPServiceComplete11
  748. USBCtrlEPServiceCompleteCopy
  749. movff SetupPkt + wLength, wCount ; Set count to maximum
  750. movff SetupPkt + wLength + 1, wCount + 1
  751. ;
  752. ; Setup packet's data direction is "Device to Host"
  753. USBCtrlEPServiceComplete11
  754. rcall USBCtrlTrfTxService    ; Actually copy the data to EP0 IN buffer
  755. movlw CTRL_TRF_TX
  756. movwf ctrl_trf_state
  757. ; Control Read:
  758. ; <SETUP[0]><IN[1]><IN[0]>...<OUT[1]> | <SETUP[0]>
  759. ; 1. Prepare OUT EP to respond to early termination
  760. ;
  761. ; NOTE:
  762. ; If something went wrong during the control transfer,
  763. ; the last status stage may not be sent by the host.
  764. ; When this happens, two different things could happen
  765. ; depending on the host.
  766. ; a) The host could send out a RESET.
  767. ; b) The host could send out a new SETUP transaction
  768. ;    without sending a RESET first.
  769. ; To properly handle case (b), the OUT EP must be setup
  770. ; to receive either a zero length OUT transaction, or a
  771. ; new SETUP transaction.
  772. ;
  773. ; Since the SETUP transaction requires the DTS bit to be
  774. ; DAT0 while the zero length OUT status requires the DTS
  775. ; bit to be DAT1, the DTS bit check by the hardware should
  776. ; be disabled. This way the SIE could accept either of
  777. ; the two transactions.
  778. ;
  779. ; Furthermore, the Cnt byte should be set to prepare for
  780. ; the SETUP data (8-byte or more), and the buffer address
  781. ; should be pointed to SetupPkt.
  782. movlw EP0_BUFF_SIZE
  783. movwf ep0Bo + Cnt
  784. movlw low SetupPkt
  785. movwf ep0Bo + ADRL
  786. movlw high SetupPkt
  787. movwf ep0Bo + ADRH
  788. movlw _USIE ; Note: DTSEN is 0!
  789. movwf ep0Bo + Stat
  790. ; 2. Prepare IN EP to transfer data, Cnt should have
  791. ;    been initialized by responsible request owner.
  792. movlw low CtrlTrfData
  793. movwf ep0Bi + ADRL
  794. movlw high CtrlTrfData
  795. movwf ep0Bi + ADRH
  796. movlw _USIE|_DAT1|_DTSEN
  797. movwf ep0Bi + Stat
  798. bra USBCtrlEPServiceCompleteExit
  799. ;
  800. ; Setup packet's data direction is "Host to Device"
  801. USBCtrlEPServiceComplete2
  802. movlw CTRL_TRF_RX
  803. movwf ctrl_trf_state
  804. ; Control Write:
  805. ; <SETUP[0]><OUT[1]><OUT[0]>...<IN[1]> | <SETUP[0]>
  806. ;
  807. ; 1. Prepare IN EP to respond to early termination
  808. ;
  809. ;    This is the same as a Zero Length Packet Response
  810. ;    for control transfer without a data stage
  811. clrf ep0Bi + Cnt
  812. movlw _USIE|_DAT1|_DTSEN
  813. movwf ep0Bi + Stat
  814. ; 2. Prepare OUT EP to receive data.
  815. movlw EP0_BUFF_SIZE
  816. movwf ep0Bo + Cnt
  817. movlw low CtrlTrfData
  818. movwf ep0Bo + ADRL
  819. movlw high CtrlTrfData
  820. movwf ep0Bo + ADRH
  821. movlw _USIE|_DAT1|_DTSEN
  822. movwf ep0Bo + Stat
  823. ;
  824. USBCtrlEPServiceCompleteExit
  825. ; PKTDIS bit is set when a Setup Transaction is received.
  826. ; Clear to resume packet processing.
  827. bcf UCON, PKTDIS
  828. return
  829. ; From usbctrltrf.c line 490
  830. ;/******************************************************************************
  831. ; * Function:        void USBPrepareForNextSetupTrf(void)
  832. ; *
  833. ; * PreCondition:    None
  834. ; *
  835. ; * Input:           None
  836. ; *
  837. ; * Output:          None
  838. ; *
  839. ; * Side Effects:    None
  840. ; *
  841. ; * Overview:        The routine forces EP0 OUT to be ready for a new Setup
  842. ; *                  transaction, and forces EP0 IN to be owned by CPU.
  843. ; *
  844. ; * Note:            None
  845. ; *****************************************************************************/
  846. USBPrepareForNextSetupTrf
  847. ; movlb high 0x400 ; Point to proper bank
  848. movlw WAIT_SETUP
  849. movwf ctrl_trf_state
  850. movlw EP0_BUFF_SIZE
  851. movwf ep0Bo + Cnt
  852. movlw low SetupPkt
  853. movwf ep0Bo + ADRL
  854. movlw high SetupPkt
  855. movwf ep0Bo + ADRH
  856. movlw _USIE|_DAT0|_DTSEN ; EP0 buff dsc init
  857. movwf ep0Bo + Stat
  858. movlw _UCPU ; EP0 IN buffer initialization
  859. movwf ep0Bi + Stat
  860. return
  861. ; From usbdrv.c line ???
  862. ;/******************************************************************************
  863. ; * Function:        void InitializeUSBDriver(void)
  864. ; *
  865. ; * PreCondition:    None
  866. ; *
  867. ; * Input:           None
  868. ; *
  869. ; * Output:          None
  870. ; *
  871. ; * Side Effects:    None
  872. ; *
  873. ; * Overview:        This routine initializes variables used by the USB library
  874. ; *                  routines.
  875. ; *
  876. ; * Note:            None
  877. ; *****************************************************************************/
  878. InitializeUSBDriver
  879. movlb high 0x400 ; Point to proper bank
  880. movlw UCFG_VAL
  881. movwf UCFG
  882. movlw DETACHED_STATE
  883. movwf usb_device_state
  884. clrf usb_stat
  885. clrf usb_active_cfg
  886. #ifdef USB_USE_HID
  887. rcall HIDInitEP
  888. #endif
  889. #ifdef USB_USE_CDC
  890. rcall CDCInitEP
  891. #endif
  892. return
  893. ; From usbdrv.c line 76
  894. ;/******************************************************************************
  895. ; * Function:        void USBCheckBusStatus(void)
  896. ; *
  897. ; * PreCondition:    None
  898. ; *
  899. ; * Input:           None
  900. ; *
  901. ; * Output:          None
  902. ; *
  903. ; * Side Effects:    None
  904. ; *
  905. ; * Overview:        This routine enables/disables the USB module by monitoring
  906. ; *                  the USB power signal.
  907. ; *
  908. ; * Note:            None
  909. ; *****************************************************************************/
  910. USBCheckBusStatus
  911. movlb high 0x400 ; Point to proper bank
  912. ; Bus Attachment & Detachment Detection
  913. ; usb_bus_sense is an i/o pin defined in io_cfg.h
  914. #ifdef USE_USB_BUS_SENSE_IO
  915. btfss usb_bus_sense ; Is USB bus attached?
  916. bra USBCheckBusStatusDetached ; No
  917. #endif
  918. btfss UCON, USBEN ; Is the module off?
  919. rcall USBModuleEnable ; Is off, enable it
  920. #ifdef USE_USB_BUS_SENSE_IO
  921. bra USBCheckBusStatus1
  922. USBCheckBusStatusDetached
  923. btfsc UCON, USBEN ; Is the module on?
  924. rcall USBModuleDisable ; Is on, disable it
  925. #endif
  926. ;
  927. ; After enabling the USB module, it takes some time for the voltage
  928. ; on the D+ or D- line to rise high enough to get out of the SE0 condition.
  929. ; The USB Reset interrupt should not be unmasked until the SE0 condition is
  930. ; cleared. This helps preventing the firmware from misinterpreting this
  931. ; unique event as a USB bus reset from the USB host.
  932. USBCheckBusStatus1
  933. movlw ATTACHED_STATE
  934. cpfseq usb_device_state
  935. return
  936. btfsc UCON, SE0
  937. return
  938. clrf UIR ; Clear all USB interrupts
  939. clrf UIE ; Mask all USB interrupts
  940. bsf UIE, URSTIE ; Unmask RESET interrupt
  941. bsf UIE, IDLEIE ; Unmask IDLE interrupt
  942. movlw POWERED_STATE
  943. movwf usb_device_state
  944. return
  945. ; From usbdrv.c line 135
  946. USBModuleEnable
  947. ; movlb high 0x400 ; Point to proper bank
  948. clrf UCON
  949. clrf UIE ; Mask all USB interrupts
  950. bsf UCON, USBEN ; Enable module & attach to bus
  951. movlw ATTACHED_STATE
  952. movwf usb_device_state
  953. return
  954. ; From usbdrv.c line 192
  955. USBSoftDetach
  956. ; From usbdrv.c line 161
  957. USBModuleDisable
  958. movlb high 0x400 ; Point to proper bank
  959. clrf UCON ; Disable module & detach from bus
  960. clrf UIE ; Mask all USB interrupts
  961. movlw DETACHED_STATE
  962. movwf usb_device_state
  963. return
  964. ; From usbdrv.c line 215
  965. ;/******************************************************************************
  966. ; * Function:        void USBDriverService(void)
  967. ; *
  968. ; * PreCondition:    None
  969. ; *
  970. ; * Input:           None
  971. ; *
  972. ; * Output:          None
  973. ; *
  974. ; * Side Effects:    None
  975. ; *
  976. ; * Overview:        This routine is the heart of this firmware. It manages
  977. ; *                  all USB interrupts.
  978. ; *
  979. ; * Note:            Device state transitions through the following stages:
  980. ; *                  DETACHED -> ATTACHED -> POWERED -> DEFAULT ->
  981. ; *                  ADDRESS_PENDING -> ADDRESSED -> CONFIGURED -> READY
  982. ; *****************************************************************************/
  983. USBDriverService
  984. movlb high 0x400 ; Point to proper bank
  985. movlw DETACHED_STATE
  986. subwf usb_device_state, W
  987. bz USBDriverServiceExit ; Pointless to continue servicing
  988. ; if USB cable is not even attached.
  989. ;
  990. ; Task A: Service USB Activity Interrupt
  991. btfss UIR, ACTVIF
  992. bra USBDriverService1
  993. btfsc UIE, ACTVIE
  994. rcall USBWakeFromSuspend
  995. ;
  996. USBDriverService1
  997. btfsc UCON, SUSPND ; Are we suspended?
  998. return ; Pointless to continue servicing if the device is in suspend mode.
  999. ;
  1000. ; Task B: Service USB Bus Reset Interrupt.
  1001. ; When bus reset is received during suspend, ACTVIF will be set first,
  1002. ; once the UCONbits.SUSPND is clear, then the URSTIF bit will be asserted.
  1003. ; This is why URSTIF is checked after ACTVIF.
  1004. ;
  1005. ; The USB reset flag is masked when the USB state is in
  1006. ; DETACHED_STATE or ATTACHED_STATE, and therefore cannot
  1007. ; cause a USB reset event during these two states.
  1008. btfss UIR, URSTIF        ; USB Bus Reset Interrupt?
  1009. bra USBDriverService2
  1010. btfsc UIE, URSTIE
  1011. rcall USBProtocolResetHandler
  1012. ;
  1013. ; Task C: Check & service other USB interrupts
  1014. USBDriverService2
  1015. btfss UIR, IDLEIF
  1016. bra USBDriverService3
  1017. btfsc UIE, IDLEIE
  1018. rcall USBSuspend
  1019. USBDriverService3
  1020. btfss UIR, SOFIF
  1021. bra USBDriverService4
  1022. btfsc UIE, SOFIE
  1023. rcall USB_SOF_Handler
  1024. USBDriverService4
  1025. btfss UIR, STALLIF
  1026. bra USBDriverService5
  1027. btfsc UIE, STALLIE
  1028. rcall USBStallHandler
  1029. USBDriverService5
  1030. btfss UIR, UERRIF
  1031. bra USBDriverService6
  1032. btfsc UIE, UERRIE
  1033. rcall USBErrorHandler
  1034. ;
  1035. ; Pointless to continue servicing if the host has not sent a bus reset.
  1036. ; Once bus reset is received, the device transitions into the DEFAULT
  1037. ;     * state and is ready for communication.
  1038. USBDriverService6
  1039. movlw DEFAULT_STATE
  1040. subwf usb_device_state, W
  1041. bnc USBDriverServiceExit
  1042. ;
  1043. ; Task D: Servicing USB Transaction Complete Interrupt
  1044. btfss UIR, TRNIF
  1045. bra USBDriverServiceExit
  1046. btfss UIE, TRNIE
  1047. bra USBDriverServiceExit
  1048. ;
  1049. ; USBCtrlEPService only services transactions over EP0.
  1050. ; It ignores all other EP transactions.
  1051. rcall USBCtrlEPService
  1052. ; Other EPs can be serviced later by responsible device class firmware.
  1053. ; Each device driver knows when an OUT or IN transaction is ready by
  1054. ; checking the buffer ownership bit.
  1055. ; An OUT EP should always be owned by SIE until the data is ready.
  1056. ; An IN EP should always be owned by CPU until the data is ready.
  1057. ;
  1058. ; Because of this logic, it is not necessary to save the USTAT value
  1059. ; of non-EP0 transactions.
  1060. bcf UIR, TRNIF
  1061. USBDriverServiceExit
  1062. return
  1063. ; From usbdrv.c line 301
  1064. ;/******************************************************************************
  1065. ; * Function:        void USBSuspend(void)
  1066. ; *
  1067. ; * PreCondition:    None
  1068. ; *
  1069. ; * Input:           None
  1070. ; *
  1071. ; * Output:          None
  1072. ; *
  1073. ; * Side Effects:    None
  1074. ; *
  1075. ; * Overview:
  1076. ; *
  1077. ; * Note:            None
  1078. ; *****************************************************************************/
  1079. USBSuspend
  1080. ; NOTE: Do not clear UIRbits.ACTVIF here!
  1081. ; Reason:
  1082. ; ACTVIF is only generated once an IDLEIF has been generated.
  1083. ; This is a 1:1 ratio interrupt generation.
  1084. ; For every IDLEIF, there will be only one ACTVIF regardless of
  1085. ; the number of subsequent bus transitions.
  1086. ;
  1087. ; If the ACTIF is cleared here, a problem could occur when:
  1088. ; [       IDLE       ][bus activity ->
  1089. ; <--- 3 ms ----->     ^
  1090. ;                ^     ACTVIF=1
  1091. ;                IDLEIF=1
  1092. ;  #           #           #           #   (#=Program polling flags)
  1093. ;                          ^
  1094. ;                          This polling loop will see both
  1095. ;                          IDLEIF=1 and ACTVIF=1.
  1096. ;                          However, the program services IDLEIF first
  1097. ;                          because ACTIVIE=0.
  1098. ;                          If this routine clears the only ACTIVIF,
  1099. ;                          then it can never get out of the suspend
  1100. ;                          mode.
  1101. bsf UIE, ACTVIE ; Enable bus activity interrupt
  1102. bcf UIR, IDLEIF
  1103. bsf UCON, SUSPND ; Put USB module in power conserve
  1104. ; At this point the PIC can go into sleep,idle, or
  1105. ; switch to a slower clock, etc.
  1106. return
  1107. ; From usbdrv.c line 353
  1108. ;/******************************************************************************
  1109. ; * Function:        void USBWakeFromSuspend(void)
  1110. ; *
  1111. ; * PreCondition:    None
  1112. ; *
  1113. ; * Input:           None
  1114. ; *
  1115. ; * Output:          None
  1116. ; *
  1117. ; * Side Effects:    None
  1118. ; *
  1119. ; * Overview:
  1120. ; *
  1121. ; * Note:            None
  1122. ; *****************************************************************************/
  1123. USBWakeFromSuspend
  1124. ; If using clock switching, this is the place to restore the
  1125. ; original clock frequency.
  1126. bcf UCON, SUSPND
  1127. bcf UIE, ACTVIE
  1128. bcf UIR, ACTVIF
  1129. return
  1130. ; From usbdrv.c line 402
  1131. ;/******************************************************************************
  1132. ; * Function:        void USBRemoteWakeup(void)
  1133. ; *
  1134. ; * PreCondition:    None
  1135. ; *
  1136. ; * Input:           None
  1137. ; *
  1138. ; * Output:          None
  1139. ; *
  1140. ; * Side Effects:    None
  1141. ; *
  1142. ; * Overview:        This function should be called by user when the device
  1143. ; *                  is waken up by an external stimulus other than ACTIVIF.
  1144. ; *                  Please read the note below to understand the limitations.
  1145. ; *
  1146. ; * Note:            The modifiable section in this routine should be changed
  1147. ; *                  to meet the application needs. Current implementation
  1148. ; *                  temporary blocks other functions from executing for a
  1149. ; *                  period of 1-13 ms depending on the core frequency.
  1150. ; *
  1151. ; *                  According to USB 2.0 specification section 7.1.7.7,
  1152. ; *                  "The remote wakeup device must hold the resume signaling
  1153. ; *                  for at lest 1 ms but for no more than 15 ms."
  1154. ; *                  The idea here is to use a delay counter loop, using a
  1155. ; *                  common value that would work over a wide range of core
  1156. ; *                  frequencies.
  1157. ; *                  That value selected is 1800. See table below:
  1158. ; *                  ==========================================================
  1159. ; *                  Core Freq(MHz)      MIP         RESUME Signal Period (ms)
  1160. ; *                  ==========================================================
  1161. ; *                      48              12          1.05
  1162. ; *                       4              1           12.6
  1163. ; *                  ==========================================================
  1164. ; *                  * These timing could be incorrect when using code
  1165. ; *                    optimization or extended instruction mode,
  1166. ; *                    or when having other interrupts enabled.
  1167. ; *                    Make sure to verify using the MPLAB SIM's Stopwatch
  1168. ; *****************************************************************************/
  1169. USBRemoteWakeup
  1170. movlb high 0x400 ; Point to proper bank
  1171. btfss usb_stat, RemoteWakeup ; Check if RemoteWakeup function has been enabled by the host.
  1172. return ; No
  1173. rcall USBWakeFromSuspend ; Unsuspend USB modue
  1174. bsf UCON, RESUME ; Start RESUME signaling
  1175. movlw 0x10 ; Set RESUME line for 1-13 ms
  1176. movwf FSR2H ; Using FSR2 as temp
  1177. clrf FSR2L
  1178. USBRemoteWakeupLoop
  1179. decfsz FSR2L, F
  1180. bra USBRemoteWakeupLoop
  1181. decfsz FSR2H, F
  1182. bra USBRemoteWakeupLoop
  1183. bcf UCON, RESUME
  1184. return
  1185. ; From usbdrv.c line 443
  1186. ;/******************************************************************************
  1187. ; * Function:        void USB_SOF_Handler(void)
  1188. ; *
  1189. ; * PreCondition:    None
  1190. ; *
  1191. ; * Input:           None
  1192. ; *
  1193. ; * Output:          None
  1194. ; *
  1195. ; * Side Effects:    None
  1196. ; *
  1197. ; * Overview:        The USB host sends out a SOF packet to full-speed devices
  1198. ; *                  every 1 ms. This interrupt may be useful for isochronous
  1199. ; *                  pipes. End designers should implement callback routine
  1200. ; *                  as necessary.
  1201. ; *
  1202. ; * Note:            None
  1203. ; *****************************************************************************/
  1204. USB_SOF_Handler
  1205. ; Callback routine here
  1206. bcf UIR, SOFIF
  1207. return
  1208. ; From usbdrv.c line 486
  1209. ;/******************************************************************************
  1210. ; * Function:        void USBStallHandler(void)
  1211. ; *
  1212. ; * PreCondition:    A STALL packet is sent to the host by the SIE.
  1213. ; *
  1214. ; * Input:           None
  1215. ; *
  1216. ; * Output:          None
  1217. ; *
  1218. ; * Side Effects:    None
  1219. ; *
  1220. ; * Overview:        The STALLIF is set anytime the SIE sends out a STALL
  1221. ; *                  packet regardless of which endpoint causes it.
  1222. ; *                  A Setup transaction overrides the STALL function. A stalled
  1223. ; *                  endpoint stops stalling once it receives a setup packet.
  1224. ; *                  In this case, the SIE will accepts the Setup packet and
  1225. ; *                  set the TRNIF flag to notify the firmware. STALL function
  1226. ; *                  for that particular endpoint pipe will be automatically
  1227. ; *                  disabled (direction specific).
  1228. ; *
  1229. ; *                  There are a few reasons for an endpoint to be stalled.
  1230. ; *                  1. When a non-supported USB request is received.
  1231. ; *                     Example: GET_DESCRIPTOR(DEVICE_QUALIFIER)
  1232. ; *                  2. When an endpoint is currently halted.
  1233. ; *                  3. When the device class specifies that an endpoint must
  1234. ; *                     stall in response to a specific event.
  1235. ; *                     Example: Mass Storage Device Class
  1236. ; *                              If the CBW is not valid, the device shall
  1237. ; *                              STALL the Bulk-In pipe.
  1238. ; *                              See USB Mass Storage Class Bulk-only Transport
  1239. ; *                              Specification for more details.
  1240. ; *
  1241. ; * Note:            UEPn.EPSTALL can be scanned to see which endpoint causes
  1242. ; *                  the stall event.
  1243. ; *                  If
  1244. ; *****************************************************************************/
  1245. USBStallHandler
  1246. ; Does not really have to do anything here,
  1247. ; even for the control endpoint.
  1248. ; All BDs of Endpoint 0 are owned by SIE right now,
  1249. ; but once a Setup Transaction is received, the ownership
  1250. ; for EP0_OUT will be returned to CPU.
  1251. ; When the Setup Transaction is serviced, the ownership
  1252. ; for EP0_IN will then be forced back to CPU by firmware.
  1253. ;
  1254. ; NOTE: Above description is not quite true at this point.
  1255. ;       It seems the SIE never returns the UOWN bit to CPU,
  1256. ;       and a TRNIF is never generated upon successful
  1257. ;       reception of a SETUP transaction.
  1258. ;       Firmware work-around is implemented below.
  1259. ;
  1260. btfsc UEP0, EPSTALL
  1261. rcall USBPrepareForNextSetupTrf ; Firmware Work-Around
  1262. bcf UEP0, EPSTALL
  1263. bcf UIR, STALLIF
  1264. return
  1265. ; From usbdrv.c line 528
  1266. ;/******************************************************************************
  1267. ; * Function:        void USBErrorHandler(void)
  1268. ; *
  1269. ; * PreCondition:    None
  1270. ; *
  1271. ; * Input:           None
  1272. ; *
  1273. ; * Output:          None
  1274. ; *
  1275. ; * Side Effects:    None
  1276. ; *
  1277. ; * Overview:        The purpose of this interrupt is mainly for debugging
  1278. ; *                  during development. Check UEIR to see which error causes
  1279. ; *                  the interrupt.
  1280. ; *
  1281. ; * Note:            None
  1282. ; *****************************************************************************/
  1283. USBErrorHandler
  1284. bcf UIR, UERRIF
  1285. return
  1286. ; From usbdrv.c line 555
  1287. ;/******************************************************************************
  1288. ; * Function:        void USBProtocolResetHandler(void)
  1289. ; *
  1290. ; * PreCondition:    A USB bus reset is received from the host.
  1291. ; *
  1292. ; * Input:           None
  1293. ; *
  1294. ; * Output:          None
  1295. ; *
  1296. ; * Side Effects:    Currently, this routine flushes any pending USB
  1297. ; *                  transactions. It empties out the USTAT FIFO. This action
  1298. ; *                  might not be desirable in some applications.
  1299. ; *
  1300. ; * Overview:        Once a USB bus reset is received from the host, this
  1301. ; *                  routine should be called. It resets the device address to
  1302. ; *                  zero, disables all non-EP0 endpoints, initializes EP0 to
  1303. ; *                  be ready for default communication, clears all USB
  1304. ; *                  interrupt flags, unmasks applicable USB interrupts, and
  1305. ; *                  reinitializes internal state-machine variables.
  1306. ; *
  1307. ; * Note:            None
  1308. ; *****************************************************************************/
  1309. USBProtocolResetHandler
  1310. ; movlb high 0x400 ; Point to proper bank
  1311. clrf UEIR ; Clear all USB error flags
  1312. clrf UIR ; Clears all USB interrupts
  1313. movlw 0x9f ; Unmask all USB error interrupts
  1314. movwf UEIE
  1315. movlw 0x7b ; Enable all interrupts except ACTVIE
  1316. movwf UIE
  1317. clrf UADDR ; Reset to default address
  1318. lfsr 2, UEP1 ; Reset all non-EP0 UEPn registers
  1319. movlw 15
  1320. USBProtocolResetHandlerClearLoop
  1321. clrf POSTINC2
  1322. decfsz WREG, F
  1323. bra USBProtocolResetHandlerClearLoop
  1324. movlw EP_CTRL|HSHK_EN ; Init EP0 as a Ctrl EP
  1325. movwf UEP0
  1326. btfsc UIR, TRNIF ; Flush any pending transactions
  1327. USBProtocolResetHandlerFlushLoop
  1328. bcf UIR, TRNIF
  1329. btfsc UIR, TRNIF
  1330. bra USBProtocolResetHandlerFlushLoop
  1331. bcf UCON, PKTDIS ; Make sure packet processing is enabled
  1332.    rcall USBPrepareForNextSetupTrf
  1333. bcf usb_stat, RemoteWakeup ; Default status flag to disable
  1334. clrf usb_active_cfg ; Clear active configuration
  1335. movlw DEFAULT_STATE
  1336.    movwf usb_device_state
  1337. return
  1338. #ifdef USB_USE_HID
  1339. ; From hid.c  line 72
  1340. ;/******************************************************************************
  1341. ; * Function:        void USBCheckHIDRequest(void)
  1342. ; *
  1343. ; * PreCondition:    None
  1344. ; *
  1345. ; * Input:           None
  1346. ; *
  1347. ; * Output:          None
  1348. ; *
  1349. ; * Side Effects:    None
  1350. ; *
  1351. ; * Overview:        This routine checks the setup data packet to see if it
  1352. ; *                  knows how to handle it
  1353. ; *
  1354. ; * Note:            None
  1355. ; *****************************************************************************/
  1356. USBCheckHIDRequest
  1357. movlb high 0x400 ; Point to proper bank
  1358. movf SetupPkt, W ; Recipient = RCPT_INTF?
  1359. andlw 0x1f ; Mask to lower 5 bits
  1360. sublw RCPT_INTF
  1361. bnz USBCheckHIDRequestExit ; No
  1362. movlw HID_INTF_ID ; IntfID = HID_INTF_ID?
  1363. cpfseq SetupPkt + bIntfID
  1364. USBCheckHIDRequestExit
  1365. return ; No
  1366. ;
  1367. ; There are two standard requests that hid.c may support.
  1368. ; 1. GET_DSC(DSC_HID,DSC_RPT,DSC_PHY);
  1369. ; 2. SET_DSC(DSC_HID,DSC_RPT,DSC_PHY);
  1370. ;
  1371. movlw GET_DSC ; Request = GET_DSC?
  1372. cpfseq SetupPkt + bRequest
  1373. bra USBCheckHIDRequestClass ; No
  1374. movlw DSC_HID ; DscType = DSC_HID?
  1375. cpfseq SetupPkt + bDscType
  1376. bra USBCheckHIDRequest1 ; No
  1377. mSetSourcePointer HIDDescriptor1
  1378. mGetRomTableCount ; Set wCount
  1379. bsf usb_stat, ctrl_trf_mem ; Indicate ROM
  1380. bra USBHIDSetSessionOwner
  1381. USBCheckHIDRequest1
  1382. movlw DSC_RPT ; DscType = DSC_RPT?
  1383. cpfseq SetupPkt + bDscType
  1384. bra USBCheckHIDRequest2 ; No
  1385. mSetSourcePointer ReportDescriptor1
  1386. movlw low (ReportDescriptor1Len) ; Set wCount
  1387. movwf TBLPTRL
  1388. movlw high (ReportDescriptor1Len)
  1389. movwf TBLPTRH
  1390. clrf TBLPTRU
  1391.         tblrd   *+ ; Read count low
  1392. movff TABLAT, wCount
  1393.         tblrd   *+ ; Skip next
  1394.         tblrd   * ; Read count high
  1395. movff TABLAT, wCount + 1
  1396. bsf usb_stat, ctrl_trf_mem ; Indicate ROM
  1397. bra USBHIDSetSessionOwner
  1398. USBCheckHIDRequest2
  1399. ; movlw DSC_PHY ; DscType = DSC_PHY?
  1400. ; cpfseq SetupPkt + bDscType
  1401. ; return ; No
  1402. USBCheckHIDRequestClass
  1403. movf SetupPkt, W ; RequestType = CLASS?
  1404. andlw 0x60 ; Mask to proper bits
  1405. sublw (CLASS) << 5
  1406. bnz USBCheckHIDRequestExit ; No
  1407. ; movlw GET_REPORT ; Request = GET_REPORT?
  1408. ; subwf SetupPkt + bRequest, W
  1409. ; bz HIDGetReportHandler ; Yes
  1410. ; movlw SET_REPORT ; Request = SET_REPORT?
  1411. ; subwf SetupPkt + bRequest, W
  1412. ; bz HIDSetReportHandler ; Yes
  1413. movlw GET_IDLE ; Request = GET_IDLE?
  1414. cpfseq SetupPkt + bRequest
  1415. bra USBCheckHIDRequestClass1 ; No
  1416. mSetSourcePointer idle_rate
  1417. movlw 1
  1418. movwf wCount
  1419. clrf wCount + 1
  1420. bcf usb_stat, ctrl_trf_mem ; Indicate RAM
  1421. bra USBHIDSetSessionOwner
  1422. USBCheckHIDRequestClass1
  1423. movlw SET_IDLE ; Request = SET_IDLE?
  1424. cpfseq SetupPkt + bRequest
  1425. bra USBCheckHIDRequestClass2 ; No
  1426. movff SetupPkt + wValue + 1, idle_rate
  1427. bra USBHIDSetSessionOwner
  1428. USBCheckHIDRequestClass2
  1429. movlw GET_PROTOCOL ; Request = GET_PROTOCOL?
  1430. cpfseq SetupPkt + bRequest
  1431. bra USBCheckHIDRequestClass3 ; No
  1432. mSetSourcePointer active_protocol
  1433. movlw 1
  1434. movwf wCount
  1435. clrf wCount + 1
  1436. bcf usb_stat, ctrl_trf_mem ; Indicate RAM
  1437. bra USBHIDSetSessionOwner
  1438. USBCheckHIDRequestClass3
  1439. movlw SET_PROTOCOL ; Request = SET_PROTOCOL?
  1440. cpfseq SetupPkt + bRequest
  1441. return ; No
  1442. movff SetupPkt + wValue, active_protocol
  1443. USBHIDSetSessionOwner
  1444. movlw MUID_HID
  1445. movwf ctrl_trf_session_owner
  1446. return
  1447. ; From hid.c  line 158
  1448. ;/******************************************************************************
  1449. ; * Function:        void HIDInitEP(void)
  1450. ; *
  1451. ; * PreCondition:    None
  1452. ; *
  1453. ; * Input:           None
  1454. ; *
  1455. ; * Output:          None
  1456. ; *
  1457. ; * Side Effects:    None
  1458. ; *
  1459. ; * Overview:        HIDInitEP initializes HID endpoints, buffer descriptors,
  1460. ; *                  internal state-machine, and variables.
  1461. ; *                  It should be called after the USB host has sent out a
  1462. ; *                  SET_CONFIGURATION request.
  1463. ; *                  See USBStdSetCfgHandler() in usb9.c for examples.
  1464. ; *
  1465. ; * Note:            None
  1466. ; *****************************************************************************/
  1467. HIDInitEP
  1468. movlw 1 ; Endpoint 1 Out
  1469. movwf FSR0L
  1470. lfsr 1, hid_report_out ; FSR1 = endpoint buffer address
  1471. movlw HID_INT_OUT_EP_SIZE ; W = endpoint size
  1472. rcall InitEPOut ; Inititalize the endpoint
  1473. movlw 1 ; Endpoint 1 In
  1474. movwf FSR0L
  1475. lfsr 1, hid_report_in ; FSR1 = endpoint buffer address
  1476. movlw HID_INT_IN_EP_SIZE ; W = endpoint size
  1477. bra InitEPIn ; Inititalize the endpoint
  1478. #endif ; USB_USE_HID
  1479. #ifdef USB_USE_CDC
  1480. ;/******************************************************************************
  1481. ; * Function:        void USBCheckCDCRequest(void)
  1482. ; *
  1483. ; * PreCondition:    None
  1484. ; *
  1485. ; * Input:           None
  1486. ; *
  1487. ; * Output:          None
  1488. ; *
  1489. ; * Side Effects:    None
  1490. ; *
  1491. ; * Overview:        This routine checks the setup data packet to see if it
  1492. ; *                  knows how to handle it
  1493. ; *
  1494. ; * Note:            None
  1495. ; *****************************************************************************/
  1496. USBCheckCDCRequest
  1497. ;    /*
  1498. ;     * If request recipient is not an interface then return
  1499. ;     */
  1500. movlb high 0x400 ; Point to proper bank
  1501. movf SetupPkt, W ; Recipient = RCPT_INTF?
  1502. andlw 0x1f ; Mask to lower 5 bits
  1503. sublw RCPT_INTF
  1504. bnz USBCheckCDCRequestExit ; No
  1505. ;    /*
  1506. ;     * If request type is not class-specific then return
  1507. ;     */
  1508. movf SetupPkt, W ; RequestType = CLASS?
  1509. andlw 0x60 ; Mask to proper bits
  1510. sublw (CLASS) << 5
  1511. bnz USBCheckCDCRequestExit ; No
  1512. ;    /*
  1513. ;     * Interface ID must match interface numbers associated with
  1514. ;     * CDC class, else return
  1515. ;     */
  1516. movlw CDC_COMM_INTF_ID ; IntfID = CDC_COMM_INTF_ID?
  1517. subwf SetupPkt + bIntfID, W
  1518. bz USBCheckCDCRequest1 ; Yes
  1519. movlw CDC_DATA_INTF_ID ; IntfID = CDC_DATA_INTF_ID?
  1520. cpfseq SetupPkt + bIntfID
  1521. USBCheckCDCRequestExit
  1522. return ; No
  1523.     
  1524. USBCheckCDCRequest1
  1525. movlw SEND_ENCAPSULATED_COMMAND ; Request = SEND_ENCAPSULATED_COMMAND?
  1526. cpfseq SetupPkt + bRequest
  1527. bra USBCheckCDCRequest2 ; No
  1528. mSetSourcePointer dummy_encapsulated_cmd_response
  1529. bcf usb_stat, ctrl_trf_mem ; Indicate RAM
  1530. movlw dummy_length
  1531. movwf wCount
  1532. clrf wCount + 1
  1533. bra USBCDCSetSessionOwner
  1534. USBCheckCDCRequest2
  1535. movlw GET_ENCAPSULATED_RESPONSE ; Request = GET_ENCAPSULATED_RESPONSE?
  1536. cpfseq SetupPkt + bRequest
  1537. bra USBCheckCDCRequest3 ; No
  1538. ;       // Populate dummy_encapsulated_cmd_response first.
  1539. mSetDestinationPointer dummy_encapsulated_cmd_response
  1540. bra USBCDCSetSessionOwner
  1541. USBCheckCDCRequest3
  1542. movlw SET_COMM_FEATURE ; Request = SET_COMM_FEATURE?
  1543. cpfseq SetupPkt + bRequest
  1544. bra USBCheckCDCRequest4 ; No
  1545. return ; Optional
  1546. USBCheckCDCRequest4
  1547. movlw GET_COMM_FEATURE ; Request = GET_COMM_FEATURE?
  1548. cpfseq SetupPkt + bRequest
  1549. bra USBCheckCDCRequest5 ; No
  1550. return ; Optional
  1551. USBCheckCDCRequest5
  1552. movlw CLEAR_COMM_FEATURE ; Request = CLEAR_COMM_FEATURE?
  1553. cpfseq SetupPkt + bRequest
  1554. bra USBCheckCDCRequest6 ; No
  1555. return ; Optional
  1556. USBCheckCDCRequest6
  1557. movlw SET_LINE_CODING ; Request = SET_LINE_CODING?
  1558. cpfseq SetupPkt + bRequest
  1559. bra USBCheckCDCRequest7 ; No
  1560. mSetDestinationPointer line_coding
  1561. bra USBCDCSetSessionOwner
  1562. USBCheckCDCRequest7
  1563. movlw GET_LINE_CODING ; Request = GET_LINE_CODING?
  1564. cpfseq SetupPkt + bRequest
  1565. bra USBCheckCDCRequest8 ; No
  1566. ; Abstract line coding information
  1567. movlw low 115200 ; baud rate
  1568. movwf line_coding + dwDTERate
  1569. movlw high 115200
  1570. movwf line_coding + dwDTERate + 1
  1571. movlw upper 115200
  1572. movwf line_coding + dwDTERate + 2
  1573. clrf line_coding + dwDTERate + 3
  1574. clrf line_coding + bCharFormat ; 1 stop bit
  1575. clrf line_coding + bParityType ; None
  1576. movlw 8
  1577. movwf line_coding + bDataBits ; 5,6,7,8, or 16
  1578. mSetSourcePointer line_coding
  1579. bcf usb_stat, ctrl_trf_mem ; Indicate RAM
  1580. movlw LINE_CODING_LENGTH
  1581. movwf wCount
  1582. clrf wCount + 1
  1583. bra USBCDCSetSessionOwner
  1584. USBCheckCDCRequest8
  1585. movlw SET_CONTROL_LINE_STATE ; Request = SET_CONTROL_LINE_STATE?
  1586. cpfseq SetupPkt + bRequest
  1587. bra USBCheckCDCRequest9 ; No
  1588. movff SetupPkt + wValue, control_signal_bitmap
  1589. bra USBCDCSetSessionOwner
  1590. USBCheckCDCRequest9
  1591. movlw SEND_BREAK ; Request = SEND_BREAK?
  1592. cpfseq SetupPkt + bRequest
  1593. bra USBCheckCDCRequest10 ; No
  1594. return ; Optional
  1595. USBCheckCDCRequest10
  1596. return ; Default
  1597. USBCDCSetSessionOwner
  1598. movlw MUID_CDC
  1599. movwf ctrl_trf_session_owner
  1600. return
  1601. ;/******************************************************************************
  1602. ; * Function:        void CDCInitEP(void)
  1603. ; *
  1604. ; * PreCondition:    None
  1605. ; *
  1606. ; * Input:           None
  1607. ; *
  1608. ; * Output:          None
  1609. ; *
  1610. ; * Side Effects:    None
  1611. ; *
  1612. ; * Overview:        CDCInitEP initializes CDC endpoints, buffer descriptors,
  1613. ; *                  internal state-machine, and variables.
  1614. ; *                  It should be called after the USB host has sent out a
  1615. ; *                  SET_CONFIGURATION request.
  1616. ; *                  See USBStdSetCfgHandler() in usb9.c for examples.
  1617. ; *
  1618. ; * Note:            None
  1619. ; *****************************************************************************/
  1620. CDCInitEP
  1621. movlw 2 ; Endpoint 2 In
  1622. movwf FSR0L
  1623. lfsr 1, cdc_notice ; FSR1 = endpoint buffer address
  1624. movlw CDC_INT_EP_SIZE ; W = endpoint size
  1625. rcall InitEPIn ; Inititalize the endpoint
  1626. movlw 3 ; Endpoint 3
  1627. movwf FSR0L
  1628. lfsr 1, cdc_data_rx ; FSR1 = endpoint buffer address
  1629. movlw CDC_BULK_OUT_EP_SIZE ; W = endpoint size
  1630. rcall InitEPOut ; Inititalize the endpoint
  1631. movlw 3 ; Endpoint 3 In
  1632. movwf FSR0L
  1633. lfsr 1, cdc_data_tx ; FSR1 = endpoint buffer address
  1634. movlw CDC_BULK_IN_EP_SIZE ; W = endpoint size
  1635. bra InitEPIn ; Inititalize the endpoint
  1636. #endif ; USB_USE_CDC
  1637. ; Generic code for use by all the classes
  1638. ; InitEPIn
  1639. ;  Generic initialize In endpoint
  1640. ; Input:
  1641. ;  FSR0L is endpoint number
  1642. ;  FSR1 is endpoint buffer address
  1643. ;  W is endpoint buffer size
  1644. ; Returns:
  1645. ;  Nada
  1646. ; Uses
  1647. ;  FSR0 is BDT pointer
  1648. ;  FSR1 is endpoint buffer pointer
  1649. ;  FSR2 is endpoint table pointer
  1650. InitEPIn
  1651. ; Save maximum count at front of endpoint buffer and move buffer pointer up (no need to put in Cnt for In)
  1652. movwf POSTINC1 ; Store maximum count at front of endpoint buffer and move up pointer
  1653. ; Point FSR2 to endpoint table
  1654. lfsr 2, UEP0
  1655. movf FSR0L, W ; Add in endpoint number
  1656. addwf FSR2L, F
  1657. ; Enable In endpoint
  1658. movlw EP_IN|HSHK_EN ; Enable In pipe
  1659. iorwf INDF2, F
  1660. ; Point FSR0 to endpoint BDT
  1661. rlncf FSR0L, W ; Endpoint number * 8
  1662. rlncf WREG, F
  1663. rlncf WREG, F
  1664. lfsr 0, ep0Bi ; Point FSR0 to beginning of BDT area
  1665. addwf FSR0L, F ; Add endpoint offset to FSR0 (can't overflow to FSR0H)
  1666. ; Set endpoint buffer address from FSR1
  1667. movlw ADRL ; Point to ADRL
  1668. movff FSR1L, PLUSW0
  1669. movlw ADRH ; Point to ADRH
  1670. movff FSR1H, PLUSW0
  1671. ; Set endpoint status
  1672. movlw _UCPU|_DAT1 ; Set transmit status
  1673. movwf INDF0 ; Set Stat
  1674. return
  1675. ; InitEPOut
  1676. ;  Generic initialize Out endpoint
  1677. ; Input:
  1678. ;  FSR0L is endpoint number
  1679. ;  FSR1 is endpoint buffer address
  1680. ;  W is endpoint buffer size
  1681. ; Returns:
  1682. ;  Nada
  1683. ; Uses
  1684. ;  FSR0 is BDT pointer
  1685. ;  FSR1 is endpoint buffer pointer
  1686. ;  FSR2 is endpoint table pointer
  1687. InitEPOut
  1688. ; Save maximum count at front of endpoint buffer and move buffer pointer up
  1689. movwf POSTINC1 ; Store maximum count at front of endpoint buffer and move up pointer
  1690. ; Point FSR2 to endpoint table
  1691. lfsr 2, UEP0
  1692. movf FSR0L, W ; Add in endpoint number
  1693. addwf FSR2L, F
  1694. ; Enable Out endpoint
  1695. movlw EP_OUT|HSHK_EN ; Enable Out pipe
  1696. iorwf INDF2, F
  1697. ; Point FSR0 to endpoint BDT
  1698. rlncf FSR0L, W ; Endpoint number * 8
  1699. rlncf WREG, F
  1700. rlncf WREG, F
  1701. lfsr 0, ep0Bo ; Point FSR0 to beginning of BDT area
  1702. addwf FSR0L, F ; Add endpoint offset to FSR0 (can't overflow to FSR0H)
  1703. ; Set endpoint buffer address from FSR1 + 1
  1704. movlw ADRL ; Point to ADRL
  1705. movff FSR1L, PLUSW0
  1706. movlw ADRH ; Point to ADRH
  1707. movff FSR1H, PLUSW0
  1708. ; Set Cnt to maximum count
  1709. movf POSTDEC1, W ; Back up endpoint buffer pointer (no PREDEC1!)
  1710. incf FSR0L, F ; Point to Cnt
  1711. movff INDF1, POSTDEC0 ; Set maximum count and point back to Stat
  1712. ; Set endpoint status
  1713. movlw _USIE|_DAT0|_DTSEN ; Set receive status
  1714. movwf INDF0 ; Set Stat
  1715. return
  1716. ; PutUSB
  1717. ;  Generic fill In endpoint for TX
  1718. ; Input:
  1719. ;  FSR0L is endpoint number
  1720. ;  FSR1 is source buffer pointer
  1721. ;  W is count
  1722. ; Returns:
  1723. ;  FSR1 is updated source buffer pointer
  1724. ;  W returns number sent
  1725. ;  Carry is clear for buffer not available
  1726. ; Uses:
  1727. ;  FSR0 is BDT pointer
  1728. ;  FSR1 is source buffer pointer
  1729. ;  FSR2 is endpoint buffer pointer
  1730. ;  R0 in BANKA is temporary length storage
  1731. PutUSB
  1732. movwf R0 ; Save count
  1733. ; Check to see if we're configured
  1734. movlb high 0x400 ; Point to proper bank
  1735. movlw CONFIGURED_STATE ; We might not be configured yet
  1736. subwf usb_device_state, W
  1737. movlw 0 ; 0 characters sent, so far
  1738. bcf STATUS, C ; Clear Carry for possible error return
  1739. bnz PutUSBNotReady ; We're not configured
  1740. ; Point FSR0 to requested endpoint In BDT
  1741. rlncf FSR0L, W ; Endpoint number * 8
  1742. rlncf WREG, F
  1743. rlncf WREG, F
  1744. lfsr 0, ep0Bi ; Point FSR0 to beginning of BDT area
  1745. addwf FSR0L, F ; Add endpoint offset to FSR0 (can't overflow to FSR0H)
  1746. movlw 0 ; 0 characters sent, so far
  1747. bcf STATUS, C ; Clear Carry for possible error return
  1748. btfsc INDF0, UOWN ; Who owns the buffer (Stat, UOWN)?
  1749. PutUSBNotReady
  1750. return ; Busy (we don't)
  1751. ; Get endpoint buffer address to FSR2
  1752. movlw ADRL ; Point to ADRL
  1753. movff PLUSW0, FSR2L
  1754. movlw ADRH ; Point to ADRH
  1755. movff PLUSW0, FSR2H
  1756. movlw -1
  1757. movf PLUSW2, W ; Get maximum length from in front of endpoint buffer
  1758. cpfslt R0 ; Find number of bytes to send this time
  1759. movwf R0 ; Too big - send maximum allowed length
  1760. incf FSR0L, F ; Point to Cnt
  1761. movf R0, W ; Get number to send
  1762. movwf POSTDEC0 ; Put length into Cnt and point back to Stat
  1763. bz PutUSBZero ; Zero to send
  1764. PutUSBRamLoop
  1765. movff POSTINC1, POSTINC2 ; Copy source buffer to endpoint buffer
  1766. decfsz WREG, F ; Count down number of bytes to transfer
  1767. bra PutUSBRamLoop
  1768. PutUSBZero
  1769. movlw _DTSMASK ; Save only DTS bit
  1770. andwf INDF0, F
  1771. btg INDF0, DTS ; Toggle DTS bit
  1772. movlw _USIE|_DTSEN ; Turn ownership to SIE
  1773. iorwf INDF0, F
  1774. movf R0, W ; Return number of bytes sent
  1775. bsf STATUS, C ; Set Carry for non-error return
  1776. return
  1777. ; GetUSB
  1778. ;  Generic get from Out endpoint for RX
  1779. ; Input:
  1780. ;  FSR0L is endpoint number
  1781. ;  FSR1 is destination buffer pointer
  1782. ;  W is max buffer length
  1783. ; Returns:
  1784. ;  FSR1 is updated destination buffer pointer
  1785. ;  W returns number received
  1786. ;  Carry is clear for buffer not available
  1787. ; Uses
  1788. ;  FSR0 is BDT pointer
  1789. ;  FSR1 is destination buffer pointer
  1790. ;  FSR2 is endpoint buffer pointer
  1791. ;  R0 in BANKA is temporary length storage
  1792. GetUSB
  1793. movwf R0 ; Save max buffer length
  1794. ; Check to see if we're configured
  1795. movlb high 0x400 ; Point to proper bank
  1796. movlw CONFIGURED_STATE ; We might not be configured yet
  1797. subwf usb_device_state, W
  1798. movlw 0 ; 0 characters received, so far
  1799. bcf STATUS, C ; Clear Carry for possible error return
  1800. bnz GetUSBNotReady ; We're not configured
  1801. ; Point FSR0 to requested endpoint Out BDT
  1802. rlncf FSR0L, W ; Endpoint number * 8
  1803. rlncf WREG, F
  1804. rlncf WREG, F
  1805. lfsr 0, ep0Bo ; Point FSR0 to beginning of BDT area
  1806. addwf FSR0L, F ; Add endpoint offset to FSR0 (can't overflow to FSR0H)
  1807. movlw 0 ; 0 characters received, so far
  1808. bcf STATUS, C ; Clear Carry for possible error return
  1809. btfsc INDF0, UOWN ; Who owns the buffer (Stat, UOWN)?
  1810. GetUSBNotReady
  1811. return ; Busy (we don't)
  1812. ; Get endpoint buffer address to FSR2
  1813. movlw ADRL ; Point to ADRL
  1814. movff PLUSW0, FSR2L
  1815. movlw ADRH ; Point to ADRH
  1816. movff PLUSW0, FSR2H
  1817. movf PREINC0, W ; Get Cnt
  1818. cpfslt R0 ; Make sure it's not longer than the buffer
  1819. movwf R0 ; It's OK, save returned length
  1820. movlw -1
  1821. movf PLUSW2, W ; Get maximum length from in front of endpoint buffer
  1822. movwf POSTDEC0 ; Reset max length and point back to Stat
  1823. movf R0, W ; Get count to W
  1824. bz GetUSBZero ; Nothing received
  1825. GetUSBRamLoop
  1826. movff POSTINC2, POSTINC1 ; Copy endpoint buffer to destination buffer
  1827. decfsz WREG, F ; Count down number of bytes
  1828. bra GetUSBRamLoop
  1829. GetUSBZero
  1830. movlw _DTSMASK ; Save only DTS bit
  1831. andwf INDF0, F
  1832. btg INDF0, DTS ; Toggle DTS bit
  1833. movlw _USIE|_DTSEN ; Turn ownership to SIE
  1834. iorwf INDF0, F
  1835. movf R0, W ; Return number of bytes received
  1836. bsf STATUS, C ; Set Carry for non-error return
  1837. return