diff --git a/main.c b/main.c deleted file mode 100644 --- a/main.c +++ /dev/null @@ -1,900 +0,0 @@ -#include "main.h" -#include -#include "stm32f0xx_hal_conf.h" -//#include "usb_device.h" -#include "ssd1306.h" -#include "config.h" -#include "eeprom_min.h" -#include "gpio.h" -#include "clock.h" -//#include "spi.h" - -// TODO: Grab buttonpresses with interrupts - -// USB Supporting Vars -//extern __IO uint8_t Receive_Buffer[64]; -//extern __IO uint32_t Receive_length ; -//extern __IO uint32_t length ; -//uint8_t Send_Buffer[64]; -//uint32_t packet_sent=1; -//uint32_t packet_receive=1; - -enum tempunits { - TEMP_UNITS_CELSIUS = 0, - TEMP_UNITS_FAHRENHEIT, -}; - -// Globalish setting vars -uint8_t boottobrew = 0; -uint8_t temp_units = TEMP_UNITS_CELSIUS; -uint16_t windup_guard = 1; -uint16_t k_p = 1; -uint16_t k_i = 1; -uint16_t k_d = 1; - -uint8_t ignore_tc_error = 0; - -// ISR ticks var -volatile uint32_t ticks = 0; - -int16_t setpoint_brew = 0; -int16_t setpoint_steam = 0; - -// HAL Variables -//extern SPI_HandleTypeDef spi1; - - -// State definition -enum state { - STATE_IDLE = 0, - - STATE_SETP, - STATE_SETI, - STATE_SETD, - STATE_SETSTEPS, - STATE_SETWINDUP, - STATE_SETBOOTTOBREW, - STATE_SETUNITS, - - STATE_PREHEAT_BREW, - STATE_MAINTAIN_BREW, - STATE_PREHEAT_STEAM, - STATE_MAINTAIN_STEAM, - - STATE_TC_ERROR -}; - -uint8_t state = STATE_IDLE; - -static __IO uint32_t TimingDelay; - -// Move to header file -void process(); -void machine(); - -void restore_settings(); -void save_settings(); -void save_setpoints(); - -int main(void) -{ - // Init clocks - HAL_Init(); - SystemClock_Config(); - - // Init GPIO - init_gpio(); - - // Turn on power LED - HAL_GPIO_WritePin(LED_POWER, 1); - - // TODO: Awesome pwm of power LED (TIM4_CH4 or TIM11_CH1) - - // Configure 1ms SysTick (change if more temporal resolution needed) - //RCC_ClocksTypeDef RCC_Clocks; - //RCC_GetClocksFreq(&RCC_Clocks); - //SysTick_Config(RCC_Clocks.HCLK_Frequency / 1000); - - // Init SPI busses - //init_spi(&spi1); - - // Init USB - //MX_USB_DEVICE_Init(); - - // Init OLED over SPI - ssd1306_Init(); - ssd1306_clearscreen(); - - // Check for problems on startup - uint8_t clock_fail = 0; // FIXME implement in system - if(clock_fail) { - //ssd1306_DrawStringBig("ERROR: Check Xtal", 2, 0); - ssd1306_DrawStringBig("NO XTAL", 2, 0); - delay(1000); - ssd1306_clearscreen(); - } - - // Init USB - //Set_System(); // hw_config.h - //Set_USBClock(); - //SB_Interrupts_Config(); - //SB_Init(); - //SYSCFG_USBPuCmd(ENABLE); - //PowerOn(); - - // Startup screen - ssd1306_DrawString("therm v0.1", 1, 40); - ssd1306_DrawString("protofusion.org/therm", 3, 0); - - delay(1500); - ssd1306_clearscreen(); - - restore_settings(); - if(boottobrew) - state = STATE_PREHEAT_BREW; // Go to brew instead of idle if configured thusly - - HAL_GPIO_WritePin(LED_STAT, 0); - - // Main loop - while(1) - { - // Process sensor inputs - process(); - - // Run state machine - machine(); - } -} - -// Read temperature and update global temp vars -int32_t temp = 0; -uint8_t temp_frac = 0; -uint8_t state_resume = 0; - - -// FIXME: Now this needs to work 8bits at a time, or change the port mode on the fly -void update_temp() { - // Assert CS - HAL_GPIO_WritePin(MAX_CS, 0); - delay(1); - - // This may not clock at all... might need to send 16 bits first - // SPI_I2S_SendData(SPI2, 0xAAAA); // send dummy data - - uint8_t data[2] = {0xAA, 0xAA}; - //HAL_SPI_Transmit(&spi1, data, 2, 100); - - //OLD: SPI_I2S_SendData(SPI2, 0xAA); // send dummy data - // OLD: uint16_t temp_pre = SPI_I2S_ReceiveData(SPI2); - - //HAL_SPI_Receive(&spi1, data, 2, 100); - - // Assemble data array into one var - uint16_t temp_pre = data[0] & (data[1]<<8); - - if(temp_pre & 0b0000000000000010) { - ssd1306_DrawString("Fatal Error", 3, 35); - state = STATE_TC_ERROR; - } - else if(temp_pre & 0b0000000000000001 && !ignore_tc_error) { - state_resume = state; - state = STATE_TC_ERROR; - temp = 0; - temp_frac = 0; - } - else - { - if(state == STATE_TC_ERROR) - { - state = state_resume; - ssd1306_clearscreen(); - } - - uint8_t sign = temp >> 15;// top bit is sign - - temp_pre = temp_pre >> 2; // Drop 2 lowest bits - temp_frac = temp_pre & 0b11; // get fractional part - temp_frac *= 25; // each bit is .25 a degree, up to fixed point - temp_pre = temp_pre >> 2; // Drop 2 fractional bits - - if(sign) { - temp = -temp_pre; - } - else { - temp = temp_pre; - } - - if(temp_units == TEMP_UNITS_FAHRENHEIT) { - temp *= 9; // fixed point mul by 1.8 - temp /= 5; - temp += 32; - - temp_frac *= 9; - temp_frac /= 5; - temp_frac += 32; - temp += temp_frac/100; // add overflow to above - temp_frac %= 100; - } - } - - // Deassert CS - delay(1); - HAL_GPIO_WritePin(MAX_CS, 1); -} - - -// PID implementation -// TODO: Make struct that has the last_temp and i_state in it, pass by ref. Make struct that has other input values maybe. -int16_t last_pid_temp = 0; -uint8_t last_pid_temp_frac = 0; -int16_t i_state = 0; - -int16_t update_pid(uint16_t k_p, uint16_t k_i, uint16_t k_d, int16_t temp, uint8_t temp_frac, int16_t setpoint) -{ - // Calculate instantaneous error - int16_t error = (int16_t)setpoint - (int16_t)temp; // TODO: Use fixed point fraction - - // Proportional component - int16_t p_term = k_p * error; - - // Error accumulator (integrator) - i_state += error; - - // to prevent the iTerm getting huge despite lots of - // error, we use a "windup guard" - // (this happens when the machine is first turned on and - // it cant help be cold despite its best efforts) - // not necessary, but this makes windup guard values - // relative to the current iGain - int16_t windup_guard_res = windup_guard / k_i; - - // Calculate integral term with windup guard - if (i_state > windup_guard_res) - i_state = windup_guard_res; - else if (i_state < -windup_guard_res) - i_state = -windup_guard_res; - int16_t i_term = k_i * i_state; - - // Calculate differential term (slope since last iteration) - int16_t d_term = (k_d * (temp - last_pid_temp)); - - // Save temperature for next iteration - last_pid_temp = temp; - last_pid_temp_frac = temp_frac; - - int16_t result = p_term + i_term - d_term; - - // Put out tenths of percent, 0-1000. - if(result > 1000) - result = 1000; - else if(result < -1000) - result = -1000; - - // Return feedback - return result; -} - - -uint32_t last_ssr_on = 0; -uint32_t last_led = 0; -int32_t setpoint = 0; -int16_t ssr_output = 0; // Duty cycle of ssr, 0 to SSR_PERIOD -uint8_t pid_enabled = 0; - -// Process things -void process() -{ - update_temp(); // Read MAX31855 - - // TODO: Add calibration offset (linear) - - if(ticks - last_led > 400) - { - HAL_GPIO_TogglePin(LED_POWER); - last_led = ticks; - } - - // Every 200ms, set the SSR on unless output is 0 - if((ticks - last_ssr_on > SSR_PERIOD)) - { - if(pid_enabled) - { - // Get ssr output for next time - int16_t power_percent = update_pid(k_p, k_i, k_d, temp, temp_frac, setpoint); - //power-percent is 0-1000 - ssr_output = power_percent; //(((uint32_t)SSR_PERIOD * (uint32_t)10 * (uint32_t)100) * power_percent) / (uint32_t)1000000; - } - else - { - ssr_output = 0; - } - - // Only support heating (ssr_output > 0) right now - if(ssr_output > 0) { - - char tempstr[6]; - itoa(ssr_output, tempstr, 10); - ssd1306_DrawString(tempstr, 0, 90); - - HAL_GPIO_WritePin(LED_STAT, 1); - HAL_GPIO_WritePin(SSR_PIN, 1); - last_ssr_on = ticks; - } - } - - // Kill SSR after elapsed period less than SSR_PERIOD - if(ticks - last_ssr_on > ssr_output || ssr_output == 0) - { - HAL_GPIO_WritePin(LED_STAT, 0); - HAL_GPIO_WritePin(SSR_PIN, 0); - } -} - -void draw_setpoint() { - char tempstr[3]; - itoa_fp(temp, temp_frac, tempstr); - ssd1306_DrawStringBig(" ", 3, 0); - ssd1306_DrawStringBig(tempstr, 3, 0); - ssd1306_DrawStringBig(">", 3, 74); - itoa(setpoint, tempstr, 10); - ssd1306_DrawStringBig(" ", 3, 90); - ssd1306_DrawStringBig(tempstr, 3, 90); -} - -uint8_t goto_mode = 2; - -// State machine -uint8_t sw_btn_last = 0; -uint8_t sw_up_last = 0; -uint8_t sw_down_last = 0; -uint8_t sw_left_last = 0; -uint8_t sw_right_last = 0; - -#define SW_BTN_PRESSED (sw_btn_last == 0 && sw_btn == 1) // rising edge on buttonpress -#define SW_UP_PRESSED (sw_up_last == 0 && sw_up == 1) -#define SW_DOWN_PRESSED (sw_down_last == 0 && sw_down == 1) -#define SW_LEFT_PRESSED (sw_left_last == 0 && sw_left == 1) -#define SW_RIGHT_PRESSED (sw_right_last == 0 && sw_right == 1) - -void save_settings() -{ -/* - Minimal_EEPROM_Unlock(); - // Try programming a word at an address divisible by 4 - Minimal_EEPROM_ProgramWord(EEPROM_BASE_ADDR + EEPROM_ADDR_BOOTTOBREW, boottobrew); - Minimal_EEPROM_ProgramWord(EEPROM_BASE_ADDR + EEPROM_ADDR_WINDUP_GUARD, windup_guard); - Minimal_EEPROM_ProgramWord(EEPROM_BASE_ADDR + EEPROM_ADDR_K_P, k_p); - Minimal_EEPROM_ProgramWord(EEPROM_BASE_ADDR + EEPROM_ADDR_K_I, k_i); - Minimal_EEPROM_ProgramWord(EEPROM_BASE_ADDR + EEPROM_ADDR_K_D, k_d); - Minimal_EEPROM_ProgramWord(EEPROM_BASE_ADDR + EEPROM_ADDR_UNITS, temp_units); - Minimal_EEPROM_Lock(); -*/ -} - -void save_setpoints() -{ -/* - - Minimal_EEPROM_Unlock(); - Minimal_EEPROM_ProgramWord(EEPROM_BASE_ADDR + EEPROM_ADDR_BREWTEMP, setpoint_brew); - Minimal_EEPROM_ProgramWord(EEPROM_BASE_ADDR + EEPROM_ADDR_STEAMTEMP, setpoint_steam); - Minimal_EEPROM_Lock(); -*/ -} - - -// TODO: Make a struct that has all settings in it. Pass by ref to this func in a library. -void restore_settings() -{ -/* Minimal_EEPROM_Unlock(); - while(Minimal_FLASH_GetStatus()==FLASH_BUSY); - boottobrew = (*(__IO uint32_t*)(EEPROM_BASE_ADDR + EEPROM_ADDR_BOOTTOBREW)); - - while(Minimal_FLASH_GetStatus()==FLASH_BUSY); - windup_guard = (*(__IO uint32_t*)(EEPROM_BASE_ADDR + EEPROM_ADDR_WINDUP_GUARD)); - - while(Minimal_FLASH_GetStatus()==FLASH_BUSY); - k_p = (*(__IO uint32_t*)(EEPROM_BASE_ADDR + EEPROM_ADDR_K_P)); - - while(Minimal_FLASH_GetStatus()==FLASH_BUSY); - k_i = (*(__IO uint32_t*)(EEPROM_BASE_ADDR + EEPROM_ADDR_K_I)); - - while(Minimal_FLASH_GetStatus()==FLASH_BUSY); - k_d = (*(__IO uint32_t*)(EEPROM_BASE_ADDR + EEPROM_ADDR_K_D)); - - while(Minimal_FLASH_GetStatus()==FLASH_BUSY); - setpoint_brew = (*(__IO uint32_t*)(EEPROM_BASE_ADDR + EEPROM_ADDR_BREWTEMP)); - - while(Minimal_FLASH_GetStatus()==FLASH_BUSY); - setpoint_steam = (*(__IO uint32_t*)(EEPROM_BASE_ADDR + EEPROM_ADDR_STEAMTEMP)); - while(Minimal_FLASH_GetStatus()==FLASH_BUSY); - temp_units = (*(__IO uint32_t*)(EEPROM_BASE_ADDR + EEPROM_ADDR_UNITS)); - - Minimal_EEPROM_Lock(); */ -} - -int16_t last_temp = 21245; - - -/////////////////////////////////////////////////////////////////////////////////////// -/// freaking multiple setpoint support /// -uint8_t step_duration[10] = {0,0,0,0,0,0,0,0,0,0}; -int16_t step_setpoint[10] = {0,0,0,0,0,0,0,0,0,0}; -uint8_t final_setpoint = 0; - -// Multiple screens to set setpoint and duration on each screen -// press center to go to the next one, and press left or right or something to confirm - -// When executing, complete on time AND(?) temperature. Maybe allow switching to OR via settings - -//////////////////////////////////////////////////////////////////////////////////////////////// - -void machine() -{ - uint8_t last_state = state; - - uint8_t temp_changed = temp != last_temp; - last_temp = temp; - - uint8_t sw_btn = !HAL_GPIO_ReadPin(SW_BTN); - uint8_t sw_up = !HAL_GPIO_ReadPin(SW_UP); - uint8_t sw_down = !HAL_GPIO_ReadPin(SW_DOWN); - uint8_t sw_left = !HAL_GPIO_ReadPin(SW_LEFT); - uint8_t sw_right = !HAL_GPIO_ReadPin(SW_RIGHT); - - switch(state) - { - // Idle state - case STATE_IDLE: - { - // Write text to OLED - // [ therm :: idle ] - ssd1306_DrawString("therm :: idle ", 0, 40); - pid_enabled = 0; - - if(temp_changed) { - char tempstr[6]; - itoa_fp(temp, temp_frac, tempstr); - ssd1306_DrawString("Temp: ", 3, 40); - ssd1306_DrawString(" ", 3, 72); - ssd1306_DrawString(tempstr, 3, 72); - } - - ssd1306_drawlogo(); - - switch(goto_mode) { - case 2: - { - ssd1306_DrawString("-> heat ", 1, 40); - } break; - - case 1: - { - ssd1306_DrawString("-> setup ", 1, 40); - } break; - - case 0: - { - ssd1306_DrawString("-> reset ", 1, 40); - } break; - } - - // Button handler - if(SW_BTN_PRESSED) { - switch(goto_mode) { - case 2: - state = STATE_PREHEAT_BREW; - break; - case 1: - state = STATE_SETP; - break; - case 0: - state = STATE_IDLE; - break; - default: - state = STATE_PREHEAT_BREW; - } - } - else if(SW_UP_PRESSED && goto_mode < 2) { - goto_mode++; - } - else if(SW_DOWN_PRESSED && goto_mode > 0) { - goto_mode--; - } - - - // Event Handler - // N/A - - } break; - - case STATE_SETP: - { - // Write text to OLED - // [ therm :: set p ] - // [ p = 12 ] - ssd1306_DrawString("Proportional", 0, 40); - ssd1306_drawlogo(); - - char tempstr[6]; - itoa(k_p, tempstr, 10); - ssd1306_DrawString("P=", 1, 45); - ssd1306_DrawString(" ", 1, 57); - ssd1306_DrawString(tempstr, 1, 57); - - ssd1306_DrawString("Press to accept", 3, 40); - - // Button handler - if(SW_BTN_PRESSED) { - state = STATE_SETI; - } - else { - user_input(&k_p); - } - - // Event Handler - // N/A - - } break; - - case STATE_SETI: - { - // Write text to OLED - // [ therm :: set i ] - // [ i = 12 ] - ssd1306_DrawString("Integral", 0, 40); - ssd1306_drawlogo(); - - char tempstr[6]; - itoa(k_i, tempstr, 10); - ssd1306_DrawString("I=", 1, 45); - ssd1306_DrawString(" ", 1, 57); - ssd1306_DrawString(tempstr, 1, 57); - - ssd1306_DrawString("Press to accept", 3, 40); - - // Button handler - if(SW_BTN_PRESSED) { - state = STATE_SETD; - } - else { - user_input(&k_i); - } - - // Event Handler - // N/A - - } break; - - case STATE_SETD: - { - // Write text to OLED - // [ therm :: set d ] - // [ d = 12 ] - ssd1306_DrawString("Derivative", 0, 40); - ssd1306_drawlogo(); - - char tempstr[6]; - itoa(k_d, tempstr, 10); - ssd1306_DrawString("D=", 1, 45); - ssd1306_DrawString(" ", 1, 57); - ssd1306_DrawString(tempstr, 1, 57); - - ssd1306_DrawString("Press to accept", 3, 40); - - // Button handler - if(SW_BTN_PRESSED) { - state = STATE_SETWINDUP; - } - else { - user_input(&k_d); - } - - // Event Handler - // N/A - - } break; - - case STATE_SETSTEPS: - { - // Write text to OLED - // [ step #1:: Duration: ### ] - // [ Setpoint: ### ] - char tempstr[6]; - - itoa(final_setpoint, tempstr, 10); - ssd1306_DrawString("Step #", 0, 0); - ssd1306_DrawString(tempstr, 0, 40); - - ssd1306_DrawString("Duration: ", 0, 5); - itoa(step_duration[final_setpoint], tempstr, 10); - ssd1306_DrawString(tempstr, 0, 70); - - ssd1306_DrawString("Setpoint: ", 0, 0); - itoa(step_setpoint[final_setpoint], tempstr, 10); - ssd1306_DrawString(tempstr, 0, 70); - - ssd1306_DrawString("Press to accept", 3, 40); - - // Button handler - TODO: increment max_step if pressed - // return and go to next state otherwise - if(SW_BTN_PRESSED) { - state = STATE_SETSTEPS; - final_setpoint++; - } - // else if(SW_LEFT_PRESSED) { - // state++; // go to next state or something - // } - else { - user_input(&k_p); - } - - // Event Handler - // N/A - - } break; - - case STATE_SETWINDUP: - { - // Write text to OLED - // [ therm :: set windup ] - // [ g = 12 ] - ssd1306_DrawString("Windup Guard", 0, 40); - ssd1306_drawlogo(); - - char tempstr[6]; - itoa(windup_guard, tempstr, 10); - ssd1306_DrawString("G=", 1, 45); - ssd1306_DrawString(" ", 1, 57); - ssd1306_DrawString(tempstr, 1, 57); - - ssd1306_DrawString("Press to accept", 3, 40); - - // Button handler - if(SW_BTN_PRESSED) { - state = STATE_SETBOOTTOBREW; - } - else { - user_input(&windup_guard); - } - - // Event Handler - // N/A - - } break; - - case STATE_SETBOOTTOBREW: - { - // Write text to OLED - // [ therm :: set windup ] - // [ g = 12 ] - ssd1306_DrawString("Start on Boot", 0, 40); - ssd1306_drawlogo(); - - ssd1306_DrawString("sob=", 1, 45); - - if(boottobrew) - ssd1306_DrawString("Enabled ", 1, 70); - else - ssd1306_DrawString("Disabled", 1, 70); - - ssd1306_DrawString("Press to accept", 3, 40); - - // Button handler - if(SW_BTN_PRESSED) { - state = STATE_SETUNITS; - } - else if(!HAL_GPIO_ReadPin(SW_UP)) { - boottobrew = 1; - } - else if(!HAL_GPIO_ReadPin(SW_DOWN)) { - boottobrew = 0; - } - - // Event Handler - // N/A - - } break; - - case STATE_SETUNITS: - { - // Write text to OLED - // [ therm :: set windup ] - // [ g = 12 ] - ssd1306_DrawString("Units: ", 0, 40); - ssd1306_drawlogo(); - - if(temp_units == TEMP_UNITS_FAHRENHEIT) - ssd1306_DrawString("Fahrenheit", 1, 60); - else - ssd1306_DrawString("Celsius ", 1, 60); - - ssd1306_DrawString("Press to accept", 3, 40); - - // Button handler - if(SW_BTN_PRESSED) { - save_settings(); - state = STATE_IDLE; - } - else if(!HAL_GPIO_ReadPin(SW_UP)) { - temp_units = TEMP_UNITS_FAHRENHEIT; - } - else if(!HAL_GPIO_ReadPin(SW_DOWN)) { - temp_units = TEMP_UNITS_CELSIUS; - } - - // Event Handler - // N/A - - } break; - - - case STATE_PREHEAT_BREW: - { - // Write text to OLED - // [ therm : preheating brew ] - // [ 30 => 120 C ] - ssd1306_DrawString("Preheating...", 0, 0); - //ssd1306_drawlogo(); - draw_setpoint(); - pid_enabled = 1; - setpoint = setpoint_brew; - - // Button handler - if(SW_BTN_PRESSED) { - save_setpoints(); // TODO: Check for mod - state = STATE_IDLE; - } - else { - user_input(&setpoint_brew); - } - - // Event Handler - if(temp >= setpoint) { - state = STATE_MAINTAIN_BREW; - } - - } break; - - case STATE_MAINTAIN_BREW: - { - // Write text to OLED - // [ therm : ready to brew ] - // [ 30 => 120 C ] - ssd1306_DrawString("Preheated!", 0, 0); - //ssd1306_drawlogo(); - draw_setpoint(); - pid_enabled = 1; - setpoint = setpoint_brew; - - // Button handler - if(SW_BTN_PRESSED) { - save_setpoints(); // TODO: Check for mod - state = STATE_IDLE; - } - else { - user_input(&setpoint_brew); - } - - // Event Handler - // N/A - - } break; - - case STATE_PREHEAT_STEAM: - { - // Write text to OLED - // [ therm : preheating steam ] - // [ 30 => 120 C ] - ssd1306_DrawString("Preheating...", 0, 0); - //ssd1306_drawlogo(); - draw_setpoint(); - pid_enabled = 1; - setpoint = setpoint_steam; - - // Button handler - if(SW_BTN_PRESSED) { - state = STATE_IDLE; - save_setpoints(); // TODO: Check for mod - } - else { - user_input(&setpoint_steam); - } - - // Event Handler - if(temp >= setpoint) { - state = STATE_MAINTAIN_STEAM; - } - - } break; - - case STATE_MAINTAIN_STEAM: - { - // Write text to OLED - // [ therm : ready to steam ] - // [ 30 => 120 C ] - ssd1306_DrawString("Ready to Steam!", 0, 0); - //ssd1306_drawlogo(); - draw_setpoint(); - pid_enabled = 1; - setpoint = setpoint_steam; - - // Button handler - if(SW_BTN_PRESSED) { - state = STATE_IDLE; - save_setpoints(); // TODO: Check for mod - } - else { - user_input(&setpoint_steam); - } - - // Event Handler - // N/A - - } break; - - case STATE_TC_ERROR: - { - // Write text to OLED - // [ therm : ready to steam ] - // [ 30 => 120 C ] - ssd1306_DrawString("Error:", 0, 0); - ssd1306_DrawString("Connect thermocouple", 1, 0); - ssd1306_DrawString("Press -> to ignore", 3, 0); - - // Button handler - if(SW_BTN_PRESSED) { - state = STATE_IDLE; - } - else if(SW_RIGHT_PRESSED) { - ignore_tc_error = 1; - state = STATE_IDLE; - } - // Event Handler - // Maybe handle if TC is plugged in - // N/A - - } break; - - // Something is terribly wrong - default: - { - state = STATE_IDLE; - pid_enabled = 0; - - } break; - - } - - if(last_state != state) { - // Clear screen on state change - goto_mode = 2; - ssd1306_clearscreen(); - } - - // Last buttonpress - sw_btn_last = sw_btn; - sw_up_last = sw_up; - sw_down_last = sw_down; - sw_left_last = sw_left; - sw_right_last = sw_right; -} - -// Delay a number of systicks -void delay(__IO uint32_t nTime) -{ - TimingDelay = nTime; - while(TimingDelay != 0); -} - -// ISR-triggered decrement of delay and increment of tickcounter -void TimingDelay_Decrement(void) -{ - if (TimingDelay != 0x00) - { - TimingDelay--; - } - ticks++; -} - -// vim:softtabstop=4 shiftwidth=4 expandtab