Page 1 of 1

How can I reset internal counter in RMT channels?

Posted: Sat Dec 30, 2017 5:25 am
by ta-mat
Hi, I'm trying to set precise delay between two RMT channels which are set as continuous mode (RMT_CHnCONF1_REG.RMT_TX_CONTI_MODE_CHn = 1).
I supposed that I can reset RMT channels' internal timers/counters by the following code. But I failed to reset them. So far, this code can change delay between 2 channels. But it seems that it changes the timing randomly. Generated signal is still same as before calling this code though.

Code: Select all

const rmt_channel_t channel0 = RMT_CHANNEL_0;
const rmt_channel_t channel1 = RMT_CHANNEL_1;

void resetRmtChannels() {
    auto& confA = RMT.conf_ch[channel0].conf1;
    auto& confB = RMT.conf_ch[channel1].conf1;

    confA.tx_conti_mode = 0;    // Clear continuous mode flag
    confB.tx_conti_mode = 0;

    confA.tx_start      = 0;    // Stop TX
    confB.tx_start      = 0;

    confA.ref_cnt_rst   = 1;    // Reset counter
    confB.ref_cnt_rst   = 1;

    confA.mem_rd_rst    = 1;    // Reset reading address
    confB.mem_rd_rst    = 1;

    confA.tx_conti_mode = 1;    // Set continuous mode flag
    confB.tx_conti_mode = 1;

    confA.tx_start      = 1;    // Start TX
    confB.tx_start      = 1;
}

Re: How can I reset internal counter in RMT channels?

Posted: Fri Jan 05, 2018 5:42 pm
by ta-mat
I think I've found how I can reset internal counter.
It seems when RMT channel reaches the end of TX state, it resets its internal counter automatically. And since I want to reset the channel which uses tx_conti_mode=1, I must set tx_conti_mode=0 firstly.
I can reset and see stable behaviour of RMT channel with the following code.

Code: Select all

rmt_channel_t chan = ...;
const uint32_t mask = BIT(chan * 3 + 0);

portDISABLE_INTERRUPTS();
RMT.conf_ch[chan].conf1.tx_conti_mode   = 0;  // Disable contiguous mode
while((RMT.int_raw.val & mask) != mask) ;     // Wait for end of TX.  TX_END resets internal counter.
portENABLE_INTERRUPTS();
RMT.conf_ch[chan].conf1.ref_cnt_rst     = 1;  // Reset clock divider
RMT.conf_ch[chan].conf1.mem_rd_rst      = 1;  // Reset read-RAM address
RMT.conf_ch[chan].conf1.tx_conti_mode   = 1;  // Enable and start contiguous mode (restart)
BTW, it'd be nice if we have named (non-anonymous) unions/structs for I/Os. I'd like to use pointer for above code. But since there's no named unions/structs for RMT.conf_ch[].conf1, I can't use any pointer for them.