125 #if QEI_ENABLE && defined(QEI_A_PIN) && defined(QEI_B_PIN)
149 uint8_t port_a, port_b, port_select;
150 volatile uint32_t dbl_click_timeout;
151 volatile uint32_t vel_timeout;
152 uint32_t vel_timestamp;
157 static iqei_t iqei = {
161 .settings.dbl_click_window = 500,
162 .encoder.caps.bidirectional =
On
165 static void iqei_select_irq (uint8_t port,
bool high);
167 static void iqei_post_event (
void *data)
171 iqei.on_event(&iqei.encoder, &iqei.event, iqei.context);
176 iqei.vel_timeout = 0;
177 iqei.dir = QEI_DirUnknown;
178 iqei.data.position = iqei.vel_count = 0;
180 iqei.vel_timeout = iqei.settings.vel_timeout;
185 if(iqei.vel_timeout !=
settings->vel_timeout)
198 static void iqei_poll (
void *data)
200 if(iqei.vel_timeout && !(--iqei.vel_timeout)) {
204 iqei.data.velocity = abs(iqei.data.position - iqei.vel_count) * 1000 / (time - iqei.vel_timestamp);
205 iqei.vel_timestamp = time;
206 iqei.vel_timeout = iqei.settings.vel_timeout;
207 if((iqei.event.position_changed = !iqei.dbl_click_timeout || iqei.data.velocity == 0))
208 iqei.on_event(&iqei.encoder, &iqei.event, iqei.context);
209 iqei.vel_count = iqei.data.position;
212 if(iqei.dbl_click_timeout && !(--iqei.dbl_click_timeout)) {
213 iqei.event.click =
On;
214 iqei.on_event(&iqei.encoder, &iqei.event, iqei.context);
218 static void iqei_ab_irq (uint8_t port,
bool high)
220 PROGMEM
static const uint8_t encoder_valid_state[] = {0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0};
223 static qei_state_t state = {0};
225 if(port == iqei.port_a)
230 uint_fast8_t idx = (((iqei.state << 2) & 0x0F) | state.pins);
232 if(encoder_valid_state[idx] ) {
236 iqei.state = ((iqei.state << 4) | idx) & 0xFF;
238 if(iqei.state == 0x42 || iqei.state == 0xD4 || iqei.state == 0x2B || iqei.state == 0xBD) {
239 iqei.data.position--;
240 if(iqei.vel_timeout == 0 || iqei.dir == QEI_DirCW) {
241 iqei.dir = QEI_DirCCW;
244 }
else if(iqei.state == 0x81 || iqei.state == 0x17 || iqei.state == 0xE8 || iqei.state == 0x7E) {
245 iqei.data.position++;
246 if(iqei.vel_timeout == 0 || iqei.dir == QEI_DirCCW) {
247 iqei.dir = QEI_DirCW;
254 static void iqei_select (
void *data)
256 static uint8_t clicks = 0;
258 if(!iqei.dbl_click_timeout) {
260 iqei.dbl_click_timeout = iqei.settings.dbl_click_window;
261 }
else if(iqei.dbl_click_timeout < iqei.settings.dbl_click_window && ++clicks == 2) {
262 iqei.dbl_click_timeout = 0;
263 iqei.event.dbl_click =
On;
264 iqei.on_event(&iqei.encoder, &iqei.event, iqei.context);
268 static void iqei_select_irq (uint8_t port,
bool high)
270 static bool lock =
false;
284 if(event_handler == NULL || iqei.on_event)
287 iqei.context = context;
288 iqei.on_event = event_handler;
289 iqei.encoder.reset = iqei_reset;
290 iqei.encoder.get_data = iqei_get_data;
291 iqei.encoder.configure = iqei_configure;
306 static inline void _encoder_pin_claimed (uint8_t port,
xbar_t *pin)
316 iqei.encoder.claim = iqei_claim;
322 iqei.port_select = port;
323 iqei.encoder.caps.select =
On;
329 pin->
config(pin, &config,
false);
@ PullMode_Up
0b01 (0x01)
Definition: crossbar.h:717
@ Input_QEI_A
Definition: crossbar.h:337
@ Input_QEI_Select
Definition: crossbar.h:339
@ Input_QEI_B
Definition: crossbar.h:338
@ IRQ_Mode_Change
0b00100 (0x04)
Definition: crossbar.h:694
bool(* encoder_configure_ptr)(encoder_t *encoder, encoder_cfg_t *settings)
Pointer to function for configuring an encoder.
Definition: encoders.h:106
encoder_data_t *(* encoder_get_data_ptr)(encoder_t *encoder)
Pointer to function for getting encoder data.
Definition: encoders.h:93
bool(* encoder_enumerate_callback_ptr)(encoder_t *encoder, void *data)
Pointer to the callbak function to be called by encoders_enumerate().
Definition: encoders.h:99
void encoder_register(encoder_t *encoder)
Definition: encoders.c:35
uint8_t encoders_get_count(void)
Definition: encoders.c:67
bool encoders_enumerate(encoder_enumerate_callback_ptr callback, void *data)
Definition: encoders.c:55
bool(* encoder_claim_ptr)(encoder_t *encoder, encoder_on_event_ptr event_handler, void *context)
Pointer to function for claiming an encoder.
Definition: encoders.h:87
void(* encoder_reset_ptr)(encoder_t *encoder)
Pointer to function for resetting encoder data.
Definition: encoders.h:79
void(* encoder_on_event_ptr)(encoder_t *encoder, encoder_event_t *events, void *context)
Pointer to callback function to receive encoder events.
Definition: encoders.h:74
ISR_CODE bool ISR_FUNC() task_add_immediate(foreground_task_ptr fn, void *data)
Enqueue a function to be called once by the foreground process.
Definition: grbllib.c:750
DCRAM grbl_hal_t hal
Global HAL struct.
Definition: grbllib.c:91
ISR_CODE bool ISR_FUNC() task_add_systick(foreground_task_ptr fn, void *data)
Definition: grbllib.c:697
FLASHMEM bool ioport_enable_irq(uint8_t port, pin_irq_mode_t irq_mode, ioport_interrupt_callback_ptr handler)
Definition: ioports.c:643
#define IOPORT_UNASSIGNED
Definition: ioports.h:26
#define On
Definition: nuts_bolts.h:36
settings_t settings
Definition: settings.c:48
Definition: encoders.h:56
uint32_t dbl_click_window
ms.
Definition: encoders.h:58
uint32_t vel_timeout
Definition: encoders.h:57
Definition: encoders.h:61
int32_t position
Definition: encoders.h:62
uint32_t velocity
Definition: encoders.h:63
Definition: encoders.h:112
encoder_reset_ptr reset
Definition: encoders.h:116
encoder_configure_ptr configure
Definition: encoders.h:118
encoder_caps_t caps
Definition: encoders.h:114
void * hw
Definition: encoders.h:113
encoder_claim_ptr claim
Definition: encoders.h:115
encoder_get_data_ptr get_data
Definition: encoders.h:117
/a cfg_data argument to /a xbar_config_ptr for gpio input pins
Definition: crossbar.h:816
bool debounce
Definition: crossbar.h:818
uint32_t(* get_elapsed_ticks)(void)
Optional handler for getting number of elapsed 1 ms tics since startup. Rolls over every 49....
Definition: hal.h:667
Definition: crossbar.h:879
xbar_config_ptr config
Optional pointer to function for configuring the port.
Definition: crossbar.h:889
pin_function_t function
Pin function.
Definition: crossbar.h:882
Definition: encoders.h:43
uint8_t value
Definition: encoders.h:44
uint8_t spindle_rpm
Definition: encoders.h:50
uint8_t mask
Definition: encoders.h:45
uint8_t select
Definition: encoders.h:48
uint8_t index
Definition: encoders.h:49
uint8_t bidirectional
Definition: encoders.h:47
uint8_t spindle_pos
Definition: encoders.h:51
uint8_t unused
Definition: encoders.h:52
Definition: encoders.h:29
uint8_t direction_changed
Definition: encoders.h:34
uint8_t index_pulse
Definition: encoders.h:38
uint8_t value
Definition: encoders.h:30
uint8_t click
Definition: encoders.h:35
uint8_t long_click
Definition: encoders.h:37
uint8_t position_changed
Definition: encoders.h:33
uint8_t events
Definition: encoders.h:31
uint8_t dbl_click
Definition: encoders.h:36
uint8_t unused
Definition: encoders.h:39