Skip to content

Commit

Permalink
Merge pull request #30 from UnifiedEngineering/max31855-integration
Browse files Browse the repository at this point in the history
Add support for the sc18is602b + max31855 combo
  • Loading branch information
xnk committed Dec 21, 2014
2 parents 9f20364 + a1822c5 commit d063bc6
Show file tree
Hide file tree
Showing 7 changed files with 231 additions and 1 deletion.
2 changes: 2 additions & 0 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include "buzzer.h"
#include "nvstorage.h"
#include "version.h"
#include "max31855.h"

extern uint8_t logobmp[];
extern uint8_t stopbmp[];
Expand Down Expand Up @@ -192,6 +193,7 @@ int main(void) {
ADC_Init();
RTC_Init();
OneWire_Init();
SPI_TC_Init();
Reflow_Init();

Sched_SetWorkfunc( MAIN_WORK, Main_Work );
Expand Down
118 changes: 118 additions & 0 deletions src/max31855.c
Original file line number Diff line number Diff line change
@@ -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 <http://www.gnu.org/licenses/>.
*/

#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#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<<i;
xfer.len = 4; // 32 bits from TC interface
retval = SC18IS602B_SPI_Xfer( &xfer ); // Doesn't matter what data contains when sending, MOSI not connected
if( retval == 0 ) {
int16_t tmp = xfer.data[0]<<8 | xfer.data[1];
spidevreadout[i] = tmp;
tmp = xfer.data[2]<<8 | xfer.data[3];
spiextrareadout[i] = tmp;
}
}
return TICKS_MS(100);
}

uint32_t SPI_TC_Init( void ) {
printf("\n%s called",__FUNCTION__);
Sched_SetWorkfunc( SPI_TC_WORK, SPI_TC_Work );

for( int i = 0; i < MAX_SPI_DEVICES; i++ ) {
spidevreadout[i] = -1; // Assume we don't find any thermocouple interfaces
spiextrareadout[i] = -1;
}

if( SC18IS602B_Init( SPICLK_1843KHZ, SPIMODE_0, SPIORDER_MSBFIRST ) >= 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;
}
9 changes: 9 additions & 0 deletions src/max31855.h
Original file line number Diff line number Diff line change
@@ -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_ */
12 changes: 11 additions & 1 deletion src/reflow.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -119,7 +120,16 @@ static int32_t Reflow_Work( void ) {
tempvalid |= (1<<i);
}
} else {
//printf("TC%x=---C ",i);
tcpresent[i] = SPI_IsTCPresent( i );
if( tcpresent[i] ) {
tctemp[i] = SPI_GetTCReading( i );
tccj[i] = SPI_GetTCColdReading( i );
printf("TC%x=%5.1fC ",i,tctemp[i]);
if(i>1) {
temperature[i] = tctemp[i];
tempvalid |= (1<<i);
}
}
}
}
cjsensorpresent = 0; // Assume no CJ sensor
Expand Down
58 changes: 58 additions & 0 deletions src/sc18is602b.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* sc18is602b.c - I2C to SPI bridge 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 <http://www.gnu.org/licenses/>.
*/

#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#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;
}
32 changes: 32 additions & 0 deletions src/sc18is602b.h
Original file line number Diff line number Diff line change
@@ -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_ */
1 change: 1 addition & 0 deletions src/sched.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ typedef enum eTask {
MAIN_WORK,
ADC_WORK,
ONEWIRE_WORK,
SPI_TC_WORK,
UI_WORK,
REFLOW_WORK,
NV_WORK,
Expand Down

0 comments on commit d063bc6

Please sign in to comment.