Skip to content

Instantly share code, notes, and snippets.

@diplfranzhoepfinger
Created July 27, 2022 21:36
Show Gist options
  • Save diplfranzhoepfinger/138598910c9c6aa02ee7579ab2a34718 to your computer and use it in GitHub Desktop.
Save diplfranzhoepfinger/138598910c9c6aa02ee7579ab2a34718 to your computer and use it in GitHub Desktop.
/*
* SPDX-FileCopyrightText: 2010-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: CC0-1.0
*/
#include <stdio.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_chip_info.h"
#include "esp_flash.h"
#include "esp_log.h"
#include "driver/rmt_tx.h"
#include "driver/rmt_rx.h"
static const char * const TAG = "TPMS";
#define RMT_TPMS_RESOLUTION_HZ 1000000 // 1MHz resolution, 1 tick = 1us
#define RMT_TPMS_GPIO_NUM 35
#define ONEWIRE_RESET_PULSE_DURATION 500 // duration of reset bit
#define ONEWIRE_RESET_WAIT_DURATION 500 // how long should master wait for device to show its presence
const static rmt_symbol_word_t onewire_reset_pulse_symbol = {
.level0 = 1,
.duration0 = ONEWIRE_RESET_PULSE_DURATION,
.level1 = 0,
.duration1 = ONEWIRE_RESET_WAIT_DURATION
};
// OPMODE register: chip config
const uint8_t reg_opmode[] = { 0, // start (0 = register, 1 = OFF command)
1, // register select (0 = LIMIT, 1 = OPMODE)
1, 1, // baud rate (00=1.8k, 01=3.2k, 10=5.6k, 11=10k)
0, 1, // bit check (00=0, 01=3, 10=6, 11=9)
0, // modulation (0=FSK, 1=ASK)
0, 0, 0, 0, 0, // sleep value (0=perma polling, 31=perma sleep)
0, // sleep factor (0=1x, 1=8x)
1, // noise suppression (0=off, 1=on)
0 // stop bit
};
// LIMIT register: bit timing (10kbit manchester decoder: 50us or 100us time between edges)
// 50us: _|¯|_|¯|_ (0b11 or 0b00)
// 100us: _|¯ ¯|_ or ¯|_ _|¯ (0b10 or 0b01)
const uint8_t reg_limit[] = { 0, // start (0 = register, 1 = OFF command)
0, // register select (0 = LIMIT, 1 = OPMODE)
// Lim_min (10 .. 63) x Tclk = bit check min. time
0, 1, 0, 1, 0, 0, // 20 x 2 = 40us min. half bit, 90us full bit
// Lim_max (12 .. 63) x Tclk - 2 = bit check max. time
0, 1, 1, 1, 1, 1, // 31 x 2 - 2 = 60us max. half bit, 110us full bit
0 // stop bit
};
void app_main(void)
{
printf("Hello world!\n");
/* Print chip information */
esp_chip_info_t chip_info;
uint32_t flash_size;
esp_chip_info(&chip_info);
printf("This is %s chip with %d CPU core(s), WiFi%s%s, ",
CONFIG_IDF_TARGET,
chip_info.cores,
(chip_info.features & CHIP_FEATURE_BT) ? "/BT" : "",
(chip_info.features & CHIP_FEATURE_BLE) ? "/BLE" : "");
printf("silicon revision %d, ", chip_info.revision);
if(esp_flash_get_size(NULL, &flash_size) != ESP_OK) {
printf("Get flash size failed");
return;
}
printf("%uMB %s flash\n", flash_size / (1024 * 1024),
(chip_info.features & CHIP_FEATURE_EMB_FLASH) ? "embedded" : "external");
printf("Minimum free heap size: %d bytes\n", esp_get_minimum_free_heap_size());
rmt_channel_handle_t rx_channel = NULL;
// create rmt rx channel
rmt_rx_channel_config_t onewire_rx_channel_cfg = {
.clk_src = RMT_CLK_SRC_DEFAULT,
.gpio_num = RMT_TPMS_GPIO_NUM,
.mem_block_symbols = 64, // when the chip is ping-pong capable, we can use less rx memory blocks
.resolution_hz = RMT_TPMS_RESOLUTION_HZ, // in us
};
ESP_ERROR_CHECK(rmt_new_rx_channel(&onewire_rx_channel_cfg, &rx_channel));
ESP_LOGI(TAG, "RMT Tx channel created for 1-wire bus");
// create rmt tx channel after rx channel
ESP_LOGI(TAG, "Create RMT TX channel");
rmt_channel_handle_t tx_channel = NULL;
// create rmt tx channel after rx channel
rmt_tx_channel_config_t tx_chan_config = {
.clk_src = RMT_CLK_SRC_DEFAULT,
.gpio_num = RMT_TPMS_GPIO_NUM,
.mem_block_symbols = 64, // ping-pong is always avaliable on tx channel, save hardware memory blocks
.resolution_hz = RMT_TPMS_RESOLUTION_HZ, // in us
.trans_queue_depth = 4,
.flags.io_loop_back = true, // make tx channel coexist with rx channel on the same gpio pin
.flags.io_od_mode = true // enable open-drain mode for 1-wire bus
};
ESP_ERROR_CHECK(rmt_new_tx_channel(&tx_chan_config, &tx_channel));
rmt_encoder_handle_t copy_encoder = NULL;
rmt_copy_encoder_config_t copy_encoder_config = {};
ESP_ERROR_CHECK(rmt_new_copy_encoder(&copy_encoder_config, &copy_encoder));
//ESP_ERROR_CHECK(rmt_new_bytes_encoder(&bytes_encoder_config, &bytes_encoder);
ESP_LOGI(TAG, "Enable RMT RX channel");
ESP_ERROR_CHECK(rmt_enable(rx_channel));
ESP_LOGI(TAG, "Enable RMT TX channel");
ESP_ERROR_CHECK(rmt_enable(tx_channel));
const static rmt_transmit_config_t onewire_rmt_tx_config = {
.loop_count = 5, // no transfer loop
.flags.eot_level = 1 // onewire bus should be released in IDLE
};
const static rmt_receive_config_t onewire_rmt_rx_config = {
.signal_range_min_ns = 1000000000 / RMT_TPMS_RESOLUTION_HZ,
.signal_range_max_ns = (ONEWIRE_RESET_PULSE_DURATION + ONEWIRE_RESET_WAIT_DURATION) * 1000
};
ESP_LOGI(TAG, "Start ESC by sending zero throttle for a while...");
rmt_symbol_word_t rx_symbols[64]; /*!< hold rmt raw symbols */
ESP_ERROR_CHECK(rmt_receive(rx_channel, rx_symbols, sizeof(rmt_symbol_word_t)*2, &onewire_rmt_rx_config));
ESP_ERROR_CHECK(rmt_transmit(tx_channel, copy_encoder, &onewire_reset_pulse_symbol, sizeof(onewire_reset_pulse_symbol), &onewire_rmt_tx_config));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment