//Registers Operation {{
-//Register read macros with an underscore prefix access DPORT memory directly. In IDF apps, use the non-underscore versions to be SMP-safe.
+// The _DPORT_xxx register read macros access DPORT memory directly (as opposed to
+// DPORT_REG_READ which applies SMP-safe protections).
+//
+// Use DPORT_REG_READ versions to be SMP-safe in IDF apps. If you want to
+// make a sequence of DPORT reads, use DPORT_STALL_OTHER_CPU_START() macro
+// explicitly and then use _DPORT_REG_READ macro while other CPU is stalled.
+//
+// _DPORT_REG_WRITE & DPORT_REG_WRITE are equivalent.
#define _DPORT_REG_READ(_r) (*(volatile uint32_t *)(_r))
#define _DPORT_REG_WRITE(_r, _v) (*(volatile uint32_t *)(_r)) = (_v)
-//write value to register
+// Write value to DPORT register (does not require protecting)
#define DPORT_REG_WRITE(_r, _v) _DPORT_REG_WRITE((_r), (_v))
-//read value from register
+// Read value from register, SMP-safe version.
static inline uint32_t IRAM_ATTR DPORT_REG_READ(uint32_t reg)
{
uint32_t val;
DPORT_STALL_OTHER_CPU_START();
val = _DPORT_REG_READ(reg);
DPORT_STALL_OTHER_CPU_END();
-
+
return val;
}
#define DPORT_FIELD_TO_VALUE2(_f, _v) (((_v)<<_f##_S) & (_f))
//Register read macros with an underscore prefix access DPORT memory directly. In IDF apps, use the non-underscore versions to be SMP-safe.
-#define _DPORT_READ_PERI_REG(addr) (*((volatile uint32_t *)(addr)))
-#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+#define _DPORT_READ_PERI_REG(addr) (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+#define _DPORT_REG_SET_BIT(_r, _b) _DPORT_REG_WRITE((_r), (_DPORT_REG_READ(_r)|(_b)))
+#define _DPORT_REG_CLR_BIT(_r, _b) _DPORT_REG_WRITE((_r), (_DPORT_REG_READ(_r) & (~(_b))))
//read value from register
static inline uint32_t IRAM_ATTR DPORT_READ_PERI_REG(uint32_t addr)