Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

How to involve the assembly code/routine into my c code??

Status
Not open for further replies.

yzou_ua

Member level 5
Joined
Nov 5, 2008
Messages
92
Helped
1
Reputation
2
Reaction score
1
Trophy points
1,288
Activity points
1,869
I know nothing about assembly code, so here is what I'm doing:

I have a assembly rouine for atan(), how to make it work for my following c code:

#include "p33fj64gs610"
#include <math.h>
...
int main()
{...
x=4;
y=5;
ang = atan(x,y);
...
}


Attaching assembly code here:

; constant definitions
.equ NEG_PI_BY_2, 0xC000
.equ PI_BY_2, 0x3FFF
.equ PI, 0x7FFF
.equ NEG_PI, 0x8000
.equ ACCUM_PHASE, w7

; in this table are the values of atan(n) scaled into the range 0 to PI
; and then converted into fractional format
.section .data
CORDIC_DATA:
.word 0x2000 ; atan(1.0) / PI
.word 0x12E4 ; atan(0.5) / PI
.word 0x09FB ; atan(0.25) / PI
.word 0x0511 ; atan(0.125) / PI
.word 0x028B ; atan(0.0625) / PI
.word 0x0146 ; etc
.word 0x00A3
.word 0x0051
.word 0x0029
.word 0x0014
.word 0x000A
.word 0x0005
.word 0x0003
.word 0x0001
.word 0x0001
.word 0x0000

.section .text



.global _atan2CORDIC

_atan2CORDIC:
lnk #0x02 ; reserve 2 bytes for storage
push w8
push w9
push CORCON

; check for values that cause errors
; due to asymptotic atan behaviour
mov #0x8000, w8
cp w0, w8 ; Q = -1.0 ?
bra NZ, checkI
mov #NEG_PI_BY_2, w0
bra exitCORDICRoutine
checkI:
cp w1, w8 ; I = -1.0
bra NZ, mainCORDICRoutine
mov #PI, w0
bra exitCORDICRoutine
mainCORDICRoutine:

; set w9 to point to the reserved 2 byte space
; this can then be used to preload w6 in the dsp MACs
mov w14, w9
; ACCUM_PHASE (w7) is the total phase angle calculated
clr ACCUM_PHASE

; adjust q and i to be in quadrant I
cp0 w1
bra NN, setupIter
mov w1, [w9] ; w2 = temporary I
cp0 w0
bra LE, quadIII
mov w0, w1
neg [w9], w0
mov #NEG_PI_BY_2, ACCUM_PHASE
bra setupIter
quadIII:
neg w0, w1
mov [w9], w0
mov #PI_BY_2, ACCUM_PHASE

setupIter:
; set ACCA and ACCB to equal I and Q
lac w0, #1, B
lac w1, #1, A

mov #CORDIC_DATA, w8 ; w8 points to CORDIC data table
mov #0x7FFF, w5 ; w5 = K = 1.0

do #9, endCORDICRoutine
sac.r a, [w9] ; put I onto local stack
sac.r b, w6 ; w6 = Q
cp0 w6 ; if Q < 0 goto rotate positive
bra N, rotate_pos
rotate_neg:
mac w5*w6, a ; I = I + Q * K, w6 = temp I
mov [w9], w6
msc w5*w6, b ; Q = Q - oldI * K
mov [w8++], w4
subbr w4, ACCUM_PHASE, ACCUM_PHASE
bra endCORDICRoutine
rotate_pos:
msc w5*w6, a ; I = I - Q * K, w6 = temp I
mov [w9], w6
mac w5*w6, b ; Q = Q + oldI * K
mov [w8++], w4
add w4, ACCUM_PHASE, ACCUM_PHASE

endCORDICRoutine:
lsr w5, w5 ; K = K / 2

neg ACCUM_PHASE, w0 ; reverse the sign
exitCORDICRoutine:
pop CORCON
pop w9
pop w8
ulnk
return

.end
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top