Skip to content

Commit

Permalink
add flex stacker reset reason
Browse files Browse the repository at this point in the history
  • Loading branch information
caila-marashaj committed Dec 4, 2024
1 parent 0e7f28f commit 8addb3a
Show file tree
Hide file tree
Showing 8 changed files with 219 additions and 4 deletions.
101 changes: 101 additions & 0 deletions stm32-modules/flex-stacker/firmware/motor_control/motor_hardware.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,39 @@ extern "C" {
TIM_HandleTypeDef htim17;
TIM_HandleTypeDef htim20;
TIM_HandleTypeDef htim3;
uint16_t reset_reason;

enum RCC_FLAGS {
_NONE,
// high speed internal clock ready
HSIRDY, // = 1
// high speed external clock ready
HSERDY, // = 2
// main phase-locked loop clock ready
PLLRDY, // = 3
// hsi48 clock ready
HSI48RDY, // = 4
// low-speed external clock ready
LSERDY, // = 5
// lse clock security system failure
LSECSSD, // = 6
// low-speed internal clock ready
LSIRDY, // = 7
// brown out
BORRST, // = 8
// option byte-loader reset
OBLRST, // = 9
// pin reset
PINRST, // = 10
// software reset
SFTRST, // = 11
// independent watchdog
IWDGRST, // = 12
// window watchdog
WWDGRST, // = 13
// low power reset
LPWRRST, // = 14
};

typedef struct PinConfig {
void* port;
Expand Down Expand Up @@ -300,7 +333,75 @@ void tim3_init(TIM_HandleTypeDef* htim) {
HAL_NVIC_EnableIRQ(TIM3_IRQn);
}

static void save_reset_reason() {
// check various reset flags to see if the HAL RCC
// reset flag matches any of them
reset_reason = 0;

// high speed internal clock ready
if (__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY)) {
reset_reason |= HSIRDY;
}
// high speed external clock ready
else if (__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY)) {
reset_reason |= HSERDY;
}
// main phase-locked loop clock ready
else if (__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY)) {
reset_reason |= PLLRDY;
}
// hsi48 clock ready
else if (__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY)) {
reset_reason |= HSI48RDY;
}
// low-speed external clock ready
else if (__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY)) {
reset_reason |= LSERDY;
}
// lse clock security system failure
else if (__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY)) {
reset_reason |= LSECSSD;
}
// low-speed internal clock ready
else if (__HAL_RCC_GET_FLAG(RCC_FLAG_LSIRDY)) {
reset_reason |= LSIRDY;
}
// brown out
else if (__HAL_RCC_GET_FLAG(RCC_FLAG_PORRST)) {
reset_reason |= BORRST;
}
// option byte-loader reset
else if (__HAL_RCC_GET_FLAG(RCC_FLAG_OBLRST)) {
reset_reason |= OBLRST;
}
// pin reset
else if (__HAL_RCC_GET_FLAG(RCC_FLAG_PINRST)) {
reset_reason |= PINRST;
}
// software reset
else if (__HAL_RCC_GET_FLAG(RCC_FLAG_SFTRST)) {
reset_reason |= SFTRST;
}
// independent watchdog
else if (__HAL_RCC_GET_FLAG(RCC_FLAG_IWDGRST)) {
reset_reason |= IWDGRST;
}
// window watchdog
else if (__HAL_RCC_GET_FLAG(RCC_FLAG_WWDGRST)) {
reset_reason |= WWDGRST;
}
// low power reset
else if (__HAL_RCC_GET_FLAG(RCC_FLAG_LPWRRST)) {
reset_reason |= LPWRRST;
}
}

uint16_t motor_hardware_reset_reason() {
return reset_reason;
}

void motor_hardware_init(void){
save_reset_reason();
if (!_motor_hardware.initialized) {
motor_hardware_gpio_init();
tim17_init(&_motor_hardware.motor_x.timer);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,9 @@ auto MotorPolicy::is_diag0_pin(uint16_t pin) -> bool {
// NOLINTNEXTLINE(readability-convert-member-functions-to-static)
auto MotorPolicy::is_estop_pin(uint16_t pin) -> bool {
return hw_is_estop_pin(pin);
}

// NOLINTNEXTLINE(readability-convert-member-functions-to-static)
auto MotorPolicy::last_reset_reason() const -> uint16_t {
return motor_hardware_reset_reason();
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ bool hw_read_platform_sensor(bool direction);
bool hw_read_estop(void);
bool hw_is_diag0_pin(uint16_t pin);
bool hw_is_estop_pin(uint16_t pin);
uint16_t motor_hardware_reset_reason();

#ifdef __cplusplus
} // extern "C"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ class MotorPolicy {
auto check_estop() -> bool;
auto is_diag0_pin(uint16_t pin) -> bool;
auto is_estop_pin(uint16_t pin) -> bool;
[[nodiscard]] auto last_reset_reason() const -> uint16_t;
};

} // namespace motor_policy
38 changes: 38 additions & 0 deletions stm32-modules/include/flex-stacker/flex-stacker/gcodes.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,44 @@ struct GetSystemInfo {
}
};

struct GetResetReason {
/*
* M114- GetResetReason retrieves the value of the RCC reset flag
* that was captured at the beginning of the hardware setup
* */
using ParseResult = std::optional<GetResetReason>;
static constexpr auto prefix = std::array{'M', '1', '1', '4'};

template <typename InputIt, typename InLimit>
requires std::forward_iterator<InputIt> &&
std::sized_sentinel_for<InputIt, InLimit>
static auto write_response_into(InputIt buf, InLimit limit, uint16_t reason)
-> InputIt {
int res = 0;
// print a hexadecimal representation of the reset flags
res = snprintf(&*buf, (limit - buf), "M114 Last Reset Reason: %X OK\n",
reason);
if (res <= 0) {
return buf;
}
return buf + res;
}
template <typename InputIt, typename Limit>
requires std::forward_iterator<InputIt> &&
std::sized_sentinel_for<Limit, InputIt>
static auto parse(const InputIt& input, Limit limit)
-> std::pair<ParseResult, InputIt> {
auto working = prefix_matches(input, limit, prefix);
if (working == input) {
return std::make_pair(ParseResult(), input);
}
if (working != limit && !std::isspace(*working)) {
return std::make_pair(ParseResult(), input);
}
return std::make_pair(ParseResult(GetResetReason()), working);
}
};

struct SetSerialNumber {
using ParseResult = std::optional<SetSerialNumber>;
static constexpr auto prefix = std::array{'M', '9', '9', '6'};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ class HostCommsTask {
gcode::GetLimitSwitches, gcode::SetMicrosteps, gcode::GetMoveParams,
gcode::SetMotorStallGuard, gcode::GetMotorStallGuard, gcode::HomeMotor,
gcode::GetPlatformSensors, gcode::GetDoorClosed, gcode::GetEstopStatus,
gcode::StopMotor>;
gcode::StopMotor, gcode::GetResetReason>;
using AckOnlyCache =
AckCache<8, gcode::EnterBootloader, gcode::SetSerialNumber,
gcode::SetTMCRegister, gcode::SetRunCurrent,
Expand All @@ -64,6 +64,7 @@ class HostCommsTask {
using GetDoorClosedCache = AckCache<8, gcode::GetDoorClosed>;
using GetPlatformSensorsCache = AckCache<8, gcode::GetPlatformSensors>;
using GetEstopCache = AckCache<8, gcode::GetEstopStatus>;
using GetResetReasonCache = AckCache<8, gcode::GetResetReason>;

public:
static constexpr size_t TICKS_TO_WAIT_ON_SEND = 10;
Expand All @@ -88,7 +89,9 @@ class HostCommsTask {
// NOLINTNEXTLINE(readability-redundant-member-init)
get_platform_sensors_cache(),
// NOLINTNEXTLINE(readability-redundant-member-init)
get_estop_cache() {}
get_estop_cache(),
// NOLINTNEXTLINE(readability-redundant-member-init)
get_reset_reason_cache() {}
HostCommsTask(const HostCommsTask& other) = delete;
auto operator=(const HostCommsTask& other) -> HostCommsTask& = delete;
HostCommsTask(HostCommsTask&& other) noexcept = delete;
Expand Down Expand Up @@ -293,6 +296,50 @@ class HostCommsTask {
cache_entry);
}

template <typename InputIt, typename InputLimit>
requires std::forward_iterator<InputIt> &&
std::sized_sentinel_for<InputLimit, InputIt>
auto visit_message(const messages::GetResetReasonResponse& response,
InputIt tx_into, InputLimit tx_limit) -> InputIt {
auto cache_entry =
get_reset_reason_cache.remove_if_present(response.responding_to_id);
return std::visit(
[tx_into, tx_limit, response](auto cache_element) {
using T = std::decay_t<decltype(cache_element)>;
if constexpr (std::is_same_v<std::monostate, T>) {
return errors::write_into(
tx_into, tx_limit,
errors::ErrorCode::BAD_MESSAGE_ACKNOWLEDGEMENT);
} else {
return cache_element.write_response_into(tx_into, tx_limit,
response.reason);
}
},
cache_entry);
}

template <typename InputIt, typename InputLimit>
requires std::forward_iterator<InputIt> &&
std::sized_sentinel_for<InputLimit, InputIt>
auto visit_gcode(const gcode::GetResetReason& gcode, InputIt tx_into,
InputLimit tx_limit) -> std::pair<bool, InputIt> {
auto id = get_reset_reason_cache.add(gcode);
if (id == 0) {
return std::make_pair(
false, errors::write_into(tx_into, tx_limit,
errors::ErrorCode::GCODE_CACHE_FULL));
}
auto message = messages::GetResetReasonMessage{.id = id};

if (!task_registry->send(message, TICKS_TO_WAIT_ON_SEND)) {
auto wrote_to = errors::write_into(
tx_into, tx_limit, errors::ErrorCode::INTERNAL_QUEUE_FULL);
get_reset_reason_cache.remove_if_present(id);
return std::make_pair(false, wrote_to);
}
return std::make_pair(true, tx_into);
}

template <typename InputIt, typename InputLimit>
requires std::forward_iterator<InputIt> &&
std::sized_sentinel_for<InputLimit, InputIt>
Expand Down Expand Up @@ -1020,6 +1067,7 @@ class HostCommsTask {
GetDoorClosedCache get_door_closed_cache;
GetPlatformSensorsCache get_platform_sensors_cache;
GetEstopCache get_estop_cache;
GetResetReasonCache get_reset_reason_cache;
bool may_connect_latch = true;
};

Expand Down
14 changes: 12 additions & 2 deletions stm32-modules/include/flex-stacker/flex-stacker/messages.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,15 @@ struct GetSystemInfoResponse {
const char* hw_version;
};

struct GetResetReasonMessage {
uint32_t id;
};

struct GetResetReasonResponse {
uint32_t responding_to_id;
uint16_t reason;
};

struct SetSerialNumberMessage {
uint32_t id;
static constexpr std::size_t SERIAL_NUMBER_LENGTH =
Expand Down Expand Up @@ -278,7 +287,7 @@ using HostCommsMessage =
GetTMCRegisterResponse, GetLimitSwitchesResponses,
GetMoveParamsResponse, GetMotorStallGuardResponse,
GetDoorClosedResponse, GetPlatformSensorsResponse,
GetEstopResponse>;
GetEstopResponse, GetResetReasonResponse>;

using SystemMessage =
::std::variant<std::monostate, AcknowledgePrevious, GetSystemInfoMessage,
Expand All @@ -296,6 +305,7 @@ using MotorMessage = ::std::variant<
MoveToLimitSwitchMessage, StopMotorMessage, MoveCompleteMessage,
GetLimitSwitchesMessage, MoveMotorInMmMessage, SetMicrostepsMessage,
GetMoveParamsMessage, SetDiag0IRQMessage, GPIOInterruptMessage,
HomeMotorMessage, GetPlatformSensorsMessage, GetEstopMessage>;
HomeMotorMessage, GetPlatformSensorsMessage, GetEstopMessage,
GetResetReasonMessage>;

}; // namespace messages
11 changes: 11 additions & 0 deletions stm32-modules/include/flex-stacker/flex-stacker/motor_task.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,17 @@ class MotorTask {
_l_controller.stop_movement(0, false);
}

template <MotorControlPolicy Policy>
auto visit_message(const messages::GetResetReasonMessage& msg,
Policy& policy) -> void {
auto reason = policy.last_reset_reason();

auto response = messages::GetResetReasonResponse{
.responding_to_id = msg.id, .reason = reason};
static_cast<void>(_task_registry->send_to_address(
response, Queues::HostCommsAddress));
}

/**
* @brief Move the motor to the limit switch; apply fast moves to XZ motors
* whenever possible.
Expand Down

0 comments on commit 8addb3a

Please sign in to comment.