iron.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571
  1. /*
  2. * iron.c
  3. *
  4. * Created on: Jan 12, 2021
  5. * Author: David Original work by Jose (PTDreamer), 2017
  6. */
  7. #include "iron.h"
  8. #include "buzzer.h"
  9. #include "settings.h"
  10. #include "main.h"
  11. #include "tempsensors.h"
  12. #include "voltagesensors.h"
  13. #include "ssd1306.h"
  14. volatile iron_t Iron;
  15. typedef struct setTemperatureReachedCallbackStruct_t setTemperatureReachedCallbackStruct_t;
  16. struct setTemperatureReachedCallbackStruct_t {
  17. setTemperatureReachedCallback callback;
  18. setTemperatureReachedCallbackStruct_t *next;
  19. };
  20. typedef struct currentModeChangedCallbackStruct_t currentModeChangedCallbackStruct_t;
  21. struct currentModeChangedCallbackStruct_t {
  22. currentModeChanged callback;
  23. currentModeChangedCallbackStruct_t *next;
  24. };
  25. static currentModeChangedCallbackStruct_t *currentModeChangedCallbacks = NULL;
  26. static setTemperatureReachedCallbackStruct_t *temperatureReachedCallbacks = NULL;
  27. static void temperatureReached(uint16_t temp) {
  28. setTemperatureReachedCallbackStruct_t *s = temperatureReachedCallbacks;
  29. while(s) {
  30. if(s->callback) {
  31. s->callback(temp);
  32. }
  33. s = s->next;
  34. }
  35. }
  36. static void modeChanged(uint8_t newMode) {
  37. currentModeChangedCallbackStruct_t *s = currentModeChangedCallbacks;
  38. while(s) {
  39. s->callback(newMode);
  40. s = s->next;
  41. }
  42. }
  43. void ironInit(TIM_HandleTypeDef *delaytimer, TIM_HandleTypeDef *pwmtimer, uint32_t pwmchannel) {
  44. Iron.Pwm_Timer = pwmtimer;
  45. Iron.Delay_Timer = delaytimer;
  46. Iron.Pwm_Channel = pwmchannel;
  47. Iron.Error.Flags = noError; // Clear all errors
  48. if(systemSettings.settings.WakeInputMode==wakeInputmode_shake){ // If in shake mode, apply init mode
  49. setCurrentMode(systemSettings.settings.initMode);
  50. }
  51. else{ // If in stand mode, read WAKE status
  52. if(WAKE_input()){
  53. setCurrentMode(mode_run); // Set run mode
  54. }
  55. else{
  56. setCurrentMode(systemSettings.settings.StandMode); // Set stand idle mode
  57. }
  58. }
  59. initTimers(); // Initialize timers
  60. // Now the PWM and ADC are working in the background.
  61. }
  62. void handleIron(void) {
  63. uint32_t CurrentTime = HAL_GetTick();
  64. uint16_t tipTemp = readTipTemperatureCompensated(update_reading,read_Avg); // Update Tip temperature in human readable format
  65. if(!Iron.Error.failState){
  66. if( (systemSettings.setupMode==setup_On) || // Ensure not being in setup mode,
  67. (systemSettings.settings.NotInitialized!=initialized) || // settings and profile are initialized
  68. (systemSettings.Profile.NotInitialized!=initialized) ||
  69. (systemSettings.Profile.ID != systemSettings.settings.currentProfile) || // Profile ID is the same as the system profile
  70. (systemSettings.settings.currentProfile>profile_C210)){ // And it's a known value
  71. SetFailState(setError);
  72. }
  73. }
  74. checkIronError(); // Error detection.
  75. if( Iron.Error.globalFlag ){ // If any error flag active, stop here
  76. return; // Do nothing else (PWM already disabled)
  77. }
  78. // Controls external mode changes (from stand mode changes), this acts as a debouncing timer
  79. if(Iron.updateMode==needs_update){ // If pending mode change
  80. if((CurrentTime-Iron.LastModeChangeTime)>100){ // Wait 100mS with steady mode (de-bouncing)
  81. Iron.updateMode=no_update; // reset flag
  82. setCurrentMode(Iron.changeMode); // Apply stand mode
  83. }
  84. }
  85. // If sleeping, stop here
  86. if(Iron.CurrentMode==mode_sleep) { // For safety, update PWM out everytime
  87. if(systemSettings.settings.activeDetection){
  88. Iron.Pwm_Out = PWMminOutput;
  89. }
  90. else{
  91. Iron.Pwm_Out = 0;
  92. }
  93. __HAL_TIM_SET_COMPARE(Iron.Pwm_Timer, Iron.Pwm_Channel, Iron.Pwm_Out); // Load new calculated PWM Duty
  94. return;
  95. }
  96. // Controls inactivity timer and enters low power modes
  97. uint32_t mode_time = CurrentTime - Iron.CurrentModeTimer;
  98. uint32_t sleep_time = (uint32_t)systemSettings.Profile.sleepTimeout*60000;
  99. uint32_t standby_time = (uint32_t)systemSettings.Profile.standbyTimeout*60000;
  100. if(Iron.calibrating==calibration_Off){ // Don't enter low power states while calibrating
  101. if(Iron.CurrentMode==mode_run) { // If running
  102. if(systemSettings.Profile.standbyTimeout>0 && mode_time>standby_time) { // If standbyTimeout not zero, check time
  103. setCurrentMode(mode_standby);
  104. }
  105. else if(systemSettings.Profile.standbyTimeout==0 && mode_time>sleep_time) { // If standbyTimeout zero, check sleep time
  106. setCurrentMode(mode_sleep);
  107. }
  108. }
  109. else if(Iron.CurrentMode==mode_standby){ // If in standby
  110. if(systemSettings.Profile.standbyTimeout>0 && mode_time>sleep_time) { // Check sleep time
  111. setCurrentMode(mode_sleep); // Only enter sleep if not zero
  112. }
  113. }
  114. }
  115. if(Iron.updatePwm==needs_update){
  116. Iron.updatePwm=no_update;
  117. __HAL_TIM_SET_AUTORELOAD(Iron.Pwm_Timer,systemSettings.Profile.pwmPeriod);
  118. __HAL_TIM_SET_AUTORELOAD(Iron.Delay_Timer,systemSettings.Profile.pwmDelay);
  119. Iron.Pwm_Limit = (systemSettings.Profile.pwmPeriod-1) - (systemSettings.Profile.pwmDelay + 1 + (uint16_t)ADC_MEASURE_TIME/10);
  120. }
  121. #ifdef USE_VIN
  122. updatePowerLimit(); // Update power limit values
  123. #endif
  124. // Update PID
  125. volatile uint16_t PID_temp;
  126. if(Iron.DebugMode==debug_On){ // If in debug mode, use debug setpoint value
  127. Iron.Pwm_Out = calculatePID(Iron.Debug_SetTemperature, TIP.last_avg, Iron.Pwm_Max);
  128. }
  129. else{ // Else, use current setpoint value
  130. PID_temp = human2adc(Iron.CurrentSetTemperature);
  131. Iron.Pwm_Out = calculatePID(PID_temp, TIP.last_avg, Iron.Pwm_Max);
  132. }
  133. if(systemSettings.settings.activeDetection && Iron.Pwm_Out<=PWMminOutput){
  134. Iron.CurrentIronPower = 0;
  135. Iron.Pwm_Out = PWMminOutput; // Maintain iron detection
  136. }
  137. else if(Iron.Pwm_Out == Iron.Pwm_Max){
  138. Iron.CurrentIronPower = 100;
  139. }
  140. else{
  141. Iron.CurrentIronPower = ((uint32_t)Iron.Pwm_Out*100)/Iron.Pwm_Max; // Compute new %
  142. }
  143. __HAL_TIM_SET_COMPARE(Iron.Pwm_Timer, Iron.Pwm_Channel, Iron.Pwm_Out); // Load new calculated PWM Duty
  144. // For calibration process. Add +-2ºC detection margin
  145. if( (tipTemp>=(Iron.CurrentSetTemperature-2)) && (tipTemp<=(Iron.CurrentSetTemperature+2)) && !Iron.Cal_TemperatureReachedFlag) {
  146. temperatureReached( Iron.CurrentSetTemperature);
  147. Iron.Cal_TemperatureReachedFlag = 1;
  148. }
  149. }
  150. // Round to closest 10
  151. uint16_t round_10(uint16_t input){
  152. if((input%10)>5){
  153. input+=(10-input%10); // ex. 640°F=337°C->340°C)
  154. }
  155. else{
  156. input-=input%10; // ex. 300°C=572°F->570°F
  157. }
  158. return input;
  159. }
  160. // Changes the system temperature unit
  161. void setSystemTempUnit(bool unit){
  162. if(systemSettings.Profile.tempUnit != unit){
  163. systemSettings.Profile.tempUnit = unit;
  164. systemSettings.Profile.UserSetTemperature = round_10(TempConversion(systemSettings.Profile.UserSetTemperature,unit,0));
  165. systemSettings.Profile.standbyTemperature = round_10(TempConversion(systemSettings.Profile.standbyTemperature,unit,0));
  166. systemSettings.Profile.MaxSetTemperature = round_10(TempConversion(systemSettings.Profile.MaxSetTemperature,unit,0));
  167. systemSettings.Profile.MinSetTemperature = round_10(TempConversion(systemSettings.Profile.MinSetTemperature,unit,0));
  168. }
  169. systemSettings.settings.tempUnit = unit;
  170. setCurrentMode(Iron.CurrentMode); // Reload temps
  171. }
  172. // This function inits the timers and sets the prescaler settings depending on the system core clock
  173. // The final PWM settings are applied by LoadProfile
  174. void initTimers(void){
  175. // Delay timer config
  176. #ifdef DELAY_TIMER_HALFCLOCK
  177. Iron.Delay_Timer->Init.Prescaler = (SystemCoreClock/50000)-1; // 10uS input clock
  178. #else
  179. Iron.Delay_Timer->Init.Prescaler = (SystemCoreClock/100000)-1;
  180. #endif
  181. Iron.Delay_Timer->Init.Period = 1999; // 20mS by default
  182. if (HAL_TIM_Base_Init(Iron.Delay_Timer) != HAL_OK){
  183. Error_Handler();
  184. }
  185. // PWM timer config
  186. #ifdef PWM_TIMER_HALFCLOCK
  187. Iron.Pwm_Timer->Init.Prescaler = (SystemCoreClock/50000)-1; // 10uS input clock
  188. #else
  189. Iron.Pwm_Timer->Init.Prescaler = (SystemCoreClock/100000)-1;
  190. #endif
  191. Iron.Pwm_Timer->Init.Period = 19999; // 200mS by default
  192. if (HAL_TIM_Base_Init(Iron.Pwm_Timer) != HAL_OK){
  193. Error_Handler();
  194. }
  195. __HAL_TIM_CLEAR_FLAG(Iron.Delay_Timer,TIM_FLAG_UPDATE | TIM_FLAG_COM | TIM_FLAG_CC1 | TIM_FLAG_CC2 | TIM_FLAG_CC3 | TIM_FLAG_CC4 ); // Clear all flags
  196. __HAL_TIM_ENABLE_IT(Iron.Delay_Timer,TIM_IT_UPDATE); // Enable Delay timer interrupt
  197. __HAL_TIM_CLEAR_FLAG(Iron.Pwm_Timer,TIM_FLAG_UPDATE | TIM_FLAG_COM | TIM_FLAG_CC1 | TIM_FLAG_CC2 | TIM_FLAG_CC3 | TIM_FLAG_CC4 ); // Clear all flags
  198. #ifdef DEBUG_PWM
  199. __HAL_TIM_ENABLE_IT(Iron.Pwm_Timer, TIM_IT_UPDATE); // For debugging PWM (TEST pin)
  200. #endif
  201. #ifdef PWM_CHx
  202. HAL_TIM_PWM_Start_IT(Iron.Pwm_Timer, Iron.Pwm_Channel); // Start PWM, output uses CHx channel
  203. #elif defined PWM_CHxN
  204. HAL_TIMEx_PWMN_Start_IT(Iron.Pwm_Timer, Iron.Pwm_Channel); // Start PWM, output uses CHxN channel
  205. #else
  206. #error No PWM ouput set (See PWM_CHx / PWM_CHxN in board.h)
  207. #endif
  208. if(systemSettings.settings.activeDetection){
  209. Iron.Pwm_Out = PWMminOutput;
  210. }
  211. else{
  212. Iron.Pwm_Out = 0;
  213. }
  214. Iron.Pwm_Limit = 17999 - (uint16_t)(ADC_MEASURE_TIME/10);
  215. __HAL_TIM_SET_COMPARE(Iron.Pwm_Timer, Iron.Pwm_Channel, Iron.Pwm_Out); // Set min value into PWM
  216. }
  217. // Check iron runaway
  218. void runAwayCheck(void){
  219. uint16_t TempStep,TempLimit;
  220. uint32_t CurrentTime = HAL_GetTick();
  221. uint16_t tipTemp = readTipTemperatureCompensated(stored_reading, read_Avg);
  222. // If by any means the PWM output is higher than max calculated, generate error
  223. if((Iron.Pwm_Out > Iron.Pwm_Limit) || (Iron.Pwm_Out != __HAL_TIM_GET_COMPARE(Iron.Pwm_Timer,Iron.Pwm_Channel))){
  224. Error_Handler();
  225. }
  226. if(systemSettings.settings.tempUnit==mode_Celsius){
  227. TempStep = 25;
  228. TempLimit = 500;
  229. }else{
  230. TempStep = 45;
  231. TempLimit = 950;
  232. }
  233. if((Iron.Pwm_Out>PWMminOutput) && (Iron.RunawayStatus==runaway_ok) && (Iron.DebugMode==debug_Off) &&(tipTemp > Iron.CurrentSetTemperature)){
  234. if(tipTemp>TempLimit){ Iron.RunawayLevel=runaway_500; }
  235. else{
  236. for(int8_t c=runaway_100; c>=runaway_ok; c--){ // Check temperature diff
  237. Iron.RunawayLevel=c;
  238. if(tipTemp > (Iron.CurrentSetTemperature + (TempStep*Iron.RunawayLevel)) ){ // 25ºC steps
  239. break; // Stop at the highest overrun condition
  240. }
  241. }
  242. }
  243. if(Iron.RunawayLevel!=runaway_ok){ // Runaway detected?
  244. if(Iron.prevRunawayLevel==runaway_ok){ // First overrun detection?
  245. Iron.prevRunawayLevel=Iron.RunawayLevel; // Yes, store in prev level
  246. Iron.RunawayTimer = CurrentTime; // Store time
  247. }
  248. else{ // Was already triggered
  249. switch(Iron.RunawayLevel){
  250. case runaway_ok: // No problem (<25ºC difference)
  251. break; // (Never used here)
  252. case runaway_25: // Temp >25°C over setpoint
  253. if((CurrentTime-Iron.RunawayTimer)>20000){ // 20 second limit
  254. Iron.RunawayStatus=runaway_triggered;
  255. FatalError(error_RUNAWAY25);
  256. }
  257. break;
  258. case runaway_50: // Temp >50°C over setpoint
  259. if((CurrentTime-Iron.RunawayTimer)>10000){ // 10 second limit
  260. Iron.RunawayStatus=runaway_triggered;
  261. FatalError(error_RUNAWAY50);
  262. }
  263. break;
  264. case runaway_75: // Temp >75°C over setpoint
  265. if((CurrentTime-Iron.RunawayTimer)>3000){ // 3 second limit
  266. Iron.RunawayStatus=runaway_triggered;
  267. FatalError(error_RUNAWAY75);
  268. }
  269. break;
  270. case runaway_100: // Temp >100°C over setpoint
  271. if((CurrentTime-Iron.RunawayTimer)>1000){ // 1 second limit
  272. Iron.RunawayStatus=runaway_triggered;
  273. FatalError(error_RUNAWAY100);
  274. }
  275. break;
  276. case runaway_500: // Exceed 500ºC!
  277. if((CurrentTime-Iron.RunawayTimer)>500){ // 0.5 second limit
  278. Iron.RunawayStatus=runaway_triggered;
  279. FatalError(error_RUNAWAY500);
  280. }
  281. break;
  282. default: // Unknown overrun state
  283. Iron.RunawayStatus=runaway_triggered;
  284. FatalError(error_RUNAWAY_UNKNOWN);
  285. break;
  286. }
  287. }
  288. }
  289. return; // Runaway active, return
  290. }
  291. Iron.RunawayTimer = CurrentTime; // If no runaway detected, reset values
  292. Iron.prevRunawayLevel=runaway_ok;
  293. }
  294. // Update PWM max value based on current supply voltage, heater resistance and power limit setting
  295. #ifdef USE_VIN
  296. void updatePowerLimit(void){
  297. uint32_t volts = getSupplyVoltage_v_x10(); // Get last voltage reading x10
  298. volts = (volts*volts)/10; // (Vx10 * Vx10)/10 = (V*V)*10 (x10 for fixed point precision)
  299. if(volts==0){
  300. volts=1; // set minimum value to avoid division by 0
  301. }
  302. uint32_t PwmPeriod=systemSettings.Profile.pwmPeriod; // Read complete PWM period
  303. uint32_t maxPower = volts/systemSettings.Profile.impedance; // Compute max power with current voltage and impedance(Impedance stored in x10)
  304. if(systemSettings.Profile.power >= maxPower){ // If set power is already higher than the max possible power given the voltage and heater resistance
  305. Iron.Pwm_Max = Iron.Pwm_Limit; // Set max PWM
  306. }
  307. else{ // Else,
  308. Iron.Pwm_Max = (PwmPeriod*systemSettings.Profile.power)/maxPower; // Compute max PWM output for current power limit
  309. if(Iron.Pwm_Max > Iron.Pwm_Limit){ // Ensure it doesn't exceed the limits
  310. Iron.Pwm_Max = Iron.Pwm_Limit;
  311. }
  312. else if(Iron.Pwm_Max==0){ // Ensure it doesn't exceed the PWM limits
  313. Iron.Pwm_Max = 1;
  314. }
  315. }
  316. }
  317. #endif
  318. // Loads the PWM delay
  319. void setPwmDelay(uint16_t delay){
  320. systemSettings.Profile.pwmDelay=delay;
  321. Iron.updatePwm=needs_update;
  322. }
  323. // Loads the PWM period
  324. void setPwmPeriod(uint16_t period){
  325. systemSettings.Profile.pwmPeriod=period;
  326. Iron.updatePwm=needs_update;
  327. }
  328. // Sets no Iron detection threshold
  329. void setNoIronValue(uint16_t noiron){
  330. systemSettings.Profile.noIronValue=noiron;
  331. }
  332. // Change the iron operating mode in stand mode
  333. void setModefromStand(uint8_t mode){
  334. if( GetIronError() ||
  335. ((Iron.changeMode==mode) && (Iron.CurrentMode==mode)) ||
  336. ((Iron.CurrentMode==mode_sleep) && (mode==mode_standby))){ // Ignore if error present, same mode, or setting standby when already in sleep mode
  337. return;
  338. }
  339. if(Iron.changeMode!=mode){
  340. Iron.changeMode = mode; // Update mode
  341. Iron.LastModeChangeTime = HAL_GetTick(); // Reset debounce timer
  342. }
  343. Iron.updateMode = needs_update; // Set flag
  344. }
  345. // Set the iron operating mode
  346. void setCurrentMode(uint8_t mode){
  347. Iron.CurrentModeTimer = HAL_GetTick(); // Refresh current mode timer
  348. if(mode==mode_standby){
  349. Iron.CurrentSetTemperature = systemSettings.Profile.standbyTemperature; // Set standby temp
  350. }
  351. else{
  352. Iron.CurrentSetTemperature = systemSettings.Profile.UserSetTemperature; // Set user temp (sleep mode ignores this)
  353. }
  354. if(Iron.CurrentMode != mode){ // If current mode is different
  355. resetPID();
  356. buzzer_long_beep();
  357. Iron.CurrentMode = mode;
  358. modeChanged(mode);
  359. if(Iron.CurrentMode == mode_run){
  360. Iron.Cal_TemperatureReachedFlag = 0;
  361. }
  362. }
  363. }
  364. // Called from program timer if WAKE change is detected
  365. void IronWake(bool source){ // source: handle shake, encoder push button
  366. if(GetIronError()){ return; } // Ignore if error present
  367. if(Iron.CurrentMode!=mode_run){
  368. // If in sleep mode, ignore if wake source disabled
  369. if( (source==source_wakeButton && (!systemSettings.settings.wakeOnButton || (systemSettings.settings.WakeInputMode==wakeInputmode_stand) )) || (source==source_wakeInput && !systemSettings.settings.wakeOnShake)){
  370. return;
  371. }
  372. }
  373. if(source==source_wakeInput){ // Else, if source wake input
  374. Iron.newActivity=1; // Enable flag for oled activity icon
  375. Iron.lastActivityTime = HAL_GetTick(); // Store time for keeping the image on
  376. }
  377. setCurrentMode(mode_run); // Set run mode. If already in run mode, this will reset the run timer.
  378. }
  379. // Checks for non critical iron errors (Errors that can be cleared)
  380. void checkIronError(void){
  381. uint32_t CurrentTime = HAL_GetTick(); // Get current time
  382. int16_t ambTemp = readColdJunctionSensorTemp_x10(mode_Celsius); // Read NTC in Celsius
  383. IronError_t Err = { 0 };
  384. Err.failState = Iron.Error.failState; // Get failState flag
  385. Err.NTC_high = ambTemp > 700 ? 1 : 0; // Check NTC too high (Wrong NTC wiring or overheating, >70ºC)
  386. Err.NTC_low = ambTemp < -500 ? 1 : 0;
  387. #ifdef USE_VIN
  388. Err.V_low = getSupplyVoltage_v_x10() < systemSettings.settings.lvp ? 1 : 0; // Check supply voltage (Mosfet will not work ok <10V, it will heat up)
  389. #endif
  390. Err.noIron = TIP.last_raw>systemSettings.Profile.noIronValue ? 1 : 0; // Check tip temperature too high (Wrong connection or not connected)
  391. if(CurrentTime<1000 || systemSettings.setupMode==setup_On){ // Don't check sensor errors during first second or in setup mode, wait for readings need to get stable
  392. Err.Flags &= 0x10; // Only check failure state
  393. }
  394. if(Err.Flags){ // If there are errors
  395. Iron.Error.Flags |= Err.Flags; // Update flags
  396. Iron.LastErrorTime = CurrentTime; // Save time
  397. if(!Iron.Error.globalFlag){ // If first detection
  398. if(Err.Flags==1 && Iron.CurrentMode == mode_sleep){ // If in sleep mode and only no iron flag is set
  399. return; // return
  400. }
  401. Iron.Error.globalFlag = 1; // Set global flag
  402. setCurrentMode(mode_sleep); // Force sleep mode
  403. if(systemSettings.settings.activeDetection && !Err.failState){
  404. Iron.Pwm_Out = PWMminOutput;
  405. }
  406. else{
  407. Iron.Pwm_Out = 0;
  408. }
  409. __HAL_TIM_SET_COMPARE(Iron.Pwm_Timer, Iron.Pwm_Channel, Iron.Pwm_Out); // Load now the value into the PWM hardware
  410. buzzer_alarm_start(); // Start alarm
  411. }
  412. }
  413. else if(!Err.Flags && Iron.Error.Flags==1){ // If no errors and only no iron flag was active (And no global flag, so it was detected while in sleep mode)
  414. Iron.Error.Flags=0; // Clear
  415. }
  416. else if (Iron.Error.globalFlag && Err.Flags==noError){ // If global flag set, but there are no errors anymore
  417. if((CurrentTime-Iron.LastErrorTime)>systemSettings.settings.errorDelay){ // Check enough time has passed
  418. Iron.Error.Flags = noError; // Reset errors
  419. buzzer_alarm_stop(); // Stop alarm
  420. setCurrentMode(mode_run); // Restore run mode
  421. }
  422. }
  423. }
  424. // Returns the actual status of the iron error.
  425. bool GetIronError(void){
  426. return Iron.Error.globalFlag;
  427. }
  428. // Sets Failure state
  429. void SetFailState(bool FailState) {
  430. if(!FailState && Iron.Error.Flags==0x90){ // If only failsafe was active? (This should only happen because it was on first init screen)
  431. Iron.Error.Flags = 0; // Reset errors (Ignore timer)
  432. setCurrentMode(mode_run); // Resume run mode
  433. }
  434. else{
  435. Iron.Error.failState=FailState;
  436. checkIronError(); // Update Error
  437. }
  438. }
  439. // Gets Failure state
  440. bool GetFailState() {
  441. return Iron.Error.failState;
  442. }
  443. // Sets the debug temperature
  444. void setDebugTemp(uint16_t value) {
  445. Iron.Debug_SetTemperature = value;
  446. }
  447. // Handles the debug activation/deactivation
  448. void setDebugMode(uint8_t value) {
  449. Iron.DebugMode = value;
  450. }
  451. // Sets the user temperature
  452. void setUserTemperature(uint16_t temperature) {
  453. Iron.Cal_TemperatureReachedFlag = 0;
  454. if(systemSettings.Profile.UserSetTemperature != temperature){
  455. systemSettings.Profile.UserSetTemperature = temperature;
  456. if(Iron.CurrentMode==mode_run){
  457. Iron.CurrentSetTemperature=temperature;
  458. resetPID();
  459. }
  460. }
  461. }
  462. // Returns the actual set temperature
  463. uint16_t getUserTemperature() {
  464. return systemSettings.Profile.UserSetTemperature;
  465. }
  466. // Returns the actual working mode of the iron
  467. uint8_t getCurrentMode() {
  468. return Iron.CurrentMode;
  469. }
  470. // Returns the output power
  471. int8_t getCurrentPower() {
  472. return Iron.CurrentIronPower;
  473. }
  474. // Adds a callback to be called when the set temperature is reached
  475. void addSetTemperatureReachedCallback(setTemperatureReachedCallback callback) {
  476. setTemperatureReachedCallbackStruct_t *s = malloc(sizeof(setTemperatureReachedCallbackStruct_t));
  477. if(!s){
  478. Error_Handler();
  479. }
  480. s->callback = callback;
  481. s->next = NULL;
  482. setTemperatureReachedCallbackStruct_t *last = temperatureReachedCallbacks;
  483. if(!last) {
  484. temperatureReachedCallbacks = s;
  485. return;
  486. }
  487. while(last && last->next != NULL) {
  488. last = last->next;
  489. }
  490. last->next = s;
  491. }
  492. // Adds a callback to be called when the iron working mode is changed
  493. void addModeChangedCallback(currentModeChanged callback) {
  494. currentModeChangedCallbackStruct_t *s = malloc(sizeof(currentModeChangedCallbackStruct_t));
  495. if(!s){
  496. Error_Handler();
  497. }
  498. s->callback = callback;
  499. s->next = NULL;
  500. currentModeChangedCallbackStruct_t *last = currentModeChangedCallbacks;
  501. while(last && last->next != NULL) {
  502. last = last->next;
  503. }
  504. if(last){
  505. last->next = s;
  506. }
  507. else{
  508. last = s;
  509. }
  510. }