Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 111 additions & 6 deletions Controllers/CDebugController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,18 @@
*/

#include "CDebugController.h"
#include "../etl/to_string.h"

CDebugController::CDebugController(etl::string<MAX_STRING_SIZE> name,
CDebugController::CDebugController(IHardwareMap *p_hardware_map,
etl::string<MAX_STRING_SIZE> name,
uint32_t run_period_ms)
: CController(name, run_period_ms),
m_breather_light(BREATHING_GPIO_Port, BREATHING_Pin)
mp_hw(p_hardware_map)

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should check that this is not anullptr somewhere.

{
// TODO Auto-generated constructor stub
if (mp_hw == nullptr)
{
Error_Handler();
}
}

CDebugController::~CDebugController()
Expand All @@ -26,14 +31,114 @@ CDebugController::~CDebugController()

void CDebugController::run()
{
m_breather_light.toggle();
static float breathing_light_intensity = 0;
mp_hw->setBreathingLight(breathing_light_intensity);
breathing_light_intensity = breathing_light_intensity ? 0 : 100;

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I understood correctly, this function sets the duty cycle to 0 or 100 to turn the LED on/off every time run() is called?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. This is really just a plug for when we get around to beautifying it. Ideally, we would want CDebugController to be able to switch this light from slow flash for "Everything is OK" to other types of flashing for when something is the matter and might require attention. But this is frills and cannot distract us right now.

}

bool CDebugController::newCommand(ICommand *p_command,
IComChannel *p_comchannel)
{
return CController::newCommand(p_command,
p_comchannel); // todo: temporary plug
bool b_command_recognised = false;
ICommand::command_error_code_t error_code;
/**
* Set mains power output.
*
* mains(channel, power);
*/
if (p_command->getName()->compare("mains") == 0)
{
error_code = setMainsPower(p_command);
b_command_recognised = true;
}
else if (p_command->getName()->compare("?mains") == 0)
{
float mains_power;
error_code = getMainsPower(p_command, &mains_power);
if (error_code == ICommand::COMMAND_OK)
{
CController::s_scratch_pad = "Mains channel ";
etl::to_string((*p_command)[0],
CController::s_scratch_pad,
etl::format_spec(),
true);
CController::s_scratch_pad += ": ";
etl::to_string(mains_power,

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be great to have an overloaded "addToString()" function that adds floats, ints, and string to the buffer before calling send(). I might have a look this weekend.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That'd be awesome. Like c# and java do.

@Vavat Vavat Oct 14, 2022

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What might be a good thing to do is create a child class based on etl::string and expand it with ability to absorb numbers.
Another option is to expand send() method within CComsController to be able to accept parameters like sprintf() does.

CController::s_scratch_pad,
etl::format_spec().precision(2),
true);
p_comchannel->send(CController::s_scratch_pad);
}
b_command_recognised = true;
}
if (b_command_recognised)
{
sendResultMessage(error_code, p_comchannel);
}
return (b_command_recognised);
}

void CDebugController::reset() {}

ICommand::command_error_code_t CDebugController::setMainsPower(
ICommand *p_command)
{
uint8_t mains_channel;
float mains_power;
// extract arguments from command.
if (p_command->getArgumentCount() == 1)
{
mains_channel = 0;
mains_power = (*p_command)[0];
}
else if (p_command->getArgumentCount() == 2)
{
mains_channel = (uint8_t)(*p_command)[0];
if (mains_channel != (*p_command)[0])
{
return (ICommand::ERROR_TYPE_MISMATCH);

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will this ever be true? How can mains_channel != (*p_command)[0] if we are assigning it that value the line before?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a bit of an awkward way of seeing if an argument is a float. Horrible solution, but I couldn't come up with a better one. Open to suggestions.

@Vavat Vavat Oct 14, 2022

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One option I can think of is to simply cast whatever is in the first argument into unsigned int and then range check. If it was sent as float, then we ignore the decimal part and use it as if it was an integer. This will not cause failures, but it'd be possible to request channel 2.5 to switch to 100% power, which will switch channel 2 or will bounce back with error depending on how casting works.

}
mains_power = (*p_command)[1];
}
else
{
return (ICommand::ERROR_ARG_COUNT);
}
// range check arguments.
if ((mains_channel > 2) || (mains_power < 0) || (mains_power > 100))

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we need to fix this because if _command->getArgumentCount() is not 1 or 2, then mains_channel and mains_power will be uninitialised.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's because I forgot final else{}. Fixed.

{
return (ICommand::ERROR_OUT_OF_BOUNDS);
}
// set channels to requested power
if (mains_channel)
{
mp_hw->setMainsPwm(mains_channel, mains_power);
}
else
{
mp_hw->setMainsPwm(1, mains_power);
mp_hw->setMainsPwm(2, mains_power);
}
return (ICommand::COMMAND_OK);
}

ICommand::command_error_code_t CDebugController::getMainsPower(
ICommand *p_command,
float *power)
{
*power = 0;
if (p_command->getArgumentCount() != 1)
{
return (ICommand::ERROR_ARG_COUNT);
}
else if (((*p_command)[0] != 1) && ((*p_command)[0] != 2))
{
return (ICommand::ERROR_OUT_OF_BOUNDS);
}
else
{
uint8_t channel = (*p_command)[0];
*power = m_mains_power[channel];
}
return (ICommand::COMMAND_OK);
}
13 changes: 11 additions & 2 deletions Controllers/CDebugController.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,29 @@
#include "../etl/string.h"
#include "CController.h"
#include "CGpioWrapper.h"
#include "IHardwareMap.h"
#include "main.h"

class CDebugController : public CController
{
public:
CDebugController(etl::string<MAX_STRING_SIZE> name, uint32_t run_period_ms);
CDebugController(IHardwareMap *p_hardware_map,
etl::string<MAX_STRING_SIZE> name,
uint32_t run_period_ms);
virtual ~CDebugController();

virtual void run();
virtual bool newCommand(ICommand *p_command, IComChannel *p_comchannel);
virtual void reset();

private:
CGpioWrapper m_breather_light;
ICommand::command_error_code_t setMainsPower(ICommand *p_command);

ICommand::command_error_code_t getMainsPower(ICommand *p_command,
float *power);

IHardwareMap *mp_hw;
float m_mains_power[2];
};

#endif /* CDEBUGCONTROLLER_H_ */
18 changes: 1 addition & 17 deletions Controllers/CTemperatureController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,23 +109,7 @@ bool CTemperatureController::newCommand(ICommand *p_command,
}
if (b_command_recognised)
{
switch (result)
{
case ICommand::COMMAND_OK:
// p_comchannel->send("OK.\n");
break;
case ICommand::ERROR_ARG_COUNT:
p_comchannel->send("Wrong number of arguments.\n");
break;
case ICommand::ERROR_OUT_OF_BOUNDS:
p_comchannel->send("Argument out of bounds.\n");
break;
case ICommand::ERROR_TYPE_MISMATCH:
p_comchannel->send("Argument type mismatch.\n");
break;
default:
p_comchannel->send("Non-specific error with the command.");
}
sendResultMessage(result, p_comchannel);
}
return b_command_recognised;
}
Expand Down
2 changes: 2 additions & 0 deletions Core/Inc/main.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,12 @@ void Error_Handler(void);
/* Private defines -----------------------------------------------------------*/
#define BUTTON_Pin GPIO_PIN_13
#define BUTTON_GPIO_Port GPIOC
#define BUTTON_EXTI_IRQn EXTI15_10_IRQn
#define PWR_EN_Pin GPIO_PIN_14
#define PWR_EN_GPIO_Port GPIOC
#define MAINS_ZERO_Pin GPIO_PIN_15
#define MAINS_ZERO_GPIO_Port GPIOC
#define MAINS_ZERO_EXTI_IRQn EXTI15_10_IRQn
#define TEMPERATURE_8_Pin GPIO_PIN_0
#define TEMPERATURE_8_GPIO_Port GPIOC
#define EVAPORATOR_T_Pin GPIO_PIN_1
Expand Down
1 change: 1 addition & 0 deletions Core/Inc/stm32f4xx_it.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ void PendSV_Handler(void);
void SysTick_Handler(void);
void USART1_IRQHandler(void);
void USART2_IRQHandler(void);
void EXTI15_10_IRQHandler(void);
void DMA2_Stream0_IRQHandler(void);
/* USER CODE BEGIN EFP */

Expand Down
16 changes: 13 additions & 3 deletions Core/Src/gpio.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,11 @@ void MX_GPIO_Init(void)
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(ENABLE_5_GPIO_Port, ENABLE_5_Pin, GPIO_PIN_RESET);

/*Configure GPIO pins : PCPin PCPin */
GPIO_InitStruct.Pin = BUTTON_Pin|MAINS_ZERO_Pin;
/*Configure GPIO pin : PtPin */
GPIO_InitStruct.Pin = BUTTON_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
HAL_GPIO_Init(BUTTON_GPIO_Port, &GPIO_InitStruct);

/*Configure GPIO pins : PCPin PCPin PCPin PCPin */
GPIO_InitStruct.Pin = PWR_EN_Pin|ENABLE_2_Pin|ENABLE_3_Pin|ENABLE_4_Pin;
Expand All @@ -76,6 +76,12 @@ void MX_GPIO_Init(void)
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

/*Configure GPIO pin : PtPin */
GPIO_InitStruct.Pin = MAINS_ZERO_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(MAINS_ZERO_GPIO_Port, &GPIO_InitStruct);

/*Configure GPIO pins : PBPin PBPin PBPin PBPin */
GPIO_InitStruct.Pin = ENABLE_7_Pin|SPI2_NSS2_Pin|ENABLE_6_Pin|USART1_DE_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
Expand All @@ -97,6 +103,10 @@ void MX_GPIO_Init(void)
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(ENABLE_5_GPIO_Port, &GPIO_InitStruct);

/* EXTI interrupt init*/
HAL_NVIC_SetPriority(EXTI15_10_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);

}

/* USER CODE BEGIN 2 */
Expand Down
15 changes: 15 additions & 0 deletions Core/Src/stm32f4xx_it.c
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,21 @@ void USART2_IRQHandler(void)
/* USER CODE END USART2_IRQn 1 */
}

/**
* @brief This function handles EXTI line[15:10] interrupts.
*/
void EXTI15_10_IRQHandler(void)
{
/* USER CODE BEGIN EXTI15_10_IRQn 0 */

/* USER CODE END EXTI15_10_IRQn 0 */
HAL_GPIO_EXTI_IRQHandler(BUTTON_Pin);
HAL_GPIO_EXTI_IRQHandler(MAINS_ZERO_Pin);
/* USER CODE BEGIN EXTI15_10_IRQn 1 */

/* USER CODE END EXTI15_10_IRQn 1 */
}

/**
* @brief This function handles DMA2 stream0 global interrupt.
*/
Expand Down
24 changes: 16 additions & 8 deletions Core/Src/tim.c
Original file line number Diff line number Diff line change
Expand Up @@ -257,9 +257,9 @@ void MX_TIM10_Init(void)

/* USER CODE END TIM10_Init 1 */
htim10.Instance = TIM10;
htim10.Init.Prescaler = 0;
htim10.Init.Prescaler = 19999;
htim10.Init.CounterMode = TIM_COUNTERMODE_UP;
htim10.Init.Period = 65535;
htim10.Init.Period = 99;
htim10.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim10.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_Base_Init(&htim10) != HAL_OK)
Expand All @@ -270,8 +270,12 @@ void MX_TIM10_Init(void)
{
Error_Handler();
}
sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = 0;
if (HAL_TIM_OnePulse_Init(&htim10, TIM_OPMODE_SINGLE) != HAL_OK)
{
Error_Handler();
}
sConfigOC.OCMode = TIM_OCMODE_PWM2;
sConfigOC.Pulse = 99;
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
if (HAL_TIM_PWM_ConfigChannel(&htim10, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
Expand All @@ -298,9 +302,9 @@ void MX_TIM11_Init(void)

/* USER CODE END TIM11_Init 1 */
htim11.Instance = TIM11;
htim11.Init.Prescaler = 0;
htim11.Init.Prescaler = 19999;
htim11.Init.CounterMode = TIM_COUNTERMODE_UP;
htim11.Init.Period = 65535;
htim11.Init.Period = 99;
htim11.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim11.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_Base_Init(&htim11) != HAL_OK)
Expand All @@ -311,8 +315,12 @@ void MX_TIM11_Init(void)
{
Error_Handler();
}
sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = 0;
if (HAL_TIM_OnePulse_Init(&htim11, TIM_OPMODE_SINGLE) != HAL_OK)
{
Error_Handler();
}
sConfigOC.OCMode = TIM_OCMODE_PWM2;
sConfigOC.Pulse = 99;
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
if (HAL_TIM_PWM_ConfigChannel(&htim11, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
Expand Down
37 changes: 37 additions & 0 deletions Hardware/CMockHardwareMap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,43 @@ void CMockHardwareMap::enableControlPower(bool b_enable)
mb_power_enable = b_enable;
}

void CMockHardwareMap::setMainsPwm(uint8_t channel, float power)
{
if (power < 0)
{
power = 0;
}
if (power > 100)
{
power = 100;
}
if (channel > 2)
{
return;
}
else if (channel == 0)
{
m_mains_pwm[0] = power;
m_mains_pwm[1] = power;
}
else
{
m_mains_pwm[channel - 1] = power;
}
}

float CMockHardwareMap::getMainsPwm(uint8_t channel)
{
if (channel > 2)
{
return 0;
}
else
{
return (m_mains_pwm[channel - 1]);
}
}

void CMockHardwareMap::run()
{
float total_radiator_flow = 0;
Expand Down
4 changes: 4 additions & 0 deletions Hardware/CMockHardwareMap.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ class CMockHardwareMap : public IHardwareMap, public CController
#endif
virtual void setBreathingLight(float duty_cycle);
virtual void enableControlPower(bool b_enable);
virtual void setMainsPwm(uint8_t channel, float power);
virtual float getMainsPwm(uint8_t channel);

/* CController methods. */
// etl::string<MAX_STRING_SIZE> getName() const;
// virtual bool tick(uint32_t current_time);
Expand Down Expand Up @@ -65,6 +68,7 @@ class CMockHardwareMap : public IHardwareMap, public CController
float m_incubator_capacity; // heat capacity of incubator
float m_incubator_loss; // rate of heat loss to ambient air.
float m_control_current; // total current flowing through the heaters.
float m_mains_pwm[2];
};

#endif /* CMOCKHARDWAREMAP_H_ */
Loading