Files @ a710d1e0fc2a
Branch filter:

Location: therm-ng/src/main.c

Ethan Zonca
Import from old therm: menus working
//
// Therm Firmware
// Copyright 2017 Ethan Zonca
// Author(s): Ethan Zonca
//

#include "stm32f3xx_hal.h"
#include "config.h"

#include "watchdog.h"
#include "system.h"
#include "display.h"
#include "gpio.h"
#include "pid.h"
#include "error.h"
#include "flash.h"
#include "ssd1306.h"
#include "dma.h"
#include "interrupts.h"
#include "buttons.h"


therm_settings_t set;
therm_status_t status;
pid_state_t pid_state;


int main(void)
{
	sysclock_init();
	hal_init();
	gpio_init();


	ssd1306_init();

	// Startup screen
    display_startup_screen();
    HAL_Delay(2000);

	ssd1306_drawlogo();

	watchdog_init();

	//just some example code for getting flash values
//	flash_getsettings()->values.can_id = 67;
//
//	if(flash_getsettings()->values.can_id == 12);

//	ssd1306_drawstring(const char *dataPtr, unsigned char row, unsigned char xPos)
//	ssd1306_drawstring("[ ProtoFuse ]", 0, 0);

    // Default status
    status.temp = 0;
    status.temp_frac = 0;
    status.state_resume = 0;
    status.state = STATE_IDLE;
    status.setpoint = 70;
    status.pid_enabled = 0;

    pid_init(&pid_state);

    flash_init();


	float temp_counter = 0;

	// Software timers
	uint32_t last_screen_update_time = HAL_GetTick();


    // Soft timers
    uint32_t last_ssr_on = 0;
    uint32_t last_vcp_tx = 0;
    uint32_t last_led = 0;
    uint32_t last_pid = 0;
    uint32_t last_thermostat = 0;
    int16_t ssr_output = 0; // Duty cycle of ssr, 0 to SSR_PERIOD
    uint8_t thermostat_plant_on = 0;


	while (1)
	{

        if(set.val.control_mode == MODE_PID && (HAL_GetTick() - last_pid > PID_PERIOD))
        {

//            #ifdef MAX31865_RTD_SENSOR
//            max31865_readtemp(spi_get(), &set, &status);
//			#else
//			max31855_readtemp(spi_get(), &set, &status); // Read MAX31855
//			#endif


            if(status.pid_enabled)
            {
                // Get ssr output for next time
                int16_t power_percent = pid_update(&set, &status, &pid_state);

                if(set.val.plant_type == PLANT_HEATER)
                    power_percent *= -1;

                //power-percent is 0-1000?
                ssr_output = power_percent; //(((uint32_t)SSR_PERIOD * (uint32_t)10 * (uint32_t)100) * power_percent) / (uint32_t)1000000;


            	// put ssr output on display
                ssd1306_drawstring("      ", 0, 90); //fixme: this is bad, but I can't get the old digits to clear otherwise
                char tempstr[6];
                itoa(ssr_output, tempstr, 10);
                ssd1306_drawstring(tempstr, 0, 90);
            }
            else
            {
                ssr_output = 0;
            }

            last_pid = HAL_GetTick();
        }

//        // Kill SSR once the desired on-time has elapsed
//        if(set.val.control_mode == MODE_PID && (HAL_GetTick() - last_ssr_on > ssr_output || ssr_output <= 0))
//        {
//            HAL_GPIO_WritePin(SSR_PIN, 0);
//            HAL_GPIO_WritePin(LED_POWER, 0);
//        }
//
//
//        // Every 200ms, set the SSR on unless output is 0
//        if(set.val.control_mode == MODE_PID && HAL_GetTick() - last_ssr_on > SSR_PERIOD)
//        {
//            // Heat or cool, if we need to
//            if(ssr_output > 0)
//            {
//                HAL_GPIO_WritePin(SSR_PIN, 1);
//                HAL_GPIO_WritePin(LED_POWER, 1);
//                last_ssr_on = HAL_GetTick();
//            }
//            else {
//                // Make sure everything is off
//                HAL_GPIO_WritePin(SSR_PIN, 0);
//                HAL_GPIO_WritePin(LED_POWER, 0);
//            }
//
//        }


        // Thermostatic control
        if(set.val.control_mode == MODE_THERMOSTAT && HAL_GetTick() - last_thermostat > SSR_PERIOD)
        {

//            #ifdef MAX31865_RTD_SENSOR
//            max31865_readtemp(spi_get(), &set, &status);
//			#else
//			max31855_readtemp(spi_get(), &set, &status); // Read MAX31855
//			#endif

            // TODO: Migrate this FxP conversion to the readtemp code or similar
            int8_t temp_frac = status.temp_frac > 9 ? status.temp_frac / 10 : status.temp_frac;
            temp_frac = status.temp > 0 ? temp_frac : temp_frac * -1;
            int32_t temp = (status.temp * 10) + temp_frac;


            // EMZ FIXME: This could be way simpler
            if(set.val.plant_type == PLANT_HEATER && status.setpoint * 10 < temp - set.val.hysteresis * 10)
                thermostat_plant_on = 1;
            else if(set.val.plant_type == PLANT_HEATER && status.setpoint * 10 > temp + set.val.hysteresis * 10)
                thermostat_plant_on = 0;

            if(set.val.plant_type == PLANT_COOLER && status.setpoint * 10 > temp + set.val.hysteresis * 10)
                thermostat_plant_on = 1;
            else if(set.val.plant_type == PLANT_COOLER && status.setpoint * 10 < temp - set.val.hysteresis * 10)
                thermostat_plant_on = 0;

            // EMZ: TODO: Refactor to output_enabled or something
            if(status.pid_enabled && thermostat_plant_on)
            {
                // EMZ TODO: functionalize this
            	// put ssr output on display
                ssd1306_drawstring("      ", 0, 90); //fixme: this is bad, but I can't get the old digits to clear otherwise
                char tempstr[6];
                itoa(ssr_output, tempstr, 10);
                ssd1306_drawstring(tempstr, 0, 90);



                HAL_GPIO_WritePin(SSR_PIN, 1);
                HAL_GPIO_WritePin(LED_POWER, 1);
            }
            else
            {
                HAL_GPIO_WritePin(SSR_PIN, 0);
                HAL_GPIO_WritePin(LED_POWER, 0);
            }

            last_thermostat = HAL_GetTick();
        }


//        // Transmit temperature over USB-CDC on a regular basis
//        if(HAL_GetTick() - last_vcp_tx > VCP_TX_FREQ)
//        {
//            // Print temp to cdc
//            char tempstr[16];
//            itoa_fp(status.temp, status.temp_frac, tempstr);
//            uint8_t numlen = strlen(tempstr);
//            tempstr[numlen] = '\r';
//            tempstr[numlen+1] = '\n';
//
//    //        if(set.val.usb_plugged)
//    //            CDC_Transmit_FS(tempstr, numlen+2);
//           // while(CDC_Transmit_FS("\r\n", 2) == USBD_BUSY);
//
//            last_vcp_tx = HAL_GetTick();
//        }

        // Run state machine
        display_process(&set, &status);

		watchdog_feed();
	}
}