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)}
|
||||
{}
|
||||
|
||||
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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
|
@ -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();
|
||||
};
|
||||
|
||||
}
|
|
@ -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) },
|
||||
|
||||
|
|
|
@ -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 },
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue