;******************************************************************************
;
;       MIDI controller based on Linear pot & LPC935
;
;******************************************************************************
;
;

;       Primary controls

$TITLE(BYTE MIDI_1)
$PAGEWIDTH(132)
$DEBUG
$OBJECT
$NOPAGING
;
;
;  Variable declarations

$include(C:\asm51\LPC936.inc)

    
;
;   Data memory

    slot1 data 30h
    slot2 data 31h
    slot3 data 32h
    slot4 data 33h
    average data 34h
    old_average data 35h
    
;   Bit memory
    
    AD_Complete         Bit     00h
    
;   Equates

    slot_pointer equ R1

;   Buffers for data storage


    
    ORG     00H
    
    CSEG
    
    LJMP INIT
        
    ORG 0073h
    
    LJMP ADC_INTERRUPT
    
        
;##############################################################################
;
;   Initialisation routines
;

    
INIT:

;//////////////////////////////////////////////////////////////////////////////
;
;   configure port pins
    
    mov P1M1, #00h      ;P1 in QBD mode as we're using TxD
    mov P2M1, #00h      ;Ditto for P2
    
;//////////////////////////////////////////////////////////////////////////////
;
;   configure uart for BaudRate,8,n,1 
    
    mov brgcon, #00h
    mov brgr0, #0dch    ;This line for 31250 (Midi)
    ;mov BRGR0, #30h    ;This line for 115200 (PC)
    mov brgr1, #00h
    mov brgcon, #03h
    mov scon, #50h      ;mode 1
    mov pcon, #0c0h     ;enable fe bit & smod = 1
    


    
;//////////////////////////////////////////////////////////////////////////////
;
;       Configure ADC
    
    clr AD_Complete     ;Init AD complete flag
    
    mov ADINS, #10h     ;Select ADI12 - Port 0.3 Pin 24
    
    mov ADCON1, #45h    ;Enable ADCI1, En ADC1, immediate mode
    
    mov ADMODB, #40h    ;ADC Clock divisor 3
    
    setb EAD            ;enable AD complete interrupt
    
    setb EA             
    
;//////////////////////////////////////////////////////////////////////////////
;
;       Init variables
    
    mov slot_pointer, #30h  ;Address of slot1
    mov a, #00h
    
;//////////////////////////////////////////////////////////////////////////////
;
;  Main loop
;       

LOOP1:

    orl ADCON1, #01h    ;Immediate start A/D conv
    
    jnb AD_Complete, $  ;Wait for interrupt
    
    mov a, AD1DAT0      ;Store ADC reading
    
    clr c
    rrc a               ;Divide by 2 to convert reading from 0-255 to 0-127
        
    mov @slot_pointer, a    ;Store our reading in the current slot
    
    inc slot_pointer        ;Increment pointer to the next slot
    cjne slot_pointer, #34h, carry_on
    mov slot_pointer, #30h  
    
carry_on:

    push acc            ;save a/d reading   
    
;//////////////////////////////////////////////////////////////////////////////
;
;   Calculate moving average  
;   
    mov a, #0h
    
    addc a, slot1
    addc a, slot2
    addc a, slot3
    addc a, slot4       ;Add all 4 values together
    

    rrc a               ;First rotate needs to include carry
    clr c
    rrc a               ;div by 4 to get average
    
    mov average, a      ;Store the average
    
    clr AD_Complete     ;Clear ADC Complete flag
    
    cjne a, old_average, diff   ;Are the old and new averages different?
    
    pop acc             ;dummy pop
    
    jmp loop1
    
diff:

    mov old_average, a  ;Store average as old average
    
;//////////////////////////////////////////////////////////////////////////////
;
;  Send data
;   
    pop acc             ;get a/d reading back

    CLR TI
    mov sbuf, #0B0h     ;MIDI CC
    jnb ti, $
    
    CLR TI
    mov sbuf, #04h      ;CC number 4
    jnb ti, $
    
    clr ti
    mov sbuf, a         ;Current A/D reading
    jnb ti, $

    mov R7, 0ffh        ;Wait for a bit
TimerLoop:
    nop
    djnz R7, TimerLoop 
    
    jmp  LOOP1                  ; endless loop

;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
;
;           ADC interrupt.
        
ADC_INTERRUPT:

    anl ADCON1, #0F4h   ;Clear conversion complete, set to stop mode
    setb AD_Complete    ;Set ADC Complete flag

RETI

;
;           End of ADC interrupt
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

    
END