/* Copyright 2025 by COG9 Enterprises LLC
 * All rights reserved.
 * Title: mcp9808.ino
 * Author: Jed Marti KI7NNP
 * Description: Temperature sensor initialization and reading.
 * Created: Sun Oct  5 11:56:08 2025
 * Revision History:
 *   Sat Dec 20 11:38:28 2025 - JBM Update for new names.
 */

#include <Wire.h>


#include "mcp9808.h"

// We handle 4 devices.
extern uint8_t aTemp_i2c;
extern uint8_t bTemp_i2c;
extern uint8_t cTemp_i2c;
extern uint8_t auxTemp_i2c;

int16_t MAXTEMP;


static uint8_t initMCP9808(uint8_t i2caddr, char *name)
/*     Initialize up to 4 temperature sensors. If a sensor is not found, then its address is 0.
 * Parameters:
 *   i2caddr: Hardware set I2C address. See schematic.
 *   name: A name for initialization message on failure.
 * External References: constants
 *   Wire: I2C bus software.
 * Returned values: the I2C address on success and 0 for not there.
 * Errors detected: sensor doesn't answer.
 */
{
  uint8_t cbyte[3];
  char    msg[25];

  // Force default configuration.
  cbyte[0] = mcp9808_CONFIG,
    cbyte[1] = 0x00,
    cbyte[2] = 0x00;
  Wire.beginTransmission(i2caddr);
  Wire.write(cbyte, 3);

  // Error on startup? Message to screen and serial port.
  if (Wire.endTransmission() != 0)
  {
    sprintf(msg, "**temp %s fails", name);
    rollString(msg);
    return 0;
  }
  return i2caddr;
}



void initTempSensors(void)
{
  aTemp_i2c = initMCP9808(TEMPA, "A");
  bTemp_i2c = initMCP9808(TEMPB, "B");
  cTemp_i2c = initMCP9808(TEMPC, "C");
  auxTemp_i2c = initMCP9808(TEMPAUX, "Aux");
  MAXTEMP = DEFAULTMAXF;
}


  
int16_t getCelcius(uint8_t i2caddr)
{
  uint8_t b2[2];
  int16_t t;
  Wire.beginTransmission(i2caddr);
  Wire.write(mcp9808_TA);
  Wire.endTransmission();
  Wire.requestFrom((int) i2caddr, 2);
  t = 0;
  while (Wire.available()) b2[t++] = Wire.read();
  b2[0] &= 0x1F;
  if (b2[0] & 0x10)
    t = 256 - (((b2[0] & 0x0F) << 4) + (b2[1] >> 4));
  else t = (b2[0] << 4) + (b2[1] >> 4);
  return t;
}


int16_t getFahrenheit(uint8_t i2caddr)
{
  uint8_t b2[2];
  int16_t t;
  Wire.beginTransmission(i2caddr);
  Wire.write(mcp9808_TA);
  Wire.endTransmission();
  Wire.requestFrom((int) i2caddr, 2);
  t = 0;
  while (Wire.available()) b2[t++] = Wire.read();
  b2[0] &= 0x1F;
  if (b2[0] & 0x10)
    t = 256 - (((b2[0] & 0x0F) << 4) + (b2[1] >> 4));
  else t = (b2[0] << 4) + (b2[1] >> 4);
  return (t * 9) / 5 + 32;
}




uint8_t checkTempLimits(void)
/*     Check for over temperature lints. Returns the i2c address of the hot one or 0 if
 *   none exceed.
 * Parameters: none
 * External References:
 *  aTemp_i2c: 5v regulator temp. i2c @.
 *  bTemp_i2c: 12v regulator temp. i2c @.
 *  cTemp_i2c: 19v regulator temp. i2c @.
 *  auxTemp_i2c: Auxiliary temp. i2c @.
 * Returned value: i2c address of first that's too hot or 0 if none.
 * Errors detected: none.
 */
{
  int16_t f;
  if (aTemp_i2c) if (getFahrenheit(aTemp_i2c) > MAXTEMP) return aTemp_i2c;
  if (bTemp_i2c) if (getFahrenheit(bTemp_i2c) > MAXTEMP) return bTemp_i2c;
  if (cTemp_i2c) if (getFahrenheit(cTemp_i2c) > MAXTEMP) return cTemp_i2c;
  if (auxTemp_i2c) if (getFahrenheit(auxTemp_i2c) > MAXTEMP) return auxTemp_i2c;
  return 0;
}


void tempPageScreen(void)
/*     The temperature page screen shows the current instantaneous values of the sensors, not the
 *   mean. This is called by the screen selection pushbutton code that doesn't work all that well.
 *   It gets called periodically when this screen is selected.
 * Parameters: none
 * External references:
 *  aTemp_i2c: 5v regulator temp. i2c @.
 *  bTemp_i2c: 12v regulator temp. i2c @.
 *  cTemp_i2c: 19v regulator temp. i2c @.
 *  auxTemp_i2c: Auxiliary temp. i2c @.
 * Returned values: none
 * Errors detected: if a temperature is not sensed, then a message is displayeed.
 */
{
  int16_t f;
  
  display.clearDisplay();
  display.setCursor(0,0);
  display.setTextSize(2);
  display.print(F("   TEMPS"));

  // 5v.
  display.setCursor(0, 17);
  display.setTextSize(1);
  display.print(F(" A "));
  if (aTemp_i2c)
  {
    display.print(getFahrenheit(aTemp_i2c));
    display.print(F(" F"));
  }
  else display.print(F(" not sensed"));
  
  // 12v.
  display.setCursor(0, 27);
  display.print(F(" B "));
  if (bTemp_i2c)
  {
    display.print(getFahrenheit(bTemp_i2c));
    display.print(F(" F"));
  }
  else display.print(F(" not sensed"));
  
  // 18v.
  display.setCursor(0, 37);
  display.print(F(" C "));
  if (cTemp_i2c)
  {
    display.print(getFahrenheit(cTemp_i2c));
    display.print(F(" F"));
  }
  else display.print(F(" not sensed"));
  
  // AUX.
  display.setCursor(0, 47);
  display.print(F("AUX "));
  if (auxTemp_i2c)
  {
    display.print(getFahrenheit(auxTemp_i2c));
    display.print(F(" F"));
  }
  else display.print(F(" not sensed"));

  // Battery icon here.
  batteryIcon();
}



// EOF
