Beablebone boards with DShot - Problems enabling DShot + PWM Outputs - Arducopter v4.3.0 Dev

Hi all,

I developed a DShot implementation for the Beaglebone PRU, and is working fine, and the idea is to have a mix of DShot + PWM outputs like, for instance, oBBBMini with 6 dshot(the first 6 outputs S1-S6) + 6 PWM outputs( S7-S12).
I made the code(PRU and Ardupilot) but I just can have outputs working when I set the output as a Motor.
For instance, If I set the Servo7 function as a motor - motor 1 for instance, the output 7 is enabled and I have a PWM ESC working. But if I set the Servo7 function as MountTilt( and enable the MNT as a Servo mount) the Servo7 output is not enabled by Ardupilot.
To use DShot I changed the MOT_PWM_TYPE to any dshot option (Dshot 300) and the SERVO_DSHOT_ESC to BLHeli32/BL_Heli_S/Kiss.

I read the parameters for the Arducopter v4.3.0 dev and there is a mention for this 2 parameters:
SERVO_BLH_MASK
SERVO_BLH_AUTO
that should be a mask to enable individual channels but I cant find this parameters - I changed this SERVO_DSHOT_ESC to 1, 2 or 0 but there is no SERVO_BLH_X enabled.
Any clue how can I set this channels (7-12) to PWM?

Thanks.

3 Likes

@juvinski Fantastic work!!! If I can assist you, I will try, just ping me.

2 Likes

Hi @mirkix
glad to hear from you :slight_smile:
I’m still trying to figure out how enable outputs as pwm instead of dshot - I reused your pwm code and added to my dshot code to do this mix between dshot and pwm, I migrate from the pasm to the ti pru compiler - was a harder work because the ti’s compiler is very tricky but is working fine right now, the only thing i need to discovery right now is how to mix the outputs with dshot and pwm.

Hi @mirkix

I need an advice.
I have my code finally working with almost all beagles, except the Pocket.
When I run the code on the pocket, the RC(Ecap) is generating randon pulses - for instance, changing the flight mode aleatory, and changing between all the fligth modes configured on the copter.
This behavior just happen in the pocket, all other (black, blue, ai) everything is working fine with at least 10 flights.
Any clue of what can be causing this erratic behavior? ( Erratic Behavior - YouTube )

Best regards.

Hi @juvinski , just to be informed, which Debian and Kernel are you using right now? Can you send me the PRU source code?

Hi @mirkix
I’m using the 5.10-ti kernel.

Sure.

I made a migration from pasm to clpru. I’m still trying to understand how to use macros to do conditional compiling but still have no luck.

.global main

; RC AllInOnePRUDShot

; 1 channel RCInput with 5ns accuracy
; 6 DShot channel outputs with 1 Khz of rate

; Timer
.define 200, TICK_PER_US
.define 200000, TICK_PER_MS

; DShot Freq 150 kHz
.define 1333, DSHOT_PERIOD

.define	(500 - 150),	DSHOT_ZERO_HIGH_PULSE
.define (1000 - 100),	DSHOT_ONE_HIGH_PULSE

.define	((DSHOT_PERIOD - DSHOT_ZERO_HIGH_PULSE) - 150),	DSHOT_ZERO_LOW_PULSE
.define ((DSHOT_PERIOD - DSHOT_ONE_HIGH_PULSE) - 100),	DSHOT_ONE_LOW_PULSE

.define (250 * TICK_PER_US),	DSHOT_END_PULSE

;Period of failsafe called
.define (1000 * TICK_PER_MS), FAILSAFE_NEXT_PERIOD

;Ringbuffer size
.define 300, RCIN_RINGBUFFERSIZE

;Register Temp - CLPRU doesn’t support bit manipulation
REG_TEMP1 .set R8

;PRU Constants Table
.define C3, ECAP
.define C24, RAM
.define C26, IEP

;IEP Constants table
.define 0x0, IEP_TMR_GLB_CFG
;.define 0x4, IEP_TMR_GLB_STS
.define 0xc, IEP_TMR_CNT
;.define 0x0, IEP_CNT_ENABLE
;.define 0x4, IEP_DEFAULT_INC

;ECAP Constants table
.define 0x0, ECAP_TSCTR
.define 0x4, ECAP_CTRPHS
.define 0x8, ECAP_CAP1
.define 0xc, ECAP_CAP2
.define 0x10, ECAP_CAP3
.define 0x14, ECAP_CAP4
.define 0x28, ECAP_ECCTL1
.define 0x2a, ECAP_ECCTL2
.define 0x2c, ECAP_ECEINT
.define 0x2e, ECAP_ECFLG
.define 0x30, ECAP_ECCLR
.define 0x32, ECAP_ECFRC
.define 0x5c, ECAP_REVID

;ECCTL1 Constants
.define 0, ECAP_CAP1POL
.define 1, ECAP_CTRRST1
.define 2, ECAP_CAP2POL
.define 3, ECAP_CTRRST2
.define 4, ECAP_CAP3POL
.define 5, ECAP_CTRRST3
.define 6, ECAP_CAP4POL
.define 7, ECAP_CTRRST4
.define 8, ECAP_CAPLDEN
.define 9, ECAP_PRESCALE
.define 14, ECAP_FREE_SOFT

;ECCTL2 Constants tables
.define 0, ECAP_CONT_ONESHT
.define 1, ECAP_STOP_WRAP
.define 3, ECAP_RE_ARM
.define 4, ECAP_TSCTRSTOP
.define 5, ECAP_SYNCI_EN
.define 6, ECAP_SYNCO_SEL
.define 8, ECAP_SWSYNC
.define 9, ECAP_CAP_APWM
.define 10, ECAP_APWMPOL

;ECEINT, ECFLG
.define 0, ECAP_INT
.define 1, ECAP_CEVT1
.define 2, ECAP_CEVT2
.define 3, ECAP_CEVT3
.define 4, ECAP_CEVT4
.define 5, ECAP_CNTOVF
.define 6, ECAP_PRDEQ
.define 7, ECAP_CMPEQ

;RAM OFFSETS
.define (0 * 4), CH_ENABLE_RAM_OFFSET
.define (1 * 4), CH_1_CURRENT_BIT_POSITION_RAM_OFFSET
.define (2 * 4), CH_1_FRAME_RAM_OFFSET
.define (3 * 4), CH_2_CURRENT_BIT_POSITION_RAM_OFFSET
.define (4 * 4), CH_2_FRAME_RAM_OFFSET
.define (5 * 4), CH_3_CURRENT_BIT_POSITION_RAM_OFFSET
.define (6 * 4), CH_3_FRAME_RAM_OFFSET
.define (7 * 4), CH_4_CURRENT_BIT_POSITION_RAM_OFFSET
.define (8 * 4), CH_4_FRAME_RAM_OFFSET
.define (9 * 4), CH_5_CURRENT_BIT_POSITION_RAM_OFFSET
.define (10 * 4), CH_5_FRAME_RAM_OFFSET
.define (11 * 4), CH_6_CURRENT_BIT_POSITION_RAM_OFFSET
.define (12 * 4), CH_6_FRAME_RAM_OFFSET
.define (13 * 4), CH_7_PULSE_TIME_RAM_OFFSET
.define (14 * 4), CH_7_T_TIME_RAM_OFFSET
.define (15 * 4), CH_8_PULSE_TIME_RAM_OFFSET
.define (16 * 4), CH_8_T_TIME_RAM_OFFSET
.define (17 * 4), CH_9_PULSE_TIME_RAM_OFFSET
.define (18 * 4), CH_9_T_TIME_RAM_OFFSET
.define (19 * 4), CH_10_PULSE_TIME_RAM_OFFSET
.define (20 * 4), CH_10_T_TIME_RAM_OFFSET
.define (21 * 4), CH_11_PULSE_TIME_RAM_OFFSET
.define (22 * 4), CH_11_T_TIME_RAM_OFFSET
.define (23 * 4), CH_12_PULSE_TIME_RAM_OFFSET
.define (24 * 4), CH_12_T_TIME_RAM_OFFSET
.define (25 * 4), FAILSAFE_RAM_OFFSET
.define (26 * 4), TIME_OFFSET
.define (27 * 4), MAX_CYCLE_TIME_OFFSET

.define 0x1000,		RCIN_RING_HEAD_OFFSET
.define 0x1002,		RCIN_RING_TAIL_OFFSET
.define 0x1004,		RCIN_RINGBUFFER_RAM_OFFSET

;POCKET
;#ifdef POCKET
;.if $defined(POCKET)
; .define r30.t7, RC_CH_1_PIN
; .define r30.t4, RC_CH_2_PIN
; .define r30.t1, RC_CH_3_PIN
; .define r30.t5, RC_CH_4_PIN
; .define r30.t2, RC_CH_5_PIN
; .define r30.t6, RC_CH_6_PIN
;
; .define 7, RC_CH_1_BIT
; .define 4, RC_CH_2_BIT
; .define 1, RC_CH_3_BIT
; .define 5, RC_CH_4_BIT
; .define 2, RC_CH_5_BIT
; .define 6, RC_CH_6_BIT
;.endif

;BBBMINI
; .if $defined(BBBMINI)
.define r30.t10, RC_CH_1_PIN
.define r30.t8, RC_CH_2_PIN
.define r30.t11, RC_CH_3_PIN
.define r30.t9, RC_CH_4_PIN
.define r30.t7, RC_CH_5_PIN
.define r30.t6, RC_CH_6_PIN
.define r30.t5, RC_CH_7_PIN
.define r30.t4, RC_CH_8_PIN
.define r30.t3, RC_CH_9_PIN
.define r30.t2, RC_CH_10_PIN
.define r30.t1, RC_CH_11_PIN
.define r30.t0, RC_CH_12_PIN

.define 10,		RC_CH_1_BIT
.define 8,		RC_CH_2_BIT
.define 11,		RC_CH_3_BIT
.define 9,		RC_CH_4_BIT
.define 7,		RC_CH_5_BIT
.define 6,		RC_CH_6_BIT
.define 5,		RC_CH_7_BIT
.define 4,		RC_CH_8_BIT
.define 3,		RC_CH_9_BIT
.define 2,		RC_CH_10_BIT
.define 1,		RC_CH_11_BIT
.define 0,		RC_CH_12_BIT

; .endif

; .if $defined(BBBLUE)
; .define r30.t8, RC_CH_1_PIN
; .define r30.t10, RC_CH_2_PIN
; .define r30.t9, RC_CH_3_PIN
; .define r30.t11, RC_CH_4_PIN
; .define r30.t6, RC_CH_5_PIN
; .define r30.t7, RC_CH_6_PIN
; .define r30.t4, RC_CH_7_PIN
; .define r30.t5, RC_CH_8_PIN
;
; .define 8, RC_CH_1_BIT
; .define 10, RC_CH_2_BIT
; .define 9, RC_CH_3_BIT
; .define 11, RC_CH_4_BIT
; .define 6, RC_CH_5_BIT
; .define 7, RC_CH_6_BIT
; .define 4, RC_CH_7_BIT
; .define 5, RC_CH_8_BIT
; .endif

;#ifdef BBBLUE
;#define RC_CH_1_PIN r30.t8
;#define RC_CH_2_PIN r30.t10
;#define RC_CH_3_PIN r30.t9
;#define RC_CH_4_PIN r30.t11
;#define RC_CH_5_PIN r30.t6
;#define RC_CH_6_PIN r30.t7
;#define RC_CH_7_PIN r30.t4
;#define RC_CH_8_PIN r30.t5
;#endif
;
;#ifdef POCKET
;#define RC_CH_1_PIN r30.t7
;#define RC_CH_2_PIN r30.t4
;#define RC_CH_3_PIN r30.t1
;#define RC_CH_4_PIN r30.t5
;#define RC_CH_5_PIN r30.t2
;#define RC_CH_6_PIN r30.t6
;#endif

;RCOut enable bits
.define 0, RC_CH_1_ENABLE
.define 1, RC_CH_2_ENABLE
.define 2, RC_CH_3_ENABLE
.define 3, RC_CH_4_ENABLE
.define 4, RC_CH_5_ENABLE
.define 5, RC_CH_6_ENABLE
.define 6, RC_CH_7_ENABLE
.define 7, RC_CH_8_ENABLE
.define 8, RC_CH_9_ENABLE
.define 9, RC_CH_10_ENABLE
.define 10, RC_CH_11_ENABLE
.define 11, RC_CH_12_ENABLE

;Register struct
RegisterStruct .struct
ch_enable .uint
ch_1_next_time .uint
ch_2_next_time .uint
ch_3_next_time .uint
;ch_0_next_time .uint
ch_4_next_time .uint
ch_5_next_time .uint
ch_6_next_time .uint
ch_7_next_time .uint
ch_8_next_time .uint
ch_9_next_time .uint
ch_10_next_time .uint
ch_11_next_time .uint
ch_12_next_time .uint
next_failsafe .uint
time .uint
time_max .uint
time_cycle .uint
rcin_ram_pointer .uint
rcin_ram_pointer_index .uint
rcin_ram_pointer_index_max .uint
rcin_ram_pointer_head .uint
rcin_ram_pointer_tail .uint
temp .uint
temp1 .uint
test .uint
RegisterStructlen .endstruct

