Files
hsb/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/hsb-mrts/src/repairProcess.c
2017-10-10 12:46:41 +00:00

325 lines
10 KiB
C

// -----------------------------------------------------------------------------
/// @file repairProcess.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 repairProcess.c
/// @ingroup {group_name}
// -----------------------------------------------------------------------------
// Include files
// -----------------------------------------------------------------------------
#include "FreeRTOS.h"
#include "queue.h"
#include "semphr.h"
#include "task.h"
#include "repairProcess.h"
#include "repairPreset.h"
#include "Logger.h"
#include "MAX5715.h"
#include "PCBA.h"
// -----------------------------------------------------------------------------
// Constant and macro definitions
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// Type definitions
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// File-scope variables
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// Function declarations
// -----------------------------------------------------------------------------
static void repairProcess_task(void* parameters);
static void SignalProfileGenerator();
// -----------------------------------------------------------------------------
// Function definitions
// -----------------------------------------------------------------------------
ErrorStatus repairProcess_construct(struct RepairProcess* self, struct RepairProcessParameters* parameters, int taskPriority, uint16_t stackSize)
{
ErrorStatus returnValue = SUCCESS;
if (!self->initialized)
{
// Create a semaphore to sync access to the display shadow
vSemaphoreCreateBinary(self->secondsSyncronisation);
xSemaphoreTake(self->secondsSyncronisation, 0);
BaseType_t rv = xTaskCreate(repairProcess_task, "RepairProcess", stackSize, self, taskPriority, &self->taskHandle);
if (rv != pdTRUE)
{
returnValue = ERROR;
}
if (returnValue == SUCCESS)
{
self->runTask = true;
self->initialized = true;
self->currentState = PREPARE;
self->adcRow1 = parameters->adcRow1;
self->adcRow2 = parameters->adcRow2;
self->adcRow3 = parameters->adcRow3;
self->dacRow1 = parameters->dacRow1;
self->dacRow2 = parameters->dacRow2;
self->dacRow3 = parameters->dacRow3;
LOGGER_INFO(mainLog, "Repair Process task started");
}
else
{
LOGGER_ERROR(mainLog, "FAILED to start repair Process with code %d", (int)rv);
}
}
else
{
returnValue = ERROR;
}
return returnValue;
}
void repairProcess_feedSecondsCounter(struct RepairProcess* self)
{
if (self->initialized)
{
xSemaphoreGive(self->secondsSyncronisation);
}
}
void repairProcess_feedSecondsCounterFromISR(struct RepairProcess* self)
{
portBASE_TYPE higherPriorityTaskWoken = pdFALSE;
if (self->initialized)
{
xSemaphoreGiveFromISR(self->secondsSyncronisation, &higherPriorityTaskWoken);
}
portEND_SWITCHING_ISR(higherPriorityTaskWoken);
}
ErrorStatus repairProcess_getRepairTime(const struct RepairProcess* self, uint32_t* repairTime)
{
ErrorStatus returnValue = SUCCESS;
if (self->initialized)
{
*repairTime = self->secondsCounter;
}
else
{
returnValue = ERROR;
}
return returnValue;
}
static void repairProcess_task(void* parameters)
{
struct RepairProcess* self = (struct RepairProcess*)parameters;
uint8_t presetIndex = 0;
uint32_t softStartTimer = 0;
uint32_t voltageHoldTimer = 0;
uint16_t voltageTarget = 0;
uint16_t voltageRow1 = 0;
uint16_t voltageRow2 = 0;
uint16_t voltageRow3 = 0;
// Reset the seconds counter to 0
self->secondsCounter = 0;
while(self->runTask)
{
xSemaphoreTake(self->secondsSyncronisation, portMAX_DELAY);
switch (self->currentState)
{
case PREPARE:
{
LOGGER_DEBUG(mainLog, "Repair Process: Preparing new stage of repair process");
// Prepare a new repair process
//Load the timers
softStartTimer = self->secondsCounter + self->repairPreset->preset[presetIndex].softstartDuration;
LOGGER_DEBUG(mainLog, "Softstart timer is %d (%d + %d)", softStartTimer, self->secondsCounter, self->repairPreset->preset[presetIndex].softstartDuration);
voltageHoldTimer = self->secondsCounter + self->repairPreset->preset[presetIndex].duration;
LOGGER_DEBUG(mainLog, "Voltagehold timer is %d (%d + %d)", voltageHoldTimer, self->secondsCounter, self->repairPreset->preset[presetIndex].duration);
voltageTarget = self->repairPreset->preset[presetIndex].voltage;
voltageRow1 = 0;
voltageRow2 = 0;
voltageRow3 = 0;
// Anode and CathodeMCP run all 3 ADCs and DACs
MAX5715Channel_setValue(self->dacRow1, voltageRow1);
MAX5715Channel_setValue(self->dacRow2, voltageRow2);
MAX5715Channel_setValue(self->dacRow3, voltageRow3);
///TODO CHECK FOR SAFETLY BEFORE START
self->currentState = SOFTSTART;
break;
}
case SOFTSTART:
{
// Perform softstart / ramp-up
// if (PCBA_getInstance()->pcba == Tesla)
// {
// // Tesla repair only runs ADC row2 and DAC row2
// calculateSoftStartStep(self->secondsCounter, softStartTimer, voltageTarget, &voltageRow2);
// LOGGER_DEBUG(mainLog, "Softstart running -> new target is %x", voltageRow2);
// MAX5715Channel_setValue(self->dacRow2, voltageRow2);
// }
// else if ((PCBA_getInstance()->pcba == Anode) || (PCBA_getInstance()->pcba == CathodeMCP))
// {
// calculateSoftStartStep(self->secondsCounter, softStartTimer, voltageTarget, &voltageRow1);
// calculateSoftStartStep(self->secondsCounter, softStartTimer, voltageTarget, &voltageRow2);
// calculateSoftStartStep(self->secondsCounter, softStartTimer, voltageTarget, &voltageRow3);
// LOGGER_DEBUG(mainLog, "Softstart running -> new target is %x %x %x", voltageRow1, voltageRow2, voltageRow3);
//
// MAX5715Channel_setValue(self->dacRow1, voltageRow1);
// MAX5715Channel_setValue(self->dacRow2, voltageRow2);
// MAX5715Channel_setValue(self->dacRow3, voltageRow3);
// }
// Check for end of softstart
if (softStartTimer < self->secondsCounter)
{
// softstart finished
self->currentState = VOLTAGE_HOLD;
}
break;
}
case VOLTAGE_HOLD:
{
// Actual repair state - hold target voltage until duration has passed
LOGGER_DEBUG(mainLog, "Voltage Hold running -> target is %x", voltageTarget);
if (PCBA_getInstance()->pcba == Tesla)
{
// Tesla repair only runs ADC row2 and DAC row2
MAX5715Channel_setValue(self->dacRow2, voltageTarget);
}
else if ((PCBA_getInstance()->pcba == Anode) || (PCBA_getInstance()->pcba == CathodeMCP))
{
MAX5715Channel_setValue(self->dacRow1, voltageTarget);
MAX5715Channel_setValue(self->dacRow2, voltageTarget);
MAX5715Channel_setValue(self->dacRow3, voltageTarget);
}
// Check for end of softstart
if (voltageHoldTimer < self->secondsCounter)
{
// softstart finished
self->currentState = FINISH_VERIFY;
}
break;
}
case PAUSE:
{
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 > (presetIndex + 1))
{
// A next stage is available
presetIndex++;
self->currentState = PREPARE;
LOGGER_DEBUG(mainLog, "Another stage is available");
}
else
{
self->currentState = FINISHED;
LOGGER_DEBUG(mainLog, "last stage reached");
}
break;
}
case FINISHED:
{
voltageRow1 = 0;
voltageRow2 = 0;
voltageRow3 = 0;
// Anode and CathodeMCP run all 3 ADCs and DACs
MAX5715Channel_setValue(self->dacRow1, voltageRow1);
MAX5715Channel_setValue(self->dacRow2, voltageRow2);
MAX5715Channel_setValue(self->dacRow3, voltageRow3);
LOGGER_DEBUG(mainLog, "Repair process finished");
break;
}
default:
LOGGER_ERROR(mainLog, "Repair Process state machine reached unknown state");
}
self->secondsCounter++;
}
LOGGER_INFO(mainLog, "Deleting repairProcess task");
vTaskDelete(self->taskHandle);
}