Manage RMT channel resources with alloc()/release().

This commit is contained in:
devsaurus 2017-04-01 10:08:13 +02:00
parent e33fb81b77
commit e2fdd4adbe
3 changed files with 139 additions and 35 deletions

View File

@ -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 );
// *****************************************************************************
// 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

View File

@ -67,6 +67,8 @@ sample code bearing this copyright.
#define TRUE (1==1)
#define FALSE !TRUE
#undef OW_DEBUG
// *****************************************************************************
// Onewire platform interface
@ -105,9 +107,16 @@ static const uint8_t owDefaultPower = 0;
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
if ((ow_rmt.tx = platform_rmt_allocate( 1 )) >= 0) {
if ((ow_rmt.rx = platform_rmt_allocate( 1 )) >= 0) {
#ifdef OW_DEBUG
ESP_LOGI("ow", "RMT TX channel: %d", ow_rmt.tx);
ESP_LOGI("ow", "RMT RX channel: %d", ow_rmt.rx);
#endif
rmt_config_t rmt_tx;
ow_rmt.tx = RMT_CHANNEL_7;
rmt_tx.channel = ow_rmt.tx;
rmt_tx.gpio_num = gpio_num;
rmt_tx.mem_block_num = 1;
@ -117,13 +126,10 @@ static int onewire_rmt_init( uint8_t gpio_num )
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;
if (rmt_config( &rmt_tx ) == ESP_OK) {
if (rmt_driver_install( rmt_tx.channel, 0, 0 ) == ESP_OK) {
rmt_config_t rmt_rx;
ow_rmt.rx = RMT_CHANNEL_6;
rmt_rx.channel = ow_rmt.rx;
rmt_rx.gpio_num = gpio_num;
rmt_rx.clk_div = 80;
@ -132,16 +138,29 @@ static int onewire_rmt_init( uint8_t gpio_num )
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;
if (rmt_config( &rmt_rx ) == ESP_OK) {
if (rmt_driver_install( rmt_rx.channel, 512, 0 ) == ESP_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
@ -223,7 +242,8 @@ int platform_onewire_reset( uint8_t gpio_num, uint8_t *presence )
if (rx_items) {
if (rx_size >= 1 * sizeof( rmt_item32_t )) {
#if 0
#ifdef OW_DEBUG
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].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 );
if (rx_items) {
#if 0
#ifdef OW_DEBUG
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].level1, rx_items[i].duration1);
}
#endif
if (rx_size >= num * sizeof( rmt_item32_t )) {
for (int i = 0; i < num; i++) {
read_data >>= 1;

58
components/platform/rmt.c Normal file
View File

@ -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;
}
}