dmx.s
author Tero Marttila <terom@fixme.fi>
Wed, 27 Jul 2011 01:46:27 +0300
changeset 45 7c684d241675
child 46 ffb0c3ec9bc0
permissions -rw-r--r--
dmx: initial try.. failed
;;; vim: set ft=avr:

.nolist
.include "m168def.inc"      ; Same family as 328P
.list


;; Interrupt Vector
.cseg
.org 0x0000
        rjmp        Main


;; CPU cycles / second: 16 Mhz
.set CPU_CYCLES = 16 * 1000 * 1000

;; DMX baud raite: 250k
.set DMX_BAUD = 250 * 1000

;; CPU cycles / bit: 64
.set DMX_CYCLES = CPU_CYCLES / DMX_BAUD

;; DMX output por
.set DMX_DDR = DDRB
.set DMX_PORT = PORTB
.equ DMX_DATA = PORTB3

;; Debug LED
.set LED_DDR = DDRB
.set LED_PORT = PORTB
.set LED_PIN = PINB
.set LED_BIT = PORTB5

;; Set up DMX output
DMX_Init:
    ; Setup output port
        ; out
        sbi     DMX_DDR, DMX_DATA

        ; drive high
        sbi     DMX_PORT, DMX_DATA

    ; OK
        ret

;; Bitbang one DMX bit out
;;  uses SREG/C to send
DMX_Bit:
    ; Output bit: 4 cycles
        brcs    _dmx_bit_1
        
        cbi     DMX_PORT, DMX_DATA
        rjmp    _dmx_bit_wait

_dmx_bit_1:
        sbi     DMX_PORT, DMX_DATA
        nop

_dmx_bit_wait:
    ; Wait: 60 cycles
        ; load: 1 cycle (offset by one less for brne)
        ldi     r20, 6

_dmx_bit_loop:
        ; waste 8 cycles
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop

        ; loop: 1 + 2/1 cycles
        ; 2/1 cycles
        dec     r20
        brne    _dmx_bit_loop
       
    ; OK
        ret

;; Break + MAB
DMX_Break:
    ; Break: 100 low bits
        ldi         r21, 100

_dmx_break_loop:
        ; bitbang zero
        clc
        rcall       DMX_Bit
        
        ; count
        dec         r21
        brne        _dmx_break_loop

    ; MAB: 4 high bits
        ldi         r21, 4

_dmx_break_mab:
        sec
        rcall       DMX_Bit

        ; loop
        dec         r21
        brne        _dmx_break_mab

    ; OK
        ret

;; Byte
;;  r16: byte value
DMX_Frame:
    ; Start bit
        sec
        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
        clc
        rcall       DMX_Bit
        rcall       DMX_Bit
    
    ; OK
        ret

;; Send one value on all frames, continuously
;;  r17: byte value
DMX_Flood:
_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

    ; OK; loop
;sbi         LED_PIN, LED_BIT
        rjmp        _dmx_flood


;; Program main
Main:
; Initialization
    ; Debug
        sbi         LED_DDR, LED_BIT
cbi         LED_PORT, LED_BIT

    ; Stack
        ldi         r16, high(RAMEND)
        ldi         r17, low(RAMEND)
        out         SPH, r16
        out         SPL, r17


    ; Init
        rcall       DMX_Init

sbi         LED_PORT, LED_BIT

    ; Send; value
        ldi         r17, 255
        rcall       DMX_Flood

_main_loop:
        ; never returns..
        rjmp        _main_loop