kopia lustrzana https://github.com/pimoroni/pimoroni-pico
Moved common PWM and MultiPWM out of servo driver, and renamed to cluster
rodzic
06c272916c
commit
aeb9705d15
|
@ -26,4 +26,5 @@ add_subdirectory(icp10125)
|
|||
add_subdirectory(scd4x)
|
||||
add_subdirectory(hub75)
|
||||
add_subdirectory(uc8151)
|
||||
add_subdirectory(pwm)
|
||||
add_subdirectory(servo)
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
include(pwm.cmake)
|
||||
include(pwm_cluster.cmake)
|
|
@ -0,0 +1,12 @@
|
|||
set(DRIVER_NAME pwm)
|
||||
add_library(${DRIVER_NAME} INTERFACE)
|
||||
|
||||
target_sources(${DRIVER_NAME} INTERFACE
|
||||
${CMAKE_CURRENT_LIST_DIR}/pwm.cpp
|
||||
)
|
||||
|
||||
target_include_directories(${DRIVER_NAME} INTERFACE ${CMAKE_CURRENT_LIST_DIR})
|
||||
|
||||
target_link_libraries(${DRIVER_NAME} INTERFACE
|
||||
pico_stdlib
|
||||
)
|
|
@ -0,0 +1,47 @@
|
|||
#include "pwm.hpp"
|
||||
#include "hardware/clocks.h"
|
||||
|
||||
namespace pimoroni {
|
||||
static const uint32_t MAX_PWM_WRAP = UINT16_MAX;
|
||||
|
||||
// Derived from the rp2 Micropython implementation: https://github.com/micropython/micropython/blob/master/ports/rp2/machine_pwm.c
|
||||
bool calculate_pwm_factors(float freq, uint16_t& top_out, uint16_t& div16_out) {
|
||||
bool success = false;
|
||||
uint32_t source_hz = clock_get_hz(clk_sys);
|
||||
|
||||
// Check the provided frequency is valid
|
||||
if((freq >= 1.0f) && (freq <= (float)(source_hz >> 1))) {
|
||||
uint32_t div16_top = (uint32_t)((float)(source_hz << 4) / freq);
|
||||
uint32_t top = 1;
|
||||
|
||||
while(true) {
|
||||
// Try a few small prime factors to get close to the desired frequency.
|
||||
if((div16_top >= (5 << 4)) && (div16_top % 5 == 0) && (top * 5 <= MAX_PWM_WRAP)) {
|
||||
div16_top /= 5;
|
||||
top *= 5;
|
||||
}
|
||||
else if((div16_top >= (3 << 4)) && (div16_top % 3 == 0) && (top * 3 <= MAX_PWM_WRAP)) {
|
||||
div16_top /= 3;
|
||||
top *= 3;
|
||||
}
|
||||
else if((div16_top >= (2 << 4)) && (top * 2 <= MAX_PWM_WRAP)) {
|
||||
div16_top /= 2;
|
||||
top *= 2;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Only return valid factors if the divisor is actually achievable
|
||||
if(div16_top >= 16 && div16_top <= (UINT8_MAX << 4)) {
|
||||
top_out = top;
|
||||
div16_out = div16_top;
|
||||
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
};
|
|
@ -0,0 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "pico/stdlib.h"
|
||||
|
||||
namespace pimoroni {
|
||||
bool calculate_pwm_factors(float freq, uint16_t& top_out, uint16_t& div16_out);
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
set(DRIVER_NAME multi_pwm)
|
||||
set(DRIVER_NAME pwm_cluster)
|
||||
add_library(${DRIVER_NAME} INTERFACE)
|
||||
|
||||
target_sources(${DRIVER_NAME} INTERFACE
|
||||
${CMAKE_CURRENT_LIST_DIR}/multi_pwm.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/pwm_cluster.cpp
|
||||
)
|
||||
|
||||
target_include_directories(${DRIVER_NAME} INTERFACE ${CMAKE_CURRENT_LIST_DIR})
|
||||
|
@ -13,4 +13,4 @@ target_link_libraries(${DRIVER_NAME} INTERFACE
|
|||
hardware_dma
|
||||
)
|
||||
|
||||
pico_generate_pio_header(${DRIVER_NAME} ${CMAKE_CURRENT_LIST_DIR}/multi_pwm.pio)
|
||||
pico_generate_pio_header(${DRIVER_NAME} ${CMAKE_CURRENT_LIST_DIR}/pwm_cluster.pio)
|
|
@ -1,12 +1,13 @@
|
|||
#include "multi_pwm.hpp"
|
||||
#include "pwm_cluster.hpp"
|
||||
#include <cstdio> // TOREMOVE once done debugging
|
||||
#include "hardware/gpio.h" // TOREMOVE once done debugging
|
||||
#include "hardware/clocks.h"
|
||||
#include "pwm_cluster.pio.h"
|
||||
|
||||
// Uncomment the below line to enable debugging
|
||||
#define DEBUG_MULTI_PWM
|
||||
|
||||
namespace servo {
|
||||
namespace pimoroni {
|
||||
|
||||
#ifdef DEBUG_MULTI_PWM
|
||||
static const uint DEBUG_SIDESET = 17;
|
||||
|
@ -76,11 +77,11 @@ interrupt is fired, and the handler reconfigures channel A so that it is ready f
|
|||
* */
|
||||
|
||||
|
||||
MultiPWM::MultiPWM(PIO pio, uint sm, uint channel_mask) : pio(pio), sm(sm), channel_mask(channel_mask) {
|
||||
PWMCluster::PWMCluster(PIO pio, uint sm, uint channel_mask) : pio(pio), sm(sm), channel_mask(channel_mask) {
|
||||
#ifdef DEBUG_MULTI_PWM
|
||||
pio_program_offset = pio_add_program(pio, &debug_multi_pwm_program);
|
||||
pio_program_offset = pio_add_program(pio, &debug_pwm_cluster_program);
|
||||
#else
|
||||
pio_program_offset = pio_add_program(pio, &multi_pwm_program);
|
||||
pio_program_offset = pio_add_program(pio, &pwm_cluster_program);
|
||||
#endif
|
||||
channel_polarities = 0x00000000;
|
||||
wrap_level = 0;
|
||||
|
@ -109,9 +110,9 @@ MultiPWM::MultiPWM(PIO pio, uint sm, uint channel_mask) : pio(pio), sm(sm), chan
|
|||
#endif
|
||||
|
||||
#ifdef DEBUG_MULTI_PWM
|
||||
pio_sm_config c = debug_multi_pwm_program_get_default_config(pio_program_offset);
|
||||
pio_sm_config c = debug_pwm_cluster_program_get_default_config(pio_program_offset);
|
||||
#else
|
||||
pio_sm_config c = multi_pwm_program_get_default_config(pio_program_offset);
|
||||
pio_sm_config c = pwm_cluster_program_get_default_config(pio_program_offset);
|
||||
#endif
|
||||
sm_config_set_out_pins(&c, 0, irq_gpio); //TODO change this to be 32
|
||||
#ifdef DEBUG_MULTI_PWM
|
||||
|
@ -189,14 +190,14 @@ MultiPWM::MultiPWM(PIO pio, uint sm, uint channel_mask) : pio(pio), sm(sm), chan
|
|||
//dma_start_channel_mask(1u << ctrl_dma_channel);
|
||||
}
|
||||
|
||||
MultiPWM::~MultiPWM() {
|
||||
PWMCluster::~PWMCluster() {
|
||||
dma_channel_unclaim(data_dma_channel);
|
||||
dma_channel_unclaim(ctrl_dma_channel);
|
||||
pio_sm_set_enabled(pio, sm, false);
|
||||
#ifdef DEBUG_MULTI_PWM
|
||||
pio_remove_program(pio, &debug_multi_pwm_program, pio_program_offset);
|
||||
pio_remove_program(pio, &debug_pwm_cluster_program, pio_program_offset);
|
||||
#else
|
||||
pio_remove_program(pio, &multi_pwm_program, pio_program_offset);
|
||||
pio_remove_program(pio, &pwm_cluster_program, pio_program_offset);
|
||||
#endif
|
||||
#ifndef MICROPY_BUILD_TYPE
|
||||
// pio_sm_unclaim seems to hardfault in MicroPython
|
||||
|
@ -210,17 +211,17 @@ MultiPWM::~MultiPWM() {
|
|||
}
|
||||
}
|
||||
|
||||
uint MultiPWM::get_chan_mask() const {
|
||||
uint PWMCluster::get_chan_mask() const {
|
||||
return channel_mask;
|
||||
}
|
||||
|
||||
void MultiPWM::set_wrap(uint32_t wrap, bool load) {
|
||||
void PWMCluster::set_wrap(uint32_t wrap, bool load) {
|
||||
wrap_level = MAX(wrap, 1); // Cannot have a wrap of zero!
|
||||
if(load)
|
||||
load_pwm();
|
||||
}
|
||||
|
||||
void MultiPWM::set_chan_level(uint8_t channel, uint32_t level, bool load) {
|
||||
void PWMCluster::set_chan_level(uint8_t channel, uint32_t level, bool load) {
|
||||
if((channel < NUM_BANK0_GPIOS) && bit_in_mask(channel, channel_mask)) {
|
||||
channel_levels[channel] = level;
|
||||
if(load)
|
||||
|
@ -228,7 +229,7 @@ void MultiPWM::set_chan_level(uint8_t channel, uint32_t level, bool load) {
|
|||
}
|
||||
}
|
||||
|
||||
void MultiPWM::set_chan_offset(uint8_t channel, uint32_t offset, bool load) {
|
||||
void PWMCluster::set_chan_offset(uint8_t channel, uint32_t offset, bool load) {
|
||||
if((channel < NUM_BANK0_GPIOS) && bit_in_mask(channel, channel_mask)) {
|
||||
channel_offsets[channel] = offset;
|
||||
if(load)
|
||||
|
@ -236,7 +237,7 @@ void MultiPWM::set_chan_offset(uint8_t channel, uint32_t offset, bool load) {
|
|||
}
|
||||
}
|
||||
|
||||
void MultiPWM::set_chan_polarity(uint8_t channel, bool polarity, bool load) {
|
||||
void PWMCluster::set_chan_polarity(uint8_t channel, bool polarity, bool load) {
|
||||
if((channel < NUM_BANK0_GPIOS) && bit_in_mask(channel, channel_mask)) {
|
||||
if(polarity)
|
||||
channel_polarities |= (1u << channel);
|
||||
|
@ -248,21 +249,21 @@ void MultiPWM::set_chan_polarity(uint8_t channel, bool polarity, bool load) {
|
|||
}
|
||||
|
||||
// These apply immediately, so do not obey the PWM update trigger
|
||||
void MultiPWM::set_clkdiv(float divider) {
|
||||
void PWMCluster::set_clkdiv(float divider) {
|
||||
pio_sm_set_clkdiv(pio, sm, divider);
|
||||
}
|
||||
|
||||
// These apply immediately, so do not obey the PWM update trigger
|
||||
void MultiPWM::set_clkdiv_int_frac(uint16_t integer, uint8_t fract) {
|
||||
void PWMCluster::set_clkdiv_int_frac(uint16_t integer, uint8_t fract) {
|
||||
pio_sm_set_clkdiv_int_frac(pio, sm, integer, fract);
|
||||
}
|
||||
|
||||
/*
|
||||
void MultiPWM::set_phase_correct(bool phase_correct);
|
||||
void PWMCluster::set_phase_correct(bool phase_correct);
|
||||
|
||||
void MultiPWM::set_enabled(bool enabled);*/
|
||||
void PWMCluster::set_enabled(bool enabled);*/
|
||||
|
||||
void MultiPWM::load_pwm() {
|
||||
void PWMCluster::load_pwm() {
|
||||
gpio_put(write_gpio, 1);
|
||||
|
||||
TransitionData transitions[64];
|
||||
|
@ -276,14 +277,14 @@ void MultiPWM::load_pwm() {
|
|||
|
||||
// If the level is greater than zero, add a transition to high
|
||||
if(channel_levels[channel] > 0) {
|
||||
MultiPWM::sorted_insert(transitions, data_size, TransitionData(channel, channel_offsets[channel], !polarity));
|
||||
PWMCluster::sorted_insert(transitions, data_size, TransitionData(channel, channel_offsets[channel], !polarity));
|
||||
//if((channel_offsets[channel] < wrap_level) && (channel_offsets[channel] + channel_levels[channel] >= wrap_level)) {
|
||||
// MultiPWM::sorted_insert(transitions, data_size, TransitionData(channel, 0, !polarity)) // Adds an initial state for PWMs that have their end offset beyond the transition line
|
||||
// PWMCluster::sorted_insert(transitions, data_size, TransitionData(channel, 0, !polarity)) // Adds an initial state for PWMs that have their end offset beyond the transition line
|
||||
//}
|
||||
}
|
||||
// If the level is less than the wrap, add a transition to low
|
||||
if(channel_levels[channel] < wrap_level) {
|
||||
MultiPWM::sorted_insert(transitions, data_size, TransitionData(channel, channel_offsets[channel] + channel_levels[channel], polarity));
|
||||
PWMCluster::sorted_insert(transitions, data_size, TransitionData(channel, channel_offsets[channel] + channel_levels[channel], polarity));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -322,9 +323,9 @@ void MultiPWM::load_pwm() {
|
|||
if(transitions[data_index].level <= current_level) {
|
||||
// Yes, so add the transition state to the pin states mask
|
||||
if(transitions[data_index].state)
|
||||
pin_states |= (1u << transitions[data_index].servo);
|
||||
pin_states |= (1u << transitions[data_index].channel);
|
||||
else
|
||||
pin_states &= ~(1u << transitions[data_index].servo);
|
||||
pin_states &= ~(1u << transitions[data_index].channel);
|
||||
|
||||
data_index++; // Move on to the next transition
|
||||
}
|
||||
|
@ -368,17 +369,17 @@ void MultiPWM::load_pwm() {
|
|||
gpio_put(write_gpio, 0); //TOREMOVE
|
||||
}
|
||||
|
||||
bool MultiPWM::bit_in_mask(uint bit, uint mask) {
|
||||
bool PWMCluster::bit_in_mask(uint bit, uint mask) {
|
||||
return ((1u << bit) & mask) != 0;
|
||||
}
|
||||
|
||||
void MultiPWM::sorted_insert(TransitionData array[], uint &size, const TransitionData &data) {
|
||||
void PWMCluster::sorted_insert(TransitionData array[], uint &size, const TransitionData &data) {
|
||||
uint i;
|
||||
for(i = size; (i > 0 && !array[i - 1].compare(data)); i--) {
|
||||
array[i] = array[i - 1];
|
||||
}
|
||||
array[i] = data;
|
||||
//printf("Added %d, %ld, %d\n", data.servo, data.level, data.state);
|
||||
//printf("Added %d, %ld, %d\n", data.channel, data.level, data.state);
|
||||
size++;
|
||||
}
|
||||
}
|
|
@ -4,27 +4,26 @@
|
|||
#include "hardware/pio.h"
|
||||
#include "hardware/dma.h"
|
||||
#include "hardware/irq.h"
|
||||
#include "multi_pwm.pio.h"
|
||||
|
||||
namespace servo {
|
||||
namespace pimoroni {
|
||||
|
||||
struct TransitionData {
|
||||
uint8_t servo;
|
||||
uint8_t channel;
|
||||
uint32_t level;
|
||||
bool state;
|
||||
|
||||
TransitionData() : servo(0), level(0), state(false) {};
|
||||
TransitionData(uint8_t servo, uint32_t level, bool new_state) : servo(servo), level(level), state(new_state) {};
|
||||
TransitionData() : channel(0), level(0), state(false) {};
|
||||
TransitionData(uint8_t channel, uint32_t level, bool new_state) : channel(channel), level(level), state(new_state) {};
|
||||
|
||||
bool compare(const TransitionData& other) const {
|
||||
return level <= other.level;
|
||||
}
|
||||
};
|
||||
|
||||
class MultiPWM {
|
||||
class PWMCluster {
|
||||
public:
|
||||
MultiPWM(PIO pio, uint sm, uint channel_mask);
|
||||
~MultiPWM();
|
||||
PWMCluster(PIO pio, uint sm, uint channel_mask);
|
||||
~PWMCluster();
|
||||
uint get_chan_mask() const;
|
||||
void set_wrap(uint32_t wrap, bool load = true);
|
||||
void set_chan_level(uint8_t channel, uint32_t level, bool load = true);
|
|
@ -37,7 +37,7 @@
|
|||
|
||||
; PWM Program
|
||||
; --------------------------------------------------
|
||||
.program multi_pwm
|
||||
.program pwm_cluster
|
||||
|
||||
.wrap_target
|
||||
pull ; Pull in the new pin states
|
||||
|
@ -55,7 +55,7 @@ delay:
|
|||
|
||||
; Debug PWM Program
|
||||
; --------------------------------------------------
|
||||
.program debug_multi_pwm
|
||||
.program debug_pwm_cluster
|
||||
.side_set 1
|
||||
|
||||
.wrap_target
|
|
@ -1,2 +1,2 @@
|
|||
include(servo.cmake)
|
||||
include(multi_pwm.cmake)
|
||||
include(servo_cluster.cmake)
|
|
@ -3,7 +3,6 @@ add_library(${DRIVER_NAME} INTERFACE)
|
|||
|
||||
target_sources(${DRIVER_NAME} INTERFACE
|
||||
${CMAKE_CURRENT_LIST_DIR}/servo.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/servo_cluster.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/calibration.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/servo_state.cpp
|
||||
)
|
||||
|
@ -13,5 +12,5 @@ target_include_directories(${DRIVER_NAME} INTERFACE ${CMAKE_CURRENT_LIST_DIR})
|
|||
target_link_libraries(${DRIVER_NAME} INTERFACE
|
||||
pico_stdlib
|
||||
hardware_pwm
|
||||
multi_pwm
|
||||
pwm
|
||||
)
|
|
@ -1,5 +1,6 @@
|
|||
#include "servo.hpp"
|
||||
#include "hardware/clocks.h"
|
||||
#include "pwm.hpp"
|
||||
|
||||
namespace servo {
|
||||
Servo::Servo(uint pin, CalibrationType type)
|
||||
|
@ -14,7 +15,7 @@ namespace servo {
|
|||
bool success = false;
|
||||
|
||||
uint16_t period; uint16_t div16;
|
||||
if(Servo::calculate_pwm_factors(pwm_frequency, period, div16)) {
|
||||
if(pimoroni::calculate_pwm_factors(pwm_frequency, period, div16)) {
|
||||
pwm_period = period;
|
||||
|
||||
pwm_cfg = pwm_get_default_config();
|
||||
|
@ -81,7 +82,7 @@ namespace servo {
|
|||
if((freq >= MIN_FREQUENCY) && (freq <= MAX_FREQUENCY)) {
|
||||
// Calculate a suitable pwm wrap period for this frequency
|
||||
uint16_t period; uint16_t div16;
|
||||
if(Servo::calculate_pwm_factors(freq, period, div16)) {
|
||||
if(pimoroni::calculate_pwm_factors(freq, period, div16)) {
|
||||
|
||||
// Record if the new period will be larger or smaller.
|
||||
// This is used to apply new pwm values either before or after the wrap is applied,
|
||||
|
@ -164,42 +165,4 @@ namespace servo {
|
|||
return state.calibration();
|
||||
}
|
||||
|
||||
// Derived from the rp2 Micropython implementation: https://github.com/micropython/micropython/blob/master/ports/rp2/machine_pwm.c
|
||||
bool Servo::calculate_pwm_factors(float freq, uint16_t& top_out, uint16_t& div16_out) {
|
||||
bool success = false;
|
||||
uint32_t source_hz = clock_get_hz(clk_sys);
|
||||
|
||||
// Check the provided frequency is valid
|
||||
if((freq >= 1.0f) && (freq <= (float)(source_hz >> 1))) {
|
||||
uint32_t div16_top = (uint32_t)((float)(source_hz << 4) / freq);
|
||||
uint32_t top = 1;
|
||||
|
||||
while(true) {
|
||||
// Try a few small prime factors to get close to the desired frequency.
|
||||
if((div16_top >= (5 << 4)) && (div16_top % 5 == 0) && (top * 5 <= MAX_PWM_WRAP)) {
|
||||
div16_top /= 5;
|
||||
top *= 5;
|
||||
}
|
||||
else if((div16_top >= (3 << 4)) && (div16_top % 3 == 0) && (top * 3 <= MAX_PWM_WRAP)) {
|
||||
div16_top /= 3;
|
||||
top *= 3;
|
||||
}
|
||||
else if((div16_top >= (2 << 4)) && (top * 2 <= MAX_PWM_WRAP)) {
|
||||
div16_top /= 2;
|
||||
top *= 2;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(div16_top >= 16 && div16_top <= (UINT8_MAX << 4)) {
|
||||
top_out = top;
|
||||
div16_out = div16_top;
|
||||
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
};
|
|
@ -17,7 +17,6 @@ namespace servo {
|
|||
static constexpr float MIN_FREQUENCY = 10.0f; // Lowest achievable with hardware PWM with good resolution
|
||||
static constexpr float MAX_FREQUENCY = 350.0f; // Highest nice value that still allows the full uS pulse range
|
||||
// Some servos are rated for 333Hz for instance
|
||||
static const uint32_t MAX_PWM_WRAP = UINT16_MAX;
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
|
@ -72,8 +71,6 @@ namespace servo {
|
|||
|
||||
Calibration& calibration();
|
||||
const Calibration& calibration() const;
|
||||
private:
|
||||
static bool calculate_pwm_factors(float freq, uint16_t& top_out, uint16_t& div16_out);
|
||||
};
|
||||
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
set(DRIVER_NAME servo_cluster)
|
||||
add_library(${DRIVER_NAME} INTERFACE)
|
||||
|
||||
target_sources(${DRIVER_NAME} INTERFACE
|
||||
${CMAKE_CURRENT_LIST_DIR}/servo_cluster.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/calibration.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/servo_state.cpp
|
||||
)
|
||||
|
||||
target_include_directories(${DRIVER_NAME} INTERFACE ${CMAKE_CURRENT_LIST_DIR})
|
||||
|
||||
target_link_libraries(${DRIVER_NAME} INTERFACE
|
||||
pico_stdlib
|
||||
pwm_cluster
|
||||
)
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
namespace servo {
|
||||
ServoCluster::ServoCluster(PIO pio, uint sm, uint channel_mask)
|
||||
: multi_pwm(pio, sm, channel_mask) {
|
||||
multi_pwm.set_wrap(20000);
|
||||
: pwms(pio, sm, channel_mask) {
|
||||
pwms.set_wrap(20000);
|
||||
}
|
||||
|
||||
ServoCluster::~ServoCluster() {
|
||||
|
@ -25,20 +25,20 @@ namespace servo {
|
|||
}
|
||||
|
||||
uint ServoCluster::get_pin_mask() const {
|
||||
return multi_pwm.get_chan_mask();
|
||||
return pwms.get_chan_mask();
|
||||
}
|
||||
|
||||
void ServoCluster::enable(uint servo, bool load) {
|
||||
if(servo < NUM_BANK0_GPIOS) {
|
||||
float new_pulse = servos[servo].enable();
|
||||
multi_pwm.set_chan_level(servo, ServoState::pulse_to_level(new_pulse, 20000, 50), load);
|
||||
pwms.set_chan_level(servo, ServoState::pulse_to_level(new_pulse, 20000, 50), load);
|
||||
}
|
||||
}
|
||||
|
||||
void ServoCluster::disable(uint servo, bool load) {
|
||||
if(servo < NUM_BANK0_GPIOS) {
|
||||
float new_pulse = servos[servo].disable();
|
||||
multi_pwm.set_chan_level(servo, ServoState::pulse_to_level(new_pulse, 20000, 50), load);
|
||||
pwms.set_chan_level(servo, ServoState::pulse_to_level(new_pulse, 20000, 50), load);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -59,7 +59,7 @@ namespace servo {
|
|||
void ServoCluster::set_value(uint servo, float value, bool load) {
|
||||
if(servo < NUM_BANK0_GPIOS) {
|
||||
float new_pulse = servos[servo].set_value(value);
|
||||
multi_pwm.set_chan_level(servo, ServoState::pulse_to_level(new_pulse, 20000, 50), load);
|
||||
pwms.set_chan_level(servo, ServoState::pulse_to_level(new_pulse, 20000, 50), load);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -73,7 +73,7 @@ namespace servo {
|
|||
void ServoCluster::set_pulse(uint servo, float pulse, bool load) {
|
||||
if(servo < NUM_BANK0_GPIOS) {
|
||||
float new_pulse = servos[servo].set_pulse(pulse);
|
||||
multi_pwm.set_chan_level(servo, ServoState::pulse_to_level(new_pulse, 20000, 50), load);
|
||||
pwms.set_chan_level(servo, ServoState::pulse_to_level(new_pulse, 20000, 50), load);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -101,35 +101,35 @@ namespace servo {
|
|||
void ServoCluster::to_min(uint servo, bool load) {
|
||||
if(servo < NUM_BANK0_GPIOS) {
|
||||
float new_pulse = servos[servo].to_min();
|
||||
multi_pwm.set_chan_level(servo, ServoState::pulse_to_level(new_pulse, 20000, 50), load);
|
||||
pwms.set_chan_level(servo, ServoState::pulse_to_level(new_pulse, 20000, 50), load);
|
||||
}
|
||||
}
|
||||
|
||||
void ServoCluster::to_mid(uint servo, bool load) {
|
||||
if(servo < NUM_BANK0_GPIOS) {
|
||||
float new_pulse = servos[servo].to_mid();
|
||||
multi_pwm.set_chan_level(servo, ServoState::pulse_to_level(new_pulse, 20000, 50), load);
|
||||
pwms.set_chan_level(servo, ServoState::pulse_to_level(new_pulse, 20000, 50), load);
|
||||
}
|
||||
}
|
||||
|
||||
void ServoCluster::to_max(uint servo, bool load) {
|
||||
if(servo < NUM_BANK0_GPIOS) {
|
||||
float new_pulse = servos[servo].to_max();
|
||||
multi_pwm.set_chan_level(servo, ServoState::pulse_to_level(new_pulse, 20000, 50), load);
|
||||
pwms.set_chan_level(servo, ServoState::pulse_to_level(new_pulse, 20000, 50), load);
|
||||
}
|
||||
}
|
||||
|
||||
void ServoCluster::to_percent(uint servo, float in, float in_min, float in_max, bool load) {
|
||||
if(servo < NUM_BANK0_GPIOS) {
|
||||
float new_pulse = servos[servo].to_percent(in, in_min, in_max);
|
||||
multi_pwm.set_chan_level(servo, ServoState::pulse_to_level(new_pulse, 20000, 50), load);
|
||||
pwms.set_chan_level(servo, ServoState::pulse_to_level(new_pulse, 20000, 50), load);
|
||||
}
|
||||
}
|
||||
|
||||
void ServoCluster::to_percent(uint servo, float in, float in_min, float in_max, float value_min, float value_max, bool load) {
|
||||
if(servo < NUM_BANK0_GPIOS) {
|
||||
float new_pulse = servos[servo].to_percent(in, in_min, in_max, value_min, value_max);
|
||||
multi_pwm.set_chan_level(servo, ServoState::pulse_to_level(new_pulse, 20000, 50), load);
|
||||
pwms.set_chan_level(servo, ServoState::pulse_to_level(new_pulse, 20000, 50), load);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "pico/stdlib.h"
|
||||
#include "multi_pwm.hpp"
|
||||
#include "pwm_cluster.hpp"
|
||||
#include "servo_state.hpp"
|
||||
|
||||
namespace servo {
|
||||
|
@ -22,7 +22,7 @@ namespace servo {
|
|||
// Variables
|
||||
//--------------------------------------------------
|
||||
private:
|
||||
MultiPWM multi_pwm;
|
||||
pimoroni::PWMCluster pwms;
|
||||
ServoState servos[NUM_BANK0_GPIOS]; // TODO change this to array of pointers
|
||||
// so that only the servos actually assigned
|
||||
// to this cluster have states
|
||||
|
|
|
@ -56,7 +56,7 @@ int main() {
|
|||
|
||||
simple_servo.init();
|
||||
|
||||
//MultiPWM pwms(pio1, 0, 0b111111111111111);
|
||||
//PWMCluster pwms(pio1, 0, 0b111111111111111);
|
||||
//pwms.set_wrap(20000);
|
||||
ServoCluster cluster(pio1, 0, 0b111100);
|
||||
|
||||
|
|
|
@ -3,4 +3,4 @@ add_library(servo2040 INTERFACE)
|
|||
target_include_directories(servo2040 INTERFACE ${CMAKE_CURRENT_LIST_DIR})
|
||||
|
||||
# Pull in pico libraries that we need
|
||||
target_link_libraries(servo2040 INTERFACE pico_stdlib plasma multi_pwm servo)
|
||||
target_link_libraries(servo2040 INTERFACE pico_stdlib plasma servo servo_cluster)
|
|
@ -2,7 +2,6 @@
|
|||
#include "pico/stdlib.h"
|
||||
|
||||
#include "ws2812.hpp"
|
||||
#include "multi_pwm.hpp"
|
||||
#include "servo.hpp"
|
||||
#include "servo_cluster.hpp"
|
||||
|
||||
|
|
|
@ -5,16 +5,18 @@ add_library(usermod_${MOD_NAME} INTERFACE)
|
|||
target_sources(usermod_${MOD_NAME} INTERFACE
|
||||
${CMAKE_CURRENT_LIST_DIR}/${MOD_NAME}.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/${MOD_NAME}.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/../../../drivers/pwm/pwm.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/../../../drivers/pwm/pwm_cluster.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/../../../drivers/servo/servo.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/../../../drivers/servo/servo_cluster.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/../../../drivers/servo/servo_state.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/../../../drivers/servo/calibration.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/../../../drivers/servo/multi_pwm.cpp
|
||||
)
|
||||
pico_generate_pio_header(usermod_${MOD_NAME} ${CMAKE_CURRENT_LIST_DIR}/../../../drivers/servo/multi_pwm.pio)
|
||||
pico_generate_pio_header(usermod_${MOD_NAME} ${CMAKE_CURRENT_LIST_DIR}/../../../drivers/pwm/pwm_cluster.pio)
|
||||
|
||||
target_include_directories(usermod_${MOD_NAME} INTERFACE
|
||||
${CMAKE_CURRENT_LIST_DIR}
|
||||
${CMAKE_CURRENT_LIST_DIR}/../../../drivers/pwm/
|
||||
${CMAKE_CURRENT_LIST_DIR}/../../../drivers/servo/
|
||||
)
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue