; ******************************************* ; ** 64 Channel Serial Servo Controller ** ; ** For ATtiny2313 ** ; ** Version 3.0 ** ; ** ** ; ** Copyright (c) July 2009 ** ; ** Len Holgate ** ; ** ** ; ** Note that this controller assumes ** ; ** that we have CD74HCT238E or equivalent** ; ** demultiplexor chips connected to the ** ; ** outputs of PortB and that the required** ; ** address lines for these MUXs are run ** ; ** from pins 3-5 of PortD. ** ; ******************************************* .nolist .include "tn2313def.inc" .list .def temp = r0 .def temp1 = r1 .def temp2 = r2 .def count = r16 .def index = r17 .def bankIndex = r19 .def temp20 = r20 .def temp21 = r21 .def resl = r22 .def resh = r23 .def muxAddress = r24 .def serialChar = r25 .equ POSITION_DATA_START = SRAM_START .equ NUM_SERVOS = 64 .equ PWM_DATA_START = POSITION_DATA_START + NUM_SERVOS .equ PWM_SERVOS_PER_CYCLE = 8 .equ PWM_BYTES_PER_SERVO = 3 .equ PWM_DATA_SIZE = (PWM_SERVOS_PER_CYCLE + 1) * PWM_BYTES_PER_SERVO .equ SERIAL_DATA_START = PWM_DATA_START + PWM_DATA_SIZE .equ SERIAL_DATA_LENGTH = 2 .equ SERIAL_DATA_END = SERIAL_DATA_START + SERIAL_DATA_LENGTH .equ JUMP_TABLE_START = $0012 .equ clock = 7372800 .equ baudrate = 9600 .equ baudconstant = (clock/(16*baudrate))-1 .ORG $0000 rjmp Init ; Reset reti ; INT0 Interrupt reti ; INT1 Interrupt reti ; TC1Capt Interrupt rjmp TC1CmpA ; Timer 1 Compare A match reti ; TC1 Overflow Int reti ; TC0 Overflow Int reti ; UART0 RX Int reti ; UART0 TX Int reti ; Ana Comp Int reti ; PCINT reti ; TC1 CompB Int reti ; TC0 Compare Match A Int reti ; TC0 Compare Match B Int reti ; USISTART Int reti ; USIOverflow Int reti ; EERDY Int reti ; WDT Overflow Int .ORG JUMP_TABLE_START rjmp PWMSetup rjmp PWMPulseStop ; Timer 1 interrupt for CTC timer TC1CmpA: push temp20 ; save the state of these as they are used by the serial protocol code push temp21 in temp20, SREG ; save status register push temp20 ijmp ; Z is set up to point into our jump table (above) so we jump to Z then ; jump to the correct state for our timer handling... TC1CmpAEnd : pop temp20 ; restore the state prior to the interrupt out SREG, temp20 pop temp21 pop temp20 reti ; Program start Init: ; Set stack pointer - we use the stack for the return address of the interrupt handler... ldi temp20, RAMEND out SPL, temp20 ; Set up the serial port ldi temp20, HIGH(baudconstant) ; Set the baud rate out UBRRH, temp20 ldi temp20, LOW(baudconstant) out UBRRL, temp20 ldi temp20, (1 << RXEN) | (1 << TXEN) ; enable rx and tx out UCSRB, temp20 ldi temp20, (3 << UCSZ0) ; 8N1 ; Initialise Timer1 in CTC mode ldi temp20, HIGH(200) ; CTC-value - something low to kick us off... Must be longer out OCR1AH, temp20 ; than it takes for us to finish our initialisation... ldi temp20, LOW(200) ; Note that the 16-bit timer control registers MUST be written out OCR1AL, temp20 ; high byte first then low byte as the low write triggers the ; 16-bit atomic write. clr temp20 ; Controlword A 0x0000 out TCCR1A, temp20 ldi temp20, (1<