RMT idle threshold accuracy

trawgz
Posts: 7
Joined: Thu Feb 11, 2021 12:21 pm

RMT idle threshold accuracy

Postby trawgz » Fri Mar 12, 2021 10:26 am

Hi,

I want to use the RMT peripheral to detect that nothing change on a bus. I configured RMT so, that it should trigger an interrupt, if the input pin doesnt change for 1,75 ms. Im using that peripheral in combination with UART receive timeout. The RMT receiver is always enabled and I'm enabling the RXEND interrupt first on the UART receive timeout interrupt (triggers after 0,75 ms). There I'm also clearing the RMT buffer to prevent overflow.

The most time it is working fine, and the interrupt of RMT is triggered correctly. But like 1 out of 20-50 times it will trigger the interrupt too late. Partially it takes more than 5ms to trigger the interrupt. Im measured that pin with an oscilloscope and have not detected any peak in between.

Any known hardware issues? Or I'm missing something?

Only relevant code below:

Code: Select all

void init_rmt()
{
		int rmt_channel = 0;

		DPORT_REG_SET_BIT(DPORT_PERIP_CLK_EN_REG, DPORT_RMT_CLK_EN);
		DPORT_REG_CLR_BIT(DPORT_PERIP_RST_EN_REG, DPORT_RMT_RST);

		RMT.apb_conf.fifo_mask = 1;
		RMT.conf_ch[rmt_channel].conf1.ref_cnt_rst = 1;
		RMT.conf_ch[rmt_channel].conf1.ref_cnt_rst = 0;
		RMT.conf_ch[rmt_channel].conf1.ref_always_on = 1;
		RMT.conf_ch[rmt_channel].conf1.rx_filter_en = 0;
		RMT.conf_ch[rmt_channel].conf1.rx_filter_thres = 0;

		RMT.conf_ch[rmt_channel].conf0.carrier_en = 0;
		RMT.conf_ch[rmt_channel].conf0.carrier_out_lv = 0;
		RMT.conf_ch[rmt_channel].conf0.clk_en = 0;
		RMT.conf_ch[rmt_channel].conf0.div_cnt = 4
		RMT.conf_ch[rmt_channel].conf0.idle_thres = 35000; // 1,75ms
		RMT.conf_ch[rmt_channel].conf0.mem_pd = 0;
		RMT.conf_ch[rmt_channel].conf0.mem_size = 1;

		RMT.conf_ch[rmt_channel].conf1.apb_mem_rst = 1;
		RMT.conf_ch[rmt_channel].conf1.apb_mem_rst = 0;
		RMT.conf_ch[rmt_channel].conf1.idle_out_en = 0;
		RMT.conf_ch[rmt_channel].conf1.idle_out_lv = 0;
		RMT.conf_ch[rmt_channel].conf1.mem_rd_rst = 1;
		RMT.conf_ch[rmt_channel].conf1.mem_rd_rst = 0;
		RMT.conf_ch[rmt_channel].conf1.mem_wr_rst = 1;
		RMT.conf_ch[rmt_channel].conf1.mem_wr_rst = 0;
		RMT.conf_ch[rmt_channel].conf1.tx_conti_mode = 0;
		RMT.conf_ch[rmt_channel].conf1.tx_start = 0;
		RMT.conf_ch[rmt_channel].conf1.mem_owner = 1;
		RMT.conf_ch[rmt_channel].conf1.rx_en = 1;
}

void uart_receive_isr(void *arg)
{
		int rmt_channel = 0;
		
		RMT.conf_ch[rmt_channel].conf1.mem_wr_rst = 1;					// Reset receiver address
		RMT.conf_ch[rmt_channel].conf1.mem_wr_rst = 0;
		RMT.conf_ch[rmt_channel].conf1.mem_owner = 1;
		RMT.int_clr.val = (1 << (RMT_CH0_RX_END_INT_ENA_S + (rmt_channel * 3)));		// Clear interrupt
		RMT.int_ena.val |= (1 << (RMT_CH0_RX_END_INT_ENA_S + (rmt_channel * 3)));	// Enable interrupt for rx end (bus rest)
}

void rmt_isr()
{
		// Triggered sometimes too late
		int rmt_channel = 0;
	
		RMT.int_ena.val &= ~(1 << (RMT_CH0_RX_END_INT_ENA_S + (rmt_channel * 3)));
		RMT.int_clr.val = (1 << (RMT_CH0_RX_END_INT_ENA_S + (rmt_channel * 3)));
		/// ...
}

Who is online

Users browsing this forum: No registered users and 218 guests