Skip to content

Commit

Permalink
Merge branch 'edge' into flex-stacker-ui-leds-bringup
Browse files Browse the repository at this point in the history
  • Loading branch information
vegano1 committed Dec 16, 2024
2 parents 2b6b4c8 + b204d5e commit 00d6a9b
Show file tree
Hide file tree
Showing 32 changed files with 740 additions and 36 deletions.
101 changes: 101 additions & 0 deletions stm32-modules/flex-stacker/firmware/system/system_hardware.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,106 @@
// address 4 in the bootable region is the address of the first instruction that
// should run, aka the data that should be loaded into $pc.
const uint32_t *const sysmem_boot_loc = (uint32_t*)SYSMEM_BOOT;
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
};

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_BORRST)) {
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 system_hardware_reset_reason() {
return reset_reason;
}

/** PUBLIC FUNCTION IMPLEMENTATION */

Expand Down Expand Up @@ -60,6 +160,7 @@ void system_hardware_enter_bootloader(void) {
}

void system_hardware_gpio_init(void) {
save_reset_reason();
GPIO_InitTypeDef init = {0};

/* GPIO Ports Clock Enable */
Expand Down
5 changes: 5 additions & 0 deletions stm32-modules/flex-stacker/firmware/system/system_policy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,8 @@ auto SystemPolicy::initialize() -> void { system_hardware_gpio_init(); }
auto SystemPolicy::get_door_closed() -> bool {
return system_hardware_read_door_closed();
}

// NOLINTNEXTLINE(readability-convert-member-functions-to-static)
auto SystemPolicy::last_reset_reason() const -> uint16_t {
return system_hardware_reset_reason();
}
101 changes: 101 additions & 0 deletions stm32-modules/heater-shaker/firmware/motor_task/motor_hardware.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,39 @@ motor_hardware_handles *MOTOR_HW_HANDLE = NULL;

static _Atomic int16_t motor_speed_buffer[MOTOR_SPEED_BUFFER_SIZE];
static _Atomic size_t motor_speed_buffer_itr = 0;
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
};

static void MX_NVIC_Init(void)
{
Expand Down Expand Up @@ -491,6 +524,69 @@ static void DAC_Init(DAC_HandleTypeDef* dac) {
HAL_DAC_SetValue(dac, SOLENOID_DAC_CHANNEL, DAC_ALIGN_8B_R, 0);
}

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;
}
}

/**
* Initializes the Global MSP.
*/
Expand Down Expand Up @@ -814,6 +910,7 @@ void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* htim_base)
}

void motor_hardware_setup(motor_hardware_handles* handles) {
save_reset_reason();
MOTOR_HW_HANDLE = handles;
memset(motor_speed_buffer, 0, sizeof(motor_speed_buffer));
MX_GPIO_Init();
Expand All @@ -840,6 +937,10 @@ void motor_hardware_solenoid_release(DAC_HandleTypeDef* dac1) {
HAL_DAC_SetValue(dac1, SOLENOID_DAC_CHANNEL, DAC_ALIGN_8B_R, 0);
}

uint16_t motor_hardware_reset_reason() {
return reset_reason;
}

void motor_hardware_plate_lock_on(TIM_HandleTypeDef* tim3, float power) {
float power_scale = fabs(power);
if (power_scale > 1.f) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,13 @@ bool motor_hardware_plate_lock_sensor_read(uint16_t GPIO_Pin);

void HAL_TIM_MspPostInit(TIM_HandleTypeDef* htim);

/**
* @brief Returns the reason saved upon startup for the last
* reset of the software.
* @return a flag containing the reason for reset.
* */
uint16_t motor_hardware_reset_reason();

/**
* @brief To be called every time the motor control library updates its speed
* measurement. This function adds new speed values to a circular buffer,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,3 +131,7 @@ auto MotorPolicy::get_serial_number(void)
-> std::array<char, SYSTEM_SERIAL_NUMBER_LENGTH> {
return _serial.get_serial_number();
}

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 @@ -46,6 +46,7 @@ class MotorPolicy {
auto plate_lock_closed_sensor_read() -> bool;
auto get_serial_number(void)
-> std::array<char, SYSTEM_SERIAL_NUMBER_LENGTH>;
auto last_reset_reason() const -> uint16_t;

private:
static constexpr uint16_t MAX_SOLENOID_CURRENT_MA = 330;
Expand Down
8 changes: 8 additions & 0 deletions stm32-modules/heater-shaker/simulator/motor_thread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,13 +109,21 @@ struct SimMotorPolicy {
}
}

auto last_reset_reason() -> uint16_t { return reset_reason; }

auto set_last_reset_reason(uint16_t sim_reason) -> void {
reset_reason = sim_reason;
}

private:
int16_t rpm_setpoint = 0;
int16_t rpm_current = 0;
int32_t ramp_rate = DEFAULT_RAMP_RATE_RPM_PER_S;
float sim_plate_lock_power = 0;
bool sim_plate_lock_enabled = false;
bool sim_plate_lock_braked = false;
// Simulated reset reason from HAL RCC flag
uint16_t reset_reason = 0;
};

struct motor_thread::TaskControlBlock {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ class MotorInterruptController {
motor_util::MovementType::FixedDistance, steps);
_policy->enable_motor(_id);
_response_id = move_id;
_policy->start_motor_timer(_id);
}
auto start_move(Move move) -> void {
motor_util::MotorState* state = move.motor_state;
Expand Down
2 changes: 2 additions & 0 deletions stm32-modules/include/flex-stacker/firmware/system_hardware.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ extern "C" {
#endif // __cplusplus

#include <stdbool.h>
#include <stdint.h>

#define HOPPER_DOR_CLOSED_PIN GPIO_PIN_13
#define HOPPER_DOR_CLOSED_GPIO_PORT GPIOC
Expand All @@ -15,6 +16,7 @@ extern "C" {
void system_hardware_enter_bootloader(void);
void system_hardware_gpio_init(void);
bool system_hardware_read_door_closed(void);
uint16_t system_hardware_reset_reason(void);

#ifdef __cplusplus
} // extern "C"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,5 @@ class SystemPolicy {
-> errors::ErrorCode;
auto get_serial_number() -> std::array<char, SYSTEM_SERIAL_NUMBER_LENGTH>;
auto get_door_closed() -> bool;
[[nodiscard]] auto last_reset_reason() const -> uint16_t;
};
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
Loading

0 comments on commit 00d6a9b

Please sign in to comment.