Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to use SysTick timer to count ticks from a rotary encoder? #153

Open
samehmohamed88 opened this issue Mar 4, 2022 · 3 comments
Open
Labels
question Further information is requested

Comments

@samehmohamed88
Copy link

I have seen a couple of examples that use the SysTick timer to count the rotations on a rotary encoder, like this example for the blue pill .

I was able to port that example to ESP32 (based on ESP32-Arduino code) as:

 static void IRAM_ATTR pcnt_example_intr_handler(void *arg) {
	uint32_t intr_status = PCNT.int_st.val;
	int i = 0;

	for (i = 0; i < PCNT_UNIT_MAX; i++) {
		if (intr_status & (BIT(i))) {
			/* Save the PCNT event type that caused an interrupt
			 to pass it to the main program */

			int64_t status=0;
			if(PCNT.status_unit[i].COUNTER_H_LIM){
				status = r_enc_config.counter_h_lim;
			}
			if(PCNT.status_unit[i].COUNTER_L_LIM){
				status = r_enc_config.counter_l_lim;
			}
			//pcnt_counter_clear(ptr->unit);
			PCNT.int_clr.val = BIT(i); // clear the interrupt
			count = status + count;
		}
	}
}

I saw there's a systick timer in this repo and a flash example based on it, but I can't reason around how I would use it for the rotary encoder.

Any help with this would be highly appreciated!

@newAM
Copy link
Member

newAM commented Mar 5, 2022

I gave it a quick skim, it looks like the SysTick is simply used to calculate the speed of the encoder: stm32f1xx_it.c#L197

The actual position comes from a different mechanism, HAL_TIM_IC_CaptureCallback (if I am reading that right, I did skim this fairly quickly 😅 )

Assuming you have that position the SysTick handler could be written in rust along the lines of:

// probably missing some use statements, I didn't actually compile this.
use cortex_m_rt::{entry, exception};

static OLDPOS: i16 = 0;
static INDX: i32 = 0;

#[exception]
fn SysTick() {

    unsafe {
        INDX += 1;
        if (INDX == 500) {
            SPEED = ((POSITION - OLDPOS) * 2);
            OLDPOS = POSITION;
            INDX = 0;
        }
    }

    // whatever else here
}

#[entry]
fn main() -> ! {
    let p = cortex_m::Peripherals::take().unwrap();
    let mut syst = p.SYST;

    // configures the system timer to trigger a SysTick exception every second
    syst.set_clock_source(SystClkSource::Core);
    // CPU clock of 8 MHz
    syst.set_reload(8_000_000);
    syst.clear_current();
    syst.enable_counter();
    syst.enable_interrupt();

    loop {
        compiler_fence(SeqCst);
    }
}

Actually getting the position is a bit more effort that I don't know about off the top of my head.

That C example you linked isn't too big, you could probably recreate that using the PAC to get started.

@newAM newAM added the question Further information is requested label Mar 5, 2022
@samehmohamed88
Copy link
Author

@newAM Thanks very much for this!

I saw in the examples that the #[exception] macro was used, but based on the comments it seems like it 's only called when an error occurs in the interrupt. But based on your example, it's the interrupt routine itself?

@newAM
Copy link
Member

newAM commented Mar 5, 2022

exception has a special meaning for Cortex-M CPUs. Some exceptions are used for error status', but more generally they are just built-in interrupts.

This is the exception number definition for ARMv6-M: https://developer.arm.com/documentation/ddi0419/c/System-Level-Architecture/System-Level-Programmers--Model/ARMv6-M-exception-model/Exception-number-definition?lang=en

2 is HardFault, that occurs only when there's an error condition, but 15 is SysTick, and that occurs as part of normal operation. All the interrupts added by ST then get allocation to number 16+

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants