Skip to content

Commit

Permalink
Servo/Motor/PWM: Avoid runtime memory alloc.
Browse files Browse the repository at this point in the history
  • Loading branch information
Gadgetoid committed Mar 13, 2023
1 parent 2b926f7 commit e75c90c
Show file tree
Hide file tree
Showing 8 changed files with 22 additions and 41 deletions.
6 changes: 1 addition & 5 deletions drivers/motor/motor_cluster.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,6 @@ namespace motor {
}

MotorCluster::~MotorCluster() {
delete[] states;
delete[] configs;
}

bool MotorCluster::init() {
Expand Down Expand Up @@ -713,10 +711,8 @@ namespace motor {
float deadzone, DecayMode mode, bool auto_phase) {
uint8_t motor_count = pwms.get_chan_pair_count();
if(motor_count > 0) {
states = new MotorState[motor_count];
configs = new motor_config[motor_count];

for(uint motor = 0; motor < motor_count; motor++) {
configs[motor] = motor_config();
states[motor] = MotorState(direction, speed_scale, zeropoint, deadzone);
configs[motor].phase = (auto_phase) ? (float)motor / (float)motor_count : 0.0f;
configs[motor].mode = mode;
Expand Down
7 changes: 5 additions & 2 deletions drivers/motor/motor_cluster.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,15 @@ namespace motor {
//--------------------------------------------------
// Variables
//--------------------------------------------------
public:
static const uint MAX_MOTOR_CHANNELS = 16;

private:
PWMCluster pwms;
uint32_t pwm_period;
float pwm_frequency;
MotorState* states;
motor_config* configs;
MotorState states[MAX_MOTOR_CHANNELS];
motor_config configs[MAX_MOTOR_CHANNELS];


//--------------------------------------------------
Expand Down
12 changes: 2 additions & 10 deletions drivers/pwm/pwm_cluster.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ PWMCluster::PWMCluster(PIO pio, uint sm, uint pin_mask, bool loading_zone)
, sm(sm)
, pin_mask(pin_mask & ((1u << NUM_BANK0_GPIOS) - 1))
, channel_count(0)
, channels(nullptr)
, wrap_level(0)
, loading_zone(loading_zone) {

Expand All @@ -48,7 +47,6 @@ PWMCluster::PWMCluster(PIO pio, uint sm, uint pin_base, uint pin_count, bool loa
, sm(sm)
, pin_mask(0x00000000)
, channel_count(0)
, channels(nullptr)
, wrap_level(0)
, loading_zone(loading_zone) {

Expand All @@ -68,7 +66,6 @@ PWMCluster::PWMCluster(PIO pio, uint sm, const uint8_t *pins, uint32_t length, b
, sm(sm)
, pin_mask(0x00000000)
, channel_count(0)
, channels(nullptr)
, wrap_level(0)
, loading_zone(loading_zone) {

Expand All @@ -90,7 +87,6 @@ PWMCluster::PWMCluster(PIO pio, uint sm, std::initializer_list<uint8_t> pins, bo
, sm(sm)
, pin_mask(0x00000000)
, channel_count(0)
, channels(nullptr)
, wrap_level(0)
, loading_zone(loading_zone) {

Expand All @@ -111,7 +107,6 @@ PWMCluster::PWMCluster(PIO pio, uint sm, const pin_pair *pin_pairs, uint32_t len
, sm(sm)
, pin_mask(0x00000000)
, channel_count(0)
, channels(nullptr)
, wrap_level(0)
, loading_zone(loading_zone) {

Expand All @@ -137,7 +132,6 @@ PWMCluster::PWMCluster(PIO pio, uint sm, std::initializer_list<pin_pair> pin_pai
, sm(sm)
, pin_mask(0x00000000)
, channel_count(0)
, channels(nullptr)
, wrap_level(0)
, loading_zone(loading_zone) {

Expand All @@ -159,8 +153,8 @@ PWMCluster::PWMCluster(PIO pio, uint sm, std::initializer_list<pin_pair> pin_pai

void PWMCluster::constructor_common() {
// Initialise all the channels this PWM will control
if(channel_count > 0) {
channels = new ChannelState[channel_count];
for(uint i = 0; i < channel_count; i++) {
channels[i] = ChannelState();
}

// Set up the transition buffers
Expand Down Expand Up @@ -216,8 +210,6 @@ PWMCluster::~PWMCluster() {
gpio_set_function(channel_to_pin_map[channel], GPIO_FUNC_NULL);
}
}

delete[] channels;
}

void PWMCluster::dma_interrupt_handler() {
Expand Down
3 changes: 2 additions & 1 deletion drivers/pwm/pwm_cluster.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ namespace pimoroni {
public:
static const uint BUFFER_SIZE = 64; // Set to 64, the maximum number of single rises and falls for 32 channels within a looping time period
static const uint NUM_BUFFERS = 3;
static const uint MAX_PWM_CHANNELS = 32;


//--------------------------------------------------
Expand Down Expand Up @@ -104,7 +105,7 @@ namespace pimoroni {
int dma_channel;
uint pin_mask;
uint8_t channel_count;
ChannelState* channels;
ChannelState channels[NUM_BANK0_GPIOS];
uint8_t channel_to_pin_map[NUM_BANK0_GPIOS];
uint wrap_level;

Expand Down
17 changes: 5 additions & 12 deletions drivers/servo/calibration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace servo {
}

Calibration::Calibration()
: calibration(nullptr), calibration_size(0), limit_lower(true), limit_upper(true) {
: calibration_size(0), limit_lower(true), limit_upper(true) {
}

Calibration::Calibration(CalibrationType default_type)
Expand All @@ -19,7 +19,7 @@ namespace servo {
}

Calibration::Calibration(const Calibration &other)
: calibration(nullptr), calibration_size(0), limit_lower(other.limit_lower), limit_upper(other.limit_upper) {
: calibration_size(0), limit_lower(other.limit_lower), limit_upper(other.limit_upper) {
uint size = other.size();
apply_blank_pairs(size);
for(uint i = 0; i < size; i++) {
Expand All @@ -28,10 +28,6 @@ namespace servo {
}

Calibration::~Calibration() {
if(calibration != nullptr) {
delete[] calibration;
calibration = nullptr;
}
}

Calibration &Calibration::operator=(const Calibration &other) {
Expand All @@ -57,16 +53,13 @@ namespace servo {
}

void Calibration::apply_blank_pairs(uint size) {
if(calibration != nullptr) {
delete[] calibration;
}

if(size > 0) {
calibration = new Pair[size];
for(auto i = 0u; i < size; i++) {
calibration[i] = Pair();
}
calibration_size = size;
}
else {
calibration = nullptr;
calibration_size = 0;
}
}
Expand Down
4 changes: 3 additions & 1 deletion drivers/servo/calibration.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ namespace servo {
static constexpr float DEFAULT_MID_PULSE = 1500.0f; // in microseconds
static constexpr float DEFAULT_MAX_PULSE = 2500.0f; // in microseconds

static const uint MAX_CALIBRATION_PAIRS = 32;

private:
static constexpr float LOWER_HARD_LIMIT = 400.0f; // The minimum microsecond pulse to send
static constexpr float UPPER_HARD_LIMIT = 2600.0f; // The maximum microsecond pulse to send
Expand Down Expand Up @@ -110,7 +112,7 @@ namespace servo {
// Variables
//--------------------------------------------------
private:
Pair* calibration;
Pair calibration[MAX_CALIBRATION_PAIRS];
uint calibration_size;
bool limit_lower;
bool limit_upper;
Expand Down
8 changes: 0 additions & 8 deletions drivers/servo/servo_cluster.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,6 @@ namespace servo {
}

ServoCluster::~ServoCluster() {
delete[] states;
delete[] servo_phases;
}

bool ServoCluster::init() {
Expand Down Expand Up @@ -502,9 +500,6 @@ namespace servo {
void ServoCluster::create_servo_states(CalibrationType default_type, bool auto_phase) {
uint8_t servo_count = pwms.get_chan_count();
if(servo_count > 0) {
states = new ServoState[servo_count];
servo_phases = new float[servo_count];

for(uint servo = 0; servo < servo_count; servo++) {
states[servo] = ServoState(default_type);
servo_phases[servo] = (auto_phase) ? (float)servo / (float)servo_count : 0.0f;
Expand All @@ -515,9 +510,6 @@ namespace servo {
void ServoCluster::create_servo_states(const Calibration& calibration, bool auto_phase) {
uint8_t servo_count = pwms.get_chan_count();
if(servo_count > 0) {
states = new ServoState[servo_count];
servo_phases = new float[servo_count];

for(uint servo = 0; servo < servo_count; servo++) {
states[servo] = ServoState(calibration);
servo_phases[servo] = (auto_phase) ? (float)servo / (float)servo_count : 0.0f;
Expand Down
6 changes: 4 additions & 2 deletions drivers/servo/servo_cluster.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,14 @@ namespace servo {
//--------------------------------------------------
// Variables
//--------------------------------------------------
public:
static const uint MAX_SERVO_CHANNELS = 32;
private:
PWMCluster pwms;
uint32_t pwm_period;
float pwm_frequency;
ServoState* states;
float* servo_phases;
ServoState states[MAX_SERVO_CHANNELS];
float servo_phases[MAX_SERVO_CHANNELS];


//--------------------------------------------------
Expand Down

0 comments on commit e75c90c

Please sign in to comment.