diff --git a/configure.ac b/configure.ac
index 81c3c3b..f09cec0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -19,6 +19,7 @@ AC_CONFIG_SUBDIRS([examples/0blink])
AC_CONFIG_SUBDIRS([examples/0hello])
AC_CONFIG_SUBDIRS([examples/0ledctrl])
AC_CONFIG_SUBDIRS([examples/1rmtblink])
+AC_CONFIG_SUBDIRS([examples/1rmtdht])
AC_CONFIG_SUBDIRS([examples/1rmtmorse])
AC_CONFIG_SUBDIRS([examples/1rmtmusic])
AC_CONFIG_SUBDIRS([examples/1rmtws2812])
@@ -35,6 +36,7 @@ AC_CONFIG_FILES([
examples/0hello/Makefile
examples/0ledctrl/Makefile
examples/1rmtblink/Makefile
+ examples/1rmtdht/Makefile
examples/1rmtmorse/Makefile
examples/1rmtmusic/Makefile
examples/1rmtws2812/Makefile
diff --git a/examples/1rmtdht/Makefile.am b/examples/1rmtdht/Makefile.am
new file mode 100644
index 0000000..f8424be
--- /dev/null
+++ b/examples/1rmtdht/Makefile.am
@@ -0,0 +1,37 @@
+include $(top_srcdir)/scripts/elf2bin.mk
+include $(top_srcdir)/ld/flags.mk
+
+noinst_HEADERS = defines.h
+
+AM_CFLAGS = -std=c11 -flto
+
+if WITH_BINARIES
+AM_LDFLAGS += \
+ -T $(top_srcdir)/ld/esp32.rom.ld \
+ -T $(top_srcdir)/ld/esp32.rom.libgcc.ld \
+ -T $(top_srcdir)/ld/esp32.rom.newlib-data.ld \
+ -T $(top_srcdir)/ld/esp32.rom.newlib-locale.ld \
+ -T $(top_srcdir)/ld/esp32.rom.newlib-nano.ld \
+ -T $(top_srcdir)/ld/esp32.rom.newlib-time.ld \
+ -T $(top_srcdir)/ld/esp32.rom.redefined.ld \
+ -T $(top_srcdir)/ld/esp32.rom.syscalls.ld
+else
+AM_LDFLAGS += \
+ -T $(top_srcdir)/ld/esp32.rom.ld \
+ -T $(top_srcdir)/ld/esp32.rom.libgcc.ld \
+ -T $(top_srcdir)/ld/esp32.rom.redefined.ld \
+ -T $(top_srcdir)/ld/esp32.rom.syscalls.ld
+endif
+
+AM_CPPFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/modules
+LDADD = $(top_builddir)/src/libesp32basic.a $(top_builddir)/modules/libesp32modules.a
+
+bin_PROGRAMS = \
+ rmtdht.elf
+
+if WITH_BINARIES
+CLEANFILES = \
+ rmtdht.bin
+endif
+
+BUILT_SOURCES = $(CLEANFILES)
diff --git a/examples/1rmtdht/README.md b/examples/1rmtdht/README.md
new file mode 100644
index 0000000..2c23cc0
--- /dev/null
+++ b/examples/1rmtdht/README.md
@@ -0,0 +1,21 @@
+### DHT22 sensor sampling example
+
+In this example we periodically read sensor data (temperature and rel. humidity)
+from DHT22 external device.
+Special 1-wire protocol is used when communicating to DHT22.
+The 1-wire protocol is implemented in `modules/dht22.c`.
+
+#### Hardware components
+
+* S1: DHT22 temp/hum sensor
+
+#### Connections
+
+```
+ESP32.GPIO2 -- S1.OUT
+ESP32.GND -- S1.-
+ESP32.VCC -- S1.+
+```
+
+#### Practices
+
diff --git a/examples/1rmtdht/defines.h b/examples/1rmtdht/defines.h
new file mode 100644
index 0000000..a767e29
--- /dev/null
+++ b/examples/1rmtdht/defines.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2024 SZIGETI János
+ *
+ * This file is part of Bilis ESP32 Basic, which is released under GNU General Public License.version 3.
+ * See LICENSE or for full license details.
+ */
+#ifndef DEFINES_H
+#define DEFINES_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ // TIMINGS
+ // const -- do not change this value
+#define APB_FREQ_HZ 80000000U // 80 MHz
+
+ // variables
+#define TIM0_0_DIVISOR 2U
+#define START_APP_CPU 0U
+#define SCHEDULE_FREQ_HZ 1000U // 1KHz
+
+ // derived invariants
+#define CLK_FREQ_HZ (APB_FREQ_HZ / TIM0_0_DIVISOR) // 40 MHz
+#define TICKS_PER_MS (CLK_FREQ_HZ / 1000U) // 40000
+#define TICKS_PER_US (CLK_FREQ_HZ / 1000000U) // 40
+#define NS_PER_TICKS (1000000000 / CLK_FREQ_HZ)
+
+#define TICKS2NS(X) ((X) * NS_PER_TICKS)
+#define TICKS2US(X) ((X) / TICKS_PER_US)
+#define MS2TICKS(X) ((X) * TICKS_PER_MS)
+#define HZ2APBTICKS(X) (APB_FREQ_HZ / (X))
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* DEFINES_H */
+
diff --git a/examples/1rmtdht/rmtdht.c b/examples/1rmtdht/rmtdht.c
new file mode 100644
index 0000000..c6773c4
--- /dev/null
+++ b/examples/1rmtdht/rmtdht.c
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2024 SZIGETI János
+ *
+ * This file is part of Bilis ESP32 Basic, which is released under GNU General Public License.version 3.
+ * See LICENSE or for full license details.
+ */
+#include
+#include
+#include
+#include
+#include
+
+#include "dht22.h"
+#include "gpio.h"
+#include "main.h"
+#include "rmt.h"
+#include "defines.h"
+#include "romfunctions.h"
+#include "iomux.h"
+#include "dport.h"
+#include "timg.h"
+#include "utils/uartutils.h"
+
+// =================== Hard constants =================
+// #1: Timings
+#define RMTDHT_PERIOD_MS 2000U ///< Higher than 8 * 0.2s, so RMT blinks will not overlap.
+
+// #2: Channels / wires / addresses
+#define RMTDHT_GPIO 21U
+#define RMTDHT_CH RMT_CH0
+#define RMTINT_CH 23U
+
+// ============= Local types ===============
+
+// ================ Local function declarations =================
+static void _rmtdht_init();
+static void _rmtdht_cycle(uint64_t u64Ticks);
+
+// =================== Global constants ================
+const bool gbStartAppCpu = START_APP_CPU;
+const uint16_t gu16Tim00Divisor = TIM0_0_DIVISOR;
+const uint64_t gu64tckSchedulePeriod = (CLK_FREQ_HZ / SCHEDULE_FREQ_HZ);
+
+// ==================== Local Data ================
+static SDht22Descriptor gsDht22Desc;
+
+// ==================== Implementation ================
+
+void _done_rx(void *pvParam, SDht22Data *psParam) {
+ uart_printf(&gsUART0, "INVALID: %02X %02X %02X %02X %02X\n",
+ psParam->au8Invalid[0],
+ psParam->au8Invalid[1],
+ psParam->au8Invalid[2],
+ psParam->au8Invalid[3],
+ psParam->au8Invalid[4]
+ );
+ uart_printf(&gsUART0, "DATA: %02X %02X %02X %02X %02X\n",
+ psParam->au8Data[0],
+ psParam->au8Data[1],
+ psParam->au8Data[2],
+ psParam->au8Data[3],
+ psParam->au8Data[4]
+ );
+ uart_printf(&gsUART0, "raw data (%c) T: %d, RH: %u\n",
+ dht22_data_valid(psParam) ? '+' : '-',
+ dht22_get_temp(psParam),
+ dht22_get_rhum(psParam)
+ );
+}
+
+static void _rmtdht_init() {
+ rmt_isr_init();
+ rmt_init_controller(true, true);
+ gsDht22Desc = dht22_config(RMTDHT_CH, _done_rx, NULL);
+ dht22_init(RMTDHT_GPIO, APB_FREQ_HZ, &gsDht22Desc);
+
+ rmt_isr_start(CPU_PRO, RMTINT_CH);
+}
+
+static void _rmtdht_cycle(uint64_t u64Ticks) {
+ static uint64_t u64NextTick = 0;
+
+ if (u64NextTick <= u64Ticks) {
+ dht22_run(&gsDht22Desc);
+
+ u64NextTick += MS2TICKS(RMTDHT_PERIOD_MS);
+ }
+}
+
+// ====================== Interface functions =========================
+
+void prog_init_pro_pre() {
+ gsUART0.CLKDIV = APB_FREQ_HZ / 115200;
+
+ _rmtdht_init();
+}
+
+void prog_init_app() {
+}
+
+void prog_init_pro_post() {
+}
+
+void prog_cycle_app(uint64_t u64tckNow) {
+}
+
+void prog_cycle_pro(uint64_t u64tckNow) {
+ _rmtdht_cycle(u64tckNow);
+}
diff --git a/examples/Makefile.am b/examples/Makefile.am
index 7c3e446..2d3ccfd 100644
--- a/examples/Makefile.am
+++ b/examples/Makefile.am
@@ -1,2 +1,2 @@
AUTOMAKE_OPTIONS =
-SUBDIRS=0blink 0button 0hello 0ledctrl 1rmtblink 1rmtmorse 1rmtmusic 3prog1 1rmtws2812
+SUBDIRS=0blink 0button 0hello 0ledctrl 1rmtblink 1rmtdht 1rmtmorse 1rmtmusic 3prog1 1rmtws2812
diff --git a/modules/Makefile.am b/modules/Makefile.am
index 0e3cba3..8556471 100644
--- a/modules/Makefile.am
+++ b/modules/Makefile.am
@@ -5,10 +5,10 @@ libesp32modules_a_AR=$(AR) rcs
lib_LIBRARIES = libesp32modules.a
-include_HEADERS = bh1750.h bme280.h ws2812.h
+include_HEADERS = bh1750.h bme280.h dht22.h ws2812.h
nodist_include_HEADERS =
-libesp32modules_a_SOURCES = bh1750.c bme280.c ws2812.c
+libesp32modules_a_SOURCES = bh1750.c bme280.c dht22.c ws2812.c
nodist_libesp32modules_a_SOURCES =
CLEANFILES =
diff --git a/modules/dht22.c b/modules/dht22.c
new file mode 100644
index 0000000..375b342
--- /dev/null
+++ b/modules/dht22.c
@@ -0,0 +1,186 @@
+/*
+ * Copyright 2025 SZIGETI János
+ *
+ * This file is part of Bilis ESP32 Basic, which is released under GNU General Public License.version 3.
+ * See LICENSE or for full license details.
+ */
+
+#include
+#include
+
+#include "dht22.h"
+#include "rmt.h"
+
+#define DHT_HOSTPULLDOWN_IVAL_US 1100U ///< The communication begins with host sending out signal 0 for 1.1 ms.
+
+// measured: [70..73] and [23..27]
+#define DHT_BIT1_IVAL_LO_US 68
+#define DHT_BIT1_IVAL_HI_US 75
+#define DHT_BIT0_IVAL_LO_US 22
+#define DHT_BIT0_IVAL_HI_US 29
+
+#define DHT22_IDLE_US 90 ///< If the input signal is constant 0 or 1 for more than 90 µs, the RX process is done.
+
+#define RMT_FREQ_KHZ 1000U ///< 1MHz -- clk: 1µs
+#define RMT_CLK_NS (1000000 / RMT_FREQ_KHZ)
+#if (1000 == RMT_FREQ_KHZ)
+#define US_TO_RMTCLK(X) (X)
+#define RMTCLK_TO_US(X) (X)
+#else
+#define US_TO_RMTCLK(X) (((X) * RMT_FREQ_KHZ) / 1000)
+#define RMTCLK_TO_US(X) (((X) * 1000) / RMT_FREQ_KHZ)
+#endif
+#define RMTDHT_FILTER_THRES 50U ///< RMT filters out spikes shorter than that many APB clocks.
+
+// ================ Local function declarations =================
+static inline bool _u16ltz(uint16_t u16Value);
+static inline int16_t _u16abs(uint16_t u16Value);
+static inline int16_t _u16toi16(uint16_t u16Value);
+static void _rmt_config_channel(const ERmtChannel eChannel, uint8_t u8Divisor);
+static void _rxstart(void *pvParam);
+static void _rxready(void *pvParam);
+// =================== Global constants ================
+
+// ==================== Local Data ================
+
+// ==================== Implementation ================
+static inline bool _u16ltz(uint16_t u16Value) {
+ return (u16Value & (1 << 15));
+}
+
+static inline int16_t _u16abs(uint16_t u16Value) {
+ return (u16Value & 0x7fff);
+}
+
+static inline int16_t _u16toi16(uint16_t u16Value) {
+ return _u16ltz(u16Value) ?
+ -_u16abs(u16Value) :
+ u16Value;
+}
+
+static void _rmt_config_channel(ERmtChannel eChannel, uint8_t u8Divisor) {
+ // rmt channel config
+ SRmtChConf rChConf = {
+ .r0 =
+ {.u8DivCnt = u8Divisor, .u4MemSize = 1,
+ .u16IdleThres = US_TO_RMTCLK(DHT22_IDLE_US)},
+ .r1 =
+ {.bRefAlwaysOn = 1, .bRefCntRst = 1, .bMemRdRst = 1,
+ .bIdleOutLvl = 1, .bIdleOutEn = 1,
+ .bRxFilterEn = 1, .u8RxFilterThres = RMTDHT_FILTER_THRES}
+ };
+ gpsRMT->asChConf[eChannel] = rChConf;
+
+ gpsRMT->arTxLim[eChannel].u9Val = 256; // currently unused
+}
+
+static void _rxstart(void *pvParam) {
+ SDht22Descriptor *psParam = (SDht22Descriptor*)pvParam;
+ rmt_start_rx(psParam->eChannel, 1);
+
+}
+
+static void _rxready(void *pvParam) {
+ SDht22Descriptor *psParam = (SDht22Descriptor*)pvParam;
+
+ RegAddr prData = rmt_ram_addr(psParam->eChannel, 1, 0);
+ uint32_t u32RecvSize = gpsRMT->asStatus[psParam->eChannel].u9RxIdx;
+ uint32_t u32DataOfs = u32RecvSize - (DHT22_DATA_LEN * 8) - 1;
+ bool bLowEnd = (prData[u32RecvSize - 1] & RMT_ENTRYMAX) == 0;
+ uint8_t u8Shr = bLowEnd ? 0 : 16;
+
+ memset(&psParam->sData, 0, sizeof (psParam->sData));
+
+ for (int i = 0; i < (DHT22_DATA_LEN * 8); ++i) {
+ int iByte = i / 8;
+ int iBit = 7 - (i % 8);
+ uint32_t u32Dat = (prData[u32DataOfs + i]) >> u8Shr;
+ bool bLevel0 = (0 != (u32Dat & RMT_SIGNAL1));
+ uint16_t u16Duration0 = RMTCLK_TO_US(u32Dat & RMT_ENTRYMAX);
+ bool bValid = bLevel0;
+ bool bValue = false;
+ if (DHT_BIT0_IVAL_LO_US <= u16Duration0 && u16Duration0 <= DHT_BIT0_IVAL_HI_US) {
+ bValue = false;
+ } else if (DHT_BIT1_IVAL_LO_US <= u16Duration0 && u16Duration0 <= DHT_BIT1_IVAL_HI_US) {
+ bValue = true;
+ } else {
+ bValid = false;
+ }
+ if (bValue)
+ psParam->sData.au8Data[iByte] |= (1 << iBit);
+ if (!bValid)
+ psParam->sData.au8Invalid[iByte] |= (1 << iBit);
+ }
+
+ psParam->fReadyCb(psParam->pvReadyCbParam, &psParam->sData);
+}
+
+// ============== Interface functions ==============
+
+/**
+ * Initializes DHT22 communication environment.
+ * @param u8Pin GPIO pin.
+ * @param u32ApbClkFreq APB clock frequency.
+ * @param psDht22Desc DHT22 communication descriptor.
+ */
+void dht22_init(uint8_t u8Pin, uint32_t u32ApbClkFreq, SDht22Descriptor *psDht22Desc) {
+ rmt_init_channel(psDht22Desc->eChannel, u8Pin, false);
+ _rmt_config_channel(psDht22Desc->eChannel, u32ApbClkFreq / (1000 * RMT_FREQ_KHZ));
+ rmt_isr_register(psDht22Desc->eChannel, RMT_INT_TXEND, _rxstart, psDht22Desc);
+ rmt_isr_register(psDht22Desc->eChannel, RMT_INT_RXEND, _rxready, psDht22Desc);
+}
+
+/**
+ * Starts a DHT22 communication process.
+ * @param psDht22Desc DHT22 communication descriptor.
+ */
+void dht22_run(SDht22Descriptor *psDht22Desc) {
+ static const uint32_t u32Tx0 = (RMT_SIGNAL0 | US_TO_RMTCLK(DHT_HOSTPULLDOWN_IVAL_US)) | (RMT_SIGNAL1 << 16);
+
+ SRmtChConf1Reg sConf1 = {.raw = 0};
+ sConf1.bMemOwner = 1;
+ gsRMT.asChConf[psDht22Desc->eChannel].r1.raw |= sConf1.raw;
+
+ rmt_ram_addr(psDht22Desc->eChannel, 1, 0)[0] = u32Tx0;
+
+ rmt_start_tx(psDht22Desc->eChannel, 1);
+}
+
+/**
+ * Gets humidity data from received and bit-decoded data.
+ * @param psData Received bit-decoded data.
+ * @return Humidity data with 1-digit precision.
+ */
+uint16_t dht22_get_rhum(const SDht22Data *psData) {
+ return (psData->au8Data[0] << 8) | psData->au8Data[1];
+}
+
+/**
+ * Gets temperature data from received and bit-decoded data.
+ * @param psData Received bit-decoded data.
+ * @return Temperature data with 1-digit precision.
+ */
+int16_t dht22_get_temp(const SDht22Data *psData) {
+ uint16_t u16T0 = (psData->au8Data[2] << 8) | psData->au8Data[3];
+ return _u16toi16(u16T0);
+}
+
+/**
+ * Tells if the received data is valid.
+ * @param psData Received bit-decoded data.
+ * @return The data does not contains any invalid bit and the checksum matches.
+ */
+bool dht22_data_valid(const SDht22Data *psData) {
+ bool bAllBitValid = true;
+ uint8_t u8DataSum = 0;
+
+ for (int i = 0; i < DHT22_DATA_LEN; ++i) {
+ bAllBitValid &= (psData->au8Invalid[i] == 0);
+ }
+ for (int i = 0; i < DHT22_DATA_LEN - 1; ++i) {
+ u8DataSum += psData->au8Data[i];
+ }
+ bool bCheckSum = (u8DataSum == psData->au8Data[DHT22_DATA_LEN - 1]);
+ return bAllBitValid && bCheckSum;
+}
+
diff --git a/modules/dht22.h b/modules/dht22.h
new file mode 100644
index 0000000..707a856
--- /dev/null
+++ b/modules/dht22.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2025 SZIGETI János
+ *
+ * This file is part of Bilis ESP32 Basic, which is released under GNU General Public License.version 3.
+ * See LICENSE or for full license details.
+ */
+#ifndef DHT22_H
+#define DHT22_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "rmt.h"
+
+#define DHT22_DATA_LEN 5
+
+ // ============= Types ===============
+
+ /**
+ * This struct contains bit decoded DHT22 data.
+ * The raw data (signal level and duration) is not stored.
+ */
+ typedef struct {
+ uint8_t au8Data[DHT22_DATA_LEN]; ///< Stores raw data decoded bit-by-bit from RMT RAM entries.
+ uint8_t au8Invalid[DHT22_DATA_LEN]; ///< Shows which bits could not be decoded from RMT RAM entries.
+ } SDht22Data;
+
+ /**
+ * Function type of the callback that gets invoked,
+ * when the DHT22 data is received and bit decoded.
+ * pvParam is Arbitrary data passed to the function,
+ * whereas psData contains the result of the bit-decoding.
+ */
+ typedef void (*FDht22Callback)(void *pvParam, SDht22Data *psData);
+
+ /**
+ * Contains data that the interface functions require.
+ */
+ typedef struct {
+ ERmtChannel eChannel; ///< RMT channel.
+ FDht22Callback fReadyCb; ///< Callback to invoke when all the data is received and decoded.
+ void *pvReadyCbParam; ///< First parameter to pass to the callback function.
+ SDht22Data sData; ///< Store decoded sensor data.
+ } SDht22Descriptor;
+
+ // ============= Inline functions ===============
+
+ /**
+ * Creates and initializes SDht22Descriptor instance.
+ * @param eChannel Identifies the RMT channel.
+ * @param fReadyCb Callback to invoke when the data is received and decoded.
+ * @param pvReadyCbParam First parameter to pass to the callback.
+ * @return Initialized descriptor instance.
+ */
+ static inline SDht22Descriptor dht22_config(ERmtChannel eChannel, FDht22Callback fReadyCb, void *pvReadyCbParam) {
+ SDht22Descriptor sRet = {.eChannel = eChannel, .fReadyCb = fReadyCb, .pvReadyCbParam = pvReadyCbParam};
+ return sRet;
+ }
+
+
+ // ============= Interface function declaration ===============
+ void dht22_init(uint8_t u8Pin, uint32_t u32ApbClkFreq, SDht22Descriptor *psDht22Desc);
+ void dht22_run(SDht22Descriptor *psDht22Desc);
+ uint16_t dht22_get_rhum(const SDht22Data *psData);
+ int16_t dht22_get_temp(const SDht22Data *psData);
+ bool dht22_data_valid(const SDht22Data *psData);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* DHT22_H */
+
diff --git a/src/rmt.h b/src/rmt.h
index 9aa42ab..810f514 100644
--- a/src/rmt.h
+++ b/src/rmt.h
@@ -26,18 +26,18 @@ extern "C" {
// ============== Types ==============
typedef enum {
- RMT_INT_RAW = 0, ///< Raw interrupt status (RO)
- RMT_INT_ST = 1, ///< Masked interrupt status (RO)
- RMT_INT_ENA = 2, ///< Interrupts with active bits are enabled (and shown in masked interrupt status), interrupts with inactive bits are disabled (RW)
- RMT_INT_CLR = 3 ///< Setting a bit clears the given interrupt (WO)
- } ERmtIntReg; ///< Types of interrupt registers.
+ RMT_INT_RAW = 0, ///< Raw interrupt status (RO)
+ RMT_INT_ST = 1, ///< Masked interrupt status (RO)
+ RMT_INT_ENA = 2, ///< Interrupts with active bits are enabled (and shown in masked interrupt status), interrupts with inactive bits are disabled (RW)
+ RMT_INT_CLR = 3 ///< Setting a bit clears the given interrupt (WO)
+ } ERmtIntReg; ///< Types of interrupt registers.
typedef enum {
- RMT_INT_TXEND = 0, ///< TX is done.
- RMT_INT_RXEND = 1, ///< RX is done.
- RMT_INT_ERR = 2, ///< An error occured.
+ RMT_INT_TXEND = 0, ///< TX is done.
+ RMT_INT_RXEND = 1, ///< RX is done.
+ RMT_INT_ERR = 2, ///< An error occured.
RMT_INT_TXTHRES = 3 ///< TX threshold is reached.
- } ERmtIntType; ///< Types of RMT interrupt.
+ } ERmtIntType; ///< Types of RMT interrupt.
typedef enum {
RMT_CH0 = 0,
@@ -53,14 +53,14 @@ extern "C" {
typedef volatile union {
volatile struct {
- uint32_t u8DivCnt : 8; ///< The divisor for the channel clock of channel n. (R/W)
+ uint32_t u8DivCnt : 8; ///< The divisor for the channel clock of channel n. (R/W)
- uint32_t u16IdleThres : 16; ///< In receive mode, when no edge is detected on the input signal for longer than REG_IDLE_THRES_CHn channel clock cycles, the receive process is finished. (R/W)
+ uint32_t u16IdleThres : 16; ///< In receive mode, when no edge is detected on the input signal for longer than REG_IDLE_THRES_CHn channel clock cycles, the receive process is finished. (R/W)
- uint32_t u4MemSize : 4; ///< The amount of memory blocks allocated to channel n. (R/W)
- uint32_t bCarrierEn : 1; ///< Carrier modulation is enabled with 1, while carrier modulation is disabled with 0. (R/W)
- uint32_t bCarrierOutLvl : 1; ///< Used when the carrier wave is being transmitted. Transmit on low output level with 0, and transmit on high output level with 1. (R/W)
- uint32_t bMemPd : 1; ///< Power down the entire RMT RAM block.Reset (It only exists in RMT_CH0CONF0). 1: power down memory; 0: power up memory. (R/W)
+ uint32_t u4MemSize : 4; ///< The amount of memory blocks allocated to channel n. (R/W)
+ uint32_t bCarrierEn : 1; ///< Carrier modulation is enabled with 1, while carrier modulation is disabled with 0. (R/W)
+ uint32_t bCarrierOutLvl : 1; ///< Used when the carrier wave is being transmitted. Transmit on low output level with 0, and transmit on high output level with 1. (R/W)
+ uint32_t bMemPd : 1; ///< Power down the entire RMT RAM block.Reset (It only exists in RMT_CH0CONF0). 1: power down memory; 0: power up memory. (R/W)
uint32_t rsvd31 : 1;
};
volatile uint32_t raw;
@@ -69,22 +69,22 @@ extern "C" {
typedef volatile union {
volatile struct {
- uint32_t bTxStart : 1; ///< Set this bit to start sending data on channel n. (R/W)
- uint32_t bRxEn : 1; ///< Set this bit to enable receiving data on channel n. (R/W)
- uint32_t bMemWrRst : 1; ///< Set this bit to reset the write-RAM address for channel n by accessing the receiver. (R/W)
- uint32_t bMemRdRst : 1; ///< Set this bit to reset the read-RAM address for channel n by accessing the transmitter. (R/W)
- uint32_t bFifoRst : 1; ///< Undocumented bit. Probably resets FIFO internal counters (R/W).
- uint32_t bMemOwner : 1; ///< Number 1 indicates that the receiver is using the RAM, while 0 indicates that the transmitter is using the RAM. (R/W)
- uint32_t bTxContiMode : 1; ///< If this bit is set, instead of going to an idle state when transmission ends, the transmitter will restart transmission. This results in a repeating output signal. (R/W)
- uint32_t bRxFilterEn : 1; ///< receive filter’s enable-bit for channel n. (R/W)
+ uint32_t bTxStart : 1; ///< Set this bit to start sending data on channel n. (R/W)
+ uint32_t bRxEn : 1; ///< Set this bit to enable receiving data on channel n. (R/W)
+ uint32_t bMemWrRst : 1; ///< Set this bit to reset the write-RAM address for channel n by accessing the receiver. (R/W)
+ uint32_t bMemRdRst : 1; ///< Set this bit to reset the read-RAM address for channel n by accessing the transmitter. (R/W)
+ uint32_t bFifoRst : 1; ///< Undocumented bit. Probably resets FIFO internal counters (R/W).
+ uint32_t bMemOwner : 1; ///< Number 1 indicates that the RX process can write the RAM (R/W).
+ uint32_t bTxContiMode : 1; ///< If this bit is set, instead of going to an idle state when transmission ends, the transmitter will restart transmission. This results in a repeating output signal. (R/W)
+ uint32_t bRxFilterEn : 1; ///< receive filter’s enable-bit for channel n. (R/W)
uint32_t u8RxFilterThres : 8; ///< In receive mode, channel n ignores input pulse when the pulse width is smaller than this value in APB clock periods. (R/W)
- uint32_t bRefCntRst : 1; ///< Setting this bit resets the clock divider of channel n. (R/W)
- uint32_t bRefAlwaysOn : 1; ///< Select the channel’s base clock. 1:clk_apb; 0:clk_ref. (R/W)
- uint32_t bIdleOutLvl : 1; ///< The level of output signals in channel n when the latter is in IDLE state. (R/W)
- uint32_t bIdleOutEn : 1; ///< Output enable-control bit for channel n in IDLE state. (R/W)
- uint32_t rsvd20 : 12; ///< Reserved
+ uint32_t bRefCntRst : 1; ///< Setting this bit resets the clock divider of channel n. (R/W)
+ uint32_t bRefAlwaysOn : 1; ///< Select the channel’s base clock. 1:clk_apb; 0:clk_ref. (R/W)
+ uint32_t bIdleOutLvl : 1; ///< The level of output signals in channel n when the latter is in IDLE state. (R/W)
+ uint32_t bIdleOutEn : 1; ///< Output enable-control bit for channel n in IDLE state. (R/W)
+ uint32_t rsvd20 : 12; ///< Reserved
};
volatile uint32_t raw;
} SRmtChConf1Reg;
@@ -97,8 +97,8 @@ extern "C" {
typedef volatile union {
volatile struct {
- uint32_t u16Low : 16; ///< If carrier is enabled, this value defines the length of low level in the carrier wave (APB/REF ticks).
- uint32_t u16High : 16; ///< If carrier is enabled, this value defines the length of high level in the carrier wave (APB/REF ticks).
+ uint32_t u16Low : 16; ///< If carrier is enabled, this value defines the length of low level in the carrier wave (APB/REF ticks).
+ uint32_t u16High : 16; ///< If carrier is enabled, this value defines the length of high level in the carrier wave (APB/REF ticks).
};
volatile uint32_t raw;
} SRmtChCarrierDutyReg;
@@ -106,7 +106,7 @@ extern "C" {
typedef union {
volatile struct {
- uint32_t u9Val : 9; ///< After sending this amount of TX entries, TX_THR_EVENT interrupt is produced.
+ uint32_t u9Val : 9; ///< After sending this amount of TX entries, TX_THR_EVENT interrupt is produced.
uint32_t rsvd9 : 23;
};
volatile uint32_t raw;
@@ -127,13 +127,14 @@ extern "C" {
typedef union {
volatile struct {
- uint32_t rsvd0 : 12; ///< ??, Probably RX status
- uint32_t u9TxIdx : 9; ///< TX mem idx
- uint32_t bTxWrapped : 1; ///< TX memory pointer is below the channel's memory block (mem idx offset is -512)
+ uint32_t u9RxIdx : 9; ///< RX mem idx
+ uint32_t rsvd9 : 3; ///< ???, probably RX status
+ uint32_t u9TxIdx : 9; ///< TX mem idx
+ uint32_t bTxWrapped : 1; ///< TX memory pointer is below the channel's memory block (mem idx offset is -512)
uint32_t rsvd22 : 2;
- uint32_t bTxState : 1; ///< TX process is ongoing
+ uint32_t bTxState : 1; ///< TX process is ongoing
uint32_t rsvd25 : 7;
- };
+ } ;
volatile uint32_t raw;
} SRmtStatusReg;