--- a/dmx.s Mon Jun 02 18:27:08 2014 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,264 +0,0 @@
-;;; vim: set ft=avr:
-
-.nolist
-.include "m168def.inc" ; Same family as 328P
-.list
-
-.include "macros.inc"
-
-;; Interrupt Vector
-.cseg
-.org 0x0000
- rjmp Main
-
-
-;; CPU cycles / second: 16 Mhz
-.set CPU_CYCLES = 16 * 1000 * 1000
-
-;; Delays
-.include "delay.inc"
-
-;; DMX baud raite: 250k
-.set DMX_BAUD = 250 * 1000
-
-;; CPU cycles / bit: 64
-.set DMX_CYCLES = CPU_CYCLES / DMX_BAUD
-
-;; DMX output I/O
-.set DMX_DDR = DDRB
-.set DMX_PORT = PORTB
-.equ DMX_DATA = PORTB3
-
-;; DMX protocol timer
-; Registers
-.set DMX_TIMER_CRA = TCCR2A
-.set DMX_TIMER_CRB = TCCR2B
-.set DMX_TIMER_CNT = TCNT2
-.set DMX_TIMER_OCRA = OCR2A
-.set DMX_TIMER_OCRB = OCR2B
-.set DMX_TIMER_IMSK = TIMSK2
-.set DMX_TIMER_IFR = TIFR2
-
-; Compare output match isn't used
-.set DMX_TIMER_COMA = 0b00
-.set DMX_TIMER_COMB = 0b00
-
-; Control register, generation mode value
-.set DMX_TIMER_WGM_10 = 0b10 ; CTC
-.set DMX_TIMER_WGM_2 = 0b0
-
-; Clock select
-.set DMX_TIMER_CS_STOP = 0b000
-.set DMX_TIMER_CS = 0b001 ; 1/1
-;.set DMX_TIMER_CS = 0b111 ; 1/1024
-
-; Counted value
-.set DMX_TIMER_TOP = DMX_CYCLES ; number of cycles for baud
-
-;; Debug LED
-.set LED_DDR = DDRB
-.set LED_PORT = PORTB
-.set LED_PIN = PINB
-.set LED_BIT = PORTB0
-
-;; Set up DMX output
-DMX_Init:
- ; Setup output port
- ; out
- sbi DMX_DDR, DMX_DATA
-
- ; drive high
- sbi DMX_PORT, DMX_DATA
-
- ; Setup timer
- ; setup CTC mode with no output pins
- poke [DMX_TIMER_CRA, r16, (DMX_TIMER_COMA << COM2A0) | (DMX_TIMER_COMB << COM2B0) | (DMX_TIMER_WGM_10 << WGM20)]
- poke [DMX_TIMER_CRB, r16, (DMX_TIMER_WGM_2 << WGM22) | (DMX_TIMER_CS_STOP << CS20)]
-
- ; trigger threshold for CTC
- poke [DMX_TIMER_OCRA, r16, (DMX_TIMER_TOP)]
-
- ; OK
- ret
-
-;; Start Break signal
-;;
-;; 22 bits - 1s long; then DMX_Break_Mark
-;;
-DMX_Break_Start:
- ; Low
- cbi DMX_PORT, DMX_DATA
-
- ret
-
-;; Start Mark-after-break signal
-;;
-;; 2 bits - 1s long; then DMX_Break_End
-;;
-DMX_Break_Mark:
- ; High
- sbi DMX_PORT, DMX_DATA
-
- ret
-
-;; End break; prepare for DMX_Frame
-DMX_Frame_Start:
- ; Start timer
- poke [DMX_TIMER_CRB, r20, (DMX_TIMER_WGM_2 << WGM22) | (DMX_TIMER_CS << CS20)]
-
- ret
-
-;; Do a full DMX break, using some random length
-;;
-DMX_Break:
- ; Break
- ; start
- rcall DMX_Break_Start
-
- ; wait; about 100ms?
- ldi r20, 82 / 10
- rcall VarDelay
-
- ; MAB
- ; mark
- rcall DMX_Break_Mark
-
- ; short wait
- ldi r20, 1
- rcall VarDelay
-
- ; Timed frames
- ; start frame
- rcall DMX_Frame_Start
-
- ; ok
- ret
-
-;; Bitbang one DMX bit out
-;; uses SREG/C to send
-;
-; Uses Timer2 as a bit sync clock, sending out the next bit once we've hit 64 cycles on the timer
-DMX_Bit:
- ; Wait for bit sync clock
-_dmx_bit_wait:
- ; test OCA hit
- sbic TIFR2, OCF2A
- rjmp _dmx_bit_wait
-
-;sbi LED_PORT, LED_BIT
-
- ; Output bit
- ; XXX: ugly bit-testing, can't we do this using something more nifty?
- brcs _dmx_bit_1
-
- ; bit 0
- cbi DMX_PORT, DMX_DATA
- rjmp _dmx_bit_done
-
-_dmx_bit_1:
- ; bit 1
- sbi DMX_PORT, DMX_DATA
- nop
-
- ; Bit sent
-_dmx_bit_done:
- ; reset OCA hit for next bit
- cbi TIFR2, OCF2A
-
- ; OK, bit sync clock keeps running for next bit
- ret
-
-;; Bitbang one DMX byte out, using DMX_Bit
-;; r16: byte value
-;
-; Uses Timer2 as a bit sync clock; must call DMX_Frame_Start before first DMX_Frame
-DMX_Frame:
- ; Start bit
- clc
- rcall DMX_Bit
-
- ; Data bits: 8
- ldi r21, 8
-
-_dmx_frame_loop:
- ; shift + send bit
- lsl r16
- rcall DMX_Bit
-
- ; loop
- dec r21
- brne _dmx_frame_loop
-
- ; Stop bits
- sec
- rcall DMX_Bit
- rcall DMX_Bit
-
- ; OK
- ret
-
-;; End of DMX frames
-DMX_Frame_End:
- ; Keep mark from end of last frame; DMX_Break_Start starts the break
- ; Stop the timer
- poke [DMX_TIMER_CRB, r20, (DMX_TIMER_WGM_2 << WGM22) | (DMX_TIMER_CS_STOP << CS20)]
-
- ; OK
- ret
-
-;; Send one value on all frames
-;; r17: byte value
-DMX_Flood:
- ; Break
- rcall DMX_Break
-
- ; Start code
- ldi r16, 0
- rcall DMX_Frame
-
- ; Channels
- ; number of channels to send
- ldi r22, 100
-
-_dmx_flood_channels:
- ; restore channel value
- mov r16, r17
-
- ; send channel value
- rcall DMX_Frame
-
- ; loop
- dec r22
- brne _dmx_flood_channels
-
- ; End packet
- rcall DMX_Frame_End
-
-
- ret
-
-;; Program main
-Main:
-; Initialization
- ; Debug
- sbi LED_DDR, LED_BIT
-sbi LED_PORT, LED_BIT
-
- ; Stack
- poke [SPL, r16:r17, RAMEND]
-
- ; Init
- rcall DMX_Init
-
-cbi LED_PORT, LED_BIT
-
- ; Send; value
-_main_loop:
- ldi r17, 255
- rcall DMX_Flood
-
-cbi LED_PORT, LED_BIT
-
- ; never returns..
- rjmp _main_loop
-