;*************************************************************************** ;ps_0424.ASM: ANN with learning and controlling modes ;changes from the MIC input, to the LIN input ; 1/32 in, *16 out ; default to weights from morning of 24 Apr 1997 ; ; Copyright 1997 by Peter C. Jones and Scott D. Tepavich. ; All Rights Reserved. ;*************************************************************************** NUMWS equ 30 ; Number of weights EFCMAX equ 30 ; Number of data points in an epoch SSEMAX equ .005 ; Value(SSE) --> "trained" FACTOR equ 5 LINEAR EQU $FFFF ; First, set up interrupt vector commands org p:$0 jmp START org p:$2 dup 6 ; copy the next line into the next 6 spots nop ; clearing some interrupt vectors we don't care for ENDM org p:$8 ; IRQA - jump to control move #control,r7 ; R7 is a pointer to the current subroutine org p:$a ; IRQB - jump to sleeper move #sleeper,r7 org p:$1e ; NMI - jump to learn move #learn,r7 org p:$14 ; Clear SCI interrupt vectors dup 10 nop ENDM ;*************************************************************************** ; Generic startup stuff include 'codec.asm' ; DON'T USE R6... it's codec's stack pointer! ; End Generic Stuff ;*************************************************************************** TONE_OUTPUT EQU HEADPHONE_EN+LINEOUT_EN+(4*LEFT_ATTN)+(4*RIGHT_ATTN) TONE_INPUT EQU LIN_IN_SELECT+(15*MONITOR_ATTN) ORG x:$10 XBOT dc $0 ; D(n-29) DUP NUMWS-2 dc $0 ; D(n-28) .. D(n-1) ENDM XTOP dc $0 ; D(n) MU2 dc 0.05*2.0 ; 2 * mu = learning rate EFC dc EFCMAX ; Epoch-fraction counter SSE dc 0 ; Sum-Squared Error ORG y:$10 ;WBOT dc 1.0/32.0 ; W(0) ; DUP NUMWS-2 ; dc 0.0 ; W(1)..W(28) ; ENDM WBOT dc -0.1637531 dc -0.1223212 dc -0.1121482 dc -0.1020336 dc -0.0919336 dc -0.0817866 dc -0.0717167 dc -0.0616356 dc -0.0516308 dc -0.0415157 dc -0.0314552 dc -0.0214006 dc -0.0112526 dc -0.0012326 dc 0.0088704 dc 0.0189886 dc 0.0291116 dc 0.0392154 dc 0.0493595 dc 0.0596108 dc 0.0697528 dc 0.0800926 dc 0.0904012 dc 0.1007456 dc 0.1110244 dc 0.1215198 dc 0.1319544 dc 0.1426575 dc 0.1536411 dc -0.9387227 ; W(29); ORG p: ; get back to program space! ;*************************************************************************** ; main: the initiation for the looping subroutine-calling function ; newloop: the looping subroutine-calling function ;*************************************************************************** main move #sleeper,r7 ;learn = default mode andi #$FC,mr ;No masking of interrupts newloop movep #$303f,x:IPR ;Level 3 interupts, edge sens. (non-maskable) jsr (r7) ;Jump to the appropriate subroutine jmp newloop ;*************************************************************************** ; learn - the learning mode algorithm for neural net ;*************************************************************************** learn ; Get new inputs A = Arm Angle, B = Desired Output jset #2,x:SSISR,* ;wait for frame sync to pass jclr #2,x:SSISR,* ;wait for frame sync; move x:RX_BUFF_BASE,a ;receive left == Arm Angle move x:RX_BUFF_BASE+1,b ;receive right == DESIRED do #FACTOR,multishift ;divide DESIRED by 2^FACTOR asr a asr b multishift jsr filter ;A = ACTUAL Neuron Output move a,x0 do #(FACTOR-1),multishif1 ;factor it up to output correctly ;since weights were trained to ;a fraction of the actual DESIRED asl a multishif1 move a,x:TX_BUFF_BASE ;transmit left move #TONE_OUTPUT,y0 ;set up control words move y0,x:TX_BUFF_BASE+2 move #TONE_INPUT,y0 move y0,x:TX_BUFF_BASE+3 move x0,a ;and get reduced filter-output ; back for training (to reduce ; weight and error magnitudes) ; calculate error: desired (B) - actual (A) -> B sub a,b move b,y0 ; y0 = error ; SSE += error^2 move x:SSE,a mac y0,y0,a move a,x:SSE ; SSE = SSEold + error^2 ; Epoch Fraction Counter (EFC: counts how far through an epoch we are) ; (as determined by [EFCMAX-EFC]/EFCMAX ) move #00,b1 move #00,b2 move x:EFC,b0 dec b move b0,x:EFC ; UPDATE THE EFC! -- without changing Z jne weight_update ; IF EFC==0 (ie, epoch is done) THEN move #SSEMAX,x0 nop cmp x0,a ; Compare SSE vs. SSEMAX (SSE-SSEMAX) jge skip ; IF SSE < SSEMAX nop ; light the led, <<<--- nop ; (yeah right, uhuh) <<<--- move #sleeper,r7 ; GO TO SLEEPER skip ; ENDIF nop move #EFCMAX,a move a,x:EFC ; EFC reset to EFCMAX move #0,a ; move a,x:SSE ; SSE = 0 at the end of an epoch ; ENDIF weight_update move #XBOT,r0 ; r0 is a pointer to input data move #WBOT,r4 ; r4 is a pointer to the weights move x:MU2,y1 ; y1 = 2*mu mpy y0,y1,a ; a = 2*mu*err move a,x0 ; x0 = 2*mu*err do #NUMWS,DO_END ; For k=1 to NUMWS (# of weights) nop move x:(r0)+,x1 ; x1 = X_k, point to next X move y:(r4),a ; a = W_k mac x0,x1,a ; a = W_k + (2*mu*err)*X_k move a,y:(r4)+ ; Update W_k, point to next W DO_END ; NEXT k rts ;*************************************************************************** ;control ;*************************************************************************** control jset #2,x:SSISR,* ;wait for frame sync to pass jclr #2,x:SSISR,* ;wait for frame sync; move x:RX_BUFF_BASE,a ;receive left do #FACTOR,multishif2 ;factor it up for output asr a multishif2 jsr filter ;produce neuron output do #(FACTOR-1),multishif3 ;factor it up for output asl a multishif3 move a,x:TX_BUFF_BASE ;transmit left move #TONE_OUTPUT,y0 ;set up control words move y0,x:TX_BUFF_BASE+2 move #TONE_INPUT,y0 move y0,x:TX_BUFF_BASE+3 rts ;return from subroutine ;*************************************************************************** ; filter: the multiply & accumulate section ; generates neuron input == neuron output ; Used by both learning and controlling modes ;*************************************************************************** filter ori #$08,mr ;set scaling mode move #LINEAR,m0 ;linear addressing move m0,m4 move #XBOT,r0 move #WBOT,r4 ; initialize pointers move r0,r1 move a,x:XTOP ; new data into clr a start_do do #30,end_do ; loop 30x (for i=0:29) nop move x:(r0)+,x0 y:(r4)+,y0 ; x0=D(n-29+i) || y0=Wi mac x0,y0,a x:(r0),x1 ; a+=D(n-29+i)*Wi move x1,x:(r1)+ ; move current D(n-28+i) ; into new D(n-29+i) end_do andi #$f3,mr ;no longer in scaling mode rts ;return from sub ;*************************************************************************** ; sleeper: a do-nothing routine that ; generates neuron input == neuron output ; Used by both learning and controlling modes ;*************************************************************************** sleeper rts end