Fixed several issues:
- ADC has now averaging - Pause screen added - Fixed display glitches for most parts git-svn-id: https://svn.vbchaos.nl/svn/hsb/trunk@258 05563f52-14a8-4384-a975-3d1654cca0fa
This commit is contained in:
@@ -69,6 +69,8 @@ struct Pid
|
|||||||
* @param Kp proportional constant
|
* @param Kp proportional constant
|
||||||
* @param Ki integration constant
|
* @param Ki integration constant
|
||||||
* @param Kd differential constant
|
* @param Kd differential constant
|
||||||
|
* @param iMin Minimum value for integrator
|
||||||
|
* @param iMax Maximum value for integrator
|
||||||
*
|
*
|
||||||
* @return ErrorStatus SUCCESS if initialisation was successful
|
* @return ErrorStatus SUCCESS if initialisation was successful
|
||||||
* ERRROR otherwise
|
* ERRROR otherwise
|
||||||
@@ -79,6 +81,20 @@ struct Pid
|
|||||||
extern ErrorStatus PID_construct(struct Pid* self, int Kp, int Ki, int Kd, int iMin, int iMax);
|
extern ErrorStatus PID_construct(struct Pid* self, int Kp, int Ki, int Kd, int iMin, int iMax);
|
||||||
|
|
||||||
|
|
||||||
|
/** ----------------------------------------------------------------------------
|
||||||
|
* PID_destruct
|
||||||
|
* Destructor for a PID regulator
|
||||||
|
*
|
||||||
|
* @param self PID object to destruct
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*
|
||||||
|
* @todo
|
||||||
|
* -----------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
extern void PID_destruct(struct Pid* self);
|
||||||
|
|
||||||
|
|
||||||
/** ----------------------------------------------------------------------------
|
/** ----------------------------------------------------------------------------
|
||||||
* PID_calculate
|
* PID_calculate
|
||||||
* Calculate
|
* Calculate
|
||||||
|
|||||||
@@ -145,16 +145,28 @@ static void InterlockTask (void* parameters)
|
|||||||
|
|
||||||
while(1)
|
while(1)
|
||||||
{
|
{
|
||||||
|
// Interlock was OK when the IRQ became active
|
||||||
|
// This tasks debounces the Interlock against accidental detections
|
||||||
|
// THe semaphore is given from ISR
|
||||||
xSemaphoreTake(self->semaphore, portMAX_DELAY);
|
xSemaphoreTake(self->semaphore, portMAX_DELAY);
|
||||||
|
// Wait for the debounce time
|
||||||
vTaskDelay(self->waitToDebounce_ms);
|
vTaskDelay(self->waitToDebounce_ms);
|
||||||
|
// Check if the Interrupt was justified
|
||||||
if (self->ID == COMMON_INTERLOCK)
|
if (!Interlock_isClosed(self))
|
||||||
{
|
{
|
||||||
Error_postError(INTERLOCK_COMMON_FAIL);
|
// The Interlock is open, so the Interrupt was justified
|
||||||
|
if (self->ID == COMMON_INTERLOCK)
|
||||||
|
{
|
||||||
|
Error_postError(INTERLOCK_COMMON_FAIL);
|
||||||
|
}
|
||||||
|
else if (self->ID == TESLA_INTERLOCK)
|
||||||
|
{
|
||||||
|
Error_postError(INTERLOCK_TESLA_FAIL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (self->ID == TESLA_INTERLOCK)
|
else
|
||||||
{
|
{
|
||||||
Error_postError(INTERLOCK_TESLA_FAIL);
|
// False alarm
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -89,6 +89,12 @@ ErrorStatus PID_construct(struct Pid* self, int Kp, int Ki, int Kd, int iMin, in
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PID_destruct(struct Pid* self)
|
||||||
|
{
|
||||||
|
self->initialized = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int PID_calculate(struct Pid* self, int error)
|
int PID_calculate(struct Pid* self, int error)
|
||||||
{
|
{
|
||||||
int returnValue = 0;
|
int returnValue = 0;
|
||||||
|
|||||||
@@ -397,12 +397,21 @@ static ErrorStatus write(const struct DisplayDevice* self, const char* buffer, s
|
|||||||
ErrorStatus returnValue = SUCCESS;
|
ErrorStatus returnValue = SUCCESS;
|
||||||
if (self->initialized)
|
if (self->initialized)
|
||||||
{
|
{
|
||||||
|
if ((length + column) > NHD0420_NUMBER_OF_COLUMNS)
|
||||||
|
{
|
||||||
|
returnValue = ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
// Set cursor on display
|
// Set cursor on display
|
||||||
returnValue = NHD0420_setCursorToPosition((const struct NHD0420*)self, row, column);
|
returnValue = NHD0420_setCursorToPosition((const struct NHD0420*)self, row, column);
|
||||||
|
|
||||||
if (returnValue == SUCCESS)
|
if (returnValue == SUCCESS)
|
||||||
{
|
{
|
||||||
returnValue = NHD0420_sendData((const struct NHD0420*)self, buffer, length);
|
int loopcounter;
|
||||||
|
for (loopcounter = 0; loopcounter < length; loopcounter++)
|
||||||
|
{
|
||||||
|
returnValue = NHD0420_sendData((const struct NHD0420*)self, &buffer[loopcounter], 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -43,7 +43,7 @@
|
|||||||
// Constant and macro definitions
|
// Constant and macro definitions
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#define ADC_AVERAGE_DEPTH (10)
|
||||||
#define ADC_NUMBER_OF_CHANNELS (18) // 16 IOs + Temp + Vcc
|
#define ADC_NUMBER_OF_CHANNELS (18) // 16 IOs + Temp + Vcc
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
@@ -85,7 +85,7 @@ struct Adc
|
|||||||
ADC_TypeDef* ADCx;
|
ADC_TypeDef* ADCx;
|
||||||
ADC_InitTypeDef ADC_InitStruct;
|
ADC_InitTypeDef ADC_InitStruct;
|
||||||
bool useDMA;
|
bool useDMA;
|
||||||
bool useRanks;
|
int numberOfUsedChannels;
|
||||||
struct AdcChannel channel[ADC_NUMBER_OF_CHANNELS];
|
struct AdcChannel channel[ADC_NUMBER_OF_CHANNELS];
|
||||||
// Only necessary when the RANK parameter determines conversion order or RANK is used anyway
|
// Only necessary when the RANK parameter determines conversion order or RANK is used anyway
|
||||||
// For single conversions the READ function simply returns the converted value
|
// For single conversions the READ function simply returns the converted value
|
||||||
@@ -93,7 +93,7 @@ struct Adc
|
|||||||
// When initialising an ADC channel to a regular group, the RANK parameter determines the
|
// When initialising an ADC channel to a regular group, the RANK parameter determines the
|
||||||
// order of convertions. E.G. channel 5 can be put first while channel 1 can be put last.
|
// order of convertions. E.G. channel 5 can be put first while channel 1 can be put last.
|
||||||
// The array index stands for the RANK
|
// The array index stands for the RANK
|
||||||
uint16_t channelValue[ADC_NUMBER_OF_CHANNELS];
|
uint16_t channelValue[ADC_NUMBER_OF_CHANNELS * ADC_AVERAGE_DEPTH];
|
||||||
bool initialized;
|
bool initialized;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -90,4 +90,7 @@ extern ErrorStatus RTC_construct(struct Rtc* self);
|
|||||||
extern struct Observable* RTC_getObservable(struct Rtc* self);
|
extern struct Observable* RTC_getObservable(struct Rtc* self);
|
||||||
|
|
||||||
|
|
||||||
|
extern void RTC_calculateTimeFromSeconds(uint32_t seconds, struct Time* time);
|
||||||
|
|
||||||
|
|
||||||
#endif /* INC_RTC_H_ */
|
#endif /* INC_RTC_H_ */
|
||||||
|
|||||||
@@ -82,6 +82,7 @@ ErrorStatus ADC_construct(struct Adc* self, struct AdcParameters* parameters)
|
|||||||
self->channelValue[loopCounter] = 0;
|
self->channelValue[loopCounter] = 0;
|
||||||
}
|
}
|
||||||
self->initialized = true;
|
self->initialized = true;
|
||||||
|
self->numberOfUsedChannels = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return returnValue;
|
return returnValue;
|
||||||
@@ -98,8 +99,8 @@ void ADC_destruct (struct Adc* self)
|
|||||||
|
|
||||||
ADC_DeInit(self->ADCx);
|
ADC_DeInit(self->ADCx);
|
||||||
self->useDMA = false;
|
self->useDMA = false;
|
||||||
self->useRanks = false;
|
|
||||||
self->initialized = false;
|
self->initialized = false;
|
||||||
|
self->numberOfUsedChannels = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -169,7 +170,7 @@ ErrorStatus ADCChannel_construct(struct AdcChannel* self, struct Adc* parent, st
|
|||||||
{
|
{
|
||||||
returnValue = ERROR;
|
returnValue = ERROR;
|
||||||
}
|
}
|
||||||
if (parameters->channel < 18)
|
if (parameters->channel < ADC_NUMBER_OF_CHANNELS)
|
||||||
{
|
{
|
||||||
self->channel = parameters->channel;
|
self->channel = parameters->channel;
|
||||||
}
|
}
|
||||||
@@ -183,11 +184,12 @@ ErrorStatus ADCChannel_construct(struct AdcChannel* self, struct Adc* parent, st
|
|||||||
{
|
{
|
||||||
parent->channel[self->channel] = *self;
|
parent->channel[self->channel] = *self;
|
||||||
self->parent = parent;
|
self->parent = parent;
|
||||||
self->ADC_SampleTime = parameters->ADC_SampleTime;
|
self->ADC_SampleTime = parameters->ADC_SampleTime;
|
||||||
|
self->initialized = true;
|
||||||
|
self->parent->numberOfUsedChannels++;
|
||||||
|
|
||||||
//TODO MAKE SURE EACH RANK IS USED ONLY ONCE
|
//TODO MAKE SURE EACH RANK IS USED ONLY ONCE
|
||||||
ADC_RegularChannelConfig(self->parent->ADCx, self->channel, self->Rank, self->ADC_SampleTime);
|
ADC_RegularChannelConfig(self->parent->ADCx, self->channel, self->Rank, self->ADC_SampleTime);
|
||||||
self->parent->useRanks = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -203,6 +205,7 @@ ErrorStatus ADCChannel_construct(struct AdcChannel* self, struct Adc* parent, st
|
|||||||
void ADCChannel_destruct(struct AdcChannel* self)
|
void ADCChannel_destruct(struct AdcChannel* self)
|
||||||
{
|
{
|
||||||
self->initialized = false;
|
self->initialized = false;
|
||||||
|
self->parent->numberOfUsedChannels--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -210,13 +213,16 @@ ErrorStatus ADCChannel_read(const struct AdcChannel* self, uint16_t* value)
|
|||||||
{
|
{
|
||||||
ErrorStatus returnValue = SUCCESS;
|
ErrorStatus returnValue = SUCCESS;
|
||||||
|
|
||||||
// For reading it is important whether Ranks are enabled or not
|
// Reading ADC value is automatically combined with an floating averaging
|
||||||
if (self->parent->useRanks)
|
uint32_t average = 0;
|
||||||
|
int loopCounter;
|
||||||
|
for (loopCounter = self->channel; loopCounter < self->parent->numberOfUsedChannels * ADC_AVERAGE_DEPTH; loopCounter = loopCounter + self->parent->numberOfUsedChannels)
|
||||||
{
|
{
|
||||||
// Rank starts with 1 - must be reduced by one in order tu be used as index
|
average = average + self->parent->channelValue[loopCounter];
|
||||||
// *value = self->parent->channelValue[self->Rank - 1];
|
|
||||||
*value = self->parent->channelValue[self->channel];
|
|
||||||
}
|
}
|
||||||
|
*value = average / ADC_AVERAGE_DEPTH;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return returnValue;
|
return returnValue;
|
||||||
}
|
}
|
||||||
@@ -238,3 +244,4 @@ static ErrorStatus read(const struct IODevice* self, char* buffer, size_t length
|
|||||||
|
|
||||||
return returnValue;
|
return returnValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -555,7 +555,7 @@ static ErrorStatus initPeriphery(void)
|
|||||||
DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;
|
DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;
|
||||||
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)adc1->channelValue;
|
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)adc1->channelValue;
|
||||||
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
|
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
|
||||||
DMA_InitStructure.DMA_BufferSize = ADC1_NUMBER_OF_USED_CHANNELS;
|
DMA_InitStructure.DMA_BufferSize = ADC_AVERAGE_DEPTH * ADC1_NUMBER_OF_USED_CHANNELS;
|
||||||
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
|
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
|
||||||
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
|
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
|
||||||
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
|
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
|
||||||
@@ -570,7 +570,7 @@ static ErrorStatus initPeriphery(void)
|
|||||||
/* --------------------------------------------------------------------*/
|
/* --------------------------------------------------------------------*/
|
||||||
/* ADC1 - for module feedback */
|
/* ADC1 - for module feedback */
|
||||||
/* --------------------------------------------------------------------*/
|
/* --------------------------------------------------------------------*/
|
||||||
IRQ_setInterruptProperties(ADC1_2_IRQn, 12, 12, DISABLE);
|
IRQ_setInterruptProperties(ADC1_2_IRQn, 12, 12, ENABLE);
|
||||||
adc1Parameters->ADC_Mode = ADC_Mode_Independent;
|
adc1Parameters->ADC_Mode = ADC_Mode_Independent;
|
||||||
adc1Parameters->ADC_ScanConvMode = ENABLE;
|
adc1Parameters->ADC_ScanConvMode = ENABLE;
|
||||||
adc1Parameters->ADC_ContinuousConvMode = ENABLE;
|
adc1Parameters->ADC_ContinuousConvMode = ENABLE;
|
||||||
|
|||||||
@@ -99,6 +99,23 @@ struct Observable* RTC_getObservable(struct Rtc* self)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void RTC_calculateTimeFromSeconds(uint32_t seconds, struct Time* time)
|
||||||
|
{
|
||||||
|
if (seconds > 0)
|
||||||
|
{
|
||||||
|
time->hours = (seconds / (60 * 60));
|
||||||
|
time->minutes = (seconds - (time->hours * 60 * 60)) / 60;
|
||||||
|
time->seconds = (seconds - (time->hours * 60 * 60) - (time->minutes * 60));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Prevent underflows
|
||||||
|
time->hours = 0;
|
||||||
|
time->minutes = 0;
|
||||||
|
time->seconds = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void RTC_IRQHandler(void)
|
void RTC_IRQHandler(void)
|
||||||
{
|
{
|
||||||
static signed portBASE_TYPE higherPriorityTaskWoken = pdFALSE;
|
static signed portBASE_TYPE higherPriorityTaskWoken = pdFALSE;
|
||||||
|
|||||||
@@ -103,4 +103,7 @@ extern ErrorStatus hsb_solenoidLock (void);
|
|||||||
*/
|
*/
|
||||||
extern ErrorStatus hsb_solenoidUnlock (void);
|
extern ErrorStatus hsb_solenoidUnlock (void);
|
||||||
|
|
||||||
|
|
||||||
|
extern ErrorStatus hsb_enableSafety(void);
|
||||||
|
extern ErrorStatus hsb_disableSafety(void);
|
||||||
#endif /* HSB_MRTS_H_ */
|
#endif /* HSB_MRTS_H_ */
|
||||||
|
|||||||
@@ -71,6 +71,7 @@ typedef enum
|
|||||||
REPAIR_RUNNING,
|
REPAIR_RUNNING,
|
||||||
REPAIR_ASK_PAUSE,
|
REPAIR_ASK_PAUSE,
|
||||||
REPAIR_PAUSE,
|
REPAIR_PAUSE,
|
||||||
|
FINISH_CONTROL,
|
||||||
FINISH,
|
FINISH,
|
||||||
ERROR_STATE,
|
ERROR_STATE,
|
||||||
WARNING_STATE,
|
WARNING_STATE,
|
||||||
|
|||||||
@@ -94,6 +94,7 @@ struct RepairProcess
|
|||||||
int TaskPriority;
|
int TaskPriority;
|
||||||
uint16_t stackSize;
|
uint16_t stackSize;
|
||||||
bool runTask;
|
bool runTask;
|
||||||
|
bool taskIsDeleted;
|
||||||
SemaphoreHandle_t secondsSyncronisation;
|
SemaphoreHandle_t secondsSyncronisation;
|
||||||
uint32_t startTime;
|
uint32_t startTime;
|
||||||
uint32_t secondsCounter;
|
uint32_t secondsCounter;
|
||||||
@@ -181,16 +182,16 @@ extern void repairProcess_feedSecondsCounterFromISR(struct RepairProcess* self);
|
|||||||
|
|
||||||
/** ----------------------------------------------------------------------------
|
/** ----------------------------------------------------------------------------
|
||||||
* repairProcess_getRemainingRepairTime
|
* repairProcess_getRemainingRepairTime
|
||||||
* Returns the currently remaining repair time in a struct Time
|
* Returns the currently remaining repair time in seconds
|
||||||
*
|
*
|
||||||
* @param self The repair process object
|
* @param self The repair process object
|
||||||
*
|
*
|
||||||
* @return struct Time The remaining repair time
|
* @return uint32_t The remaining repair time
|
||||||
*
|
*
|
||||||
* @todo
|
* @todo
|
||||||
* -----------------------------------------------------------------------------
|
* -----------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
extern struct Time repairProcess_getRemainingRepairTime(const struct RepairProcess* self);
|
extern uint32_t repairProcess_getRemainingRepairTime(const struct RepairProcess* self);
|
||||||
|
|
||||||
|
|
||||||
/** ----------------------------------------------------------------------------
|
/** ----------------------------------------------------------------------------
|
||||||
@@ -219,6 +220,6 @@ extern struct RepairProcessRow* repairProcess_getRowInformation(const struct Rep
|
|||||||
* @todo
|
* @todo
|
||||||
* -----------------------------------------------------------------------------
|
* -----------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
extern struct Observable* repairProcess_getObservable(struct RepairProcess* self);
|
extern const struct Observable* repairProcess_getObservable(struct RepairProcess* self);
|
||||||
|
|
||||||
#endif /* REPAIRPROCESS_H_ */
|
#endif /* REPAIRPROCESS_H_ */
|
||||||
|
|||||||
@@ -126,6 +126,7 @@ ErrorStatus Display_clearScreen(struct Display* self)
|
|||||||
{
|
{
|
||||||
ErrorStatus returnValue = SUCCESS;
|
ErrorStatus returnValue = SUCCESS;
|
||||||
returnValue = DisplayDevice_clear(self->displayDevice);
|
returnValue = DisplayDevice_clear(self->displayDevice);
|
||||||
|
vTaskDelay(5);
|
||||||
Display_clearShadow(self);
|
Display_clearShadow(self);
|
||||||
return returnValue;
|
return returnValue;
|
||||||
}
|
}
|
||||||
@@ -309,6 +310,7 @@ static void DisplayTask(void* parameters)
|
|||||||
|
|
||||||
size_t rowStart;
|
size_t rowStart;
|
||||||
size_t columnStart;
|
size_t columnStart;
|
||||||
|
|
||||||
while (self->runTask)
|
while (self->runTask)
|
||||||
{
|
{
|
||||||
// Wait until a write or refresh function has requested this task to write to the display
|
// Wait until a write or refresh function has requested this task to write to the display
|
||||||
@@ -406,7 +408,7 @@ static void DisplayTask(void* parameters)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Task has been marked to end - after leaving the endless loop, end/delete this task
|
// Task has been marked to end - after leaving the endless loop, end/delete this task
|
||||||
vTaskDelete(self->taskHandle);
|
vTaskDelete(NULL);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -30,8 +30,10 @@
|
|||||||
#include "hsb-mrts.h"
|
#include "hsb-mrts.h"
|
||||||
|
|
||||||
#include "Display.h"
|
#include "Display.h"
|
||||||
|
#include "Error.h"
|
||||||
|
|
||||||
#include "platform.h"
|
#include "platform.h"
|
||||||
|
#include "Interlock.h"
|
||||||
#include "Logger.h"
|
#include "Logger.h"
|
||||||
#include "PCBA.h"
|
#include "PCBA.h"
|
||||||
#include "Version.h"
|
#include "Version.h"
|
||||||
@@ -104,3 +106,81 @@ ErrorStatus hsb_solenoidUnlock (void)
|
|||||||
{
|
{
|
||||||
return GPIO_setValue(solenoid, true);
|
return GPIO_setValue(solenoid, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ErrorStatus hsb_enableSafety(void)
|
||||||
|
{
|
||||||
|
ErrorStatus returnValue = SUCCESS;
|
||||||
|
|
||||||
|
// First, Lock the cover
|
||||||
|
if (returnValue == SUCCESS)
|
||||||
|
{
|
||||||
|
hsb_solenoidLock();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (returnValue == SUCCESS)
|
||||||
|
{
|
||||||
|
// Check for INTERLOCK CLOSE
|
||||||
|
if (Interlock_isClosed(interlock))
|
||||||
|
{
|
||||||
|
// Enable Interrupt for interlock switch
|
||||||
|
Interlock_setEXTI(interlock, ENABLE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Error_postError(INTERLOCK_COMMON_FAIL);
|
||||||
|
returnValue = ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (returnValue == SUCCESS)
|
||||||
|
{
|
||||||
|
// TESLA has a second interlock that must be closed
|
||||||
|
if (PCBA_getInstance()->pcba == Tesla)
|
||||||
|
{
|
||||||
|
if (Interlock_isClosed(teslalock))
|
||||||
|
{
|
||||||
|
// Enable Interrupt for tesla interlock switch
|
||||||
|
Interlock_setEXTI(teslalock, ENABLE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Error_postError(INTERLOCK_TESLA_FAIL);
|
||||||
|
returnValue = ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if Interlock(s) closed, continue procedure
|
||||||
|
if (returnValue == SUCCESS)
|
||||||
|
{
|
||||||
|
// Power the circuit
|
||||||
|
if (GPIO_setValue(power6v5Enable, false) != SUCCESS)
|
||||||
|
{
|
||||||
|
Error_postError(POWERENABLE_FAIL);
|
||||||
|
returnValue = ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return returnValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ErrorStatus hsb_disableSafety(void)
|
||||||
|
{
|
||||||
|
ErrorStatus returnValue = SUCCESS;
|
||||||
|
|
||||||
|
// Power the circuit
|
||||||
|
if (GPIO_setValue(power6v5Enable, true) != SUCCESS)
|
||||||
|
{
|
||||||
|
Error_postError(POWERENABLE_FAIL);
|
||||||
|
returnValue = ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
Interlock_setEXTI(interlock, DISABLE);
|
||||||
|
// TESLA has a second interlock that must be closed
|
||||||
|
if (PCBA_getInstance()->pcba == Tesla)
|
||||||
|
{
|
||||||
|
Interlock_setEXTI(teslalock, DISABLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnValue;
|
||||||
|
}
|
||||||
|
|||||||
@@ -194,6 +194,8 @@ static void initTask(void* parameters)
|
|||||||
// IRQs are defined here
|
// IRQs are defined here
|
||||||
initPlatform();
|
initPlatform();
|
||||||
|
|
||||||
|
// Disable power
|
||||||
|
GPIO_setValue(power6v5Enable, true);
|
||||||
|
|
||||||
// Create a small task that only blinks a LED and flashes the identification letter on the display
|
// Create a small task that only blinks a LED and flashes the identification letter on the display
|
||||||
xTaskCreate(ledBlinkTask, (const char* const)"ledTask", 100, &ledTaskArguments, 0, &ledTaskHandle);
|
xTaskCreate(ledBlinkTask, (const char* const)"ledTask", 100, &ledTaskArguments, 0, &ledTaskHandle);
|
||||||
@@ -229,10 +231,7 @@ static void initTask(void* parameters)
|
|||||||
// Construct the repair menu
|
// Construct the repair menu
|
||||||
repairMenus_construct();
|
repairMenus_construct();
|
||||||
|
|
||||||
// Disable power
|
// xTaskCreate(printSystemInfoTask, (const char* const)"SysInfoTask", 512, NULL, 0, &sysTaskHandle);
|
||||||
GPIO_setValue(power6v5Enable, false);
|
|
||||||
|
|
||||||
xTaskCreate(printSystemInfoTask, (const char* const)"SysInfoTask", 512, NULL, 0, &sysTaskHandle);
|
|
||||||
|
|
||||||
// Delete this init task
|
// Delete this init task
|
||||||
vTaskDelete(NULL);
|
vTaskDelete(NULL);
|
||||||
|
|||||||
@@ -52,6 +52,7 @@
|
|||||||
#define MENU_HAS_CURSOR (true)
|
#define MENU_HAS_CURSOR (true)
|
||||||
#define MENU_HAS_NO_CURSOR (false)
|
#define MENU_HAS_NO_CURSOR (false)
|
||||||
|
|
||||||
|
#define REPAIRMENU_POPUPSCREEN_TIME (3)
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// Type definitions
|
// Type definitions
|
||||||
@@ -103,6 +104,7 @@ static void repairMenu_solenoidLock(struct RepairMenu* self, int cursorIndex);
|
|||||||
static void repairMenu_solenoidUnlock(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_startRepairProcess(struct RepairMenu* self, int cursorIndex);
|
||||||
static void repairMenu_stopRepairProcess(struct RepairMenu* self, int cursorIndex);
|
static void repairMenu_stopRepairProcess(struct RepairMenu* self, int cursorIndex);
|
||||||
|
static void repairMenu_abortRepairProcessAndGotoMainMenu(struct RepairMenu* self, int cursorIndex);
|
||||||
|
|
||||||
static ErrorStatus repairMenu_createMenu(struct RepairMenu* self);
|
static ErrorStatus repairMenu_createMenu(struct RepairMenu* self);
|
||||||
static ErrorStatus repairMenu_createMenuPage (struct MenuPage* self, bool hasCursor, int maxNumberOfRows);
|
static ErrorStatus repairMenu_createMenuPage (struct MenuPage* self, bool hasCursor, int maxNumberOfRows);
|
||||||
@@ -218,6 +220,8 @@ static void repairMenu_task(void* parameters)
|
|||||||
repairMenu_printMenu(self);
|
repairMenu_printMenu(self);
|
||||||
// Add cursor if necessary
|
// Add cursor if necessary
|
||||||
repairMenu_printCursor(self);
|
repairMenu_printCursor(self);
|
||||||
|
int tempScreenCounter;
|
||||||
|
T_MenuState tempMenuState;
|
||||||
|
|
||||||
while(self->runTask)
|
while(self->runTask)
|
||||||
{
|
{
|
||||||
@@ -239,11 +243,16 @@ static void repairMenu_task(void* parameters)
|
|||||||
else if (self->menuState == REPAIR_RUNNING)
|
else if (self->menuState == REPAIR_RUNNING)
|
||||||
{
|
{
|
||||||
// Check the remaining repair time
|
// Check the remaining repair time
|
||||||
struct Time remainingTime = repairProcess_getRemainingRepairTime(repairProcesses_getMainRepairProcess());
|
uint32_t remainingTime = repairProcess_getRemainingRepairTime(repairProcesses_getMainRepairProcess());
|
||||||
if ((remainingTime.hours == 0) && (remainingTime.minutes == 0) && (remainingTime.seconds == 0))
|
if (remainingTime > REPAIRMENU_POPUPSCREEN_TIME)
|
||||||
|
{
|
||||||
|
tempScreenCounter = remainingTime - REPAIRMENU_POPUPSCREEN_TIME;
|
||||||
|
tempMenuState = self->menuState;
|
||||||
|
}
|
||||||
|
if (remainingTime == 0)
|
||||||
{
|
{
|
||||||
// repair is finished
|
// repair is finished
|
||||||
repairMenu_changeState(self, FINISH);
|
repairMenu_changeState(self, FINISH_CONTROL);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -253,15 +262,26 @@ static void repairMenu_task(void* parameters)
|
|||||||
}
|
}
|
||||||
else if (self->menuState == REPAIR_ASK_PAUSE)
|
else if (self->menuState == REPAIR_ASK_PAUSE)
|
||||||
{
|
{
|
||||||
|
uint32_t remainingTime = repairProcess_getRemainingRepairTime(repairProcesses_getMainRepairProcess());
|
||||||
|
if (tempScreenCounter >= remainingTime)
|
||||||
|
{
|
||||||
|
// POPUP screen time is over, return to previous state
|
||||||
|
repairMenu_changeState(self, tempMenuState);
|
||||||
|
}
|
||||||
|
|
||||||
repairMenu_printAskPause(self);
|
repairMenu_printAskPause(self);
|
||||||
}
|
}
|
||||||
else if (self->menuState == REPAIR_PAUSE)
|
else if (self->menuState == REPAIR_PAUSE)
|
||||||
{
|
{
|
||||||
repairMenu_printPause(self);
|
repairMenu_printPause(self);
|
||||||
}
|
}
|
||||||
else if (self->menuState == FINISH)
|
else if (self->menuState == FINISH_CONTROL)
|
||||||
{
|
{
|
||||||
repairMenu_stopRepairProcess(self, 0);
|
repairMenu_stopRepairProcess(self, 0);
|
||||||
|
repairMenu_changeState(self, FINISH);
|
||||||
|
}
|
||||||
|
else if (self->menuState == FINISH)
|
||||||
|
{
|
||||||
repairMenu_printFinish(self);
|
repairMenu_printFinish(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -317,9 +337,10 @@ static void repairMenu_printRepair(struct RepairMenu* self)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
struct Time remainingTime = repairProcess_getRemainingRepairTime(repairProcesses_getMainRepairProcess());
|
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);
|
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);
|
Display_write(self->display, buffer, strlen(buffer), 1, 1);
|
||||||
|
|
||||||
// Regulation is unique for each row
|
// Regulation is unique for each row
|
||||||
@@ -346,7 +367,7 @@ static void repairMenu_printRepair(struct RepairMenu* self)
|
|||||||
static void repairMenu_printAskPause(struct RepairMenu* self)
|
static void repairMenu_printAskPause(struct RepairMenu* self)
|
||||||
{
|
{
|
||||||
Display_write(self->display, "REPAIR BUSY", strlen("REPAIR BUSY"), 2, 6);
|
Display_write(self->display, "REPAIR BUSY", strlen("REPAIR BUSY"), 2, 6);
|
||||||
Display_write(self->display, "Hit X to RESET", strlen("Hit X to RESET"), 3, 2);
|
Display_write(self->display, "Hit X to PAUSE", strlen("Hit X to RESET"), 3, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -571,58 +592,19 @@ static void repairMenu_startRepairProcess(struct RepairMenu* self, int cursorInd
|
|||||||
self->rpParameters.dacRow2 = &max5715->dac[1];
|
self->rpParameters.dacRow2 = &max5715->dac[1];
|
||||||
self->rpParameters.dacRow3 = &max5715->dac[2];
|
self->rpParameters.dacRow3 = &max5715->dac[2];
|
||||||
|
|
||||||
// First, Lock the cover
|
|
||||||
if (returnValue == SUCCESS)
|
if (returnValue == SUCCESS)
|
||||||
{
|
{
|
||||||
hsb_solenoidLock();
|
// Enable all safety features of the HSB setup
|
||||||
}
|
returnValue = hsb_enableSafety();
|
||||||
|
|
||||||
if (returnValue == SUCCESS)
|
|
||||||
{
|
|
||||||
// Check for INTERLOCK CLOSE
|
|
||||||
if (Interlock_isClosed(interlock))
|
|
||||||
{
|
|
||||||
// Enable Interrupt for interlock switch
|
|
||||||
Interlock_setEXTI(interlock, ENABLE);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Error_postError(INTERLOCK_COMMON_FAIL);
|
|
||||||
returnValue = ERROR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (returnValue == SUCCESS)
|
|
||||||
{
|
|
||||||
// TESLA has a second interlock that must be closed
|
|
||||||
if (PCBA_getInstance()->pcba == Tesla)
|
|
||||||
{
|
|
||||||
if (Interlock_isClosed(teslalock))
|
|
||||||
{
|
|
||||||
// Enable Interrupt for tesla interlock switch
|
|
||||||
Interlock_setEXTI(teslalock, ENABLE);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Error_postError(INTERLOCK_TESLA_FAIL);
|
|
||||||
returnValue = ERROR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// if Interlock(s) closed, continue procedure
|
|
||||||
if (returnValue == SUCCESS)
|
|
||||||
{
|
|
||||||
// Power the circuit
|
|
||||||
if (GPIO_setValue(power6v5Enable, false) != SUCCESS)
|
|
||||||
{
|
|
||||||
Error_postError(POWERENABLE_FAIL);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (returnValue == SUCCESS)
|
if (returnValue == SUCCESS)
|
||||||
{
|
{
|
||||||
// For MCP/Cathode, the right settings must be made
|
// For MCP/Cathode, the right settings must be made
|
||||||
|
if (PCBA_getInstance()->pcba == CathodeMCP)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
///TODO
|
///TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -652,6 +634,14 @@ static void repairMenu_stopRepairProcess(struct RepairMenu* self, int cursorInde
|
|||||||
{
|
{
|
||||||
repairProcesses_mainRepairProcessRemoveObserver(self->observer);
|
repairProcesses_mainRepairProcessRemoveObserver(self->observer);
|
||||||
repairProcesses_abortMainRepairProcess();
|
repairProcesses_abortMainRepairProcess();
|
||||||
|
hsb_disableSafety();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void repairMenu_abortRepairProcessAndGotoMainMenu(struct RepairMenu* self, int cursorIndex)
|
||||||
|
{
|
||||||
|
repairMenu_stopRepairProcess(self, cursorIndex);
|
||||||
|
repairMenu_changeState(self, MAINMENU);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -733,6 +723,7 @@ static ErrorStatus repairMenu_createMenu(struct RepairMenu* self)
|
|||||||
repairMenu_addKeyAction_GOTOSTATE(&self->menuArray[REPAIR_ASK_PAUSE], 'X', PRESSED, REPAIR_PAUSE);
|
repairMenu_addKeyAction_GOTOSTATE(&self->menuArray[REPAIR_ASK_PAUSE], 'X', PRESSED, REPAIR_PAUSE);
|
||||||
|
|
||||||
repairMenu_createMenuPage(&self->menuArray[REPAIR_PAUSE], MENU_HAS_NO_CURSOR, 4);
|
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_GOTOSTATE(&self->menuArray[REPAIR_PAUSE], 'E', PRESSED, REPAIR_RUNNING);
|
||||||
|
|
||||||
repairMenu_createMenuPage(&self->menuArray[FINISH], MENU_HAS_NO_CURSOR, 4);
|
repairMenu_createMenuPage(&self->menuArray[FINISH], MENU_HAS_NO_CURSOR, 4);
|
||||||
|
|||||||
@@ -25,6 +25,8 @@
|
|||||||
// Include files
|
// Include files
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include "stm32f10x.h"
|
||||||
|
|
||||||
#include "FreeRTOS.h"
|
#include "FreeRTOS.h"
|
||||||
#include "queue.h"
|
#include "queue.h"
|
||||||
#include "semphr.h"
|
#include "semphr.h"
|
||||||
@@ -91,6 +93,7 @@ ErrorStatus repairProcess_construct(struct RepairProcess* self, struct RepairPro
|
|||||||
Observable_construct(&self->observable);
|
Observable_construct(&self->observable);
|
||||||
|
|
||||||
self->initialized = true;
|
self->initialized = true;
|
||||||
|
self->taskIsDeleted = false;
|
||||||
self->isProcessRunning = false;
|
self->isProcessRunning = false;
|
||||||
self->repairPreset = preset;
|
self->repairPreset = preset;
|
||||||
self->currentState = PREPARE;
|
self->currentState = PREPARE;
|
||||||
@@ -142,9 +145,22 @@ ErrorStatus repairProcess_construct(struct RepairProcess* self, struct RepairPro
|
|||||||
|
|
||||||
void repairProcess_destruct(struct RepairProcess* self)
|
void repairProcess_destruct(struct RepairProcess* self)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
MAX5715Channel_setValue(self->row[0].dacChannel, 0);
|
||||||
|
MAX5715Channel_setValue(self->row[1].dacChannel, 0);
|
||||||
|
MAX5715Channel_setValue(self->row[2].dacChannel, 0);
|
||||||
|
|
||||||
self->runTask = false;
|
self->runTask = false;
|
||||||
// Observable_destruct(&self->observable);
|
while (!self->taskIsDeleted)
|
||||||
// self->initialized = false;
|
{
|
||||||
|
vTaskDelay(10);
|
||||||
|
}
|
||||||
|
Observable_destruct(&self->observable);
|
||||||
|
PID_destruct(&self->row[0].pid);
|
||||||
|
PID_destruct(&self->row[1].pid);
|
||||||
|
PID_destruct(&self->row[2].pid);
|
||||||
|
vSemaphoreDelete(self->secondsSyncronisation);
|
||||||
|
self->initialized = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -169,32 +185,25 @@ void repairProcess_feedSecondsCounterFromISR(struct RepairProcess* self)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct Time repairProcess_getRemainingRepairTime(const struct RepairProcess* self)
|
uint32_t repairProcess_getRemainingRepairTime(const struct RepairProcess* self)
|
||||||
{
|
{
|
||||||
struct Time returnValue;
|
uint32_t returnValue;
|
||||||
|
|
||||||
if ((self->initialized) && (self->isProcessRunning))
|
if ((self->initialized) && (self->isProcessRunning))
|
||||||
{
|
{
|
||||||
uint32_t timeToRemain = self->voltageHoldTimer - self->secondsCounter;
|
if (self->voltageHoldTimer >= self->secondsCounter)
|
||||||
if (timeToRemain > 0)
|
|
||||||
{
|
{
|
||||||
returnValue.hours = (timeToRemain / (60 * 60));
|
returnValue = (self->voltageHoldTimer - self->secondsCounter);
|
||||||
returnValue.minutes = (timeToRemain - (returnValue.hours * 60 * 60)) / 60;
|
|
||||||
returnValue.seconds = (timeToRemain - (returnValue.hours * 60 * 60) - (returnValue.minutes * 60));
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Prevent underflows
|
// ERROR - negative time
|
||||||
returnValue.hours = 0;
|
returnValue = 0;
|
||||||
returnValue.minutes = 0;
|
|
||||||
returnValue.seconds = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
returnValue.hours = 99;
|
returnValue = 0xFFFFFFFF;
|
||||||
returnValue.minutes = 99;
|
|
||||||
returnValue.seconds = 99;
|
|
||||||
}
|
}
|
||||||
return returnValue;
|
return returnValue;
|
||||||
}
|
}
|
||||||
@@ -206,7 +215,7 @@ struct RepairProcessRow* repairProcess_getRowInformation(const struct RepairProc
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct Observable* repairProcess_getObservable(struct RepairProcess* self)
|
const struct Observable* repairProcess_getObservable(struct RepairProcess* self)
|
||||||
{
|
{
|
||||||
return &self->observable;
|
return &self->observable;
|
||||||
}
|
}
|
||||||
@@ -272,7 +281,8 @@ static void repairProcess_task(void* parameters)
|
|||||||
}
|
}
|
||||||
|
|
||||||
LOGGER_INFO(mainLog, "Deleting repairProcess task");
|
LOGGER_INFO(mainLog, "Deleting repairProcess task");
|
||||||
vTaskDelete(self->taskHandle);
|
self->taskIsDeleted = true;
|
||||||
|
vTaskDelete(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -88,6 +88,7 @@ void repairProcesses_abortMainRepairProcess(void)
|
|||||||
GPIO_setValue(power6v5Enable, true);
|
GPIO_setValue(power6v5Enable, true);
|
||||||
|
|
||||||
repairProcess_destruct(&mainRepairProcess);
|
repairProcess_destruct(&mainRepairProcess);
|
||||||
|
Observable_deleteObserver(RTC_getObservable(rtc), repairProcesses_feedMainRepairProcessSecondsCounter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user