From 51ffde94d75053805d3508dbfe89fb268fcaf183 Mon Sep 17 00:00:00 2001 From: mmi Date: Wed, 18 Oct 2017 15:26:05 +0000 Subject: [PATCH] Progress on the menu - Debounced the interlocks - Created a specified screen for pre-compliance tests ADCs must be averaged menu handling of screens is not OK destructing tasks is not OK git-svn-id: https://svn.vbchaos.nl/svn/hsb/trunk@257 05563f52-14a8-4384-a975-3d1654cca0fa --- .../0 - Code/HAL/inc/Interlock.h | 9 +- .../0 - Code/HAL/src/Interlock.c | 59 +++++- .../0 - Code/HAL/src/nhd0420.c | 4 +- .../0 - Code/Platform/inc/rtc.h | 9 +- .../0 - Code/Platform/src/oli_stm32_h107.c | 11 +- .../0 - Code/Platform/src/rtc.c | 38 +++- .../0 - Code/hsb-mrts/Makefile | 1 + .../0 - Code/hsb-mrts/inc/hsb-mrts.h | 3 + .../0 - Code/hsb-mrts/inc/repairMenu.h | 8 +- .../0 - Code/hsb-mrts/inc/repairMenus.h | 5 + .../0 - Code/hsb-mrts/inc/repairProcess.h | 65 ++++-- .../0 - Code/hsb-mrts/inc/repairProcesses.h | 69 ++++++ .../0 - Code/hsb-mrts/src/Display.c | 15 +- .../0 - Code/hsb-mrts/src/Error.c | 35 ++- .../0 - Code/hsb-mrts/src/main.c | 26 ++- .../0 - Code/hsb-mrts/src/repairMenu.c | 200 +++++++++++------- .../0 - Code/hsb-mrts/src/repairMenus.c | 24 ++- .../0 - Code/hsb-mrts/src/repairProcess.c | 127 +++++++---- .../0 - Code/hsb-mrts/src/repairProcesses.c | 116 ++++++++++ .../0 - Code/hsb-mrts/src/stm32f10x_it.c | 40 +--- 20 files changed, 649 insertions(+), 215 deletions(-) create mode 100644 S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/hsb-mrts/inc/repairProcesses.h create mode 100644 S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/hsb-mrts/src/repairProcesses.c diff --git a/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/HAL/inc/Interlock.h b/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/HAL/inc/Interlock.h index ddfd3c0..29604d8 100644 --- a/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/HAL/inc/Interlock.h +++ b/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/HAL/inc/Interlock.h @@ -34,6 +34,10 @@ #include #include "stm32f10x.h" +#include "FreeRTOS.h" +#include "task.h" +#include "semphr.h" + #include "platform.h" #include "gpio.h" @@ -66,6 +70,9 @@ struct Interlock struct InterlockElement NC; bool initialized; T_INTERLOCK_ID ID; + TaskHandle_t taskHandle; + SemaphoreHandle_t semaphore; + int waitToDebounce_ms; }; // ----------------------------------------------------------------------------- @@ -88,7 +95,7 @@ struct Interlock * @todo * ----------------------------------------------------------------------------- */ -extern ErrorStatus Interlock_construct(struct Interlock* self, T_INTERLOCK_ID ID, struct Gpio* NO, EXTI_InitTypeDef NOEXTI, struct Gpio* NC, EXTI_InitTypeDef NCEXTI); +extern ErrorStatus Interlock_construct(struct Interlock* self, T_INTERLOCK_ID ID, struct Gpio* NO, EXTI_InitTypeDef NOEXTI, struct Gpio* NC, EXTI_InitTypeDef NCEXTI, int waitToDebounce_ms); /** ---------------------------------------------------------------------------- diff --git a/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/HAL/src/Interlock.c b/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/HAL/src/Interlock.c index 2c3f50b..5bd340e 100644 --- a/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/HAL/src/Interlock.c +++ b/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/HAL/src/Interlock.c @@ -25,8 +25,14 @@ // Include files // ----------------------------------------------------------------------------- +#include "stm32f10x.h" + +#include "Error.h" + +#include "Logger.h" #include "Interlock.h" + // ----------------------------------------------------------------------------- // Constant and macro definitions // ----------------------------------------------------------------------------- @@ -48,23 +54,39 @@ // Function declarations // ----------------------------------------------------------------------------- - +static void InterlockTask (void* parameters); // ----------------------------------------------------------------------------- // Function definitions // ----------------------------------------------------------------------------- -ErrorStatus Interlock_construct(struct Interlock* self, T_INTERLOCK_ID ID, struct Gpio* NO, EXTI_InitTypeDef NOEXTI, struct Gpio* NC, EXTI_InitTypeDef NCEXTI) +ErrorStatus Interlock_construct(struct Interlock* self, T_INTERLOCK_ID ID, struct Gpio* NO, EXTI_InitTypeDef NOEXTI, struct Gpio* NC, EXTI_InitTypeDef NCEXTI, int waitToDebounce_ms) { ErrorStatus returnValue = SUCCESS; if (!self->initialized) { - self->ID = ID; - self->NO.io = NO; - self->NO.ioEXTI = NOEXTI; - self->NC.io = NC; - self->NC.ioEXTI = NCEXTI; - self->initialized = true; + vSemaphoreCreateBinary(self->semaphore); + xSemaphoreTake(self->semaphore, 0); + + BaseType_t rv = xTaskCreate(InterlockTask, (const char*)"InterlockIO", 300, self, 1, &self->taskHandle); + + if (rv != pdTRUE) + { + returnValue = ERROR; + LOGGER_ERROR(mainLog, "FAILED to start Interlock ID %d with code %d", ID, (int)rv); + } + else + { + self->ID = ID; + self->NO.io = NO; + self->NO.ioEXTI = NOEXTI; + self->NC.io = NC; + self->NC.ioEXTI = NCEXTI; + self->waitToDebounce_ms = waitToDebounce_ms; + self->initialized = true; + LOGGER_INFO(mainLog, "Interlock ID %d started", self->ID); + } + } else { @@ -115,3 +137,24 @@ void Interlock_setEXTI(struct Interlock* self, FunctionalState command) self->NC.ioEXTI.EXTI_LineCmd = command; EXTI_Init(&self->NC.ioEXTI); } + + +static void InterlockTask (void* parameters) +{ + struct Interlock* self = (struct Interlock*)parameters; + + while(1) + { + xSemaphoreTake(self->semaphore, portMAX_DELAY); + vTaskDelay(self->waitToDebounce_ms); + + if (self->ID == COMMON_INTERLOCK) + { + Error_postError(INTERLOCK_COMMON_FAIL); + } + else if (self->ID == TESLA_INTERLOCK) + { + Error_postError(INTERLOCK_TESLA_FAIL); + } + } +} diff --git a/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/HAL/src/nhd0420.c b/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/HAL/src/nhd0420.c index 12646ae..2301c7f 100644 --- a/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/HAL/src/nhd0420.c +++ b/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/HAL/src/nhd0420.c @@ -341,7 +341,9 @@ ErrorStatus NHD0420_sendCommand(const struct NHD0420* self, char command) ErrorStatus returnValue = SUCCESS; if (self->initialized) { - char buffer[NHD0420_CMD_LENGTH] = {NHD0420_CMD_PREFIX, command}; + char buffer[NHD0420_CMD_LENGTH]; + buffer[0] = NHD0420_CMD_PREFIX; + buffer[1] = command; returnValue = IODevice_write(self->device, buffer, NHD0420_CMD_LENGTH); } diff --git a/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/Platform/inc/rtc.h b/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/Platform/inc/rtc.h index 0ee0b56..e4a3399 100644 --- a/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/Platform/inc/rtc.h +++ b/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/Platform/inc/rtc.h @@ -32,7 +32,6 @@ // ----------------------------------------------------------------------------- #include "FreeRTOS.h" -#include "semphr.h" #include "stm32f10x.h" @@ -48,9 +47,15 @@ // Type definitions. // ----------------------------------------------------------------------------- +struct Time +{ + int hours; + int minutes; + int seconds; +}; + struct Rtc { - SemaphoreHandle_t secondSync; struct Observable observable; }; diff --git a/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/Platform/src/oli_stm32_h107.c b/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/Platform/src/oli_stm32_h107.c index 1809478..ee6c41a 100644 --- a/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/Platform/src/oli_stm32_h107.c +++ b/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/Platform/src/oli_stm32_h107.c @@ -81,6 +81,9 @@ #define KEYPAD_STACK_SIZE (128) #define KEYPAD_TASK_PRIORITY (3) #define KEYPAD_DEF_QUEUESIZE (32) + +// Interlock settings +#define INTERLOCK_DEBOUNCE_TIME_MS (50) // ----------------------------------------------------------------------------- // Type definitions // ----------------------------------------------------------------------------- @@ -602,7 +605,7 @@ static ErrorStatus initPeriphery(void) /* --------------------------------------------------------------------*/ /* RTC */ /* --------------------------------------------------------------------*/ - IRQ_setInterruptProperties(RTC_IRQn, 12, 12, ENABLE); + IRQ_setInterruptProperties(RTC_IRQn, 13, 0, ENABLE); RTC_construct(rtc); /* --------------------------------------------------------------------*/ @@ -702,6 +705,8 @@ static ErrorStatus initPeriphery(void) GPIO_construct(ledOrange, OUTPUT, ledOrange->gpio); // 6V5 Power Enable GPIO_construct(power6v5Enable, OUTPUT, power6v5Enable->gpio); + // powerEnable is inverted. Set to HIGH/TRUE to switch OFF + GPIO_setValue(power6v5Enable, true); IRQ_setInterruptProperties(EXTI0_IRQn, 12, 0, ENABLE); IRQ_setInterruptProperties(EXTI1_IRQn, 12, 0, ENABLE); @@ -712,7 +717,7 @@ static ErrorStatus initPeriphery(void) EXTI_InitTypeDef intNCEXTI = configureEXTI(EXTI_Line1, EXTI_Mode_Interrupt, EXTI_Trigger_Rising_Falling, DISABLE); GPIO_construct(interlockNC, INPUT, interlockNC->gpio); - Interlock_construct(interlock, COMMON_INTERLOCK, interlockNO, intNOEXTI, interlockNC, intNCEXTI); + Interlock_construct(interlock, COMMON_INTERLOCK, interlockNO, intNOEXTI, interlockNC, intNCEXTI, INTERLOCK_DEBOUNCE_TIME_MS); // Solenoid GPIO_construct(solenoid, OUTPUT, solenoid->gpio); @@ -742,7 +747,7 @@ static ErrorStatus initPeriphery(void) EXTI_InitTypeDef teslaNCEXTI = configureEXTI(EXTI_Line10, EXTI_Mode_Interrupt, EXTI_Trigger_Rising_Falling, DISABLE); GPIO_construct(teslaNC, INPUT, teslaNC->gpio); - Interlock_construct(teslalock, TESLA_INTERLOCK, teslaNO, teslaNOEXTI, teslaNC, teslaNCEXTI); + Interlock_construct(teslalock, TESLA_INTERLOCK, teslaNO, teslaNOEXTI, teslaNC, teslaNCEXTI, INTERLOCK_DEBOUNCE_TIME_MS); } return returnValue; diff --git a/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/Platform/src/rtc.c b/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/Platform/src/rtc.c index 724633b..7e15db4 100644 --- a/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/Platform/src/rtc.c +++ b/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/Platform/src/rtc.c @@ -31,6 +31,7 @@ #include "rtc.h" #include "stm32f10x_rtc.h" +#include "Logger.h" #include "Observable.h" // ----------------------------------------------------------------------------- @@ -64,15 +65,6 @@ ErrorStatus RTC_construct(struct Rtc* self) { ErrorStatus returnValue = SUCCESS; - //! Create semaphore to synchronize with RTC interrupt handler - vSemaphoreCreateBinary(self->secondSync); - // Take semaphore - if (xSemaphoreTake(self->secondSync, 0) == pdFALSE) - { - //! An error has occurred - returnValue = ERROR; - } - /* Wait for RTC registers synchronization */ RTC_WaitForSynchro(); @@ -105,3 +97,31 @@ struct Observable* RTC_getObservable(struct Rtc* self) { return &self->observable; } + + +void RTC_IRQHandler(void) +{ + static signed portBASE_TYPE higherPriorityTaskWoken = pdFALSE; + + if (RTC_GetITStatus(RTC_IT_SEC) != RESET) + { + /* Clear the RTC Second interrupt */ + RTC_ClearITPendingBit(RTC_IT_SEC); + + Observable_notifyObservers(RTC_getObservable(rtc), NULL); + /* Wait until last write operation on RTC registers has finished */ + RTC_WaitForLastTask(); + + } + + if (RTC_GetITStatus(RTC_IT_OW)) + { + // Counter overflow on next cycle pending - RESET counter to 0 + + RTC_ClearITPendingBit(RTC_IT_OW); + RTC_SetCounter(0x00); + LOGGER_WARNING_ISR(mainLog, "RTC counter overflow detected - reset system clock counter to 0"); + } + + portEND_SWITCHING_ISR(higherPriorityTaskWoken); +} diff --git a/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/hsb-mrts/Makefile b/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/hsb-mrts/Makefile index 2c6e676..0bb5a08 100644 --- a/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/hsb-mrts/Makefile +++ b/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/hsb-mrts/Makefile @@ -20,6 +20,7 @@ hwValidationMenu.o \ repairMenu.o \ repairMenus.o \ repairProcess.o \ +repairProcesses.o \ \ heap_2.o\ list.o \ diff --git a/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/hsb-mrts/inc/hsb-mrts.h b/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/hsb-mrts/inc/hsb-mrts.h index 775045d..79da3db 100644 --- a/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/hsb-mrts/inc/hsb-mrts.h +++ b/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/hsb-mrts/inc/hsb-mrts.h @@ -45,6 +45,9 @@ #define HSB_MAINDISP_TASK_PRIORITY (2) #define HSB_MAINDISP_TASK_STACKSIZE (512) +#define HSB_MAINREPR_TASK_PRIORITY (2) +#define HSB_MAINREPR_TASK_STACKSIZE (1024) + // Exports of objects on application level extern struct Display* const mainDisplay; diff --git a/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/hsb-mrts/inc/repairMenu.h b/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/hsb-mrts/inc/repairMenu.h index b2b4307..0340217 100644 --- a/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/hsb-mrts/inc/repairMenu.h +++ b/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/hsb-mrts/inc/repairMenu.h @@ -71,6 +71,7 @@ typedef enum REPAIR_RUNNING, REPAIR_ASK_PAUSE, REPAIR_PAUSE, + FINISH, ERROR_STATE, WARNING_STATE, NO_MENU, @@ -133,12 +134,13 @@ struct RepairMenu T_MenuState menuState; int cursorIndex; int scrollOffset; - struct RepairProcess repairProcess; + SemaphoreHandle_t repairScreenUpdateSemaphore; const struct RepairPreset* repairPreset; struct RepairProcessParameters rpParameters; struct MenuPage menuArray[NUMBER_OF_MENUS]; char errorMessage[20]; char warningMessage[20]; + Observer observer; }; // ----------------------------------------------------------------------------- @@ -155,14 +157,14 @@ struct RepairMenu * @param keyboardDevice * @param taskPriority * @param stackSize - * @param keyStateTrigger + * @param repairScreenUpdateObserver * * @return ErrorStatus * * @todo * ----------------------------------------------------------------------------- */ -extern ErrorStatus repairMenu_construct(struct RepairMenu* self, struct Display* display, struct KeyboardDevice* keyboardDevice, int taskPriority, uint16_t stackSize, Keypad_KeyState keyStateTrigger); +extern ErrorStatus repairMenu_construct(struct RepairMenu* self, struct Display* display, struct KeyboardDevice* keyboardDevice, int taskPriority, uint16_t stackSize, Observer repairScreenUpdateObserver); /** ---------------------------------------------------------------------------- diff --git a/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/hsb-mrts/inc/repairMenus.h b/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/hsb-mrts/inc/repairMenus.h index bf0636c..13c2b2a 100644 --- a/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/hsb-mrts/inc/repairMenus.h +++ b/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/hsb-mrts/inc/repairMenus.h @@ -74,4 +74,9 @@ extern ErrorStatus repairMenus_construct(void); extern void repairMenus_destruct(void); +extern struct RepairMenu* repairMenus_getMainRepairMenu(void); + + + + #endif /* REPAIRMENUS_H_ */ diff --git a/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/hsb-mrts/inc/repairProcess.h b/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/hsb-mrts/inc/repairProcess.h index 9f4fd46..f9c37b5 100644 --- a/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/hsb-mrts/inc/repairProcess.h +++ b/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/hsb-mrts/inc/repairProcess.h @@ -42,6 +42,9 @@ #include "PID.h" +#include "Observable.h" +#include "rtc.h" + // ----------------------------------------------------------------------------- // Constant and macro definitions // ----------------------------------------------------------------------------- @@ -74,6 +77,17 @@ struct RepairProcessParameters const struct MAX5715_DAC* dacRow3; }; +struct RepairProcessRow +{ + const struct AdcChannel* adcChannel; + uint16_t lastADCValue; + const struct MAX5715_DAC* dacChannel; + uint16_t lastDACValue; + int pidError; + struct Pid pid; + bool rowHasError; +}; + struct RepairProcess { TaskHandle_t taskHandle; @@ -87,11 +101,11 @@ struct RepairProcess uint32_t voltageHoldTimer; RepairState currentState; bool initialized; + bool isProcessRunning; size_t currentPresetIndex; - struct RepairPreset* repairPreset; - const struct AdcChannel* adc[REPAIRPROCESS_NUMBER_OF_ROWS]; - const struct MAX5715_DAC* dac[REPAIRPROCESS_NUMBER_OF_ROWS]; - struct Pid pid[REPAIRPROCESS_NUMBER_OF_ROWS]; + const struct RepairPreset* repairPreset; + struct RepairProcessRow row[REPAIRPROCESS_NUMBER_OF_ROWS]; + struct Observable observable; }; // ----------------------------------------------------------------------------- @@ -166,20 +180,45 @@ extern void repairProcess_feedSecondsCounterFromISR(struct RepairProcess* self); /** ---------------------------------------------------------------------------- - * repairProcess_getRepairTime - * Returns the current active repair time in seconds. + * repairProcess_getRemainingRepairTime + * Returns the currently remaining repair time in a struct Time * - * @param self - * @param repairTime - * @param hours - * @param minutes - * @param seconds + * @param self The repair process object * - * @return ErrorStatus + * @return struct Time The remaining repair time * * @todo * ----------------------------------------------------------------------------- */ -extern ErrorStatus repairProcess_getRepairTime(const struct RepairProcess* self, uint32_t* repairTime, int* hours, int* minutes, int* seconds); +extern struct Time repairProcess_getRemainingRepairTime(const struct RepairProcess* self); + + +/** ---------------------------------------------------------------------------- + * repairProcess_getRowInformation + * Returns the current active repair time in seconds. + * + * @param self The repair process object + * @param rowIndex Index of the requested row. Starts with 0 + * + * @return struct RepairProcessRow* The requested row object + * + * @todo + * ----------------------------------------------------------------------------- + */ +extern struct RepairProcessRow* repairProcess_getRowInformation(const struct RepairProcess* self, int rowIndex); + + +/** ---------------------------------------------------------------------------- + * repairProcess_getObservable + * Returns the observable of the repair process + * + * @param self THe repair process object + * + * @return struct Observable* The observable object + * + * @todo + * ----------------------------------------------------------------------------- + */ +extern struct Observable* repairProcess_getObservable(struct RepairProcess* self); #endif /* REPAIRPROCESS_H_ */ diff --git a/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/hsb-mrts/inc/repairProcesses.h b/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/hsb-mrts/inc/repairProcesses.h new file mode 100644 index 0000000..70c86c2 --- /dev/null +++ b/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/hsb-mrts/inc/repairProcesses.h @@ -0,0 +1,69 @@ +// ----------------------------------------------------------------------------- +/// @file repairProcesses.h +/// @brief File description +// ----------------------------------------------------------------------------- +// Micro-Key bv +// Industrieweg 28, 9804 TG Noordhorn +// Postbus 92, 9800 AB Zuidhorn +// The Netherlands +// Tel: +31 594 503020 +// Fax: +31 594 505825 +// Email: support@microkey.nl +// Web: www.microkey.nl +// ----------------------------------------------------------------------------- +/// $Revision$ +/// $Author$ +/// $Date$ +// (c) 2015 Micro-Key bv +// ----------------------------------------------------------------------------- + +/// @defgroup {group_name} {group_description} +/// Description + +/// @file repairProcesses.h +/// @ingroup {group_name} + +#ifndef REPAIRPROCESSES_H_ +#define REPAIRPROCESSES_H_ + + +// ----------------------------------------------------------------------------- +// Include files +// ----------------------------------------------------------------------------- + +#include "stm32f10x.h" + +#include "repairPreset.h" +#include "repairProcess.h" + +// ----------------------------------------------------------------------------- +// Constant and macro definitions +// ----------------------------------------------------------------------------- + + + +// ----------------------------------------------------------------------------- +// Type definitions. +// ----------------------------------------------------------------------------- + + + +// ----------------------------------------------------------------------------- +// Function declarations +// ----------------------------------------------------------------------------- + +extern ErrorStatus repairProcesses_startMainRepairProcess(const struct RepairPreset* repairPreset, struct RepairProcessParameters* rpParameters); + + +extern void repairProcesses_abortMainRepairProcess(void); + + +extern ErrorStatus repairProcesses_mainRepairProcessAddObserver (const Observer observer); + + +extern void repairProcesses_mainRepairProcessRemoveObserver (const Observer observer); + + +extern struct RepairProcess* repairProcesses_getMainRepairProcess(void); + +#endif /* REPAIRPROCESSES_H_ */ diff --git a/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/hsb-mrts/src/Display.c b/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/hsb-mrts/src/Display.c index 7fc7af1..4de23ec 100644 --- a/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/hsb-mrts/src/Display.c +++ b/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/hsb-mrts/src/Display.c @@ -124,8 +124,10 @@ void Display_destruct(struct Display* self) ErrorStatus Display_clearScreen(struct Display* self) { + ErrorStatus returnValue = SUCCESS; + returnValue = DisplayDevice_clear(self->displayDevice); Display_clearShadow(self); - return DisplayDevice_clear(self->displayDevice); + return returnValue; } @@ -284,9 +286,13 @@ inline static void Display_clearShadow(struct Display* self) { for (colCounter = 0; colCounter < self->displayDevice->parameters.numberOfColumns; colCounter++) { - buffer[colCounter] = 0x20; + // All characters of the display shadow are set to BLANK, but the isUpdated flag is kept at FALSE + // this is, because the display itself has already received a command to clear its content. So + // blanking the shadow without setting isUpdated to TRUE is only an action to update the + // shadow to the actual situation on the screen + self->displayShadow[rowCounter][colCounter].character = 0x20; + self->displayShadow[rowCounter][colCounter].isUpdated = false; } - Display_write(self, buffer, self->displayDevice->parameters.numberOfColumns, rowCounter + 1, 1); } } @@ -395,10 +401,7 @@ static void DisplayTask(void* parameters) self->refreshFeedCounter = 0; Display_characterUpdateAll(self); } - -// vTaskDelay(10); } - vTaskDelay(10); } diff --git a/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/hsb-mrts/src/Error.c b/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/hsb-mrts/src/Error.c index 80758bc..127fc89 100644 --- a/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/hsb-mrts/src/Error.c +++ b/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/hsb-mrts/src/Error.c @@ -34,25 +34,31 @@ // Constant and macro definitions // ----------------------------------------------------------------------------- +#define ERROR_QUEUE_SIZE (10) // ----------------------------------------------------------------------------- // Type definitions // ----------------------------------------------------------------------------- - +struct ErrorQueueItem +{ + T_ErrorCode errorCode; +}; // ----------------------------------------------------------------------------- // File-scope variables // ----------------------------------------------------------------------------- static struct Observable observable; +static TaskHandle_t errorTaskHandle; +static QueueHandle_t errorQueue; // ----------------------------------------------------------------------------- // Function declarations // ----------------------------------------------------------------------------- - +static void ErrorTask (void* parameters); // ----------------------------------------------------------------------------- // Function definitions @@ -63,6 +69,9 @@ ErrorStatus Error_construct(void) { Observable_construct(&observable); + errorQueue = xQueueCreate(ERROR_QUEUE_SIZE, sizeof(struct ErrorQueueItem)); + xTaskCreate(ErrorTask, "ErrorTask", 256, NULL, 1, &errorTaskHandle); + return SUCCESS; } @@ -76,7 +85,9 @@ struct Observable* Error_getObservable(void) void Error_postError(T_ErrorCode errorCode) { LOGGER_ERROR(mainLog, "ERROR POSTED WITH CODE %d", errorCode); - Observable_notifyObservers(&observable, (const void* const)errorCode); + struct ErrorQueueItem queueItem; + queueItem.errorCode = errorCode; + xQueueSend(errorQueue, &queueItem, 0); } @@ -84,6 +95,22 @@ void Error_postErrorFromISR(T_ErrorCode errorCode) { portBASE_TYPE higherPriorityTaskWoken = pdFALSE; LOGGER_ERROR_ISR(mainLog, "ERROR POSTED FROM ISR"); - Observable_notifyObservers(&observable, (const void* const)errorCode); + + struct ErrorQueueItem queueItem; + queueItem.errorCode = errorCode; + xQueueSendFromISR(errorQueue, &queueItem, &higherPriorityTaskWoken); + portEND_SWITCHING_ISR(higherPriorityTaskWoken); } + + +static void ErrorTask (void* parameters) +{ + struct ErrorQueueItem queueItem; + while (1) + { + xQueueReceive(errorQueue, &queueItem, portMAX_DELAY); + Observable_notifyObservers(&observable, (const void* const)queueItem.errorCode); + vTaskDelay(1); + } +} diff --git a/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/hsb-mrts/src/main.c b/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/hsb-mrts/src/main.c index 5933218..d08f19a 100644 --- a/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/hsb-mrts/src/main.c +++ b/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/hsb-mrts/src/main.c @@ -34,11 +34,13 @@ #include "task.h" #include "Displays.h" +#include "Error.h" #include "hsb-mrts.h" #include "hwValidationMenu.h" #include "repairMenu.h" #include "repairMenus.h" #include "repairProcess.h" +#include "repairProcesses.h" #include "misc.h" #include "stm32f10x_rcc.h" @@ -164,6 +166,18 @@ static ErrorStatus systeminfoCommandHandler(void) OS_logTaskInfo(ledTaskHandle); vTaskDelay(10); OS_logTaskInfo(sysTaskHandle); + vTaskDelay(10); + OS_logTaskInfo(interlock->taskHandle); + vTaskDelay(10); + OS_logTaskInfo(teslalock->taskHandle); + vTaskDelay(10); + OS_logTaskInfo(keypad->taskHandle); + vTaskDelay(10); + OS_logTaskInfo(mainDisplay->taskHandle); + vTaskDelay(10); + OS_logTaskInfo(repairMenus_getMainRepairMenu()->taskHandle); + vTaskDelay(10); + OS_logTaskInfo(repairProcesses_getMainRepairProcess()->taskHandle); return errorStatus; @@ -171,23 +185,25 @@ static ErrorStatus systeminfoCommandHandler(void) static void initTask(void* parameters) { + // Create the error handler + Error_construct(); + // Initialize the platform first // All IO is initialized here // Also, all periphery and platform-specifics are initialized here // IRQs are defined here initPlatform(); + // Create a small task that only blinks a LED and flashes the identification letter on the display xTaskCreate(ledBlinkTask, (const char* const)"ledTask", 100, &ledTaskArguments, 0, &ledTaskHandle); // Construct the displays Displays_construct(); -// xTaskCreate(printSystemInfoTask, (const char* const)"SysInfoTask", 512, NULL, 0, &sysTaskHandle); - hsb_generateStartScreen(mainDisplay); // Let start screen stay for 5 seconds - vTaskDelay(INIT_START_SCREEN_DELAY); +// vTaskDelay(INIT_START_SCREEN_DELAY); hwTestItems.display = &nhd0420->displayDevice; @@ -213,9 +229,11 @@ static void initTask(void* parameters) // Construct the repair menu repairMenus_construct(); - + // Disable power GPIO_setValue(power6v5Enable, false); + xTaskCreate(printSystemInfoTask, (const char* const)"SysInfoTask", 512, NULL, 0, &sysTaskHandle); + // Delete this init task vTaskDelete(NULL); } diff --git a/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/hsb-mrts/src/repairMenu.c b/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/hsb-mrts/src/repairMenu.c index dd9b41e..d10c066 100644 --- a/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/hsb-mrts/src/repairMenu.c +++ b/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/hsb-mrts/src/repairMenu.c @@ -29,6 +29,7 @@ #include "string.h" #include "repairMenu.h" #include "repairProcess.h" +#include "repairProcesses.h" #include "Display.h" #include "Error.h" @@ -41,6 +42,7 @@ #include "KeyboardDevice.h" #include "PCBA.h" +#include "rtc.h" #include "storm700.h" // ----------------------------------------------------------------------------- @@ -61,8 +63,6 @@ // File-scope variables // ----------------------------------------------------------------------------- -//TODO THIS IS UGLY -static struct RepairProcess* rp = NULL; static const char cursorValue = 0x7E; @@ -87,6 +87,9 @@ static void repairMenu_changeState(struct RepairMenu* self, T_MenuState newState static void repairMenu_printError(struct RepairMenu* self); static void repairMenu_printWarning(struct RepairMenu* self); static void repairMenu_printRepair(struct RepairMenu* self); +static void repairMenu_printAskPause(struct RepairMenu* self); +static void repairMenu_printPause(struct RepairMenu* self); +static void repairMenu_printFinish(struct RepairMenu* self); static void repairMenu_printMenu(struct RepairMenu* self); static void repairMenu_printCursor(struct RepairMenu* self); static ErrorStatus repairMenu_performAction(struct RepairMenu* self, char key, Keypad_KeyState keyState); @@ -94,13 +97,12 @@ static struct KeyActionBinding repairMenu_findKeyAction(struct RepairMenu* self, static void repairMenu_scrollIndexHandlerReset (struct RepairMenu* self); static void repairMenu_scrollUpIndexHandler(struct RepairMenu* self); static void repairMenu_scrollDownIndexHandler(struct RepairMenu* self); -static void repairMenu_startRepairProcess(struct RepairMenu* self, int cursorIndex); -static void repairMenu_abortRepairProcess(struct RepairMenu* self); -static ErrorStatus repairMenu_feedProcessSecondsCounter(const void* const data); static void repairMenu_selectPreset(struct RepairMenu* self, int cursorIndex); static void repairMenu_solenoidLock(struct RepairMenu* self, int cursorIndex); static void repairMenu_solenoidUnlock(struct RepairMenu* self, int cursorIndex); +static void repairMenu_startRepairProcess(struct RepairMenu* self, int cursorIndex); +static void repairMenu_stopRepairProcess(struct RepairMenu* self, int cursorIndex); static ErrorStatus repairMenu_createMenu(struct RepairMenu* self); static ErrorStatus repairMenu_createMenuPage (struct MenuPage* self, bool hasCursor, int maxNumberOfRows); @@ -118,7 +120,7 @@ static ErrorStatus repairMenu_addKeyAction_SCROLLDOWN (struct MenuPage* self, ch // ----------------------------------------------------------------------------- -ErrorStatus repairMenu_construct(struct RepairMenu* self, struct Display* display, struct KeyboardDevice* keyboardDevice, int taskPriority, uint16_t stackSize, Keypad_KeyState keyStateTrigger) +ErrorStatus repairMenu_construct(struct RepairMenu* self, struct Display* display, struct KeyboardDevice* keyboardDevice, int taskPriority, uint16_t stackSize, Observer repairScreenUpdateObserver) { ErrorStatus returnValue = SUCCESS; @@ -165,7 +167,10 @@ ErrorStatus repairMenu_construct(struct RepairMenu* self, struct Display* displa } else { + vSemaphoreCreateBinary(self->repairScreenUpdateSemaphore); + self->observer = repairScreenUpdateObserver; self->initialized = true; + self->repairPreset = presetArray[0]; self->cursorIndex = 1; self->scrollOffset = 0; LOGGER_INFO(mainLog, "Repair Menu task started"); @@ -183,6 +188,8 @@ ErrorStatus repairMenu_construct(struct RepairMenu* self, struct Display* displa void repairMenu_destruct (struct RepairMenu* self) { + repairProcesses_abortMainRepairProcess(); + self->runTask = false; self->initialized = false; } @@ -223,7 +230,7 @@ static void repairMenu_task(void* parameters) // Show ERROR message repairMenu_printError(self); // Handle error - repairMenu_abortRepairProcess(self); + repairMenu_stopRepairProcess(self, 0); } else if (self->menuState == WARNING_STATE) { @@ -231,8 +238,31 @@ static void repairMenu_task(void* parameters) } else if (self->menuState == REPAIR_RUNNING) { - // Create the repair screen - repairMenu_printRepair(self); + // Check the remaining repair time + struct Time remainingTime = repairProcess_getRemainingRepairTime(repairProcesses_getMainRepairProcess()); + if ((remainingTime.hours == 0) && (remainingTime.minutes == 0) && (remainingTime.seconds == 0)) + { + // repair is finished + repairMenu_changeState(self, FINISH); + } + else + { + // Create the repair screen + repairMenu_printRepair(self); + } + } + else if (self->menuState == REPAIR_ASK_PAUSE) + { + repairMenu_printAskPause(self); + } + else if (self->menuState == REPAIR_PAUSE) + { + repairMenu_printPause(self); + } + else if (self->menuState == FINISH) + { + repairMenu_stopRepairProcess(self, 0); + repairMenu_printFinish(self); } if (KeyboardDevice_read(&storm700->keyboardDevice, &key, &keyState) == SUCCESS) @@ -278,44 +308,64 @@ static void repairMenu_printWarning(struct RepairMenu* self) static void repairMenu_printRepair(struct RepairMenu* self) { - uint32_t rpSecondsCounter; - int hoursToRemain; - int minutesToRemain; - int secondsToRemain; + int loopCounter = 0; char buffer[20]; - repairProcess_getRepairTime(&self->repairProcess, &rpSecondsCounter, &hoursToRemain, &minutesToRemain, &secondsToRemain); - snprintf(buffer, sizeof(buffer) / sizeof(buffer[0]), " %02d:%02d:%02d remain", hoursToRemain, minutesToRemain, secondsToRemain); - Display_write(self->display, buffer, strlen(buffer), 2, 1); - - if (PCBA_getInstance()->pcba == Tesla) + if (xSemaphoreTake(self->repairScreenUpdateSemaphore, 0) != pdTRUE) { - Display_write(self->display, "R2", strlen("R2"), 3, 10); - uint16_t value; - ADCChannel_read(self->repairProcess.adc[1], &value); - snprintf(buffer, sizeof(buffer) / sizeof(buffer[0]), "%05dV", value); - Display_write(self->display, buffer, strlen(buffer), 4, 8); + // Taking semaphore failed - no update on the screen } - else if ((PCBA_getInstance()->pcba == Anode) || (PCBA_getInstance()->pcba == CathodeMCP)) + else { - Display_write(self->display, "R1", strlen("R1"), 3, 3); - Display_write(self->display, "R2", strlen("R2"), 3, 10); - Display_write(self->display, "R3", strlen("R3"), 3, 17); + struct Time remainingTime = repairProcess_getRemainingRepairTime(repairProcesses_getMainRepairProcess()); - uint16_t value; - ADCChannel_read(self->repairProcess.adc[0], &value); - snprintf(buffer, sizeof(buffer) / sizeof(buffer[0]), "%05dV", value); - Display_write(self->display, buffer, strlen(buffer), 4, 1); - ADCChannel_read(self->repairProcess.adc[1], &value); - snprintf(buffer, sizeof(buffer) / sizeof(buffer[0]), "%05dV", value); - Display_write(self->display, buffer, strlen(buffer), 4, 8); - ADCChannel_read(self->repairProcess.adc[2], &value); - snprintf(buffer, sizeof(buffer) / sizeof(buffer[0]), "%05dV", value); - Display_write(self->display, buffer, strlen(buffer), 4, 15); + snprintf(buffer, sizeof(buffer) / sizeof(buffer[0]), " %02d:%02d:%02d remain", remainingTime.hours, remainingTime.minutes, remainingTime.seconds); + Display_write(self->display, buffer, strlen(buffer), 1, 1); + + // Regulation is unique for each row + // For TESLA repair only row 1 (out of 0,1,2) is used + // For ANODE and Cathode/MCP, all 3 rows are used + for (loopCounter = ((PCBA_getInstance()->pcba == Tesla) ? 1 : 0); loopCounter <= ((PCBA_getInstance()->pcba == Tesla) ? 1 : 2); loopCounter++) + { + struct RepairProcessRow* row; + row = repairProcess_getRowInformation(repairProcesses_getMainRepairProcess(), loopCounter); + + snprintf (buffer, sizeof(buffer) / sizeof(buffer[0]), "R%d", loopCounter + 1); + Display_write(self->display, buffer, strlen(buffer), 2, ((loopCounter * (self->display->displayDevice->parameters.numberOfColumns / REPAIRPROCESS_NUMBER_OF_ROWS)) + (self->display->displayDevice->parameters.numberOfColumns / REPAIRPROCESS_NUMBER_OF_ROWS) / strlen(buffer))); + + snprintf(buffer, sizeof(buffer) / sizeof(buffer[0]), "%05dV", row->lastADCValue); + Display_write(self->display, buffer, strlen(buffer), 3, (loopCounter + (loopCounter * (self->display->displayDevice->parameters.numberOfColumns / REPAIRPROCESS_NUMBER_OF_ROWS)) + (self->display->displayDevice->parameters.numberOfColumns / REPAIRPROCESS_NUMBER_OF_ROWS) / strlen(buffer))); + + snprintf(buffer, sizeof(buffer) / sizeof(buffer[0]), "%04dER", row->pidError); + Display_write(self->display, buffer, strlen(buffer), 4, (loopCounter + (loopCounter * (self->display->displayDevice->parameters.numberOfColumns / REPAIRPROCESS_NUMBER_OF_ROWS)) + (self->display->displayDevice->parameters.numberOfColumns / REPAIRPROCESS_NUMBER_OF_ROWS) / strlen(buffer))); + } } } +static void repairMenu_printAskPause(struct RepairMenu* self) +{ + Display_write(self->display, "REPAIR BUSY", strlen("REPAIR BUSY"), 2, 6); + Display_write(self->display, "Hit X to RESET", strlen("Hit X to RESET"), 3, 2); +} + + +static void repairMenu_printPause(struct RepairMenu* self) +{ + Display_write(self->display, "!!PAUSE!!", strlen("!!PAUSE!!"), 2, 6); + Display_write(self->display, "Hit ENT to continue", strlen("Hit ENT to continue"), 3, 2); + Display_write(self->display, "Hit X to RESET", strlen("Hit X to RESET"), 4, 2); +} + + +static void repairMenu_printFinish(struct RepairMenu* self) +{ + Display_write(self->display, "REPAIR FINISHED", strlen("REPAIR FINISHED"), 2, 6); + Display_write(self->display, "Hit ENT to continue", strlen("Hit ENT to continue"), 4, 2); + +} + + static void repairMenu_printMenu(struct RepairMenu* self) { int loopCounter; @@ -492,6 +542,25 @@ static void repairMenu_scrollDownIndexHandler(struct RepairMenu* self) } +static void repairMenu_selectPreset(struct RepairMenu* self, int cursorIndex) +{ + self->repairPreset = presetArray[cursorIndex - 1]; + LOGGER_INFO(mainLog, "Preset %d selected", cursorIndex); +} + + +static void repairMenu_solenoidLock(struct RepairMenu* self, int cursorIndex) +{ + hsb_solenoidLock(); +} + + +static void repairMenu_solenoidUnlock(struct RepairMenu* self, int cursorIndex) +{ + hsb_solenoidUnlock(); +} + + static void repairMenu_startRepairProcess(struct RepairMenu* self, int cursorIndex) { ErrorStatus returnValue = SUCCESS; @@ -502,7 +571,6 @@ static void repairMenu_startRepairProcess(struct RepairMenu* self, int cursorInd self->rpParameters.dacRow2 = &max5715->dac[1]; self->rpParameters.dacRow3 = &max5715->dac[2]; - // First, Lock the cover if (returnValue == SUCCESS) { @@ -536,8 +604,8 @@ static void repairMenu_startRepairProcess(struct RepairMenu* self, int cursorInd } else { -// Error_postError(INTERLOCK_TESLA_FAIL); -// returnValue = ERROR; + Error_postError(INTERLOCK_TESLA_FAIL); + returnValue = ERROR; } } } @@ -546,7 +614,7 @@ static void repairMenu_startRepairProcess(struct RepairMenu* self, int cursorInd if (returnValue == SUCCESS) { // Power the circuit - if (GPIO_setValue(power6v5Enable, true) != SUCCESS) + if (GPIO_setValue(power6v5Enable, false) != SUCCESS) { Error_postError(POWERENABLE_FAIL); } @@ -561,9 +629,11 @@ static void repairMenu_startRepairProcess(struct RepairMenu* self, int cursorInd // If all is OK, start the repair process if (returnValue == SUCCESS) { - rp = &self->repairProcess; - Observable_addObserver(RTC_getObservable(rtc), repairMenu_feedProcessSecondsCounter); - returnValue = repairProcess_construct(&self->repairProcess, &self->rpParameters, self->repairPreset, 2, 1024); + returnValue = repairProcesses_startMainRepairProcess(self->repairPreset, &self->rpParameters); + } + if (returnValue == SUCCESS) + { + returnValue = repairProcesses_mainRepairProcessAddObserver(self->observer); if (returnValue == SUCCESS) { @@ -578,40 +648,10 @@ static void repairMenu_startRepairProcess(struct RepairMenu* self, int cursorInd } -static void repairMenu_abortRepairProcess(struct RepairMenu* self) +static void repairMenu_stopRepairProcess(struct RepairMenu* self, int cursorIndex) { - Interlock_setEXTI(interlock, DISABLE); - if (PCBA_getInstance()->pcba == Tesla) - { - Interlock_setEXTI(teslalock, ENABLE); - } - - repairProcess_destruct(&self->repairProcess); -} - -static ErrorStatus repairMenu_feedProcessSecondsCounter(const void* const data) -{ - repairProcess_feedSecondsCounterFromISR(rp); - return SUCCESS; -} - - -static void repairMenu_selectPreset(struct RepairMenu* self, int cursorIndex) -{ - self->repairPreset = presetArray[cursorIndex - 1]; - LOGGER_INFO(mainLog, "Preset %d selected", cursorIndex); -} - - -static void repairMenu_solenoidLock(struct RepairMenu* self, int cursorIndex) -{ - hsb_solenoidLock(); -} - - -static void repairMenu_solenoidUnlock(struct RepairMenu* self, int cursorIndex) -{ - hsb_solenoidUnlock(); + repairProcesses_mainRepairProcessRemoveObserver(self->observer); + repairProcesses_abortMainRepairProcess(); } @@ -693,11 +733,13 @@ static ErrorStatus repairMenu_createMenu(struct RepairMenu* self) repairMenu_addKeyAction_GOTOSTATE(&self->menuArray[REPAIR_ASK_PAUSE], 'X', PRESSED, REPAIR_PAUSE); repairMenu_createMenuPage(&self->menuArray[REPAIR_PAUSE], MENU_HAS_NO_CURSOR, 4); - repairMenu_addKeyAction_GOTOSTATE(&self->menuArray[REPAIR_PAUSE], 'X', PRESSED, REPAIR_PAUSE); + repairMenu_addKeyAction_GOTOSTATE(&self->menuArray[REPAIR_PAUSE], 'E', PRESSED, REPAIR_RUNNING); + + repairMenu_createMenuPage(&self->menuArray[FINISH], MENU_HAS_NO_CURSOR, 4); + repairMenu_addKeyAction_GOTOSTATE(&self->menuArray[FINISH], 'E', PRESSED, MAINMENU); repairMenu_createMenuPage(&self->menuArray[ERROR_STATE], MENU_HAS_NO_CURSOR, 4); repairMenu_addKeyAction_GOTOSTATE(&self->menuArray[ERROR_STATE], 'X', PRESSED, MAINMENU); - repairMenu_addKeyAction_GOTOSTATE(&self->menuArray[ERROR_STATE], 'E', PRESSED, REPAIR_RUNNING); return returnValue; } diff --git a/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/hsb-mrts/src/repairMenus.c b/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/hsb-mrts/src/repairMenus.c index 6e917e7..328dbbc 100644 --- a/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/hsb-mrts/src/repairMenus.c +++ b/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/hsb-mrts/src/repairMenus.c @@ -34,10 +34,10 @@ #include "repairMenu.h" #include "platform.h" -#include "storm700.h" +#include "Logger.h" #include "Observable.h" #include "rtc.h" - +#include "storm700.h" // ----------------------------------------------------------------------------- // Constant and macro definitions @@ -63,6 +63,7 @@ struct RepairMenu* const mainMenu = &_mainMenu; // ----------------------------------------------------------------------------- static ErrorStatus repairMenu_errorReceive(const void* const data); +static ErrorStatus repairMenu_freeMainMenuRepairScreenUpdateSemaphore(const void* const data); // ----------------------------------------------------------------------------- // Function definitions @@ -75,7 +76,7 @@ ErrorStatus repairMenus_construct(void) if (returnValue == SUCCESS) { // Create first repair menu - returnValue = repairMenu_construct(mainMenu, mainDisplay, &storm700->keyboardDevice, HSB_MAINMENU_TASK_PRIORITY, HSB_MAINMENU_TASK_STACKSIZE, PRESSED); + returnValue = repairMenu_construct(mainMenu, mainDisplay, &storm700->keyboardDevice, HSB_MAINMENU_TASK_PRIORITY, HSB_MAINMENU_TASK_STACKSIZE, repairMenu_freeMainMenuRepairScreenUpdateSemaphore); } if (returnValue == SUCCESS) @@ -94,6 +95,12 @@ ErrorStatus repairMenus_construct(void) } +struct RepairMenu* repairMenus_getMainRepairMenu(void) + { + return mainMenu; + } + + static ErrorStatus repairMenu_errorReceive(const void* const data) { T_ErrorCode errorCode = (T_ErrorCode)data; @@ -116,3 +123,14 @@ static ErrorStatus repairMenu_errorReceive(const void* const data) } return SUCCESS; } + + +static ErrorStatus repairMenu_freeMainMenuRepairScreenUpdateSemaphore(const void* const data) +{ + ErrorStatus returnValue = SUCCESS; + if (xSemaphoreGive(mainMenu->repairScreenUpdateSemaphore) != pdTRUE) + { + returnValue = ERROR; + } + return returnValue; +} diff --git a/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/hsb-mrts/src/repairProcess.c b/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/hsb-mrts/src/repairProcess.c index 3fa7fe6..e10c621 100644 --- a/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/hsb-mrts/src/repairProcess.c +++ b/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/hsb-mrts/src/repairProcess.c @@ -75,11 +75,7 @@ ErrorStatus repairProcess_construct(struct RepairProcess* self, struct RepairPro if (!self->initialized) { - // Create a semaphore to sync access to the display shadow - vSemaphoreCreateBinary(self->secondsSyncronisation); - xSemaphoreTake(self->secondsSyncronisation, 0); - - + self->runTask = true; BaseType_t rv = xTaskCreate(repairProcess_task, "RepairProcess", stackSize, self, taskPriority, &self->taskHandle); if (rv != pdTRUE) { @@ -88,26 +84,45 @@ ErrorStatus repairProcess_construct(struct RepairProcess* self, struct RepairPro if (returnValue == SUCCESS) { - self->runTask = true; + // Create a semaphore to sync access to the display shadow + vSemaphoreCreateBinary(self->secondsSyncronisation); + xSemaphoreTake(self->secondsSyncronisation, 0); + + Observable_construct(&self->observable); + self->initialized = true; + self->isProcessRunning = false; self->repairPreset = preset; self->currentState = PREPARE; - self->adc[0] = parameters->adcRow1; - self->adc[1] = parameters->adcRow2; - self->adc[2] = parameters->adcRow3; - self->dac[0] = parameters->dacRow1; - self->dac[1] = parameters->dacRow2; - self->dac[2] = parameters->dacRow3; - self->pid[0].initialized = false; - self->pid[1].initialized = false; - self->pid[2].initialized = false; + self->row[0].adcChannel = parameters->adcRow1; + self->row[1].adcChannel = parameters->adcRow2; + self->row[2].adcChannel = parameters->adcRow3; + self->row[0].lastADCValue = 0; + self->row[1].lastADCValue = 0; + self->row[2].lastADCValue = 0; - PID_construct(&self->pid[0], 3000, 2000, 0, 0, 10000000); - PID_construct(&self->pid[1], 3000, 2000, 0, 0, 10000000); - PID_construct(&self->pid[2], 3000, 2000, 0, 0, 10000000); + self->row[0].dacChannel = parameters->dacRow1; + self->row[1].dacChannel = parameters->dacRow2; + self->row[2].dacChannel = parameters->dacRow3; + + self->row[0].lastDACValue = 0; + self->row[1].lastDACValue = 0; + self->row[2].lastDACValue = 0; + + self->row[0].pid.initialized = false; + self->row[1].pid.initialized = false; + self->row[2].pid.initialized = false; + + self->row[0].rowHasError = false; + self->row[1].rowHasError = false; + self->row[2].rowHasError = false; + + PID_construct(&self->row[0].pid, 3000, 2000, 0, 0, 100000000); + PID_construct(&self->row[1].pid, 3000, 2000, 0, 0, 100000000); + PID_construct(&self->row[2].pid, 3000, 2000, 0, 0, 100000000); LOGGER_INFO(mainLog, "Repair Process task started"); } @@ -128,7 +143,8 @@ ErrorStatus repairProcess_construct(struct RepairProcess* self, struct RepairPro void repairProcess_destruct(struct RepairProcess* self) { self->runTask = false; - self->initialized = false; +// Observable_destruct(&self->observable); +// self->initialized = false; } @@ -153,43 +169,61 @@ void repairProcess_feedSecondsCounterFromISR(struct RepairProcess* self) } -ErrorStatus repairProcess_getRepairTime(const struct RepairProcess* self, uint32_t* repairTime, int* hours, int* minutes, int* seconds) +struct Time repairProcess_getRemainingRepairTime(const struct RepairProcess* self) { - ErrorStatus returnValue = SUCCESS; + struct Time returnValue; - if (self->initialized) + if ((self->initialized) && (self->isProcessRunning)) { - *repairTime = self->secondsCounter; - uint32_t timeToRemain = self->voltageHoldTimer - self->secondsCounter; - *hours = (timeToRemain / (60 * 60)); - *minutes = (timeToRemain - (*hours * 60 * 60)) / 60; - *seconds = (timeToRemain - (*hours * 60 * 60) - (*minutes * 60)); + if (timeToRemain > 0) + { + returnValue.hours = (timeToRemain / (60 * 60)); + returnValue.minutes = (timeToRemain - (returnValue.hours * 60 * 60)) / 60; + returnValue.seconds = (timeToRemain - (returnValue.hours * 60 * 60) - (returnValue.minutes * 60)); + } + else + { + // Prevent underflows + returnValue.hours = 0; + returnValue.minutes = 0; + returnValue.seconds = 0; + } } else { - returnValue = ERROR; + returnValue.hours = 99; + returnValue.minutes = 99; + returnValue.seconds = 99; } - return returnValue; } +struct RepairProcessRow* repairProcess_getRowInformation(const struct RepairProcess* self, int rowIndex) +{ + return &self->row[rowIndex]; +} + + +struct Observable* repairProcess_getObservable(struct RepairProcess* self) +{ + return &self->observable; +} + + static void repairProcess_task(void* parameters) { struct RepairProcess* self = (struct RepairProcess*)parameters; int signal; - uint16_t adcValue; - int error; - int pid; int loopCounter; // Reset the seconds counter to 0 self->secondsCounter = 0; - MAX5715Channel_setValue(self->dac[0], 0); - MAX5715Channel_setValue(self->dac[1], 0); - MAX5715Channel_setValue(self->dac[2], 0); + MAX5715Channel_setValue(self->row[0].dacChannel, self->row[0].lastDACValue); + MAX5715Channel_setValue(self->row[1].dacChannel, self->row[0].lastDACValue); + MAX5715Channel_setValue(self->row[2].dacChannel, self->row[0].lastDACValue); while(self->runTask) { @@ -210,28 +244,30 @@ static void repairProcess_task(void* parameters) for (loopCounter = ((PCBA_getInstance()->pcba == Tesla) ? 1 : 0); loopCounter <= ((PCBA_getInstance()->pcba == Tesla) ? 1 : 2); loopCounter++) { // Read the last ADC channel value - ADCChannel_read(self->adc[loopCounter], &adcValue); + ADCChannel_read(self->row[loopCounter].adcChannel, &self->row[loopCounter].lastADCValue); // Calculate the error - error = signal - (int)adcValue; + self->row[loopCounter].pidError = signal - (int)self->row[loopCounter].lastADCValue; // Calculate the PID - pid = PID_calculate(&self->pid[loopCounter], error); + self->row[loopCounter].lastDACValue = PID_calculate(&self->row[loopCounter].pid, self->row[loopCounter].pidError); ///TODO MUST BE MOVED TO DACDevice // Verify that pid value does not overflow the DAC - if (pid > 0xFFF) + if (self->row[loopCounter].lastDACValue > 0xFFF) { - pid = 0xFFF; + self->row[loopCounter].lastDACValue = 0xFFF; } - else if (pid < 0) + else if (self->row[loopCounter].lastDACValue < 0) { - pid = 0; + self->row[loopCounter].lastDACValue = 0; } // Send the PID value to the DAC - MAX5715Channel_setValue(self->dac[loopCounter], pid); + MAX5715Channel_setValue(self->row[loopCounter].dacChannel, self->row[loopCounter].lastDACValue); - LOGGER_DEBUG(mainLog, "Row %d --- ADC: %d Error: %d PID: %d", loopCounter, adcValue, error, pid); + LOGGER_DEBUG(mainLog, "Row %d --- ADC: %d Error: %d PID: %d", loopCounter, self->row[loopCounter].lastADCValue, self->row[loopCounter].pidError, self->row[loopCounter].lastDACValue); } } + // Notify observers that an update is available + Observable_notifyObservers(&self->observable, NULL); self->secondsCounter++; } @@ -263,6 +299,8 @@ static int SignalProfileGenerator(struct RepairProcess* self) } case SOFTSTART: { + self->isProcessRunning = true; + // Still in Softstart int startVoltage = 0; @@ -328,6 +366,7 @@ static int SignalProfileGenerator(struct RepairProcess* self) } case FINISHED: { + self->isProcessRunning = false; returnValue = 0; break; } diff --git a/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/hsb-mrts/src/repairProcesses.c b/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/hsb-mrts/src/repairProcesses.c new file mode 100644 index 0000000..258533e --- /dev/null +++ b/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/hsb-mrts/src/repairProcesses.c @@ -0,0 +1,116 @@ +// ----------------------------------------------------------------------------- +/// @file repairProcesses.c +/// @brief Description +// ----------------------------------------------------------------------------- +// Micro-Key bv +// Industrieweg 28, 9804 TG Noordhorn +// Postbus 92, 9800 AB Zuidhorn +// The Netherlands +// Tel: +31 594 503020 +// Fax: +31 594 505825 +// Email: support@microkey.nl +// Web: www.microkey.nl +// ----------------------------------------------------------------------------- +/// $Revision$ +/// $Author$ +/// $Date$ +// (c) 2017 Micro-Key bv +// ----------------------------------------------------------------------------- + +/// @file repairProcesses.c +/// @ingroup {group_name} + + +// ----------------------------------------------------------------------------- +// Include files +// ----------------------------------------------------------------------------- + +#include "hsb-mrts.h" +#include "repairProcesses.h" + +#include "Interlock.h" +#include "Logger.h" +#include "PCBA.h" +#include "rtc.h" + +// ----------------------------------------------------------------------------- +// Constant and macro definitions +// ----------------------------------------------------------------------------- + + + +// ----------------------------------------------------------------------------- +// Type definitions +// ----------------------------------------------------------------------------- + + + +// ----------------------------------------------------------------------------- +// File-scope variables +// ----------------------------------------------------------------------------- + +static struct RepairProcess mainRepairProcess; + +// ----------------------------------------------------------------------------- +// Function declarations +// ----------------------------------------------------------------------------- + +static ErrorStatus repairProcesses_feedMainRepairProcessSecondsCounter(const void* const data); + +// ----------------------------------------------------------------------------- +// Function definitions +// ----------------------------------------------------------------------------- + +ErrorStatus repairProcesses_startMainRepairProcess(const struct RepairPreset* repairPreset, struct RepairProcessParameters* rpParameters) +{ + ErrorStatus returnValue = SUCCESS; + if (returnValue == SUCCESS) + { + returnValue = repairProcess_construct(&mainRepairProcess, rpParameters, repairPreset, HSB_MAINREPR_TASK_PRIORITY, HSB_MAINREPR_TASK_STACKSIZE); + } + if (returnValue == SUCCESS) + { + returnValue = Observable_addObserver(RTC_getObservable(rtc), repairProcesses_feedMainRepairProcessSecondsCounter); + } + return returnValue; +} + + +void repairProcesses_abortMainRepairProcess(void) +{ + Interlock_setEXTI(interlock, DISABLE); + if (PCBA_getInstance()->pcba == Tesla) + { + Interlock_setEXTI(teslalock, DISABLE); + } + + // DISABLE external power + GPIO_setValue(power6v5Enable, true); + + repairProcess_destruct(&mainRepairProcess); +} + + +static ErrorStatus repairProcesses_feedMainRepairProcessSecondsCounter(const void* const data) +{ + repairProcess_feedSecondsCounterFromISR(&mainRepairProcess); + return SUCCESS; +} + + +ErrorStatus repairProcesses_mainRepairProcessAddObserver (const Observer observer) +{ + return Observable_addObserver(&mainRepairProcess.observable, observer); +} + + +void repairProcesses_mainRepairProcessRemoveObserver (const Observer observer) +{ + Observable_deleteObserver(&mainRepairProcess.observable, observer); +} + + +struct RepairProcess* repairProcesses_getMainRepairProcess(void) +{ + return &mainRepairProcess; +} diff --git a/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/hsb-mrts/src/stm32f10x_it.c b/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/hsb-mrts/src/stm32f10x_it.c index a33bccb..267d0c6 100644 --- a/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/hsb-mrts/src/stm32f10x_it.c +++ b/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/hsb-mrts/src/stm32f10x_it.c @@ -237,8 +237,8 @@ void EXTI0_IRQHandler(void) { static signed portBASE_TYPE higherPriorityTaskWoken = pdFALSE; + xSemaphoreGiveFromISR(interlock->semaphore, &higherPriorityTaskWoken); EXTI_ClearITPendingBit(EXTI_Line0); - Error_postErrorFromISR(INTERLOCK_COMMON_FAIL); portEND_SWITCHING_ISR(higherPriorityTaskWoken); } @@ -248,8 +248,8 @@ void EXTI1_IRQHandler(void) { static signed portBASE_TYPE higherPriorityTaskWoken = pdFALSE; + xSemaphoreGiveFromISR(interlock->semaphore, &higherPriorityTaskWoken); EXTI_ClearITPendingBit(EXTI_Line1); - Error_postErrorFromISR(INTERLOCK_COMMON_FAIL); portEND_SWITCHING_ISR(higherPriorityTaskWoken); } @@ -295,7 +295,8 @@ void EXTI9_5_IRQHandler (void) else if (EXTI_GetITStatus(EXTI_Line9) != RESET) { EXTI_ClearITPendingBit(EXTI_Line9); - Error_postErrorFromISR(INTERLOCK_TESLA_FAIL); + + xSemaphoreGiveFromISR(teslalock->semaphore, &higherPriorityTaskWoken); } portEND_SWITCHING_ISR(higherPriorityTaskWoken); @@ -309,7 +310,7 @@ void EXTI15_10_IRQHandler (void) if (EXTI_GetITStatus(EXTI_Line10) != RESET) { EXTI_ClearITPendingBit(EXTI_Line10); - Error_postErrorFromISR(INTERLOCK_TESLA_FAIL); + xSemaphoreGiveFromISR(teslalock->semaphore, &higherPriorityTaskWoken); } else if (EXTI_GetITStatus(EXTI_Line11) != RESET) { @@ -335,34 +336,3 @@ void EXTI15_10_IRQHandler (void) portEND_SWITCHING_ISR(higherPriorityTaskWoken); } - - -void RTC_IRQHandler(void) -{ - static signed portBASE_TYPE higherPriorityTaskWoken = pdFALSE; - - if (RTC_GetITStatus(RTC_IT_SEC) != RESET) - { - /* Clear the RTC Second interrupt */ - RTC_ClearITPendingBit(RTC_IT_SEC); - - xSemaphoreGiveFromISR(rtc->secondSync, &higherPriorityTaskWoken); - - Observable_notifyObservers(RTC_getObservable(rtc), NULL); - - - /* Wait until last write operation on RTC registers has finished */ - RTC_WaitForLastTask(); - } - - if (RTC_GetITStatus(RTC_IT_OW)) - { - // Counter overflow on next cycle pending - RESET counter to 0 - - RTC_ClearITPendingBit(RTC_IT_OW); - RTC_SetCounter(0x00); - LOGGER_WARNING_ISR(mainLog, "RTC counter overflow detected - reset system clock counter to 0"); - } - - portEND_SWITCHING_ISR(higherPriorityTaskWoken); -}