I found this asm code for a pic and I need code that does the same thing for a mega8 in C. Can anyone translate?
;
; IR Widget Firmware
;
; Copyright (C) 2007, 2008 Kevin Timmerman
; irwidget [@t] compendiumarcana [d0t] com
; http://www.compendiumarcana.com/irwidget
;
; This program is free software; you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation; either version 3 of the License, or
; (at your option) any later version.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with this program. If not, see <http://www.gnu.org/licenses/>.
;
;
; Version History
;----------------
; Rev 0
; 2006-10-19
; First release
;
; Rev 1
; 2007-01-08
; Added support for using an IR LED as a IR detector. The comparator is used,
; so the I/O changes a bit when this option is enabled. (#define LED_DET)
; Changed 19200 bps rate for compat time mode, now 57600
; Added support for host control of sending on and off times in time mode (was a #define option)
; Count mode trasmission will not start until the first IR pulse is received
;
; Rev 2
; 2007-01-11
; Count mode can be stopped and restarted under host control
;
; Rev 3
; 2007-08-18
; -> Uses revision 2 schematic and PCB <-
; Support for PICs other than 12F629/675 removed
; Support for compatibility with 74HC circuits removed
; Time capture is now 15 bits with 16 uS resolution sent at 115 kbps
; Default time capture mode is rising and falling edge
; Autodetect QSE15x or LED
; Tx output pin changed to allow IR pulse detector autodetect
; Output reserved for wake-on-ring
;
; Rev 4
; 2008-08-15
; Suppoort for use of FTDI232 USB to serial converter chip (inverted I/O, reset pin enabled)
; Status LED output
; License change to GPLv3
;
;#define HW_USB ; Define this for USB version only!
#ifdef __12F629
include <P12F629.INC>
#define CORE14
#define FIRSTREG 0x20
#define PGMSIZE 1024
#endif
#ifdef __12F675
include <P12F675.INC>
#define CORE14
#define FIRSTREG 0x20
#define PGMSIZE 1024
#endif
; Configuration bits
#ifdef HW_USB
__config _CPD_OFF & _CP_OFF & _BODEN_ON & _MCLRE_ON & _PWRTE_ON & _WDT_ON & _INTRC_OSC_NOCLKOUT
#else
__config _CPD_OFF & _CP_OFF & _BODEN_ON & _MCLRE_OFF & _PWRTE_ON & _WDT_ON & _INTRC_OSC_NOCLKOUT
;__config _CPD_OFF & _CP_OFF & _BODEN_ON & _MCLRE_OFF & _PWRTE_ON & _WDT_ON & _INTRC_OSC_CLKOUT ; For testing internal osc freq only
#endif
errorlevel -220 ; Stupid MPLAB complains about IDLOCS
org 0x2000 ; IDLOCS
dw 'I','R','W','4' ; IR Widget Rev 4
errorlevel +220
BANK1 equ 0x80 ; Reduce assembler whining
radix dec ; Default radix of decimal
; --- I/O
; 8 Ground
;
bSerTx equ 0 ; 7 Serial data to host PC
pSerTx equ GPIO ;
#ifdef HW_USB ;
bOpMode equ 1 ; 6 Operational Mode (RTS) [USB]
pOpMode equ GPIO ;
#else ;
bLED equ 1 ; 6 IR LED input [Serial]
pLED equ GPIO ;
#endif ;
bIRDetect equ 2 ; 5 IR Detector module (QSE15x) input and
pIRDetect equ GPIO ; comparator output (-> TMR0 input)
;
; 4 Reset (DTR) [USB]
#ifndef HW_USB ;
bOpMode equ 3 ; 4 Operational Mode (RTS) [Serial]
pOpMode equ GPIO ;
#endif ;
bStatus equ 4 ; 3 Status LED output (RI)
pStatus equ GPIO ;
;
bIRDemod equ 5 ; 2 IR Demodulator module input
pIRDemod equ GPIO ;
;
; 1 Power
;
cblock FIRSTREG ; Registers
time_h
time_l
prev_time_h
prev_time_l
prev_count
flags
temp1
endc
fEdge equ 0 ; IR Demod edge flag bit
org 0x0000 ; - Start of program memory
nop ;
#ifdef HW_USB ;
movlw (1<<bStatus) | (1<<bSerTx) ; Idle outputs
movwf GPIO ;
#else ;
clrf GPIO ; All outputs off
#endif ;
goto skip_isr ; Jump over the ISR
;
org 0x0004 ; - ISR
goto $ ; Let the watchdog handle this
;
;
skip_isr ;
; - Initiailize peripherals
;
movlw (1<<CM0) | (1<<CM1) | (1<<CM2) ; Disable comparator
movwf CMCON ;
;
call PGMSIZE-1 ; Get OSCCAL
;
bsf STATUS,RP0 ; Bank 1
;
movwf OSCCAL ^ BANK1 ; Setup OSCCAL
;
#ifdef ANSEL ;
movlw (1<<ADCS0) | (1<<ADCS2) ; Make all pins digital I/O
movwf ANSEL ^ BANK1 ;
#endif ;
;
#ifdef HW_USB ;
movlw (1<<bIRDetect) | (1<<bOpMode) | (1<<bIRDemod) ; Setup TRIS
#else ;
movlw (1<<bLED) | (1<<bIRDetect) | (1<<bOpMode) | (1<<bIRDemod) ; Setup TRIS
#endif ;
movwf TRISIO ^ BANK1 ;
;
errorlevel -219 ;
movwf WPU ^ BANK1 ; Setup WPU
errorlevel +219 ;
;
; *GPPU = 0 - WPU enabled
; INTEDG = 0
; T0CS = 0 - Internal clock source
; T0SE = 0 - Inc on rising edge
; PSA = 0 - Assign prescaller to TMR0
; PSx - Prescaler = 1:16 (16 uS)
movlw (1<<PS1) | (1<<PS0) ;
movwf OPTION_REG ^ BANK1 ;
;
#ifdef HW_USB ;
bcf STATUS,RP0 ; Bank 0
;
; Check operational mode
btfsc pOpMode,bOpMode ;
goto irw_count ; Pulse count mode...
; ...else pulse time mode...
#else ;
; Setup voltage ref for LED IR detector
movlw (1<<VREN) | (1<<VRR) | (1<<VR0) ; 1 / 24 * Vdd (~200 mV)
movwf VRCON ^ BANK1 ;
;
bcf STATUS,RP0 ; Bank 0
;
;
btfsc pLED,bLED ; Check if LED is present
goto noled ; No...
;
movlw (1<<CM0) | (1<<CM1) ; Enable comparator with internal ref and out -> GP2 (TMR0 ext in)
movwf CMCON ;
noled ;
; Check operational mode
btfss pOpMode,bOpMode ;
goto irw_count ; Pulse count mode...
; ...else pulse time mode...
#endif ;
;
;
; ----- Pulse time capture -----
;
; - Initialize registers
;
bcf flags,fEdge ; Start with falling edge
clrf prev_time_h ; Init previous pulse time
clrf prev_time_l ;
clrf time_h ; Init current time
clrf TMR0 ;
;
ptloop ;
btfsc flags,fEdge ;
goto ptwr ;
;
ptwf ; - Wait for falling edge
clrwdt ; Prevent watchdog timeout while waiting
btfss pIRDemod,bIRDemod ; Check IR demodulator output level
goto ptfe ; Low, capture time...
btfss INTCON,T0IF ; Check for TMR0 overflow
goto ptwf ; No overflow, loop...
incf time_h,F ; Increment time high byte
bcf INTCON,T0IF ; Clear TMR0 interrupt flag
goto ptwf ; Loop...
;
ptfe ;
#ifdef HW_USB ;
bcf pStatus,bStatus ; Turn on status LED
#else ;
bsf pStatus,bStatus ; Turn on status LED
#endif ;
goto ptcap ;
;
ptwr ; - Wait for rising edge
clrwdt ; Prevent watchdog timeout while waiting
btfsc pIRDemod,bIRDemod ; Check IR demodulator output level
goto ptre ; High, check if capture required...
btfss INTCON,T0IF ; Check for TMR0 overflow
goto ptwr ; No overflow, loop...
incf time_h,F ; Increment time high byte
bcf INTCON,T0IF ; Clear TMR0 interrupt flag
goto ptwr ; Loop...
;
ptre ;
#ifdef HW_USB ;
bsf pStatus,bStatus ; Turn off status LED
btfsc pOpMode,bOpMode ; Only send on and off time if RTS is high
#else ;
bcf pStatus,bStatus ; Turn off status LED
btfss pOpMode,bOpMode ; Only send on and off time if RTS is high
#endif ;
goto ptedge ; Not wanted, skip calcutlation and trasmission...
;
ptcap ; - Capture current time
movf TMR0,W ; Get TMR0 value
movwf time_l ; Save it
btfss time_l,7 ; If not a low value, no need to check for TMR0 overflow...
btfss INTCON,T0IF ; It is zero, so check for overflow
; This is necessary because TMR0 may have oveflowed
; between the time it was last checked and the time it
; was read. It will be zero if that has happened.
goto ptcno ; Skip overflow code
incf time_h,F ; Increment time high byte
bcf INTCON,T0IF ; Clear TMR0 interrupt flag
ptcno ;
; - Send elapsed time to host
movf prev_time_l,W ; Get previous time low byte
subwf time_l,W ; Subtract last time from current time
; W now holds elapsed time
btfss STATUS,C ; Adjust time high byte for borrow
incf prev_time_h,F ; time_h must not be changed, so adjust prev_time_h instead
call tx115 ; Send elapsed time low byte to host
;
movf prev_time_h,W ; Get previous time high byte
subwf time_h,W ; Subtract last time from current time
andlw 0x7F ; Assume falling edge, clear msb
btfsc flags,fEdge ; Check edge flag, skip next if falling edge
iorlw 0x80 ; Rising edge, set msb
call tx115 ; Send elapsed time high byte to host
;
movf time_l,W ; Update previous time
movwf prev_time_l ;
movf time_h,W ;
movwf prev_time_h ;
;
ptedge ;
movlw 1<<fEdge ; Toggle edge
xorwf flags,F ;
;
goto ptloop ; Loop...
;
;
;
; ----- Pulse count capture ------
;
;
irw_count ; - Change the TMR0 clock from internal to external. This
; must be done as specified in the data sheet to avoid
; false trigger of the watchdog timer.
;
clrwdt ;
clrf TMR0 ;
bsf STATUS,RP0 ; Bank 1
;
movlw (1<<T0CS) | (1<<T0SE) | (1<<PSA) | 7 ;
movwf OPTION_REG ^ BANK1 ;
clrwdt ;
; *GPPU = 0 - WPU enabled
; INTEDG = 0
; T0CS = 1 - External clock source
; T0SE = 1 - Inc on falling edge
; PSA = 1 - Assign prescaller to WDT
; PSx - Prescaler = 0 (1:1)
movlw (1<<T0CS) | (1<<T0SE) | (1<<PSA) ;
movwf OPTION_REG ^ BANK1 ;
;
bcf STATUS,RP0 ; Bank 0
;
ircw ; - Wait for the host signal to proceed
clrwdt ;
#ifdef HW_USB ;
btfsc pOpMode,bOpMode ;
#else ;
btfss pOpMode,bOpMode ;
#endif ;
goto ircw ;
;
clrf TMR0 ; - Wait for first IR pulse
clrf prev_count ;
irpw ;
clrwdt ;
movf TMR0,W ;
btfsc STATUS,Z ;
goto irpw ;
movlw 0 ;
goto spc ;
;
; --- Count pulses and send to host every 100 microseconds ---
ircl ;
clrwdt ; 1
movf TMR0,W ; 2 Get pulse count
spc ;
movwf temp1 ; 3 Save pulse count
xorwf prev_count,F ; 4 Compare to previous pulse count
movwf prev_count ; 5 Update previouse pulse count
#ifdef HW_USB ;
btfss STATUS,Z ; 6 Count has changed...
bcf pStatus,bStatus ; 7 turn on status LED
btfsc STATUS,Z ; 8 Count has not changed...
bsf pStatus,bStatus ; 9 turn off status LED
#else ;
btfss STATUS,Z ; 6 Count has changed...
bsf pStatus,bStatus ; 7 turn on status LED
btfsc STATUS,Z ; 8 Count has not changed...
bcf pStatus,bStatus ; 9 turn off status LED
#endif ;
;
call tx115 ; 10 Send pulse count to host
;
nop ; 96
nop ; 97
;
#ifdef HW_USB ;
btfss pOpMode,bOpMode ; 98 Continue until host says stop...
#else ;
btfsc pOpMode,bOpMode ; 98 Continue until host says stop...
#endif ;
goto ircl ; 99,100
;
goto ircw ; Restart count mode...
;
;
;
; --- Async 115 kbps transmission ---
;
; - Macros for 4 and 5 cycle delays used for serial
; tx timing
;
delay4 macro ; 4 cycle delay call
call dly4 ;
endm ;
delay5 macro ; 4 cycle delay call
call dly5 ;
endm ;
;
#ifdef HW_USB ;
#define TXHIGH andlw ~(1<<bSerTx) ;
#define TXLOW iorlw (1<<bSerTx) ;
#else ;
#define TXHIGH iorlw (1<<bSerTx) ;
#define TXLOW andlw ~(1<<bSerTx) ;
#endif ;
;
sendbit macro reg, bit ; Macro to send a bit
; 4 cycles
TXLOW ; 1 Assume bit is a 1, drive output low - tx data is inverted
btfss reg,bit ; 2 Test it
TXHIGH ; 3 It is a 1, not zero, drive output high
movwf pSerTx ; 4 Update output
endm ;
;
; 115200 bps bit times
; 0.00 8.68 17.36 26.04 34.72
; 43.40 52.08 60.76 69.44 78.13
tx115 ;
movwf temp1 ;
movf pSerTx,W ; Get port output latch
TXHIGH ; Start bit - high
movwf pSerTx ; 0
delay5 ; 1-5
sendbit temp1,0 ; 6-9 Bit 0
delay4 ; 10-13
sendbit temp1,1 ; 14-17 Bit 1
delay5 ; 18-22
sendbit temp1,2 ; 23-26 Bit 2
delay5 ; 27-31
sendbit temp1,3 ; 32-35 Bit 3
delay4 ; 36-39
sendbit temp1,4 ; 40-43 Bit 4
delay5 ; 44-48
sendbit temp1,5 ; 49-52 Bit 5
delay5 ; 53-57
sendbit temp1,6 ; 58-61 Bit 6
delay4 ; 62-65
sendbit temp1,7 ; 66-69 Bit 7
delay5 ; 70-74
goto $+1 ; 75,76
TXLOW ; 77 Stop bit - low
movwf pSerTx ; 78
return ;
;
dly5 ; 5 cycle delay subroutine
nop ;
dly4 ; 4 cycle delay subroutine
return ;
;
;
end ;
;