-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Initial Commit] Port main logic from other repo
Topic: inital-commit Relative: Reviewers:
- Loading branch information
1 parent
ffd8c83
commit 09caa51
Showing
64 changed files
with
4,528 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
--- | ||
BasedOnStyle: Google | ||
IndentWidth: 4 | ||
ColumnLimit: 130 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
name: Code Format check | ||
|
||
on: | ||
pull_request: | ||
branches: [ main ] | ||
|
||
jobs: | ||
check-format: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v2 | ||
- run: sudo apt install clang-format | ||
- run: bash scripts/test_clang_format.sh |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
name: Test | ||
|
||
on: | ||
pull_request: | ||
branches: [ main ] | ||
|
||
jobs: | ||
test: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v2 | ||
- run: bash scripts/setup.sh | ||
- run: bash scripts/test.sh |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -30,3 +30,5 @@ | |
*.exe | ||
*.out | ||
*.app | ||
|
||
build/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
[submodule "libs/googletest"] | ||
path = libs/googletest | ||
url = https://github.com/google/googletest.git |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
cmake_minimum_required(VERSION 3.8) | ||
|
||
set(This MAINS) | ||
set(BINARY ${CMAKE_PROJECT_NAME}) | ||
|
||
project(${This} C CXX) | ||
|
||
set(CMAKE_C_STANDARD 99) | ||
set(CMAKE_CXX_STANDARD 14) | ||
set(CMAKE_POSITION_INDEPENDENT_CODE ON) | ||
set(BUILD_GMOCK ON) | ||
|
||
# enable Werror | ||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Werror") | ||
|
||
enable_testing() | ||
|
||
# add the googletest subdirectory, located in the lib folder tree that is one level above this one | ||
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/libs/googletest ${CMAKE_CURRENT_BINARY_DIR}/googletest) | ||
|
||
# set the HEADERS as everything in the inc folder, as well as test *.hpp files | ||
file(GLOB HEADERS "inc/*.hpp") | ||
|
||
# set the SOURCES as everything in the src folder | ||
file(GLOB SOURCES "src/*.cpp") | ||
|
||
# add_executable(${BINARY}_run ${SOURCES}) | ||
add_library(${This} STATIC ${SOURCES} ${HEADERS}) | ||
|
||
add_subdirectory(test) | ||
|
||
# To find the tests, this is rquired | ||
include_directories(inc) | ||
include_directories(src) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
#ifndef BRIDGE_3PHASE_HPP | ||
#define BRIDGE_3PHASE_HPP | ||
|
||
#include "hal_common.hpp" | ||
|
||
namespace hwbridge { | ||
|
||
// Define a generic 3-phase bridge class | ||
|
||
class Bridge3Phase { | ||
public: | ||
Bridge3Phase() = default; | ||
virtual ~Bridge3Phase() = default; | ||
|
||
typedef struct phase_command { | ||
float duty_cycle_high_side; | ||
bool invert_low_side; | ||
} phase_command_t; | ||
|
||
// Define a struct to return the PHASE (not backemf) voltage | ||
typedef struct bemf_voltage { | ||
float u; | ||
float v; | ||
float w; | ||
} bemf_voltage_t; | ||
|
||
// Define a struct to return the current | ||
typedef struct current { | ||
float u; | ||
float v; | ||
float w; | ||
} phase_current_t; | ||
|
||
virtual app_hal_status_E init() = 0; | ||
|
||
// Define a virtual function to set the individual phases' duty cycles and enable/disable the phase | ||
virtual void set_phase(const phase_command_t& u, const phase_command_t& v, const phase_command_t& w) = 0; | ||
|
||
// Define a virtual function to get the back emf voltage | ||
virtual app_hal_status_E read_bemf(bemf_voltage_t& bemf_voltage) = 0; | ||
|
||
// Define a virtual function to get the current | ||
virtual app_hal_status_E read_current(phase_current_t& current) = 0; | ||
|
||
// Define a virtual function to get the bus voltage | ||
virtual app_hal_status_E read_bus_voltage(float& bus_voltage) = 0; | ||
|
||
static constexpr uint8_t NUM_PHASES = 3; | ||
}; | ||
|
||
// Define a generic class for a sensor that returns the sector of the rotor | ||
class BldcRotorSectorSensor { | ||
public: | ||
BldcRotorSectorSensor() = default; | ||
virtual ~BldcRotorSectorSensor() = default; | ||
|
||
// Define a virtual function to initialize the sensor | ||
virtual app_hal_status_E init() = 0; | ||
|
||
// Define a virtual function to get the sector | ||
// @RETURNS the sector (0-5) | ||
virtual app_hal_status_E get_sector(uint8_t& sector) = 0; | ||
}; | ||
|
||
} // namespace hwbridge | ||
|
||
#endif // BRIDGE_3PHASE_HPP |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,164 @@ | ||
#ifndef BRIDGE_3PHASE_DRV8323_HPP | ||
#define BRIDGE_3PHASE_DRV8323_HPP | ||
|
||
#include <math.h> | ||
|
||
#include "bridge_3phase.hpp" | ||
#include "control_loop.hpp" | ||
#include "hal_adc.hpp" | ||
#include "hal_common.hpp" | ||
#include "hal_gpio.hpp" | ||
#include "hal_timer.hpp" | ||
|
||
namespace hwbridge { | ||
|
||
// Define a 3-phase bridge class using DRV8323 | ||
class Bridge3PhaseDRV8323 : public Bridge3Phase { | ||
public: | ||
typedef struct drv8323_phase_config_info { | ||
// Timer channel | ||
// TODO: there should be a timer object here as well. Assuming all channels are on the same timer | ||
basilisk_hal::timer_channel_E channel; | ||
basilisk_hal::HAL_GPIO* low_side_gpio; // Not supporting low side gate control for now except for enable/disable | ||
basilisk_hal::HAL_ADC* bemf_sense_adc; | ||
uint8_t bemf_sense_adc_channel; | ||
// TODO: add current sense support. For now, only 6 step is supported. | ||
// basilisk_hal::HAL_ADC* current_sense_adc; | ||
// uint8_t current_sense_adc_channel; | ||
} drv8323_phase_config_info_t; | ||
|
||
Bridge3PhaseDRV8323(basilisk_hal::HAL_ComplementaryPWM_Timer& timer, drv8323_phase_config_info_t& u, | ||
drv8323_phase_config_info_t& v, drv8323_phase_config_info_t& w, uint32_t frequency) { | ||
// Register the timer and pin | ||
pwm_timer_ = &timer; | ||
u_ = u; | ||
v_ = v; | ||
w_ = w; | ||
frequency_ = frequency; | ||
}; | ||
~Bridge3PhaseDRV8323() = default; | ||
|
||
app_hal_status_E init() override { | ||
// Set the direction pin to output | ||
u_.low_side_gpio->set_mode(basilisk_hal::gpio_mode_E::OUTPUT); | ||
v_.low_side_gpio->set_mode(basilisk_hal::gpio_mode_E::OUTPUT); | ||
w_.low_side_gpio->set_mode(basilisk_hal::gpio_mode_E::OUTPUT); | ||
|
||
// Set the pwm timer to PWM_CENTRE_ALIGNED | ||
pwm_timer_->set_timer_params(basilisk_hal::timer_mode_E::PWM_CENTRE_ALIGNED, frequency_); | ||
|
||
// Set the timer channel | ||
pwm_timer_->set_channel(0, u_.channel); | ||
pwm_timer_->set_channel(0, v_.channel); | ||
pwm_timer_->set_channel(0, w_.channel); | ||
|
||
// Start the timer | ||
pwm_timer_->start(); | ||
|
||
// Start PWM | ||
pwm_timer_->start_pwm(u_.channel); | ||
pwm_timer_->start_pwm(v_.channel); | ||
pwm_timer_->start_pwm(w_.channel); | ||
|
||
return app_hal_status_E::APP_HAL_OK; | ||
} | ||
|
||
// Define a virtual function to set the individual phases' duty cycles and enable/disable the phase | ||
void set_phase(const phase_command_t& u, const phase_command_t& v, const phase_command_t& w) { | ||
// Determine the appropriate amount of ticks by getting the timer period | ||
uint32_t period = pwm_timer_->get_period(); | ||
uint32_t ticks_u = | ||
static_cast<uint32_t>(period * fabs(u.duty_cycle_high_side) / control_loop::ControlLoop::MAX_MOTOR_SPEED); | ||
uint32_t ticks_v = | ||
static_cast<uint32_t>(period * fabs(v.duty_cycle_high_side) / control_loop::ControlLoop::MAX_MOTOR_SPEED); | ||
uint32_t ticks_w = | ||
static_cast<uint32_t>(period * fabs(w.duty_cycle_high_side) / control_loop::ControlLoop::MAX_MOTOR_SPEED); | ||
|
||
// Determine the low-side phase active high or active low signal for the complementary timer | ||
// If the inverted boolean is set in the phase command, we should set the command | ||
// to active low, otherwise, we should set the command to active high | ||
|
||
basilisk_hal::HAL_ComplementaryPWM_Timer::complementary_PWM_phase_E u_complementary_phase = | ||
u.invert_low_side ? basilisk_hal::HAL_ComplementaryPWM_Timer::complementary_PWM_phase_E::ACTIVE_LOW | ||
: basilisk_hal::HAL_ComplementaryPWM_Timer::complementary_PWM_phase_E::ACTIVE_HIGH; | ||
|
||
basilisk_hal::HAL_ComplementaryPWM_Timer::complementary_PWM_phase_E v_complementary_phase = | ||
v.invert_low_side ? basilisk_hal::HAL_ComplementaryPWM_Timer::complementary_PWM_phase_E::ACTIVE_LOW | ||
: basilisk_hal::HAL_ComplementaryPWM_Timer::complementary_PWM_phase_E::ACTIVE_HIGH; | ||
|
||
basilisk_hal::HAL_ComplementaryPWM_Timer::complementary_PWM_phase_E w_complementary_phase = | ||
w.invert_low_side ? basilisk_hal::HAL_ComplementaryPWM_Timer::complementary_PWM_phase_E::ACTIVE_LOW | ||
: basilisk_hal::HAL_ComplementaryPWM_Timer::complementary_PWM_phase_E::ACTIVE_HIGH; | ||
|
||
// Set the PWM timer | ||
pwm_timer_->set_channel_with_complementary_phase(ticks_u, u_.channel, u_complementary_phase); | ||
pwm_timer_->set_channel_with_complementary_phase(ticks_v, v_.channel, v_complementary_phase); | ||
pwm_timer_->set_channel_with_complementary_phase(ticks_w, w_.channel, w_complementary_phase); | ||
} | ||
|
||
// Define a function to read the BEMF voltage | ||
app_hal_status_E read_bemf(bemf_voltage_t& bemf_voltage) { | ||
app_hal_status_E status = app_hal_status_E::APP_HAL_OK; | ||
if (u_.bemf_sense_adc == nullptr || v_.bemf_sense_adc == nullptr || w_.bemf_sense_adc == nullptr) { | ||
status = app_hal_status_E::APP_HAL_NOT_INITIALIZED; | ||
} else { | ||
do { | ||
status = u_.bemf_sense_adc->read_adc(bemf_voltage.u, u_.bemf_sense_adc_channel); | ||
if (status != app_hal_status_E::APP_HAL_OK) { | ||
break; | ||
} | ||
status = v_.bemf_sense_adc->read_adc(bemf_voltage.v, v_.bemf_sense_adc_channel); | ||
if (status != app_hal_status_E::APP_HAL_OK) { | ||
break; | ||
} | ||
status = w_.bemf_sense_adc->read_adc(bemf_voltage.w, w_.bemf_sense_adc_channel); | ||
if (status != app_hal_status_E::APP_HAL_OK) { | ||
break; | ||
} | ||
} while (0); | ||
} | ||
|
||
return status; | ||
} | ||
|
||
// Define a function to read the current | ||
app_hal_status_E read_current(phase_current_t& current) { | ||
IGNORE(current); | ||
return app_hal_status_E::APP_HAL_NOT_IMPLEMENTED; | ||
} | ||
|
||
// Define a function that averages out the BEMF voltage readings. Returns a bemf_voltage_t object that contains the | ||
// average of the BEMF voltage readings. | ||
bemf_voltage_t average_bemf_readings(const bemf_voltage_t& new_reading) { | ||
bemf_voltage_t average_bemf_voltage = {0, 0, 0}; | ||
for (uint8_t i = 0; i < BEMF_VOLTAGE_AVERAGE_SIZE - 1; i++) { | ||
bemf_voltage_[i] = bemf_voltage_[i + 1]; | ||
average_bemf_voltage.u += bemf_voltage_[i].u; | ||
average_bemf_voltage.v += bemf_voltage_[i].v; | ||
average_bemf_voltage.w += bemf_voltage_[i].w; | ||
} | ||
bemf_voltage_[BEMF_VOLTAGE_AVERAGE_SIZE - 1] = new_reading; | ||
average_bemf_voltage.u += new_reading.u; | ||
average_bemf_voltage.v += new_reading.v; | ||
average_bemf_voltage.w += new_reading.w; | ||
average_bemf_voltage.u /= BEMF_VOLTAGE_AVERAGE_SIZE; | ||
average_bemf_voltage.v /= BEMF_VOLTAGE_AVERAGE_SIZE; | ||
average_bemf_voltage.w /= BEMF_VOLTAGE_AVERAGE_SIZE; | ||
return average_bemf_voltage; | ||
} | ||
|
||
private: | ||
// Define a timer object | ||
basilisk_hal::HAL_ComplementaryPWM_Timer* pwm_timer_; | ||
drv8323_phase_config_info_t u_; | ||
drv8323_phase_config_info_t v_; | ||
drv8323_phase_config_info_t w_; | ||
uint32_t frequency_; | ||
static constexpr uint8_t BEMF_VOLTAGE_AVERAGE_SIZE = 10; | ||
// Define an array of bemf voltage objects to average out the readings | ||
bemf_voltage_t bemf_voltage_[BEMF_VOLTAGE_AVERAGE_SIZE]; | ||
}; | ||
|
||
} // namespace hwbridge | ||
|
||
#endif // BRIDGE_3PHASE_DRV8323_HPP |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
#ifndef BRIDGE_HBRIDGE_HPP | ||
#define BRIDGE_HBRIDGE_HPP | ||
|
||
namespace hwbridge { | ||
|
||
// Define a generic h-bridge class | ||
class HBridge { | ||
public: | ||
HBridge() = default; | ||
virtual ~HBridge() = default; | ||
|
||
// Define a virtual function to run the h-bridge | ||
virtual void run(float speed) = 0; | ||
}; | ||
|
||
} // namespace hwbridge | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
#ifndef BRIDGE_HBRIDGE_DRV8801_HPP | ||
#define BRIDGE_HBRIDGE_DRV8801_HPP | ||
#include <math.h> | ||
|
||
#include "bridge_hbridge.hpp" | ||
#include "control_loop.hpp" | ||
#include "hal_gpio.hpp" | ||
#include "hal_timer.hpp" | ||
|
||
namespace hwbridge { | ||
|
||
// Define a class that inherits from HBridge | ||
class HBridgeDRV8801 : public HBridge { | ||
public: | ||
HBridgeDRV8801() = default; | ||
~HBridgeDRV8801() = default; | ||
|
||
void init(basilisk_hal::HAL_Timer& timer, basilisk_hal::timer_channel_E channel, basilisk_hal::HAL_GPIO& pin, | ||
uint32_t frequency) { | ||
// Register the timer and pin | ||
pwm_timer_ = &timer; | ||
dir_pin_ = &pin; | ||
channel_ = channel; | ||
|
||
// Set the direction pin to output | ||
dir_pin_->set_mode(basilisk_hal::gpio_mode_E::OUTPUT); | ||
|
||
// Set the pwm timer to PWM_CENTRE_ALIGNED | ||
pwm_timer_->set_timer_params(basilisk_hal::timer_mode_E::PWM_CENTRE_ALIGNED, frequency); | ||
|
||
// Set the timer channel | ||
pwm_timer_->set_channel(0, channel_); | ||
|
||
// Start the timer | ||
pwm_timer_->start(); | ||
} | ||
|
||
// Define a run method that overrides the run method in HBridge | ||
void run(float speed) override { | ||
// Set the direction pin | ||
dir_pin_->set_output_state(speed > 0); | ||
|
||
// Determine the appropriate amount of ticks by getting the timer period | ||
uint32_t period = pwm_timer_->get_period(); | ||
uint32_t ticks = static_cast<uint32_t>(period * fabs(speed) / control_loop::ControlLoop::MAX_MOTOR_SPEED); | ||
|
||
// Set the PWM timer | ||
pwm_timer_->set_channel(ticks, channel_); | ||
} | ||
|
||
private: | ||
// Define a timer object | ||
basilisk_hal::HAL_Timer* pwm_timer_; | ||
basilisk_hal::timer_channel_E channel_; | ||
basilisk_hal::HAL_GPIO* dir_pin_; | ||
}; | ||
|
||
} // namespace hwbridge | ||
#endif // BRIDGE_HBRIDGE_DRV8801_HPP |
Oops, something went wrong.