Problem with comparison.
/Modules/Sensors/MAG01A/SW/Python/MAG_test.ipynb
0,0 → 1,704
{
"metadata": {
"name": ""
},
"nbformat": 3,
"nbformat_minor": 0,
"worksheets": [
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Uk\u00e1zka pou\u017eit\u00ed n\u00e1stroje IPython na manipulaci se senzorov\u00fdmi daty\n",
"=======\n",
"\n",
"P\u0159\u00edklad vyu\u017e\u00edv\u00e1 modulovou stavebnici MLAB a jej\u00ed knihovnu [pymlab](https://github.com/MLAB-project/MLAB-I2c-modules). Sn\u00edma\u010d je k po\u010d\u00edta\u010di p\u0159ipojen\u00fd p\u0159es rozhradn\u00ed USB a data jsou vy\u010d\u00edt\u00e1na p\u0159es [I\u00b2C](http://wiki.mlab.cz/doku.php?id=cs:i2c)\n",
"\n",
"Pou\u017eit\u00fd sn\u00edma\u010d [HMC5883L](http://www.magneticsensors.com/three-axis-digital-compass.php) m\u00e1 n\u00e1sleduj\u00edc\u00ed katalogov\u00e9 parametry: \n",
"\n",
"* M\u011b\u0159\u00edc\u00ed rozsah +/- 800 uT\n",
"* Rozli\u0161en\u00ed typicky 5 uT\n",
"* \u010cetnost m\u011b\u0159en\u00ed 75 Hz\n",
"\n",
"Zprovozn\u011bn\u00ed demo k\u00f3du\n",
"---------------------\n",
"\n",
"Nejd\u0159\u00edve zjist\u00edme zda m\u00e1me p\u0159\u00edstup pro z\u00e1pis a \u010dten\u00ed do syst\u00e9mov\u00e9ho za\u0159\u00edzen\u00ed. A jak\u00e9 \u010d\u00edslo m\u00e1 I\u00b2C sb\u011brnice na kterou m\u00e1me p\u0159ipojen\u00e1 \u010didla. \n"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"!i2cdetect -l"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"i2c-0\ti2c \ti915 gmbus ssc \tI2C adapter\r\n",
"i2c-1\ti2c \ti915 gmbus vga \tI2C adapter\r\n",
"i2c-2\ti2c \ti915 gmbus panel \tI2C adapter\r\n",
"i2c-3\ti2c \ti915 gmbus dpc \tI2C adapter\r\n",
"i2c-4\ti2c \ti915 gmbus dpb \tI2C adapter\r\n",
"i2c-5\ti2c \ti915 gmbus dpd \tI2C adapter\r\n",
"i2c-6\ti2c \tDPDDC-B \tI2C adapter\r\n",
"i2c-7\ti2c \ti2c-tiny-usb at bus 001 device 070\tI2C adapter\r\n"
]
}
],
"prompt_number": 1
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Proto\u017ee pro p\u0159ipojen\u00ed \u010didel k po\u010d\u00edta\u010di pou\u017e\u00edv\u00e1me adapt\u00e9r i2c-tiny-usb. Vid\u00edme, \u017ee sb\u011brnice m\u00e1 aktu\u00e1ln\u011b ozna\u010den\u00ed nap\u0159\u00edklad i2c-8. \n",
"\n",
"V p\u0159\u00edpad\u011b, \u017ee v\u00fd\u0161e uveden\u00fd p\u0159\u00edklad vr\u00e1t\u00ed chybu, nebo pojmenov\u00e1n\u00ed \"unknown\" tak nem\u00e1me p\u0159\u00edstup k syst\u00e9mov\u00fdm rozhran\u00edm. Ten z\u00edsk\u00e1me vytvo\u0159en\u00edm souboru s n\u00e1sleduj\u00edc\u00edm obsahem ve slo\u017ece: /etc/udev/rules.d/i2c-devices.rules"
]
},
{
"cell_type": "raw",
"metadata": {},
"source": [
"KERNEL==\"i2c-[0-9]*\", GROUP=\"i2c\""
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Toto ozna\u010den\u00ed budeme je\u0161t\u011b d\u00e1le pot\u0159ebovat, proto si jej ulo\u017e\u00edme da prom\u011bnn\u00e9. "
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"port = 7"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 2
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Budeme pokra\u010dovat na\u010dten\u00edm pot\u0159ebn\u00fdch modul\u016f pro zach\u00e1zen\u00ed s I\u00b2C sn\u00edma\u010di."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"import time\n",
"import datetime\n",
"import sys\n",
"\n",
"from pymlab import config\n",
"import matplotlib.pyplot as plt\n",
"import numpy as np"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 3
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Nyn\u00ed si nadefinujeme strukturu p\u0159ipojen\u00ed jednotliv\u00fdch \u010didel na I\u00b2C sb\u011brnici."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"cfg = config.Config(\n",
" i2c = {\n",
" \"port\": port,\n",
" },\n",
" bus = [\n",
" {\n",
" \"type\": \"i2chub\",\n",
" \"address\": 0x71,\n",
" \n",
" \"children\": [\n",
" {\"name\": \"mag\", \"type\": \"mag01\", \"gauss\": 0.88, \"channel\": 0, }, \n",
" ],\n",
" },\n",
" ],\n",
")"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 26
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Tuto strukturu inicializujeme, aby jsme dos\u00e1hli definovan\u00e9 konfigurace \u010didel."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"cfg.initialize()\n",
"mag_sensor = cfg.get_device(\"mag\")\n",
"time.sleep(0.5)"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 27
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Nyn\u00ed u\u017e m\u016f\u017eeme p\u0159\u00edmo komunikovat se za\u0159\u00edzen\u00edm pojmenovan\u00fdm jako mag_sensor. A vy\u010d\u00edst z n\u011bj sadu dat."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"import sys\n",
"import time\n",
"from IPython.display import clear_output\n",
"\n",
"MEASUREMENTS = 500\n",
"list_meas = []\n",
"\n",
"for n in range(MEASUREMENTS):\n",
"# mag_sensor.route() #V p\u0159\u00edpad\u011b v\u00edce \u010didel je pot\u0159eba ke ka\u017ed\u00e9mu p\u0159ed jeho pou\u017eit\u00edm nechat vyroutovat cesutu na sb\u011brnici.\n",
" clear_output()\n",
" (x, y, z) = mag_sensor.axes()\n",
" list_meas.append([x, y, z])\n",
" print (n, list_meas[n])\n",
" time.sleep(0.2)\n",
" sys.stdout.flush()"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"(499, [5.109999999999999, 163.51999999999998, -689.85])\n"
]
}
],
"prompt_number": 31
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"V\u00fdstupn\u00ed jsou v jednotk\u00e1ch miliGauss a m\u011b\u0159\u00edc\u00ed rozsah je nastaven\u00fd na 0.88 Gauss. Viz konfigurace \u010didel naho\u0159e.\n",
"Nam\u011b\u0159en\u00e9 hodnoty n\u00e1sledn\u011b ulo\u017e\u00edme do souboru. "
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"np.savez(\"calibration_data_2Dset\", data=list_meas)"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 32
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Zpracov\u00e1n\u00ed dat 2D\n",
"-----------\n",
"\n",
"V dal\u0161\u00ed \u010d\u00e1sti budeme pracovat s daty v ulo\u017een\u00e9m souboru, kter\u00fd na\u010dteme do pol\u00ed x, y, z. "
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"data = np.load('./calibration_data_2Dset.npz')\n",
"list_meas = data['data']\n",
"x = list_meas[:, 0]\n",
"y = list_meas[:, 1]\n",
"z = list_meas[:, 2]"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 33
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Nam\u011b\u0159en\u00e9 hodnoty vykresl\u00edme do 3D grafu."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"from mpl_toolkits.mplot3d.axes3d import Axes3D\n",
"#%pylab qt\n",
"%pylab inline\n",
"fig = plt.figure()\n",
"ax = Axes3D(fig)\n",
"p = ax.scatter(x,y,z)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"Populating the interactive namespace from numpy and matplotlib\n"
]
},
{
"metadata": {},
"output_type": "display_data",
"png": "iVBORw0KGgoAAAANSUhEUgAAAb4AAAEuCAYAAADx63eqAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzsnXmYVNWd9z+39qWrF2i6aRqaXUE2FVQQcAX3JWoS9U3G\nSEw0iZNHMxnHzCS+RsdkNMlE8ybjZNHJmOiocdSoEQUXREFF2WRtdmmapRu66drXe+/7R3nK20VV\nde291P08D48JVN977ulb53t+v/NbJFVVVXR0dHR0dCoEQ38PQEdHR0dHp5zowqejo6OjU1Howqej\no6OjU1Howqejo6OjU1Howqejo6OjU1Howqejo6OjU1Howqejo6OjU1Howqejo6OjU1Howqejo6Oj\nU1Howqejo6OjU1Howqejo6OjU1Howqejo6OjU1Howqejo6OjU1Howqejo6OjU1Howqejo6OjU1Ho\nwqejo6OjU1Howqejo6OjU1Howqejo6OjU1Howqejo6OjU1Howqejo6OjU1Howqejo6OjU1Howqej\no6OjU1Howqejo6OjU1Howqejo6OjU1GY+nsAOjqlRFEUYrEYoVAIk8mE0WjEaDRiMBiQJAlJkvp7\niDo6OmVGFz6dIYmiKIRCIQBUVUWWZRRFQVXVxH+1QqgLoo5O5aALn86QQlEUotEoiqLg9XqpqqpK\nCJnRaARI/LvBYEBRFGRZPuE6QghNJhMGg0EXRB2dIYQufDqDHlVVUVU1IWgAkiShqiqxWIxwOIws\nywkBE59XVRVJkjAYDCdcTwhiJBJJ/L34rC6IOjqDG0lVVbW/B6Gjkw/pBA8gEong9/sxGAzY7fbE\nZ8WZn/i8qqoJAdP+SSVmWsHUoguijs7gQhc+nUFHKgHTCl4wGEy4MZ1OJ0ajkWg0mvhMNBpFlmVs\nNlviWsl/ii2I+hmijs7AQXd16gwakgVPKyDhcJhQKITBYMDpdGIymfB4PH0KjDj7E+d/yfcSf4RV\nmUkQ07lMg8EgkiRhNpsT9zQYDIngGt1C1NEpL7rw6Qx4RFSmiMxMJXhGoxGn05kQF+3Piv+KnxHn\nf5kotiBqg2vENcLhcNp7agUxWVB1dHQKQxc+nQGLELxYLJYQLiFeoVAokZtXVVWFyXTiq6y1nopl\nSWUSRCHMqdyw4v7C9ZnKOgQSz5vqntrzQ6PRqFuHOjp5ogufzoBDRGMKARBWk6qqvQTP5XKlFLxk\n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\nRK5CYII=\n",
"text": [
"<matplotlib.figure.Figure at 0x7f5bf89a3590>"
]
}
],
"prompt_number": 34
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Pro lep\u0161\u00ed zobrazen\u00ed jednotliv\u00fdch zkreslen\u00ed vykresl\u00edme i 2D pr\u016fm\u011bt dat."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"plt.plot(x, y,'.')"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 36,
"text": [
"[<matplotlib.lines.Line2D at 0x7f5bf8806910>]"
]
},
{
"metadata": {},
"output_type": "display_data",
"png": "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\noOMnhJAk4/8DBn8m5sEsux0AAAAASUVORK5CYII=\n",
"text": [
"<matplotlib.figure.Figure at 0x7f5bf88a9ad0>"
]
}
],
"prompt_number": 36
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Z grafu je vid\u011bt, \u017ee se uplat\u0148uj\u00ed oba zn\u00e1m\u00e9 deforma\u010dn\u00ed jevy - soft-iron a hard-iron. Pokus\u00edme se je proto kompenzovat. Nejd\u0159\u00edve zkus\u00edme odstranit Hard-iron efekty zp\u016fsobuj\u00edc\u00ed offsety."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"xoffset = (min(x) + max(x))/2\n",
"print xoffset"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"34.675\n"
]
}
],
"prompt_number": 37
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"yoffset = (min(y) + max(y))/2\n",
"print yoffset"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"-53.29\n"
]
}
],
"prompt_number": 39
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"plt.plot(x-xoffset, y-yoffset,'.')"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 41,
"text": [
"[<matplotlib.lines.Line2D at 0x7f5bf860a410>]"
]
},
{
"metadata": {},
"output_type": "display_data",
"png": "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\nDL4AAAAASUVORK5CYII=\n",
"text": [
"<matplotlib.figure.Figure at 0x7f5bf86a8fd0>"
]
}
],
"prompt_number": 41
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Interaktivn\u00ed test, kter\u00fd vypisuje aktua\u00e1ln\u00ed azimut. Lze si na n\u011bm vyzkou\u0161et funkci kompasu. Je vid\u011bt, \u017ee p\u0159i vzniku v\u011bt\u0161\u00edho n\u00e1klonu, dvouos\u00fd kompas za\u010dne ukazovat p\u0159esn\u011b opa\u010dn\u00fd sm\u011br."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"try:\n",
"\n",
" for n in range(MEASUREMENTS):\n",
" (x, y, z) = mag_sensor.axes()\n",
" phi = np.arctan2(x-xoffset, y-yoffset)\n",
" clear_output()\n",
" print ((phi*180)/pi+180)\n",
" time.sleep(0.2)\n",
" sys.stdout.flush()\n",
"except KeyboardInterrupt:\n",
" sys.exit(0)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"83.1246570299\n"
]
}
],
"prompt_number": 44
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Vid\u00edme, \u017ee po tomto zp\u016fsobu korekce m\u00e1 vykreslen\u00fd \u00fatvar od kru\u017enice je\u0161t\u011b v\u00fdznamn\u00e9 odchylky. Nyn\u00ed pot\u0159ebujeme kompenzovat soft-iron efekty. K tomu mus\u00edme pracovat s nam\u011b\u0159en\u00fdmi daty, jako s elipsou a naj\u00edt jej\u00ed hlavn\u00ed a vedlej\u0161\u00ed poloosu. Postup je trochu komplikovan\u011bj\u0161\u00ed, proto adoptujeme k\u00f3d z [PaparazziUAV](http://wiki.paparazziuav.org/wiki/ImuCalibration). Ten pomoc\u00ed fitov\u00e1n\u00ed elipsoindu najde korek\u010dn\u00ed parametry citlivosti pro jednotliv\u00e9 osy. Zanedb\u00e1v\u00e1 ale p\u0159\u00edpadnou rotaci elipsoidu popsanou v \u010dl\u00e1nku [Compensating for Tilt, Hard-Iron, and Soft-Iron Effects](http://www.sensorsmag.com/sensors/motion-velocity-displacement/compensating-tilt-hard-iron-and-soft-iron-effects-6475)\n",
"Tento p\u0159\u00edstup je tak\u00e9 v\u00fdhodn\u00fd v tom, \u017ee vyu\u017e\u00edv\u00e1 v\u0161echny 3 osy magnetometru. Proto nen\u00ed pot\u0159eba pro kompenzaci n\u00e1klonu pou\u017e\u00edvat akcelerometr. Kompenzace akcererometrem by ale pozd\u011bji m\u011bla b\u00fdt vyu\u017eita ke korekci rotace os magnetometru v\u016f\u010di vn\u011bj\u0161\u00edmu pouzdru.\n",
"\n",
"Zpracov\u00e1n\u00ed dat 3D\n",
"-----------\n",
"\n",
"K tomu pou\u017eijeme datov\u00fd set, kde jsou body rozprost\u0159en\u00e9 po cel\u00e9m povrchu koule. "
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"data = np.load('./calibration_data_3Dset.npz')\n",
"list_meas = data['data']\n",
"x = list_meas[:, 0]\n",
"y = list_meas[:, 1]\n",
"z = list_meas[:, 2]"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 1
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"from mpl_toolkits.mplot3d.axes3d import Axes3D\n",
"#%pylab qt ## po odkomentovani a zakomentovani nasledujiciho radku udela vystup do QT okna. \n",
"%pylab inline\n",
"fig = plt.figure()\n",
"ax = Axes3D(fig)\n",
"p = ax.scatter(x,y,z)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"Populating the interactive namespace from numpy and matplotlib\n"
]
},
{
"metadata": {},
"output_type": "display_data",
"png": "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\ndK1KAERdWwAAAABJRU5ErkJggg==\n",
"text": [
"<matplotlib.figure.Figure at 0x7f5bf86dd450>"
]
}
],
"prompt_number": 23
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"import scipy\n",
"from scipy import optimize\n",
"import calibration_utils\n",
"\n",
"sensor_ref = 1.\n",
"sensor_res = 0.73\n",
"noise_window = 10\n",
"noise_threshold = 1000"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 3
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Uprav\u00edme strukuturu pole m\u011b\u0159en\u00fdch hodnot do sn\u00e1ze indexovateln\u00e9ho form\u00e1tu."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"measurements = np.array(list_meas)"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 4
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Spo\u010d\u00edt\u00e1me medi\u00e1n magnitudy zm\u011b\u0159en\u00fdch vektor\u016f. A nastav\u00edme podle n\u011bj rozhodovac\u00ed \u00farove\u0148 pro filtraci a ofiltrujeme nam\u011b\u0159en\u00e1 kalibra\u010dn\u00ed data. "
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"meas_median=scipy.median(scipy.array([scipy.linalg.norm(v) for v in measurements]))\n",
"noise_threshold = meas_median * 0.8\n",
"print noise_threshold\n",
"flt_meas, flt_idx = calibration_utils.filter_meas(measurements, noise_window, noise_threshold)\n",
"print(\"remaining \"+str(len(flt_meas))+\" after filtering\")"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"460.895326306\n",
"remaining 346 after filtering\n"
]
}
],
"prompt_number": 5
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Spo\u010d\u00edt\u00e1me odhad elipsoidu z nam\u011b\u0159en\u00fdch minim\u00e1ln\u00edch a maxim\u00e1ln\u00edch hodnot."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
" p0 = calibration_utils.get_min_max_guess(flt_meas, sensor_ref)\n",
" cp0, np0 = calibration_utils.scale_measurements(flt_meas, p0)\n",
" print(\"initial guess : avg \"+str(np0.mean())+\" std \"+str(np0.std()))\n",
"\n",
" def err_func(p, meas, y):\n",
" cp, np = calibration_utils.scale_measurements(meas, p)\n",
" err = y*scipy.ones(len(meas)) - np\n",
" return err"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"initial guess : avg 0.999920050427 std 0.0671243703038\n"
]
}
],
"prompt_number": 6
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Optimalizujeme odhad fitov\u00e1n\u00edm elipsoidu."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
" p1, cov, info, msg, success = optimize.leastsq(err_func, p0[:], args=(flt_meas, sensor_ref), full_output=1)\n",
" if not success in [1, 2, 3, 4]:\n",
" print(\"Optimization error: \", msg)\n",
" print(\"Please try to provide a clean logfile.\")\n",
" sys.exit(1)\n",
"\n",
" cp1, np1 = calibration_utils.scale_measurements(flt_meas, p1)\n",
" print(\"optimized guess : avg \"+str(np1.mean())+\" std \"+str(np1.std()))"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"optimized guess : avg 0.999137645687 std 0.0293532050592\n"
]
}
],
"prompt_number": 7
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Vykresl\u00edme v\u00fdsledek filtrace a fitov\u00e1n\u00ed. "
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"%pylab qt\n",
"#%pylab inline\n",
"calibration_utils.plot_results(False, measurements, flt_idx, flt_meas, cp0, np0, cp1, np1, sensor_ref)\n",
"calibration_utils.plot_mag_3d(flt_meas, cp1, p1)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"Populating the interactive namespace from numpy and matplotlib\n"
]
},
{
"output_type": "stream",
"stream": "stderr",
"text": [
"WARNING: pylab import has clobbered these variables: ['cov', 'info']\n",
"`%pylab --no-import-all` prevents importing * from pylab and numpy\n"
]
}
],
"prompt_number": 8
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Nyn\u00ed m\u016f\u017eeme z\u00edskan\u00e9 scale faktory a offsety pou\u017e\u00edt na kompenzaci libovoln\u00e9ho m\u011b\u0159en\u00ed a n\u00e1sledn\u011b vypo\u010d\u00edtat polohov\u00e9 \u00fahly platformy ve sf\u00e9rick\u00fdch sou\u0159adnic\u00edch."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"for n in range(MEASUREMENTS):\n",
" m = mag_sensor.axes()\n",
" sm = (m - p1[0:3])*p1[3:6]\n",
" r = norm(sm)\n",
" theta = np.arccos(sm[2]/r)\n",
" phi = np.arctan2(sm[1],sm[0])\n",
" clear_output()\n",
" print (r,(theta*180)/pi,(phi*180)/pi)\n",
" sys.stdout.flush()"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"(1.0033330291141624, 159.16410600293204, 61.66914855382452)\n"
]
}
],
"prompt_number": 35
}
],
"metadata": {}
}
]
}
/Modules/Sensors/MAG01A/SW/Python/calibration_data_2Dset.npz
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/Modules/Sensors/MAG01A/SW/Python/calibration_utils.py
0,0 → 1,282
 
