PCNT :: How to modify peripheral registers?
Posted: Thu Oct 05, 2023 10:56 pm
Dear Espressif,
I'm trying to set up a PCNT peripheral with a pure registry approach (non-IDF) and getting the following mind-blowing mishappening:
And here is the printf() output:
Once again: I can write new values, verify with printf() and after a while they are gone!
It's the only code in main(); no other tasks/functionality yet! My platorm: ESP-WROOM-32 / IDF-5.0.1
Q1: Now how am I supposed to write data to PCNT config and control registers?
PS. No matter what address base is used (0x3FF57000 or 0x60017000) it still fails...
Q2: Additionally, I don't quite understand the purpose and usage of PCNT_CLK_EN bit in the PCNT_CTRL_REG:
Can you clarify this?
"PCNT_CLK_EN Configures register clock gating.
0: Support clock only when the application writes registers. (what does it mean?)
1: Always force the clock on for registers. (what registers?)
(R/W)"
I'm trying to set up a PCNT peripheral with a pure registry approach (non-IDF) and getting the following mind-blowing mishappening:
Code: Select all
// (1) make a snapshot of any (for example, CONF0) register prior to modification:
printf("(%08lX) = %08lX\n", (uint32_t)&PCNT.conf_unit[0].conf0, *((uint32_t*)&PCNT.conf_unit[0].conf0));
// (2) configure unit_0 as per my requirements
PCNT.conf_unit[0].conf0.filter_thres = 0; // This register is used to filter pulse whose width is smaller than this value for unit0.
PCNT.conf_unit[0].conf0.filter_en = 0; // This is the enable bit for filtering input signals for unit0.
PCNT.conf_unit[0].conf0.thr_zero_en = 0; // This is the enable bit for comparing unit0's count with 0 value.
PCNT.conf_unit[0].conf0.thr_h_lim_en = 1; // This is the enable bit for comparing unit0's count with thr_h_lim value.
PCNT.conf_unit[0].conf0.thr_l_lim_en = 0; // This is the enable bit for comparing unit0's count with thr_l_lim value.
PCNT.conf_unit[0].conf0.thr_thres0_en = 0; // This is the enable bit for comparing unit0's count with thres0 value.
PCNT.conf_unit[0].conf0.thr_thres1_en = 0; // This is the enable bit for comparing unit0's count with thres1 value .
PCNT.conf_unit[0].conf0.ch0_neg_mode = 0; // This register is used to control the mode of channel0's input neg-edge signal for unit0. 2'd1: increase at the negedge of input signal 2'd2:decrease at the negedge of input signal others:forbidden
PCNT.conf_unit[0].conf0.ch0_pos_mode = 1; // This register is used to control the mode of channel0's input pos-edge signal for unit0. 2'd1: increase at the posedge of input signal 2'd2:decrease at the posedge of input signal others:forbidd
PCNT.conf_unit[0].conf0.ch0_hctrl_mode = 0; // This register is used to control the mode of channel0's high control signal for unit0. 2'd0:increase when control signal is low 2'd1 decrease when control signal is high others:forbidden
PCNT.conf_unit[0].conf0.ch0_lctrl_mode = 0; // This register is used to control the mode of channel0's low control signal for unit0. 2'd0:increase when control signal is low 2'd1 decrease when control signal is high others:forbidd
PCNT.conf_unit[0].conf0.ch1_neg_mode = 0; // This register is used to control the mode of channel1's input neg-edge signal for unit0. 2'd1пјљincrease at the negedge of input signal 2'd2:decrease at the negedge of input signal others:forbidden
PCNT.conf_unit[0].conf0.ch1_pos_mode = 1; // This register is used to control the mode of channel1's input pos-edge signal for unit0. 2'd1пјљincrease at the posedge of input signal 2'd2:decrease at the posedge of input signal others:forbidden
PCNT.conf_unit[0].conf0.ch1_hctrl_mode = 0; // This register is used to control the mode of channel1's high control signal for unit0. 2'd0:increase when control signal is low 2'd1пјљdecrease when control signal is high others:forbidden
PCNT.conf_unit[0].conf0.ch1_lctrl_mode = 0; // This register is used to control the mode of channel1's low control signal for unit0. 2'd0:increase when control signal is low 2'd1пјљdecrease when control signal is high others:forbidden
// (3) take another snapshot
printf("(%08lX) = %08lX\n", (uint32_t)&PCNT.conf_unit[0].conf0, *((uint32_t*)&PCNT.conf_unit[0].conf0));
// (4) now getthe whole thing stuck in an infinite loop:
while (PCNT.conf_unit[0].conf0.val == 0x04041000){}; // 0x04041000 here is the hex value of the just configured CONF0 register; see the printf() output below
// (5) Hell no, says esp32, there's gonna be no loop because CONF0 register has been reset to its initial value:
printf("(%08lX) = %08lX\n", (uint32_t)&PCNT.conf_unit[0].conf0, *((uint32_t*)&PCNT.conf_unit[0].conf0));
Code: Select all
(3FF57000) = 00003C10
(3FF57000) = 04041000
(3FF57000) = 00003C10
It's the only code in main(); no other tasks/functionality yet! My platorm: ESP-WROOM-32 / IDF-5.0.1
Q1: Now how am I supposed to write data to PCNT config and control registers?
PS. No matter what address base is used (0x3FF57000 or 0x60017000) it still fails...
Q2: Additionally, I don't quite understand the purpose and usage of PCNT_CLK_EN bit in the PCNT_CTRL_REG:
Can you clarify this?
"PCNT_CLK_EN Configures register clock gating.
0: Support clock only when the application writes registers. (what does it mean?)
1: Always force the clock on for registers. (what registers?)
(R/W)"