Finalised motor cluster frequency, and disabled loading zone
This commit is contained in:
parent
15e5eaa890
commit
898e4bace4
|
@ -10,21 +10,21 @@ namespace motor {
|
|||
MotorCluster::MotorCluster(PIO pio, uint sm, uint pin_base, uint pin_pair_count, Direction direction,
|
||||
float speed_scale, float zeropoint, float deadzone, float freq, DecayMode mode,
|
||||
bool auto_phase, PWMCluster::Sequence *seq_buffer, PWMCluster::TransitionData *dat_buffer)
|
||||
: pwms(pio, sm, pin_base, (pin_pair_count * 2), seq_buffer, dat_buffer), pwm_frequency(freq) {
|
||||
: pwms(pio, sm, pin_base, (pin_pair_count * 2), seq_buffer, dat_buffer, false), pwm_frequency(freq) {
|
||||
create_motor_states(direction, speed_scale, zeropoint, deadzone, mode, auto_phase);
|
||||
}
|
||||
|
||||
MotorCluster::MotorCluster(PIO pio, uint sm, const pin_pair *pin_pairs, uint32_t length, Direction direction,
|
||||
float speed_scale, float zeropoint, float deadzone, float freq, DecayMode mode,
|
||||
bool auto_phase, PWMCluster::Sequence *seq_buffer, PWMCluster::TransitionData *dat_buffer)
|
||||
: pwms(pio, sm, pin_pairs, length, seq_buffer, dat_buffer), pwm_frequency(freq) {
|
||||
: pwms(pio, sm, pin_pairs, length, seq_buffer, dat_buffer, false), pwm_frequency(freq) {
|
||||
create_motor_states(direction, speed_scale, zeropoint, deadzone, mode, auto_phase);
|
||||
}
|
||||
|
||||
MotorCluster::MotorCluster(PIO pio, uint sm, std::initializer_list<pin_pair> pin_pairs, Direction direction,
|
||||
float speed_scale, float zeropoint, float deadzone, float freq, DecayMode mode,
|
||||
bool auto_phase, PWMCluster::Sequence *seq_buffer, PWMCluster::TransitionData *dat_buffer)
|
||||
: pwms(pio, sm, pin_pairs, seq_buffer, dat_buffer), pwm_frequency(freq) {
|
||||
: pwms(pio, sm, pin_pairs, seq_buffer, dat_buffer, false), pwm_frequency(freq) {
|
||||
create_motor_states(direction, speed_scale, zeropoint, deadzone, mode, auto_phase);
|
||||
}
|
||||
|
||||
|
@ -289,7 +289,7 @@ namespace motor {
|
|||
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
//}
|
||||
return success;
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ namespace motor {
|
|||
static const DecayMode DEFAULT_DECAY_MODE = SLOW_DECAY; // The standard motor decay behaviour
|
||||
static constexpr float DEFAULT_FREQUENCY = 25000.0f; // The standard motor update rate
|
||||
static constexpr float MIN_FREQUENCY = 10.0f;
|
||||
static constexpr float MAX_FREQUENCY = 50000.0f;
|
||||
static constexpr float MAX_FREQUENCY = 400000.0f;
|
||||
|
||||
static constexpr float ZERO_PERCENT = 0.0f;
|
||||
static constexpr float ONEHUNDRED_PERCENT = 1.0f;
|
||||
|
|
|
@ -22,13 +22,14 @@ uint8_t PWMCluster::claimed_sms[] = { 0x0, 0x0 };
|
|||
uint PWMCluster::pio_program_offset = 0;
|
||||
|
||||
|
||||
PWMCluster::PWMCluster(PIO pio, uint sm, uint pin_mask, Sequence *seq_buffer, TransitionData *dat_buffer)
|
||||
PWMCluster::PWMCluster(PIO pio, uint sm, uint pin_mask, Sequence *seq_buffer, TransitionData *dat_buffer, bool loading_zone)
|
||||
: pio(pio)
|
||||
, sm(sm)
|
||||
, pin_mask(pin_mask & ((1u << NUM_BANK0_GPIOS) - 1))
|
||||
, channel_count(0)
|
||||
, channels(nullptr)
|
||||
, wrap_level(0) {
|
||||
, wrap_level(0)
|
||||
, loading_zone(loading_zone) {
|
||||
|
||||
// Create the channel mapping
|
||||
for(uint pin = 0; pin < NUM_BANK0_GPIOS; pin++) {
|
||||
|
@ -42,13 +43,14 @@ PWMCluster::PWMCluster(PIO pio, uint sm, uint pin_mask, Sequence *seq_buffer, Tr
|
|||
}
|
||||
|
||||
|
||||
PWMCluster::PWMCluster(PIO pio, uint sm, uint pin_base, uint pin_count, Sequence *seq_buffer, TransitionData *dat_buffer)
|
||||
PWMCluster::PWMCluster(PIO pio, uint sm, uint pin_base, uint pin_count, Sequence *seq_buffer, TransitionData *dat_buffer, bool loading_zone)
|
||||
: pio(pio)
|
||||
, sm(sm)
|
||||
, pin_mask(0x00000000)
|
||||
, channel_count(0)
|
||||
, channels(nullptr)
|
||||
, wrap_level(0) {
|
||||
, wrap_level(0)
|
||||
, loading_zone(loading_zone) {
|
||||
|
||||
// Create the pin mask and channel mapping
|
||||
uint pin_end = MIN(pin_count + pin_base, NUM_BANK0_GPIOS);
|
||||
|
@ -61,13 +63,14 @@ PWMCluster::PWMCluster(PIO pio, uint sm, uint pin_base, uint pin_count, Sequence
|
|||
constructor_common(seq_buffer, dat_buffer);
|
||||
}
|
||||
|
||||
PWMCluster::PWMCluster(PIO pio, uint sm, const uint8_t *pins, uint32_t length, Sequence *seq_buffer, TransitionData *dat_buffer)
|
||||
PWMCluster::PWMCluster(PIO pio, uint sm, const uint8_t *pins, uint32_t length, Sequence *seq_buffer, TransitionData *dat_buffer, bool loading_zone)
|
||||
: pio(pio)
|
||||
, sm(sm)
|
||||
, pin_mask(0x00000000)
|
||||
, channel_count(0)
|
||||
, channels(nullptr)
|
||||
, wrap_level(0) {
|
||||
, wrap_level(0)
|
||||
, loading_zone(loading_zone) {
|
||||
|
||||
// Create the pin mask and channel mapping
|
||||
for(uint i = 0; i < length; i++) {
|
||||
|
@ -82,13 +85,14 @@ PWMCluster::PWMCluster(PIO pio, uint sm, const uint8_t *pins, uint32_t length, S
|
|||
constructor_common(seq_buffer, dat_buffer);
|
||||
}
|
||||
|
||||
PWMCluster::PWMCluster(PIO pio, uint sm, std::initializer_list<uint8_t> pins, Sequence *seq_buffer, TransitionData *dat_buffer)
|
||||
PWMCluster::PWMCluster(PIO pio, uint sm, std::initializer_list<uint8_t> pins, Sequence *seq_buffer, TransitionData *dat_buffer, bool loading_zone)
|
||||
: pio(pio)
|
||||
, sm(sm)
|
||||
, pin_mask(0x00000000)
|
||||
, channel_count(0)
|
||||
, channels(nullptr)
|
||||
, wrap_level(0) {
|
||||
, wrap_level(0)
|
||||
, loading_zone(loading_zone) {
|
||||
|
||||
// Create the pin mask and channel mapping
|
||||
for(auto pin : pins) {
|
||||
|
@ -102,13 +106,14 @@ PWMCluster::PWMCluster(PIO pio, uint sm, std::initializer_list<uint8_t> pins, Se
|
|||
constructor_common(seq_buffer, dat_buffer);
|
||||
}
|
||||
|
||||
PWMCluster::PWMCluster(PIO pio, uint sm, const pin_pair *pin_pairs, uint32_t length, Sequence *seq_buffer, TransitionData *dat_buffer)
|
||||
PWMCluster::PWMCluster(PIO pio, uint sm, const pin_pair *pin_pairs, uint32_t length, Sequence *seq_buffer, TransitionData *dat_buffer, bool loading_zone)
|
||||
: pio(pio)
|
||||
, sm(sm)
|
||||
, pin_mask(0x00000000)
|
||||
, channel_count(0)
|
||||
, channels(nullptr)
|
||||
, wrap_level(0) {
|
||||
, wrap_level(0)
|
||||
, loading_zone(loading_zone) {
|
||||
|
||||
// Create the pin mask and channel mapping
|
||||
for(uint i = 0; i < length; i++) {
|
||||
|
@ -127,13 +132,14 @@ PWMCluster::PWMCluster(PIO pio, uint sm, const pin_pair *pin_pairs, uint32_t len
|
|||
constructor_common(seq_buffer, dat_buffer);
|
||||
}
|
||||
|
||||
PWMCluster::PWMCluster(PIO pio, uint sm, std::initializer_list<pin_pair> pin_pairs, Sequence *seq_buffer, TransitionData *dat_buffer)
|
||||
PWMCluster::PWMCluster(PIO pio, uint sm, std::initializer_list<pin_pair> pin_pairs, Sequence *seq_buffer, TransitionData *dat_buffer, bool loading_zone)
|
||||
: pio(pio)
|
||||
, sm(sm)
|
||||
, pin_mask(0x00000000)
|
||||
, channel_count(0)
|
||||
, channels(nullptr)
|
||||
, wrap_level(0) {
|
||||
, wrap_level(0)
|
||||
, loading_zone(loading_zone) {
|
||||
|
||||
// Create the pin mask and channel mapping
|
||||
for(auto pair : pin_pairs) {
|
||||
|
@ -535,12 +541,14 @@ void PWMCluster::load_pwm() {
|
|||
gpio_put(WRITE_GPIO, false);
|
||||
#endif
|
||||
|
||||
// Introduce "Loading Zone" transitions to the end of the sequence to
|
||||
// prevent the DMA interrupt firing many milliseconds before the sequence ends.
|
||||
uint32_t zone_inserts = MIN(LOADING_ZONE_SIZE, wrap_level - LOADING_ZONE_POSITION);
|
||||
for(uint32_t i = zone_inserts + LOADING_ZONE_POSITION; i > LOADING_ZONE_POSITION; i--) {
|
||||
PWMCluster::sorted_insert(transitions, data_size, TransitionData(wrap_level - i));
|
||||
PWMCluster::sorted_insert(looping_transitions, looping_data_size, TransitionData(wrap_level - i));
|
||||
if(loading_zone) {
|
||||
// Introduce "Loading Zone" transitions to the end of the sequence to
|
||||
// prevent the DMA interrupt firing many milliseconds before the sequence ends.
|
||||
uint32_t zone_inserts = MIN(LOADING_ZONE_SIZE, wrap_level - LOADING_ZONE_POSITION);
|
||||
for(uint32_t i = zone_inserts + LOADING_ZONE_POSITION; i > LOADING_ZONE_POSITION; i--) {
|
||||
PWMCluster::sorted_insert(transitions, data_size, TransitionData(wrap_level - i));
|
||||
PWMCluster::sorted_insert(looping_transitions, looping_data_size, TransitionData(wrap_level - i));
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG_MULTI_PWM
|
||||
|
|
|
@ -15,11 +15,12 @@ namespace pimoroni {
|
|||
// Constants
|
||||
//--------------------------------------------------
|
||||
private:
|
||||
static const uint64_t MAX_PWM_CLUSTER_WRAP = UINT16_MAX; // UINT32_MAX works too, but seems to produce less accurate counters
|
||||
static const uint32_t LOADING_ZONE_SIZE = 3; // The number of dummy transitions to insert into the data to delay the DMA interrupt (if zero then no zone is used)
|
||||
static const uint32_t LOADING_ZONE_POSITION = 55; // The number of levels before the wrap level to insert the load zone
|
||||
// Smaller values will make the DMA interrupt trigger closer to the time the data is needed,
|
||||
// but risks stalling the PIO if the interrupt takes longer due to other processes
|
||||
static const uint64_t MAX_PWM_CLUSTER_WRAP = UINT16_MAX; // UINT32_MAX works too, but seems to produce less accurate counters
|
||||
static const uint32_t LOADING_ZONE_SIZE = 3; // The number of dummy transitions to insert into the data to delay the DMA interrupt (if zero then no zone is used)
|
||||
static const uint32_t LOADING_ZONE_POSITION = 55; // The number of levels before the wrap level to insert the load zone
|
||||
// Smaller values will make the DMA interrupt trigger closer to the time the data is needed,
|
||||
// but risks stalling the PIO if the interrupt takes longer due to other processes
|
||||
static const bool DEFAULT_USE_LOADING_ZONE = true; // Whether or not the default behaviour of PWMCluster is to use the loading zone
|
||||
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;
|
||||
|
@ -119,6 +120,7 @@ namespace pimoroni {
|
|||
volatile uint last_written_index = 0;
|
||||
|
||||
bool initialised = false;
|
||||
bool loading_zone = true;
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
|
@ -134,13 +136,13 @@ namespace pimoroni {
|
|||
// Constructors/Destructor
|
||||
//--------------------------------------------------
|
||||
public:
|
||||
PWMCluster(PIO pio, uint sm, uint pin_mask, Sequence *seq_buffer = nullptr, TransitionData *dat_buffer = nullptr);
|
||||
PWMCluster(PIO pio, uint sm, uint pin_base, uint pin_count, Sequence *seq_buffer = nullptr, TransitionData *dat_buffer = nullptr);
|
||||
PWMCluster(PIO pio, uint sm, const uint8_t *pins, uint32_t length, Sequence *seq_buffer = nullptr, TransitionData *dat_buffer = nullptr);
|
||||
PWMCluster(PIO pio, uint sm, std::initializer_list<uint8_t> pins, Sequence *seq_buffer = nullptr, TransitionData *dat_buffer = nullptr);
|
||||
PWMCluster(PIO pio, uint sm, uint pin_mask, Sequence *seq_buffer = nullptr, TransitionData *dat_buffer = nullptr, bool loading_zone = DEFAULT_USE_LOADING_ZONE);
|
||||
PWMCluster(PIO pio, uint sm, uint pin_base, uint pin_count, Sequence *seq_buffer = nullptr, TransitionData *dat_buffer = nullptr, bool loading_zone = DEFAULT_USE_LOADING_ZONE);
|
||||
PWMCluster(PIO pio, uint sm, const uint8_t *pins, uint32_t length, Sequence *seq_buffer = nullptr, TransitionData *dat_buffer = nullptr, bool loading_zone = DEFAULT_USE_LOADING_ZONE);
|
||||
PWMCluster(PIO pio, uint sm, std::initializer_list<uint8_t> pins, Sequence *seq_buffer = nullptr, TransitionData *dat_buffer = nullptr, bool loading_zone = DEFAULT_USE_LOADING_ZONE);
|
||||
|
||||
PWMCluster(PIO pio, uint sm, const pin_pair *pin_pairs, uint32_t length, Sequence *seq_buffer = nullptr, TransitionData *dat_buffer = nullptr);
|
||||
PWMCluster(PIO pio, uint sm, std::initializer_list<pin_pair> pin_pairs, Sequence *seq_buffer = nullptr, TransitionData *dat_buffer = nullptr);
|
||||
PWMCluster(PIO pio, uint sm, const pin_pair *pin_pairs, uint32_t length, Sequence *seq_buffer = nullptr, TransitionData *dat_buffer = nullptr, bool loading_zone = DEFAULT_USE_LOADING_ZONE);
|
||||
PWMCluster(PIO pio, uint sm, std::initializer_list<pin_pair> pin_pairs, Sequence *seq_buffer = nullptr, TransitionData *dat_buffer = nullptr, bool loading_zone = DEFAULT_USE_LOADING_ZONE);
|
||||
~PWMCluster();
|
||||
|
||||
private:
|
||||
|
|
|
@ -302,9 +302,8 @@ extern mp_obj_t Motor_frequency(size_t n_args, const mp_obj_t *pos_args, mp_map_
|
|||
|
||||
float freq = mp_obj_get_float(args[ARG_freq].u_obj);
|
||||
|
||||
// TODO confirm frequency range
|
||||
if(!self->motor->frequency(freq)) {
|
||||
mp_raise_ValueError("freq out of range. Expected 10Hz to 350Hz"); //TODO
|
||||
mp_raise_ValueError("freq out of range. Expected 10Hz to 400KHz");
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
|
@ -1442,7 +1441,7 @@ extern mp_obj_t MotorCluster_frequency(size_t n_args, const mp_obj_t *pos_args,
|
|||
float freq = mp_obj_get_float(args[ARG_freq].u_obj);
|
||||
|
||||
if(!self->cluster->frequency(freq))
|
||||
mp_raise_ValueError("freq out of range. Expected 10Hz to 350Hz");
|
||||
mp_raise_ValueError("freq out of range. Expected 10Hz to 400KHz");
|
||||
else
|
||||
return mp_const_none;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue