kopia lustrzana https://github.com/pimoroni/pimoroni-pico
More work on encoder wheel C++, adding reset to ioe
rodzic
387df3bd12
commit
1cfae8b5f8
|
@ -320,8 +320,21 @@ namespace pimoroni {
|
||||||
Pin::adc(1, 7, 0)}
|
Pin::adc(1, 7, 0)}
|
||||||
{}
|
{}
|
||||||
|
|
||||||
bool IOExpander::init(bool skipChipIdCheck) {
|
bool IOExpander::init(bool skipChipIdCheck, bool perform_reset) {
|
||||||
bool succeeded = true;
|
if(!skipChipIdCheck) {
|
||||||
|
uint16_t chip_id = get_chip_id();
|
||||||
|
if(chip_id != CHIP_ID) {
|
||||||
|
if(debug) {
|
||||||
|
printf("Chip ID invalid: %04x expected: %04x\n", chip_id, CHIP_ID);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset the chip if requested, to put it into a known state
|
||||||
|
if(perform_reset && !reset()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if(interrupt != PIN_UNUSED) {
|
if(interrupt != PIN_UNUSED) {
|
||||||
gpio_set_function(interrupt, GPIO_FUNC_SIO);
|
gpio_set_function(interrupt, GPIO_FUNC_SIO);
|
||||||
|
@ -331,17 +344,36 @@ namespace pimoroni {
|
||||||
enable_interrupt_out(true);
|
enable_interrupt_out(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!skipChipIdCheck) {
|
return true;
|
||||||
uint16_t chip_id = get_chip_id();
|
}
|
||||||
if(chip_id != CHIP_ID) {
|
|
||||||
if(debug) {
|
uint8_t IOExpander::check_reset() {
|
||||||
printf("Chip ID invalid: %04x expected: %04x\n", chip_id, CHIP_ID);
|
uint8_t user_flash_reg = reg::USER_FLASH;
|
||||||
}
|
uint8_t value;
|
||||||
succeeded = false;
|
if(i2c_write_blocking(i2c->get_i2c(), address, &user_flash_reg, 1, false) == PICO_ERROR_GENERIC) {
|
||||||
|
return 0x00;
|
||||||
|
}
|
||||||
|
if(i2c_read_blocking(i2c->get_i2c(), address, (uint8_t *)&value, sizeof(uint8_t), false) == PICO_ERROR_GENERIC) {
|
||||||
|
return 0x00;
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IOExpander::reset() {
|
||||||
|
uint32_t start_time = millis();
|
||||||
|
set_bits(reg::CTRL, ctrl_mask::RESET);
|
||||||
|
// Wait for a register to read its initialised value
|
||||||
|
while(check_reset() != 0x78) {
|
||||||
|
sleep_ms(1);
|
||||||
|
if(millis() - start_time >= timeout) {
|
||||||
|
if(debug)
|
||||||
|
printf("Timed out waiting for Reset!");
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return succeeded;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
i2c_inst_t* IOExpander::get_i2c() const {
|
i2c_inst_t* IOExpander::get_i2c() const {
|
||||||
|
|
|
@ -171,7 +171,12 @@ namespace pimoroni {
|
||||||
// Methods
|
// Methods
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
public:
|
public:
|
||||||
bool init(bool skip_chip_id_check = false);
|
bool init(bool skip_chip_id_check = false, bool perform_reset = false);
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint8_t check_reset();
|
||||||
|
public:
|
||||||
|
bool reset();
|
||||||
|
|
||||||
// For print access in micropython
|
// For print access in micropython
|
||||||
i2c_inst_t* get_i2c() const;
|
i2c_inst_t* get_i2c() const;
|
||||||
|
|
|
@ -6,35 +6,29 @@ namespace pimoroni {
|
||||||
|
|
||||||
bool BreakoutEncoderWheel::init(bool skip_chip_id_check) {
|
bool BreakoutEncoderWheel::init(bool skip_chip_id_check) {
|
||||||
bool success = false;
|
bool success = false;
|
||||||
if(ioe.init(skip_chip_id_check)) {
|
if(ioe.init(skip_chip_id_check, true) && led_ring.init()) {
|
||||||
|
|
||||||
if(interrupt_pin != PIN_UNUSED) {
|
ioe.setup_rotary_encoder(ENC_CHANNEL, ENC_TERM_A, ENC_TERM_B, 0, true); // count microsteps
|
||||||
ioe.enable_interrupt_out(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
ioe.setup_rotary_encoder(ENC_CHANNEL, ENC_TERM_A, ENC_TERM_B);
|
|
||||||
|
|
||||||
if(led_ring.init()) {
|
|
||||||
led_ring.enable({
|
|
||||||
0b00000000, 0b10111111,
|
|
||||||
0b00111110, 0b00111110,
|
|
||||||
0b00111111, 0b10111110,
|
|
||||||
0b00000111, 0b10000110,
|
|
||||||
0b00110000, 0b00110000,
|
|
||||||
0b00111111, 0b10111110,
|
|
||||||
0b00111111, 0b10111110,
|
|
||||||
0b01111111, 0b11111110,
|
|
||||||
0b01111111, 0b00000000
|
|
||||||
}, 0);
|
|
||||||
|
|
||||||
success = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
ioe.set_mode(SW_UP, IOExpander::PIN_IN_PU);
|
ioe.set_mode(SW_UP, IOExpander::PIN_IN_PU);
|
||||||
ioe.set_mode(SW_DOWN, IOExpander::PIN_IN_PU);
|
ioe.set_mode(SW_DOWN, IOExpander::PIN_IN_PU);
|
||||||
ioe.set_mode(SW_LEFT, IOExpander::PIN_IN_PU);
|
ioe.set_mode(SW_LEFT, IOExpander::PIN_IN_PU);
|
||||||
ioe.set_mode(SW_RIGHT, IOExpander::PIN_IN_PU);
|
ioe.set_mode(SW_RIGHT, IOExpander::PIN_IN_PU);
|
||||||
ioe.set_mode(SW_CENTRE, IOExpander::PIN_IN_PU);
|
ioe.set_mode(SW_CENTRE, IOExpander::PIN_IN_PU);
|
||||||
|
|
||||||
|
led_ring.enable({
|
||||||
|
0b00000000, 0b10111111,
|
||||||
|
0b00111110, 0b00111110,
|
||||||
|
0b00111111, 0b10111110,
|
||||||
|
0b00000111, 0b10000110,
|
||||||
|
0b00110000, 0b00110000,
|
||||||
|
0b00111111, 0b10111110,
|
||||||
|
0b00111111, 0b10111110,
|
||||||
|
0b01111111, 0b11111110,
|
||||||
|
0b01111111, 0b00000000
|
||||||
|
}, 0);
|
||||||
|
|
||||||
|
success = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
|
@ -67,7 +61,7 @@ namespace pimoroni {
|
||||||
void BreakoutEncoderWheel::set_ioe_address(uint8_t address) {
|
void BreakoutEncoderWheel::set_ioe_address(uint8_t address) {
|
||||||
ioe.set_address(address);
|
ioe.set_address(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BreakoutEncoderWheel::get_interrupt_flag() {
|
bool BreakoutEncoderWheel::get_interrupt_flag() {
|
||||||
return ioe.get_interrupt_flag();
|
return ioe.get_interrupt_flag();
|
||||||
}
|
}
|
||||||
|
@ -93,36 +87,50 @@ namespace pimoroni {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int BreakoutEncoderWheel::count() {
|
int16_t BreakoutEncoderWheel::count() {
|
||||||
return 0; // TODO
|
take_encoder_reading();
|
||||||
|
return enc_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
int BreakoutEncoderWheel::delta() {
|
int16_t BreakoutEncoderWheel::delta() {
|
||||||
return 0; // TODO
|
take_encoder_reading();
|
||||||
}
|
|
||||||
|
|
||||||
int BreakoutEncoderWheel::step() {
|
// Determine the change in counts since the last time this function was performed
|
||||||
return 0; // TODO
|
int16_t change = enc_count - last_delta_count;
|
||||||
}
|
last_delta_count = enc_count;
|
||||||
|
|
||||||
int BreakoutEncoderWheel::turn() {
|
return change;
|
||||||
return 0; // TODO
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BreakoutEncoderWheel::zero() {
|
void BreakoutEncoderWheel::zero() {
|
||||||
|
ioe.clear_rotary_encoder(ENC_CHANNEL);
|
||||||
|
enc_count = 0;
|
||||||
|
enc_step = 0;
|
||||||
|
enc_turn = 0;
|
||||||
|
last_raw_count = 0;
|
||||||
|
last_delta_count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16_t BreakoutEncoderWheel::step() {
|
||||||
|
take_encoder_reading();
|
||||||
|
return enc_step;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16_t BreakoutEncoderWheel::turn() {
|
||||||
|
take_encoder_reading();
|
||||||
|
return enc_turn;
|
||||||
}
|
}
|
||||||
|
|
||||||
float BreakoutEncoderWheel::revolutions() {
|
float BreakoutEncoderWheel::revolutions() {
|
||||||
return 0; // TODO
|
return (float)count() / (float)ENC_COUNTS_PER_REV;
|
||||||
}
|
}
|
||||||
|
|
||||||
float BreakoutEncoderWheel::degrees() {
|
float BreakoutEncoderWheel::degrees() {
|
||||||
return 0; // TODO
|
return revolutions() * 360.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
float BreakoutEncoderWheel::radians() {
|
float BreakoutEncoderWheel::radians() {
|
||||||
return 0; // TODO
|
return revolutions() * M_PI * 2.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
Direction BreakoutEncoderWheel::direction() {
|
Direction BreakoutEncoderWheel::direction() {
|
||||||
|
@ -209,19 +217,31 @@ namespace pimoroni {
|
||||||
return 0; // TODO
|
return 0; // TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
void BreakoutEncoderWheel::take_encoder_reading() {
|
||||||
bool BreakoutEncoderWheel::wheel_available() {
|
// Read the current count
|
||||||
return (ioe.get_interrupt_flag() > 0);
|
int16_t raw_count = ioe.read_rotary_encoder(ENC_CHANNEL) / ENC_COUNT_DIVIDER;
|
||||||
}
|
int16_t raw_change = raw_count - last_raw_count;
|
||||||
|
last_raw_count = raw_count;
|
||||||
|
|
||||||
int16_t BreakoutEncoderWheel::read_wheel() {
|
// Invert the change
|
||||||
//int16_t count = ioe.read_rotary_encoder(ENC_CHANNEL);
|
if(enc_direction == REVERSED_DIR) {
|
||||||
//if(direction != DIRECTION_CW)
|
raw_change = 0 - raw_change;
|
||||||
// count = 0 - count;
|
}
|
||||||
|
|
||||||
ioe.clear_interrupt_flag();
|
enc_count += raw_change;
|
||||||
//return count;
|
|
||||||
return 0;
|
enc_step += raw_change;
|
||||||
|
if(raw_change > 0) {
|
||||||
|
while(enc_step >= ENC_COUNTS_PER_REV) {
|
||||||
|
enc_step -= ENC_COUNTS_PER_REV;
|
||||||
|
enc_turn += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(raw_change < 0) {
|
||||||
|
while(enc_step < 0) {
|
||||||
|
enc_step += ENC_COUNTS_PER_REV;
|
||||||
|
enc_turn -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
}
|
}
|
|
@ -29,6 +29,8 @@ namespace pimoroni {
|
||||||
static const uint8_t ENC_CHANNEL = 1;
|
static const uint8_t ENC_CHANNEL = 1;
|
||||||
static const uint8_t ENC_TERM_A = 12;
|
static const uint8_t ENC_TERM_A = 12;
|
||||||
static const uint8_t ENC_TERM_B = 3;
|
static const uint8_t ENC_TERM_B = 3;
|
||||||
|
static const uint8_t ENC_COUNTS_PER_REV = 24;
|
||||||
|
static const uint8_t ENC_COUNT_DIVIDER = 2;
|
||||||
|
|
||||||
static const uint8_t SW_UP = 13;
|
static const uint8_t SW_UP = 13;
|
||||||
static const uint8_t SW_DOWN = 4;
|
static const uint8_t SW_DOWN = 4;
|
||||||
|
@ -73,9 +75,14 @@ namespace pimoroni {
|
||||||
private:
|
private:
|
||||||
IOExpander ioe;
|
IOExpander ioe;
|
||||||
IS31FL3731 led_ring;
|
IS31FL3731 led_ring;
|
||||||
//Direction direction = DEFAULT_DIRECTION;
|
|
||||||
uint interrupt_pin = PIN_UNUSED; // A local copy of the value passed to the IOExpander, used in initialisation
|
|
||||||
Direction enc_direction = DEFAULT_DIRECTION;
|
Direction enc_direction = DEFAULT_DIRECTION;
|
||||||
|
int16_t enc_count = 0;
|
||||||
|
int16_t enc_step = 0;
|
||||||
|
int16_t enc_turn = 0;
|
||||||
|
int16_t last_raw_count = 0;
|
||||||
|
int16_t last_delta_count = 0;
|
||||||
|
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// Constructors/Destructor
|
// Constructors/Destructor
|
||||||
|
@ -109,11 +116,11 @@ namespace pimoroni {
|
||||||
|
|
||||||
// Encoder breakout specific
|
// Encoder breakout specific
|
||||||
bool pressed(uint button);
|
bool pressed(uint button);
|
||||||
int count();
|
int16_t count();
|
||||||
int delta();
|
int16_t delta();
|
||||||
int step();
|
|
||||||
int turn();
|
|
||||||
void zero();
|
void zero();
|
||||||
|
int16_t step();
|
||||||
|
int16_t turn();
|
||||||
float revolutions();
|
float revolutions();
|
||||||
float degrees();
|
float degrees();
|
||||||
float radians();
|
float radians();
|
||||||
|
@ -131,6 +138,9 @@ namespace pimoroni {
|
||||||
void gpio_pin_value(int gpio, int value, bool load = true, bool wait_for_load = false);
|
void gpio_pin_value(int gpio, int value, bool load = true, bool wait_for_load = false);
|
||||||
void gpio_pwm_load(bool wait_for_load = false);
|
void gpio_pwm_load(bool wait_for_load = false);
|
||||||
int gpio_pwm_frequency(float frequency, bool load = true, bool wait_for_load = false);
|
int gpio_pwm_frequency(float frequency, bool load = true, bool wait_for_load = false);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void take_encoder_reading();
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
|
@ -5,7 +5,7 @@
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
/***** Methods *****/
|
/***** Methods *****/
|
||||||
MP_DEFINE_CONST_FUN_OBJ_KW(BreakoutEncoderWheel_set_address_obj, 2, BreakoutEncoderWheel_set_address);
|
MP_DEFINE_CONST_FUN_OBJ_KW(BreakoutEncoderWheel_set_ioe_address_obj, 2, BreakoutEncoderWheel_set_ioe_address);
|
||||||
MP_DEFINE_CONST_FUN_OBJ_1(BreakoutEncoderWheel_get_interrupt_flag_obj, BreakoutEncoderWheel_get_interrupt_flag);
|
MP_DEFINE_CONST_FUN_OBJ_1(BreakoutEncoderWheel_get_interrupt_flag_obj, BreakoutEncoderWheel_get_interrupt_flag);
|
||||||
MP_DEFINE_CONST_FUN_OBJ_1(BreakoutEncoderWheel_clear_interrupt_flag_obj, BreakoutEncoderWheel_clear_interrupt_flag);
|
MP_DEFINE_CONST_FUN_OBJ_1(BreakoutEncoderWheel_clear_interrupt_flag_obj, BreakoutEncoderWheel_clear_interrupt_flag);
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(BreakoutEncoderWheel_gpio_pwm_frequency_obj, 2, Break
|
||||||
|
|
||||||
/***** Binding of Methods *****/
|
/***** Binding of Methods *****/
|
||||||
STATIC const mp_rom_map_elem_t BreakoutEncoderWheel_locals_dict_table[] = {
|
STATIC const mp_rom_map_elem_t BreakoutEncoderWheel_locals_dict_table[] = {
|
||||||
{ MP_ROM_QSTR(MP_QSTR_set_address), MP_ROM_PTR(&BreakoutEncoderWheel_set_address_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_set_ioe_address), MP_ROM_PTR(&BreakoutEncoderWheel_set_ioe_address_obj) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_get_interrupt_flag), MP_ROM_PTR(&BreakoutEncoderWheel_get_interrupt_flag_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_get_interrupt_flag), MP_ROM_PTR(&BreakoutEncoderWheel_get_interrupt_flag_obj) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_clear_interrupt_flag), MP_ROM_PTR(&BreakoutEncoderWheel_clear_interrupt_flag_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_clear_interrupt_flag), MP_ROM_PTR(&BreakoutEncoderWheel_clear_interrupt_flag_obj) },
|
||||||
|
|
||||||
|
@ -92,7 +92,7 @@ STATIC const mp_rom_map_elem_t breakout_encoder_wheel_globals_table[] = {
|
||||||
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_breakout_encoder_wheel) },
|
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_breakout_encoder_wheel) },
|
||||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_BreakoutEncoderWheel), (mp_obj_t)&breakout_encoder_wheel_BreakoutEncoderWheel_type },
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_BreakoutEncoderWheel), (mp_obj_t)&breakout_encoder_wheel_BreakoutEncoderWheel_type },
|
||||||
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_I2C_ADDR), MP_ROM_INT(0x13) },
|
{ MP_ROM_QSTR(MP_QSTR_DEFAULT_IOE_I2C_ADDR), MP_ROM_INT(0x13) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_DEFAULT_LED_I2C_ADDR), MP_ROM_INT(0x77) },
|
{ MP_ROM_QSTR(MP_QSTR_DEFAULT_LED_I2C_ADDR), MP_ROM_INT(0x77) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_ALTERNATE_LED_I2C_ADDR), MP_ROM_INT(0x74) },
|
{ MP_ROM_QSTR(MP_QSTR_ALTERNATE_LED_I2C_ADDR), MP_ROM_INT(0x74) },
|
||||||
|
|
||||||
|
|
|
@ -48,7 +48,7 @@ mp_obj_t BreakoutEncoderWheel_make_new(const mp_obj_type_t *type, size_t n_args,
|
||||||
}
|
}
|
||||||
|
|
||||||
/***** Methods *****/
|
/***** Methods *****/
|
||||||
mp_obj_t BreakoutEncoderWheel_set_address(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
mp_obj_t BreakoutEncoderWheel_set_ioe_address(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||||
enum { ARG_self, ARG_address };
|
enum { ARG_self, ARG_address };
|
||||||
static const mp_arg_t allowed_args[] = {
|
static const mp_arg_t allowed_args[] = {
|
||||||
{ MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ },
|
{ MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ },
|
||||||
|
|
|
@ -6,7 +6,7 @@ extern const mp_obj_type_t breakout_encoder_wheel_BreakoutEncoderWheel_type;
|
||||||
|
|
||||||
/***** Extern of Class Methods *****/
|
/***** Extern of Class Methods *****/
|
||||||
extern mp_obj_t BreakoutEncoderWheel_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args);
|
extern mp_obj_t BreakoutEncoderWheel_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args);
|
||||||
extern mp_obj_t BreakoutEncoderWheel_set_address(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
|
extern mp_obj_t BreakoutEncoderWheel_set_ioe_address(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
|
||||||
extern mp_obj_t BreakoutEncoderWheel_get_interrupt_flag(mp_obj_t self_in);
|
extern mp_obj_t BreakoutEncoderWheel_get_interrupt_flag(mp_obj_t self_in);
|
||||||
extern mp_obj_t BreakoutEncoderWheel_clear_interrupt_flag(mp_obj_t self_in);
|
extern mp_obj_t BreakoutEncoderWheel_clear_interrupt_flag(mp_obj_t self_in);
|
||||||
|
|
||||||
|
|
Ładowanie…
Reference in New Issue