diff --git a/source/shoh/.cproject b/source/shoh/.cproject index 1f9b41f..7436f16 100644 --- a/source/shoh/.cproject +++ b/source/shoh/.cproject @@ -55,6 +55,7 @@ + @@ -208,6 +211,7 @@ + @@ -238,6 +242,7 @@ + diff --git a/source/shoh/src/peripherals/Clock.cpp b/source/shoh/src/peripherals/Clock.cpp index 6366182..298d495 100644 --- a/source/shoh/src/peripherals/Clock.cpp +++ b/source/shoh/src/peripherals/Clock.cpp @@ -7,6 +7,7 @@ #include "Clock.h" #include "FreeRTOS.h" #include "task.h" +#include "Log.h" static const uint64_t max_counter_value = 0xffffffff; @@ -71,14 +72,16 @@ Clock::~Clock() {} * large, if it will be enough to get overflow amount of overflows * 2 times between the function calls the clock will desync. * *Barely possible with counter overflows every 89 sec, but still. + * *Is fully guarded by mutex, since it is expected to + * send log messages one after another, but it can happen simultaneously. */ void Clock::updateClock() { + this->_guard.lock(); uint64_t diff_overflows = 0; //Remember old number of overflows. uint64_t old_overflows = this->_overflows; - this->_guard.lock(); //Stop the counter. Chip_SCT_SetControl(LPC_SCT1, 0x1 << 1); //Capture number of counter overflows. @@ -86,8 +89,7 @@ void Clock::updateClock() //Capture the counter value. uint64_t cur_count_u = LPC_SCT1->COUNT_U; //Resume the counter. - Chip_SCT_ClearControl(LPC_SCT1, 0x1 << 1); - this->_guard.unlock(); + Chip_SCT_ClearControl(LPC_SCT1, 0x1 << 1); //Handle overflows. diff_overflows = (old_overflows <= this->_overflows) @@ -110,7 +112,7 @@ void Clock::updateClock() //Add full counter values for all overflows except one. (max_counter_value * (diff_overflows - 1) //Add the difference between counter values having overflow in mind. - + (cur_count_u + (max_counter_value - _last_counter_value))) + + (cur_count_u + (max_counter_value - this->_last_counter_value))) //Convert to milliseconds. * 1000) / (double)(Chip_Clock_GetMainClockRate()); @@ -119,6 +121,7 @@ void Clock::updateClock() //Remember last counter value. //It is important if we won't have an overflow next time. this->_last_counter_value = cur_count_u; + this->_guard.unlock(); } TimeFromStart Clock::getTimeFromStart() diff --git a/source/shoh/src/peripherals/I2C.cpp b/source/shoh/src/peripherals/I2C.cpp index 2104c06..5f9c753 100644 --- a/source/shoh/src/peripherals/I2C.cpp +++ b/source/shoh/src/peripherals/I2C.cpp @@ -103,7 +103,7 @@ I2C::transaction (uint8_t devAddr, uint8_t *txBuffPtr, uint16_t txSize, I2CM_XFER_T i2cmXferRec; // make sure that master is idle - while (Chip_I2CM_StateChanged(this->device) == 0); + //while (Chip_I2CM_StateChanged(this->device) == 0); /* Setup I2C transfer record */ i2cmXferRec.slaveAddr = devAddr; diff --git a/source/shoh/src/peripherals/I2C.h b/source/shoh/src/peripherals/I2C.h index 34a856b..6bf5016 100644 --- a/source/shoh/src/peripherals/I2C.h +++ b/source/shoh/src/peripherals/I2C.h @@ -14,9 +14,8 @@ struct I2C_config { unsigned int device_number; unsigned int speed; - unsigned int clock_divider; - unsigned int i2c_mode; - I2C_config(unsigned int dn, unsigned int sp, unsigned int cd): device_number(dn), speed(sp), clock_divider(cd), i2c_mode(IOCON_SFI2C_EN) {}; + unsigned int i2c_mode = IOCON_SFI2C_EN; +// I2C_config(unsigned int dn, unsigned int sp, unsigned int cd): device_number(dn), speed(sp), i2c_mode(IOCON_SFI2C_EN) {}; }; class I2C { diff --git a/source/shoh/src/threads/manager/Menu.cpp b/source/shoh/src/threads/manager/Menu.cpp index f2086f4..6a3afb7 100644 --- a/source/shoh/src/threads/manager/Menu.cpp +++ b/source/shoh/src/threads/manager/Menu.cpp @@ -32,9 +32,11 @@ Menu::readSetPointFromEEPROM (void) { EventRawData *data = (EventRawData *)eeprom.read_from (EEPROM_START_ADDR, sizeof(EventRawData)); - if ((*data) > 0 && (*data) < 120) + if ((*data) > 0 && (*data) < 100) { set_point.setCurrent(*data); + Event e(Event::EventType::SetPoint, set_point.getCurrent()); + _qm->send(ThreadCommon::QueueManager::master_event_all, &e , 1); } } diff --git a/source/shoh/src/threads/master/Master.cpp b/source/shoh/src/threads/master/Master.cpp index a431323..ea1d38f 100644 --- a/source/shoh/src/threads/master/Master.cpp +++ b/source/shoh/src/threads/master/Master.cpp @@ -13,6 +13,7 @@ #include "Manager.h" #include "Logging.h" #include "UserInterface.h" +#include "Temperature.h" #include "queue.h" static const char* rotary_direction[] = @@ -39,30 +40,31 @@ Master::~Master() void Master::HandleEventType(Event* e) { EventRawData rd = e->getData(); - switch (e->getType()) + bool send = false; + switch (e->getType()) { case Event::Null: LOG_ERROR("Master recieved Event::Null with data: %d", rd); break; case Event::Rotary: //Comes from rotary, goes to manager - _qm->send(ThreadCommon::QueueManager::manager_event_master, e, 0); + send = _qm->send(ThreadCommon::QueueManager::manager_event_master, e, 0); //LOG_WARNING("Timestamp: %zus, Clock: %zu, Chip freq: %zu", LPC_SCT1->COUNT_U / Chip_Clock_GetMainClockRate(), LPC_SCT1->COUNT_U, Chip_Clock_GetMainClockRate()); - LOG_DEBUG("Rotary: %s has been forwarded to manager", rotary_direction[rd]); + if (send) LOG_DEBUG("Rotary: %s has been forwarded to manager", rotary_direction[rd]); break; case Event::InternalTemp: // TODO remove (deprecated) break; case Event::ExternalTemp: //Comes from sensors, goes to relay & manager - _qm->send(ThreadCommon::QueueManager::relay_event_master, e, 0); - _qm->send(ThreadCommon::QueueManager::manager_event_master, e, 0); - LOG_DEBUG("ExtTemp: %d has been forwarded to manager and relay", rd); + send = _qm->send(ThreadCommon::QueueManager::relay_event_master, e, 0); + send = _qm->send(ThreadCommon::QueueManager::manager_event_master, e, 0); + if (send) LOG_DEBUG("ExtTemp: %d has been forwarded to manager and relay", rd); break; case Event::SetPoint: //Comes from manager, goes to relay - _qm->send(ThreadCommon::QueueManager::relay_event_master, e, 0); - LOG_DEBUG("SetPoint: %d has been forwarded to relay", rd); + send = _qm->send(ThreadCommon::QueueManager::relay_event_master, e, 0); + if (send) LOG_DEBUG("SetPoint: %d has been forwarded to relay", rd); break; default: LOG_ERROR("Unknown EventType"); @@ -120,16 +122,19 @@ void thread_master(void* pvParams) { LOG_INFO("Master is creating tasks"); manager->tm->createTask(thread_manager, "manager", - configMINIMAL_STACK_SIZE * 15,tskIDLE_PRIORITY + 1UL, + configMINIMAL_STACK_SIZE * 13,tskIDLE_PRIORITY + 1UL, static_cast(manager)); manager->tm->createTask(thread_rotary, "rotary", - configMINIMAL_STACK_SIZE * 9,tskIDLE_PRIORITY + 1UL, + configMINIMAL_STACK_SIZE * 8,tskIDLE_PRIORITY + 1UL, static_cast(manager)); manager->tm->createTask(thread_user_interface, "user_interface", - configMINIMAL_STACK_SIZE * 9,tskIDLE_PRIORITY + 1UL, + configMINIMAL_STACK_SIZE * 8,tskIDLE_PRIORITY + 1UL, static_cast(manager)); manager->tm->createTask(thread_relay, "relay", - configMINIMAL_STACK_SIZE * 9,tskIDLE_PRIORITY + 1UL, + configMINIMAL_STACK_SIZE * 8,tskIDLE_PRIORITY + 1UL, + static_cast(manager)); + manager->tm->createTask(thread_temperature, "temperature", + configMINIMAL_STACK_SIZE * 8,tskIDLE_PRIORITY + 1UL, static_cast(manager)); LOG_INFO("Master created tasks"); m.taskFunction(); diff --git a/source/shoh/src/threads/relay/Relay.cpp b/source/shoh/src/threads/relay/Relay.cpp index 12a4640..d548802 100644 --- a/source/shoh/src/threads/relay/Relay.cpp +++ b/source/shoh/src/threads/relay/Relay.cpp @@ -38,7 +38,8 @@ void inline RelayDevice::RelayOff() } -Relay::Relay(ThreadCommon::QueueManager* qm): _qm(qm) +Relay::Relay(ThreadCommon::QueueManager* qm): + _qm(qm), ext_temp(0x7f), setpoint(0) { LOG_DEBUG("Creating Relay"); } @@ -56,6 +57,7 @@ void Relay::setPowerMode(PowerMode pm) relays[INF_RELAY].RelayOff(); relays[SUP_RELAY].RelayOff(); LOG_INFO("Heater is turned OFF"); + break; case PowerMode::POWER_1: relays[INF_RELAY].RelayOn(); relays[SUP_RELAY].RelayOff(); @@ -94,9 +96,11 @@ void Relay::parseEvent(Event* e) { case Event::ExternalTemp: ext_temp = rd; + LOG_DEBUG("Relay got ext_temp: %d", rd); break; case Event::SetPoint: setpoint = rd; + LOG_DEBUG("Relay got setpoint: %d", rd); break; default: assert(0); diff --git a/source/shoh/src/threads/temperature/SensorTempTC74.cpp b/source/shoh/src/threads/temperature/SensorTempTC74.cpp new file mode 100644 index 0000000..b8d47dd --- /dev/null +++ b/source/shoh/src/threads/temperature/SensorTempTC74.cpp @@ -0,0 +1,105 @@ +/* + * SensorTempTC74.cpp + * + * Created on: 16 May 2023 + */ + +#include "SensorTempTC74.h" +#include "FreeRTOS.h" +#include "task.h" +#include "Log.h" + +SensorTempTC74::SensorTempTC74(I2C* pi2c, const uint8_t dev_addr) +: _pi2c(pi2c), _dev_addr(dev_addr), _temp_reg(0x00), _ctrl_reg(0x01), + _ready_bit(0x40), _standby_bit(0x80), _up_flag(false) +{} + +SensorTempTC74::~SensorTempTC74() +{} + +int8_t SensorTempTC74::getTemperature() +{ + return static_cast(this->read()) - 6; +} + +bool SensorTempTC74::is_up() +{ + this->on_standby(); + if (!this->_up_flag) + LOG_WARNING("Unable to reach temperature sensor [%d]", this->_dev_addr); + return this->_up_flag; +} + +bool SensorTempTC74::on_standby() +{ + uint8_t data = 0x00; + this->_up_flag = this->read_reg(this->_ctrl_reg, &data, 1); + return data & this->_standby_bit; +} + +bool SensorTempTC74::is_ready() +{ + uint8_t data = 0x00; + this->_up_flag = this->read_reg(this->_ctrl_reg, &data, 1); + return data & this->_ready_bit; +} + +uint8_t SensorTempTC74::read() +{ + uint8_t data = 0x80; // b(1000 0000) + //if on standby - remove standby and wait for 1 ms. + if (this->on_standby()) + { + this->remove_standby(); + vTaskDelay(3000); + } + + //if ready and up - read + if (this->is_ready() && this->_up_flag) + { + this->_up_flag = this->read_reg(this->_temp_reg, &data, 1); + if(!this->_up_flag) + LOG_WARNING("I2C transaction for getting the temperature failed."); + LOG_DEBUG("Temperature sensor returned: %x", data); + } + else + LOG_WARNING("Unable to read temperature sensor [%d] value.", this->_dev_addr); + + //set standy. + //this->set_standby(); + + return data; +} + +void SensorTempTC74::remove_standby() +{ + uint8_t data = 0x00; + this->_up_flag = this->write_reg(this->_ctrl_reg, &data, 1); + if(!this->_up_flag) + LOG_WARNING("Unable to remove standby for temperature sensor [%d].", this->_dev_addr); +} + +void SensorTempTC74::set_standby() +{ + uint8_t data = this->_standby_bit; + this->_up_flag = this->write_reg(this->_ctrl_reg, &data, 1); + if(!this->_up_flag) + LOG_WARNING("Unable to set standby for temperature sensor [%d].", this->_dev_addr); +} + +bool SensorTempTC74::write_reg(uint8_t com, uint8_t *trdata, const uint16_t size) +{ + vTaskDelay(1); //Not sure if it is needed. + uint8_t arr[size + 1]; + arr[0] = com; + for (unsigned int i = 1; i < (unsigned int)size + 1; i++) { + arr[i] = trdata[i - 1]; + } + return this->_pi2c->write(this->_dev_addr, arr, size + 1); +} + +bool SensorTempTC74::read_reg(uint8_t com, uint8_t *rdata, uint16_t size) +{ + vTaskDelay(1); //Not sure if it is needed. + return this->_pi2c->transaction(this->_dev_addr, &com, 1, rdata, size); +} diff --git a/source/shoh/src/threads/temperature/SensorTempTC74.h b/source/shoh/src/threads/temperature/SensorTempTC74.h new file mode 100644 index 0000000..c30478b --- /dev/null +++ b/source/shoh/src/threads/temperature/SensorTempTC74.h @@ -0,0 +1,39 @@ +/* + * SensorTempTC74.h + * + * Created on: 16 May 2023 + */ + +#ifndef THREADS_TEMPERATURE_SENSORTEMPTC74_H_ +#define THREADS_TEMPERATURE_SENSORTEMPTC74_H_ + +#include "I2C.h" +#include "chip.h" + +class SensorTempTC74 { +public: + SensorTempTC74(I2C* pi2c, const uint8_t dev_addr); + virtual ~SensorTempTC74(); + int8_t getTemperature(); + bool is_up(); +private: + uint8_t read(); + bool on_standby(); + bool is_ready(); + + void remove_standby(); + void set_standby(); + + bool write_reg(uint8_t com, uint8_t *trdata, const uint16_t size); + bool read_reg(uint8_t com, uint8_t *rdata, uint16_t size); + + I2C* _pi2c; + const uint8_t _dev_addr; + const uint8_t _temp_reg; + const uint8_t _ctrl_reg; + const uint8_t _ready_bit; + uint8_t _standby_bit; + bool _up_flag; +}; + +#endif /* THREADS_TEMPERATURE_SENSORTEMPTC74_H_ */ diff --git a/source/shoh/src/threads/temperature/Temperature.cpp b/source/shoh/src/threads/temperature/Temperature.cpp new file mode 100644 index 0000000..9c3692d --- /dev/null +++ b/source/shoh/src/threads/temperature/Temperature.cpp @@ -0,0 +1,46 @@ +/* + * Temperature.cpp + * + * Created on: 16 May 2023 + */ + +#include "Temperature.h" +#include "SensorTempTC74.h" +#include "Event.h" +#include "Log.h" + +Temperature::Temperature(ThreadCommon::QueueManager* qm, I2C* pi2c) : _qm(qm), _pi2c(pi2c) {} + +Temperature::~Temperature() {} + +void Temperature::taskFunction() +{ + SensorTempTC74 ext_temp_sensor(this->_pi2c, 0x4a); + Event t (Event::ExternalTemp, -10); + int8_t temp_value = -10; + for (;;) + { + if (ext_temp_sensor.is_up()) + temp_value = ext_temp_sensor.getTemperature(); + + if(temp_value == -10) + { + LOG_ERROR("Failed to get temperature."); + continue; + } + + LOG_DEBUG("External temperature is: %d", temp_value); + t.setEvent(Event::ExternalTemp, temp_value); + _qm->send(ThreadCommon::QueueManager::master_event_all, &t, 0); + vTaskDelay(5000); + } +} + +void thread_temperature(void* pvParams) +{ + ThreadCommon::CommonManagers * manager = static_cast(pvParams); + I2C_config conf{0x4a, 100000}; + I2C i2c(conf); + Temperature t(manager->qm, &i2c); + t.taskFunction(); +} diff --git a/source/shoh/src/threads/temperature/Temperature.h b/source/shoh/src/threads/temperature/Temperature.h new file mode 100644 index 0000000..1fdbe7a --- /dev/null +++ b/source/shoh/src/threads/temperature/Temperature.h @@ -0,0 +1,28 @@ +/* + * Temperature.h + * + * Created on: 16 May 2023 + */ + +#ifndef THREADS_TEMPERATURE_TEMPERATURE_H_ +#define THREADS_TEMPERATURE_TEMPERATURE_H_ + +#include "FreeRTOS.h" +#include "task.h" +#include "ThreadCommon.h" +#include "DigitalIoPin.h" +#include "I2C.h" + +class Temperature { +public: + Temperature(ThreadCommon::QueueManager* qm, I2C* pi2c); + virtual ~Temperature(); + void taskFunction(); +private: + ThreadCommon::QueueManager* _qm; + I2C* _pi2c; +}; + +void thread_temperature(void* pvParams); + +#endif /* THREADS_TEMPERATURE_TEMPERATURE_H_ */