// ----------------------------------------------------------------------------- /// @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); }