hodhod96
hodhod96

Reputation: 5

error with calculating sin in assembly in arduino

#include <avr/pgmspace.h>

//max errror ~0.017452 [91*4=364 bytes]
static const float PROGMEM SineTable[91] = {
 0.0, 0.017452, 0.034899, 0.052336, 0.069756, 0.087156, 
 0.104528, 0.121869, 0.139173, 0.156434, 0.173648, 0.190809, 
 0.207912, 0.224951, 0.241922, 0.258819, 0.275637, 0.292372, 
 0.309017, 0.325568, 0.34202, 0.358368, 0.374607, 0.390731, 
 0.406737, 0.422618, 0.438371, 0.45399, 0.469472, 0.48481, 
 0.5, 0.515038, 0.529919, 0.544639, 0.559193, 0.573576, 
 0.587785, 0.601815, 0.615661, 0.62932, 0.642788, 0.656059, 
 0.669131, 0.681998, 0.694658, 0.707107, 0.71934, 0.731354, 
 0.743145, 0.75471, 0.766044, 0.777146, 0.788011, 0.798636, 
 0.809017, 0.819152, 0.829038, 0.838671, 0.848048, 0.857167, 
 0.866025, 0.87462, 0.882948, 0.891007, 0.898794, 0.906308, 
 0.913545, 0.920505, 0.927184, 0.93358, 0.939693, 0.945519, 
 0.951057, 0.956305, 0.961262, 0.965926, 0.970296, 0.97437, 
 0.978148, 0.981627, 0.984808, 0.987688, 0.990268, 0.992546, 
 0.994522, 0.996195, 0.997564, 0.99863, 0.999391, 0.999848, 1.0
 };

float _Sine(uint16_t angle) {
  float tmp;

 asm (
   //validate angle >= 0 && angle <= 90
"cpi  %A1, 90+1 \n" 
"cpc  %B1, __zero_reg__ \n"
"brcc _NaN      \n" //out of range

 //calculate table index
"lsl  %A1       \n" //float is 4 bytes wide
"rol  %B1       \n" //index = angle * 4
"lsl  %A1       \n"
"rol  %B1       \n"

//add index to start of SineTable
"add  r30, %A1  \n" 
"adc  r31, %B1  \n"

//get sine value (4-bytes)
"lpm  %A0, Z+   \n" 
"lpm  %B0, Z+   \n"
"lpm  %C0, Z+   \n"
"lpm  %D0, Z    \n"
"ret            \n" //exit

//return NAN
"_NaN:              \n" 
"ldi  %A0, lo8(%3)  \n" //NAN = 0x7fc00000
"ldi  %B0, hi8(%3)  \n"
"ldi  %C0, hlo8(%3) \n"
"ldi  %D0, hhi8(%3) \n"
: "=r" (tmp) : "r" (angle), "z" (SineTable), "F" (NAN) : 
 );

 return tmp;
 }

int main() {
  uint16_t a = 40;
  float temp = _Sine(a);
  Serial.begin(9600);
  Serial.println(temp);
 }

This is code i have for calculating sin of an angel in avr assembly. but I am coding in arduino and writing assembly in arduino IDE. the error I am getting for this is :register number above 15 required but i am not using any registers below 15 and i have no idea what is wrong with this code.

Upvotes: 0

Views: 510

Answers (1)

Jester
Jester

Reputation: 58792

The error is that ldi requires register above 15, but you use a generic register constraint r so the compiler is allowed to pick a low register for those operands. You could switch to d constraint for tmp.

Also, you destroy Z without telling the compiler.

All that said, I don't see any point in doing this using assembly. The compiler is perfectly capable of indexing an array, you basically just need:

return angle <= 90 ? SineTable[angle] : NAN;

In fact according to my testing that pretty much generates the exact same assembly code.

Upvotes: 3

Related Questions