# Copyright (C) 2010 Antoine Drouin
#
# This file is part of Paparazzi.
#
# Paparazzi is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# Paparazzi is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Paparazzi; see the file COPYING. If not, write to
# the Free Software Foundation, 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
#
 
from __future__ import print_function, division
 
import re
import numpy as np
from numpy import sin, cos
from scipy import linalg, stats
 
import matplotlib
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
 
 
def get_ids_in_log(filename):
"""Returns available ac_id from a log."""
f = open(filename, 'r')
ids = []
pattern = re.compile("\S+ (\S+)")
while True:
line = f.readline().strip()
if line == '':
break
m = re.match(pattern, line)
if m:
ac_id = m.group(1)
if not ac_id in ids:
ids.append(ac_id)
return ids
 
 
def read_log(ac_id, filename, sensor):
"""Extracts raw sensor measurements from a log."""
f = open(filename, 'r')
pattern = re.compile("(\S+) "+ac_id+" IMU_"+sensor+"_RAW (\S+) (\S+) (\S+)")
list_meas = []
while True:
line = f.readline().strip()
if line == '':
break
m = re.match(pattern, line)
if m:
list_meas.append([float(m.group(2)), float(m.group(3)), float(m.group(4))])
return np.array(list_meas)
 
 
def read_log_mag_current(ac_id, filename):
"""Extracts raw magnetometer and current measurements from a log."""
f = open(filename, 'r')
pattern = re.compile("(\S+) "+ac_id+" IMU_MAG_CURRENT_CALIBRATION (\S+) (\S+) (\S+) (\S+)")
list_meas = []
while True:
line = f.readline().strip()
if line == '':
break
m = re.match(pattern, line)
if m:
list_meas.append([float(m.group(2)), float(m.group(3)), float(m.group(4)), float(m.group(5))])
return np.array(list_meas)
 
 
def filter_meas(meas, window_size, noise_threshold):
"""Select only non-noisy data."""
filtered_meas = []
filtered_idx = []
for i in range(window_size, len(meas)-window_size):
noise = meas[i-window_size:i+window_size, :].std(axis=0)
if linalg.norm(noise) < noise_threshold:
filtered_meas.append(meas[i, :])
filtered_idx.append(i)
return np.array(filtered_meas), filtered_idx
 
 
def get_min_max_guess(meas, scale):
"""Initial boundary based calibration."""
max_meas = meas[:, :].max(axis=0)
min_meas = meas[:, :].min(axis=0)
n = (max_meas + min_meas) / 2
sf = 2*scale/(max_meas - min_meas)
return np.array([n[0], n[1], n[2], sf[0], sf[1], sf[2]])
 
 
def scale_measurements(meas, p):
"""Scale the set of measurements."""
l_comp = []
l_norm = []
for m in meas[:, ]:
sm = (m - p[0:3])*p[3:6]
l_comp.append(sm)
l_norm.append(linalg.norm(sm))
return np.array(l_comp), np.array(l_norm)
 
 
def estimate_mag_current_relation(meas):
"""Calculate linear coefficient of magnetometer-current relation."""
coefficient = []
for i in range(0, 3):
gradient, intercept, r_value, p_value, std_err = stats.linregress(meas[:, 3], meas[:, i])
coefficient.append(gradient)
return coefficient
 
 
def print_xml(p, sensor, res):
"""Print xml for airframe file."""
print("")
print("<define name=\""+sensor+"_X_NEUTRAL\" value=\""+str(int(round(p[0])))+"\"/>")
print("<define name=\""+sensor+"_Y_NEUTRAL\" value=\""+str(int(round(p[1])))+"\"/>")
print("<define name=\""+sensor+"_Z_NEUTRAL\" value=\""+str(int(round(p[2])))+"\"/>")
print("<define name=\""+sensor+"_X_SENS\" value=\""+str(p[3]*2**res)+"\" integer=\"16\"/>")
print("<define name=\""+sensor+"_Y_SENS\" value=\""+str(p[4]*2**res)+"\" integer=\"16\"/>")
print("<define name=\""+sensor+"_Z_SENS\" value=\""+str(p[5]*2**res)+"\" integer=\"16\"/>")
 
 
def plot_results(block, measurements, flt_idx, flt_meas, cp0, np0, cp1, np1, sensor_ref):
"""Plot calibration results in 2D graphs."""
plt.subplot(3, 1, 1)
plt.plot(measurements[:, 0])
plt.plot(measurements[:, 1])
plt.plot(measurements[:, 2])
plt.plot(flt_idx, flt_meas[:, 0], 'ro')
plt.plot(flt_idx, flt_meas[:, 1], 'ro')
plt.plot(flt_idx, flt_meas[:, 2], 'ro')
plt.xlabel('sample number')
plt.ylabel('miligauss')
plt.title('Raw sensors')
 
plt.subplot(3, 2, 3)
plt.plot(cp0[:, 0])
plt.plot(cp0[:, 1])
plt.plot(cp0[:, 2])
plt.plot(-sensor_ref*np.ones(len(flt_meas)))
plt.plot(sensor_ref*np.ones(len(flt_meas)))
plt.xlabel('sample number')
plt.ylabel('-')
plt.title('First approximation')
 
plt.subplot(3, 2, 4)
plt.plot(np0)
plt.plot(sensor_ref*np.ones(len(flt_meas)))
plt.xlabel('sample number')
plt.ylabel('-')
plt.title('magnitude')
 
plt.subplot(3, 2, 5)
plt.plot(cp1[:, 0])
plt.plot(cp1[:, 1])
plt.plot(cp1[:, 2])
plt.plot(-sensor_ref*np.ones(len(flt_meas)))
plt.plot(sensor_ref*np.ones(len(flt_meas)))
plt.xlabel('sample number')
plt.ylabel('-')
plt.title('separate axes')
 
plt.subplot(3, 2, 6)
plt.plot(np1)
plt.plot(sensor_ref*np.ones(len(flt_meas)))
plt.xlabel('sample number')
plt.ylabel('-')
plt.title('magnitude')
 
# if we want to have another plot we only draw the figure (non-blocking)
# also in matplotlib before 1.0.0 there is only one call to show possible
if block:
plt.show()
else:
plt.draw()
 
 
def plot_mag_3d(measured, calibrated, p):
"""Plot magnetometer measurements on 3D sphere."""
# set up points for sphere and ellipsoid wireframes
u = np.r_[0:2 * np.pi:20j]
v = np.r_[0:np.pi:20j]
wx = np.outer(cos(u), sin(v))
wy = np.outer(sin(u), sin(v))
wz = np.outer(np.ones(np.size(u)), cos(v))
ex = p[0] * np.ones(np.size(u)) + np.outer(cos(u), sin(v)) / p[3]
ey = p[1] * np.ones(np.size(u)) + np.outer(sin(u), sin(v)) / p[4]
ez = p[2] * np.ones(np.size(u)) + np.outer(np.ones(np.size(u)), cos(v)) / p[5]
 
# measurements
mx = measured[:, 0]
my = measured[:, 1]
mz = measured[:, 2]
 
# calibrated values
cx = calibrated[:, 0]
cy = calibrated[:, 1]
cz = calibrated[:, 2]
 
# axes size
left = 0.02
bottom = 0.05
width = 0.46
height = 0.9
rect_l = [left, bottom, width, height]
rect_r = [left/2+0.5, bottom, width, height]
 
fig = plt.figure(figsize=plt.figaspect(0.5))
if matplotlib.__version__.startswith('0'):
ax = Axes3D(fig, rect=rect_l)
else:
ax = fig.add_subplot(1, 2, 1, position=rect_l, projection='3d')
# plot measurements
ax.scatter(mx, my, mz)
plt.hold(True)
# plot line from center to ellipsoid center
ax.plot([0.0, p[0]], [0.0, p[1]], [0.0, p[2]], color='black', marker='+', markersize=10)
# plot ellipsoid
ax.plot_wireframe(ex, ey, ez, color='grey', alpha=0.5)
 
# Create cubic bounding box to simulate equal aspect ratio
max_range = np.array([mx.max() - mx.min(), my.max() - my.min(), mz.max() - mz.min()]).max()
Xb = 0.5 * max_range * np.mgrid[-1:2:2, -1:2:2, -1:2:2][0].flatten() + 0.5 * (mx.max() + mx.min())
Yb = 0.5 * max_range * np.mgrid[-1:2:2, -1:2:2, -1:2:2][1].flatten() + 0.5 * (my.max() + my.min())
Zb = 0.5 * max_range * np.mgrid[-1:2:2, -1:2:2, -1:2:2][2].flatten() + 0.5 * (mz.max() + mz.min())
# add the fake bounding box:
for xb, yb, zb in zip(Xb, Yb, Zb):
ax.plot([xb], [yb], [zb], 'w')
 
ax.set_title('MAG raw with fitted ellipsoid and center offset')
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_zlabel('z')
 
if matplotlib.__version__.startswith('0'):
ax = Axes3D(fig, rect=rect_r)
else:
ax = fig.add_subplot(1, 2, 2, position=rect_r, projection='3d')
ax.plot_wireframe(wx, wy, wz, color='grey', alpha=0.5)
plt.hold(True)
ax.scatter(cx, cy, cz)
 
ax.set_title('MAG calibrated on unit sphere')
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_zlabel('z')
ax.set_xlim3d(-1, 1)
ax.set_ylim3d(-1, 1)
ax.set_zlim3d(-1, 1)
plt.show()
 
 
def read_turntable_log(ac_id, tt_id, filename, _min, _max):
""" Read a turntable log.
return an array which first column is turnatble and next 3 are gyro
"""
f = open(filename, 'r')
pattern_g = re.compile("(\S+) "+str(ac_id)+" IMU_GYRO_RAW (\S+) (\S+) (\S+)")
pattern_t = re.compile("(\S+) "+str(tt_id)+" IMU_TURNTABLE (\S+)")
last_tt = None
list_tt = []
while True:
line = f.readline().strip()
if line == '':
break
m = re.match(pattern_t, line)
if m:
last_tt = float(m.group(2))
m = re.match(pattern_g, line)
if m and last_tt and _min < last_tt < _max:
list_tt.append([last_tt, float(m.group(2)), float(m.group(3)), float(m.group(4))])
return np.array(list_tt)
/Modules/Sensors/MAG01A/SW/Python/calibration_data_3Dset.npz
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/Modules/Sensors/MAG01A/SW/PIC16F887/main.c
0,0 → 1,42
#include "main.h"
#include "HMC5883L.h"
#include <math.h>
 
void main()
{
setup_adc_ports(NO_ANALOGS|VSS_VDD);
setup_adc(ADC_CLOCK_DIV_2);
setup_spi(SPI_SS_DISABLED);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_ccp1(CCP_OFF);
setup_comparator(NC_NC_NC_NC);
 
printf("Magnetometr: \r\n",);
printf("(c)mlab.cz kaklik 2013: \r\n",);
printf("X, Y, Z \r\n",);
 
 
// Init the HMC5883L. Set Mode register for
// continuous measurements.
hmc5883l_write_reg(HMC5883L_CFG_A_REG, 0x18); // no average, maximal update range
hmc5883l_write_reg(HMC5883L_CFG_B_REG, 0x00); // minimal range
hmc5883l_write_reg(HMC5883L_MODE_REG, 0x00);
 
// Continuously read and display the x,y,z results.
// Wait at least 67 ms between reads, re the HMC5883L data sheet.
 
 
while(TRUE)
{
 
hmc5883l_read_data();
printf("%6Ld %6Ld %6Ld \n\r", compass.x, compass.y, compass.z);
delay_ms(100);
}
 
}
 
 
 
/Modules/Sensors/MAG01A/SW/PIC16F887/main.cof
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/Modules/Sensors/MAG01A/SW/PIC16F887/main.err
0,0 → 1,2
Memory usage: ROM=9% RAM=3% - 6%
0 Errors, 0 Warnings.
/Modules/Sensors/MAG01A/SW/PIC16F887/main.esym
0,0 → 1,601
D G "__PCM__" 0 44 ""4.106""
D G "__DEVICE__" 0 44 "887"
D G "__DATE__" 0 44 ""25-VIII-13""
D G "__TIME__" 0 44 ""18:55:43"" "Standard Header file for the PIC16F887 device ////////////////"
d G "PIN_A0" 2 20 "40"
d G "PIN_A1" 2 21 "41"
d G "PIN_A2" 2 22 "42"
d G "PIN_A3" 2 23 "43"
d G "PIN_A4" 2 24 "44"
d G "PIN_A5" 2 25 "45"
d G "PIN_A6" 2 26 "46"
d G "PIN_A7" 2 27 "47"
d G "PIN_B0" 2 29 "48"
d G "PIN_B1" 2 30 "49"
d G "PIN_B2" 2 31 "50"
d G "PIN_B3" 2 32 "51"
d G "PIN_B4" 2 33 "52"
d G "PIN_B5" 2 34 "53"
d G "PIN_B6" 2 35 "54"
d G "PIN_B7" 2 36 "55"
d G "PIN_C0" 2 38 "56"
d G "PIN_C1" 2 39 "57"
d G "PIN_C2" 2 40 "58"
d G "PIN_C3" 2 41 "59"
d G "PIN_C4" 2 42 "60"
d G "PIN_C5" 2 43 "61"
d G "PIN_C6" 2 44 "62"
d G "PIN_C7" 2 45 "63"
d G "PIN_D0" 2 47 "64"
d G "PIN_D1" 2 48 "65"
d G "PIN_D2" 2 49 "66"
d G "PIN_D3" 2 50 "67"
d G "PIN_D4" 2 51 "68"
d G "PIN_D5" 2 52 "69"
d G "PIN_D6" 2 53 "70"
d G "PIN_D7" 2 54 "71"
d G "PIN_E0" 2 56 "72"
d G "PIN_E1" 2 57 "73"
d G "PIN_E2" 2 58 "74"
d G "PIN_E3" 2 59 "75"
d G "FALSE" 2 62 "0"
d G "TRUE" 2 63 "1"
d G "BYTE" 2 65 "int8"
d G "BOOLEAN" 2 66 "int1"
d G "getc" 2 68 "getch"
d G "fgetc" 2 69 "getch"
d G "getchar" 2 70 "getch"
d G "putc" 2 71 "putchar"
d G "fputc" 2 72 "putchar"
d G "fgets" 2 73 "gets"
d G "fputs" 2 74 "puts"
d G "WDT_FROM_SLEEP" 2 79 "3"
d G "WDT_TIMEOUT" 2 80 "11"
d G "MCLR_FROM_SLEEP" 2 81 "19"
d G "MCLR_FROM_RUN" 2 82 "27"
d G "NORMAL_POWER_UP" 2 83 "25"
d G "BROWNOUT_RESTART" 2 84 "26"
d G "T0_INTERNAL" 2 91 "0"
d G "T0_EXT_L_TO_H" 2 92 "32"
d G "T0_EXT_H_TO_L" 2 93 "48"
d G "T0_DIV_1" 2 95 "8"
d G "T0_DIV_2" 2 96 "0"
d G "T0_DIV_4" 2 97 "1"
d G "T0_DIV_8" 2 98 "2"
d G "T0_DIV_16" 2 99 "3"
d G "T0_DIV_32" 2 100 "4"
d G "T0_DIV_64" 2 101 "5"
d G "T0_DIV_128" 2 102 "6"
d G "T0_DIV_256" 2 103 "7"
d G "T0_8_BIT" 2 106 "0"
d G "RTCC_INTERNAL" 2 108 "0" "The following are provided for compatibility"
d G "RTCC_EXT_L_TO_H" 2 109 "32" "with older compiler versions"
d G "RTCC_EXT_H_TO_L" 2 110 "48"
d G "RTCC_DIV_1" 2 111 "8"
d G "RTCC_DIV_2" 2 112 "0"
d G "RTCC_DIV_4" 2 113 "1"
d G "RTCC_DIV_8" 2 114 "2"
d G "RTCC_DIV_16" 2 115 "3"
d G "RTCC_DIV_32" 2 116 "4"
d G "RTCC_DIV_64" 2 117 "5"
d G "RTCC_DIV_128" 2 118 "6"
d G "RTCC_DIV_256" 2 119 "7"
d G "RTCC_8_BIT" 2 120 "0"
d G "WDT_18MS" 2 132 "8"
d G "WDT_36MS" 2 133 "9"
d G "WDT_72MS" 2 134 "10"
d G "WDT_144MS" 2 135 "11"
d G "WDT_288MS" 2 136 "12"
d G "WDT_576MS" 2 137 "13"
d G "WDT_1152MS" 2 138 "14"
d G "WDT_2304MS" 2 139 "15"
d G "WDT_ON" 2 143 "0x4100"
d G "WDT_OFF" 2 144 "0"
d G "WDT_DIV_16" 2 145 "0x100"
d G "WDT_DIV_8" 2 146 "0x300"
d G "WDT_DIV_4" 2 147 "0x500"
d G "WDT_DIV_2" 2 148 "0x700"
d G "WDT_TIMES_1" 2 149 "0x900" "Default"
d G "WDT_TIMES_2" 2 150 "0xB00"
d G "WDT_TIMES_4" 2 151 "0xD00"
d G "WDT_TIMES_8" 2 152 "0xF00"
d G "WDT_TIMES_16" 2 153 "0x1100"
d G "WDT_TIMES_32" 2 154 "0x1300"
d G "WDT_TIMES_64" 2 155 "0x1500"
d G "WDT_TIMES_128" 2 156 "0x1700"
d G "T1_DISABLED" 2 162 "0"
d G "T1_INTERNAL" 2 163 "5"
d G "T1_EXTERNAL" 2 164 "7"
d G "T1_EXTERNAL_SYNC" 2 165 "3"
d G "T1_CLK_OUT" 2 167 "8"
d G "T1_DIV_BY_1" 2 169 "0"
d G "T1_DIV_BY_2" 2 170 "0x10"
d G "T1_DIV_BY_4" 2 171 "0x20"
d G "T1_DIV_BY_8" 2 172 "0x30"
d G "T1_GATE" 2 174 "0x40"
d G "T1_GATE_INVERTED" 2 175 "0xC0"
d G "T2_DISABLED" 2 180 "0"
d G "T2_DIV_BY_1" 2 181 "4"
d G "T2_DIV_BY_4" 2 182 "5"
d G "T2_DIV_BY_16" 2 183 "6"
d G "CCP_OFF" 2 189 "0"
d G "CCP_CAPTURE_FE" 2 190 "4"
d G "CCP_CAPTURE_RE" 2 191 "5"
d G "CCP_CAPTURE_DIV_4" 2 192 "6"
d G "CCP_CAPTURE_DIV_16" 2 193 "7"
d G "CCP_COMPARE_SET_ON_MATCH" 2 194 "8"
d G "CCP_COMPARE_CLR_ON_MATCH" 2 195 "9"
d G "CCP_COMPARE_INT" 2 196 "0xA"
d G "CCP_COMPARE_RESET_TIMER" 2 197 "0xB"
d G "CCP_PWM" 2 198 "0xC"
d G "CCP_PWM_PLUS_1" 2 199 "0x1c"
d G "CCP_PWM_PLUS_2" 2 200 "0x2c"
d G "CCP_PWM_PLUS_3" 2 201 "0x3c"
d G "CCP_PWM_H_H" 2 206 "0x0c"
d G "CCP_PWM_H_L" 2 207 "0x0d"
d G "CCP_PWM_L_H" 2 208 "0x0e"
d G "CCP_PWM_L_L" 2 209 "0x0f"
d G "CCP_PWM_FULL_BRIDGE" 2 211 "0x40"
d G "CCP_PWM_FULL_BRIDGE_REV" 2 212 "0xC0"
d G "CCP_PWM_HALF_BRIDGE" 2 213 "0x80"
d G "CCP_SHUTDOWN_ON_COMP1" 2 215 "0x100000"
d G "CCP_SHUTDOWN_ON_COMP2" 2 216 "0x200000"
d G "CCP_SHUTDOWN_ON_COMP" 2 217 "0x300000"
d G "CCP_SHUTDOWN_ON_INT0" 2 218 "0x400000"
d G "CCP_SHUTDOWN_ON_COMP1_INT0" 2 219 "0x500000"
d G "CCP_SHUTDOWN_ON_COMP2_INT0" 2 220 "0x600000"
d G "CCP_SHUTDOWN_ON_COMP_INT0" 2 221 "0x700000"
d G "CCP_SHUTDOWN_AC_L" 2 223 "0x000000"
d G "CCP_SHUTDOWN_AC_H" 2 224 "0x040000"
d G "CCP_SHUTDOWN_AC_F" 2 225 "0x080000"
d G "CCP_SHUTDOWN_BD_L" 2 227 "0x000000"
d G "CCP_SHUTDOWN_BD_H" 2 228 "0x010000"
d G "CCP_SHUTDOWN_BD_F" 2 229 "0x020000"
d G "CCP_SHUTDOWN_RESTART" 2 231 "0x80000000"
d G "CCP_PULSE_STEERING_A" 2 233 "0x01000000"
d G "CCP_PULSE_STEERING_B" 2 234 "0x02000000"
d G "CCP_PULSE_STEERING_C" 2 235 "0x04000000"
d G "CCP_PULSE_STEERING_D" 2 236 "0x08000000"
d G "CCP_PULSE_STEERING_SYNC" 2 237 "0x10000000"
d G "SPI_MASTER" 2 245 "0x20"
d G "SPI_SLAVE" 2 246 "0x24"
d G "SPI_L_TO_H" 2 247 "0"
d G "SPI_H_TO_L" 2 248 "0x10"
d G "SPI_CLK_DIV_4" 2 249 "0"
d G "SPI_CLK_DIV_16" 2 250 "1"
d G "SPI_CLK_DIV_64" 2 251 "2"
d G "SPI_CLK_T2" 2 252 "3"
d G "SPI_SS_DISABLED" 2 253 "1"
d G "SPI_SAMPLE_AT_END" 2 255 "0x8000"
d G "SPI_XMIT_L_TO_H" 2 256 "0x4000"
d G "UART_ADDRESS" 2 262 "2"
d G "UART_DATA" 2 263 "4"
d G "UART_AUTODETECT" 2 264 "8"
d G "UART_AUTODETECT_NOWAIT" 2 265 "9"
d G "UART_WAKEUP_ON_RDA" 2 266 "10"
d G "UART_SEND_BREAK" 2 267 "13"
d G "NC_NC_NC_NC" 2 273 "0x00"
d G "NC_NC" 2 274 "0x00"
d G "CP1_A0_A3" 2 277 "0x00090080"
d G "CP1_A1_A3" 2 278 "0x000A0081"
d G "CP1_B3_A3" 2 279 "0x00880082"
d G "CP1_B1_A3" 2 280 "0x00280083"
d G "CP1_A0_VREF" 2 281 "0x00010084"
d G "CP1_A1_VREF" 2 282 "0x00020085"
d G "CP1_B3_VREF" 2 283 "0x00800086"
d G "CP1_B1_VREF" 2 284 "0x00200087"
d G "CP1_OUT_ON_A4" 2 286 "0x00000020"
d G "CP1_INVERT" 2 287 "0x00000010"
d G "CP1_ABSOLUTE_VREF" 2 288 "0x20000000"
d G "CP2_A0_A2" 2 291 "0x00058000"
d G "CP2_A1_A2" 2 292 "0x00068100"
d G "CP2_B3_A2" 2 293 "0x00848200"
d G "CP2_B1_A2" 2 294 "0x00248300"
d G "CP2_A0_VREF" 2 295 "0x00018400"
d G "CP2_A1_VREF" 2 296 "0x00028500"
d G "CP2_B3_VREF" 2 297 "0x00808600"
d G "CP2_B1_VREF" 2 298 "0x00208700"
d G "CP2_OUT_ON_A5" 2 300 "0x00002000"
d G "CP2_INVERT" 2 301 "0x00001000"
d G "CP2_ABSOLUTE_VREF" 2 302 "0x10000000"
d G "CP2_T1_SYNC" 2 305 "0x01000000"
d G "CP2_T1_GATE" 2 306 "0x02000000"
d G "VREF_LOW" 2 315 "0xa0"
d G "VREF_HIGH" 2 316 "0x80"
d G "OSC_31KHZ" 2 322 "1"
d G "OSC_125KHZ" 2 323 "0x11"
d G "OSC_250KHZ" 2 324 "0x21"
d G "OSC_500KHZ" 2 325 "0x31"
d G "OSC_1MHZ" 2 326 "0x41"
d G "OSC_2MHZ" 2 327 "0x51"
d G "OSC_4MHZ" 2 328 "0x61"
d G "OSC_8MHZ" 2 329 "0x71"
d G "OSC_INTRC" 2 330 "1"
d G "OSC_NORMAL" 2 331 "0"
d G "OSC_STATE_STABLE" 2 333 "4"
d G "OSC_31KHZ_STABLE" 2 334 "2"
d G "ADC_OFF" 2 342 "0" "ADC Off"
d G "ADC_CLOCK_DIV_2" 2 343 "0x100"
d G "ADC_CLOCK_DIV_8" 2 344 "0x40"
d G "ADC_CLOCK_DIV_32" 2 345 "0x80"
d G "ADC_CLOCK_INTERNAL" 2 346 "0xc0" "Internal 2-6us"
d G "sAN0" 2 350 "1" "| A0"
d G "sAN1" 2 351 "2" "| A1"
d G "sAN2" 2 352 "4" "| A2"
d G "sAN3" 2 353 "8" "| A3"
d G "sAN4" 2 354 "16" "| A5"
d G "sAN5" 2 355 "32" "| E0"
d G "sAN6" 2 356 "64" "| E1"
d G "sAN7" 2 357 "128" "| E2"
d G "sAN8" 2 358 "0x10000" "| B2"
d G "sAN9" 2 359 "0x20000" "| B3"
d G "sAN10" 2 360 "0x40000" "| B1"
d G "sAN11" 2 361 "0x80000" "| B4"
d G "sAN12" 2 362 "0x100000" "| B0"
d G "sAN13" 2 363 "0x200000" "| B5"
d G "NO_ANALOGS" 2 364 "0" "None"
d G "ALL_ANALOG" 2 365 "0x1F00FF" "A0 A1 A2 A3 A5 E0 E1 E2 B0 B1 B2 B3 B4 B5"
d G "VSS_VDD" 2 368 "0x0000" "| Range 0-Vdd"
d G "VSS_VREF" 2 369 "0x1000" "| Range 0-Vref"
d G "VREF_VREF" 2 370 "0x3000" "| Range Vref-Vref"
d G "VREF_VDD" 2 371 "0x2000" "| Range Vref-Vdd"
d G "ADC_START_AND_READ" 2 375 "7" "This is the default if nothing is specified"
d G "ADC_START_ONLY" 2 376 "1"
d G "ADC_READ_ONLY" 2 377 "6"
d G "L_TO_H" 2 389 "0x40"
d G "H_TO_L" 2 390 "0"
d G "GLOBAL" 2 392 "0x0BC0"
d G "INT_RTCC" 2 393 "0x000B20"
d G "INT_RB" 2 394 "0x01FF0B08"
d G "INT_EXT_L2H" 2 395 "0x50000B10"
d G "INT_EXT_H2L" 2 396 "0x60000B10"
d G "INT_EXT" 2 397 "0x000B10"
d G "INT_AD" 2 398 "0x008C40"
d G "INT_TBE" 2 399 "0x008C10"
d G "INT_RDA" 2 400 "0x008C20"
d G "INT_TIMER1" 2 401 "0x008C01"
d G "INT_TIMER2" 2 402 "0x008C02"
d G "INT_CCP1" 2 403 "0x008C04"
d G "INT_CCP2" 2 404 "0x008D01"
d G "INT_SSP" 2 405 "0x008C08"
d G "INT_BUSCOL" 2 406 "0x008D08"
d G "INT_EEPROM" 2 407 "0x008D10"
d G "INT_TIMER0" 2 408 "0x000B20"
d G "INT_OSC_FAIL" 2 409 "0x008D80"
d G "INT_COMP" 2 410 "0x008D20"
d G "INT_COMP2" 2 411 "0x008D40"
d G "INT_ULPWU" 2 412 "0x008D04"
d G "INT_RB0" 2 413 "0x0010B08"
d G "INT_RB1" 2 414 "0x0020B08"
d G "INT_RB2" 2 415 "0x0040B08"
d G "INT_RB3" 2 416 "0x0080B08"
d G "INT_RB4" 2 417 "0x0100B08"
d G "INT_RB5" 2 418 "0x0200B08"
d G "INT_RB6" 2 419 "0x0400B08"
d G "INT_RB7" 2 420 "0x0800B08"
D G "HMC5883L_WRT_ADDR" 3 2 "0x3C"
D G "HMC5883L_READ_ADDR" 3 3 "0x3D"
D G "HMC5883L_CFG_A_REG" 3 6 "0x00"
D G "HMC5883L_CFG_B_REG" 3 7 "0x01"
D G "HMC5883L_MODE_REG" 3 8 "0x02"
D G "HMC5883L_X_MSB_REG" 3 9 "0x03"
D G "MAG_ROZ088" 3 13 "0x00"
D G "MAG_ROZ130" 3 14 "0x20"
D G "MAG_ROZ190" 3 15 "0x40"
D G "MAG_ROZ250" 3 16 "0x60"
D G "MAG_ROZ400" 3 17 "0x80"
D G "MAG_ROZ470" 3 18 "0xA0"
D G "MAG_ROZ560" 3 19 "0xC0"
D G "MAG_ROZ810" 3 20 "0xE0"
C L "hmc5883l_write_reg" 4 2 1 "FUNCTION"
F G "hmc5883l_write_reg" 4 4 "void(int8 reg,int8 data)"
V L "reg" 4 4 "int8"
V L "data" 4 4 "int8"
F G "hmc5883l_read_reg" 4 14 "int8(int8 reg)"
V L "reg" 4 14 "int8"
V L "retval" 4 16 "int8"
T G "hmc5883l_result" 4 35 "{sint16 x,sint16 y,sint16 z}" "This global structure holds the values read"
V G "compass" 4 39 "hmc5883l_result"
F G "hmc5883l_read_data" 4 42 "void()"
V L "x_lsb" 4 44 "int8"
V L "x_msb" 4 45 "int8"
V L "y_lsb" 4 47 "int8"
V L "y_msb" 4 48 "int8"
V L "z_lsb" 4 50 "int8"
V L "z_msb" 4 51 "int8"
C L "hmc5883l_read_data" 4 2 1 "FUNCTION"
C L "hmc5883l_read_data" 4 2 1 "FUNCTION"
C L "hmc5883l_read_data" 4 2 1 "FUNCTION"
D G "MATH_H" 5 21 ""
D G "PI" 5 26 "3.1415926535897932"
D G "SQRT2" 5 29 "1.4142135623730950"
C L "CEIL_FLOOR" 5 2 3 "FUNCTION"
F G "CEIL_FLOOR" 5 36 "float(float x,int8 n)"
V L "x" 5 36 "float"
V L "n" 5 36 "int8"
V L "y" 5 38 "float"
V L "res" 5 38 "float"
V L "l" 5 39 "int16"
V L "s" 5 40 "int1"
C L "floor" 5 2 5 "FUNCTION"
F G "floor" 5 192 "float(float x)"
V L "x" 5 192 "float"
C L "ceil" 5 2 5 "FUNCTION"
F G "ceil" 5 218 "float(float x)"
V L "x" 5 218 "float"
D G "fabs" 5 244 "abs"
C L "fmod" 5 2 6 "FUNCTION"
F G "fmod" 5 256 "float(float x,float y)"
V L "x" 5 256 "float"
V L "y" 5 256 "float"
V L "i" 5 258 "float"
D G "LN2" 5 319 "0.6931471805599453"
V G "pe" 5 321 "float[6]"
F G "exp" 5 325 "float(float x)"
V L "x" 5 325 "float"
V L "y" 5 327 "float"
V L "res" 5 327 "float"
V L "r" 5 327 "float"
V L "n" 5 331 "sint8"
V L "s" 5 332 "int1"
C L "exp" 5 2 1 "FUNCTION"
V G "pl" 5 496 "float[4]"
V G "ql" 5 497 "float[4]"
C L "log" 5 2 3 "FUNCTION"
F G "log" 5 505 "float(float x)"
V L "x" 5 505 "float"
V L "y" 5 507 "float"
V L "res" 5 507 "float"
V L "r" 5 507 "float"
V L "y2" 5 507 "float"
V L "n" 5 511 "sint8"
C L "log" 5 2 1 "FUNCTION"
D G "LN10" 5 729 "2.3025850929940456"
C L "log10" 5 2 3 "FUNCTION"
F G "log10" 5 737 "float(float x)"
V L "x" 5 737 "float"
V L "r" 5 739 "float"
C L "modf" 5 2 8 "FUNCTION"
F G "modf" 5 778 "float(float value,*float iptr)"
V L "value" 5 778 "float"
V L "iptr" 5 778 "*float"
C L "pwr" 5 2 6 "FUNCTION"
F G "pwr" 5 806 "float(float x,float y)"
V L "x" 5 806 "float"
V L "y" 5 806 "float"
C L "pow" 5 2 7 "FUNCTION"
F G "pow" 5 869 "float(float x,float y)"
V L "x" 5 869 "float"
V L "y" 5 869 "float"
C L "sqrt" 5 2 5 "FUNCTION"
F G "sqrt" 5 930 "float(float x)"
V L "x" 5 930 "float"
V L "y" 5 932 "float"
V L "res" 5 932 "float"
V L "p" 5 936 "*int8"
D G "PI_DIV_BY_TWO" 5 1125 "1.5707963267948966"
C L "cos" 5 2 3 "FUNCTION"
F G "cos" 5 1136 "float(float x)"
V L "x" 5 1136 "float"
V L "y" 5 1138 "float"
V L "t" 5 1138 "float"
V L "t2" 5 1138 "float"
V L "quad" 5 1139 "int8"
V L "i" 5 1139 "int8"
V L "frac" 5 1140 "float"
V L "p" 5 1141 "float[6]" "by the series definition for cosine"
C L "cos" 5 2 1 "FUNCTION"
C L "cos" 5 2 2 "FUNCTION"
C L "cos" 5 2 1 "FUNCTION"
C L "cos" 5 2 1 "FUNCTION"
C L "cos" 5 2 1 "FUNCTION"
C L "cos" 5 2 1 "FUNCTION"
C L "cos" 5 2 1 "FUNCTION"
C L "cos" 5 2 1 "FUNCTION"
C L "sin" 5 2 5 "FUNCTION"
F G "sin" 5 1278 "float(float x)"
V L "x" 5 1278 "float"
C L "tan" 5 2 5 "FUNCTION"
F G "tan" 5 1304 "float(float x)"
V L "x" 5 1304 "float"
V L "c" 5 1306 "float"
V L "s" 5 1306 "float"
V G "pas" 5 1344 "float[3]"
V G "qas" 5 1345 "float[3]"
F G "ASIN_COS" 5 1347 "float(float x,int8 n)"
V L "x" 5 1347 "float"
V L "n" 5 1347 "int8"
V L "y" 5 1349 "float"
V L "res" 5 1349 "float"
V L "r" 5 1349 "float"
V L "y2" 5 1349 "float"
V L "s" 5 1350 "int1"
C L "ASIN_COS" 5 2 1 "FUNCTION"
C L "ASIN_COS" 5 2 1 "FUNCTION"
C L "asin" 5 2 5 "FUNCTION"
F G "asin" 5 1493 "float(float x)"
V L "x" 5 1493 "float"
V L "r" 5 1495 "float"
C L "acos" 5 2 5 "FUNCTION"
F G "acos" 5 1527 "float(float x)"
V L "x" 5 1527 "float"
V L "r" 5 1529 "float"
V G "pat" 5 1555 "float[4]"
V G "qat" 5 1556 "float[4]"
C L "atan" 5 2 3 "FUNCTION"
F G "atan" 5 1564 "float(float x)"
V L "x" 5 1564 "float"
V L "y" 5 1566 "float"
V L "res" 5 1566 "float"
V L "r" 5 1566 "float"
V L "s" 5 1567 "int1"
V L "flag" 5 1567 "int1"
C L "atan" 5 2 1 "FUNCTION"
C L "atan2" 5 2 7 "FUNCTION"
F G "atan2" 5 1697 "float(float y,float x)"
V L "y" 5 1697 "float"
V L "x" 5 1697 "float"
V L "z" 5 1699 "float"
V L "sign" 5 1700 "int1"
V L "quad" 5 1701 "int8"
C L "atan2" 5 2 1 "FUNCTION"
C L "atan2" 5 2 1 "FUNCTION"
C L "cosh" 5 2 7 "FUNCTION"
F G "cosh" 5 1919 "float(float x)"
V L "x" 5 1919 "float"
C L "sinh" 5 2 6 "FUNCTION"
F G "sinh" 5 1946 "float(float x)"
V L "x" 5 1946 "float"
C L "tanh" 5 2 6 "FUNCTION"
F G "tanh" 5 1976 "float(float x)"
V L "x" 5 1976 "float"
D G "LOG2" 5 2006 ".30102999566398119521"
F G "frexp" 5 2007 "float(float x,*sint8 exp)"
V L "x" 5 2007 "float"
V L "exp" 5 2007 "*sint8"
V L "res" 5 2009 "float"
V L "sign" 5 2010 "int1"
C L "ldexp" 5 2 6 "FUNCTION"
F G "ldexp" 5 2152 "float(float value,sint8 exp)"
V L "value" 5 2152 "float"
V L "exp" 5 2152 "sint8"
C L "MAIN" 5 2 2 "FUNCTION"
F G "MAIN" 0 5 "void()"
C L "MAIN" 0 21 2 "FUNCTION"
C L "MAIN" 0 21 1 "FUNCTION"
C L "MAIN" 0 21 1 "FUNCTION"
C L "MAIN" 0 21 2 "FUNCTION"
F B "reset_cpu" 0 0
F B "abs" 1 0
F B "sleep_ulpwu" 1 0
F B "sleep" 0 0
F B "delay_cycles" 1 0
F B "read_bank" 2 0
F B "write_bank" 3 0
F B "shift_left" 2 2
F B "shift_right" 2 2
F B "rotate_left" 2 0
F B "rotate_right" 2 0
F B "_mul" 2 0
F B "memset" 3 0
F B "isamoung" 2 0
F B "isamong" 2 0
F B "bit_set" 2 0
F B "bit_clear" 2 0
F B "bit_test" 2 0
F B "toupper" 1 0
F B "tolower" 1 0
F B "swap" 1 0
F B "printf" 1 255
F B "fprintf" 1 255
F B "sprintf" 1 255
F B "make8" 2 0
F B "make16" 2 0
F B "make32" 1 255
F B "label_address" 1 1
F B "goto_address" 1 0
F B "_va_arg" 1 0
F B "offsetofbit" 2 2
F B "enable_interrupts" 1 0
F B "disable_interrupts" 1 0
F B "interrupt_active" 1 0
F B "clear_interrupt" 1 0
F B "jump_to_isr" 1 0
F B "ext_int_edge" 1 2
F B "read_eeprom" 1 0
F B "write_eeprom" 2 0
F B "read_program_eeprom" 1 0
F B "write_program_eeprom" 2 0
F B "write_program_memory" 4 0
F B "write_program_memory8" 4 0
F B "read_program_memory" 4 0
F B "read_program_memory8" 4 0
F B "erase_program_eeprom" 1 0
F B "strcpy" 2 0
F B "memcpy" 3 0
F B "strstr100" 2 0
F B "output_high" 1 0
F B "output_low" 1 0
F B "input" 1 0
F B "input_state" 1 0
F B "output_float" 1 0
F B "output_drive" 1 0
F B "output_bit" 1 1
F B "output_toggle" 1 0
F B "output_a" 1 0
F B "output_b" 1 0
F B "output_c" 1 0
F B "output_d" 1 0
F B "output_e" 1 0
F B "input_a" 0 0
F B "input_b" 0 0
F B "input_c" 0 0
F B "input_d" 0 0
F B "input_e" 0 0
F B "set_tris_a" 1 0
F B "set_tris_b" 1 0
F B "set_tris_c" 1 0
F B "set_tris_d" 1 0
F B "set_tris_e" 1 0
F B "get_tris_a" 0 0
F B "get_tris_b" 0 0
F B "get_tris_c" 0 0
F B "get_tris_d" 0 0
F B "get_tris_e" 0 0
F B "input_change_a" 0 0
F B "input_change_b" 0 0
F B "input_change_c" 0 0
F B "input_change_d" 0 0
F B "input_change_e" 0 0
F B "port_b_pullups" 1 0
F B "setup_counters" 2 0
F B "setup_wdt" 1 0
F B "restart_cause" 0 0
F B "restart_wdt" 0 0
F B "get_rtcc" 0 0
F B "set_rtcc" 1 0
F B "get_timer0" 0 0
F B "set_timer0" 1 0
F B "setup_comparator" 1 0
F B "setup_port_a" 1 0
F B "setup_adc_ports" 1 0
F B "setup_adc" 1 0
F B "set_adc_channel" 1 0
F B "read_adc" 0 1
F B "adc_done" 0 0
F B "setup_timer_0" 1 0
F B "setup_vref" 1 0
F B "setup_timer_1" 1 0
F B "get_timer1" 0 0
F B "set_timer1" 1 0
F B "setup_timer_2" 3 0
F B "get_timer2" 0 0
F B "set_timer2" 1 0
F B "setup_ccp1" 1 2
F B "set_pwm1_duty" 1 0
F B "setup_ccp2" 1 0
F B "set_pwm2_duty" 1 0
F B "setup_oscillator" 1 2
F B "setup_spi" 1 0
F B "spi_read" 0 1
F B "spi_write" 1 0
F B "spi_data_is_in" 0 0
F B "setup_spi2" 1 0
F B "spi_read2" 0 1
F B "spi_write2" 1 0
F B "spi_data_is_in2" 0 0
F B "brownout_enable" 1 0
F B "delay_ms" 1 0
F B "delay_us" 1 0
F B "i2c_read" 0 2
F B "i2c_write" 1 2
F B "i2c_start" 0 2
F B "i2c_stop" 0 1
F B "i2c_isr_state" 0 1
F B "putchar" 1 2
F B "puts" 1 2
F B "getch" 0 1
F B "gets" 1 3
F B "kbhit" 0 1
F B "set_uart_speed" 1 3
F B "setup_uart" 1 3
/Modules/Sensors/MAG01A/SW/PIC16F887/main.h
0,0 → 1,21
#include <16F887.h>
#device adc=8
 
#FUSES NOWDT //No Watch Dog Timer
#FUSES INTRC //Internal RC Osc
#FUSES NOPUT //No Power Up Timer
#FUSES MCLR //Master Clear pin enabled
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOCPD //No EE protection
#FUSES NOBROWNOUT //No brownout reset
#FUSES IESO //Internal External Switch Over mode enabled
#FUSES FCMEN //Fail-safe clock monitor enabled
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOWRT //Program memory not write protected
#FUSES BORV40 //Brownout reset at 4.0V
 
#use delay(clock=8000000)
#use i2c(Master,Slow,sda=PIN_C4,scl=PIN_C3)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8) //rcv TXD xmit RXD
 
/Modules/Sensors/MAG01A/SW/PIC16F887/main.hex
0,0 → 1,100
:1000000002308A003C2A0000CD306737653AEF366F
:10001000653A721D20100D050000A831A936EC309C
:100020006217633DA035E135EC346B103218B1191D
:100030003A10A0060A005816A02C2C105A100D05D4
:100040000001831603178C170C14000000008312A4
:100050000C087F39031967280313A70003170D083D
:100060000313A80003170F080313A90027080C1E89
:1000700037289900280803178D0003132908031750
:100080008F0083168C170C140000000083120C0DD7
:100090000E0D7F39031967280313A70003170D08F6
:1000A0000313A80003170F080313A90027080C1E49
:1000B00057289900280803178D00031329080317F0
:1000C0008F008D0A03198F0A0313212803170313C6
:1000D00008000830F80000008711A01120088316DE
:1000E000870000008312AD0D0712031C7D28201627
:1000F0002008831687008128831220122008831687
:10010000870000008312A015200883168700831241
:10011000871D8828F80B6B2800008711A011200884
:10012000831687000000831220162008831687009C
:10013000000000008312A015200883168700831298
:10014000871DA028F8010000071A78148711A01154
:1001500020088316870083120712201220088316B6
:1001600087008312080020162008831687000000ED
:100170008312A0152008831687000000831207123F
:100180002012200883168700000083128711A01117
:100190002008831687003C308312AD0069202708B1
:1001A000AD0069202808AD006920201220088316C0
:1001B000870000008312A015200883168700831291
:1001C000871DE0280000E428000020162008831680
:1001D00087000000831208000830AE007708AF00E7
:1001E000201620088316870000008312A01520081F
:1001F000831687008312871DFB28071A0314071E26
:100200000310F80D0000A011200883168700831248
:100210008711AE0BF02820162008831687000000F7
:10022000831207122F0803191A2920122008831697
:10023000870083120000A015200883168700831210
:10024000871D202900008711A01120088316870030
:1002500000008312071220122008831687008312E1
:100260000800201620088316870000008312A015BE
:10027000200883168700000083120712201220082E
:1002800083168700000083128711A01120088316AF
:1002900087003C308312AD0069200330AD00692037
:1002A000201620088316870000008312A01520085E
:1002B0008316870000008312871D5C290712201215
:1002C000200883168700000083128711A0112008E0
:1002D000831687003D308312AD0069200130F7009E
:1002E000EC207808A8000130F700EC207808A7007F
:1002F0000130F700EC207808AC000130F700EC206A
:100300007808AB000130F700EC207808AA00F7016C
:10031000EC207808A900201220088316870000002E
:100320008312A0152008831687008312871D962943
:1003300000009A290000201620088316870000007C
:1003400083122808A2002708A1002A08A40029086F
:10035000A3002C08A6002B08A5008A110A12CC2A9B
:10036000AF010408AE002F10831B2F14A81FC02953
:10037000AE172E1EAE0AA709A809A70A0319A80AD4
:10038000280EF038AA00AA07E23EAB00323EAD00CC
:1003900028080F39AB07AB07AD07E93EAC00AC0747
:1003A000AC07270E0F39AC07AD07AC0DAD0DAD098D
:1003B000AD0D27080F39AD07AA0D0730A9000A3087
:1003C000AD07AC03031CE029AC07AB03031CE42915
:1003D000AB07AA03031CE829AA07A903031CEC29FD
:1003E00029308400831307302E052E1384032E0535
:1003F000031D012A2E1A840A2E1A012A2030F70022
:100400001E2A84072D30040203192E170008F70056
:10041000031D122A2E1B122A2E1A222AAE19122A64
:1004200020301D2AAE1F1A2A2D30F70084032E1308
:10043000AE131E2AAE152E123030F70777080C1EA9
:100440001F2A9900840A2E1F022A080027308400E0
:10045000831300080319392A0230F800F701F70B5B
:100460002F2AF80B2E2A9730F700F70B352A800B2E
:100470002C2A8A110A12F82A840183131F3083055B
:10048000713083168F000F08031787110C30031388
:100490009900A230980090308312980083160317B9
:1004A0000908C039890003131F129F120030031777
:1004B00088008312870188018901FF300313A0009F
:1004C000A101A201A301A401A501A601831603179E
:1004D0000908C039890003131F129F120030031747
:1004E0008800831203131F139F1383169F13831215
:1004F0001F149412A012200883168700831220165E
:100500002008831687008312A01120088316870015
:100510000130831294000030831694000108C7391B
:1005200008388100831290010030F80092000030FA
:1005300083169200831220152008831687008312E9
:10054000970183169B019C0101309D0083120317C4
:1005500087018801890104308D0000308F0003136A
:1005600021200D3003178D0000308F000313212050
:100570001B3003178D0000308F0003132120A701CB
:100580001830A800B3200130A700A801B320023022
:10059000A700A801B3203129003084002208A80058
:1005A0002108A700B02120300C1ED42A9900003069
:1005B00084002408A8002308A700B02120300C1EC6
:1005C000DF2A9900003084002608A8002508A7002B
:1005D000B02120300C1EEA2A99000A300C1EEE2AA7
:1005E00099000D300C1EF22A99006430A700262ACB
:0405F000CB2A6300AF
:04400E00F52CFF3F4F
:00000001FF
;PIC16F887
;CRC=2B66 CREATED="25-VIII-13 18:55"
/Modules/Sensors/MAG01A/SW/PIC16F887/main.lst
0,0 → 1,2904
CCS PCM C Compiler, Version 4.106, 47914 25-VIII-13 18:55
 
Filename: Z:\home\kaklik\svnMLAB\Modules\Sensors\MAG01A\SW\PIC16F887\main.lst
 
ROM used: 762 words (9%)
Largest free fragment is 2048
RAM used: 12 (3%) at main() level
21 (6%) worst case
Stack: 2 locations
 
*
0000: MOVLW 02
0001: MOVWF 0A
0002: GOTO 23C
0003: NOP
.................... #include "main.h"
.................... #include <16F887.h>
.................... //////// Standard Header file for the PIC16F887 device ////////////////
.................... #device PIC16F887
.................... #list
....................
.................... #device adc=8
....................
.................... #FUSES NOWDT //No Watch Dog Timer
.................... #FUSES INTRC //Internal RC Osc
.................... #FUSES NOPUT //No Power Up Timer
.................... #FUSES MCLR //Master Clear pin enabled
.................... #FUSES NOPROTECT //Code not protected from reading
.................... #FUSES NOCPD //No EE protection
.................... #FUSES NOBROWNOUT //No brownout reset
.................... #FUSES IESO //Internal External Switch Over mode enabled
.................... #FUSES FCMEN //Fail-safe clock monitor enabled
.................... #FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
.................... #FUSES NODEBUG //No Debug mode for ICD
.................... #FUSES NOWRT //Program memory not write protected
.................... #FUSES BORV40 //Brownout reset at 4.0V
....................
.................... #use delay(clock=8000000)
*
0226: MOVLW 27
0227: MOVWF 04
0228: BCF 03.7
0229: MOVF 00,W
022A: BTFSC 03.2
022B: GOTO 239
022C: MOVLW 02
022D: MOVWF 78
022E: CLRF 77
022F: DECFSZ 77,F
0230: GOTO 22F
0231: DECFSZ 78,F
0232: GOTO 22E
0233: MOVLW 97
0234: MOVWF 77
0235: DECFSZ 77,F
0236: GOTO 235
0237: DECFSZ 00,F
0238: GOTO 22C
0239: BCF 0A.3
023A: BCF 0A.4
023B: GOTO 2F8 (RETURN)
.................... #use i2c(Master,Slow,sda=PIN_C4,scl=PIN_C3)
*
0069: MOVLW 08
006A: MOVWF 78
006B: NOP
006C: BCF 07.3
006D: BCF 20.3
006E: MOVF 20,W
006F: BSF 03.5
0070: MOVWF 07
0071: NOP
0072: BCF 03.5
0073: RLF 2D,F
0074: BCF 07.4
0075: BTFSS 03.0
0076: GOTO 07D
0077: BSF 20.4
0078: MOVF 20,W
0079: BSF 03.5
007A: MOVWF 07
007B: GOTO 081
007C: BCF 03.5
007D: BCF 20.4
007E: MOVF 20,W
007F: BSF 03.5
0080: MOVWF 07
0081: NOP
0082: BCF 03.5
0083: BSF 20.3
0084: MOVF 20,W
0085: BSF 03.5
0086: MOVWF 07
0087: BCF 03.5
0088: BTFSS 07.3
0089: GOTO 088
008A: DECFSZ 78,F
008B: GOTO 06B
008C: NOP
008D: BCF 07.3
008E: BCF 20.3
008F: MOVF 20,W
0090: BSF 03.5
0091: MOVWF 07
0092: NOP
0093: BCF 03.5
0094: BSF 20.4
0095: MOVF 20,W
0096: BSF 03.5
0097: MOVWF 07
0098: NOP
0099: NOP
009A: BCF 03.5
009B: BSF 20.3
009C: MOVF 20,W
009D: BSF 03.5
009E: MOVWF 07
009F: BCF 03.5
00A0: BTFSS 07.3
00A1: GOTO 0A0
00A2: CLRF 78
00A3: NOP
00A4: BTFSC 07.4
00A5: BSF 78.0
00A6: BCF 07.3
00A7: BCF 20.3
00A8: MOVF 20,W
00A9: BSF 03.5
00AA: MOVWF 07
00AB: BCF 03.5
00AC: BCF 07.4
00AD: BCF 20.4
00AE: MOVF 20,W
00AF: BSF 03.5
00B0: MOVWF 07
00B1: BCF 03.5
00B2: RETURN
*
00EC: MOVLW 08
00ED: MOVWF 2E
00EE: MOVF 77,W
00EF: MOVWF 2F
00F0: BSF 20.4
00F1: MOVF 20,W
00F2: BSF 03.5
00F3: MOVWF 07
00F4: NOP
00F5: BCF 03.5
00F6: BSF 20.3
00F7: MOVF 20,W
00F8: BSF 03.5
00F9: MOVWF 07
00FA: BCF 03.5
00FB: BTFSS 07.3
00FC: GOTO 0FB
00FD: BTFSC 07.4
00FE: BSF 03.0
00FF: BTFSS 07.4
0100: BCF 03.0
0101: RLF 78,F
0102: NOP
0103: BCF 20.3
0104: MOVF 20,W
0105: BSF 03.5
0106: MOVWF 07
0107: BCF 03.5
0108: BCF 07.3
0109: DECFSZ 2E,F
010A: GOTO 0F0
010B: BSF 20.4
010C: MOVF 20,W
010D: BSF 03.5
010E: MOVWF 07
010F: NOP
0110: BCF 03.5
0111: BCF 07.4
0112: MOVF 2F,W
0113: BTFSC 03.2
0114: GOTO 11A
0115: BCF 20.4
0116: MOVF 20,W
0117: BSF 03.5
0118: MOVWF 07
0119: BCF 03.5
011A: NOP
011B: BSF 20.3
011C: MOVF 20,W
011D: BSF 03.5
011E: MOVWF 07
011F: BCF 03.5
0120: BTFSS 07.3
0121: GOTO 120
0122: NOP
0123: BCF 07.3
0124: BCF 20.3
0125: MOVF 20,W
0126: BSF 03.5
0127: MOVWF 07
0128: NOP
0129: BCF 03.5
012A: BCF 07.4
012B: BCF 20.4
012C: MOVF 20,W
012D: BSF 03.5
012E: MOVWF 07
012F: BCF 03.5
0130: RETURN
.................... #use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8) //rcv TXD xmit RXD
....................
....................
.................... #include "HMC5883L.h"
.................... // i2c slave addresses
.................... #define HMC5883L_WRT_ADDR 0x3C
.................... #define HMC5883L_READ_ADDR 0x3D
....................
.................... // Register addresses
.................... #define HMC5883L_CFG_A_REG 0x00
.................... #define HMC5883L_CFG_B_REG 0x01
.................... #define HMC5883L_MODE_REG 0x02
.................... #define HMC5883L_X_MSB_REG 0x03
....................
.................... //Konstanty nastavujici rozsah
.................... //pro void set_mag_roz (unsigned int8 h)
.................... #define MAG_ROZ088 0x00
.................... #define MAG_ROZ130 0x20
.................... #define MAG_ROZ190 0x40
.................... #define MAG_ROZ250 0x60
.................... #define MAG_ROZ400 0x80
.................... #define MAG_ROZ470 0xA0
.................... #define MAG_ROZ560 0xC0
.................... #define MAG_ROZ810 0xE0
....................
....................
.................... #include "HMC5883L.c"
.................... //------------------------------
.................... // Low level routines
.................... //------------------------------
.................... void hmc5883l_write_reg(int8 reg, int8 data)
.................... {
.................... i2c_start();
*
00B3: BSF 20.4
00B4: MOVF 20,W
00B5: BSF 03.5
00B6: MOVWF 07
00B7: NOP
00B8: BCF 03.5
00B9: BSF 20.3
00BA: MOVF 20,W
00BB: BSF 03.5
00BC: MOVWF 07
00BD: NOP
00BE: BCF 03.5
00BF: BCF 07.4
00C0: BCF 20.4
00C1: MOVF 20,W
00C2: BSF 03.5
00C3: MOVWF 07
00C4: NOP
00C5: BCF 03.5
00C6: BCF 07.3
00C7: BCF 20.3
00C8: MOVF 20,W
00C9: BSF 03.5
00CA: MOVWF 07
.................... i2c_write(HMC5883L_WRT_ADDR);
00CB: MOVLW 3C
00CC: BCF 03.5
00CD: MOVWF 2D
00CE: CALL 069
.................... i2c_write(reg);
00CF: MOVF 27,W
00D0: MOVWF 2D
00D1: CALL 069
.................... i2c_write(data);
00D2: MOVF 28,W
00D3: MOVWF 2D
00D4: CALL 069
.................... i2c_stop();
00D5: BCF 20.4
00D6: MOVF 20,W
00D7: BSF 03.5
00D8: MOVWF 07
00D9: NOP
00DA: BCF 03.5
00DB: BSF 20.3
00DC: MOVF 20,W
00DD: BSF 03.5
00DE: MOVWF 07
00DF: BCF 03.5
00E0: BTFSS 07.3
00E1: GOTO 0E0
00E2: NOP
00E3: GOTO 0E4
00E4: NOP
00E5: BSF 20.4
00E6: MOVF 20,W
00E7: BSF 03.5
00E8: MOVWF 07
00E9: NOP
.................... }
00EA: BCF 03.5
00EB: RETURN
....................
.................... //------------------------------
.................... int8 hmc5883l_read_reg(int8 reg)
.................... {
.................... int8 retval;
....................
.................... i2c_start();
.................... i2c_write(HMC5883L_WRT_ADDR);
.................... i2c_write(reg);
.................... i2c_start();
.................... i2c_write(HMC5883L_READ_ADDR);
.................... retval = i2c_read(0);
.................... i2c_stop();
....................
.................... return(retval);
.................... }
....................
.................... //------------------------------
.................... typedef struct
.................... {
.................... signed int16 x;
.................... signed int16 y;
.................... signed int16 z;
.................... }hmc5883l_result;
....................
.................... // This global structure holds the values read
.................... // from the HMC5883L x,y,z registers.
.................... hmc5883l_result compass = {0,0,0};
*
0260: CLRF 21
0261: CLRF 22
0262: CLRF 23
0263: CLRF 24
0264: CLRF 25
0265: CLRF 26
....................
.................... //------------------------------
.................... void hmc5883l_read_data(void)
.................... {
.................... unsigned int8 x_lsb;
.................... unsigned int8 x_msb;
....................
.................... unsigned int8 y_lsb;
.................... unsigned int8 y_msb;
....................
.................... unsigned int8 z_lsb;
.................... unsigned int8 z_msb;
....................
.................... i2c_start();
*
0131: BSF 20.4
0132: MOVF 20,W
0133: BSF 03.5
0134: MOVWF 07
0135: NOP
0136: BCF 03.5
0137: BSF 20.3
0138: MOVF 20,W
0139: BSF 03.5
013A: MOVWF 07
013B: NOP
013C: BCF 03.5
013D: BCF 07.4
013E: BCF 20.4
013F: MOVF 20,W
0140: BSF 03.5
0141: MOVWF 07
0142: NOP
0143: BCF 03.5
0144: BCF 07.3
0145: BCF 20.3
0146: MOVF 20,W
0147: BSF 03.5
0148: MOVWF 07
.................... i2c_write(HMC5883L_WRT_ADDR);
0149: MOVLW 3C
014A: BCF 03.5
014B: MOVWF 2D
014C: CALL 069
.................... i2c_write(HMC5883L_X_MSB_REG); // Point to X-msb register
014D: MOVLW 03
014E: MOVWF 2D
014F: CALL 069
.................... i2c_start();
0150: BSF 20.4
0151: MOVF 20,W
0152: BSF 03.5
0153: MOVWF 07
0154: NOP
0155: BCF 03.5
0156: BSF 20.3
0157: MOVF 20,W
0158: BSF 03.5
0159: MOVWF 07
015A: NOP
015B: BCF 03.5
015C: BTFSS 07.3
015D: GOTO 15C
015E: BCF 07.4
015F: BCF 20.4
0160: MOVF 20,W
0161: BSF 03.5
0162: MOVWF 07
0163: NOP
0164: BCF 03.5
0165: BCF 07.3
0166: BCF 20.3
0167: MOVF 20,W
0168: BSF 03.5
0169: MOVWF 07
.................... i2c_write(HMC5883L_READ_ADDR);
016A: MOVLW 3D
016B: BCF 03.5
016C: MOVWF 2D
016D: CALL 069
....................
.................... x_msb = i2c_read();
016E: MOVLW 01
016F: MOVWF 77
0170: CALL 0EC
0171: MOVF 78,W
0172: MOVWF 28
.................... x_lsb = i2c_read();
0173: MOVLW 01
0174: MOVWF 77
0175: CALL 0EC
0176: MOVF 78,W
0177: MOVWF 27
....................
.................... z_msb = i2c_read();
0178: MOVLW 01
0179: MOVWF 77
017A: CALL 0EC
017B: MOVF 78,W
017C: MOVWF 2C
.................... z_lsb = i2c_read();
017D: MOVLW 01
017E: MOVWF 77
017F: CALL 0EC
0180: MOVF 78,W
0181: MOVWF 2B
....................
.................... y_msb = i2c_read();
0182: MOVLW 01
0183: MOVWF 77
0184: CALL 0EC
0185: MOVF 78,W
0186: MOVWF 2A
.................... y_lsb = i2c_read(0); // do a NACK on last read
0187: CLRF 77
0188: CALL 0EC
0189: MOVF 78,W
018A: MOVWF 29
....................
.................... i2c_stop();
018B: BCF 20.4
018C: MOVF 20,W
018D: BSF 03.5
018E: MOVWF 07
018F: NOP
0190: BCF 03.5
0191: BSF 20.3
0192: MOVF 20,W
0193: BSF 03.5
0194: MOVWF 07
0195: BCF 03.5
0196: BTFSS 07.3
0197: GOTO 196
0198: NOP
0199: GOTO 19A
019A: NOP
019B: BSF 20.4
019C: MOVF 20,W
019D: BSF 03.5
019E: MOVWF 07
019F: NOP
....................
.................... // Combine high and low bytes into 16-bit values.
.................... compass.x = make16(x_msb, x_lsb);
01A0: BCF 03.5
01A1: MOVF 28,W
01A2: MOVWF 22
01A3: MOVF 27,W
01A4: MOVWF 21
.................... compass.y = make16(y_msb, y_lsb);
01A5: MOVF 2A,W
01A6: MOVWF 24
01A7: MOVF 29,W
01A8: MOVWF 23
.................... compass.z = make16(z_msb, z_lsb);
01A9: MOVF 2C,W
01AA: MOVWF 26
01AB: MOVF 2B,W
01AC: MOVWF 25
.................... }
01AD: BCF 0A.3
01AE: BCF 0A.4
01AF: GOTO 2CC (RETURN)
....................
....................
....................
....................
.................... #include <math.h>
.................... ////////////////////////////////////////////////////////////////////////////
.................... //// (C) Copyright 1996,2008 Custom Computer Services ////
.................... //// This source code may only be used by licensed users of the CCS C ////
.................... //// compiler. This source code may only be distributed to other ////
.................... //// licensed users of the CCS C compiler. No other use, reproduction ////
.................... //// or distribution is permitted without written permission. ////
.................... //// Derivative programs created using this software in object code ////
.................... //// form are not restricted in any way. ////
.................... ////////////////////////////////////////////////////////////////////////////
.................... //// ////
.................... //// History: ////
.................... //// * 9/20/2001 : Improvments are made to sin/cos code. ////
.................... //// The code now is small, much faster, ////
.................... //// and more accurate. ////
.................... //// * 2/21/2007 : Compiler handles & operator differently and does
.................... //// not return generic (int8 *) so type cast is done ////
.................... //// ////
.................... ////////////////////////////////////////////////////////////////////////////
....................
.................... #ifndef MATH_H
.................... #define MATH_H
....................
.................... #ifdef PI
.................... #undef PI
.................... #endif
.................... #define PI 3.1415926535897932
....................
....................
.................... #define SQRT2 1.4142135623730950
....................
.................... //float const ps[4] = {5.9304945, 21.125224, 8.9403076, 0.29730279};
.................... //float const qs[4] = {1.0000000, 15.035723, 17.764134, 2.4934718};
....................
.................... ///////////////////////////// Round Functions //////////////////////////////
....................
.................... float32 CEIL_FLOOR(float32 x, unsigned int8 n)
.................... {
.................... float32 y, res;
.................... unsigned int16 l;
.................... int1 s;
....................
.................... s = 0;
.................... y = x;
....................
.................... if (x < 0)
.................... {
.................... s = 1;
.................... y = -y;
.................... }
....................
.................... if (y <= 32768.0)
.................... res = (float32)(unsigned int16)y;
....................
.................... else if (y < 10000000.0)
.................... {
.................... l = (unsigned int16)(y/32768.0);
.................... y = 32768.0*(y/32768.0 - (float32)l);
.................... res = 32768.0*(float32)l;
.................... res += (float32)(unsigned int16)y;
.................... }
....................
.................... else
.................... res = y;
....................
.................... y = y - (float32)(unsigned int16)y;
....................
.................... if (s)
.................... res = -res;
....................
.................... if (y != 0)
.................... {
.................... if (s == 1 && n == 0)
.................... res -= 1.0;
....................
.................... if (s == 0 && n == 1)
.................... res += 1.0;
.................... }
.................... if (x == 0)
.................... res = 0;
....................
.................... return (res);
.................... }
....................
.................... // Overloaded Functions to take care for new Data types in PCD
.................... // Overloaded function CEIL_FLOOR() for data type - Float48
.................... #if defined(__PCD__)
.................... float48 CEIL_FLOOR(float48 x, unsigned int8 n)
.................... {
.................... float48 y, res;
.................... unsigned int16 l;
.................... int1 s;
....................
.................... s = 0;
.................... y = x;
....................
.................... if (x < 0)
.................... {
.................... s = 1;
.................... y = -y;
.................... }
....................
.................... if (y <= 32768.0)
.................... res = (float48)(unsigned int16)y;
....................
.................... else if (y < 10000000.0)
.................... {
.................... l = (unsigned int16)(y/32768.0);
.................... y = 32768.0*(y/32768.0 - (float48)l);
.................... res = 32768.0*(float32)l;
.................... res += (float48)(unsigned int16)y;
.................... }
....................
.................... else
.................... res = y;
....................
.................... y = y - (float48)(unsigned int16)y;
....................
.................... if (s)
.................... res = -res;
....................
.................... if (y != 0)
.................... {
.................... if (s == 1 && n == 0)
.................... res -= 1.0;
....................
.................... if (s == 0 && n == 1)
.................... res += 1.0;
.................... }
.................... if (x == 0)
.................... res = 0;
....................
.................... return (res);
.................... }
....................
....................
.................... // Overloaded function CEIL_FLOOR() for data type - Float64
.................... float64 CEIL_FLOOR(float64 x, unsigned int8 n)
.................... {
.................... float64 y, res;
.................... unsigned int16 l;
.................... int1 s;
....................
.................... s = 0;
.................... y = x;
....................
.................... if (x < 0)
.................... {
.................... s = 1;
.................... y = -y;
.................... }
....................
.................... if (y <= 32768.0)
.................... res = (float64)(unsigned int16)y;
....................
.................... else if (y < 10000000.0)
.................... {
.................... l = (unsigned int16)(y/32768.0);
.................... y = 32768.0*(y/32768.0 - (float64)l);
.................... res = 32768.0*(float64)l;
.................... res += (float64)(unsigned int16)y;
.................... }
....................
.................... else
.................... res = y;
....................
.................... y = y - (float64)(unsigned int16)y;
....................
.................... if (s)
.................... res = -res;
....................
.................... if (y != 0)
.................... {
.................... if (s == 1 && n == 0)
.................... res -= 1.0;
....................
.................... if (s == 0 && n == 1)
.................... res += 1.0;
.................... }
.................... if (x == 0)
.................... res = 0;
....................
.................... return (res);
.................... }
.................... #endif
....................
.................... ////////////////////////////////////////////////////////////////////////////
.................... // float floor(float x)
.................... ////////////////////////////////////////////////////////////////////////////
.................... // Description : rounds down the number x.
.................... // Date : N/A
.................... //
.................... float32 floor(float32 x)
.................... {
.................... return CEIL_FLOOR(x, 0);
.................... }
.................... // Following 2 functions are overloaded functions of floor() for PCD
.................... // Overloaded function floor() for data type - Float48
.................... #if defined(__PCD__)
.................... float48 floor(float48 x)
.................... {
.................... return CEIL_FLOOR(x, 0);
.................... }
....................
.................... // Overloaded function floor() for data type - Float64
.................... float64 floor(float64 x)
.................... {
.................... return CEIL_FLOOR(x, 0);
.................... }
.................... #endif
....................
....................
.................... ////////////////////////////////////////////////////////////////////////////
.................... // float ceil(float x)
.................... ////////////////////////////////////////////////////////////////////////////
.................... // Description : rounds up the number x.
.................... // Date : N/A
.................... //
.................... float32 ceil(float32 x)
.................... {
.................... return CEIL_FLOOR(x, 1);
.................... }
.................... // Following 2 functions are overloaded functions of ceil() for PCD
.................... // Overloaded function ceil() for data type - Float48
.................... #if defined(__PCD__)
.................... float48 ceil(float48 x)
.................... {
.................... return CEIL_FLOOR(x, 1);
.................... }
....................
.................... // Overloaded function ceil() for data type - Float64
.................... float64 ceil(float64 x)
.................... {
.................... return CEIL_FLOOR(x, 1);
.................... }
.................... #endif
....................
.................... ////////////////////////////////////////////////////////////////////////////
.................... // float fabs(float x)
.................... ////////////////////////////////////////////////////////////////////////////
.................... // Description : Computes the absolute value of floating point number x
.................... // Returns : returns the absolute value of x
.................... // Date : N/A
.................... //
.................... #define fabs abs
....................
.................... ////////////////////////////////////////////////////////////////////////////
.................... // float fmod(float x)
.................... ////////////////////////////////////////////////////////////////////////////
.................... // Description : Computes the floating point remainder of x/y
.................... // Returns : returns the value of x= i*y, for some integer i such that, if y
.................... // is non zero, the result has the same isgn of x na dmagnitude less than the
.................... // magnitude of y. If y is zero then a domain error occurs.
.................... // Date : N/A
.................... //
....................
.................... float fmod(float32 x,float32 y)
.................... {
.................... float32 i;
.................... if (y!=0.0)
.................... {
.................... i=(x/y < 0.0)? ceil(x/y): floor(x/y);
.................... return(x-(i*y));
.................... }
.................... else
.................... {
.................... #ifdef _ERRNO
.................... {
.................... errno=EDOM;
.................... }
.................... #endif
.................... }
.................... }
.................... //Overloaded function for fmod() for PCD
.................... // Overloaded function fmod() for data type - Float48
.................... #if defined(__PCD__)
.................... float48 fmod(float48 x,float48 y)
.................... {
.................... float48 i;
.................... if (y!=0.0)
.................... {
.................... i=(x/y < 0.0)? ceil(x/y): floor(x/y);
.................... return(x-(i*y));
.................... }
.................... else
.................... {
.................... #ifdef _ERRNO
.................... {
.................... errno=EDOM;
.................... }
.................... #endif
.................... }
.................... }
.................... // Overloaded function fmod() for data type - Float64
.................... float64 fmod(float64 x,float64 y)
.................... {
.................... float64 i;
.................... if (y!=0.0)
.................... {
.................... i=(x/y < 0.0)? ceil(x/y): floor(x/y);
.................... return(x-(i*y));
.................... }
.................... else
.................... {
.................... #ifdef _ERRNO
.................... {
.................... errno=EDOM;
.................... }
.................... #endif
.................... }
.................... }
.................... #endif
.................... //////////////////// Exponential and logarithmic functions ////////////////////
.................... ////////////////////////////////////////////////////////////////////////////
.................... // float exp(float x)
.................... ////////////////////////////////////////////////////////////////////////////
.................... // Description : returns the value (e^x)
.................... // Date : N/A
.................... //
.................... #define LN2 0.6931471805599453
....................
.................... float const pe[6] = {0.000207455774, 0.00127100575, 0.00965065093,
.................... 0.0554965651, 0.240227138, 0.693147172};
....................
....................
.................... float32 exp(float32 x)
.................... {
.................... float32 y, res, r;
.................... #if defined(__PCD__)
.................... int8 data1;
.................... #endif
.................... signed int8 n;
.................... int1 s;
.................... #ifdef _ERRNO
.................... if(x > 88.722838)
.................... {
.................... errno=ERANGE;
.................... return(0);
.................... }
.................... #endif
.................... n = (signed int16)(x/LN2);
.................... s = 0;
.................... y = x;
....................
.................... if (x < 0)
.................... {
.................... s = 1;
.................... n = -n;
.................... y = -y;
.................... }
....................
.................... res = 0.0;
.................... #if !defined(__PCD__)
.................... *((unsigned int8 *)(&res)) = n + 0x7F;
.................... #endif
....................
.................... #if defined(__PCD__) // Takes care of IEEE format for PCD
.................... data1 = n+0x7F;
.................... if(bit_test(data1,0))
.................... bit_set(*(((unsigned int8 *)(&res)+2)),7);
.................... rotate_right(&data1,1);
.................... bit_clear(data1,7);
.................... *(((unsigned int8 *)(&res)+3)) = data1;
.................... #endif
....................
.................... y = y/LN2 - (float32)n;
....................
.................... r = pe[0]*y + pe[1];
.................... r = r*y + pe[2];
.................... r = r*y + pe[3];
.................... r = r*y + pe[4];
.................... r = r*y + pe[5];
....................
.................... res = res*(1.0 + y*r);
....................
.................... if (s)
.................... res = 1.0/res;
.................... return(res);
.................... }
....................
....................
.................... //Overloaded function for exp() for PCD
.................... // Overloaded function exp() for data type - Float48
.................... #if defined(__PCD__)
.................... float48 exp(float48 x)
.................... {
.................... float48 y, res, r;
.................... int8 data1;
.................... signed int8 n;
.................... int1 s;
.................... #ifdef _ERRNO
.................... if(x > 88.722838)
.................... {
.................... errno=ERANGE;
.................... return(0);
.................... }
.................... #endif
.................... n = (signed int16)(x/LN2);
.................... s = 0;
.................... y = x;
....................
.................... if (x < 0)
.................... {
.................... s = 1;
.................... n = -n;
.................... y = -y;
.................... }
....................
.................... res = 0.0;
....................
.................... data1 = n+0x7F;
.................... if(bit_test(data1,0))
.................... bit_set(*(((unsigned int8 *)(&res)+4)),7);
.................... rotate_right(&data1,1);
.................... bit_clear(data1,7);
.................... *(((unsigned int8 *)(&res)+5)) = data1;
....................
.................... y = y/LN2 - (float48)n;
....................
.................... r = pe[0]*y + pe[1];
.................... r = r*y + pe[2];
.................... r = r*y + pe[3];
.................... r = r*y + pe[4];
.................... r = r*y + pe[5];
....................
.................... res = res*(1.0 + y*r);
....................
.................... if (s)
.................... res = 1.0/res;
.................... return(res);
.................... }
....................
.................... // Overloaded function exp() for data type - Float64
.................... float64 exp(float64 x)
.................... {
.................... float64 y, res, r;
.................... unsigned int16 data1, data2;
.................... unsigned int16 *p;
.................... signed int16 n;
.................... int1 s;
.................... #ifdef _ERRNO
.................... if(x > 709.7827128)
.................... {
.................... errno=ERANGE;
.................... return(0);
.................... }
.................... #endif
.................... n = (signed int16)(x/LN2);
.................... s = 0;
.................... y = x;
....................
.................... if (x < 0)
.................... {
.................... s = 1;
.................... n = -n;
.................... y = -y;
.................... }
....................
.................... res = 0.0;
....................
.................... #if !defined(__PCD__)
.................... *((unsigned int16 *)(&res)) = n + 0x7F;
.................... #endif
.................... p= (((unsigned int16 *)(&res))+3);
.................... data1 = *p;
.................... data2 = *p;
.................... data1 = n + 0x3FF;
.................... data1 = data1 <<4;
.................... if(bit_test(data2,15))
.................... bit_set(data1,15);
.................... data2 = data2 & 0x000F;
.................... data1 ^= data2;
....................
.................... *(((unsigned int16 *)(&res)+3)) = data1;
....................
....................
.................... y = y/LN2 - (float64)n;
....................
.................... r = pe[0]*y + pe[1];
.................... r = r*y + pe[2];
.................... r = r*y + pe[3];
.................... r = r*y + pe[4];
.................... r = r*y + pe[5];
....................
.................... res = res*(1.0 + y*r);
....................
.................... if (s)
.................... res = 1.0/res;
.................... return(res);
.................... }
....................
.................... #ENDIF
....................
....................
.................... /************************************************************/
....................
.................... float32 const pl[4] = {0.45145214, -9.0558803, 26.940971, -19.860189};
.................... float32 const ql[4] = {1.0000000, -8.1354259, 16.780517, -9.9300943};
....................
.................... ////////////////////////////////////////////////////////////////////////////
.................... // float log(float x)
.................... ////////////////////////////////////////////////////////////////////////////
.................... // Description : returns the the natural log of x
.................... // Date : N/A
.................... //
.................... float32 log(float32 x)
.................... {
.................... float32 y, res, r, y2;
.................... #if defined(__PCD__)
.................... unsigned int8 data1,data2;
.................... #endif
.................... signed int8 n;
.................... #ifdef _ERRNO
.................... if(x <0)
.................... {
.................... errno=EDOM;
.................... }
.................... if(x ==0)
.................... {
.................... errno=ERANGE;
.................... return(0);
.................... }
.................... #endif
.................... y = x;
....................
.................... if (y != 1.0)
.................... {
.................... #if !defined(__PCD__)
.................... *((unsigned int8 *)(&y)) = 0x7E;
.................... #endif
....................
.................... #if defined(__PCD__) // Takes care of IEEE format
.................... data2 = *(((unsigned int8 *)(&y))+3);
.................... *(((unsigned int8 *)(&y))+3) = 0x3F;
.................... data1 = *(((unsigned int8 *)(&y))+2);
.................... bit_clear(data1,7);
.................... *(((unsigned int8 *)(&y))+2) = data1;
.................... if(bit_test(data2,7))
.................... bit_set(*(((unsigned int8 *)(&y))+3),7);
.................... #endif
....................
.................... y = (y - 1.0)/(y + 1.0);
....................
.................... y2=y*y;
....................
.................... res = pl[0]*y2 + pl[1];
.................... res = res*y2 + pl[2];
.................... res = res*y2 + pl[3];
....................
.................... r = ql[0]*y2 + ql[1];
.................... r = r*y2 + ql[2];
.................... r = r*y2 + ql[3];
....................
.................... res = y*res/r;
.................... #if !defined(__PCD__)
.................... n = *((unsigned int8 *)(&x)) - 0x7E;
.................... #endif
.................... #if defined(__PCD__)
.................... data1 = *(((unsigned int8 *)(&x)+3));
.................... rotate_left(&data1,1);
.................... data2 = *(((unsigned int8 *)(&x)+2));
.................... if(bit_test (data2,7))
.................... bit_set(data1,0);
.................... n = data1 - 0x7E;
.................... #endif
....................
.................... if (n<0)
.................... r = -(float32)-n;
.................... else
.................... r = (float32)n;
....................
.................... res += r*LN2;
.................... }
....................
.................... else
.................... res = 0.0;
....................
.................... return(res);
.................... }
....................
.................... //Overloaded function for log() for PCD
.................... // Overloaded function log() for data type - Float48
.................... #if defined(__PCD__)
.................... float48 log(float48 x)
.................... {
.................... float48 y, res, r, y2;
.................... unsigned int8 data1,data2;
.................... signed int8 n;
.................... #ifdef _ERRNO
.................... if(x <0)
.................... {
.................... errno=EDOM;
.................... }
.................... if(x ==0)
.................... {
.................... errno=ERANGE;
.................... return(0);
.................... }
.................... #endif
.................... y = x;
....................
.................... if (y != 1.0)
.................... {
....................
.................... #if !defined(__PCD__)
.................... *((unsigned int8 *)(&y)) = 0x7E;
.................... #endif
.................... data2 = *(((unsigned int8 *)(&y))+5);
.................... *(((unsigned int8 *)(&y))+5) = 0x3F;
.................... data1 = *(((unsigned int8 *)(&y))+4);
.................... bit_clear(data1,7);
.................... *(((unsigned int8 *)(&y))+4) = data1;
....................
.................... if(bit_test(data2,7))
.................... bit_set(*(((unsigned int8 *)(&y))+4),7);
.................... y = (y - 1.0)/(y + 1.0);
....................
.................... y2=y*y;
....................
.................... res = pl[0]*y2 + pl[1];
.................... res = res*y2 + pl[2];
.................... res = res*y2 + pl[3];
....................
.................... r = ql[0]*y2 + ql[1];
.................... r = r*y2 + ql[2];
.................... r = r*y2 + ql[3];
....................
.................... res = y*res/r;
....................
.................... data1 = *(((unsigned int8 *)(&x)+5));
.................... rotate_left(&data1,1);
.................... data2 = *(((unsigned int8 *)(&x)+4));
.................... if(bit_test (data2,7))
.................... bit_set(data1,0);
....................
.................... n = data1 - 0x7E;
....................
.................... if (n<0)
.................... r = -(float48)-n;
.................... else
.................... r = (float48)n;
....................
.................... res += r*LN2;
.................... }
....................
.................... else
.................... res = 0.0;
....................
.................... return(res);
.................... }
....................
.................... // Overloaded function log() for data type - Float48
.................... #if defined(__PCD__)
.................... float32 const pl_64[4] = {0.45145214, -9.0558803, 26.940971, -19.860189};
.................... float32 const ql_64[4] = {1.0000000, -8.1354259, 16.780517, -9.9300943};
.................... #endif
.................... float64 log(float64 x)
.................... {
.................... float64 y, res, r, y2;
.................... unsigned int16 data1,data2;
.................... unsigned int16 *p;
.................... signed int16 n;
.................... #ifdef _ERRNO
.................... if(x <0)
.................... {
.................... errno=EDOM;
.................... }
.................... if(x ==0)
.................... {
.................... errno=ERANGE;
.................... return(0);
.................... }
.................... #endif
.................... y = x;
....................
.................... if (y != 1.0)
.................... {
.................... #if !defined(__PCD__)
.................... *((unsigned int8 *)(&y)) = 0x7E;
.................... #endif
.................... p= (((unsigned int16 *)(&y))+3);
.................... data1 = *p;
.................... data2 = *p;
.................... data1 = 0x3FE;
.................... data1 = data1 <<4;
.................... if(bit_test (data2,15))
.................... bit_set(data1,15);
.................... data2 = data2 & 0x000F;
.................... data1 ^=data2;
....................
.................... *p = data1;
....................
.................... y = (y - 1.0)/(y + 1.0);
....................
.................... y2=y*y;
....................
.................... res = pl_64[0]*y2 + pl_64[1];
.................... res = res*y2 + pl_64[2];
.................... res = res*y2 + pl_64[3];
....................
.................... r = ql_64[0]*y2 + ql_64[1];
.................... r = r*y2 + ql_64[2];
.................... r = r*y2 + ql_64[3];
....................
.................... res = y*res/r;
....................
.................... p= (((unsigned int16 *)(&x))+3);
.................... data1 = *p;
.................... bit_clear(data1,15);
.................... data1 = data1 >>4;
.................... n = data1 - 0x3FE;
....................
....................
.................... if (n<0)
.................... r = -(float64)-n;
.................... else
.................... r = (float64)n;
....................
.................... res += r*LN2;
.................... }
....................
.................... else
.................... res = 0.0;
....................
.................... return(res);
.................... }
.................... #endif
....................
....................
.................... #define LN10 2.3025850929940456
....................
.................... ////////////////////////////////////////////////////////////////////////////
.................... // float log10(float x)
.................... ////////////////////////////////////////////////////////////////////////////
.................... // Description : returns the the log base 10 of x
.................... // Date : N/A
.................... //
.................... float32 log10(float32 x)
.................... {
.................... float32 r;
....................
.................... r = log(x);
.................... r = r/LN10;
.................... return(r);
.................... }
....................
.................... //Overloaded functions for log10() for PCD
.................... // Overloaded function log10() for data type - Float48
.................... #if defined(__PCD__)
.................... float48 log10(float48 x)
.................... {
.................... float48 r;
....................
.................... r = log(x);
.................... r = r/LN10;
.................... return(r);
.................... }
....................
.................... // Overloaded function log10() for data type - Float64
.................... float64 log10(float64 x)
.................... {
.................... float64 r;
....................
.................... r = log(x);
.................... r = r/LN10;
.................... return(r);
.................... }
.................... #endif
.................... ////////////////////////////////////////////////////////////////////////////
.................... // float modf(float x)
.................... ////////////////////////////////////////////////////////////////////////////
.................... // Description :breaks the argument value int integral and fractional parts,
.................... // ach of which have the same sign as the argument. It stores the integral part
.................... // as a float in the object pointed to by the iptr
.................... // Returns : returns the signed fractional part of value.
.................... // Date : N/A
.................... //
....................
.................... float32 modf(float32 value,float32 *iptr)
.................... {
.................... *iptr=(value < 0.0)? ceil(value): floor(value);
.................... return(value - *iptr);
.................... }
.................... //Overloaded functions for modf() for PCD
.................... // Overloaded function modf() for data type - Float48
.................... #if defined(__PCD__)
.................... float48 modf(float48 value,float48 *iptr)
.................... {
.................... *iptr=(value < 0.0)? ceil(value): floor(value);
.................... return(value - *iptr);
.................... }
.................... // Overloaded function modf() for data type - Float64
.................... float64 modf(float64 value,float64 *iptr)
.................... {
.................... *iptr=(value < 0.0)? ceil(value): floor(value);
.................... return(value - *iptr);
.................... }
.................... #endif
....................
.................... ////////////////////////////////////////////////////////////////////////////
.................... // float pwr(float x,float y)
.................... ////////////////////////////////////////////////////////////////////////////
.................... // Description : returns the value (x^y)
.................... // Date : N/A
.................... // Note : 0 is returned when the function will generate an imaginary number
.................... //
.................... float32 pwr(float32 x,float32 y)
.................... {
.................... if(0 > x && fmod(y, 1) == 0) {
.................... if(fmod(y, 2) == 0) {
.................... return (exp(log(-x) * y));
.................... } else {
.................... return (-exp(log(-x) * y));
.................... }
.................... } else if(0 > x && fmod(y, 1) != 0) {
.................... return 0;
.................... } else {
.................... if(x != 0 || 0 >= y) {
.................... return (exp(log(x) * y));
.................... }
.................... }
.................... }
.................... //Overloaded functions for pwr() for PCD
.................... // Overloaded function pwr() for data type - Float48
.................... #if defined(__PCD__)
.................... float48 pwr(float48 x,float48 y)
.................... {
.................... if(0 > x && fmod(y, 1) == 0) {
.................... if(fmod(y, 2) == 0) {
.................... return (exp(log(-x) * y));
.................... } else {
.................... return (-exp(log(-x) * y));
.................... }
.................... } else if(0 > x && fmod(y, 1) != 0) {
.................... return 0;
.................... } else {
.................... if(x != 0 || 0 >= y) {
.................... return (exp(log(x) * y));
.................... }
.................... }
.................... }
.................... // Overloaded function pwr() for data type - Float64
.................... float64 pwr(float64 x,float64 y)
.................... {
.................... if(0 > x && fmod(y, 1) == 0) {
.................... if(fmod(y, 2) == 0) {
.................... return (exp(log(-x) * y));
.................... } else {
.................... return (-exp(log(-x) * y));
.................... }
.................... } else if(0 > x && fmod(y, 1) != 0) {
.................... return 0;
.................... } else {
.................... if(x != 0 || 0 >= y) {
.................... return (exp(log(x) * y));
.................... }
.................... }
.................... }
.................... #endif
....................
.................... //////////////////// Power functions ////////////////////
....................
.................... ////////////////////////////////////////////////////////////////////////////
.................... // float pow(float x,float y)
.................... ////////////////////////////////////////////////////////////////////////////
.................... // Description : returns the value (x^y)
.................... // Date : N/A
.................... // Note : 0 is returned when the function will generate an imaginary number
.................... //
.................... float32 pow(float32 x,float32 y)
.................... {
.................... if(0 > x && fmod(y, 1) == 0) {
.................... if(fmod(y, 2) == 0) {
.................... return (exp(log(-x) * y));
.................... } else {
.................... return (-exp(log(-x) * y));
.................... }
.................... } else if(0 > x && fmod(y, 1) != 0) {
.................... return 0;
.................... } else {
.................... if(x != 0 || 0 >= y) {
.................... return (exp(log(x) * y));
.................... }
.................... }
.................... }
.................... //Overloaded functions for pow() for PCD
.................... // Overloaded function for pow() data type - Float48
.................... #if defined(__PCD__)
.................... float48 pow(float48 x,float48 y)
.................... {
.................... if(0 > x && fmod(y, 1) == 0) {
.................... if(fmod(y, 2) == 0) {
.................... return (exp(log(-x) * y));
.................... } else {
.................... return (-exp(log(-x) * y));
.................... }
.................... } else if(0 > x && fmod(y, 1) != 0) {
.................... return 0;
.................... } else {
.................... if(x != 0 || 0 >= y) {
.................... return (exp(log(x) * y));
.................... }
.................... }
.................... }
....................
.................... // Overloaded function pow() for data type - Float64
.................... float64 pow(float64 x,float64 y)
.................... {
.................... if(0 > x && fmod(y, 1) == 0) {
.................... if(fmod(y, 2) == 0) {
.................... return (exp(log(-x) * y));
.................... } else {
.................... return (-exp(log(-x) * y));
.................... }
.................... } else if(0 > x && fmod(y, 1) != 0) {
.................... return 0;
.................... } else {
.................... if(x != 0 || 0 >= y) {
.................... return (exp(log(x) * y));
.................... }
.................... }
.................... }
.................... #endif
....................
.................... ////////////////////////////////////////////////////////////////////////////
.................... // float sqrt(float x)
.................... ////////////////////////////////////////////////////////////////////////////
.................... // Description : returns the square root of x
.................... // Date : N/A
.................... //
.................... float32 sqrt(float32 x)
.................... {
.................... float32 y, res;
.................... #if defined(__PCD__)
.................... unsigned int16 data1,data2;
.................... #endif
.................... BYTE *p;
....................
.................... #ifdef _ERRNO
.................... if(x < 0)
.................... {
.................... errno=EDOM;
.................... }
.................... #endif
....................
.................... if( x<=0.0)
.................... return(0.0);
....................
.................... y=x;
....................
.................... #if !defined(__PCD__)
.................... p=&y;
.................... (*p)=(BYTE)((((unsigned int16)(*p)) + 127) >> 1);
.................... #endif
....................
.................... #if defined(__PCD__)
.................... p = (((unsigned int8 *)(&y))+3);
.................... data1 = *(((unsigned int8 *)(&y))+3);
.................... data2 = *(((unsigned int8 *)(&y))+2);
.................... rotate_left(&data1,1);
.................... if(bit_test(data2,7))
.................... bit_set(data1,0);
.................... data1 = ((data1+127) >>1);
.................... bit_clear(data2,7);
.................... if(bit_test(data1,0))
.................... bit_set(data2,7);
.................... data1 = data1 >>1;
.................... *(((unsigned int8 *)(&y))+3) = data1;
.................... *(((unsigned int8 *)(&y))+2) = data2;
....................
.................... #endif
....................
.................... do {
.................... res=y;
.................... y+=(x/y);
....................
.................... #if !defined(__PCD__)
.................... (*p)--;
.................... #endif
....................
.................... #if defined(__PCD__)
.................... data1 = *(((unsigned int8 *)(&y))+3);
.................... data2 = *(((unsigned int8 *)(&y))+2);
.................... rotate_left(&data1,1);
.................... if(bit_test(data2,7))
.................... bit_set(data1,0);
.................... data1--;
.................... bit_clear(data2,7);
.................... if(bit_test(data1,0))
.................... bit_set(data2,7);
.................... data1 = data1 >>1;
.................... *(((unsigned int8 *)(&y))+3) = data1;
.................... *(((unsigned int8 *)(&y))+2) = data2;
....................
.................... #endif
.................... } while(res != y);
....................
.................... return(res);
.................... }
.................... //Overloaded functions for sqrt() for PCD
.................... // Overloaded function sqrt() for data type - Float48
.................... #if defined(__PCD__)
.................... float48 sqrt(float48 x)
.................... {
.................... float48 y, res;
.................... unsigned int16 data1,data2;
.................... BYTE *p;
....................
.................... #ifdef _ERRNO
.................... if(x < 0)
.................... {
.................... errno=EDOM;
.................... }
.................... #endif
....................
.................... if( x<=0.0)
.................... return(0.0);
....................
.................... y=x;
....................
.................... #if !defined(__PCD__)
.................... p=&y;
.................... (*p)=(BYTE)((((unsigned int16)(*p)) + 127) >> 1);
.................... #endif
....................
.................... #if defined(__PCD__)
.................... p = (((unsigned int8 *)(&y))+5);
.................... data1 = *(((unsigned int8 *)(&y))+5);
.................... data2 = *(((unsigned int8 *)(&y))+4);
.................... rotate_left(&data1,1);
.................... if(bit_test(data2,7))
.................... bit_set(data1,0);
.................... data1 = ((data1+127) >>1);
.................... bit_clear(data2,7);
.................... if(bit_test(data1,0))
.................... bit_set(data2,7);
.................... data1 = data1 >>1;
.................... *(((unsigned int8 *)(&y))+5) = data1;
.................... *(((unsigned int8 *)(&y))+4) = data2;
....................
.................... #endif
....................
.................... do {
.................... res=y;
.................... y+=(x/y);
....................
.................... #if !defined(__PCD__)
.................... (*p)--;
.................... #endif
....................
.................... data1 = *(((unsigned int8 *)(&y))+5);
.................... data2 = *(((unsigned int8 *)(&y))+4);
.................... rotate_left(&data1,1);
.................... if(bit_test(data2,7))
.................... bit_set(data1,0);
.................... data1--;
.................... bit_clear(data2,7);
.................... if(bit_test(data1,0))
.................... bit_set(data2,7);
.................... data1 = data1 >>1;
.................... *(((unsigned int8 *)(&y))+5) = data1;
.................... *(((unsigned int8 *)(&y))+4) = data2;
....................
.................... } while(res != y);
....................
.................... return(res);
.................... }
....................
.................... // Overloaded function sqrt() for data type - Float64
.................... float64 sqrt(float64 x)
.................... {
.................... float64 y, res;
.................... unsigned int16 *p;
.................... unsigned int16 temp1,temp2;
....................
.................... #ifdef _ERRNO
.................... if(x < 0)
.................... {
.................... errno=EDOM;
.................... }
.................... #endif
....................
.................... if( x<=0.0)
.................... return(0.0);
....................
.................... y=x;
.................... p= (((unsigned int16 *)(&y))+3);
.................... temp1 = *p;
.................... temp2 = *p;
.................... bit_clear(temp1,15);
.................... temp1 = (temp1>>4)+1023;
.................... temp1 = temp1 >> 1;
.................... temp1 = (temp1<<4) & 0xFFF0;
.................... if(bit_test(temp2,15))
.................... bit_set(temp1,15);
.................... temp2 = temp2 & 0x000F;
.................... temp1 ^= temp2;
....................
.................... (*p) = temp1;
....................
.................... do {
.................... res=y;
.................... y+=(x/y);
.................... temp1 = *p;
.................... temp2 = *p;
.................... bit_clear(temp1,15);
.................... temp1 = (temp1>>4);
.................... temp1--;
.................... temp1 = (temp1<<4) & 0xFFF0;
.................... if(bit_test(temp2,15))
.................... bit_set(temp1,15);
.................... temp2 = temp2 & 0x000F;
.................... temp1 ^= temp2;
.................... (*p) = temp1;
....................
.................... } while(res != y);
....................
.................... return(res);
.................... }
.................... #endif
....................
.................... ////////////////////////////// Trig Functions //////////////////////////////
.................... #ifdef PI_DIV_BY_TWO
.................... #undef PI_DIV_BY_TWO
.................... #endif
.................... #define PI_DIV_BY_TWO 1.5707963267948966
.................... #ifdef TWOBYPI
.................... #undef TWOBYPI
.................... #define TWOBYPI 0.6366197723675813
.................... #endif
.................... ////////////////////////////////////////////////////////////////////////////
.................... // float cos(float x)
.................... ////////////////////////////////////////////////////////////////////////////
.................... // Description : returns the cosine value of the angle x, which is in radian
.................... // Date : 9/20/2001
.................... //
.................... float32 cos(float32 x)
.................... {
.................... float32 y, t, t2 = 1.0;
.................... unsigned int8 quad, i;
.................... float32 frac;
.................... float32 p[6] = { //by the series definition for cosine
.................... -0.5, // sum ( ( (-1)^n * x^2n )/(2n)! )
.................... 0.04166666666667,
.................... -0.00138888888889,
.................... 0.00002480158730,
.................... -0.00000027557319,
.................... 0.00000000208767,
.................... //-0.00000000001147,
.................... // 0.00000000000005
.................... };
....................
.................... if (x < 0) x = -x; // absolute value of input
....................
.................... quad = (unsigned int8)(x / PI_DIV_BY_TWO); // quadrant
.................... frac = (x / PI_DIV_BY_TWO) - quad; // fractional part of input
.................... quad = quad % 4; // quadrant (0 to 3)
....................
.................... if (quad == 0 || quad == 2)
.................... t = frac * PI_DIV_BY_TWO;
.................... else if (quad == 1)
.................... t = (1-frac) * PI_DIV_BY_TWO;
.................... else // should be 3
.................... t = (frac-1) * PI_DIV_BY_TWO;
....................
.................... y = 1.0;
.................... t = t * t;
.................... for (i = 0; i <= 5; i++)
.................... {
.................... t2 = t2 * t;
.................... y = y + p[i] * t2;
.................... }
....................
.................... if (quad == 2 || quad == 1)
.................... y = -y; // correct sign
....................
.................... return (y);
.................... }
....................
....................
.................... //Overloaded functions for cos() for PCD
.................... // Overloaded function cos() for data type - Float48
.................... #if defined(__PCD__)
.................... float48 cos(float48 x)
.................... {
.................... float48 y, t, t2 = 1.0;
.................... unsigned int8 quad, i;
.................... float48 frac;
.................... float48 p[6] = { //by the series definition for cosine
.................... -0.5, // sum ( ( (-1)^n * x^2n )/(2n)! )
.................... 0.04166666666667,
.................... -0.00138888888889,
.................... 0.00002480158730,
.................... -0.00000027557319,
.................... 0.00000000208767,
.................... //-0.00000000001147,
.................... // 0.00000000000005
.................... };
....................
.................... if (x < 0) x = -x; // absolute value of input
....................
.................... quad = (unsigned int8)(x / PI_DIV_BY_TWO); // quadrant
.................... frac = (x / PI_DIV_BY_TWO) - quad; // fractional part of input
.................... quad = quad % 4; // quadrant (0 to 3)
....................
.................... if (quad == 0 || quad == 2)
.................... t = frac * PI_DIV_BY_TWO;
.................... else if (quad == 1)
.................... t = (1-frac) * PI_DIV_BY_TWO;
.................... else // should be 3
.................... t = (frac-1) * PI_DIV_BY_TWO;
....................
.................... y = 0.999999999781;
.................... t = t * t;
.................... for (i = 0; i <= 5; i++)
.................... {
.................... t2 = t2 * t;
.................... y = y + p[i] * t2;
.................... }
....................
.................... if (quad == 2 || quad == 1)
.................... y = -y; // correct sign
....................
.................... return (y);
.................... }
....................
.................... // Overloaded function cos() for data type - Float48
.................... float64 cos(float64 x)
.................... {
.................... float64 y, t, t2 = 1.0;
.................... unsigned int8 quad, i;
.................... float64 frac;
.................... float64 p[6] = { //by the series definition for cosine
.................... -0.5, // sum ( ( (-1)^n * x^2n )/(2n)! )
.................... 0.04166666666667,
.................... -0.00138888888889,
.................... 0.00002480158730,
.................... -0.00000027557319,
.................... 0.00000000208767,
.................... //-0.00000000001147,
.................... // 0.00000000000005
.................... };
....................
.................... if (x < 0) x = -x; // absolute value of input
....................
.................... quad = (unsigned int8)(x / PI_DIV_BY_TWO); // quadrant
.................... frac = (x / PI_DIV_BY_TWO) - quad; // fractional part of input
.................... quad = quad % 4; // quadrant (0 to 3)
....................
.................... if (quad == 0 || quad == 2)
.................... t = frac * PI_DIV_BY_TWO;
.................... else if (quad == 1)
.................... t = (1-frac) * PI_DIV_BY_TWO;
.................... else // should be 3
.................... t = (frac-1) * PI_DIV_BY_TWO;
....................
.................... y = 0.999999999781;
.................... t = t * t;
.................... for (i = 0; i <= 5; i++)
.................... {
.................... t2 = t2 * t;
.................... y = y + p[i] * t2;
.................... }
....................
.................... if (quad == 2 || quad == 1)
.................... y = -y; // correct sign
....................
.................... return (y);
.................... }
....................
.................... #endif
....................
.................... ////////////////////////////////////////////////////////////////////////////
.................... // float sin(float x)
.................... ////////////////////////////////////////////////////////////////////////////
.................... // Description : returns the sine value of the angle x, which is in radian
.................... // Date : 9/20/2001
.................... //
.................... float32 sin(float32 x)
.................... {
.................... return cos(x - PI_DIV_BY_TWO);
.................... }
....................
.................... //Overloaded functions for sin() for PCD
.................... // Overloaded function sin() for data type - Float48
.................... #if defined(__PCD__)
.................... float48 sin(float48 x)
.................... {
.................... return cos(x - PI_DIV_BY_TWO);
.................... }
....................
.................... // Overloaded function sin() for data type - Float48
.................... float64 sin(float64 x)
.................... {
.................... return cos(x - PI_DIV_BY_TWO);
.................... }
.................... #endif
....................
.................... ////////////////////////////////////////////////////////////////////////////
.................... // float tan(float x)
.................... ////////////////////////////////////////////////////////////////////////////
.................... // Description : returns the tangent value of the angle x, which is in radian
.................... // Date : 9/20/2001
.................... //
.................... float32 tan(float32 x)
.................... {
.................... float32 c, s;
....................
.................... c = cos(x);
.................... if (c == 0.0)
.................... return (1.0e+36);
....................
.................... s = sin(x);
.................... return(s/c);
.................... }
.................... //Overloaded functions for tan() for PCD
.................... // Overloaded function tan() for data type - Float48
.................... #if defined(__PCD__)
.................... float48 tan(float48 x)
.................... {
.................... float48 c, s;
....................
.................... c = cos(x);
.................... if (c == 0.0)
.................... return (1.0e+36);
....................
.................... s = sin(x);
.................... return(s/c);
.................... }
....................
.................... // Overloaded function tan() for data type - Float48
.................... float64 tan(float64 x)
.................... {
.................... float64 c, s;
....................
.................... c = cos(x);
.................... if (c == 0.0)
.................... return (1.0e+36);
....................
.................... s = sin(x);
.................... return(s/c);
.................... }
.................... #endif
....................
.................... float32 const pas[3] = {0.49559947, -4.6145309, 5.6036290};
.................... float32 const qas[3] = {1.0000000, -5.5484666, 5.6036290};
....................
.................... float32 ASIN_COS(float32 x, unsigned int8 n)
.................... {
.................... float32 y, res, r, y2;
.................... int1 s;
.................... #ifdef _ERRNO
.................... if(x <-1 || x > 1)
.................... {
.................... errno=EDOM;
.................... }
.................... #endif
.................... s = 0;
.................... y = x;
....................
.................... if (x < 0)
.................... {
.................... s = 1;
.................... y = -y;
.................... }
....................
.................... if (y > 0.5)
.................... {
.................... y = sqrt((1.0 - y)/2.0);
.................... n += 2;
.................... }
....................
.................... y2=y*y;
....................
.................... res = pas[0]*y2 + pas[1];
.................... res = res*y2 + pas[2];
....................
.................... r = qas[0]*y2 + qas[1];
.................... r = r*y2 + qas[2];
....................
.................... res = y*res/r;
....................
.................... if (n & 2) // |x| > 0.5
.................... res = PI_DIV_BY_TWO - 2.0*res;
.................... if (s)
.................... res = -res;
.................... if (n & 1) // take arccos
.................... res = PI_DIV_BY_TWO - res;
....................
.................... return(res);
.................... }
....................
.................... //Overloaded functions for ASIN_COS() for PCD
.................... // Overloaded function ASIN_COS() for data type - Float48
.................... #if defined(__PCD__)
.................... float48 ASIN_COS(float48 x, unsigned int8 n)
.................... {
.................... float48 y, res, r, y2;
.................... int1 s;
.................... #ifdef _ERRNO
.................... if(x <-1 || x > 1)
.................... {
.................... errno=EDOM;
.................... }
.................... #endif
.................... s = 0;
.................... y = x;
....................
.................... if (x < 0)
.................... {
.................... s = 1;
.................... y = -y;
.................... }
....................
.................... if (y > 0.5)
.................... {
.................... y = sqrt((1.0 - y)/2.0);
.................... n += 2;
.................... }
....................
.................... y2=y*y;
....................
.................... res = pas[0]*y2 + pas[1];
.................... res = res*y2 + pas[2];
....................
.................... r = qas[0]*y2 + qas[1];
.................... r = r*y2 + qas[2];
....................
.................... res = y*res/r;
....................
.................... if (n & 2) // |x| > 0.5
.................... res = PI_DIV_BY_TWO - 2.0*res;
.................... if (s)
.................... res = -res;
.................... if (n & 1) // take arccos
.................... res = PI_DIV_BY_TWO - res;
....................
.................... return(res);
.................... }
....................
.................... // Overloaded function ASIN_COS() for data type - Float64
.................... float64 ASIN_COS(float64 x, unsigned int8 n)
.................... {
.................... float64 y, res, r, y2;
.................... int1 s;
.................... #ifdef _ERRNO
.................... if(x <-1 || x > 1)
.................... {
.................... errno=EDOM;
.................... }
.................... #endif
.................... s = 0;
.................... y = x;
....................
.................... if (x < 0)
.................... {
.................... s = 1;
.................... y = -y;
.................... }
....................
.................... if (y > 0.5)
.................... {
.................... y = sqrt((1.0 - y)/2.0);
.................... n += 2;
.................... }
....................
.................... y2=y*y;
....................
.................... res = pas[0]*y2 + pas[1];
.................... res = res*y2 + pas[2];
....................
.................... r = qas[0]*y2 + qas[1];
.................... r = r*y2 + qas[2];
....................
.................... res = y*res/r;
....................
.................... if (n & 2) // |x| > 0.5
.................... res = PI_DIV_BY_TWO - 2.0*res;
.................... if (s)
.................... res = -res;
.................... if (n & 1) // take arccos
.................... res = PI_DIV_BY_TWO - res;
....................
.................... return(res);
.................... }
.................... #endif
....................
.................... ////////////////////////////////////////////////////////////////////////////
.................... // float asin(float x)
.................... ////////////////////////////////////////////////////////////////////////////
.................... // Description : returns the arcsine value of the value x.
.................... // Date : N/A
.................... //
.................... float32 asin(float32 x)
.................... {
.................... float32 r;
....................
.................... r = ASIN_COS(x, 0);
.................... return(r);
.................... }
.................... //Overloaded functions for asin() for PCD
.................... // Overloaded function asin() for data type - Float48
.................... #if defined(__PCD__)
.................... float48 asin(float48 x)
.................... {
.................... float48 r;
....................
.................... r = ASIN_COS(x, 0);
.................... return(r);
.................... }
....................
.................... // Overloaded function asin() for data type - Float64
.................... float64 asin(float64 x)
.................... {
.................... float64 r;
....................
.................... r = ASIN_COS(x, 0);
.................... return(r);
.................... }
.................... #endif
....................
.................... ////////////////////////////////////////////////////////////////////////////
.................... // float acos(float x)
.................... ////////////////////////////////////////////////////////////////////////////
.................... // Description : returns the arccosine value of the value x.
.................... // Date : N/A
.................... //
.................... float32 acos(float32 x)
.................... {
.................... float32 r;
....................
.................... r = ASIN_COS(x, 1);
.................... return(r);
.................... }
.................... //Overloaded functions for acos() for PCD
.................... // Overloaded function acos() for data type - Float48
.................... #if defined(__PCD__)
.................... float48 acos(float48 x)
.................... {
.................... float48 r;
....................
.................... r = ASIN_COS(x, 1);
.................... return(r);
.................... }
....................
.................... // Overloaded function acos() for data type - Float64
.................... float64 acos(float64 x)
.................... {
.................... float64 r;
....................
.................... r = ASIN_COS(x, 1);
.................... return(r);
.................... }
.................... #endif
....................
.................... float32 const pat[4] = {0.17630401, 5.6710795, 22.376096, 19.818457};
.................... float32 const qat[4] = {1.0000000, 11.368190, 28.982246, 19.818457};
....................
.................... ////////////////////////////////////////////////////////////////////////////
.................... // float atan(float x)
.................... ////////////////////////////////////////////////////////////////////////////
.................... // Description : returns the arctangent value of the value x.
.................... // Date : N/A
.................... //
.................... float32 atan(float32 x)
.................... {
.................... float32 y, res, r;
.................... int1 s, flag;
....................
.................... s = 0;
.................... flag = 0;
.................... y = x;
....................
.................... if (x < 0)
.................... {
.................... s = 1;
.................... y = -y;
.................... }
....................
.................... if (y > 1.0)
.................... {
.................... y = 1.0/y;
.................... flag = 1;
.................... }
....................
.................... res = pat[0]*y*y + pat[1];
.................... res = res*y*y + pat[2];
.................... res = res*y*y + pat[3];
....................
.................... r = qat[0]*y*y + qat[1];
.................... r = r*y*y + qat[2];
.................... r = r*y*y + qat[3];
....................
.................... res = y*res/r;
....................
....................
.................... if (flag) // for |x| > 1
.................... res = PI_DIV_BY_TWO - res;
.................... if (s)
.................... res = -res;
....................
.................... return(res);
.................... }
.................... //Overloaded functions for atan() for PCD
.................... // Overloaded function atan() for data type - Float48
.................... #if defined(__PCD__)
.................... float48 atan(float48 x)
.................... {
.................... float48 y, res, r;
.................... int1 s, flag;
....................
.................... s = 0;
.................... flag = 0;
.................... y = x;
....................
.................... if (x < 0)
.................... {
.................... s = 1;
.................... y = -y;
.................... }
....................
.................... if (y > 1.0)
.................... {
.................... y = 1.0/y;
.................... flag = 1;
.................... }
....................
.................... res = pat[0]*y*y + pat[1];
.................... res = res*y*y + pat[2];
.................... res = res*y*y + pat[3];
....................
.................... r = qat[0]*y*y + qat[1];
.................... r = r*y*y + qat[2];
.................... r = r*y*y + qat[3];
....................
.................... res = y*res/r;
....................
....................
.................... if (flag) // for |x| > 1
.................... res = PI_DIV_BY_TWO - res;
.................... if (s)
.................... res = -res;
....................
.................... return(res);
.................... }
....................
.................... // Overloaded function atan() for data type - Float64
.................... float64 atan(float64 x)
.................... {
.................... float64 y, res, r;
.................... int1 s, flag;
....................
.................... s = 0;
.................... flag = 0;
.................... y = x;
....................
.................... if (x < 0)
.................... {
.................... s = 1;
.................... y = -y;
.................... }
....................
.................... if (y > 1.0)
.................... {
.................... y = 1.0/y;
.................... flag = 1;
.................... }
....................
.................... res = pat[0]*y*y + pat[1];
.................... res = res*y*y + pat[2];
.................... res = res*y*y + pat[3];
....................
.................... r = qat[0]*y*y + qat[1];
.................... r = r*y*y + qat[2];
.................... r = r*y*y + qat[3];
....................
.................... res = y*res/r;
....................
....................
.................... if (flag) // for |x| > 1
.................... res = PI_DIV_BY_TWO - res;
.................... if (s)
.................... res = -res;
....................
.................... return(res);
.................... }
.................... #endif
....................
.................... /////////////////////////////////////////////////////////////////////////////
.................... // float atan2(float y, float x)
.................... /////////////////////////////////////////////////////////////////////////////
.................... // Description :computes the principal value of arc tangent of y/x, using the
.................... // signs of both the arguments to determine the quadrant of the return value
.................... // Returns : returns the arc tangent of y/x.
.................... // Date : N/A
.................... //
....................
.................... float32 atan2(float32 y,float32 x)
.................... {
.................... float32 z;
.................... int1 sign;
.................... unsigned int8 quad;
.................... sign=0;
.................... quad=0; //quadrant
.................... quad=((y<=0.0)?((x<=0.0)?3:4):((x<0.0)?2:1));
.................... if(y<0.0)
.................... {
.................... sign=1;
.................... y=-y;
.................... }
.................... if(x<0.0)
.................... {
.................... x=-x;
.................... }
.................... if (x==0.0)
.................... {
.................... if(y==0.0)
.................... {
.................... #ifdef _ERRNO
.................... {
.................... errno=EDOM;
.................... }
.................... #endif
.................... }
.................... else
.................... {
.................... if(sign)
.................... {
.................... return (-(PI_DIV_BY_TWO));
.................... }
.................... else
.................... {
.................... return (PI_DIV_BY_TWO);
.................... }
.................... }
.................... }
.................... else
.................... {
.................... z=y/x;
.................... switch(quad)
.................... {
.................... case 1:
.................... {
.................... return atan(z);
.................... break;
.................... }
.................... case 2:
.................... {
.................... // return (atan(z)+PI_DIV_BY_TWO); //2L3122
.................... return (PI-atan(z));
.................... break;
.................... }
.................... case 3:
.................... {
.................... return (atan(z)-PI);
.................... break;
.................... }
.................... case 4:
.................... {
.................... return (-atan(z));
.................... break;
.................... }
.................... }
.................... }
.................... }
....................
.................... //Overloaded functions for atan2() for PCD
.................... // Overloaded function atan2() for data type - Float48
.................... #if defined(__PCD__)
.................... float48 atan2(float48 y,float48 x)
.................... {
.................... float48 z;
.................... int1 sign;
.................... unsigned int8 quad;
.................... sign=0;
.................... quad=0; //quadrant
.................... quad=((y<=0.0)?((x<=0.0)?3:4):((x<0.0)?2:1));
.................... if(y<0.0)
.................... {
.................... sign=1;
.................... y=-y;
.................... }
.................... if(x<0.0)
.................... {
.................... x=-x;
.................... }
.................... if (x==0.0)
.................... {
.................... if(y==0.0)
.................... {
.................... #ifdef _ERRNO
.................... {
.................... errno=EDOM;
.................... }
.................... #endif
.................... }
.................... else
.................... {
.................... if(sign)
.................... {
.................... return (-(PI_DIV_BY_TWO));
.................... }
.................... else
.................... {
.................... return (PI_DIV_BY_TWO);
.................... }
.................... }
.................... }
.................... else
.................... {
.................... z=y/x;
.................... switch(quad)
.................... {
.................... case 1:
.................... {
.................... return atan(z);
.................... break;
.................... }
.................... case 2:
.................... {
.................... // return (atan(z)+PI_DIV_BY_TWO); //2L3122
.................... return (PI-atan(z));
.................... break;
.................... }
.................... case 3:
.................... {
.................... return (atan(z)-PI);
.................... break;
.................... }
.................... case 4:
.................... {
.................... return (-atan(z));
.................... break;
.................... }
.................... }
.................... }
.................... }
....................
.................... // Overloaded function atan2() for data type - Float64
.................... float64 atan2(float64 y,float64 x)
.................... {
.................... float64 z;
.................... int1 sign;
.................... unsigned int8 quad;
.................... sign=0;
.................... quad=0; //quadrant
.................... quad=((y<=0.0)?((x<=0.0)?3:4):((x<0.0)?2:1));
.................... if(y<0.0)
.................... {
.................... sign=1;
.................... y=-y;
.................... }
.................... if(x<0.0)
.................... {
.................... x=-x;
.................... }
.................... if (x==0.0)
.................... {
.................... if(y==0.0)
.................... {
.................... #ifdef _ERRNO
.................... {
.................... errno=EDOM;
.................... }
.................... #endif
.................... }
.................... else
.................... {
.................... if(sign)
.................... {
.................... return (-(PI_DIV_BY_TWO));
.................... }
.................... else
.................... {
.................... return (PI_DIV_BY_TWO);
.................... }
.................... }
.................... }
.................... else
.................... {
.................... z=y/x;
.................... switch(quad)
.................... {
.................... case 1:
.................... {
.................... return atan(z);
.................... break;
.................... }
.................... case 2:
.................... {
.................... // return (atan(z)+PI_DIV_BY_TWO); //2L3122
.................... return (PI-atan(z));
.................... break;
.................... }
.................... case 3:
.................... {
.................... return (atan(z)-PI);
.................... break;
.................... }
.................... case 4:
.................... {
.................... return (-atan(z));
.................... break;
.................... }
.................... }
.................... }
.................... }
.................... #endif
....................
.................... //////////////////// Hyperbolic functions ////////////////////
....................
.................... ////////////////////////////////////////////////////////////////////////////
.................... // float cosh(float x)
.................... ////////////////////////////////////////////////////////////////////////////
.................... // Description : Computes the hyperbolic cosine value of x
.................... // Returns : returns the hyperbolic cosine value of x
.................... // Date : N/A
.................... //
....................
.................... float32 cosh(float32 x)
.................... {
.................... return ((exp(x)+exp(-x))/2);
.................... }
.................... //Overloaded functions for cosh() for PCD
.................... // Overloaded function cosh() for data type - Float48
.................... #if defined(__PCD__)
.................... float48 cosh(float48 x)
.................... {
.................... return ((exp(x)+exp(-x))/2);
.................... }
....................
.................... // Overloaded function cosh() for data type - Float64
.................... float64 cosh(float64 x)
.................... {
.................... return ((exp(x)+exp(-x))/2);
.................... }
.................... #endif
....................
.................... ////////////////////////////////////////////////////////////////////////////
.................... // float sinh(float x)
.................... ////////////////////////////////////////////////////////////////////////////
.................... // Description : Computes the hyperbolic sine value of x
.................... // Returns : returns the hyperbolic sine value of x
.................... // Date : N/A
.................... //
....................
.................... float32 sinh(float32 x)
.................... {
....................
.................... return ((exp(x) - exp(-x))/2);
.................... }
.................... //Overloaded functions for sinh() for PCD
.................... // Overloaded function sinh() for data type - Float48
.................... #if defined(__PCD__)
.................... float48 sinh(float48 x)
.................... {
....................
.................... return ((exp(x) - exp(-x))/2);
.................... }
....................
.................... // Overloaded function sinh() for data type - Float48
.................... float64 sinh(float64 x)
.................... {
....................
.................... return ((exp(x) - exp(-x))/2);
.................... }
.................... #endif
....................
.................... ////////////////////////////////////////////////////////////////////////////
.................... // float tanh(float x)
.................... ////////////////////////////////////////////////////////////////////////////
.................... // Description : Computes the hyperbolic tangent value of x
.................... // Returns : returns the hyperbolic tangent value of x
.................... // Date : N/A
.................... //
....................
.................... float32 tanh(float32 x)
.................... {
.................... return(sinh(x)/cosh(x));
.................... }
.................... //Overloaded functions for tanh() for PCD
.................... // Overloaded function tanh() for data type - Float48
.................... #if defined(__PCD__)
.................... float48 tanh(float48 x)
.................... {
.................... return(sinh(x)/cosh(x));
.................... }
....................
.................... // Overloaded function tanh() for data type - Float64
.................... float64 tanh(float64 x)
.................... {
.................... return(sinh(x)/cosh(x));
.................... }
.................... #endif
....................
.................... ////////////////////////////////////////////////////////////////////////////
.................... // float frexp(float x, signed int *exp)
.................... ////////////////////////////////////////////////////////////////////////////
.................... // Description : breaks a floating point number into a normalized fraction and an integral
.................... // power of 2. It stores the integer in the signed int object pointed to by exp.
.................... // Returns : returns the value x, such that x is a double with magnitude in the interval
.................... // [1/2,1) or zero, and value equals x times 2 raised to the power *exp.If value is zero,
.................... // both parts of the result are zero.
.................... // Date : N/A
.................... //
....................
.................... #define LOG2 .30102999566398119521
.................... float32 frexp(float32 x, signed int8 *exp)
.................... {
.................... float32 res;
.................... int1 sign = 0;
.................... if(x == 0.0)
.................... {
.................... *exp=0;
.................... return (0.0);
.................... }
.................... if(x < 0.0)
.................... {
.................... x=-x;
.................... sign=1;
.................... }
.................... if (x > 1.0)
.................... {
.................... *exp=(ceil(log10(x)/LOG2));
.................... res=x/(pow(2, *exp));
.................... if (res == 1)
.................... {
.................... *exp=*exp+1;
.................... res=.5;
.................... }
.................... }
.................... else
.................... {
.................... if(x < 0.5)
.................... {
.................... *exp=-1;
.................... res=x*2;
.................... }
.................... else
.................... {
.................... *exp=0;
.................... res=x;
.................... }
.................... }
.................... if(sign)
.................... {
.................... res=-res;
.................... }
.................... return res;
.................... }
....................
.................... //Overloaded functions for frexp() for PCD
.................... // Overloaded function frexp() for data type - Float48
.................... #if defined(__PCD__)
.................... float48 frexp(float48 x, signed int8 *exp)
.................... {
.................... float48 res;
.................... int1 sign = 0;
.................... if(x == 0.0)
.................... {
.................... *exp=0;
.................... return (0.0);
.................... }
.................... if(x < 0.0)
.................... {
.................... x=-x;
.................... sign=1;
.................... }
.................... if (x > 1.0)
.................... {
.................... *exp=(ceil(log10(x)/LOG2));
.................... res=x/(pow(2, *exp));
.................... if (res == 1)
.................... {
.................... *exp=*exp+1;
.................... res=.5;
.................... }
.................... }
.................... else
.................... {
.................... if(x < 0.5)
.................... {
.................... *exp=-1;
.................... res=x*2;
.................... }
.................... else
.................... {
.................... *exp=0;
.................... res=x;
.................... }
.................... }
.................... if(sign)
.................... {
.................... res=-res;
.................... }
.................... return res;
.................... }
....................
.................... // Overloaded function frexp() for data type - Float64
.................... float64 frexp(float64 x, signed int8 *exp)
.................... {
.................... float64 res;
.................... int1 sign = 0;
.................... if(x == 0.0)
.................... {
.................... *exp=0;
.................... return (0.0);
.................... }
.................... if(x < 0.0)
.................... {
.................... x=-x;
.................... sign=1;
.................... }
.................... if (x > 1.0)
.................... {
.................... *exp=(ceil(log10(x)/LOG2));
.................... res=x/(pow(2, *exp));
.................... if (res == 1)
.................... {
.................... *exp=*exp+1;
.................... res=.5;
.................... }
.................... }
.................... else
.................... {
.................... if(x < 0.5)
.................... {
.................... *exp=-1;
.................... res=x*2;
.................... }
.................... else
.................... {
.................... *exp=0;
.................... res=x;
.................... }
.................... }
.................... if(sign)
.................... {
.................... res=-res;
.................... }
.................... return res;
.................... }
.................... #endif
....................
.................... //////////////////////////////////////////////////////////////////////////////
.................... // float ldexp(float x, signed int *exp)
.................... //////////////////////////////////////////////////////////////////////////////
.................... // Description : multiplies a floating point number by an integral power of 2.
.................... // Returns : returns the value of x times 2 raised to the power exp.
.................... // Date : N/A
.................... //
....................
.................... float32 ldexp(float32 value, signed int8 exp)
.................... {
.................... return (value * pow(2,exp));
.................... }
.................... //Overloaded functions for ldexp() for PCD
.................... // Overloaded function ldexp() for data type - Float48
....................
.................... #if defined(__PCD__)
.................... float48 ldexp(float48 value, signed int8 exp)
.................... {
.................... return (value * pow(2,exp));
.................... }
.................... // Overloaded function ldexp() for data type - Float64
.................... float64 ldexp(float64 value, signed int8 exp)
.................... {
.................... return (value * pow(2,exp));
.................... }
.................... #endif
....................
.................... #endif
....................
....................
.................... void main()
.................... {
*
023C: CLRF 04
023D: BCF 03.7
023E: MOVLW 1F
023F: ANDWF 03,F
0240: MOVLW 71
0241: BSF 03.5
0242: MOVWF 0F
0243: MOVF 0F,W
0244: BSF 03.6
0245: BCF 07.3
0246: MOVLW 0C
0247: BCF 03.6
0248: MOVWF 19
0249: MOVLW A2
024A: MOVWF 18
024B: MOVLW 90
024C: BCF 03.5
024D: MOVWF 18
024E: BSF 03.5
024F: BSF 03.6
0250: MOVF 09,W
0251: ANDLW C0
0252: MOVWF 09
0253: BCF 03.6
0254: BCF 1F.4
0255: BCF 1F.5
0256: MOVLW 00
0257: BSF 03.6
0258: MOVWF 08
0259: BCF 03.5
025A: CLRF 07
025B: CLRF 08
025C: CLRF 09
.................... setup_adc_ports(NO_ANALOGS|VSS_VDD);
*
0266: BSF 03.5
0267: BSF 03.6
0268: MOVF 09,W
0269: ANDLW C0
026A: MOVWF 09
026B: BCF 03.6
026C: BCF 1F.4
026D: BCF 1F.5
026E: MOVLW 00
026F: BSF 03.6
0270: MOVWF 08
.................... setup_adc(ADC_CLOCK_DIV_2);
0271: BCF 03.5
0272: BCF 03.6
0273: BCF 1F.6
0274: BCF 1F.7
0275: BSF 03.5
0276: BCF 1F.7
0277: BCF 03.5
0278: BSF 1F.0
.................... setup_spi(SPI_SS_DISABLED);
0279: BCF 14.5
027A: BCF 20.5
027B: MOVF 20,W
027C: BSF 03.5
027D: MOVWF 07
027E: BCF 03.5
027F: BSF 20.4
0280: MOVF 20,W
0281: BSF 03.5
0282: MOVWF 07
0283: BCF 03.5
0284: BCF 20.3
0285: MOVF 20,W
0286: BSF 03.5
0287: MOVWF 07
0288: MOVLW 01
0289: BCF 03.5
028A: MOVWF 14
028B: MOVLW 00
028C: BSF 03.5
028D: MOVWF 14
.................... setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
028E: MOVF 01,W
028F: ANDLW C7
0290: IORLW 08
0291: MOVWF 01
.................... setup_timer_1(T1_DISABLED);
0292: BCF 03.5
0293: CLRF 10
.................... setup_timer_2(T2_DISABLED,0,1);
0294: MOVLW 00
0295: MOVWF 78
0296: MOVWF 12
0297: MOVLW 00
0298: BSF 03.5
0299: MOVWF 12
.................... setup_ccp1(CCP_OFF);
029A: BCF 03.5
029B: BSF 20.2
029C: MOVF 20,W
029D: BSF 03.5
029E: MOVWF 07
029F: BCF 03.5
02A0: CLRF 17
02A1: BSF 03.5
02A2: CLRF 1B
02A3: CLRF 1C
02A4: MOVLW 01
02A5: MOVWF 1D
.................... setup_comparator(NC_NC_NC_NC);
02A6: BCF 03.5
02A7: BSF 03.6
02A8: CLRF 07
02A9: CLRF 08
02AA: CLRF 09
....................
.................... printf("Magnetometr: \r\n",);
02AB: MOVLW 04
02AC: MOVWF 0D
02AD: MOVLW 00
02AE: MOVWF 0F
02AF: BCF 03.6
02B0: CALL 021
.................... printf("(c)mlab.cz kaklik 2013: \r\n",);
02B1: MOVLW 0D
02B2: BSF 03.6
02B3: MOVWF 0D
02B4: MOVLW 00
02B5: MOVWF 0F
02B6: BCF 03.6
02B7: CALL 021
.................... printf("X, Y, Z \r\n",);
02B8: MOVLW 1B
02B9: BSF 03.6
02BA: MOVWF 0D
02BB: MOVLW 00
02BC: MOVWF 0F
02BD: BCF 03.6
02BE: CALL 021
....................
....................
.................... // Init the HMC5883L. Set Mode register for
.................... // continuous measurements.
.................... hmc5883l_write_reg(HMC5883L_CFG_A_REG, 0x18); // no average, maximal update range
02BF: CLRF 27
02C0: MOVLW 18
02C1: MOVWF 28
02C2: CALL 0B3
.................... hmc5883l_write_reg(HMC5883L_CFG_B_REG, 0x00); // minimal range
02C3: MOVLW 01
02C4: MOVWF 27
02C5: CLRF 28
02C6: CALL 0B3
.................... hmc5883l_write_reg(HMC5883L_MODE_REG, 0x00);
02C7: MOVLW 02
02C8: MOVWF 27
02C9: CLRF 28
02CA: CALL 0B3
....................
.................... // Continuously read and display the x,y,z results.
.................... // Wait at least 67 ms between reads, re the HMC5883L data sheet.
....................
....................
.................... while(TRUE)
.................... {
....................
.................... hmc5883l_read_data();
02CB: GOTO 131
.................... printf("%6Ld %6Ld %6Ld \n\r", compass.x, compass.y, compass.z);
02CC: MOVLW 00
02CD: MOVWF 04
02CE: MOVF 22,W
02CF: MOVWF 28
02D0: MOVF 21,W
02D1: MOVWF 27
02D2: CALL 1B0
02D3: MOVLW 20
02D4: BTFSS 0C.4
02D5: GOTO 2D4
02D6: MOVWF 19
02D7: MOVLW 00
02D8: MOVWF 04
02D9: MOVF 24,W
02DA: MOVWF 28
02DB: MOVF 23,W
02DC: MOVWF 27
02DD: CALL 1B0
02DE: MOVLW 20
02DF: BTFSS 0C.4
02E0: GOTO 2DF
02E1: MOVWF 19
02E2: MOVLW 00
02E3: MOVWF 04
02E4: MOVF 26,W
02E5: MOVWF 28
02E6: MOVF 25,W
02E7: MOVWF 27
02E8: CALL 1B0
02E9: MOVLW 20
02EA: BTFSS 0C.4
02EB: GOTO 2EA
02EC: MOVWF 19
02ED: MOVLW 0A
02EE: BTFSS 0C.4
02EF: GOTO 2EE
02F0: MOVWF 19
02F1: MOVLW 0D
02F2: BTFSS 0C.4
02F3: GOTO 2F2
02F4: MOVWF 19
.................... delay_ms(100);
02F5: MOVLW 64
02F6: MOVWF 27
02F7: GOTO 226
.................... }
02F8: GOTO 2CB
....................
.................... }
....................
....................
....................
02F9: SLEEP
 
Configuration Fuses:
Word 1: 2CF5 INTRC NOWDT NOPUT MCLR NOPROTECT NOCPD NOBROWNOUT IESO FCMEN NOLVP NODEBUG
Word 2: 3FFF NOWRT BORV40
/Modules/Sensors/MAG01A/SW/PIC16F887/main.pjt
0,0 → 1,31
[PROJECT]
Target=main.hex
Development_Mode=
Processor_Text=PIC16F887
ToolSuite=CCS
Processor=0x887F
[main]
Type=4
Path=
FileList=
BuildTool=
OptionString=
AdditionalOptionString=
[mru-list]
1=main.c
[Windows]
0=0000 %S 0 0 796 451 3 0
[Opened Files]
1=main.c
2=main.h
3=C:\Program Files (x86)\PICC\devices\16F887.h
4=HMC5883L.h
5=HMC5883L.c
6=C:\Program Files (x86)\PICC\drivers\math.h
7=
[Target Data]
OptionString=-p +FM
FileList=Z:\home\kaklik\svnMLAB\Modules\Sensors\MAG01A\SW\PIC16F887\main.c
[Units]
Count=1
1=main (main)
/Modules/Sensors/MAG01A/SW/PIC16F887/main.sta
0,0 → 1,59
 
ROM used: 762 (9%)
762 (9%) including unused fragments
 
0 Average locations per line
2 Average locations per statement
 
RAM used: 12 (3%) at main() level
21 (6%) worst case
 
Stack used: 2 worst case (out of 8 total available)
 
Lines Stmts % Files
----- ----- --- -----
43 19 6 main.c
22 0 0 main.h
423 0 0 C:\Program Files (x86)\PICC\devices\16F887.h
25 0 0 HMC5883L.h
76 28 9 HMC5883L.c
2172 260 85 C:\Program Files (x86)\PICC\drivers\math.h
----- -----
2761 307 Total
 
Page ROM % RAM Vol Diff Functions:
---- --- --- --- --- ---- ----------
0 22 3 1 @delay_ms1
0 69 9 3 @I2C_READ_1
0 74 10 1 @I2C_WRITE_1
0 57 7 2 102 1.8 hmc5883l_write_reg
0 127 17 6 636 3.3 hmc5883l_read_data
0 190 25 0 595 3.3 MAIN
0 9 1 0 78 2.7 @const229
0 72 9 3 722 3.9 @PSTRINGC7_9600_62_63
0 14 2 0 @const231
0 6 1 0 @const232
0 118 15 9 @PRINTF_LD_9600_62_63
 
Program metrics:
Functions 5
Statements 307
Comments 356
Volume (V) 2913
Difficilty (D) 14.9
Effort to implement (E) 43483
Time to implement (T) 40 minutes
Est Delivered Bugs (B) 0
Cyclomatic Complexity 1
Maintainability (MI) 95
 
Segment Used Free
----------- ---- ----
00000-00003 4 0
00004-007FF 758 1286
00800-00FFF 0 2048
01000-017FF 0 2048
01800-01FFF 0 2048
 
 
 
/Modules/Sensors/MAG01A/SW/PIC16F887/main.sym
0,0 → 1,95
004-005 @READ_PROGRAM_MEMORY8.P1
004 @WRITE_PROGRAM_MEMORY8.P2
015 CCP_1
015 CCP_1_LOW
016 CCP_1_HIGH
01B CCP_2_LOW
01B CCP_2
01C CCP_2_HIGH
020 @TRIS_C
021-026 compass
027 hmc5883l_write_reg.reg
027 @delay_ms1.P1
027 hmc5883l_read_data.x_lsb
027-028 @PRINTF_LD_9600_62_63.P1
027 @PSTRINGC7_9600_62_63.@SCRATCH1
028 hmc5883l_write_reg.data
028 hmc5883l_read_data.x_msb
028 @PSTRINGC7_9600_62_63.@SCRATCH2
029 hmc5883l_read_data.y_lsb
029 @PSTRINGC7_9600_62_63.@SCRATCH3
029 @PRINTF_LD_9600_62_63.@SCRATCH1
02A hmc5883l_read_data.y_msb
02A @PRINTF_LD_9600_62_63.@SCRATCH2
02B hmc5883l_read_data.z_lsb
02B @PRINTF_LD_9600_62_63.@SCRATCH3
02C hmc5883l_read_data.z_msb
02C @PRINTF_LD_9600_62_63.@SCRATCH4
02D @I2C_READ_1.P1
02D @I2C_WRITE_1.P2
02D @PRINTF_LD_9600_62_63.@SCRATCH5
02E @I2C_READ_1.@SCRATCH1
02E @PRINTF_LD_9600_62_63.@SCRATCH6
02F @I2C_READ_1.@SCRATCH2
02F @PRINTF_LD_9600_62_63.@SCRATCH7
077 @SCRATCH
078 @SCRATCH
078 _RETURN_
079 @SCRATCH
07A @SCRATCH
107.6 C1OUT
108.6 C2OUT
10D-10E @WRITE_PROGRAM_MEMORY8.P1
10D-10E @READ_PROGRAM_MEMORY8.P2
 
ROM Allocation:
0226 @delay_ms1
00EC @I2C_READ_1
0069 @I2C_WRITE_1
00B3 hmc5883l_write_reg
0131 hmc5883l_read_data
023C MAIN
0004 @const229
0021 @PSTRINGC7_9600_62_63
000D @const231
001B @const232
01B0 @PRINTF_LD_9600_62_63
023C @cinit
 
 
User Memory space:
 
User Memory space:
 
Project Directory:
Z:\home\kaklik\svnMLAB\Modules\Sensors\MAG01A\SW\PIC16F887\
 
Project Files:
main.c
main.h
C:\Program Files (x86)\PICC\devices\16F887.h
HMC5883L.h
HMC5883L.c
C:\Program Files (x86)\PICC\drivers\math.h
 
Units:
Z:\home\kaklik\svnMLAB\Modules\Sensors\MAG01A\SW\PIC16F887\main (main)
 
Compiler Settings:
Processor: PIC16F887
Pointer Size: 16
ADC Range: 0-255
Opt Level: 9
Short,Int,Long: UNSIGNED: 1,8,16
Float,Double: 32,32
 
Output Files:
Errors: main.err
Ext Symbols: main.esym
INHX8: main.hex
Symbols: main.sym
List: main.lst
Debug/COFF: main.cof
Project: main.PJT
Call Tree: main.tre
Statistics: main.sta
/Modules/Sensors/MAG01A/SW/PIC16F887/main.tre
0,0 → 1,32
ÀÄmain
ÀÄMAIN 0/190 Ram=0
ÃÄ??0??
ÃÄ@PSTRINGC7_9600_62_63 0/72 Ram=3
ÃÄ@PSTRINGC7_9600_62_63 0/72 Ram=3
ÃÄ@PSTRINGC7_9600_62_63 0/72 Ram=3
ÃÄhmc5883l_write_reg 0/57 Ram=2
³ ÃÄ@I2C_WRITE_1 0/74 Ram=1
³ ÃÄ@I2C_WRITE_1 0/74 Ram=1
³ ÀÄ@I2C_WRITE_1 0/74 Ram=1
ÃÄhmc5883l_write_reg 0/57 Ram=2
³ ÃÄ@I2C_WRITE_1 0/74 Ram=1
³ ÃÄ@I2C_WRITE_1 0/74 Ram=1
³ ÀÄ@I2C_WRITE_1 0/74 Ram=1
ÃÄhmc5883l_write_reg 0/57 Ram=2
³ ÃÄ@I2C_WRITE_1 0/74 Ram=1
³ ÃÄ@I2C_WRITE_1 0/74 Ram=1
³ ÀÄ@I2C_WRITE_1 0/74 Ram=1
ÃÄhmc5883l_read_data 0/127 Ram=6
³ ÃÄ@I2C_WRITE_1 0/74 Ram=1
³ ÃÄ@I2C_WRITE_1 0/74 Ram=1
³ ÃÄ@I2C_WRITE_1 0/74 Ram=1
³ ÃÄ@I2C_READ_1 0/69 Ram=3
³ ÃÄ@I2C_READ_1 0/69 Ram=3
³ ÃÄ@I2C_READ_1 0/69 Ram=3
³ ÃÄ@I2C_READ_1 0/69 Ram=3
³ ÃÄ@I2C_READ_1 0/69 Ram=3
³ ÀÄ@I2C_READ_1 0/69 Ram=3
ÃÄ@PRINTF_LD_9600_62_63 0/118 Ram=9
ÃÄ@PRINTF_LD_9600_62_63 0/118 Ram=9
ÃÄ@PRINTF_LD_9600_62_63 0/118 Ram=9
ÀÄ@delay_ms1 0/22 Ram=1
/Modules/Sensors/MAG01A/SW/PIC16F887/HMC5883L.c
0,0 → 1,75
//------------------------------
// Low level routines
//------------------------------
void hmc5883l_write_reg(int8 reg, int8 data)
{
i2c_start();
i2c_write(HMC5883L_WRT_ADDR);
i2c_write(reg);
i2c_write(data);
i2c_stop();
}
 
//------------------------------
int8 hmc5883l_read_reg(int8 reg)
{
int8 retval;
 
i2c_start();
i2c_write(HMC5883L_WRT_ADDR);
i2c_write(reg);
i2c_start();
i2c_write(HMC5883L_READ_ADDR);
retval = i2c_read(0);
i2c_stop();
 
return(retval);
}
 
//------------------------------
typedef struct
{
signed int16 x;
signed int16 y;
signed int16 z;
}hmc5883l_result;
 
// This global structure holds the values read
// from the HMC5883L x,y,z registers.
hmc5883l_result compass = {0,0,0};
 
//------------------------------
void hmc5883l_read_data(void)
{
unsigned int8 x_lsb;
unsigned int8 x_msb;
 
unsigned int8 y_lsb;
unsigned int8 y_msb;
 
unsigned int8 z_lsb;
unsigned int8 z_msb;
 
i2c_start();
i2c_write(HMC5883L_WRT_ADDR);
i2c_write(HMC5883L_X_MSB_REG); // Point to X-msb register
i2c_start();
i2c_write(HMC5883L_READ_ADDR);
 
x_msb = i2c_read();
x_lsb = i2c_read();
 
z_msb = i2c_read();
z_lsb = i2c_read();
 
y_msb = i2c_read();
y_lsb = i2c_read(0); // do a NACK on last read
 
i2c_stop();
// Combine high and low bytes into 16-bit values.
compass.x = make16(x_msb, x_lsb);
compass.y = make16(y_msb, y_lsb);
compass.z = make16(z_msb, z_lsb);
}
 
/Modules/Sensors/MAG01A/SW/PIC16F887/HMC5883L.h
0,0 → 1,23
// i2c slave addresses
#define HMC5883L_WRT_ADDR 0x3C
#define HMC5883L_READ_ADDR 0x3D
 
// Register addresses
#define HMC5883L_CFG_A_REG 0x00
#define HMC5883L_CFG_B_REG 0x01
#define HMC5883L_MODE_REG 0x02
#define HMC5883L_X_MSB_REG 0x03
 
//Konstanty nastavujici rozsah
//pro void set_mag_roz (unsigned int8 h)
#define MAG_ROZ088 0x00
#define MAG_ROZ130 0x20
#define MAG_ROZ190 0x40
#define MAG_ROZ250 0x60
#define MAG_ROZ400 0x80
#define MAG_ROZ470 0xA0
#define MAG_ROZ560 0xC0
#define MAG_ROZ810 0xE0
 
 
#include "HMC5883L.c"
/Modules/Sensors/MAG01A/SW/PIC16F887/main.bak
0,0 → 1,32
#include "main.h"
#include "HMC5883L.h"
 
void main()
{
setup_adc_ports(NO_ANALOGS|VSS_VDD);
setup_adc(ADC_CLOCK_DIV_2);
setup_spi(SPI_SS_DISABLED);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_ccp1(CCP_OFF);
setup_comparator(NC_NC_NC_NC);// This device COMP currently not supported by the PICWizard
 
printf("Magnetometr: \r\n",);
printf("(c)mlab JACHO 2013: \r\n",);
printf("Vysledky z jednotlivych os:\r\n",);
signed int16 X,Y,Z;
 
while(true)
{
printf("Vysledky z jednotlivych os:\r\n",);
X = mag_readX();
Y = mag_readY();
Z = mag_readZ();
printf("X: %Ld \r\n", X);
printf("Y %Ld \r\n", Y);
printf("Z: %Ld \r\n", Z);
Delay_ms(500);
}
}