No output with RMT peripheral
Posted: Thu Sep 09, 2021 5:39 am
I'm trying to use the RMT peripheral to bit-bang an array to a GPIO pin, but I'm not getting any output. I've gotten the expected output from the WS2812 driver example and used that example as a staring place for my implementation. I think the part that I'm having trouble understanding is the definition of rmt_item_t. If anyone can see what I'm doing wrong, please help! The code is below.
Code: Select all
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "driver/rmt.h"
#include "led_strip.h"
#include <string.h>
#define RMT_TX_CHANNEL RMT_CHANNEL_0
#define RMT_TX_PIN 21
#define DATA_LEN 10
static void IRAM_ATTR rmt_sample_to_rmt_t(const void *src, rmt_item32_t *dest, size_t src_size, size_t wanted_num, size_t *translated_size, size_t *item_num)
{
if (src == NULL || dest == NULL)
{
*translated_size = 0;
*item_num = 0;
return;
}
const rmt_item32_t bit0 = {{{500, 0, 0, 0}}}; //Logical 0
const rmt_item32_t bit1 = {{{500, 1, 0, 0}}}; //Logical 1
size_t size = 0;
size_t num = 0;
uint8_t *psrc = (uint8_t *)src;
rmt_item32_t *pdest = dest;
// loop over bytes in src array
while (size < src_size && num < wanted_num)
{
for (int i = 0; i < 8; i++)
{
// LSB first
if (*psrc & (1 << (i)))
pdest->val = bit1.val;
else
pdest->val = bit0.val;
num++;
pdest++;
}
size++;
psrc++;
}
}
void app_main(void)
{
rmt_config_t rmt_video_config = {.rmt_mode = RMT_MODE_TX,
.channel = RMT_TX_CHANNEL,
.gpio_num = RMT_TX_PIN,
.clk_div = 16, // 80MHz / 16 = 5MHz
.mem_block_num = 1,
.flags = 0,
.tx_config = {
.carrier_freq_hz = 22220 * 2,
.carrier_level = RMT_CARRIER_LEVEL_HIGH,
.idle_level = RMT_IDLE_LEVEL_LOW,
.carrier_duty_percent = 50,
.carrier_en = false,
.loop_en = false,
.idle_output_en = true}};
// Configure and install RMT driver
ESP_ERROR_CHECK(rmt_config(&rmt_video_config));
ESP_ERROR_CHECK(rmt_driver_install(rmt_video_config.channel, 0, 0));
ESP_ERROR_CHECK(rmt_translator_init(rmt_video_config.channel, rmt_sample_to_rmt_t));
// fill an array with alternating zeros and ones
uint8_t data[DATA_LEN] = {0};
for (int i = 0; i < DATA_LEN; i++)
data[i] = i % 2;
while (1)
{
rmt_write_sample(rmt_video_config.channel, (const uint8_t *)&data, DATA_LEN, true);
rmt_wait_tx_done(rmt_video_config.channel, 1000);
vTaskDelay(pdMS_TO_TICKS(1000));
}
}