Trig functions on LPC812

Questions about the BASICtools and MakeItC
Post Reply
Ivar
Posts: 5
Joined: Tue Jan 06, 2015 8:08 pm
Location: Netherlands

Trig functions on LPC812

Post by Ivar »

I need a sin(x) function and found one in the ARMBasic manual. However the example there does not compile on my LPC812 eval board.

Code: Select all

'example code from: ARMBasic.pdf : Runtime Library  / Floating Point Functions/ trig Functions (page 214)
#define include_trig
#include <AB_Math.bas>
for i=0 to 90 step 10
print i,sin(_deg2rad *i),cos(_deg2rad *i),tan((_deg2rad *i)
next i
AB_Math.bas: 567: Out of code space, found powi((_halfpi-symm),2)*divbyfact(2))+(powi((_halfpi-symm),4)*divbyfact(4))-(powi((_halfpi-symm),6)*divbyfact(6)))

Can anybody confirm this issue or maybe suggest a solution ?



basicchip
Posts: 1090
Joined: Fri Oct 19, 2012 2:39 am
Location: Weeki Watchee, FL
Contact:

Trig functions on LPC812

Post by basicchip »

The LPC812 only has 4K available for user BASIC programs, and the error you are getting is out of code space.

The AB math lib was contributed by a user, and intensively checked, but it was not developed for small spaces.

