Files
hsb/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/hsb-mrts/src/repairMenu.c
mmi 4901cb1a09 Updated memory storage functionality
- cachedStorage is functional
- Presets can be loaded from FLASH
- CRC32 added and applied
- Presets with corrputed data will be replaced by default preset

Next: Preset update functionality from menu 

git-svn-id: https://svn.vbchaos.nl/svn/hsb/trunk@269 05563f52-14a8-4384-a975-3d1654cca0fa
2017-11-02 12:58:27 +00:00

1080 lines
41 KiB
C

// -----------------------------------------------------------------------------
/// @file repairMenu.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 repairMenu.c
/// @ingroup {group_name}
// -----------------------------------------------------------------------------
// Include files
// -----------------------------------------------------------------------------
#include "stdio.h"
#include "string.h"
#include "repairMenu.h"
#include "RepairPreset.h"
#include "repairProcess.h"
#include "repairProcesses.h"
#include "ADConverters.h"
#include "CathodeMCP.h"
#include "DAConverters.h"
#include "Display.h"
#include "Error.h"
#include "hsb-mrts.h"
#include "CoverSolenoid.h"
#include "Logger.h"
#include "Interlock.h"
#include "internalADC.h"
#include "MAX5715.h"
#include "TeslaGunSafety.h"
#include "KeyboardDevice.h"
#include "PCBA.h"
#include "rtc.h"
#include "storm700.h"
// -----------------------------------------------------------------------------
// Constant and macro definitions
// -----------------------------------------------------------------------------
#define MENU_HAS_CURSOR (true)
#define MENU_HAS_NO_CURSOR (false)
#define REPAIRMENU_POPUPSCREEN_TIME (3)
// -----------------------------------------------------------------------------
// Type definitions
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// File-scope variables
// -----------------------------------------------------------------------------
static const char cursorValue[2] = {0x7E, '\0'};
// -----------------------------------------------------------------------------
// Function declarations
// -----------------------------------------------------------------------------
static void repairMenu_task(void* parameters);
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_printPreset(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);
static struct KeyActionBinding repairMenu_findKeyAction(struct RepairMenu* self, char key, Keypad_KeyState keyState);
static void repairMenu_scrollIndexHandlerReset (struct RepairMenu* self);
static void repairMenu_scrollUpIndexHandler(struct RepairMenu* self);
static void repairMenu_scrollDownIndexHandler(struct RepairMenu* self);
static void repairMenu_selectCathodeRepair(struct RepairMenu* self, int cursorIndex);
static void repairMenu_selectMCPRepair(struct RepairMenu* self, int cursorIndex);
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 void repairMenu_abortRepairProcessAndGotoMainMenu(struct RepairMenu* self, int cursorIndex);
static void repairMenu_pauseRepairProcess(struct RepairMenu* self, int cursorIndex);
static void repairMenu_continueRepairProcess(struct RepairMenu* self, int cursorIndex);
static ErrorStatus repairMenu_createMenu(struct RepairMenu* self);
static ErrorStatus repairMenu_createMenuPage (struct MenuPage* self, bool hasCursor, int maxNumberOfRows);
static ErrorStatus repairMenu_addMenuPageRow (struct MenuPage* self, char* text, int newState, RepairMenuFunctionCall actionCall);
static ErrorStatus repairMenu_addKeyAction_HOTKEYSELECT (struct MenuPage* self, char key, Keypad_KeyState keyState, int rowToSelect);
static ErrorStatus repairMenu_addKeyAction_SELECT (struct MenuPage* self, char key, Keypad_KeyState keyState);
static ErrorStatus repairMenu_addKeyAction_GOTOSTATE (struct MenuPage* self, char key, Keypad_KeyState keyState, T_MenuState state);
static ErrorStatus repairMenu_addKeyAction_EXECUTEFUNCTION (struct MenuPage* self, char key, Keypad_KeyState keyState, RepairMenuFunctionCall actionPointer);
static ErrorStatus repairMenu_addKeyAction_SCROLLUP (struct MenuPage* self, char key, Keypad_KeyState keyState);
static ErrorStatus repairMenu_addKeyAction_SCROLLDOWN (struct MenuPage* self, char key, Keypad_KeyState keyState);
// -----------------------------------------------------------------------------
// Function definitions
// -----------------------------------------------------------------------------
ErrorStatus repairMenu_construct(struct RepairMenu* self, struct Display* display, struct KeyboardDevice* keyboardDevice, struct MemoryDevice* memoryDevice, int taskPriority, uint16_t stackSize, Observer repairScreenUpdateObserver)
{
ErrorStatus returnValue = SUCCESS;
if (!self->initialized)
{
if (returnValue == SUCCESS)
{
if (display->initialized)
{
self->display = display;
}
else
{
returnValue = ERROR;
}
}
if (returnValue == SUCCESS)
{
if (keyboardDevice->initialized)
{
self->keyboardDevice = keyboardDevice;
}
else
{
returnValue = ERROR;
}
}
if (returnValue == SUCCESS)
{
if (memoryDevice->initialized)
{
self->memoryDevice = memoryDevice;
self->presetStorage.initialized = false;
}
else
{
returnValue = ERROR;
}
}
if (returnValue == SUCCESS)
{
if (PCBA_getInstance()->pcba == PCBA_CathodeMCP)
{
// Loading of presets is done when selecting either Cathode or MCP repair
}
else if (PCBA_getInstance()->pcba == PCBA_Anode)
{
RepairPresets_loadPresets(REPAIR_PRESETS_ANODE);
self->repairPreset = RepairPresets_getPreset(1);
}
else if (PCBA_getInstance()->pcba == PCBA_Tesla)
{
RepairPresets_loadPresets(REPAIR_PRESETS_TESLA);
self->repairPreset = RepairPresets_getPreset(1);
}
// Construct the menu based on PCBA information
returnValue = repairMenu_createMenu(self);
repairMenu_changeState(self, MAINMENU);
self->runTask = true;
BaseType_t rv = xTaskCreate(repairMenu_task, "RepairMenu", stackSize, self, taskPriority, &self->taskHandle);
if (rv != pdTRUE)
{
returnValue = ERROR;
LOGGER_ERROR(mainLog, "FAILED to start repair Menu with code %d", (int)rv);
}
else
{
vSemaphoreCreateBinary(self->repairScreenUpdateSemaphore);
self->observer = repairScreenUpdateObserver;
self->initialized = true;
self->cursorIndex = 1;
self->scrollOffset = 0;
LOGGER_INFO(mainLog, "Repair Menu task started");
}
}
}
else
{
returnValue = ERROR;
}
return returnValue;
}
void repairMenu_destruct (struct RepairMenu* self)
{
repairProcesses_abortMainRepairProcess();
self->runTask = false;
self->initialized = false;
}
void repairMenu_interlockFailed(struct RepairMenu* self, T_INTERLOCK_ID interlockID)
{
repairMenu_changeState(self, ERROR_STATE);
if (interlockID == COMMON_INTERLOCK)
{
snprintf(self->errorMessage, sizeof(self->errorMessage) / sizeof(self->errorMessage[0]), "COVER OPEN");
}
}
void repairMenu_processFailed(struct RepairMenu* self)
{
repairMenu_changeState(self, ERROR_STATE);
snprintf(self->errorMessage, sizeof(self->errorMessage) / sizeof(self->errorMessage[0]), "PROCESS FAILED");
}
static void repairMenu_task(void* parameters)
{
struct RepairMenu* self = (struct RepairMenu*)parameters;
// Clear the screen for a new menu
Display_clearScreen(self->display);
// Print menu content to output device
repairMenu_printMenu(self);
// Add cursor if necessary
repairMenu_printCursor(self);
int tempScreenCounter = 0;
T_MenuState tempMenuState = MAINMENU;
while(self->runTask)
{
char key;
Keypad_KeyState keyState;
// Catch ERROR state
if (self->menuState == ERROR_STATE)
{
// Show ERROR message
repairMenu_printError(self);
// Handle error
repairMenu_stopRepairProcess(self, 0);
}
else if (self->menuState == WARNING_STATE)
{
}
else if (self->menuState == RM_PRESET_PRINT)
{
repairMenu_printPreset(self);
}
else if (self->menuState == REPAIR_RUNNING)
{
// Check the remaining repair time
uint32_t remainingTime = repairProcess_getRemainingRepairTime(repairProcesses_getMainRepairProcess());
if (remainingTime > REPAIRMENU_POPUPSCREEN_TIME)
{
tempScreenCounter = remainingTime - REPAIRMENU_POPUPSCREEN_TIME;
tempMenuState = self->menuState;
}
if (remainingTime == 0)
{
// repair is finished
repairMenu_changeState(self, FINISH_CONTROL);
}
else
{
// Create the repair screen
repairMenu_printRepair(self);
}
}
else if (self->menuState == REPAIR_ASK_PAUSE)
{
uint32_t remainingTime = repairProcess_getRemainingRepairTime(repairProcesses_getMainRepairProcess());
repairMenu_printAskPause(self);
if (tempScreenCounter >= remainingTime)
{
// POPUP screen time is over, return to previous state
repairMenu_changeState(self, tempMenuState);
}
}
else if (self->menuState == REPAIR_PAUSE)
{
repairMenu_printPause(self);
}
else if (self->menuState == FINISH_CONTROL)
{
repairMenu_stopRepairProcess(self, 0);
repairMenu_changeState(self, FINISH);
}
else if (self->menuState == FINISH)
{
repairMenu_printFinish(self);
}
if (KeyboardDevice_read(&storm700->keyboardDevice, &key, &keyState) == SUCCESS)
{
if (repairMenu_performAction(self, key, keyState) == SUCCESS)
{
// The key had an action
// Clear the screen for a new menu
Display_clearScreen(self->display);
// Print menu content to output device
repairMenu_printMenu(self);
// Add cursor if necessary
repairMenu_printCursor(self);
}
}
vTaskDelay(50);
}
LOGGER_INFO(mainLog, "Deleting RepairMenu task");
vTaskDelete(NULL);
}
static void repairMenu_changeState(struct RepairMenu* self, T_MenuState newState)
{
Display_clearScreen(self->display);
self->menuState = newState;
LOGGER_WARNING(mainLog, "New menu index is %d", self->menuState);
}
static void repairMenu_printError(struct RepairMenu* self)
{
Display_write(self->display, "!!ERROR!!", 2, 6);
Display_write(self->display, self->errorMessage, 3, 1 + ((self->display->displayDevice->parameters.numberOfColumns - strlen(self->errorMessage)) / 2));
}
static void repairMenu_printWarning(struct RepairMenu* self)
{
}
static void repairMenu_printRepair(struct RepairMenu* self)
{
int loopCounter = 0;
char buffer[20];
struct RepairProcess* repairProcess = repairProcesses_getMainRepairProcess();
if (repairProcess_isProcessRunning(repairProcess))
{
if (xSemaphoreTake(self->repairScreenUpdateSemaphore, 0) != pdTRUE)
{
// Taking semaphore failed - no update on the screen
}
else
{
struct Time remainingTime;
RTC_calculateTimeFromSeconds(repairProcess_getRemainingRepairTime(repairProcess), &remainingTime);
snprintf(buffer, sizeof(buffer) / sizeof(buffer[0]), "%1d", self->repairPreset->presetNumber);
Display_write(self->display, buffer, 1, 1);
snprintf(buffer, sizeof(buffer) / sizeof(buffer[0]), "%02d:%02d:%02d remain ", remainingTime.hours, remainingTime.minutes, remainingTime.seconds);
Display_write(self->display, buffer, 1, 4);
// 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 == PCBA_Tesla) ? 1 : 0); loopCounter <= ((PCBA_getInstance()->pcba == PCBA_Tesla) ? 1 : 2); loopCounter++)
{
const struct RepairProcessRow* row;
row = repairProcess_getRowInformation(repairProcess, loopCounter);
snprintf (buffer, sizeof(buffer) / sizeof(buffer[0]), "R%d", loopCounter + 1);
Display_write(self->display, buffer, 2, ((loopCounter * (self->display->displayDevice->parameters.numberOfColumns / REPAIRPROCESS_NUMBER_OF_ROWS) + loopCounter) + (self->display->displayDevice->parameters.numberOfColumns / REPAIRPROCESS_NUMBER_OF_ROWS) / strlen(buffer)));
if (!row->errorData.rowHasError)
{
snprintf(buffer, sizeof(buffer) / sizeof(buffer[0]), "%5dV", row->lastADCValue);
Display_write(self->display, 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]), "%4dER", row->pidError);
Display_write(self->display, buffer, 4, (loopCounter + (loopCounter * (self->display->displayDevice->parameters.numberOfColumns / REPAIRPROCESS_NUMBER_OF_ROWS)) + (self->display->displayDevice->parameters.numberOfColumns / REPAIRPROCESS_NUMBER_OF_ROWS) / strlen(buffer)));
}
else
{
snprintf(buffer, sizeof(buffer) / sizeof(buffer[0]), " ROW ");
Display_write(self->display, 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]), "ERROR ");
Display_write(self->display, buffer, 4, (loopCounter + (loopCounter * (self->display->displayDevice->parameters.numberOfColumns / REPAIRPROCESS_NUMBER_OF_ROWS)) + (self->display->displayDevice->parameters.numberOfColumns / REPAIRPROCESS_NUMBER_OF_ROWS) / strlen(buffer)));
}
}
}
}
else
{
snprintf(buffer, sizeof(buffer) / sizeof(buffer[0]), "Initialising");
Display_write(self->display, buffer, 1, 6);
}
}
static void repairMenu_printAskPause(struct RepairMenu* self)
{
Display_write(self->display, "REPAIR BUSY", 2, 6);
Display_write(self->display, "Hit X to PAUSE", 3, 2);
}
static void repairMenu_printPause(struct RepairMenu* self)
{
Display_write(self->display, "!!PAUSE!!", 2, 6);
Display_write(self->display, "Hit ENT to continue", 3, 2);
Display_write(self->display, "Hit X to RESET", 4, 2);
}
static void repairMenu_printFinish(struct RepairMenu* self)
{
Display_write(self->display, "REPAIR FINISHED", 2, 6);
Display_write(self->display, "Hit ENT to continue", 4, 2);
}
static void repairMenu_printPreset(struct RepairMenu* self)
{
int loopCounter;
char buffer[self->display->displayDevice->parameters.numberOfColumns];
// Print the preset information of the current preset under the cursor, NOT the preset that is currently selected
snprintf(buffer, sizeof(buffer) / sizeof(buffer[0]), "Preset %d info", self->cursorIndex);
// Always print Row1 (index0), ignoring the scrolling index
Display_write(self->display, buffer, 1, 1);
snprintf(buffer, sizeof(buffer) / sizeof(buffer[0]), "Start:");
Display_write(self->display, buffer, 2, 1);
snprintf(buffer, sizeof(buffer) / sizeof(buffer[0]), "Time:");
Display_write(self->display, buffer, 3, 1);
snprintf(buffer, sizeof(buffer) / sizeof(buffer[0]), "Volt:");
Display_write(self->display, buffer, 4, 1);
for (loopCounter = 0; loopCounter < RepairPresets_getPreset(self->cursorIndex)->numberOfStages; loopCounter++)
{
snprintf(buffer, sizeof(buffer) / sizeof(buffer[0]), "%5dm", (RepairPresets_getPreset(self->cursorIndex)->preset[loopCounter].softstartDuration / 60));
Display_write(self->display, buffer, 2, 8 + loopCounter * 7);
snprintf(buffer, sizeof(buffer) / sizeof(buffer[0]), "%5dm", (RepairPresets_getPreset(self->cursorIndex)->preset[loopCounter].duration / 60));
Display_write(self->display, buffer, 3, 8 + loopCounter * 7);
snprintf(buffer, sizeof(buffer) / sizeof(buffer[0]), "%5dV", RepairPresets_getPreset(self->cursorIndex)->preset[loopCounter].voltage);
Display_write(self->display, buffer, 4, 8 + loopCounter * 7);
}
}
static void repairMenu_printMenu(struct RepairMenu* self)
{
int loopCounter;
// Always print Row1 (index0), ignoring the scrolling index
Display_write(self->display, self->menuArray[self->menuState].row[0].text, 1, 1);
for (loopCounter = 1 ; loopCounter < self->display->displayDevice->parameters.numberOfRows; loopCounter++)
{
Display_write(self->display, self->menuArray[self->menuState].row[loopCounter + self->scrollOffset].text, loopCounter + 1, 1);
}
}
static void repairMenu_printCursor(struct RepairMenu* self)
{
if (self->menuArray[self->menuState].hasCursor)
{
Display_write(self->display, cursorValue, 1 + self->cursorIndex - self->scrollOffset, 1);
}
}
static ErrorStatus repairMenu_performAction(struct RepairMenu* self, char key, Keypad_KeyState keyState)
{
ErrorStatus returnValue = SUCCESS;
struct KeyActionBinding keyAction = repairMenu_findKeyAction(self, key, keyState);
LOGGER_DEBUG(mainLog, "Action: received key %c, action to perform %d,", key, keyAction.action);
switch (keyAction.action)
{
case NO_ACTION:
{
LOGGER_INFO(mainLog, "This button has no action");
returnValue = ERROR;
break;
}
case HOTKEY_SELECT:
{
LOGGER_INFO(mainLog, "HOTKEY SELECT ITEM: char %c, argument %d - Going to state %d", keyAction.key, keyAction.argument, self->menuArray[self->menuState].row[keyAction.argument].newState);
T_MenuState tempState = self->menuState;
repairMenu_changeState(self, self->menuArray[self->menuState].row[keyAction.argument].newState);
if (self->menuArray[tempState].row[keyAction.argument].actionPointer != NULL)
{
self->menuArray[tempState].row[keyAction.argument].actionPointer(self, keyAction.argument);
}
repairMenu_scrollIndexHandlerReset(self);
break;
}
case SELECT:
{
LOGGER_INFO(mainLog, "SELECT ITEM %d - going to state %d", self->cursorIndex, self->menuArray[self->menuState].row[self->cursorIndex].newState);
T_MenuState tempState = self->menuState;
repairMenu_changeState(self, self->menuArray[self->menuState].row[self->cursorIndex].newState);
if (self->menuArray[tempState].row[self->cursorIndex].actionPointer != NULL)
{
self->menuArray[tempState].row[self->cursorIndex].actionPointer(self, self->cursorIndex);
}
repairMenu_scrollIndexHandlerReset(self);
break;
}
case GOTO_STATE:
{
LOGGER_INFO(mainLog, "Going to new state %d directly", keyAction.argument);
repairMenu_changeState(self, keyAction.argument);
break;
}
case EXECUTE_FUNCTION:
{
LOGGER_INFO(mainLog, "Executing function directly");
if (keyAction.actionPointer != NULL)
{
keyAction.actionPointer(self, 0);
}
break;
}
case SCROLL_UP:
{
LOGGER_INFO(mainLog, "Scrolling up");
repairMenu_scrollUpIndexHandler(self);
break;
}
case SCROLL_DOWN:
{
LOGGER_INFO(mainLog, "Scrolling down");
repairMenu_scrollDownIndexHandler(self);
break;
}
case DIGIT_INSERT:
{
LOGGER_INFO(mainLog, "Key is allowed as insert");
break;
}
}
return returnValue;
}
static struct KeyActionBinding repairMenu_findKeyAction(struct RepairMenu* self, char key, Keypad_KeyState keyState)
{
int loopCounter;
struct KeyActionBinding returnValue;
returnValue.action = NO_ACTION;
for (loopCounter = 0; loopCounter < REPAIRMENU_MAX_NUMBER_OF_KEYS; loopCounter++)
{
if ((self->menuArray[self->menuState].keyActionBinding[loopCounter].key == key) && (self->menuArray[self->menuState].keyActionBinding[loopCounter].keyState == keyState))
{
returnValue = self->menuArray[self->menuState].keyActionBinding[loopCounter];
break;
}
}
return returnValue;
}
static void repairMenu_scrollIndexHandlerReset (struct RepairMenu* self)
{
self->cursorIndex = 1;
self->scrollOffset = 0;
}
static void repairMenu_scrollUpIndexHandler(struct RepairMenu* self)
{
if (self->cursorIndex - self->scrollOffset > 1)
{
if (self->cursorIndex > 1)
{
self->cursorIndex--;
}
}
else
{
if (self->cursorIndex > 1)
{
self->cursorIndex--;
}
if (self->scrollOffset > 0)
{
self->scrollOffset--;
}
}
}
static void repairMenu_scrollDownIndexHandler(struct RepairMenu* self)
{
if (self->cursorIndex < self->display->displayDevice->parameters.numberOfRows - 1)
{
if (self->cursorIndex < self->menuArray[self->menuState].numberOfRows - 1)
{
self->cursorIndex++;
}
}
else
{
if (self->cursorIndex < self->menuArray[self->menuState].numberOfRows - 1)
{
self->cursorIndex++;
}
if (self->scrollOffset < (self->menuArray[self->menuState].numberOfRows - self->display->displayDevice->parameters.numberOfRows))
{
self->scrollOffset++;
}
}
}
static void repairMenu_selectCathodeRepair(struct RepairMenu* self, int cursorIndex)
{
RepairPresets_loadPresets(REPAIR_PRESETS_CATHODE);
self->repairPreset = RepairPresets_getPreset(1);
CathodeMCP_switchToCathode();
}
static void repairMenu_selectMCPRepair(struct RepairMenu* self, int cursorIndex)
{
RepairPresets_loadPresets(REPAIR_PRESETS_MCP);
self->repairPreset = RepairPresets_getPreset(1);
CathodeMCP_switchToMCP();
}
static void repairMenu_selectPreset(struct RepairMenu* self, int cursorIndex)
{
self->repairPreset = RepairPresets_getPreset(cursorIndex);
LOGGER_INFO(mainLog, "Preset %d selected", cursorIndex);
Display_clearScreen(self->display);
char buffer[20];
snprintf(buffer, sizeof(buffer) / sizeof(buffer[0]), "Preset %d selected", cursorIndex);
Display_write(self->display, buffer, 2, 2);
vTaskDelay(2000);
}
static void repairMenu_solenoidLock(struct RepairMenu* self, int cursorIndex)
{
CoverSolenoid_lock();
}
static void repairMenu_solenoidUnlock(struct RepairMenu* self, int cursorIndex)
{
CoverSolenoid_unlock();
}
static void repairMenu_startRepairProcess(struct RepairMenu* self, int cursorIndex)
{
ErrorStatus returnValue = SUCCESS;
self->rpParameters.adcR1 = adcRow1;
self->rpParameters.adcR2 = adcRow2;
self->rpParameters.adcR3 = adcRow3;
self->rpParameters.dacR1 = dacRow1;
self->rpParameters.dacR2 = dacRow2;
self->rpParameters.dacR3 = dacRow3;
if (returnValue == SUCCESS)
{
// Enable all safety features of the HSB setup
returnValue = hsb_enableSafety();
}
if (returnValue == SUCCESS)
{
// In case of a TESLA repair, release the teslaGunSafety
if (PCBA_getInstance()->pcba == PCBA_Tesla)
{
TeslaGunSafety_release();
}
}
// If all is OK, start the repair process
if (returnValue == SUCCESS)
{
returnValue = repairProcesses_startMainRepairProcess(self->repairPreset, &self->rpParameters);
if (returnValue != SUCCESS)
{
Error_postError(REPAIR_FAIL);
}
}
if (returnValue == SUCCESS)
{
returnValue = repairProcesses_mainRepairProcessAddObserver(self->observer);
if (returnValue == SUCCESS)
{
// repair process is running
repairMenu_changeState(self, REPAIR_RUNNING);
}
else
{
Error_postError(REPAIR_FAIL);
}
}
}
static void repairMenu_stopRepairProcess(struct RepairMenu* self, int cursorIndex)
{
if (PCBA_getInstance()->pcba == PCBA_Tesla)
{
TeslaGunSafety_block();
}
repairProcesses_mainRepairProcessRemoveObserver(self->observer);
repairProcesses_abortMainRepairProcess();
hsb_disableSafety();
}
static void repairMenu_abortRepairProcessAndGotoMainMenu(struct RepairMenu* self, int cursorIndex)
{
repairMenu_stopRepairProcess(self, cursorIndex);
repairMenu_changeState(self, MAINMENU);
}
static void repairMenu_pauseRepairProcess(struct RepairMenu* self, int cursorIndex)
{
repairMenu_changeState(self, REPAIR_PAUSE);
repairProcess_pauseProcess(repairProcesses_getMainRepairProcess());
hsb_disableSafety();
}
static void repairMenu_continueRepairProcess(struct RepairMenu* self, int cursorIndex)
{
hsb_enableSafety();
repairMenu_changeState(self, REPAIR_RUNNING);
repairProcess_continueProcess(repairProcesses_getMainRepairProcess());
}
static ErrorStatus repairMenu_createMenu(struct RepairMenu* self)
{
ErrorStatus returnValue = SUCCESS;
repairMenu_createMenuPage(&self->menuArray[MAINMENU], MENU_HAS_CURSOR, 4);
repairMenu_addMenuPageRow(&self->menuArray[MAINMENU], PCBA_getInstance()->name, MAINMENU, NULL);
if (PCBA_getInstance()->pcba == PCBA_CathodeMCP)
{
// For Cathode/MCP PCBA, the type of repair must be selected first
repairMenu_addMenuPageRow(&self->menuArray[MAINMENU], " 1.Tube repair", RM_CATHODEMCP_SELECT, NULL);
}
else
{
repairMenu_addMenuPageRow(&self->menuArray[MAINMENU], " 1.Tube repair", REPAIRMENU, NULL);
}
repairMenu_addMenuPageRow(&self->menuArray[MAINMENU], " 2.Administrator", ADMINMENU, NULL);
repairMenu_addMenuPageRow(&self->menuArray[MAINMENU], " 3.Calibration", CALIBRATIONMENU, NULL);
repairMenu_addKeyAction_SCROLLUP(&self->menuArray[MAINMENU], 'U', PRESSED);
repairMenu_addKeyAction_SCROLLDOWN(&self->menuArray[MAINMENU], 'D', PRESSED);
repairMenu_addKeyAction_SELECT(&self->menuArray[MAINMENU], 'E', PRESSED);
repairMenu_addKeyAction_HOTKEYSELECT(&self->menuArray[MAINMENU], '1', PRESSED, 1);
repairMenu_addKeyAction_HOTKEYSELECT(&self->menuArray[MAINMENU], '2', PRESSED, 2);
repairMenu_addKeyAction_HOTKEYSELECT(&self->menuArray[MAINMENU], '3', PRESSED, 3);
repairMenu_addKeyAction_EXECUTEFUNCTION(&self->menuArray[MAINMENU], '0', PRESSED, repairMenu_solenoidUnlock);
repairMenu_addKeyAction_EXECUTEFUNCTION(&self->menuArray[MAINMENU], '0', RELEASED, repairMenu_solenoidLock);
repairMenu_createMenuPage(&self->menuArray[RM_CATHODEMCP_SELECT], MENU_HAS_CURSOR, 3);
repairMenu_addMenuPageRow(&self->menuArray[RM_CATHODEMCP_SELECT], "Tube repair", RM_CATHODEMCP_SELECT, NULL);
repairMenu_addMenuPageRow(&self->menuArray[RM_CATHODEMCP_SELECT], " 1.Cathode repair", REPAIRMENU, repairMenu_selectCathodeRepair);
repairMenu_addMenuPageRow(&self->menuArray[RM_CATHODEMCP_SELECT], " 2.MCP repair", REPAIRMENU, repairMenu_selectMCPRepair);
repairMenu_addKeyAction_SCROLLUP(&self->menuArray[RM_CATHODEMCP_SELECT], 'U', PRESSED);
repairMenu_addKeyAction_SCROLLDOWN(&self->menuArray[RM_CATHODEMCP_SELECT], 'D', PRESSED);
repairMenu_addKeyAction_SELECT(&self->menuArray[RM_CATHODEMCP_SELECT], 'E', PRESSED);
repairMenu_addKeyAction_HOTKEYSELECT(&self->menuArray[RM_CATHODEMCP_SELECT], '1', PRESSED, 1);
repairMenu_addKeyAction_HOTKEYSELECT(&self->menuArray[RM_CATHODEMCP_SELECT], '2', PRESSED, 2);
repairMenu_addKeyAction_GOTOSTATE(&self->menuArray[RM_CATHODEMCP_SELECT], 'X', PRESSED, MAINMENU);
repairMenu_addKeyAction_EXECUTEFUNCTION(&self->menuArray[RM_CATHODEMCP_SELECT], '0', PRESSED, repairMenu_solenoidUnlock);
repairMenu_addKeyAction_EXECUTEFUNCTION(&self->menuArray[RM_CATHODEMCP_SELECT], '0', RELEASED, repairMenu_solenoidLock);
repairMenu_createMenuPage(&self->menuArray[REPAIRMENU], MENU_HAS_CURSOR, 4);
repairMenu_addMenuPageRow(&self->menuArray[REPAIRMENU], "Tube repair", REPAIRMENU, NULL);
repairMenu_addMenuPageRow(&self->menuArray[REPAIRMENU], " 1.Select preset", PRESETMENU, NULL);
repairMenu_addMenuPageRow(&self->menuArray[REPAIRMENU], " 2.Start", START_REPAIR, repairMenu_startRepairProcess);
repairMenu_addKeyAction_SCROLLUP(&self->menuArray[REPAIRMENU], 'U', PRESSED);
repairMenu_addKeyAction_SCROLLDOWN(&self->menuArray[REPAIRMENU], 'D', PRESSED);
repairMenu_addKeyAction_SELECT(&self->menuArray[REPAIRMENU], 'E', PRESSED);
repairMenu_addKeyAction_HOTKEYSELECT(&self->menuArray[REPAIRMENU], '1', PRESSED, 1);
repairMenu_addKeyAction_HOTKEYSELECT(&self->menuArray[REPAIRMENU], '2', PRESSED, 2);
if (PCBA_getInstance()->pcba == PCBA_CathodeMCP)
{
// For Cathode/MCP PCBA, the type of repair must can be selected
repairMenu_addKeyAction_GOTOSTATE(&self->menuArray[REPAIRMENU], 'X', PRESSED, RM_CATHODEMCP_SELECT);
}
else
{
repairMenu_addKeyAction_GOTOSTATE(&self->menuArray[REPAIRMENU], 'X', PRESSED, MAINMENU);
}
repairMenu_addKeyAction_EXECUTEFUNCTION(&self->menuArray[REPAIRMENU], '0', PRESSED, repairMenu_solenoidUnlock);
repairMenu_addKeyAction_EXECUTEFUNCTION(&self->menuArray[REPAIRMENU], '0', RELEASED, repairMenu_solenoidLock);
repairMenu_createMenuPage(&self->menuArray[ADMINMENU], MENU_HAS_NO_CURSOR, 2);
repairMenu_addMenuPageRow(&self->menuArray[ADMINMENU], "Administration", ADMINMENU, NULL);
repairMenu_addMenuPageRow(&self->menuArray[ADMINMENU], " 1.Nothing", ADMINMENU, NULL);
repairMenu_addKeyAction_GOTOSTATE(&self->menuArray[ADMINMENU], 'X', PRESSED, MAINMENU);
repairMenu_createMenuPage(&self->menuArray[CALIBRATIONMENU], MENU_HAS_NO_CURSOR, 2);
repairMenu_addMenuPageRow(&self->menuArray[CALIBRATIONMENU], "Calibration", CALIBRATIONMENU, NULL);
repairMenu_addMenuPageRow(&self->menuArray[CALIBRATIONMENU], " 1.Nothing", CALIBRATIONMENU, NULL);
repairMenu_addKeyAction_GOTOSTATE(&self->menuArray[CALIBRATIONMENU], 'X', PRESSED, MAINMENU);
repairMenu_createMenuPage(&self->menuArray[PRESETMENU], MENU_HAS_CURSOR, 10);
repairMenu_addMenuPageRow(&self->menuArray[PRESETMENU], "Select preset", PRESETMENU, NULL);
repairMenu_addMenuPageRow(&self->menuArray[PRESETMENU], " 1.Preset1", REPAIRMENU, repairMenu_selectPreset);
repairMenu_addMenuPageRow(&self->menuArray[PRESETMENU], " 2.Preset2", REPAIRMENU, repairMenu_selectPreset);
repairMenu_addMenuPageRow(&self->menuArray[PRESETMENU], " 3.Preset3", REPAIRMENU, repairMenu_selectPreset);
repairMenu_addMenuPageRow(&self->menuArray[PRESETMENU], " 4.Preset4", REPAIRMENU, repairMenu_selectPreset);
repairMenu_addMenuPageRow(&self->menuArray[PRESETMENU], " 5.Preset5", REPAIRMENU, repairMenu_selectPreset);
repairMenu_addMenuPageRow(&self->menuArray[PRESETMENU], " 6.Preset6", REPAIRMENU, repairMenu_selectPreset);
repairMenu_addMenuPageRow(&self->menuArray[PRESETMENU], " 7.Preset7", REPAIRMENU, repairMenu_selectPreset);
repairMenu_addMenuPageRow(&self->menuArray[PRESETMENU], " 8.Preset8", REPAIRMENU, repairMenu_selectPreset);
repairMenu_addMenuPageRow(&self->menuArray[PRESETMENU], " 9.Preset9", REPAIRMENU, repairMenu_selectPreset);
repairMenu_addKeyAction_SCROLLUP(&self->menuArray[PRESETMENU], 'U', PRESSED);
repairMenu_addKeyAction_SCROLLDOWN(&self->menuArray[PRESETMENU], 'D', PRESSED);
repairMenu_addKeyAction_SELECT(&self->menuArray[PRESETMENU], 'E', PRESSED);
repairMenu_addKeyAction_HOTKEYSELECT(&self->menuArray[PRESETMENU], '1', PRESSED, 1);
repairMenu_addKeyAction_HOTKEYSELECT(&self->menuArray[PRESETMENU], '2', PRESSED, 2);
repairMenu_addKeyAction_HOTKEYSELECT(&self->menuArray[PRESETMENU], '3', PRESSED, 3);
repairMenu_addKeyAction_HOTKEYSELECT(&self->menuArray[PRESETMENU], '4', PRESSED, 4);
repairMenu_addKeyAction_HOTKEYSELECT(&self->menuArray[PRESETMENU], '5', PRESSED, 5);
repairMenu_addKeyAction_HOTKEYSELECT(&self->menuArray[PRESETMENU], '6', PRESSED, 6);
repairMenu_addKeyAction_HOTKEYSELECT(&self->menuArray[PRESETMENU], '7', PRESSED, 7);
repairMenu_addKeyAction_HOTKEYSELECT(&self->menuArray[PRESETMENU], '8', PRESSED, 8);
repairMenu_addKeyAction_HOTKEYSELECT(&self->menuArray[PRESETMENU], '9', PRESSED, 9);
repairMenu_addKeyAction_GOTOSTATE(&self->menuArray[PRESETMENU], 'X', PRESSED, REPAIRMENU);
repairMenu_addKeyAction_EXECUTEFUNCTION(&self->menuArray[PRESETMENU], '0', PRESSED, repairMenu_solenoidUnlock);
repairMenu_addKeyAction_EXECUTEFUNCTION(&self->menuArray[PRESETMENU], '0', RELEASED, repairMenu_solenoidLock);
repairMenu_addKeyAction_GOTOSTATE(&self->menuArray[PRESETMENU], 'R', PRESSED, RM_PRESET_PRINT);
repairMenu_createMenuPage(&self->menuArray[RM_PRESET_PRINT], MENU_HAS_NO_CURSOR, 10);
repairMenu_addKeyAction_GOTOSTATE(&self->menuArray[RM_PRESET_PRINT], 'X', PRESSED, PRESETMENU);
repairMenu_addKeyAction_GOTOSTATE(&self->menuArray[RM_PRESET_PRINT], 'L', PRESSED, PRESETMENU);
repairMenu_createMenuPage(&self->menuArray[REPAIR_RUNNING], MENU_HAS_NO_CURSOR, 4);
repairMenu_addKeyAction_GOTOSTATE(&self->menuArray[REPAIR_RUNNING], 'X', PRESSED, REPAIR_ASK_PAUSE);
repairMenu_createMenuPage(&self->menuArray[REPAIR_ASK_PAUSE], MENU_HAS_NO_CURSOR, 4);
repairMenu_addKeyAction_EXECUTEFUNCTION(&self->menuArray[REPAIR_ASK_PAUSE], 'X', PRESSED, repairMenu_pauseRepairProcess);
repairMenu_createMenuPage(&self->menuArray[REPAIR_PAUSE], MENU_HAS_NO_CURSOR, 4);
repairMenu_addKeyAction_EXECUTEFUNCTION(&self->menuArray[REPAIR_PAUSE], 'X', PRESSED, repairMenu_abortRepairProcessAndGotoMainMenu);
repairMenu_addKeyAction_EXECUTEFUNCTION(&self->menuArray[REPAIR_PAUSE], 'E', PRESSED, repairMenu_continueRepairProcess);
repairMenu_addKeyAction_EXECUTEFUNCTION(&self->menuArray[REPAIR_PAUSE], '0', PRESSED, repairMenu_solenoidUnlock);
repairMenu_addKeyAction_EXECUTEFUNCTION(&self->menuArray[REPAIR_PAUSE], '0', RELEASED, repairMenu_solenoidLock);
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);
return returnValue;
}
static ErrorStatus repairMenu_createMenuPage (struct MenuPage* self, bool hasCursor, int maxNumberOfRows)
{
ErrorStatus returnValue = SUCCESS;
if (maxNumberOfRows <= REPAIRMENU_MAX_NUMBER_OF_ROWS)
{
self->maxNumberOfKeys = NUMBER_OF_KEY_EVENTS * REPAIRMENU_MAX_NUMBER_OF_KEYS;
self->numberOfRows = 0;
self->numberOfKeys = 0;
self->maxNumberOfRows = maxNumberOfRows;
self->hasCursor = hasCursor;
}
else
{
returnValue = ERROR;
}
return returnValue;
}
static ErrorStatus repairMenu_addMenuPageRow (struct MenuPage* self, char* text, int newState, RepairMenuFunctionCall actionCall)
{
ErrorStatus returnValue = SUCCESS;
if (self->numberOfRows < self->maxNumberOfRows)
{
memcpy(self->row[self->numberOfRows].text, text, 20);
self->row[self->numberOfRows].newState = newState;
self->row[self->numberOfRows].actionPointer = actionCall;
self->numberOfRows++;
}
else
{
returnValue = ERROR;
}
return returnValue;
}
static ErrorStatus repairMenu_addKeyAction_HOTKEYSELECT (struct MenuPage* self, char key, Keypad_KeyState keyState, int rowToSelect)
{
ErrorStatus returnValue = SUCCESS;
if (self->numberOfKeys < self->maxNumberOfKeys)
{
self->keyActionBinding[self->numberOfKeys].key = key;
self->keyActionBinding[self->numberOfKeys].keyState = keyState;
self->keyActionBinding[self->numberOfKeys].action = HOTKEY_SELECT;
self->keyActionBinding[self->numberOfKeys].argument = rowToSelect;
self->keyActionBinding[self->numberOfKeys].actionPointer = NULL;
self->numberOfKeys++;
}
else
{
returnValue = ERROR;
}
return returnValue;
}
static ErrorStatus repairMenu_addKeyAction_SELECT (struct MenuPage* self, char key, Keypad_KeyState keyState)
{
ErrorStatus returnValue = SUCCESS;
if (self->numberOfKeys < self->maxNumberOfKeys)
{
self->keyActionBinding[self->numberOfKeys].key = key;
self->keyActionBinding[self->numberOfKeys].keyState = keyState;
self->keyActionBinding[self->numberOfKeys].action = SELECT;
self->keyActionBinding[self->numberOfKeys].argument = 0;
self->keyActionBinding[self->numberOfKeys].actionPointer = NULL;
self->numberOfKeys++;
}
else
{
returnValue = ERROR;
}
return returnValue;
}
static ErrorStatus repairMenu_addKeyAction_GOTOSTATE (struct MenuPage* self, char key, Keypad_KeyState keyState, T_MenuState state)
{
ErrorStatus returnValue = SUCCESS;
if (self->numberOfKeys < self->maxNumberOfKeys)
{
self->keyActionBinding[self->numberOfKeys].key = key;
self->keyActionBinding[self->numberOfKeys].keyState = keyState;
self->keyActionBinding[self->numberOfKeys].action = GOTO_STATE;
self->keyActionBinding[self->numberOfKeys].argument = state;
self->keyActionBinding[self->numberOfKeys].actionPointer = NULL;
self->numberOfKeys++;
}
else
{
returnValue = ERROR;
}
return returnValue;
}
static ErrorStatus repairMenu_addKeyAction_EXECUTEFUNCTION (struct MenuPage* self, char key, Keypad_KeyState keyState, RepairMenuFunctionCall actionPointer)
{
ErrorStatus returnValue = SUCCESS;
if (self->numberOfKeys < self->maxNumberOfKeys)
{
self->keyActionBinding[self->numberOfKeys].key = key;
self->keyActionBinding[self->numberOfKeys].keyState = keyState;
self->keyActionBinding[self->numberOfKeys].action = EXECUTE_FUNCTION;
self->keyActionBinding[self->numberOfKeys].argument = 0;
self->keyActionBinding[self->numberOfKeys].actionPointer = actionPointer;
self->numberOfKeys++;
}
else
{
returnValue = ERROR;
}
return returnValue;
}
static ErrorStatus repairMenu_addKeyAction_SCROLLUP (struct MenuPage* self, char key, Keypad_KeyState keyState)
{
ErrorStatus returnValue = SUCCESS;
if (self->numberOfKeys < self->maxNumberOfKeys)
{
self->keyActionBinding[self->numberOfKeys].key = key;
self->keyActionBinding[self->numberOfKeys].keyState = keyState;
self->keyActionBinding[self->numberOfKeys].action = SCROLL_UP;
self->keyActionBinding[self->numberOfKeys].argument = 0;
self->keyActionBinding[self->numberOfKeys].actionPointer = NULL;
self->numberOfKeys++;
}
else
{
returnValue = ERROR;
}
return returnValue;
}
static ErrorStatus repairMenu_addKeyAction_SCROLLDOWN (struct MenuPage* self, char key, Keypad_KeyState keyState)
{
ErrorStatus returnValue = SUCCESS;
if (self->numberOfKeys < self->maxNumberOfKeys)
{
self->keyActionBinding[self->numberOfKeys].key = key;
self->keyActionBinding[self->numberOfKeys].keyState = keyState;
self->keyActionBinding[self->numberOfKeys].action = SCROLL_DOWN;
self->keyActionBinding[self->numberOfKeys].argument = 0;
self->keyActionBinding[self->numberOfKeys].actionPointer = NULL;
self->numberOfKeys++;
}
else
{
returnValue = ERROR;
}
return returnValue;
}