More work on encoder wheel C++, adding reset to ioe

pull/774/head
ZodiusInfuser 2023-05-02 22:55:19 +01:00
rodzic 387df3bd12
commit 1cfae8b5f8
7 zmienionych plików z 137 dodań i 70 usunięć

Wyświetl plik

@ -320,8 +320,21 @@ namespace pimoroni {
Pin::adc(1, 7, 0)}
{}
bool IOExpander::init(bool skipChipIdCheck) {
bool succeeded = true;
bool IOExpander::init(bool skipChipIdCheck, bool perform_reset) {
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) {
gpio_set_function(interrupt, GPIO_FUNC_SIO);
@ -331,17 +344,36 @@ namespace pimoroni {
enable_interrupt_out(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);
}
succeeded = false;
return true;
}
uint8_t IOExpander::check_reset() {
uint8_t user_flash_reg = reg::USER_FLASH;
uint8_t value;
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 {

Wyświetl plik

@ -171,7 +171,12 @@ namespace pimoroni {
// Methods
//--------------------------------------------------
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
i2c_inst_t* get_i2c() const;

Wyświetl plik

@ -6,35 +6,29 @@ namespace pimoroni {
bool BreakoutEncoderWheel::init(bool skip_chip_id_check) {
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.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.setup_rotary_encoder(ENC_CHANNEL, ENC_TERM_A, ENC_TERM_B, 0, true); // count microsteps
ioe.set_mode(SW_UP, 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_RIGHT, 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;
@ -67,7 +61,7 @@ namespace pimoroni {
void BreakoutEncoderWheel::set_ioe_address(uint8_t address) {
ioe.set_address(address);
}
bool BreakoutEncoderWheel::get_interrupt_flag() {
return ioe.get_interrupt_flag();
}
@ -93,36 +87,50 @@ namespace pimoroni {
}
}
int BreakoutEncoderWheel::count() {
return 0; // TODO
int16_t BreakoutEncoderWheel::count() {
take_encoder_reading();
return enc_count;
}
int BreakoutEncoderWheel::delta() {
return 0; // TODO
}
int16_t BreakoutEncoderWheel::delta() {
take_encoder_reading();
int BreakoutEncoderWheel::step() {
return 0; // TODO
}
// Determine the change in counts since the last time this function was performed
int16_t change = enc_count - last_delta_count;
last_delta_count = enc_count;
int BreakoutEncoderWheel::turn() {
return 0; // TODO
return change;
}
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() {
return 0; // TODO
return (float)count() / (float)ENC_COUNTS_PER_REV;
}
float BreakoutEncoderWheel::degrees() {
return 0; // TODO
return revolutions() * 360.0f;
}
float BreakoutEncoderWheel::radians() {
return 0; // TODO
return revolutions() * M_PI * 2.0f;
}
Direction BreakoutEncoderWheel::direction() {
@ -209,19 +217,31 @@ namespace pimoroni {
return 0; // TODO
}
/*
bool BreakoutEncoderWheel::wheel_available() {
return (ioe.get_interrupt_flag() > 0);
}
void BreakoutEncoderWheel::take_encoder_reading() {
// Read the current count
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() {
//int16_t count = ioe.read_rotary_encoder(ENC_CHANNEL);
//if(direction != DIRECTION_CW)
// count = 0 - count;
// Invert the change
if(enc_direction == REVERSED_DIR) {
raw_change = 0 - raw_change;
}
ioe.clear_interrupt_flag();
//return count;
return 0;
enc_count += raw_change;
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;
}
}
}
*/
}

Wyświetl plik

@ -29,6 +29,8 @@ namespace pimoroni {
static const uint8_t ENC_CHANNEL = 1;
static const uint8_t ENC_TERM_A = 12;
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_DOWN = 4;
@ -73,9 +75,14 @@ namespace pimoroni {
private:
IOExpander ioe;
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;
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
@ -109,11 +116,11 @@ namespace pimoroni {
// Encoder breakout specific
bool pressed(uint button);
int count();
int delta();
int step();
int turn();
int16_t count();
int16_t delta();
void zero();
int16_t step();
int16_t turn();
float revolutions();
float degrees();
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_pwm_load(bool wait_for_load = false);
int gpio_pwm_frequency(float frequency, bool load = true, bool wait_for_load = false);
private:
void take_encoder_reading();
};
}

Wyświetl plik

@ -5,7 +5,7 @@
////////////////////////////////////////////////////////////////////////////////////////////////////
/***** 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_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 *****/
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_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_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_ALTERNATE_LED_I2C_ADDR), MP_ROM_INT(0x74) },

Wyświetl plik

@ -48,7 +48,7 @@ mp_obj_t BreakoutEncoderWheel_make_new(const mp_obj_type_t *type, size_t n_args,
}
/***** 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 };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ },

Wyświetl plik

@ -6,7 +6,7 @@ extern const mp_obj_type_t breakout_encoder_wheel_BreakoutEncoderWheel_type;
/***** 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_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_clear_interrupt_flag(mp_obj_t self_in);