Help! Program works on T3.5 but fails on T4.x (DCC++)

Status
Not open for further replies.
@KurtE
Ran a test with analog read in the interrupt and worked down to 20us. This makes sense since analog read is taking about 17us.

Did get response on github discussion:
I guess that the problem is not in the analogRead but the integer lastCurrent. lastCurrent is several bytes wide so setting it is not an atomic operation. If you get an interrupt in the middle of setting lastCurrent then the value can be aything. As an int is 4 bytes on the Teensy and faster clock I guess that the chance that it is corrupted is much higher.

So pretty much done until the next problem.

Oh - forgot - someone tested to see if native ethernet was working with it and the short answer is yes it does.
 
Cool! - you got it working

Single 32 word is to be atomic - says Paul - is lastCurrent not a single 32 bit DWORD word ... from a single DWORD? Maybe it changes between READ and Assignment?

If you ever have issues with atomic - see CORES::micros(). It reads local copy of two DWORDS from millis() realm - with that 'ANY interrupt' detected then re-read the 'enclosed' code {that has to be read only as write could/will repeat on ANY interrupt}. Total time for micros() is { with Paul ASM edit } about 36 cycles - reading two DWORDS and then doing the add to millisTick of the fractional diff between current CYCCNT and CYCCNT when the miilisTick was last updated - and Paul's added asm and Conditional to make sure at slow clocks don't wrap UP one ms if the millisTick is slow in coming - runs 2-4 clocks FASTER than original.
 
Cool! - you got it working

Single 32 word is to be atomic - says Paul - is lastCurrent not a single 32 bit DWORD word ... from a single DWORD? Maybe it changes between READ and Assignment?

If you ever have issues with atomic - see CORES::micros(). It reads local copy of two DWORDS from millis() realm - with that 'ANY interrupt' detected then re-read the 'enclosed' code {that has to be read only as write could/will repeat on ANY interrupt}. Total time for micros() is { with Paul ASM edit } about 36 cycles - reading two DWORDS and then doing the add to millisTick of the fractional diff between current CYCCNT and CYCCNT when the miilisTick was last updated - and Paul's added asm and Conditional to make sure at slow clocks don't wrap UP one ms if the millisTick is slow in coming - runs 2-4 clocks FASTER than original.

Not quite sure how that is being done but I did see in micros() looks like you have to wrap msec = systick_millis_count; with disabling the interrupt and then re-enabling it.
 
Not quite sure how that is being done but I did see in micros() looks like you have to wrap msec = systick_millis_count; with disabling the interrupt and then re-enabling it.

No interrupt disable! I should try looking at the Teensy3 code ( that does disable ) to replace when over 48 MHZ ( exclude T_LC with no CYCCNT and slow speed issue ? - but ould require CYCNT - and not having user using is and resetting it already for some reason )

Every thing in the {do {} while ();} repeats if ANY interrupt is processed between __LDREXW and the __STREXW. Thus they should only be non-destructive reads - any INC++ or Write would repeat when it cycles.

So when it exits the while() it is known there were no interrupts in getting a copy of those two variables.

...\hardware\teensy\avr\cores\teensy4\delay.c
Code:
uint32_t micros(void)
{
	uint32_t smc, scc;
	[B]do [/B]{
		__LDREXW(&systick_safe_read);
		smc = systick_millis_count;
		scc = systick_cycle_count;
	} [B]while [/B]( __STREXW(1, &systick_safe_read));
	uint32_t cyccnt = ARM_DWT_CYCCNT;
	asm volatile("" : : : "memory");
	uint32_t ccdelta = cyccnt - scc;
	uint32_t frac = ((uint64_t)ccdelta * scale_cpu_cycles_to_microseconds) >> 32;
	if (frac > 1000) frac = 1000;
	uint32_t usec = 1000*smc + frac;
	return usec;
}

The 'systick_safe_read' is just a placeholder variable - doesn't have to be a related - the MCU just repeats the loop on ANY interrupt - not specific to any memory location.
Looking at that asm again - it doesn't process anything - but that and the added conditional resulted in faster exec as noted ???
 
Status
Not open for further replies.
Back
Top