Merge branch 'edge' into multitool
[clinton/Smoothieware.git] / src / modules / tools / temperaturecontrol / max31855.cpp
CommitLineData
9d955060 1/*
2 This file is part of Smoothie (http://smoothieware.org/). The motion control part is heavily based on Grbl (https://github.com/simen/grbl).
3 Smoothie 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 3 of the License, or (at your option) any later version.
4 Smoothie 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.
5 You should have received a copy of the GNU General Public License along with Smoothie. If not, see <http://www.gnu.org/licenses/>.
6*/
7
8#include "libs/Kernel.h"
9#include <math.h>
10#include "libs/Pin.h"
11#include "Config.h"
12#include "checksumm.h"
13#include "ConfigValue.h"
14
15#include "max31855.h"
16
17#include "MRI_Hooks.h"
18
b1cf0bf5 19#define chip_select_checksum CHECKSUM("chip_select_pin")
9d955060 20#define spi_channel_checksum CHECKSUM("spi_channel")
21
d8baddd9 22Max31855::Max31855() :
23 spi(nullptr)
9d955060 24{
25}
26
27Max31855::~Max31855()
28{
d8baddd9 29 delete spi;
9d955060 30}
31
32// Get configuration from the config file
33void Max31855::UpdateConfig(uint16_t module_checksum, uint16_t name_checksum)
34{
d8baddd9 35 // Chip select
b1cf0bf5 36 this->spi_cs_pin.from_string(THEKERNEL->config->value(module_checksum, name_checksum, chip_select_checksum)->by_default("0.16")->as_string());
d8baddd9 37 this->spi_cs_pin.set(true);
38 this->spi_cs_pin.as_output();
39
9d955060 40 // select which SPI channel to use
41 int spi_channel = THEKERNEL->config->value(module_checksum, name_checksum, spi_channel_checksum)->by_default(0)->as_number();
42 PinName miso;
43 PinName mosi;
44 PinName sclk;
45 if(spi_channel == 0) {
d8baddd9 46 // Channel 0
9d955060 47 mosi=P0_18; miso=P0_17; sclk=P0_15;
48 } else {
d8baddd9 49 // Channel 1
9d955060 50 mosi=P0_9; miso=P0_8; sclk=P0_7;
51 }
52
d8baddd9 53 delete spi;
54 spi = new mbed::SPI(mosi, miso, sclk);
9d955060 55
d8baddd9 56 // Spi settings: 1MHz (default), 16 bits, mode 0 (default)
57 spi->format(16);
9d955060 58}
59
60float Max31855::get_temperature()
61{
d8baddd9 62 // Return an average of the last readings
63 if (readings.size() >= readings.capacity()) {
64 readings.delete_tail();
65 }
66
67 float temp = read_temp();
68
69 // Discard occasional errors...
70 if(!isinf(temp))
71 {
72 readings.push_back(temp);
73 }
74
75 if(readings.size()==0) return infinityf();
9d955060 76
d8baddd9 77 float sum = 0;
78 for (int i=0; i<readings.size(); i++)
79 sum += *readings.get_ref(i);
80
81 return sum / readings.size();
82}
83
84float Max31855::read_temp()
85{
86 this->spi_cs_pin.set(false);
87 wait_us(1); // Must wait for first bit valid
88
89 // Read 16 bits (writing something as well is required by the api)
90 uint16_t data = spi->write(0);
91 // Read next 16 bits (diagnostics)
ee6b7bd5 92// uint16_t data2 = spi->write(0);
93
d8baddd9 94 this->spi_cs_pin.set(true);
95
96 float temperature;
9d955060 97
98 //Process temp
ee6b7bd5 99 if (data & 0x0001)
d8baddd9 100 {
101 // Error flag.
b057d616 102 temperature = infinityf();
d8baddd9 103 // Todo: Interpret data2 for more diagnostics.
104 }
9d955060 105 else
106 {
ee6b7bd5 107 data = data >> 2;
108 temperature = (data & 0x1FFF) / 4.f;
9d955060 109
ee6b7bd5 110 if (data & 0x2000)
9d955060 111 {
112 data = ~data;
ee6b7bd5 113 temperature = ((data & 0x1FFF) + 1) / -4.f;
9d955060 114 }
115 }
d8baddd9 116 return temperature;
9d955060 117}