;----------------------------------------------------------------------------------------- ;内容 ; PIC18F4550 ; clock:48MHz ; ; マウスのクリックでLED点灯 ; ; ; PICのピン接続(LED) ; RD0 LED1 ; RC2 LED2 ; ; ; PICのピン接続(USB) ; RB0 DATA+ ; RB1 DATA- ; LIST P=PIC18F4550 INCLUDE CONFIG IESO = OFF ;Oscillator Switchover mode CONFIG FCMEN = OFF ;Fail-Safe Clock Monitor CONFIG FOSC = HSPLL_HS ;Use Pull up CONFIG PLLDIV = 5 ;Divide by 5 (20MHz / 5) CONFIG CPUDIV = OSC1_PLL2 ;[OSC1/OSC2 Src: /1][96 MHz PLL Src: /2] CONFIG BOR = OFF CONFIG PWRT = ON ;Power-up Timer CONFIG WDT = OFF ;Watchdog Timer CONFIG MCLRE = OFF ;RE3 input pin enabled; MCLR disabled CONFIG PBADEN = OFF ;PORTB<4:0> pins are configured as digital I/O on Reset CONFIG LVP = OFF; Single-Supply ICSP disabled CBLOCK 000h CNT1mS ;1mSカウンタ CNT50uS ;50μSカウンタ USB_FLAG ;0bit Data+,-ゼロ判別 ENDC CBLOCK 0600h DISK_DATA ;0600h-0800h データ書込み用 512byte ;USB DATA用 ENDC LED EQU 00h ;Power on LED_P EQU PORTD ;Power on PORT LED2 EQU 02h ;Power on LED2_P EQU PORTC ;Power on PORT USB_P_S EQU TRISB ;PORT for USB USB_D1 EQU 00H ;USB DATA+ USB_D2 EQU 01H ;USB DATA- ORG 0 GOTO INIT ;----------------------------------------------------------------------------------------- ;初期化 INIT MOVLW b'01110000' ;プリスケーラ設定 外部クロック MOVWF OSCCON MOVLW b'00101111' MOVWF TRISA ; MOVLW b'00000000' MOVWF TRISB MOVLW b'10000001' MOVWF TRISC ; MOVLW b'00010000' MOVWF TRISD ; MOVLW b'00000111' MOVWF TRISE ; CLRF PORTA CLRF PORTB CLRF PORTC CLRF PORTD CLRF PORTE BSF LED_P,LED ;動作確認用信号出力 BSF LED2_P,LED2 ;LED2 MAIN CALL EOP8 CALL EOP8 CALL EOP8 CALL USB_PID_SETUP CALL USB_SET_CONFIGURATION CALL USB_WAIT_ANSWER ;Wait For Replay CALL USB_IN_ANSWER_RETRY ;NAK以外が返答されるまでリトライ CALL USB_PID_ACK ; BCF LED2_P,LED2 ;LED2 MAIN_LOOP CALL EOP8 ;スリープしないようにする CALL USB_IN_ANSWER_RETRY_EP1 ;NAK以外が返答されるまでリトライ CALL USB_PID_ACK ;データ受信のために必ず必要 CALL USB_CALC_NRZI ;NRZI計算 CALL EOP_NO_WAIT ;スリープしないように CALL SET_USB_DATA INCF FSR0L,F MOVF INDF0,W SUBLW b'01011010' ;NAK=0101 BTFSC STATUS,Z ;Z=1のときデータクリア CALL CLEAR_USB_DATA ;データをクリア CALL SET_USB_DATA INCF FSR0L,F INCF FSR0L,F BSF LED2_P,LED2 ;LED2 BTFSS INDF0,7 ;1 のときSkip BCF LED2_P,LED2 ;LED2 BSF LED_P,LED ;LED BTFSS INDF0,6 ;1 のときSkip BCF LED_P,LED ;LED CALL CLEAR_USB_DATA ;データをクリア GOTO MAIN_LOOP SET_USB_DATA MOVLW 0x06 ;RAM上位アドレス MOVWF FSR0H MOVLW 0x00 ;RAM下位アドレス MOVWF FSR0L RETURN SET_USB_DATA_FSR1 MOVLW 0x06 ;RAM上位アドレス MOVWF FSR1H MOVLW 0x00 ;RAM下位アドレス MOVWF FSR1L RETURN CLEAR_USB_DATA CALL SET_USB_DATA INCF FSR0L,F ;つぎのアドレス CLRF INDF0 ;データクリア INCF FSR0L,F ;つぎのアドレス CLRF INDF0 ;データクリア INCF FSR0L,F ;つぎのアドレス CLRF INDF0 ;データクリア INCF FSR0L,F ;つぎのアドレス CLRF INDF0 ;データクリア INCF FSR0L,F ;つぎのアドレス CLRF INDF0 ;データクリア INCF FSR0L,F ;つぎのアドレス CLRF INDF0 ;データクリア INCF FSR0L,F ;つぎのアドレス CLRF INDF0 ;データクリア INCF FSR0L,F ;つぎのアドレス CLRF INDF0 ;データクリア RETURN ;----------------------------------------------------------------------------------------- ;SET CONFIGURATION ; USB_SET_CONFIGURATION CALL BIT_RESET ;Reset CALL BIT_0000 ;SYNC CALL BIT_0001 CALL BIT_1100 ;PID DATA0 CALL BIT_0011 CALL BIT_0000 ;bmRequestType CALL BIT_0000 CALL BIT_1001 ;bRequest CALL BIT_0000 CALL BIT_1000 ;wValue CALL BIT_0000 CALL BIT_0000 CALL BIT_0000 CALL BIT_0000 ;wIndex CALL BIT_0000 CALL BIT_0000 CALL BIT_0000 CALL BIT_0000 ;wLength CALL BIT_0000 CALL BIT_0000 CALL BIT_0000 CALL BIT_1110 ;CRC16 CALL BIT_0100 CALL BIT_1010 CALL BIT_0100 CALL BIT_END RETURN ;----------------------------------------------------------------------------------------- ;PID SETUP ; USB_PID_SETUP CALL BIT_RESET ;Reset CALL BIT_0000 ;SYNC CALL BIT_0001 CALL BIT_1011 ;PID SETUP CALL BIT_0100 CALL BIT_0000 CALL BIT_0000 CALL BIT_0000 CALL BIT_1000 ;CRC5 = 00010 =0x02 CALL BIT_END RETURN ;----------------------------------------------------------------------------------------- ;PID IN ; USB_PID_IN CALL WAIT_05US CALL BIT_RESET ;Reset CALL BIT_0000 ;SYNC CALL BIT_0001 CALL BIT_1001 ;PID IN CALL BIT_0110 CALL BIT_0000 CALL BIT_0000 CALL BIT_0000 CALL BIT_1000 ;CRC5 = 00010 =0x02 CALL BIT_END RETURN USB_PID_IN_EP1 CALL WAIT_05US CALL BIT_RESET ;Reset CALL BIT_0000 ;SYNC CALL BIT_0001 CALL BIT_1001 ;PID IN CALL BIT_0110 CALL BIT_0000 CALL BIT_0001 CALL BIT_0000 CALL BIT_0101 ;CRC5 CALL BIT_END RETURN ;----------------------------------------------------------------------------------------- ;PID ACK ; USB_PID_ACK CALL BIT_RESET ;Reset CALL BIT_0000 ;SYNC CALL BIT_0001 CALL BIT_0100 ;PID ACK CALL BIT_1011 CALL BIT_END RETURN ;----------------------------------------------------------------------------------------- ;PID IN RETRY ; USB_IN_ANSWER_RETRY USB_IN_ANSWER_RETRY_LOOP CALL USB_PID_IN CALL USB_WAIT_ANSWER ;Wait For Replay CALL SET_USB_DATA INCF FSR0L,F MOVF INDF0,W SUBLW b'10011100' ;NAK=01011010 BTFSC STATUS,Z ;Z=1のときループ GOTO USB_IN_ANSWER_RETRY_LOOP RETURN USB_IN_ANSWER_RETRY_EP1 USB_IN_ANSWER_RETRY_EP1_LOOP CALL USB_PID_IN_EP1 CALL USB_WAIT_ANSWER ;Wait For Replay CALL SET_USB_DATA INCF FSR0L,F MOVF INDF0,W SUBLW b'10011100' ;NAK=01011010 BTFSC STATUS,Z ;Z=1のときループ GOTO USB_IN_ANSWER_RETRY_EP1_LOOP RETURN ;----------------------------------------------------------------------------------------- ;WAIT ANSWER ; USB_WAIT_ANSWER MOVLW b'00000010' ;0 MOVWF PORTB BSF USB_P_S,USB_D1 ;DATA+ 入力 BSF USB_P_S,USB_D2 ;DATA- 入力 BCF USB_FLAG,0 CALL SET_USB_DATA USB_WAIT_ANSWER_LOOP BTFSS PORTB,0 ;DATA+が1になるまでWAIT GOTO USB_WAIT_ANSWER_LOOP CLRF INDF0 ;データクリア NOP ;時間調整 NOP ;時間調整 BSF INDF0,6 ;CALLはサイクル間に合わない CALL ANSWER_6BIT BTFSC USB_FLAG,0 ;USB_FLAG =1のときEND GOTO USB_WAIT_ANSWER_END BTFSC PORTB,0 ;ポインタ移動のためRETURN後 BSF INDF0,0 ;ポインタ移動のためRETURN後 NOP ;時間調整 NOP ;時間調整 USB_WAIT_ANSWER_LOOP2 INCF FSR0L,F ;つぎのアドレス CALL ANSWER_8BIT BTFSC USB_FLAG,0 ;USB_FLAG =1のときEND GOTO USB_WAIT_ANSWER_END BTFSC PORTB,0 ;ポインタ移動のためRETURN後 BSF INDF0,0 ;ポインタ移動のためRETURN後 GOTO USB_WAIT_ANSWER_LOOP2 ;NRZI計算用に最後に1bit必要 USB_WAIT_ANSWER_END BCF USB_P_S,USB_D1 ;DATA+ 出力 BCF USB_P_S,USB_D2 ;DATA- 出力 MOVLW b'00000010' ;0 MOVWF PORTB RETURN ANSWER_8BIT CLRF INDF0 BTFSC PORTB,0 BSF INDF0,7 MOVF PORTB,W ANDLW b'00000011' BTFSC STATUS,Z ;Z=1のときEND BSF USB_FLAG,0 ; ANSWER_7BIT NOP ;時間調整 NOP ;時間調整 BTFSC PORTB,0 BSF INDF0,6 MOVF PORTB,W ANDLW b'00000011' BTFSC STATUS,Z ;Z=1のときEND BSF USB_FLAG,0 ; ANSWER_6BIT NOP ;時間調整 NOP ;時間調整 BTFSC PORTB,0 BSF INDF0,5 MOVF PORTB,W ANDLW b'00000011' BTFSC STATUS,Z ;Z=1のときEND BSF USB_FLAG,0 ; NOP ;時間調整 NOP ;時間調整 BTFSC PORTB,0 BSF INDF0,4 MOVF PORTB,W ANDLW b'00000011' BTFSC STATUS,Z ;Z=1のときEND BSF USB_FLAG,0 ; NOP ;時間調整 NOP ;時間調整 BTFSC PORTB,0 BSF INDF0,3 MOVF PORTB,W ANDLW b'00000011' BTFSC STATUS,Z ;Z=1のときEND BSF USB_FLAG,0 ; NOP ;時間調整 NOP ;時間調整 BTFSC PORTB,0 BSF INDF0,2 MOVF PORTB,W ANDLW b'00000011' BTFSC STATUS,Z ;Z=1のときEND BSF USB_FLAG,0 ; NOP ;時間調整 NOP ;時間調整 BTFSC PORTB,0 BSF INDF0,1 NOP ;ポインタ移動のためコメントアウト RETURN ;----------------------------------------------------------------------------------------- ;NRZI計算 ; USB_CALC_NRZI CALL SET_USB_DATA CALL SET_USB_DATA_FSR1 INCF FSR1L,F CALL USB_CALC_NRZI_XOR INCF FSR0L,F INCF FSR1L,F CALL USB_CALC_NRZI_XOR INCF FSR0L,F INCF FSR1L,F CALL USB_CALC_NRZI_XOR INCF FSR0L,F INCF FSR1L,F CALL USB_CALC_NRZI_XOR INCF FSR0L,F INCF FSR1L,F CALL USB_CALC_NRZI_XOR INCF FSR0L,F INCF FSR1L,F CALL USB_CALC_NRZI_XOR RETURN USB_CALC_NRZI_XOR RLCF INDF1,W RLCF INDF0,W XORWF INDF0,F COMF INDF0,F RETURN ;----------------------------------------------------------------------------------------- ;ビット処理 ; EOP8 CALL EOP CALL EOP CALL EOP CALL EOP CALL EOP CALL EOP CALL EOP CALL EOP RETURN EOP MOVLW b'00000000' ;D+ D- MOVWF PORTB CALL WAIT_05US ; 0.5usec CALL WAIT_05US ; 0.5usec MOVLW b'00000010' ;0 MOVWF PORTB CALL wait1ms RETURN EOP_NO_WAIT BIT_END MOVLW b'00000000' ;D+ D- MOVWF PORTB CALL WAIT_05US ; 0.5usec CALL WAIT_05US ; 0.5usec MOVLW b'00000010' ;0 MOVWF PORTB RETURN BIT_RESET MOVLW b'00000000' ;D+ D- MOVWF PORTB CALL WAIT_05US ; 0.5usec CALL WAIT_05US ; 0.5usec MOVLW b'00000010' ;0 MOVWF PORTB CALL WAIT_05US ; 0.5usec CALL WAIT_05US ; 0.5usec CALL WAIT_05US ; 0.5usec CALL WAIT_05US ; 0.5usec CALL WAIT_05US ; 0.5usec CALL WAIT_05US ; 0.5usec RETURN BIT_0000 MOVLW b'00000011' ;SWITCH XORWF PORTB,F ;0 CALL WAIT_05US ; 0.5usec XORWF PORTB,F ;0 CALL WAIT_05US ; 0.5usec XORWF PORTB,F ;0 CALL WAIT_05US ; 0.5usec XORWF PORTB,F ;0 NOP ;WAIT NOP ;WAIT RETURN BIT_0001 MOVLW b'00000011' ;SWITCH XORWF PORTB,F ;0 CALL WAIT_05US ; 0.5usec XORWF PORTB,F ;0 CALL WAIT_05US ; 0.5usec XORWF PORTB,F ;0 CALL WAIT_05US ; 0.5usec NOP ;1 NOP ;WAIT NOP ;WAIT RETURN BIT_0010 MOVLW b'00000011' ;SWITCH XORWF PORTB,F ;0 CALL WAIT_05US ; 0.5usec XORWF PORTB,F ;0 CALL WAIT_05US ; 0.5usec NOP ;1 CALL WAIT_05US ; 0.5usec XORWF PORTB,F ;0 NOP ;WAIT NOP ;WAIT RETURN BIT_0011 MOVLW b'00000011' ;SWITCH XORWF PORTB,F ;0 CALL WAIT_05US ; 0.5usec XORWF PORTB,F ;0 CALL WAIT_05US ; 0.5usec NOP ;1 CALL WAIT_05US ; 0.5usec NOP ;1 NOP ;WAIT NOP ;WAIT RETURN BIT_0100 MOVLW b'00000011' ;SWITCH XORWF PORTB,F ;0 CALL WAIT_05US ; 0.5usec NOP ;1 CALL WAIT_05US ; 0.5usec XORWF PORTB,F ;0 CALL WAIT_05US ; 0.5usec XORWF PORTB,F ;0 NOP ;WAIT NOP ;WAIT RETURN BIT_0101 MOVLW b'00000011' ;SWITCH XORWF PORTB,F ;0 CALL WAIT_05US ; 0.5usec NOP ;1 CALL WAIT_05US ; 0.5usec XORWF PORTB,F ;0 CALL WAIT_05US ; 0.5usec NOP ;1 NOP ;WAIT NOP ;WAIT RETURN BIT_0110 MOVLW b'00000011' ;SWITCH XORWF PORTB,F ;0 CALL WAIT_05US ; 0.5usec NOP ;1 CALL WAIT_05US ; 0.5usec NOP ;1 CALL WAIT_05US ; 0.5usec XORWF PORTB,F ;0 NOP ;WAIT NOP ;WAIT RETURN BIT_0111 MOVLW b'00000011' ;SWITCH XORWF PORTB,F ;0 CALL WAIT_05US ; 0.5usec NOP ;1 CALL WAIT_05US ; 0.5usec NOP ;1 CALL WAIT_05US ; 0.5usec NOP ;1 NOP ;WAIT NOP ;WAIT RETURN BIT_1000 MOVLW b'00000011' ;SWITCH NOP ;1 CALL WAIT_05US ; 0.5usec XORWF PORTB,F ;0 CALL WAIT_05US ; 0.5usec XORWF PORTB,F ;0 CALL WAIT_05US ; 0.5usec XORWF PORTB,F ;0 NOP ;WAIT NOP ;WAIT RETURN BIT_1001 MOVLW b'00000011' ;SWITCH NOP ;1 CALL WAIT_05US ; 0.5usec XORWF PORTB,F ;0 CALL WAIT_05US ; 0.5usec XORWF PORTB,F ;0 CALL WAIT_05US ; 0.5usec NOP ;1 NOP ;WAIT NOP ;WAIT RETURN BIT_1010 MOVLW b'00000011' ;SWITCH NOP ;1 CALL WAIT_05US ; 0.5usec XORWF PORTB,F ;0 CALL WAIT_05US ; 0.5usec NOP ;1 CALL WAIT_05US ; 0.5usec XORWF PORTB,F ;0 NOP ;WAIT NOP ;WAIT RETURN BIT_1011 MOVLW b'00000011' ;SWITCH NOP ;1 CALL WAIT_05US ; 0.5usec XORWF PORTB,F ;0 CALL WAIT_05US ; 0.5usec NOP ;1 CALL WAIT_05US ; 0.5usec NOP ;1 NOP ;WAIT NOP ;WAIT RETURN BIT_1100 MOVLW b'00000011' ;SWITCH NOP ;1 CALL WAIT_05US ; 0.5usec NOP ;1 CALL WAIT_05US ; 0.5usec XORWF PORTB,F ;0 CALL WAIT_05US ; 0.5usec XORWF PORTB,F ;0 NOP ;WAIT NOP ;WAIT RETURN BIT_1101 MOVLW b'00000011' ;SWITCH NOP ;1 CALL WAIT_05US ; 0.5usec NOP ;1 CALL WAIT_05US ; 0.5usec XORWF PORTB,F ;0 CALL WAIT_05US ; 0.5usec NOP ;1 NOP ;WAIT NOP ;WAIT RETURN BIT_1110 MOVLW b'00000011' ;SWITCH NOP ;1 CALL WAIT_05US ; 0.5usec NOP ;1 CALL WAIT_05US ; 0.5usec NOP ;1 CALL WAIT_05US ; 0.5usec XORWF PORTB,F ;0 NOP ;WAIT NOP ;WAIT RETURN BIT_1111 MOVLW b'00000011' ;SWITCH NOP ;1 CALL WAIT_05US ; 0.5usec NOP ;1 CALL WAIT_05US ; 0.5usec NOP ;1 CALL WAIT_05US ; 0.5usec NOP ;1 NOP ;WAIT NOP ;WAIT RETURN ;----------------------------------------------------------------------------------------- ;ウェイト ; WAIT_02US RETURN WAIT_05US NOP NOP NOP RETURN WAIT_2US CALL WAIT_05US ; 0.5usec CALL WAIT_05US ; 0.5usec CALL WAIT_05US ; 0.5usec RETURN ;----------------------------------------------------------------------------------------- ;1mS wait ; 1mS = 50μS x 20 ; CNT1mS wait1ms MOVLW d'20' MOVWF CNT1mS wait1ms_loop CALL wait50us DECFSZ CNT1mS,F GOTO wait1ms_loop RETURN ;----------------------------------------------------------------------------------------- ;50μS wait ; 1サイクル(4クロック):0.2μS (20MHz) 0.5μS (8MHz) ; 50μS = 0.2μS x (3x81 + 4) 250サイクル ; 50μS = 0.5μS x (3x31 + 4) 100サイクル ; CNT_50uS wait50us MOVLW d'198' ;1 MOVWF CNT50uS ;1 DECFSZ CNT50uS,F ;1 GOTO $-1 ;2 RETURN ;2+1 END ;-----------------------------------------------------------------------------------------