We have been thinking about publishing an integer version of BASIC for the LPC812 which would free up another 4K. Yes I know BASIC on early micros was condensed into 4K (I just finished Isaacson's "The Innovators", and we are being wasteful at 12K which has floating point, string and download support. And that is why we have support for a range chips with memories from 16K to 512K.

Ivar
Posts: 5
Joined: Tue Jan 06, 2015 8:08 pm
Location: Netherlands

Trig functions on LPC812

Post by Ivar »

@basicchip
Thank you for your quick reaction. Now I understand the problem I could solve it by only copying the sin(x) code from the library directly in my code. The compiler told me the other things I had to copy from the library and now I have a working sin(x) function !

basicchip
Posts: 1090
Joined: Fri Oct 19, 2012 2:39 am
Location: Weeki Watchee, FL
Contact:

Trig functions on LPC812

Post by basicchip »

Hi Ivar-

Please publish your condensed sin(x) code here when you have it working. thanks

Ivar
Posts: 5
Joined: Tue Jan 06, 2015 8:08 pm
Location: Netherlands

Trig functions on LPC812

Post by Ivar »

It works. No code of myself, just the right lines from AB-Math.bas. I would be happy to share them but i am unsure of the policy of Coridium on possible copyright issues. But if you start with these lines and the code for sin(x), the compiler will tell you the 2 or 3 other functions you need. 3 minutes work.

Code: Select all

const _nan		=	$7fc00000

CONST DivByFact = { 0.0, 1.00000000000000000000000, 0.50000000000000000000000,
					0.16666666666666700000000, 0.04166666666666670000000, 0.00833333333333333000000,
					0.00138888888888889000000, 0.00019841269841269800000, 0.00002480158730158730000,
					0.00000275573192239859000, 0.00000027557319223985900, 0.00000002505210838544170 }


const _2pi 		=	6.283185307179590000
const _halfpi 	=	1.570796326794900000
const _qtrpi 	=	0.785398163397448000

function fix(x as single) as integer
	' fix truncates a floating-point expression to its integer portion, returning an integer
	' print fix(12.49), fix(12.54)    'output is:  12  12
	return x
	endfunction

function floor(x as single) as single
	' floor returns the largest integral single value not greater than fparam
	' floor of 3.8 is 3.0, floor of -2.3 is -3.0
	if(x = fix(x)) or x>=0 then return fix(x) else return fix(x)-1
	endfunction	

function int(x as single) as integer
	return floor(x)
	endfunction
 

basicchip
Posts: 1090
Joined: Fri Oct 19, 2012 2:39 am
Location: Weeki Watchee, FL
Contact:

Trig functions on LPC812

Post by basicchip »

Feel free to post it here.

Bruce Eisenhard, Coridium Corp

Ivar
Posts: 5
Joined: Tue Jan 06, 2015 8:08 pm
Location: Netherlands

Trig functions on LPC812

Post by Ivar »

Thanks Bruce. Just to be sure.

Code: Select all

'=== Workaround to use sine function (library AB_Math.bas being too big for the memory of the LPC812 eval board):
'=== 
'=== 1) Do not include AB_Math.bas 
'=== 2) Only include the code between the dashed lines to your program:
'===    The code is taken straight from AB_Math. Except for the constants _rad2deg and _deg2rad everything is essential. 
'=== 
'=== At the end of this file at main: you find a some example code to show it works.
 


'-------------- start of AB_Math code ---------------------------------------------------------------------

const _nan      =   $7fc00000

CONST DivByFact = { 0.0, 1.00000000000000000000000, 0.50000000000000000000000,
               0.16666666666666700000000, 0.04166666666666670000000, 0.00833333333333333000000,
               0.00138888888888889000000, 0.00019841269841269800000, 0.00002480158730158730000,
               0.00000275573192239859000, 0.00000027557319223985900, 0.00000002505210838544170 }


const _2pi       =   6.283185307179590000
const _halfpi    =   1.570796326794900000
const _qtrpi    =   0.785398163397448000

const _rad2deg 	= 57.295779513082320876798154814105		'x*180/pi
const _deg2rad 	= 0.01745329251994329576923690768489	'x*pi/180


function fix(x as single) as integer
   ' fix truncates a floating-point expression to its integer portion, returning an integer
   ' print fix(12.49), fix(12.54)    'output is:  12  12
   return x
   endfunction

function floor(x as single) as single
   ' floor returns the largest integral single value not greater than fparam
   ' floor of 3.8 is 3.0, floor of -2.3 is -3.0
   if(x = fix(x)) or x>=0 then return fix(x) else return fix(x)-1
   endfunction   

function int(x as single) as integer
   return floor(x)
   endfunction
 


function fmod(n as single, d as single) as single
	' returns the floating-point remainder of numerator/denominator.
	if d <> 0 then return n-(fix(n/d)*d) else return _nan
	endfunction

function powi(b as single, e as integer) as single
	' returns the base raised to the integral power of exponent
	dim res as single
	if e = 0 then return 1
	if e = 1 then return b
	res = 1
	while e		' iterate thru the exponent, moving it towards zero while multiplying the base
		res = res*if(e<0,1/b,b)
		e = e+if(e<0,1,-1)
		loop
	return res
	endfunction

function reducerange(x as single, sc as single, byref m as integer) as single

	' this is used to reduce a number to within a range and maintain the phase angles
	' for some gawd awful reason, this kicked my arse for hours over a few nights,
	' i strongly suspect that i got lost as i couldn't see the gd forest 'cause of all of
	' the effin trees. i was, admittedly, buring the candle at both ends too.
	' this is a function that can be optimized a lot i suspect.
	' however, i am still tired and ... it ain't broke, boss...

	dim res as single	
	dim scsign, xsign as integer
	
	xsign=1
	scsign =1
	
	if x < 0 then
		xsign = -1
		x *= -1
		endif
	
	if sc < 0 then
		scsign = -1
		sc *= -1
		endif
		
	res = fmod(x,sc)
	m = (int(x/sc))
	
	if (res = 0) and (m = 1) and (xsign=scsign)
		' print "same side same val - unity"
		m = 0
		return x * xsign
	elseif (res = 0) and (m = 1) and (xsign<>scsign)
		' print "opposite unities"
		m = 2 * if(scsign=-1,-1,1)
		return sc * scsign
	elseif (res = 0) and (m > 1) and (xsign <> scsign)
		' print "opposite side - multiples: ";m
		m = if(scsign=-1,-m-1,m+1)
		return sc * scsign
	elseif (res = 0) and (m > 1) 'and xsign = scsign
		' print "same side - multiples: ";m
		m = if(scsign=1,(m-1)*-1,m-1)
		return sc * scsign
	elseif scsign = 1 and xsign = 1
		m *= -1
		return res
	elseif scsign = 1 and xsign = -1
		m += 1
		return sc - res	
	elseif scsign = -1 and xsign = -1
		return res * -1
	else ' scsign = -1 and xsign = 1
		m += 1
		m *= -1
		return res - sc
	endif
	endfunction



function sin(rad as single) as single		' using polynomial - good
	' domain and range: from the graphs above we see that for both the sin and cos functions the
	' domain is all real numbers and the range is all reals from -1 to +1 inclusive. for the tan
	' function the domain is all real numbers except ±p/2, ±3p/2, ±5p/2, …, 
	' (or in degrees: ±90°, ±270°, ±450°, …), where the tan function is undefined.
	' the range of the tan function is all real numbers.
	
	dim multiple as integer
	dim period, symm as single
	period = reducerange(rad,_2pi,multiple)		' 0-360
	symm = reducerange(period,_halfpi,multiple)	' 0-90
	if multiple = -1 then symm = _halfpi-symm
	if multiple = -3 then symm = _halfpi-symm
	
	if symm <=_qtrpi			' <=45 deg
		return if(multiple<-1,-1,1)*(symm-(powi(symm,3)*divbyfact(3))+(powi(symm,5)*divbyfact(5))-(powi(symm,7)*divbyfact(7)))
	else
		return if(multiple<-1,-1,1)*(1-(powi((_halfpi-symm),2)*divbyfact(2))+(powi((_halfpi-symm),4)*divbyfact(4))-(powi((_halfpi-symm),6)*divbyfact(6)))
	endif
	endfunction

'-------------- end of AB_Math code --------------------------------------------------------------------- 


main:

'=== example from ARMbasic.pdf( Trigonometric Functions) adapted to use only sin(x)

for i=0 to 90 step 10
print i,sin(_deg2rad *i)
next i

Post Reply