#include "pmsa003.h"


#include <Arduino.h>

/****************************************************************/
bool PMSA003::Initialize(){
   bool success(true);

   success &= ReadChipID();

   if(success) success = WriteSettings();
   
   m_initialized = success;
   return m_initialized;
}


/****************************************************************/
bool PMSA003::ReadChipID(){
   uint8_t id = 0;

   ReadRegister(REG_VERSION, &id, 1);
   Serial.print("PMSSA DEV: ");Serial.println(id);
   // switch(id){
   //    case ChipModel_PMSA003_REV0: 
   //       m_chip_model = ChipModel_PMSA003_REV0;
   //       break;
   //    default:
   //       m_chip_model = ChipModel_UNKNOWN;
   //       return false;
   // }

   return true;
}


/****************************************************************/
bool PMSA003::WriteSettings(){
   return true; //No settings
}


/****************************************************************/
bool PMSA003::begin(){
   bool success = Initialize();
   success &= m_initialized;
   return success;
}

/****************************************************************/
bool PMSA003::reset(){
   return true; //Cannot be reset
}

/****************************************************************/
bool PMSA003::ReadData(uint8_t data[SENSOR_DATA_LENGTH]){

   ReadRegister(REG_Char1,data,SENSOR_DATA_LENGTH);
   
   if (data[0] != 0x42 || data[1] != 0x4d) return false;

   uint16_t sum = 0;
   for (uint8_t i = 0; i < 30; i++) sum += data[i];
   uint16_t checksum = data[30]<<8 | data[31];
   if (sum != checksum) return false;

   return true;
}


/****************************************************************/

void PMSA003::read(PM25_AQI_Data& data){
   if(!m_initialized) return;
   uint8_t rd[SENSOR_DATA_LENGTH];
   if(!ReadData(rd)) return;
   uint16_t md[16] = {0};
   for (uint8_t i = 0; i < 15; i++) {
      md[i] =  rd[i * 2] << 8;
      md[i] |= rd[i * 2 + 1];
   }

   data.pm10_standard = md[2];
   data.pm25_standard = md[3];
   data.pm100_standard = md[4];
   data.pm10_env = md[5];
   data.pm25_env = md[6];
   data.pm100_env = md[7];
   data.particles_03um = md[8];
   data.particles_05um = md[9];
   data.particles_10um = md[10];
   data.particles_25um = md[11];
   data.particles_50um = md[12];
   data.particles_100um = md[13];
}

/****************************************************************/
PMSA003::ChipModel PMSA003::chipModel(){
   return m_chip_model;
}


/****************************************************************/
bool PMSA003::WriteRegister(uint16_t addr, uint8_t data){
  i2c->beginTransmission(PMSA003_ADDRESS);
  i2c->write(highByte(addr));
  i2c->write(lowByte(addr));
  i2c->write(data);
  i2c->endTransmission();

  return true;
}


/****************************************************************/
bool PMSA003::ReadRegister(uint8_t addr,uint8_t data[],uint8_t length){
  uint8_t ord(0);

  i2c->beginTransmission(PMSA003_ADDRESS);
  i2c->write(addr);
  i2c->endTransmission();

  i2c->requestFrom(static_cast<uint8_t>(PMSA003_ADDRESS), length);

  while(i2c->available()){
    data[ord++] = i2c->read();
  }

  return ord == length;
}
