; Reverse engineering tool for PLL ; in Uniden UH036SX UHF radio ; attempt2 ; ; Ross Whenmouth 2007 ; ; ATtiny2313 target ; Atmel ATtiny2313 ; pin 1 RESET ; pin 2 RXD (PD0) Serial port RX data ; pin 3 TXD (PD1) Serial port TX data ; pin 4 XTAL2 18.432 MHz XTAL ; pin 5 XTAL1 18.432 MHz XTAL ; pin 6 PD2 ***SPARE*** ; pin 7 PD3 ***SPARE*** ; pin 8 PD4 ***SPARE*** ; pin 9 PD5 select CLOCK valid on rising or falling edge (high = rising, low = falling) ; pin 10 GND 0V ; pin 11 PD6 ***SPARE*** ; pin 12 PB0 DATA in ; pin 13 PB1 CLOCK in ; pin 14 PB2 STROBE in ; pin 15 PB3 ***SPARE*** ; pin 16 PB4 ***SPARE*** ; pin 17 PB5/MOSI ***SPARE*** ; pin 18 PB6/MISO ***SPARE*** ; pin 19 PB7/SCK ***SPARE*** ; pin 20 VCC +5V .include "tn2313def.inc" ; Register aliasing ; =r0 ; register for LPM instruction .def OLD =r15 ; previous input .def NEW =r16 ; latest input .def buffi =r17 ; ring buffer input pointer .def buffo =r18 ; ring buffer output pointer .def A =r20 ; working register A .def B =r21 ; working register B .def C =r22 ; working register C .def BUFF_OVF =r27 ; buffer overflow flag ;.def YL =r28 ; Y pointer low byte buffer input pointer ;.def YH =r29 ; Y pointer high byte ;.def ZL =r30 ; Z pointer low byte buffer ouput pointer ;.def ZH =r31 ; Z pointer high byte ; SRAM Memory Map ; ; 0x60 - 0x9F 64 byte Stack ; 0xA0 - 0xDF 64 byte ring buffer .cseg .org 0 ; interrupt table rjmp RESET ; Reset Handler ; rjmp INT0 ; External Interrupt0 Handle ; rjmp INT1 ; External Interrupt1 Handle ; rjmp TIM1_CAPT ; Timer1 Capture Handler ; rjmp TIM1_COMPA ; Timer1 CompareA Handler ; rjmp TIM1_OVF ; Timer1 Overflow Handler ; rjmp TIM0_OVF ; Timer0 Overflow Handler ; rjmp USART0_RXC ; USART0 RX Complete Handler ; rjmp USART0_DRE ; USART0,UDR Empty Handler ; rjmp USART0_TXC ; USART0 TX Complete Handler ; rjmp ANA_COMP ; Analog Comparator Handler ; rjmp PCINT ; Pin Change Interrupt ; rjmp TIMER1_COMPB ; Timer1 Compare B Handler ; rjmp TIMER0_COMPA ; Timer0 Compare A Handler ; rjmp TIMER0_COMPB ; Timer0 Compare B Handler ; rjmp USI_START ; USI Start Handler ; rjmp USI_OVERFLOW ; USI Overflow Handler ; rjmp EE_READY ; EEPROM Ready Handler ; rjmp WDT_OVERFLOW ; Watchdog Overflow Handler RESET: ldi A, 0b10000000 ; disable the analogue comaparator to save power out ACSR, A ldi A, 0b00000000 out DDRB, A ; PortB & D are all inputs out DDRD, A ldi A, 0b11111111 out PORTB, A ; turn on pullups on PortB & D out PORTD, A ldi A, 0x9F ; point the stack pointer at the top of Stack out SPL, A ldi YL, 0xA0 ; point buffer input pointer at start of buffer ldi YH, 0 ; Initalise the serial port ldi A, 0 ; set UART speed to 115,200 bps out UBRRH, A ldi A, 9 out UBRRL, A ldi A, 0b00000110 ; set 8 data bits, no parity, 1 stop bit out UCSRC, A ldi A, 0b00001000 ; enable transmitter ;ldi A, 0b00011000 ; enable receiver and transmitter out UCSRB, A ldi ZL, 0xA0 ; point buffer output pointer at start of buffer ldi ZH, 0 MAIN: sbis UCSRA,UDRE ; see if serial port is ready to send a byte rjmp POLL ; if not, keep polling PortB ldi BUFF_OVF, 0 ; clear the overflow flag cp ZL, YL ; if ZL == YL, then buffer is empty breq POLL ; keep polling PortB ld A, Z+ ; put byte from buffer into A and post increment Z pointer out UDR, A ; send byte to the UART cpi ZL, 0xE0 ; if ZL is off the end of the buffer, reset it to the start of buffer brlo POLL ldi ZL, 0xA0 POLL: ; Look for state change on PortB in NEW, PINB ; poll PortB cp OLD, NEW breq MAIN ; if PortB has not changed state then keep polling mov A, NEW ; make a copy of NEW PortB state andi A, 0b00000111 ; mask out upper bits (we are interested in bits 0 - 2) ldi B, 0x30 add B, A ; convert bits to ASCII character from '0' to '7' rcall BUFF_IN ; put ASCII char in B into the TX buffer mov OLD, NEW ; OLD = NEW, so we can detect the next PortB state change rjmp MAIN BUFF_IN: sbrc BUFF_OVF, 0 ; if overflow flag set, return without putting data in buffer ret mov C, YL ; make a copy of pointer ZL to check for buffer overflow inc C inc C cpi C, 0xE0 ; if C is off the end of the buffer, reset it to the start of buffer brlo BUFF_IN_OVF ldi C, 0xA0 BUFF_IN_OVF: cpse C, ZL ; if C and ZL point to the same place, there is a buffer overflow! rjmp BUFF_IN_CHR ldi B, 0x21 ; stuff a "!" (ASCII 0x21) into the buffer so we know that there is an overflow ldi BUFF_OVF, 1 ; set the overflow flag BUFF_IN_CHR: st Y+, B ; put character in register B into the buffer with pointer post increment ldi C, 0xE0 ; if pointer has run off end of buffer then reset pointer to start of buffer cpse YL, C ret ; else return ldi YL, 0xA0 ret