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,