61 #include "driver/rmt.h"
62 #include "driver/gpio.h"
63 #include "sdkconfig.h"
69 #define OW_DURATION_RESET 480
71 #define OW_DURATION_SLOT 75
73 #define OW_DURATION_1_LOW 2
74 #define OW_DURATION_1_HIGH (OW_DURATION_SLOT - OW_DURATION_1_LOW)
76 #define OW_DURATION_0_LOW 65
77 #define OW_DURATION_0_HIGH (OW_DURATION_SLOT - OW_DURATION_0_LOW)
79 #define OW_DURATION_SAMPLE (15 - 2)
82 #define OW_DURATION_RX_IDLE (OW_DURATION_SLOT + 2)
85 #define MAX_BITS_PER_SLOT (8)
87 static const char *
TAG = CONFIG_OWB_RMT_TAG;
89 #define info_of_driver(owb) container_of(owb, owb_rmt_driver_info, bus)
92 static void onewire_flush_rmt_rx_buf(
const OneWireBus *bus)
99 while ((p = xRingbufferReceive(i->
rb, &s, 0)))
101 ESP_LOGD(
TAG,
"flushing entry");
102 vRingbufferReturnItem(i->
rb, p);
108 rmt_item32_t tx_items[1] = {0};
109 bool _is_present =
false;
115 tx_items[0].level0 = 0;
116 tx_items[0].duration1 = 0;
117 tx_items[0].level1 = 1;
119 uint16_t old_rx_thresh = 0;
120 rmt_get_rx_idle_thresh(i->
rx_channel, &old_rx_thresh);
123 onewire_flush_rmt_rx_buf(bus);
125 if (rmt_write_items(i->
tx_channel, tx_items, 1,
true) == ESP_OK)
128 rmt_item32_t *rx_items = (rmt_item32_t *)xRingbufferReceive(i->
rb, &rx_size, 100 / portTICK_PERIOD_MS);
132 if (rx_size >= (1 *
sizeof(rmt_item32_t)))
135 ESP_LOGI(
TAG,
"rx_size: %d", rx_size);
137 for (
int i = 0; i < (rx_size /
sizeof(rmt_item32_t)); i++)
139 ESP_LOGI(
TAG,
"i: %d, level0: %d, duration %d", i, rx_items[i].level0, rx_items[i].duration0);
140 ESP_LOGI(
TAG,
"i: %d, level1: %d, duration %d", i, rx_items[i].level1, rx_items[i].duration1);
145 if ((rx_items[0].level0 == 0) && (rx_items[0].duration0 >=
OW_DURATION_RESET - 2))
147 if ((rx_items[0].level1 == 1) && (rx_items[0].duration1 > 0))
149 if (rx_items[1].level0 == 0)
157 vRingbufferReturnItem(i->
rb, (
void *)rx_items);
162 ESP_LOGE(
TAG,
"rx_items == 0");
169 ESP_LOGE(
TAG,
"Error tx");
174 rmt_set_rx_idle_thresh(i->
rx_channel, old_rx_thresh);
176 *is_present = _is_present;
178 ESP_LOGD(
TAG,
"_is_present %d", _is_present);
183 static rmt_item32_t _encode_write_slot(uint8_t val)
185 rmt_item32_t item = {0};
217 for (
int i = 0; i < number_of_bits_to_write; i++)
219 tx_items[i] = _encode_write_slot(out & 0x01);
224 tx_items[number_of_bits_to_write].level0 = 1;
225 tx_items[number_of_bits_to_write].duration0 = 0;
229 if (rmt_write_items(info->
tx_channel, tx_items, number_of_bits_to_write + 1,
true) == ESP_OK)
236 ESP_LOGE(
TAG,
"rmt_write_items() failed");
242 static rmt_item32_t _encode_read_slot(
void)
244 rmt_item32_t item = {0};
258 uint8_t read_data = 0;
265 ESP_LOGE(
TAG,
"_read_bits() OWB_STATUS_TOO_MANY_BITS");
270 for (
int i = 0; i < number_of_bits_to_read; i++)
272 tx_items[i] = _encode_read_slot();
276 tx_items[number_of_bits_to_read].level0 = 1;
277 tx_items[number_of_bits_to_read].duration0 = 0;
279 onewire_flush_rmt_rx_buf(bus);
281 if (rmt_write_items(info->
tx_channel, tx_items, number_of_bits_to_read + 1,
true) == ESP_OK)
284 rmt_item32_t *rx_items = (rmt_item32_t *)xRingbufferReceive(info->
rb, &rx_size, 100 / portTICK_PERIOD_MS);
289 for (
int i = 0; i < rx_size / 4; i++)
291 ESP_LOGI(
TAG,
"level: %d, duration %d", rx_items[i].level0, rx_items[i].duration0);
292 ESP_LOGI(
TAG,
"level: %d, duration %d", rx_items[i].level1, rx_items[i].duration1);
296 if (rx_size >= number_of_bits_to_read *
sizeof(rmt_item32_t))
298 for (
int i = 0; i < number_of_bits_to_read; i++)
302 if (rx_items[i].level1 == 1)
311 read_data >>= 8 - number_of_bits_to_read;
314 vRingbufferReturnItem(info->
rb, (
void *)rx_items);
319 ESP_LOGE(
TAG,
"rx_items == 0");
326 ESP_LOGE(
TAG,
"Error tx");
349 .uninitialize = _uninitialize,
351 .write_bits = _write_bits,
352 .read_bits = _read_bits};
355 rmt_channel_t tx_channel, rmt_channel_t rx_channel)
367 info->
gpio = gpio_num;
374 rmt_config_t rmt_tx = {0};
376 rmt_tx.gpio_num = gpio_num;
377 rmt_tx.mem_block_num = 1;
379 rmt_tx.tx_config.loop_en =
false;
380 rmt_tx.tx_config.carrier_en =
false;
381 rmt_tx.tx_config.idle_level = 1;
382 rmt_tx.tx_config.idle_output_en =
true;
383 rmt_tx.rmt_mode = RMT_MODE_TX;
384 if (rmt_config(&rmt_tx) == ESP_OK)
386 rmt_set_source_clk(info->
tx_channel, RMT_BASECLK_APB);
387 if (rmt_driver_install(rmt_tx.channel, 0, ESP_INTR_FLAG_LOWMED | ESP_INTR_FLAG_IRAM | ESP_INTR_FLAG_SHARED) == ESP_OK)
389 rmt_config_t rmt_rx = {0};
391 rmt_rx.gpio_num = gpio_num;
393 rmt_rx.mem_block_num = 1;
394 rmt_rx.rmt_mode = RMT_MODE_RX;
395 rmt_rx.rx_config.filter_en =
true;
396 rmt_rx.rx_config.filter_ticks_thresh = 30;
398 if (rmt_config(&rmt_rx) == ESP_OK)
400 rmt_set_source_clk(info->
rx_channel, RMT_BASECLK_APB);
401 if (rmt_driver_install(rmt_rx.channel, 512, ESP_INTR_FLAG_LOWMED | ESP_INTR_FLAG_IRAM | ESP_INTR_FLAG_SHARED) == ESP_OK)
408 ESP_LOGE(
TAG,
"failed to install rx driver");
414 ESP_LOGE(
TAG,
"failed to configure rx, uninstalling rmt driver on tx channel");
415 rmt_driver_uninstall(rmt_tx.channel);
420 ESP_LOGE(
TAG,
"failed to install tx driver");
425 ESP_LOGE(
TAG,
"failed to configure tx");
431 GPIO.enable_w1ts = (0x1 << gpio_num);
435 GPIO.enable1_w1ts.data = (0x1 << (gpio_num - 32));
441 rmt_set_pin(info->
rx_channel, RMT_MODE_RX, gpio_num);
442 rmt_set_pin(info->
tx_channel, RMT_MODE_TX, gpio_num);
445 PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[gpio_num]);
448 GPIO.pin[gpio_num].pad_driver = 1;
454 rmt_channel_t tx_channel, rmt_channel_t rx_channel)
456 ESP_LOGD(
TAG,
"%s: gpio_num: %d, tx_channel: %d, rx_channel: %d",
457 __func__, gpio_num, tx_channel, rx_channel);
459 owb_status status = _init(info, gpio_num, tx_channel, rx_channel);
462 ESP_LOGE(
TAG,
"_init() failed with status %d", status);
Interface definitions for the 1-Wire bus component.
owb_status
Represents the result of OWB API functions.
@ OWB_STATUS_OK
Operation succeeded.
@ OWB_STATUS_TOO_MANY_BITS
Attempt to write an incorrect number of bits to the One Wire Bus.
@ OWB_STATUS_HW_ERROR
A hardware error occurred.
@ OWB_STATUS_NOT_SET
A status value has not been set.
#define GPIO_NUM_NC
ESP-IDF prior to v4.x does not define GPIO_NUM_NC.
#define OW_DURATION_RX_IDLE
OneWireBus * owb_rmt_initialize(owb_rmt_driver_info *info, gpio_num_t gpio_num, rmt_channel_t tx_channel, rmt_channel_t rx_channel)
Initialise the RMT driver.
#define OW_DURATION_RESET
#define MAX_BITS_PER_SLOT
#define OW_DURATION_1_HIGH
#define OW_DURATION_SAMPLE
#define info_of_driver(owb)
#define OW_DURATION_1_LOW
#define OW_DURATION_0_HIGH
#define OW_DURATION_0_LOW
Structure containing 1-Wire bus information relevant to a single instance.
gpio_num_t strong_pullup_gpio
Set if an external strong pull-up circuit is required.
const struct owb_driver * driver
Pointer to hardware driver instance.
int rx_channel
RMT channel to use for RX.
int tx_channel
RMT channel to use for TX.
OneWireBus bus
OneWireBus instance.
RingbufHandle_t rb
Ring buffer handle.