Manage RMT channel resources with alloc()/release().
This commit is contained in:
parent
e33fb81b77
commit
e2fdd4adbe
|
@ -115,6 +115,30 @@ int platform_i2c_send_byte( unsigned id, uint8_t data, int ack_check_en );
|
||||||
int platform_i2c_recv_byte( unsigned id, int ack_val );
|
int platform_i2c_recv_byte( unsigned id, int ack_val );
|
||||||
|
|
||||||
|
|
||||||
|
// *****************************************************************************
|
||||||
|
// RMT platform interface
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Allocate an RMT channel.
|
||||||
|
*
|
||||||
|
* @param num_mem Number of memory blocks.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* - Channel number when successful
|
||||||
|
* - -1 if no channel available
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int platform_rmt_allocate( uint8_t num_mem );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Release a previously allocated RMT channel.
|
||||||
|
*
|
||||||
|
* @param channel Channel number.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void platform_rmt_release( uint8_t channel );
|
||||||
|
|
||||||
|
|
||||||
// *****************************************************************************
|
// *****************************************************************************
|
||||||
// Onewire platform interface
|
// Onewire platform interface
|
||||||
|
|
||||||
|
|
|
@ -67,6 +67,8 @@ sample code bearing this copyright.
|
||||||
#define TRUE (1==1)
|
#define TRUE (1==1)
|
||||||
#define FALSE !TRUE
|
#define FALSE !TRUE
|
||||||
|
|
||||||
|
#undef OW_DEBUG
|
||||||
|
|
||||||
// *****************************************************************************
|
// *****************************************************************************
|
||||||
// Onewire platform interface
|
// Onewire platform interface
|
||||||
|
|
||||||
|
@ -105,43 +107,60 @@ static const uint8_t owDefaultPower = 0;
|
||||||
|
|
||||||
static int onewire_rmt_init( uint8_t gpio_num )
|
static int onewire_rmt_init( uint8_t gpio_num )
|
||||||
{
|
{
|
||||||
// acquire an RMT module for TX and RX
|
// acquire an RMT module for TX and RX each
|
||||||
rmt_config_t rmt_tx;
|
if ((ow_rmt.tx = platform_rmt_allocate( 1 )) >= 0) {
|
||||||
ow_rmt.tx = RMT_CHANNEL_7;
|
if ((ow_rmt.rx = platform_rmt_allocate( 1 )) >= 0) {
|
||||||
rmt_tx.channel = ow_rmt.tx;
|
|
||||||
rmt_tx.gpio_num = gpio_num;
|
|
||||||
rmt_tx.mem_block_num = 1;
|
|
||||||
rmt_tx.clk_div = 80;
|
|
||||||
rmt_tx.tx_config.loop_en = false;
|
|
||||||
rmt_tx.tx_config.carrier_en = false;
|
|
||||||
rmt_tx.tx_config.idle_level = 1;
|
|
||||||
rmt_tx.tx_config.idle_output_en = true;
|
|
||||||
rmt_tx.rmt_mode = RMT_MODE_TX;
|
|
||||||
if (rmt_config( &rmt_tx ) != ESP_OK)
|
|
||||||
return PLATFORM_ERR;
|
|
||||||
if (rmt_driver_install( rmt_tx.channel, 0, 0 ) != ESP_OK)
|
|
||||||
return PLATFORM_ERR;
|
|
||||||
|
|
||||||
rmt_config_t rmt_rx;
|
#ifdef OW_DEBUG
|
||||||
ow_rmt.rx = RMT_CHANNEL_6;
|
ESP_LOGI("ow", "RMT TX channel: %d", ow_rmt.tx);
|
||||||
rmt_rx.channel = ow_rmt.rx;
|
ESP_LOGI("ow", "RMT RX channel: %d", ow_rmt.rx);
|
||||||
rmt_rx.gpio_num = gpio_num;
|
#endif
|
||||||
rmt_rx.clk_div = 80;
|
|
||||||
rmt_rx.mem_block_num = 1;
|
|
||||||
rmt_rx.rmt_mode = RMT_MODE_RX;
|
|
||||||
rmt_rx.rx_config.filter_en = true;
|
|
||||||
rmt_rx.rx_config.filter_ticks_thresh = 30;
|
|
||||||
rmt_rx.rx_config.idle_threshold = OW_DURATION_RX_IDLE;
|
|
||||||
if (rmt_config( &rmt_rx ) != ESP_OK)
|
|
||||||
return PLATFORM_ERR;
|
|
||||||
if (rmt_driver_install( rmt_rx.channel, 512, 0 ) != ESP_OK)
|
|
||||||
return PLATFORM_ERR;
|
|
||||||
|
|
||||||
rmt_get_ringbuf_handler( ow_rmt.rx, &ow_rmt.rb );
|
rmt_config_t rmt_tx;
|
||||||
|
rmt_tx.channel = ow_rmt.tx;
|
||||||
|
rmt_tx.gpio_num = gpio_num;
|
||||||
|
rmt_tx.mem_block_num = 1;
|
||||||
|
rmt_tx.clk_div = 80;
|
||||||
|
rmt_tx.tx_config.loop_en = false;
|
||||||
|
rmt_tx.tx_config.carrier_en = false;
|
||||||
|
rmt_tx.tx_config.idle_level = 1;
|
||||||
|
rmt_tx.tx_config.idle_output_en = true;
|
||||||
|
rmt_tx.rmt_mode = RMT_MODE_TX;
|
||||||
|
if (rmt_config( &rmt_tx ) == ESP_OK) {
|
||||||
|
if (rmt_driver_install( rmt_tx.channel, 0, 0 ) == ESP_OK) {
|
||||||
|
|
||||||
ow_rmt.gpio = gpio_num;
|
rmt_config_t rmt_rx;
|
||||||
|
rmt_rx.channel = ow_rmt.rx;
|
||||||
|
rmt_rx.gpio_num = gpio_num;
|
||||||
|
rmt_rx.clk_div = 80;
|
||||||
|
rmt_rx.mem_block_num = 1;
|
||||||
|
rmt_rx.rmt_mode = RMT_MODE_RX;
|
||||||
|
rmt_rx.rx_config.filter_en = true;
|
||||||
|
rmt_rx.rx_config.filter_ticks_thresh = 30;
|
||||||
|
rmt_rx.rx_config.idle_threshold = OW_DURATION_RX_IDLE;
|
||||||
|
if (rmt_config( &rmt_rx ) == ESP_OK) {
|
||||||
|
if (rmt_driver_install( rmt_rx.channel, 512, 0 ) == ESP_OK) {
|
||||||
|
|
||||||
return PLATFORM_OK;
|
rmt_get_ringbuf_handler( ow_rmt.rx, &ow_rmt.rb );
|
||||||
|
|
||||||
|
ow_rmt.gpio = gpio_num;
|
||||||
|
|
||||||
|
return PLATFORM_OK;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rmt_driver_uninstall( rmt_tx.channel );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
platform_rmt_release( ow_rmt.rx );
|
||||||
|
}
|
||||||
|
|
||||||
|
platform_rmt_release( ow_rmt.tx );
|
||||||
|
}
|
||||||
|
|
||||||
|
return PLATFORM_ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
// flush any pending/spurious traces from the RX channel
|
// flush any pending/spurious traces from the RX channel
|
||||||
|
@ -223,7 +242,8 @@ int platform_onewire_reset( uint8_t gpio_num, uint8_t *presence )
|
||||||
|
|
||||||
if (rx_items) {
|
if (rx_items) {
|
||||||
if (rx_size >= 1 * sizeof( rmt_item32_t )) {
|
if (rx_size >= 1 * sizeof( rmt_item32_t )) {
|
||||||
#if 0
|
|
||||||
|
#ifdef OW_DEBUG
|
||||||
for (int i = 0; i < rx_size / 4; i++) {
|
for (int i = 0; i < rx_size / 4; i++) {
|
||||||
ESP_LOGI("ow", "level: %d, duration %d", rx_items[i].level0, rx_items[i].duration0);
|
ESP_LOGI("ow", "level: %d, duration %d", rx_items[i].level0, rx_items[i].duration0);
|
||||||
ESP_LOGI("ow", "level: %d, duration %d", rx_items[i].level1, rx_items[i].duration1);
|
ESP_LOGI("ow", "level: %d, duration %d", rx_items[i].level1, rx_items[i].duration1);
|
||||||
|
@ -366,12 +386,14 @@ static int onewire_read_bits( uint8_t gpio_num, uint8_t *data, uint8_t num )
|
||||||
rmt_item32_t* rx_items = (rmt_item32_t *)xRingbufferReceive( ow_rmt.rb, &rx_size, portMAX_DELAY );
|
rmt_item32_t* rx_items = (rmt_item32_t *)xRingbufferReceive( ow_rmt.rb, &rx_size, portMAX_DELAY );
|
||||||
|
|
||||||
if (rx_items) {
|
if (rx_items) {
|
||||||
#if 0
|
|
||||||
|
#ifdef OW_DEBUG
|
||||||
for (int i = 0; i < rx_size / 4; i++) {
|
for (int i = 0; i < rx_size / 4; i++) {
|
||||||
ESP_LOGI("ow", "level: %d, duration %d", rx_items[i].level0, rx_items[i].duration0);
|
ESP_LOGI("ow", "level: %d, duration %d", rx_items[i].level0, rx_items[i].duration0);
|
||||||
ESP_LOGI("ow", "level: %d, duration %d", rx_items[i].level1, rx_items[i].duration1);
|
ESP_LOGI("ow", "level: %d, duration %d", rx_items[i].level1, rx_items[i].duration1);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (rx_size >= num * sizeof( rmt_item32_t )) {
|
if (rx_size >= num * sizeof( rmt_item32_t )) {
|
||||||
for (int i = 0; i < num; i++) {
|
for (int i = 0; i < num; i++) {
|
||||||
read_data >>= 1;
|
read_data >>= 1;
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
|
||||||
|
#include "platform.h"
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "driver/rmt.h"
|
||||||
|
|
||||||
|
|
||||||
|
static uint8_t rmt_channel_alloc[RMT_CHANNEL_MAX];
|
||||||
|
|
||||||
|
|
||||||
|
static bool rmt_channel_check( uint8_t channel, uint8_t num_mem )
|
||||||
|
{
|
||||||
|
if (num_mem == 0 || channel >= RMT_CHANNEL_MAX) {
|
||||||
|
// wrong parameter
|
||||||
|
return false;
|
||||||
|
|
||||||
|
} else if (num_mem == 1) {
|
||||||
|
if (rmt_channel_alloc[channel] == 0)
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rmt_channel_check( channel-1, num_mem-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int platform_rmt_allocate( uint8_t num_mem )
|
||||||
|
{
|
||||||
|
int channel;
|
||||||
|
uint8_t tag = 1;
|
||||||
|
|
||||||
|
for (channel = RMT_CHANNEL_MAX-1; channel >= 0; channel--) {
|
||||||
|
if (rmt_channel_alloc[channel] == 0) {
|
||||||
|
if (rmt_channel_check( channel, num_mem )) {
|
||||||
|
rmt_channel_alloc[channel] = tag++;
|
||||||
|
if (--num_mem == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (channel >= 0 && num_mem == 0)
|
||||||
|
return channel;
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void platform_rmt_release( uint8_t channel )
|
||||||
|
{
|
||||||
|
for ( ; channel < RMT_CHANNEL_MAX; channel++ ) {
|
||||||
|
uint8_t tag = rmt_channel_alloc[channel];
|
||||||
|
|
||||||
|
rmt_channel_alloc[channel] = 0;
|
||||||
|
if (tag <= 1)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue