- Re-located repairprocessrow information in dedicated object
- added error conditions to repair row and added condition handling to repair process

git-svn-id: https://svn.vbchaos.nl/svn/hsb/trunk@260 05563f52-14a8-4384-a975-3d1654cca0fa
This commit is contained in:
mmi
2017-10-23 09:02:13 +00:00
parent aa9ba5ea8e
commit e3ca058c96
30 changed files with 1348 additions and 323 deletions

View File

@@ -126,7 +126,6 @@ ErrorStatus Display_clearScreen(struct Display* self)
{
ErrorStatus returnValue = SUCCESS;
returnValue = DisplayDevice_clear(self->displayDevice);
vTaskDelay(5);
Display_clearShadow(self);
return returnValue;
}
@@ -134,15 +133,16 @@ ErrorStatus Display_clearScreen(struct Display* self)
ErrorStatus Display_clearLine(struct Display* self, size_t line)
{
char buffer[self->displayDevice->parameters.numberOfColumns];
char buffer[self->displayDevice->parameters.numberOfColumns + 1];
int loopcounter;
for (loopcounter = 0; loopcounter < self->displayDevice->parameters.numberOfColumns; loopcounter++)
{
buffer[loopcounter] = 0x20;
}
buffer[self->displayDevice->parameters.numberOfColumns] = '\0';
return Display_write(self, buffer, self->displayDevice->parameters.numberOfColumns, line, 1);
return Display_write(self, buffer, line, 1);
}
@@ -164,12 +164,13 @@ ErrorStatus Display_setContrast(struct Display* self, size_t contrast)
}
ErrorStatus Display_write(struct Display* self, const char* buffer, unsigned int length, size_t row, size_t column)
ErrorStatus Display_write(struct Display* self, const char* buffer, size_t row, size_t column)
{
ErrorStatus returnValue = SUCCESS;
if (self->initialized)
{
int length = 0;
// Prior to any action on the display memory, perform necessary checkings
if (returnValue == SUCCESS)
{
@@ -189,6 +190,7 @@ ErrorStatus Display_write(struct Display* self, const char* buffer, unsigned int
}
if (returnValue == SUCCESS)
{
length = strlen(buffer);
// Check that the length request does not exceed the display boundary
// This is checked in combination with the column coordinate
// numberOfColumns - column >= length
@@ -282,7 +284,7 @@ inline static void Display_clearShadow(struct Display* self)
// Clear the display shadow
size_t rowCounter;
size_t colCounter;
char buffer[self->displayDevice->parameters.numberOfColumns];
xSemaphoreTake(self->displayShadowAccessSemaphore, portMAX_DELAY);
for (rowCounter = 0; rowCounter < self->displayDevice->parameters.numberOfRows; rowCounter++)
{
for (colCounter = 0; colCounter < self->displayDevice->parameters.numberOfColumns; colCounter++)
@@ -295,6 +297,7 @@ inline static void Display_clearShadow(struct Display* self)
self->displayShadow[rowCounter][colCounter].isUpdated = false;
}
}
xSemaphoreGive(self->displayShadowAccessSemaphore);
}

View File

@@ -70,7 +70,7 @@ ErrorStatus Error_construct(void)
Observable_construct(&observable);
errorQueue = xQueueCreate(ERROR_QUEUE_SIZE, sizeof(struct ErrorQueueItem));
xTaskCreate(ErrorTask, "ErrorTask", 256, NULL, 1, &errorTaskHandle);
xTaskCreate(ErrorTask, "ErrorTask", 300, NULL, 1, &errorTaskHandle);
return SUCCESS;
}

View File

@@ -0,0 +1,259 @@
// -----------------------------------------------------------------------------
/// @file SignalProfileGenerator.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 SignalProfileGenerator.c
/// @ingroup {group_name}
// -----------------------------------------------------------------------------
// Include files
// -----------------------------------------------------------------------------
#include "SignalProfileGenerator.h"
#include "Logger.h"
// -----------------------------------------------------------------------------
// Constant and macro definitions
// -----------------------------------------------------------------------------
#define SPG_0V_OFFSET (450)
#define SPG_PAUSE_SOFTSTART (300) // 5 minutes softstart after pause
#define SPG_FIXPOINT_FACTOR (1000)
// -----------------------------------------------------------------------------
// Type definitions
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// File-scope variables
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// Function declarations
// -----------------------------------------------------------------------------
static inline void incrementSecondsCounter(struct SignalProfileGenerator* self);
// -----------------------------------------------------------------------------
// Function definitions
// -----------------------------------------------------------------------------
ErrorStatus SignalProfileGenerator_construct(struct SignalProfileGenerator* self, const struct RepairPreset* preset)
{
ErrorStatus returnValue = SUCCESS;
if (!self->initialized)
{
self->secondsCounter = 0;
self->currentState = SPG_PREPARE;
self->initialized = true;
self->repairPreset = preset;
}
else
{
returnValue = ERROR;
}
return returnValue;
}
void SignalProfileGenerator_destruct(struct SignalProfileGenerator* self)
{
self->initialized = false;
}
void SignalProfileGenerator_calculate(struct SignalProfileGenerator* self)
{
self->signal = 0;
if (self->initialized)
{
switch (self->currentState)
{
case SPG_PREPARE:
{
// Prepare a new repair process
//Load the timers
self->startTime = self->secondsCounter;
self->softStartTimer = self->secondsCounter + self->repairPreset->preset[self->currentPresetIndex].softstartDuration;
self->voltageHoldTimer = self->secondsCounter + self->repairPreset->preset[self->currentPresetIndex].duration;
LOGGER_DEBUG(mainLog, "startTime %d - softStartTime %d - HoldTimer %d", self->startTime, self->softStartTimer, self->voltageHoldTimer);
// If first preset, start voltage is 0
if (self->currentPresetIndex == 0)
{
self->startVoltage = SPG_0V_OFFSET;
}
else
{
// Softstart for another stage - start voltage is hold voltage of previous preset
self->startVoltage = self->repairPreset->preset[self->currentPresetIndex - 1].voltage;
}
incrementSecondsCounter(self);
self->currentState = SPG_SOFTSTART;
break;
}
case SPG_SOFTSTART:
{
self->isProcessRunning = true;
self->signal = ((self->repairPreset->preset[self->currentPresetIndex].voltage * SPG_FIXPOINT_FACTOR - self->startVoltage * SPG_FIXPOINT_FACTOR) / self->repairPreset->preset[self->currentPresetIndex].softstartDuration) * (self->secondsCounter - self->startTime) + self->startVoltage * SPG_FIXPOINT_FACTOR;
self->signal = self->signal / SPG_FIXPOINT_FACTOR;
incrementSecondsCounter(self);
// Check for end of softstart
if (self->softStartTimer < self->secondsCounter)
{
// softstart finished
self->currentState = SPG_VOLTAGE_HOLD;
}
break;
}
case SPG_VOLTAGE_HOLD:
{
self->signal = self->repairPreset->preset[self->currentPresetIndex].voltage;
incrementSecondsCounter(self);
// Check for end of voltage hold
if (self->voltageHoldTimer < self->secondsCounter)
{
// softstart finished
self->currentState = SPG_FINISH_VERIFY;
}
break;
}
case SPG_PAUSE:
{
// Nothing happens here, just wait until the process gets continued
break;
}
case SPG_PAUSE_RESTORE:
{
self->pauseStartTime = self->secondsCounter;
self->pauseSoftStartTimer = self->secondsCounter + SPG_PAUSE_SOFTSTART;
self->startTime = self->startTime + SPG_PAUSE_SOFTSTART;
self->softStartTimer = self->softStartTimer + SPG_PAUSE_SOFTSTART;
self->voltageHoldTimer = self->voltageHoldTimer + SPG_PAUSE_SOFTSTART;
self->currentState = SPG_PAUSE_RESTORE_SOFTSTART;
break;
}
case SPG_PAUSE_RESTORE_SOFTSTART:
{
self->pauseStartVoltage = SPG_0V_OFFSET;
self->signal = ((self->voltagePriorToPause * SPG_FIXPOINT_FACTOR - self->pauseStartVoltage * SPG_FIXPOINT_FACTOR) / SPG_PAUSE_SOFTSTART) * (self->secondsCounter - self->pauseStartTime) + self->pauseStartVoltage * SPG_FIXPOINT_FACTOR;
self->signal = self->signal / SPG_FIXPOINT_FACTOR;
incrementSecondsCounter(self);
// Check for end of softstart
if (self->pauseSoftStartTimer < self->secondsCounter)
{
// softstart finished
self->currentState = self->statePriorToPause;
}
break;
}
case SPG_FINISH_VERIFY:
{
incrementSecondsCounter(self);
// The current preset might contain multiple stages, so before going to FINISHED state
// verify that no further stage must be entered
// presetIndex carries the current index in the preset array
// number of stages is 1-based (Starting with 1) while presetIndex is 0-based
// So, the verification must compensate for the different bases
if (self->repairPreset->numberOfStages > (self->currentPresetIndex + 1))
{
// A next stage is available
self->currentPresetIndex++;
self->currentState = SPG_PREPARE;
}
else
{
self->currentState = SPG_FINISHED;
}
break;
}
case SPG_FINISHED:
{
self->isProcessRunning = false;
self->signal = 0;
break;
}
}
}
else
{
self->signal = -1;
}
}
void SignalProfileGenerator_pause(struct SignalProfileGenerator* self)
{
self->voltagePriorToPause = self->signal;
self->statePriorToPause = self->currentState;
self->currentState = SPG_PAUSE;
}
void SignalProfileGenerator_continue(struct SignalProfileGenerator* self)
{
self->currentState = SPG_PAUSE_RESTORE;
}
uint32_t SignalProfileGenerator_getRemainingTime(const struct SignalProfileGenerator* self)
{
uint32_t returnValue;
if ((self->initialized) && (self->isProcessRunning))
{
if (self->voltageHoldTimer >= self->secondsCounter)
{
returnValue = (self->voltageHoldTimer - self->secondsCounter);
}
else
{
// ERROR - negative time
returnValue = 0;
}
}
else
{
returnValue = 0xFFFFFFFF;
}
return returnValue;
}
static inline void incrementSecondsCounter(struct SignalProfileGenerator* self)
{
self->secondsCounter++;
}

View File

@@ -72,7 +72,7 @@ ErrorStatus hsb_generateStartScreen(struct Display* Display)
if (returnValue == SUCCESS)
{
returnValue = Display_write(mainDisplay, pcba->name, strlen(pcba->name), 1, 1);
returnValue = Display_write(mainDisplay, PCBA_getInstance()->name, 1, 1);
}
else
{
@@ -87,7 +87,7 @@ ErrorStatus hsb_generateStartScreen(struct Display* Display)
Version_getInstance()->minor,
Version_getInstance()->branch,
Version_getInstance()->patch);
Display_write(mainDisplay, buffer, strlen(buffer), 3, 4);
Display_write(mainDisplay, buffer, 3, 4);
}
else
{
@@ -135,7 +135,7 @@ ErrorStatus hsb_enableSafety(void)
if (returnValue == SUCCESS)
{
// TESLA has a second interlock that must be closed
if (PCBA_getInstance()->pcba == Tesla)
if (PCBA_getInstance()->pcba == PCBA_Tesla)
{
if (Interlock_isClosed(teslalock))
{
@@ -177,7 +177,7 @@ ErrorStatus hsb_disableSafety(void)
Interlock_setEXTI(interlock, DISABLE);
// TESLA has a second interlock that must be closed
if (PCBA_getInstance()->pcba == Tesla)
if (PCBA_getInstance()->pcba == PCBA_Tesla)
{
Interlock_setEXTI(teslalock, DISABLE);
}

View File

@@ -895,7 +895,7 @@ static void hwValidationMenuSM(struct HwValidationMenu* self, Button_Pressed_t b
else if (self->menuItemSelected == MENU_TEST_INTERLOCK_2 )
{
if(pcba->pcba == Tesla)
if(self->testItems->pcba->pcba == PCBA_Tesla)
{
if( GPIO_getValue(self->testItems->teslaNO, &value1) == SUCCESS &&

View File

@@ -33,6 +33,7 @@
#include "FreeRTOS.h"
#include "task.h"
#include "CathodeMCP.h"
#include "Displays.h"
#include "Error.h"
#include "hsb-mrts.h"
@@ -223,7 +224,7 @@ static void initTask(void* parameters)
hwTestItems.cat0Relay = cat0Relay;
hwTestItems.cat1Relay = cat1Relay;
hwTestItems.cat2Relay = cat2Relay;
hwTestItems.pcba = pcba;
hwTestItems.pcba = PCBA_getInstance();
hwTestItems.keypad = keypad;
// EEPROM TO BE DONE
// HwValidationMenu_construct(hwValidation, &uart1->device, &hwTestItems, 1, 1024);
@@ -242,16 +243,30 @@ static void ledBlinkTask (void* parameters)
{
char high = 1;
char low = 0;
char indicator[2];
indicator[0] = ' ';
indicator[1] = '\0';
struct LedTaskArguments* arguments = (struct LedTaskArguments*) parameters;
struct Gpio* gpio = arguments->led;
int frequency = arguments->frequency;
while (1)
{
IODevice_write(&gpio->device, &high, 1);
Display_write(mainDisplay, pcba->name, 1, 1, 20);
if (PCBA_getInstance()->pcba == PCBA_CathodeMCP)
{
indicator[0] = CathodeMCP_getInstance()->name[0];
Display_write(mainDisplay, indicator, 1, 20);
}
else
{
indicator[0] = PCBA_getInstance()->name[0];
Display_write(mainDisplay, indicator, 1, 20);
}
vTaskDelay(configTICK_RATE_HZ / (frequency * 2));
IODevice_write(&gpio->device, &low, 1);
Display_write(mainDisplay, " ", 1, 1, 20);
indicator[0] = ' ';
Display_write(mainDisplay, indicator, 1, 20);
vTaskDelay(configTICK_RATE_HZ / (frequency * 2));
}
}

View File

@@ -31,6 +31,7 @@
#include "repairProcess.h"
#include "repairProcesses.h"
#include "CathodeMCP.h"
#include "Display.h"
#include "Error.h"
#include "hsb-mrts.h"
@@ -64,7 +65,7 @@
// File-scope variables
// -----------------------------------------------------------------------------
static const char cursorValue = 0x7E;
static const char cursorValue[2] = {0x7E, '\0'};
// TEMPORARY PRESET STORAGE
@@ -99,12 +100,16 @@ 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);
@@ -210,6 +215,13 @@ void repairMenu_interlockFailed(struct RepairMenu* self, T_INTERLOCK_ID interloc
}
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;
@@ -220,8 +232,8 @@ static void repairMenu_task(void* parameters)
repairMenu_printMenu(self);
// Add cursor if necessary
repairMenu_printCursor(self);
int tempScreenCounter;
T_MenuState tempMenuState;
int tempScreenCounter = 0;
T_MenuState tempMenuState = MAINMENU;
while(self->runTask)
{
@@ -273,6 +285,7 @@ static void repairMenu_task(void* parameters)
}
else if (self->menuState == REPAIR_PAUSE)
{
repairMenu_printPause(self);
}
else if (self->menuState == FINISH_CONTROL)
@@ -296,14 +309,13 @@ static void repairMenu_task(void* parameters)
repairMenu_printMenu(self);
// Add cursor if necessary
repairMenu_printCursor(self);
LOGGER_WARNING(mainLog, "menu index is %d", self->menuState);
}
}
vTaskDelay(50);
}
LOGGER_INFO(mainLog, "Deleting RepairMenu task");
vTaskDelete(self->taskHandle);
vTaskDelete(NULL);
}
@@ -311,12 +323,13 @@ 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!!", strlen("!!ERROR!!"), 2, 6);
Display_write(self->display, self->errorMessage, strlen(self->errorMessage), 3, 1 + ((self->display->displayDevice->parameters.numberOfColumns - strlen(self->errorMessage)) / 2));
Display_write(self->display, "!!ERROR!!", 2, 6);
Display_write(self->display, self->errorMessage, 3, 1 + ((self->display->displayDevice->parameters.numberOfColumns - strlen(self->errorMessage)) / 2));
}
@@ -331,58 +344,79 @@ static void repairMenu_printRepair(struct RepairMenu* self)
int loopCounter = 0;
char buffer[20];
if (xSemaphoreTake(self->repairScreenUpdateSemaphore, 0) != pdTRUE)
struct RepairProcess* repairProcess = repairProcesses_getMainRepairProcess();
if (repairProcess_isProcessRunning(repairProcess))
{
// Taking semaphore failed - no update on the screen
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]), " %02d:%02d:%02d remain ", remainingTime.hours, remainingTime.minutes, remainingTime.seconds);
Display_write(self->display, buffer, 1, 1);
LOGGER_DEBUG(mainLog, "%s", buffer);
// 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)) + (self->display->displayDevice->parameters.numberOfColumns / REPAIRPROCESS_NUMBER_OF_ROWS) / strlen(buffer)));
if (!row->errorData.rowHasError)
{
snprintf(buffer, sizeof(buffer) / sizeof(buffer[0]), "%05dV", 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]), "%04dER", 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
{
struct Time remainingTime;
RTC_calculateTimeFromSeconds(repairProcess_getRemainingRepairTime(repairProcesses_getMainRepairProcess()), &remainingTime);
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)));
}
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", strlen("REPAIR BUSY"), 2, 6);
Display_write(self->display, "Hit X to PAUSE", strlen("Hit X to RESET"), 3, 2);
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!!", 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);
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", strlen("REPAIR FINISHED"), 2, 6);
Display_write(self->display, "Hit ENT to continue", strlen("Hit ENT to continue"), 4, 2);
Display_write(self->display, "REPAIR FINISHED", 2, 6);
Display_write(self->display, "Hit ENT to continue", 4, 2);
}
@@ -392,11 +426,11 @@ 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, strlen(self->menuArray[self->menuState].row[0].text), 1, 1);
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, strlen(self->menuArray[self->menuState].row[loopCounter + self->scrollOffset].text), loopCounter + 1, 1);
Display_write(self->display, self->menuArray[self->menuState].row[loopCounter + self->scrollOffset].text, loopCounter + 1, 1);
}
}
@@ -405,7 +439,7 @@ static void repairMenu_printCursor(struct RepairMenu* self)
{
if (self->menuArray[self->menuState].hasCursor)
{
Display_write(self->display, &cursorValue, 1, 1 + self->cursorIndex - self->scrollOffset, 1);
Display_write(self->display, cursorValue, 1 + self->cursorIndex - self->scrollOffset, 1);
}
}
@@ -563,6 +597,18 @@ static void repairMenu_scrollDownIndexHandler(struct RepairMenu* self)
}
static void repairMenu_selectCathodeRepair(struct RepairMenu* self, int cursorIndex)
{
CathodeMCP_switchToCathode();
}
static void repairMenu_selectMCPRepair(struct RepairMenu* self, int cursorIndex)
{
CathodeMCP_switchToMCP();
}
static void repairMenu_selectPreset(struct RepairMenu* self, int cursorIndex)
{
self->repairPreset = presetArray[cursorIndex - 1];
@@ -601,7 +647,7 @@ static void repairMenu_startRepairProcess(struct RepairMenu* self, int cursorInd
if (returnValue == SUCCESS)
{
// For MCP/Cathode, the right settings must be made
if (PCBA_getInstance()->pcba == CathodeMCP)
if (PCBA_getInstance()->pcba == PCBA_CathodeMCP)
{
}
@@ -612,7 +658,12 @@ static void repairMenu_startRepairProcess(struct RepairMenu* self, int cursorInd
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);
@@ -645,13 +696,35 @@ static void repairMenu_abortRepairProcessAndGotoMainMenu(struct RepairMenu* self
}
static void repairMenu_pauseRepairProcess(struct RepairMenu* self, int cursorIndex)
{
repairMenu_changeState(self, REPAIR_PAUSE);
repairProcess_pauseProcess(repairProcesses_getMainRepairProcess());
}
static void repairMenu_continueRepairProcess(struct RepairMenu* self, int cursorIndex)
{
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);
repairMenu_addMenuPageRow(&self->menuArray[MAINMENU], " 1.Tube repair", REPAIRMENU, 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);
@@ -663,6 +736,18 @@ static ErrorStatus repairMenu_createMenu(struct RepairMenu* self)
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);
@@ -673,7 +758,16 @@ static ErrorStatus repairMenu_createMenu(struct RepairMenu* self)
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);
repairMenu_addKeyAction_GOTOSTATE(&self->menuArray[REPAIRMENU], 'X', PRESSED, MAINMENU);
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);
@@ -720,11 +814,13 @@ static ErrorStatus repairMenu_createMenu(struct RepairMenu* self)
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_GOTOSTATE(&self->menuArray[REPAIR_ASK_PAUSE], 'X', PRESSED, REPAIR_PAUSE);
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_GOTOSTATE(&self->menuArray[REPAIR_PAUSE], 'E', PRESSED, REPAIR_RUNNING);
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);

View File

@@ -119,7 +119,7 @@ static ErrorStatus repairMenu_errorReceive(const void* const data)
}
else if (errorCode == REPAIR_FAIL)
{
repairMenu_processFailed(mainMenu);
}
return SUCCESS;
}

View File

@@ -32,6 +32,7 @@
#include "semphr.h"
#include "task.h"
#include "hsb-mrts.h"
#include "repairProcess.h"
#include "repairPreset.h"
@@ -64,7 +65,6 @@
static void repairProcess_task(void* parameters);
static int SignalProfileGenerator(struct RepairProcess* self);
// -----------------------------------------------------------------------------
// Function definitions
@@ -78,12 +78,18 @@ ErrorStatus repairProcess_construct(struct RepairProcess* self, struct RepairPro
if (!self->initialized)
{
self->runTask = true;
self->taskIsRunning = false;
BaseType_t rv = xTaskCreate(repairProcess_task, "RepairProcess", stackSize, self, taskPriority, &self->taskHandle);
if (rv != pdTRUE)
{
LOGGER_ERROR(mainLog, "FAILED to start repair Process task with code %d", (int)rv);
returnValue = ERROR;
}
if (returnValue == SUCCESS)
{
returnValue = SignalProfileGenerator_construct(&self->signalProfileGenerator, preset);
}
if (returnValue == SUCCESS)
{
// Create a semaphore to sync access to the display shadow
@@ -91,47 +97,28 @@ ErrorStatus repairProcess_construct(struct RepairProcess* self, struct RepairPro
xSemaphoreTake(self->secondsSyncronisation, 0);
Observable_construct(&self->observable);
}
if (returnValue == SUCCESS)
{
returnValue = repairProcessRow_construct(&self->row[0], parameters->adcRow1, parameters->dacRow1, HSB_MAINREPR_OOL_DURATION, HSB_MAINREPR_OOL_VALUE);
}
if (returnValue == SUCCESS)
{
returnValue = repairProcessRow_construct(&self->row[1], parameters->adcRow2, parameters->dacRow2, HSB_MAINREPR_OOL_DURATION, HSB_MAINREPR_OOL_VALUE);
}
if (returnValue == SUCCESS)
{
returnValue = repairProcessRow_construct(&self->row[2], parameters->adcRow3, parameters->dacRow3, HSB_MAINREPR_OOL_DURATION, HSB_MAINREPR_OOL_VALUE);
}
if (returnValue == SUCCESS)
{
self->initialized = true;
self->taskIsDeleted = false;
self->isProcessRunning = false;
self->repairPreset = preset;
self->currentState = PREPARE;
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;
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");
}
else
{
LOGGER_ERROR(mainLog, "FAILED to start repair Process with code %d", (int)rv);
self->initialized = false;
LOGGER_ERROR(mainLog, "Repair Process failed to construct");
}
}
else
@@ -151,20 +138,20 @@ void repairProcess_destruct(struct RepairProcess* self)
MAX5715Channel_setValue(self->row[2].dacChannel, 0);
self->runTask = false;
while (!self->taskIsDeleted)
while (!self->taskIsRunning)
{
vTaskDelay(10);
vTaskDelay(1);
}
Observable_destruct(&self->observable);
PID_destruct(&self->row[0].pid);
PID_destruct(&self->row[1].pid);
PID_destruct(&self->row[2].pid);
repairProcessRow_destruct(&self->row[0]);
repairProcessRow_destruct(&self->row[1]);
repairProcessRow_destruct(&self->row[2]);
vSemaphoreDelete(self->secondsSyncronisation);
self->initialized = false;
}
void repairProcess_feedSecondsCounter(struct RepairProcess* self)
void repairProcess_secondsFeed(struct RepairProcess* self)
{
if (self->initialized)
{
@@ -172,44 +159,29 @@ void repairProcess_feedSecondsCounter(struct RepairProcess* self)
}
}
void repairProcess_feedSecondsCounterFromISR(struct RepairProcess* self)
void repairProcess_secondsFeedFromISR(struct RepairProcess* self)
{
portBASE_TYPE higherPriorityTaskWoken = pdFALSE;
if (self->initialized)
{
xSemaphoreGiveFromISR(self->secondsSyncronisation, &higherPriorityTaskWoken);
}
portEND_SWITCHING_ISR(higherPriorityTaskWoken);
}
bool repairProcess_isProcessRunning(struct RepairProcess* self)
{
return self->signalProfileGenerator.isProcessRunning;
}
uint32_t repairProcess_getRemainingRepairTime(const struct RepairProcess* self)
{
uint32_t returnValue;
if ((self->initialized) && (self->isProcessRunning))
{
if (self->voltageHoldTimer >= self->secondsCounter)
{
returnValue = (self->voltageHoldTimer - self->secondsCounter);
}
else
{
// ERROR - negative time
returnValue = 0;
}
}
else
{
returnValue = 0xFFFFFFFF;
}
return returnValue;
return SignalProfileGenerator_getRemainingTime(&self->signalProfileGenerator);
}
struct RepairProcessRow* repairProcess_getRowInformation(const struct RepairProcess* self, int rowIndex)
const struct RepairProcessRow* repairProcess_getRowInformation(const struct RepairProcess* self, int rowIndex)
{
return &self->row[rowIndex];
}
@@ -221,171 +193,113 @@ const struct Observable* repairProcess_getObservable(struct RepairProcess* self)
}
void repairProcess_pauseProcess(struct RepairProcess* self)
{
SignalProfileGenerator_pause(&self->signalProfileGenerator);
}
void repairProcess_continueProcess(struct RepairProcess* self)
{
SignalProfileGenerator_continue(&self->signalProfileGenerator);
}
static void repairProcess_task(void* parameters)
{
struct RepairProcess* self = (struct RepairProcess*)parameters;
int signal;
int loopCounter;
self->taskIsRunning = true;
// Reset the seconds counter to 0
self->secondsCounter = 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);
MAX5715Channel_setValue(self->row[1].dacChannel, self->row[1].lastDACValue);
MAX5715Channel_setValue(self->row[2].dacChannel, self->row[2].lastDACValue);
while(self->runTask)
{
LOGGER_DEBUG(mainLog, "----------------------------------------");
xSemaphoreTake(self->secondsSyncronisation, portMAX_DELAY);
LOGGER_DEBUG(mainLog, "----------------------------------------");
// The signal profile is identical for all rows in the regulation process
signal = SignalProfileGenerator(self);
LOGGER_DEBUG(mainLog, "Signal: %d", signal);
SignalProfileGenerator_calculate(&self->signalProfileGenerator);
LOGGER_DEBUG(mainLog, "Signal: %d, TimeToRemain %d", self->signalProfileGenerator.signal, SignalProfileGenerator_getRemainingTime(&self->signalProfileGenerator));
// Check for correct signal
if (signal >= 0)
if (self->signalProfileGenerator.signal >= 0)
{
// 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++)
for (loopCounter = ((PCBA_getInstance()->pcba == PCBA_Tesla) ? 1 : 0); loopCounter <= ((PCBA_getInstance()->pcba == PCBA_Tesla) ? 1 : 2); loopCounter++)
{
// Read the last ADC channel value
ADCChannel_read(self->row[loopCounter].adcChannel, &self->row[loopCounter].lastADCValue);
// Calculate the error
self->row[loopCounter].pidError = signal - (int)self->row[loopCounter].lastADCValue;
// Calculate the PID
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 (self->row[loopCounter].lastDACValue > 0xFFF)
if (!self->row[loopCounter].errorData.rowHasError)
{
self->row[loopCounter].lastDACValue = 0xFFF;
}
else if (self->row[loopCounter].lastDACValue < 0)
{
self->row[loopCounter].lastDACValue = 0;
}
// Send the PID value to the DAC
MAX5715Channel_setValue(self->row[loopCounter].dacChannel, self->row[loopCounter].lastDACValue);
// Read the last ADC channel value
ADCChannel_read(self->row[loopCounter].adcChannel, &self->row[loopCounter].lastADCValue);
// Calculate the error
self->row[loopCounter].pidError = self->signalProfileGenerator.signal - (int)self->row[loopCounter].lastADCValue;
// Calculate the PID
int pidCalculate = PID_calculate(&self->row[loopCounter].pid, self->row[loopCounter].pidError);
LOGGER_DEBUG(mainLog, "Row %d --- ADC: %d Error: %d PID: %d", loopCounter, self->row[loopCounter].lastADCValue, self->row[loopCounter].pidError, self->row[loopCounter].lastDACValue);
///TODO MUST BE MOVED TO DACDevice
// Verify that pid value does not overflow the DAC
if (pidCalculate > 0xFFF)
{
self->row[loopCounter].lastDACValue = 0xFFF;
}
else if (pidCalculate < 0)
{
self->row[loopCounter].lastDACValue = 0;
}
else
{
self->row[loopCounter].lastDACValue = pidCalculate;
}
// Check if the error condition exceeds the tolerated duration
if (self->row[loopCounter].errorData.outOfLimitsCounter >= self->row[loopCounter].errorData.outOfLimitsDuration)
{
// Tolerated duration exceeded - put the current ROW in error state
self->row[loopCounter].errorData.rowHasError = true;
}
else
{
// Calculate/Update ERROR conditions
if ((self->row[loopCounter].lastADCValue < self->signalProfileGenerator.signal - self->row[loopCounter].errorData.outOfLimitsValue)
||(self->row[loopCounter].lastADCValue > self->signalProfileGenerator.signal + self->row[loopCounter].errorData.outOfLimitsValue))
{
// The current ADC value is outside the error boundaries
self->row[loopCounter].errorData.outOfLimitsCounter += 1;
LOGGER_WARNING(mainLog, "Row %d outside boundaries", loopCounter);
}
else
{
self->row[loopCounter].errorData.outOfLimitsCounter = 0;
}
}
// Send the PID value to the DAC
MAX5715Channel_setValue(self->row[loopCounter].dacChannel, self->row[loopCounter].lastDACValue);
LOGGER_DEBUG(mainLog, "Row %d --- ADC: %d Error: %d PID: %d", loopCounter, self->row[loopCounter].lastADCValue, self->row[loopCounter].pidError, self->row[loopCounter].lastDACValue);
}
else
{
// ROW is in error state
self->row[loopCounter].lastDACValue = 0;
MAX5715Channel_setValue(self->row[loopCounter].dacChannel, self->row[loopCounter].lastDACValue);
LOGGER_ERROR(mainLog, "Row %d --- Row in ERROR state", loopCounter);
}
}
}
// Notify observers that an update is available
Observable_notifyObservers(&self->observable, NULL);
self->secondsCounter++;
}
LOGGER_INFO(mainLog, "Deleting repairProcess task");
self->taskIsDeleted = true;
self->taskIsRunning = false;
vTaskDelete(NULL);
}
static int SignalProfileGenerator(struct RepairProcess* self)
{
int returnValue = 0;
if (self->initialized)
{
switch (self->currentState)
{
case PREPARE:
{
// Prepare a new repair process
//Load the timers
self->startTime = self->secondsCounter;
self->softStartTimer = self->secondsCounter + self->repairPreset->preset[self->currentPresetIndex].softstartDuration;
self->voltageHoldTimer = self->secondsCounter + self->repairPreset->preset[self->currentPresetIndex].duration;
self->currentState = SOFTSTART;
break;
}
case SOFTSTART:
{
self->isProcessRunning = true;
// Still in Softstart
int startVoltage = 0;
// If first preset, start voltage is 0
if (self->currentPresetIndex == 0)
{
startVoltage = 450;
}
else
{
// Softstart for another stage - start voltage is hold voltage of previous preset
startVoltage = self->repairPreset->preset[self->currentPresetIndex - 1].voltage;
}
returnValue = ((self->repairPreset->preset[self->currentPresetIndex].voltage - startVoltage) / self->repairPreset->preset[self->currentPresetIndex].softstartDuration) * (self->secondsCounter - self->startTime) + startVoltage;
// Check for end of softstart
if (self->softStartTimer < self->secondsCounter)
{
// softstart finished
self->currentState = VOLTAGE_HOLD;
}
break;
}
case VOLTAGE_HOLD:
{
returnValue = self->repairPreset->preset[self->currentPresetIndex].voltage;
// Check for end of voltage hold
if (self->voltageHoldTimer < self->secondsCounter)
{
// softstart finished
self->currentState = FINISH_VERIFY;
}
break;
}
case PAUSE:
{
break;
}
case PAUSE_RESTORE:
{
break;
}
case FINISH_VERIFY:
{
// The current preset might contain multiple stages, so before going to FINISHED state
// verify that no further stage must be entered
// presetIndex carries the current index in the preset array
// number of stages is 1-based (Starting with 1) while presetIndex is 0-based
// So, the verification must compensate for the different bases
if (self->repairPreset->numberOfStages > (self->currentPresetIndex + 1))
{
// A next stage is available
self->currentPresetIndex++;
self->currentState = PREPARE;
}
else
{
self->currentState = FINISHED;
}
break;
}
case FINISHED:
{
self->isProcessRunning = false;
returnValue = 0;
break;
}
}
}
else
{
returnValue = -1;
}
return returnValue;
}

View File

@@ -0,0 +1,97 @@
// -----------------------------------------------------------------------------
/// @file repairProcessRow.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 repairProcessRow.c
/// @ingroup {group_name}
// -----------------------------------------------------------------------------
// Include files
// -----------------------------------------------------------------------------
#include "repairProcessRow.h"
// -----------------------------------------------------------------------------
// Constant and macro definitions
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// Type definitions
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// File-scope variables
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// Function declarations
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// Function definitions
// -----------------------------------------------------------------------------
ErrorStatus repairProcessRow_construct(struct RepairProcessRow* self, const struct AdcChannel* adcChannel, const struct MAX5715_DAC* dacChannel, int outOfLimitsDuration, int outOfLimitsValue)
{
ErrorStatus returnValue = SUCCESS;
if (!self->initialized)
{
if (returnValue == SUCCESS)
{
self->adcChannel = adcChannel;
self->dacChannel = dacChannel;
self->lastADCValue = 0;
self->lastDACValue = 0;
self->pid.initialized = false;
self->errorData.rowHasError = false;
self->errorData.outOfLimitsCounter = 0;
self->errorData.outOfLimitsDuration = outOfLimitsDuration;
self->errorData.outOfLimitsValue = outOfLimitsValue;
}
if (returnValue == SUCCESS)
{
returnValue = PID_construct(&self->pid, 3000, 2000, 0, 0, 100000000);
}
if (returnValue == SUCCESS)
{
self->initialized = true;
}
}
else
{
returnValue = ERROR;
}
return returnValue;
}
void repairProcessRow_destruct(struct RepairProcessRow* self)
{
PID_destruct(&self->pid);
self->initialized = false;
}

View File

@@ -79,7 +79,7 @@ ErrorStatus repairProcesses_startMainRepairProcess(const struct RepairPreset* re
void repairProcesses_abortMainRepairProcess(void)
{
Interlock_setEXTI(interlock, DISABLE);
if (PCBA_getInstance()->pcba == Tesla)
if (PCBA_getInstance()->pcba == PCBA_Tesla)
{
Interlock_setEXTI(teslalock, DISABLE);
}
@@ -94,7 +94,7 @@ void repairProcesses_abortMainRepairProcess(void)
static ErrorStatus repairProcesses_feedMainRepairProcessSecondsCounter(const void* const data)
{
repairProcess_feedSecondsCounterFromISR(&mainRepairProcess);
repairProcess_secondsFeedFromISR(&mainRepairProcess);
return SUCCESS;
}