register .sassign R3, RegisterStruct

;RegisterChannel .struct
;ch_4_next_time .uint
;ch_5_next_time .uint
;ch_6_next_time .uint
;ch_7_next_time .uint
;ch_8_next_time .uint
;ch_9_next_time .uint
;ch_10_next_time .uint
;ch_11_next_time .uint
;ch_12_next_time .uint
;next_failsafe .uint
;RegisterChannellen .endstruct

;channelregister .sassign R10, RegisterChannel

RCOUT_PWM .macro RC_CH_X_PIN, CH_X_NEXT_TIME, CH_X_ENABLE, CH_X_PULSE_TIME_RAM_OFFSET, CH_X_T_TIME_RAM_OFFSET, RC_CH_X_BIT
;pwm:
;Check if channel is enabled
qbbc pwmend?, register.ch_enable, CH_X_ENABLE
lbco &register.time, IEP, IEP_TMR_CNT, 4
;Handle arithmetic and counter overflow, check if there is something to do
sub register.temp, CH_X_NEXT_TIME, register.time
ldi32 register.temp1, 0xF0000000
qbgt pwmend?, register.temp, register.temp1

		;mov CH_X_NEXT_TIME, register.time

		;Set pin or clear pin?
		qbbs pwmclear?, R30, RC_CH_X_BIT
		;Load pulse duration
		lbco &register.temp, RAM, CH_X_PULSE_TIME_RAM_OFFSET, 4

		;Calculate time to next event
		add CH_X_NEXT_TIME, CH_X_NEXT_TIME, register.temp

		;Do not set pin if pulse time is 0
		qbeq pwmend?, register.temp, 0

		;Set pin
		set RC_CH_X_PIN
		jmp pwmend?

pwmclear?:
;Load pulse time
lbco &register.temp1, RAM, CH_X_PULSE_TIME_RAM_OFFSET, 4

     ;Load T time
     lbco &register.temp, RAM, CH_X_T_TIME_RAM_OFFSET, 4

     ;Calculate time to next event (T - pulse duration)
     sub register.temp, register.temp, register.temp1
     add CH_X_NEXT_TIME, CH_X_NEXT_TIME, register.temp

     ;Clear pin
     clr RC_CH_X_PIN

pwmend?:
.endm

RCOUT_DSHOT .macro RC_CH_X_PIN, CH_X_NEXT_TIME, CH_X_ENABLE, CH_X_CURRENT_BIT_POSITION_RAM_OFFSET, CH_X_FRAME_RAM_OFFSET, RC_CH_X_BIT

qbbc dshotend?, register.ch_enable, CH_X_ENABLE
	lbco &register.time, IEP, IEP_TMR_CNT, 4

	;Handle arithmetic and counter overflow, check if there is something to do
	sub register.temp, CH_X_NEXT_TIME, register.time
	ldi32 register.temp1, 0xF0000000
	qbgt dshotend?, register.temp, register.temp1

      ;ldi32 register.temp1, DSHOT_END_PULSE
      ;add CH_X_NEXT_TIME, register.time, register.temp1

      ;Offset larger than FRAME? No new FRAME.
      ldi32 register.temp1, 0x0000000F

      lbco &register.temp, RAM, CH_X_CURRENT_BIT_POSITION_RAM_OFFSET, 4

      ;End and wait until new frame.
      qbgt dshotendforceupdate?, register.temp1, register.temp

      lbco &register.temp1, RAM, CH_X_FRAME_RAM_OFFSET, 4

      ;Set pin or clear pin?
      qbbs dshotclear?, R30, RC_CH_X_BIT
		;Set pin
		set RC_CH_X_PIN

		qbbs dshothigh?, register.temp1, register.temp
			ldi32 register.temp, DSHOT_ZERO_HIGH_PULSE
            add CH_X_NEXT_TIME, register.time, register.temp

		jmp dshotend?

dshothigh?:
ldi32 register.temp, DSHOT_ONE_HIGH_PULSE
add CH_X_NEXT_TIME, register.time, register.temp
jmp dshotend?

dshotclear?:
;Clear pin
clr RC_CH_X_PIN
qbbs dshotoffhigh?, register.temp1, register.temp
ldi32 register.temp1, DSHOT_ZERO_LOW_PULSE
add CH_X_NEXT_TIME, register.time, register.temp1
add register.temp, register.temp, 1
sbco &register.temp, RAM, CH_X_CURRENT_BIT_POSITION_RAM_OFFSET, 4
jmp dshotend?
dshotoffhigh?:
ldi32 register.temp1, DSHOT_ONE_LOW_PULSE
add CH_X_NEXT_TIME, register.time, register.temp1
add register.temp, register.temp, 1
sbco &register.temp, RAM, CH_X_CURRENT_BIT_POSITION_RAM_OFFSET, 4
jmp dshotend?
dshotendforceupdate?:
;We force an update the next polling cycle.
ldi32 register.temp, 0
sbco &register.temp, RAM, CH_X_CURRENT_BIT_POSITION_RAM_OFFSET, 4
ldi32 register.temp1, DSHOT_END_PULSE
add CH_X_NEXT_TIME, register.time, register.temp1
dshotend?:
.endm

RCIN_ECAP_INIT .macro
;Initialize ECAP
ldi32 register.temp, (1 << ECAP_CTRRST1) | (1 << ECAP_CAP1POL) | (1 << ECAP_CTRRST2) | (1 << ECAP_CAPLDEN)
sbco &register.temp, ECAP, ECAP_ECCTL1, 4
ldi32 register.temp, (1 << ECAP_STOP_WRAP) | (1 << ECAP_TSCTRSTOP) | (2 << ECAP_SYNCO_SEL)
sbco &register.temp, ECAP, ECAP_ECCTL2, 4
.endm

RCIN_ECAP .macro
;New value?
lbco &REG_TEMP1, ECAP, ECAP_ECFLG, 4
qbbc rcin_ecap_end, REG_TEMP1, 2

	;Copy S0 and S1 duration to temp and temp1
	lbco &register.temp, ECAP, ECAP_CAP1, 8

	;Copy S0 and S1 duration to RAM
	sbbo &register.temp, register.rcin_ram_pointer, 0, 8

	;Clear event flags
	ldi32 register.temp, (1 << ECAP_CEVT1) | (1 << ECAP_CEVT2)
	sbco &register.temp, ECAP, ECAP_ECCLR, 4

	;Set new tail value
	RCIN_WRITE_TAIL register.rcin_ram_pointer_index

	;Update pointer
	add register.rcin_ram_pointer_index, register.rcin_ram_pointer_index, 1
	add register.rcin_ram_pointer, register.rcin_ram_pointer, 8

	;Check end of ringbuffer
  	qblt rcin_ecap_end, register.rcin_ram_pointer_index_max, register.rcin_ram_pointer_index
		ldi register.rcin_ram_pointer, RCIN_RINGBUFFER_RAM_OFFSET
		ldi register.rcin_ram_pointer_index, 0

rcin_ecap_end:
.endm

RCIN_WRITE_HEAD .macro RCIN_HEAD
sbbo &RCIN_HEAD, register.rcin_ram_pointer_head, 0, 2
.endm

RCIN_WRITE_TAIL .macro RCIN_TAIL
sbbo &RCIN_TAIL, register.rcin_ram_pointer_tail, 0, 2
.endm

MAX_CYCLE_TIME .macro
lbco &register.temp1, IEP, IEP_TMR_CNT, 4
sub register.temp, register.temp1, register.time_cycle
mov register.time_cycle, register.temp1
max register.time_max, register.time_max, register.temp
sbco &register.time_max, RAM, MAX_CYCLE_TIME_OFFSET, 4
.endm

INIT .macro
;Reset PWM pins
ldi32 r30, 0x0

;Clear register
zero &register, $sizeof(register)
;zero &channelregister, $sizeof(channelregister)
;Initialize max cycle time
ldi32 register.temp, 0
sbco &register.temp, RAM, MAX_CYCLE_TIME_OFFSET, 4

;Initialize ringbuffer
ldi32 register.rcin_ram_pointer, RCIN_RINGBUFFER_RAM_OFFSET
ldi32 register.rcin_ram_pointer_index_max, RCIN_RINGBUFFERSIZE
ldi32 register.rcin_ram_pointer_head, RCIN_RING_HEAD_OFFSET
ldi32 register.rcin_ram_pointer_tail, RCIN_RING_TAIL_OFFSET
ldi32 register.temp, 0
RCIN_WRITE_HEAD register.temp
RCIN_WRITE_TAIL register.temp

;Load balancing
ldi32 register.ch_1_next_time, 1000
ldi32 register.ch_2_next_time, 2000
ldi32 register.ch_3_next_time, 3000
ldi32 register.ch_4_next_time, 4000
;ldi32 register.ch_0_next_time, 4000
ldi32 register.ch_5_next_time, 5000
ldi32 register.ch_6_next_time, 6000
ldi32 register.ch_7_next_time, 7000
ldi32 register.ch_8_next_time, 8000
ldi32 register.ch_9_next_time, 9000
ldi32 register.ch_10_next_time, 10000
ldi32 register.ch_11_next_time, 11000
ldi32 register.ch_12_next_time, 12000


;Disable all channels
ldi32 register.ch_enable, 0x0
sbco &register.ch_enable, RAM, CH_ENABLE_RAM_OFFSET, 4

;Initialize empty frames.
ldi32 register.temp, 0
sbco &register.temp, RAM, CH_1_FRAME_RAM_OFFSET, 4
sbco &register.temp, RAM, CH_2_FRAME_RAM_OFFSET, 4
sbco &register.temp, RAM, CH_3_FRAME_RAM_OFFSET, 4
sbco &register.temp, RAM, CH_4_FRAME_RAM_OFFSET, 4
sbco &register.temp, RAM, CH_5_FRAME_RAM_OFFSET, 4
sbco &register.temp, RAM, CH_6_FRAME_RAM_OFFSET, 4

sbco &register.temp, RAM, CH_7_PULSE_TIME_RAM_OFFSET, 4
sbco &register.temp, RAM, CH_8_PULSE_TIME_RAM_OFFSET, 4
sbco &register.temp, RAM, CH_9_PULSE_TIME_RAM_OFFSET, 4
sbco &register.temp, RAM, CH_10_PULSE_TIME_RAM_OFFSET, 4
sbco &register.temp, RAM, CH_11_PULSE_TIME_RAM_OFFSET, 4
sbco &register.temp, RAM, CH_12_PULSE_TIME_RAM_OFFSET, 4

;sbco &register.temp, RAM, CH_7_T_TIME_RAM_OFFSET, 4
;sbco &register.temp, RAM, CH_8_T_TIME_RAM_OFFSET, 4
;sbco &register.temp, RAM, CH_9_T_TIME_RAM_OFFSET, 4
;sbco &register.temp, RAM, CH_10_T_TIME_RAM_OFFSET, 4
;sbco &register.temp, RAM, CH_11_T_TIME_RAM_OFFSET, 4
;sbco &register.temp, RAM, CH_12_T_TIME_RAM_OFFSET, 4

;Initialize frame offsets (to empty frames)
ldi32 register.temp, 0x10
sbco &register.temp, RAM, CH_1_CURRENT_BIT_POSITION_RAM_OFFSET, 4
sbco &register.temp, RAM, CH_2_CURRENT_BIT_POSITION_RAM_OFFSET, 4
sbco &register.temp, RAM, CH_3_CURRENT_BIT_POSITION_RAM_OFFSET, 4
sbco &register.temp, RAM, CH_4_CURRENT_BIT_POSITION_RAM_OFFSET, 4
sbco &register.temp, RAM, CH_5_CURRENT_BIT_POSITION_RAM_OFFSET, 4
sbco &register.temp, RAM, CH_6_CURRENT_BIT_POSITION_RAM_OFFSET, 4

sbco &register.temp, RAM, CH_7_T_TIME_RAM_OFFSET, 4
sbco &register.temp, RAM, CH_8_T_TIME_RAM_OFFSET, 4
sbco &register.temp, RAM, CH_9_T_TIME_RAM_OFFSET, 4
sbco &register.temp, RAM, CH_10_T_TIME_RAM_OFFSET, 4
sbco &register.temp, RAM, CH_11_T_TIME_RAM_OFFSET, 4
sbco &register.temp, RAM, CH_12_T_TIME_RAM_OFFSET, 4



;Stop counter - This is important as the IEP timer appears
;to sometimes go into an undefined state if we change other
;parts of the control register while it's counting. Needing
;a hard reset to resume functioning.
;;lbco &register.temp, IEP, IEP_TMR_GLB_CFG, 4
;;ldi32 register.temp1, 0xFFFFFFFE
;;and register.temp, register.temp, register.temp1
;;sbco &register.temp, IEP, IEP_TMR_GLB_CFG, 4
lbco &register.temp, IEP, IEP_TMR_GLB_CFG, 4
ldi32 register.temp1, 0xFFFFFFFE
sbco &register.temp1, IEP, IEP_TMR_GLB_CFG, 4


;Configures the IEP counter and enables it
;-> 4.5.4.1 IEP_TMR_GLB_CFG Register in TRM
;-> Reference: https://github.com/beagleboard/am335x_pru_package/blob/master/pru_sw/example_apps/PRU_industrialEthernetTimer/PRU_industrialEthernetTimer.p
; CMP_INC     = 1
;DEFAULT_INC = 1
;CNT_ENABLE  = 1
;;ldi register.temp, 0x0110
;;sbco &register.temp, IEP, IEP_TMR_GLB_CFG, 4
ldi32 register.temp, 0xffffffff
sbco &register.temp, IEP, IEP_TMR_CNT, 4


;********************
;Resets the counter of IEP timer
;Reset Count Register (CNT) by writing 0xFFFFFFFF to clear
;-> 4.4.3.2.2 Basic Programming Model in TRM
;-> 4.5.4.4 IEP_TMR_CNT Register in TRM
;;ldi32 register.temp, 0xffffffff
;;sbco &register.temp, IEP, IEP_TMR_CNT, 4

;Start counter
;;lbco &register.temp, IEP, IEP_TMR_GLB_CFG, 4
;;or register.temp, register.temp, 1 << IEP_CNT_ENABLE
;;sbco &register.temp, IEP, IEP_TMR_GLB_CFG, 4

ldi32 register.temp, 0x0111
sbco &register.temp, IEP, IEP_TMR_GLB_CFG, 2

.endm

;Without this motors would keep spinning if ardupilot disappeared.
FAILSAFE_HANDLING .macro
sub register.temp, register.next_failsafe, register.time
ldi32 register.temp1, 0xF0000000
qbgt failsafeend, register.temp, register.temp1
ldi32 register.temp, FAILSAFE_NEXT_PERIOD
add register.next_failsafe, register.time, register.temp
lbco &REG_TEMP1, RAM, FAILSAFE_RAM_OFFSET, 4
qbbs failsafe_succesful, REG_TEMP1, 0
sbco &register.temp, RAM, CH_ENABLE_RAM_OFFSET, 4
failsafe_succesful:
ldi32 register.temp, 0
sbco &register.temp, RAM, FAILSAFE_RAM_OFFSET, 4
failsafeend:
.endm

main
INIT
RCIN_ECAP_INIT
mainloop:
lbco &register.ch_enable, RAM, CH_ENABLE_RAM_OFFSET, 4
lbco &register.time, IEP, IEP_TMR_CNT, 4
sbco &register.time, RAM, TIME_OFFSET, 4

RCOUT_DSHOT RC_CH_1_PIN, register.ch_1_next_time,  RC_CH_1_ENABLE,  CH_1_CURRENT_BIT_POSITION_RAM_OFFSET, CH_1_FRAME_RAM_OFFSET,   RC_CH_1_BIT
RCOUT_DSHOT RC_CH_2_PIN, register.ch_2_next_time,  RC_CH_2_ENABLE,  CH_2_CURRENT_BIT_POSITION_RAM_OFFSET, CH_2_FRAME_RAM_OFFSET,   RC_CH_2_BIT
RCOUT_DSHOT RC_CH_3_PIN, register.ch_3_next_time,  RC_CH_3_ENABLE,  CH_3_CURRENT_BIT_POSITION_RAM_OFFSET, CH_3_FRAME_RAM_OFFSET,   RC_CH_3_BIT
RCOUT_DSHOT RC_CH_4_PIN, register.ch_4_next_time,  RC_CH_4_ENABLE,  CH_4_CURRENT_BIT_POSITION_RAM_OFFSET, CH_4_FRAME_RAM_OFFSET,   RC_CH_4_BIT
RCOUT_DSHOT RC_CH_5_PIN, register.ch_5_next_time,  RC_CH_5_ENABLE,  CH_5_CURRENT_BIT_POSITION_RAM_OFFSET, CH_5_FRAME_RAM_OFFSET,   RC_CH_5_BIT
RCOUT_DSHOT RC_CH_6_PIN, register.ch_6_next_time,  RC_CH_6_ENABLE,  CH_6_CURRENT_BIT_POSITION_RAM_OFFSET, CH_6_FRAME_RAM_OFFSET,   RC_CH_6_BIT

FAILSAFE_HANDLING

;.if $defined(BBBMINI)
;RCOUT_DSHOT RC_CH_7_PIN, register.ch_7_next_time,  RC_CH_7_ENABLE,  CH_7_CURRENT_BIT_POSITION_RAM_OFFSET, CH_7_FRAME_RAM_OFFSET,   RC_CH_7_BIT
;RCOUT_DSHOT RC_CH_8_PIN, register.ch_8_next_time,  RC_CH_8_ENABLE,  CH_8_CURRENT_BIT_POSITION_RAM_OFFSET, CH_8_FRAME_RAM_OFFSET,   RC_CH_8_BIT
;RCOUT_DSHOT RC_CH_9_PIN, register.ch_9_next_time,  RC_CH_9_ENABLE,  CH_9_CURRENT_BIT_POSITION_RAM_OFFSET, CH_9_FRAME_RAM_OFFSET,   RC_CH_9_BIT
;RCOUT_DSHOT RC_CH_10_PIN, register.ch_10_next_time,  RC_CH_10_ENABLE,  CH_10_CURRENT_BIT_POSITION_RAM_OFFSET, CH_10_FRAME_RAM_OFFSET,   RC_CH_10_BIT
;RCOUT_DSHOT RC_CH_11_PIN, register.ch_11_next_time,  RC_CH_11_ENABLE,  CH_11_CURRENT_BIT_POSITION_RAM_OFFSET, CH_11_FRAME_RAM_OFFSET,   RC_CH_11_BIT
;RCOUT_DSHOT RC_CH_12_PIN, register.ch_12_next_time,  RC_CH_12_ENABLE,  CH_12_CURRENT_BIT_POSITION_RAM_OFFSET, CH_12_FRAME_RAM_OFFSET,   RC_CH_12_BIT
;.endif

;.if $defined(BBBLUE)
;RCOUT_DSHOT RC_CH_7_PIN, register.ch_7_next_time,  RC_CH_7_ENABLE,  CH_7_CURRENT_BIT_POSITION_RAM_OFFSET, CH_7_FRAME_RAM_OFFSET,   RC_CH_7_BIT
;RCOUT_DSHOT RC_CH_8_PIN, register.ch_8_next_time,  RC_CH_8_ENABLE,  CH_8_CURRENT_BIT_POSITION_RAM_OFFSET, CH_8_FRAME_RAM_OFFSET,   RC_CH_8_BIT
;.endif
;RCOUT_PWM RC_CH_7_PIN,   register.ch_7_next_time,  RC_CH_7_ENABLE,  CH_7_PULSE_TIME_RAM_OFFSET,           CH_7_T_TIME_RAM_OFFSET,  RC_CH_7_BIT
;RCOUT_PWM RC_CH_8_PIN,   register.ch_8_next_time,  RC_CH_8_ENABLE,  CH_8_PULSE_TIME_RAM_OFFSET, 		  CH_8_T_TIME_RAM_OFFSET,  RC_CH_8_BIT
;RCOUT_PWM RC_CH_9_PIN,   register.ch_9_next_time,  RC_CH_9_ENABLE,  CH_9_PULSE_TIME_RAM_OFFSET, 		  CH_9_T_TIME_RAM_OFFSET,  RC_CH_9_BIT
;RCOUT_PWM RC_CH_10_PIN,  register.ch_10_next_time, RC_CH_10_ENABLE, CH_10_PULSE_TIME_RAM_OFFSET, 		  CH_10_T_TIME_RAM_OFFSET, RC_CH_10_BIT
;RCOUT_PWM RC_CH_11_PIN,  register.ch_11_next_time, RC_CH_11_ENABLE, CH_11_PULSE_TIME_RAM_OFFSET, 		  CH_11_T_TIME_RAM_OFFSET, RC_CH_11_BIT
;RCOUT_PWM RC_CH_12_PIN,  register.ch_12_next_time, RC_CH_12_ENABLE, CH_12_PULSE_TIME_RAM_OFFSET, 		  CH_12_T_TIME_RAM_OFFSET, RC_CH_12_BIT

RCIN_ECAP
;MAX_CYCLE_TIME
jmp mainloop

Hi @mirkix
I made a test.
I downgraded the kernel to 4.19-ti and the problem has gone - the DShot code is working fine.
I noted one difference, meanwhile in the 4.19 the pin is configured as ecap, in kernel 5.10 is configured as ecap_pwm, I don’t know if this is the difference, because in my undertanding the PRU is a peripherical hardware and there is interference in the kernel itself.