?? transmitter.asm
字號:
; ================================================================================================
; PROJECT: SnesHack - A wireless/Wii-enabled SNES controller hack.
; FILENAME: Transmitter.asm
; DESCRIPTION: Code for the 16F84A firmware in the SNES controller.
; COPYRIGHT: Copyright (c) 2007 Mark Feldman. All Rights Reserved.
; ================================================================================================
list p=16F84A
radix hex
#include "C:\Program Files\Microchip\MPASM Suite\p16f84a.inc"
__config _HS_OSC & _PWRTE_OFF & _WDT_ON & _CP_OFF
; ================================================================================================
; constants
; ================================================================================================
NUM_BUTTONS equ 0Ch
; clocks the data out of the controller
CLOCK_PORT equ PORTB
CLOCK_BIT equ 0
; signals the controller to latch all button states
LATCH_PORT equ PORTB
LATCH_BIT equ 1
; reads the clocked data from the controller
DATA_PORT equ PORTB
DATA_BIT equ 2
; sends a packet of button press data to the transmitter chip
WIRELESS_PORT equ PORTA
WIRELESS_BIT equ 1
; ================================================================================================
; variables
; ================================================================================================
TIMER1 equ 0Ch ; misc variables used by the routines
TIMER2 equ 0Dh
CURBIT equ 0Eh
START_BIT equ 0Fh ; this must be on an odd address to assist ASK-friendly encoding
BUTTON_BITS equ (START_BIT+1)
STOP_BIT equ (BUTTON_BITS+NUM_BUTTONS)
org 0000h
; ================================================================================================
; entry point - performs initialization
; ================================================================================================
start
bsf STATUS, RP0 ; select bank 1
bcf WIRELESS_PORT, WIRELESS_BIT ; wireless bit is an output
bcf LATCH_PORT, LATCH_BIT ; latch bit is an output
bcf CLOCK_PORT, CLOCK_BIT ; clock bit is an output
bsf DATA_PORT, DATA_BIT ; data bit is an input
bcf STATUS, RP0 ; select bank 0
clrf START_BIT ; set packet start bit to 0 (gets negated during output)
clrf STOP_BIT ; set packet stop bit to 1 (doesn't get negated during output)
bsf STOP_BIT, WIRELESS_BIT
bcf LATCH_PORT, LATCH_BIT ; default latch state is 0
bsf CLOCK_PORT, CLOCK_BIT ; default clock state is 1
bcf WIRELESS_PORT, WIRELESS_BIT ; default wireless state is 0
main_loop
; read the button states from the controller
bsf LATCH_PORT, LATCH_BIT ; latch = 1 maintain for 12us
movlw 2
call delay
bcf LATCH_PORT, LATCH_BIT ; latch = 0 maintain for 6us
movlw BUTTON_BITS ; point FSR to the location of the button states array
movwf FSR
movlw NUM_BUTTONS ; set up the bit counter
movwf CURBIT
nop
read_loop
bcf CLOCK_PORT, CLOCK_BIT ; clock = 0, maintain for 6uS
clrf INDF ; clear destination bit
btfss DATA_PORT, DATA_BIT ; read the button state, is it a 0?
bsf INDF, WIRELESS_BIT ; if yes then set destination bit
nop
incf FSR, F ; move the array ptr to the next entry
bsf CLOCK_PORT, CLOCK_BIT ; clock = 1, maintain for 6uS
nop
nop
decfsz CURBIT, F ; any more bits to read?
goto read_loop ; yep, so loop back
; send the packet to the transmitter
transmit_packet
movlw START_BIT ; point FSR to the location of the button states
movwf FSR
movlw NUM_BUTTONS+2 ; 1 start bit + 12 data bits + 1 stop bit
movwf CURBIT
send_loop
movfw WIRELESS_PORT ; grab the port state
andlw ~(1 << WIRELESS_BIT) ; clear the send bit
iorwf INDF, W ; move the bit from the buffer into W
btfsc FSR, 0 ; change polarity of each bit for ASK-friendly encoding
xorlw 1 << WIRELESS_BIT
movwf PORTA ; send it to the transmitter
incf FSR, F ; move to the next position
movlw 4Eh ; hard-coded delay to help pad the pulse out to 250 cycles
call delay ; keep the line like this for the duration of the pulse
nop
decfsz CURBIT, F ; any more bits to send?
goto send_loop ; yep, so loop back
bcf WIRELESS_PORT, WIRELESS_BIT ; pad the 3.5mS between packets with 0s
; the length of the wireless packet is exactly 3.5ms/3500 cycles, so we now need to pad it out with enough
; 0s to make the main loop exactly 7ms/7000 cycles. i would have liked to put the chip to sleep for this
; to save power, but clock interrupts are disabled during sleep :(
pause
movlw 0ffh
call delay
movlw 0ffh
call delay
movlw 0ffh
call delay
movlw 0ffh
call delay
movlw 052h
call delay
nop
clrwdt ; let the watchdog timer know I'm still awake
goto main_loop ; all done
; this routine causes a delay of (4 + W * 3) instructions (ie. uS), including the call here and the return
delay movwf TIMER1
dloop decfsz TIMER1,f
goto dloop
return
end
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -