fome-fw/firmware/hw_layer/max31855.cpp

168 lines
3.5 KiB
C++
Raw Normal View History

2014-09-17 09:03:04 -07:00
/**
2014-12-31 08:05:21 -08:00
* @file max31855.cpp
2014-09-17 09:03:04 -07:00
* @brief MAX31855 Thermocouple-to-Digital Converter driver
*
*
* http://datasheets.maximintegrated.com/en/ds/MAX31855.pdf
*
2014-09-17 17:02:53 -07:00
*
* Read-only communication over 5MHz SPI
*
2014-09-17 09:03:04 -07:00
* @date Sep 17, 2014
* @author Andrey Belomutskiy, (c) 2012-2014
*/
2014-12-31 16:03:30 -08:00
#include "main.h"
2014-09-17 09:03:04 -07:00
#include "max31855.h"
2014-09-17 10:02:56 -07:00
2014-12-31 08:05:21 -08:00
#include "hardware.h"
2015-01-10 08:04:53 -08:00
#include "mpu_util.h"
2014-12-31 15:03:34 -08:00
#if EFI_PROD_CODE
2014-12-31 08:05:21 -08:00
#include "settings.h"
#include "pin_repository.h"
#endif /* EFI_PROD_CODE */
2014-09-17 17:02:53 -07:00
#if EFI_MAX_31855
2014-09-20 18:02:53 -07:00
#define EGT_ERROR_VALUE -1000
2014-12-30 12:03:24 -08:00
static SPIDriver *driver;
2014-09-17 10:02:56 -07:00
static Logging logger;
2014-09-20 15:02:48 -07:00
static SPIConfig spiConfig[MAX31855_CS_COUNT];
2014-12-31 08:05:21 -08:00
EXTERN_ENGINE;
static void showEgtInfo(void) {
#if EFI_PROD_CODE
2014-09-20 12:03:00 -07:00
printSpiState(&logger, boardConfiguration);
2014-09-20 18:02:53 -07:00
scheduleMsg(&logger, "EGT spi: %d", boardConfiguration->max31855spiDevice);
2014-09-17 10:02:56 -07:00
for (int i = 0; i < MAX31855_CS_COUNT; i++) {
2014-11-10 07:03:20 -08:00
if (boardConfiguration->max31855_cs[i] != GPIO_UNASSIGNED) {
2014-09-17 17:02:53 -07:00
scheduleMsg(&logger, "%d ETG @ %s", i, hwPortname(boardConfiguration->max31855_cs[i]));
}
2014-09-17 10:02:56 -07:00
}
2014-12-31 08:05:21 -08:00
#endif
2014-09-17 10:02:56 -07:00
}
2014-09-17 09:03:04 -07:00
2014-09-20 15:02:48 -07:00
// bits D17 and D3 are always expected to be zero
#define MC_RESERVED_BITS 0x20008
#define MC_OPEN_BIT 1
#define MC_GND_BIT 2
#define MC_VCC_BIT 4
typedef enum {
MC_OK = 0, MC_INVALID = 1, MC_OPEN = 2, MC_SHORT_GND = 3, MC_SHORT_VCC = 4,
} max_32855_code;
static const char * getMcCode(max_32855_code code) {
switch (code) {
case MC_OK:
return "Ok";
case MC_OPEN:
return "Open";
case MC_SHORT_GND:
return "short gnd";
case MC_SHORT_VCC:
return "short VCC";
default:
return "invalid";
}
}
2014-09-20 18:02:53 -07:00
static max_32855_code getResultCode(uint32_t egtPacket) {
if ((egtPacket & MC_RESERVED_BITS) != 0) {
return MC_INVALID;
} else if ((egtPacket & MC_OPEN_BIT) != 0) {
return MC_OPEN;
} else if ((egtPacket & MC_GND_BIT) != 0) {
return MC_SHORT_GND;
} else if ((egtPacket & MC_VCC_BIT) != 0) {
return MC_SHORT_VCC;
} else {
return MC_OK;
}
}
2014-09-20 15:02:48 -07:00
2014-12-30 12:03:24 -08:00
static uint32_t readEgtPacket(int egtChannel) {
2014-09-20 18:02:53 -07:00
uint32_t egtPacket;
if (driver == NULL) {
return 0xFFFFFFFF;
}
2014-09-20 15:02:48 -07:00
2014-09-20 18:02:53 -07:00
spiStart(driver, &spiConfig[egtChannel]);
2014-09-20 15:02:48 -07:00
spiSelect(driver);
2014-12-30 12:03:24 -08:00
spiReceive(driver, sizeof(egtPacket), &egtPacket);
2014-09-20 15:02:48 -07:00
spiUnselect(driver);
spiStop(driver);
2014-09-20 18:02:53 -07:00
egtPacket = SWAP_UINT32(egtPacket);
return egtPacket;
}
2014-09-20 15:02:48 -07:00
2014-09-20 18:02:53 -07:00
#define GET_TEMPERATURE_C(x) (((x) >> 18) / 4)
2014-09-20 15:02:48 -07:00
2014-12-30 12:03:24 -08:00
uint16_t getEgtValue(int egtChannel) {
uint32_t packet = readEgtPacket(egtChannel);
2014-09-20 18:02:53 -07:00
max_32855_code code = getResultCode(packet);
if (code != MC_OK) {
return EGT_ERROR_VALUE + code;
2014-09-20 15:02:48 -07:00
} else {
2014-09-20 18:02:53 -07:00
return GET_TEMPERATURE_C(packet);
2014-09-20 15:02:48 -07:00
}
2014-09-20 18:02:53 -07:00
}
2014-12-30 12:03:24 -08:00
static void egtRead(void) {
2014-09-20 15:02:48 -07:00
2014-12-30 12:03:24 -08:00
if (driver == NULL) {
2014-09-20 18:02:53 -07:00
scheduleMsg(&logger, "No SPI selected for EGT");
return;
}
scheduleMsg(&logger, "Reading egt");
2014-12-30 12:03:24 -08:00
uint32_t egtPacket = readEgtPacket(0);
2014-09-20 18:02:53 -07:00
max_32855_code code = getResultCode(egtPacket);
scheduleMsg(&logger, "egt %x code=%d %s", egtPacket, code, getMcCode(code));
2014-09-20 15:02:48 -07:00
if (code != MC_INVALID) {
2014-09-20 18:02:53 -07:00
int refBits = ((egtPacket & 0xFFFF) / 16); // bits 15:4
2014-09-20 15:02:48 -07:00
float refTemp = refBits / 16.0;
scheduleMsg(&logger, "reference temperature %f", refTemp);
2014-09-20 18:02:53 -07:00
scheduleMsg(&logger, "EGT temperature %d", GET_TEMPERATURE_C(egtPacket));
}
2014-09-20 15:02:48 -07:00
}
2014-12-31 08:05:21 -08:00
void initMax31855(SPIDriver *drv, egt_cs_array_t max31855_cs) {
2014-09-17 10:02:56 -07:00
initLogging(&logger, "EGT");
2014-12-31 08:05:21 -08:00
driver = drv;
2014-12-30 12:03:24 -08:00
2014-12-31 08:05:21 -08:00
addConsoleAction("egtinfo", (Void) showEgtInfo);
2014-09-17 10:02:56 -07:00
2014-12-30 12:03:24 -08:00
addConsoleAction("egtread", (Void) egtRead);
2014-09-20 15:02:48 -07:00
2014-12-31 15:03:34 -08:00
#if EFI_PROD_CODE
2014-09-20 15:02:48 -07:00
turnOnSpi(SPI_DEVICE_3);
2014-12-31 15:03:34 -08:00
#endif /* EFI_PROD_CODE */
2014-09-20 15:02:48 -07:00
2014-09-17 10:02:56 -07:00
for (int i = 0; i < MAX31855_CS_COUNT; i++) {
2014-12-31 08:05:21 -08:00
if (max31855_cs[i] != GPIO_UNASSIGNED) {
2014-09-17 10:02:56 -07:00
2014-12-31 08:05:21 -08:00
initSpiCs(&spiConfig[i], max31855_cs[i]);
2014-09-17 10:02:56 -07:00
2014-09-20 15:02:48 -07:00
spiConfig[i].cr1 = SPI_BaudRatePrescaler_8;
}
2014-09-17 10:02:56 -07:00
}
2014-09-17 09:03:04 -07:00
}
2014-09-17 17:02:53 -07:00
#endif /* EFI_MAX_31855 */