📄 ipodtest-g3.asm
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!-- saved from url=(0061)http://www.maushammer.com/systems/ipod-remote/ipodtest-g3.asm -->
<HTML><HEAD>
<META http-equiv=Content-Type content="text/html; charset=gb2312">
<META content="MSHTML 6.00.2900.3132" name=GENERATOR></HEAD>
<BODY><PRE>;***************************************************************************
;*
;* G3 iPod test application
;*
;* Copyright 2004, John Maushammer. Released under GPL license.
;* http://www.maushammer.com/systems/ipod-remote/ipod-remote.html
;*
;***************************************************************************
;*
;* Target: ATtiny12-8PI
;* +---v---+
;* pull high -> reset/PB5|1 8|vcc
;* rev button -> PB3|2 7|PB2 <-- output to ipod
;* fwd button -> PB4|3 6|PB1 not used
;* gnd|4 5|PB0 not used
;* +-------+
;*
;* Buttons are pulled high by internal pullups; connect inputs through
;* normally open switches to ground. Output goes to VCC - if using a
;* VCC=+3.3v, then protect the ipod with a 1k ohm resistor. If using a
;* VCC=+5v, then you must use a divider to bring down the voltage and
;* provide a high output impedence.
;*
;* Internal oscillator @ 1.2MHz
;*
;* Program with: stk500 -dATTINY12 -iftest.hex -O -e -pf -vf -Sf3ff
;* (stores osc cal value at last byte in memory)
;*
;***************************************************************************
.include "tn12def.inc"
;***** Pin definitions
.equ ipodTx =2 ;Transmit pin is PB2
.equ btnRev =3 ;reverse button PB3
.equ btnFwd =4 ;forward button PB4 (normally high, pulled low)
;***** Global register variables
.def temp =R16 ;temporary storage register
.def temp2 =R17
.def bitcnt =R18 ;bit counter
.def TXipod1 =R19 ;first variable byte of message
.def TXipod2 =R20 ;checksum
;***** OSCCAL value set by programmer
.equ osccal_value =$1ff ;last byte of memory
.cseg
.org 0 ;interrupt table:
rjmp reset
rjmp ext_int0
rjmp pin_change ;pin change
rjmp tim0_ovf ;timer
rjmp ee_rdy ;eeprom ready
rjmp ana_comp ;comparator
;***** Program Execution Starts Here
reset: ldi ZH, high((osccal_value<<1)+1) ;get value set by programmer
ldi ZL, low((osccal_value<<1)+1)
lpm ; R0<-(Z)
out OSCCAL, R0
ldi temp, 0b00000110 ; 1=out
out DDRB, temp
ldi temp, 0b00011000 ; pull up buttons (PB3 & 4)
out PORTB, temp
;***************************************************************************
;* Main loop
;*
;***************************************************************************
;***************************************************************************
;*
;* G3 iPod remote control application
;*
;* Warning: uses all 3 stack levels: ipod_packet> putchar > delay
main_loop: sbis PINB,btnFwd ;if button not pressed, skip
rjmp ipod_fwd
sbis PINB,btnRev
rjmp ipod_rev
; other button inputs would go here...
rjmp main_loop
ipod_fwd: ldi TXipod1, 0x10
ldi TXipod2, 0xeb
rcall ipod_packet
sbis PINB,btnFwd ;if button not pressed, skip out of loop
rjmp ipod_fwd
rjmp ipod_rel
ipod_rev: ldi TXipod1, 0x08
ldi TXipod2, 0xf3
rcall ipod_packet
sbis PINB,btnRev ;if button not pressed, skip out of loop
rjmp ipod_rev2
rjmp ipod_rel
ipod_rel: ldi TXipod1, 0x00 ;button release code
ldi TXipod2, 0xfb
rcall ipod_packet
rjmp main_loop
;***************************************************************************
;* Unused interrupts
;* shouldn't be called, but if they are, then we'll know it.
;***************************************************************************
ext_int0:
pin_change:
tim0_ovf:
ee_rdy:
ana_comp:
;***************************************************************************
;*
;* oscillator output test function. A not-quite symetrical square wave.
;*
;* For the tested chip, the correct OSCCAL value is $40
;*
;* OSCCAL=0/uncal: 149.83 --> RC osc = 1048.8 = -12.6%
;* OSCCAL=40: 172.43 1207 = + 1.0%
;* OSCCAL=80: 202.86 1420 = +18.3%
;* OSCCAL=FF: 315.80 2210.6 = +84.2%
;*
;***************************************************************************
osctest: sbi DDRB,TxD ;set direction
ot2: cbi PORTB,TxD ;send a '0' 2 cycles
; nop ; 1 cycle - this would make 50/50
nop ; 1 cycle
sbi PORTB,TxD ;send a '1' 2 cycles
rjmp ot2 ; 2 cycles
;***************************************************************************
;*
;* ipod putchar
;*
;* This subroutine transmits the byte stored in the "TXbyte" register
;*xxxx Rate is 9600 baud (=125 cycles/bit @ 1.2MHz) !!! from g2 spec!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
;* Rate is 19047 baud (=63 cycles/bit @ 1.2MHz)
;* (19200 is hard to do exactly because it is 62.5 cycles/bit)
;*
;* input: TXbyte
;* registers: bitcnt, TXbyte, temp
;* stack: one level (UART_delay)
;*
;***************************************************************************
iputchar: ldi bitcnt,10 ;1+8+1 stopbit
iputchar0: com TXbyte ;invert everything (so stop bits will be 1's)
sec ;start bit
; cycle count if carry set clr
; --- ---
iputchar1: brcc iputchar2 ;If carry set 1 2
cbi PORTB,ipodTx ; send a '0' 2
rjmp iputchar3 ;else 2
iputchar2: sbi PORTB,ipodTx ; send a '1' 2
nop ; 1
iputchar3: ldi temp,15 ; 1 1
rcall UART_delay ; 52 52
nop ; 1 1
nop ; 1 1
lsr TXbyte ;Get next bit 1 1
dec bitcnt ;If not all bit sent 1 1
brne iputchar1 ; send next 2 2
ret
;***************************************************************************
;*
;* G3 iPod output routine - ipod_packet
;*
;* Format: output normally low
;* | output high, 500 uSec
;* | output message @ 8N1, 9600 baud, lsb first
;* | output high 4 extra bits
;* loop| low for ~11.16 mSec
;*
;* VOL+ 0x55 0x03 0x02 0x00 0x02 0xE9
;* VOL- 0x55 0x03 0x02 0x00 0x04 0xF7
;* SKIP>> 0x55 0x03 0x02 0x00 0x10 0xEB
;* <<SKIP 0x55 0x03 0x02 0x00 0x08 0xF3
;* PLAY/PAUSE 0x55 0x03 0x02 0x00 0x01 0xFA
;* (button release) 0x55 0x03 0x02 0x00 0x00 0xFB
;*
;* input: TXipod1-2 has these bytes --------^^ ^^
;* stack: uses 2 stack locations (iputchar > UARTdelay)
;*
;***************************************************************************
ipod_packet: ldi TXbyte, 0x00 ; stop bits (inverted)
ldi bitcnt,10 ; send 10 stop bits (500uS)
rcall iputchar2 ; alternate entry doesn't have start bit
ldi TXbyte, 0x55
rcall iputchar
ldi TXbyte, 0x03
rcall iputchar
ldi TXbyte, 0x02
rcall iputchar
ldi TXbyte, 0x00
rcall iputchar
mov TXbyte, TXipod1
rcall iputchar
mov TXbyte, TXipod2
ldi bitcnt,14 ; 1+8+1 stopbit + 4 extra stop bits
rcall iputchar0
cbi PORTB,ipodTx ; bring back down to 0
ldi temp2,17 ; (774 + 3) * 17 = 13209 ~= 11 msec
ldi temp, 0
ipod_packet2: rcall UART_delay ; 256 * 3 + 6 = 774 clocks
dec temp2
brne ipod_packet2
ret
;***************************************************************************
;*
;* UART_delay
;*
;* This delay subroutine generates the required delay between the bits when
;* transmitting and receiving bytes. The total execution time is set by the
;* constant "b":
;*
;* 3穊 + 6 cycles (including rcall and ret)
;*
;* High registers used: temp
;*
;***************************************************************************
;3 cycles (rcall)
UART_delay: dec temp ;1 cycle
brne UART_delay1 ;2/1 cycles
ret ;4 cycles
</PRE></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -