diff --git a/src/main.c b/src/main.c
index da7995f..0c597b8 100644
--- a/src/main.c
+++ b/src/main.c
@@ -34,6 +34,7 @@
#include "buzzer.h"
#include "nvstorage.h"
#include "version.h"
+#include "max31855.h"
extern uint8_t logobmp[];
extern uint8_t stopbmp[];
@@ -192,6 +193,7 @@ int main(void) {
ADC_Init();
RTC_Init();
OneWire_Init();
+ SPI_TC_Init();
Reflow_Init();
Sched_SetWorkfunc( MAIN_WORK, Main_Work );
diff --git a/src/max31855.c b/src/max31855.c
new file mode 100644
index 0000000..3f6cefe
--- /dev/null
+++ b/src/max31855.c
@@ -0,0 +1,118 @@
+/*
+ * max31855.c - SPI TC interface handling for T-962 reflow controller
+ *
+ * Copyright (C) 2014 Werner Johansson, wj@unifiedengineering.se
+ *
+ * This program 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.
+
+ * This program 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 this program. If not, see .
+ */
+
+#include
+#include
+#include
+#include
+#include "sc18is602b.h"
+#include "sched.h"
+
+#define MAX_SPI_DEVICES (4)
+int16_t spidevreadout[MAX_SPI_DEVICES]; // Keeps last readout from each device
+int16_t spiextrareadout[MAX_SPI_DEVICES]; // Keeps last readout from each device
+int numspidevices = 0;
+
+static int32_t SPI_TC_Work( void ) {
+ int32_t retval;
+
+ for( int i = 0; i < numspidevices; i++ ) {
+ SPIxfer_t xfer;
+ xfer.ssmask = 1<= 0 ) { // Only continue of we find the I2C to SPI bridge chip
+ printf("\nProbing for MAX31855 devices...");
+
+ numspidevices = MAX_SPI_DEVICES; // Assume all devices are present for SPI_TC_Work
+ SPI_TC_Work(); // Run one iteration to update all data
+ numspidevices = 0; // And reset it afterwards
+
+ for( int i = 0; i < MAX_SPI_DEVICES; i++ ) {
+ if( (spidevreadout[i] == -1 && spiextrareadout[i] == -1) ||
+ (spidevreadout[i] == 0 && spiextrareadout[i] == 0) ) {
+ //printf(" Unknown/Invalid/Absent device");
+ } else {
+ printf("\nSS%x: [SPI Thermocouple interface]", i);
+ numspidevices = i + 1; // A bit of a hack as it assumes all earlier devices are present
+ }
+ }
+
+ if( numspidevices ) {
+ Sched_SetState( SPI_TC_WORK, 2, 0 ); // Enable SPI TC task if there's at least one device
+ } else {
+ printf(" No devices found!");
+ }
+ }
+ return numspidevices;
+}
+
+int SPI_IsTCPresent(uint8_t tcid) {
+ if(tcid < numspidevices) {
+ if( !(spidevreadout[tcid] & 0x01) ) return 1; // A faulty/not connected TC will not be flagged as present
+ }
+ return 0;
+}
+
+float SPI_GetTCReading(uint8_t tcid) {
+ float retval = 0.0f; // Report 0C for missing sensors
+ if(tcid < numspidevices) {
+ if(spidevreadout[tcid] & 0x01) { // Fault detected
+ retval = 999.0f; // Invalid
+ } else {
+ retval=(float)(spidevreadout[tcid] & 0xfffc); // Mask reserved bit
+ retval/=16;
+ //printf(" (%x=%.1f C)",tcid,retval);
+ }
+ }
+ return retval;
+}
+
+float SPI_GetTCColdReading(uint8_t tcid) {
+ float retval = 0.0f; // Report 0C for missing sensors
+ if(tcid < numspidevices) {
+ if(spiextrareadout[tcid] & 0x07) { // Any fault detected
+ retval = 999.0f; // Invalid
+ } else {
+ retval=(float)(spiextrareadout[tcid] & 0xfff0); // Mask reserved/fault bits
+ retval/=256;
+ //printf(" (%x=%.1f C)",tcid,retval);
+ }
+ }
+ return retval;
+}
diff --git a/src/max31855.h b/src/max31855.h
new file mode 100644
index 0000000..5119b47
--- /dev/null
+++ b/src/max31855.h
@@ -0,0 +1,9 @@
+#ifndef MAX31855_H_
+#define MAX31855_H_
+
+uint32_t SPI_TC_Init( void );
+int SPI_IsTCPresent(uint8_t tcid);
+float SPI_GetTCReading(uint8_t tcid);
+float SPI_GetTCColdReading(uint8_t tcid);
+
+#endif /* MAX31855_H_ */
diff --git a/src/reflow.c b/src/reflow.c
index 95428e9..52ea3d4 100644
--- a/src/reflow.c
+++ b/src/reflow.c
@@ -31,6 +31,7 @@
#include "onewire.h"
#include "adc.h"
#include "nvstorage.h"
+#include "max31855.h"
float adcgainadj[2]; // Gain adjust, this may have to be calibrated per device if factory trimmer adjustments are off
float adcoffsetadj[2]; // Offset adjust, this will definitely have to be calibrated per device
@@ -119,7 +120,16 @@ static int32_t Reflow_Work( void ) {
tempvalid |= (1<1) {
+ temperature[i] = tctemp[i];
+ tempvalid |= (1<.
+ */
+
+#include
+#include
+#include
+#include
+#include "i2c.h"
+#include "sc18is602b.h"
+
+#define SCADDR (0x28<<1)
+
+int32_t SC18IS602B_Init( SPIclk_t clk, SPImode_t mode, SPIorder_t order ) {
+ uint8_t function[2];
+ int32_t retval;
+ printf("\n%s ",__FUNCTION__);
+ function[0] = 0xf0;
+ function[1] = clk | mode | order;
+ retval = I2C_Xfer(SCADDR, function, sizeof(function), 1); // Attempt to initialize I2C to SPI bridge
+ if( retval == 0 ) {
+ printf( "- Done");
+ } else {
+ printf( "- No chip found");
+ }
+ return retval;
+}
+
+int32_t SC18IS602B_SPI_Xfer( SPIxfer_t* item ) {
+ int32_t retval;
+ if( item->len > (sizeof(SPIxfer_t) - 2) ) {
+ printf("\n%s: Invalid length!",__FUNCTION__);
+ return -1;
+ }
+ retval = I2C_Xfer(SCADDR, (uint8_t*)item, item->len + 1, 1); // Initialize transfer, ssmask + data
+ if( retval == 0 ) {
+ // TODO: There should be a timeout here
+ do {
+ retval = I2C_Xfer(SCADDR + 1, (uint8_t*)item->data, item->len, 1); // Initialize read transfer, data only
+ } while( retval != 0 ); // Wait for chip to be done with transaction
+ }
+ return retval;
+}
diff --git a/src/sc18is602b.h b/src/sc18is602b.h
new file mode 100644
index 0000000..348872f
--- /dev/null
+++ b/src/sc18is602b.h
@@ -0,0 +1,32 @@
+#ifndef SC18IS602B_H_
+#define SC18IS602B_H_
+
+typedef enum eSPIclk {
+ SPICLK_1843KHZ=0,
+ SPICLK_461KHZ=1,
+ SPICLK_115KHZ=2,
+ SPICLK_58KHZ=3,
+} SPIclk_t;
+
+typedef enum eSPImode {
+ SPIMODE_0=(0<<2),
+ SPIMODE_1=(1<<2),
+ SPIMODE_2=(2<<2),
+ SPIMODE_3=(3<<2),
+} SPImode_t;
+
+typedef enum eSPIorder {
+ SPIORDER_MSBFIRST=(0<<5),
+ SPIORDER_LSBFIRST=(1<<5),
+} SPIorder_t;
+
+typedef struct __attribute__ ((__packed__)) {
+ uint8_t ssmask;
+ uint8_t data[16]; // Max 16 bytes at the moment
+ uint8_t len;
+} SPIxfer_t;
+
+int32_t SC18IS602B_Init( SPIclk_t clk, SPImode_t mode, SPIorder_t order );
+int32_t SC18IS602B_SPI_Xfer( SPIxfer_t* item );
+
+#endif /* SC18IS602B_H_ */
diff --git a/src/sched.h b/src/sched.h
index 19c93ef..d7fb987 100644
--- a/src/sched.h
+++ b/src/sched.h
@@ -23,6 +23,7 @@ typedef enum eTask {
MAIN_WORK,
ADC_WORK,
ONEWIRE_WORK,
+ SPI_TC_WORK,
UI_WORK,
REFLOW_WORK,
NV_WORK,