Page 1 of 1

SPI warning "Allocate RX buffer for DMA"

Posted: Sun Nov 04, 2018 6:33 pm
by Prasad
Hi Everyone,

I was using MAX6675 chip to read out temperature from k-type thermocouple.However all works fine but i'm keep getting "I (8421) spi_master: Allocate RX buffer for DMA" warning whenever i transmit a transaction. Maybe some of you guys already encountered similar warning before and found any workaround and wanna share your findings?

I understand that disabling DMA(By passing 0 as the DMA channel) will stop throwing this warning, but in my design i'm using two MAX6675 chips, so i'm stuck using two different DMA channels.



Thanks in advance!

Here is my simplified complete code,

Code: Select all

#include "freertos/FreeRTOS.h"
#include "esp_wifi.h"
#include "esp_system.h"
#include "esp_event.h"
#include "esp_event_loop.h"
#include "nvs_flash.h"
#include "driver/gpio.h"
#include "driver/spi_master.h"
#include "esp_log.h"

static const char *TAG = "test";

#define MAX6675_MISO 4
#define MAX6675_SCK 27
#define MAX6675_CS 25
#define MAX6675_SPI_HOST HSPI_HOST
#define GPIO_OUTPUT_PIN_MASK  ((1<<MAX6675_CS))

static spi_device_handle_t spi_handle; // SPI handle.

esp_err_t event_handler(void *ctx, system_event_t *event)
{
    return ESP_OK;
}

static void init_gpio() {
    gpio_config_t io_conf;
    
    io_conf.intr_type = GPIO_PIN_INTR_DISABLE; //disable interrupt
    io_conf.mode = GPIO_MODE_OUTPUT; //set as output mode
    io_conf.pin_bit_mask = GPIO_OUTPUT_PIN_MASK; //bit mask of the pins
    io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE; //disable pull-down mode
    io_conf.pull_up_en = GPIO_PULLUP_DISABLE;   //disable pull-up mode
    ESP_LOGD(TAG, "gpio_config");
    gpio_config(&io_conf); //configure GPIO with the given settings
    
}

void readMax6675() {
    
    float temp=0.0;
    uint16_t data,rawtemp;
    spi_bus_config_t bus_config;
    spi_device_interface_config_t dev_config;
    spi_transaction_t trans_word;
    
    ESP_LOGE(TAG, "readMax6675 start");
    
    gpio_set_level(MAX6675_CS, 1); // MAX6675_CS
    bus_config.sclk_io_num   = MAX6675_SCK; // CLK
    bus_config.mosi_io_num   = -1; // MOSI not used
    bus_config.miso_io_num   = MAX6675_MISO; // MISO
    bus_config.quadwp_io_num = -1; // not used
    bus_config.quadhd_io_num = -1; // not used
    ESP_LOGE(TAG, "spi_bus_initialize");
    
    ESP_ERROR_CHECK(spi_bus_initialize(MAX6675_SPI_HOST, &bus_config, 2));
    
    dev_config.address_bits     = 0;
    dev_config.command_bits     = 0;
    dev_config.dummy_bits       = 0;
    dev_config.mode             = 0; // SPI_MODE0
    dev_config.duty_cycle_pos   = 0;
    dev_config.cs_ena_posttrans = 0;
    dev_config.cs_ena_pretrans  = 0;
    dev_config.clock_speed_hz   = 1000000;  // 1 MHz
    dev_config.spics_io_num     = -1; // CS External
    dev_config.flags            = 0; // SPI_MSBFIRST
    dev_config.queue_size       = 100;
    dev_config.pre_cb           = NULL;
    dev_config.post_cb          = NULL;
    ESP_LOGE(TAG, "spi_bus_add_device");
    
    ESP_ERROR_CHECK(spi_bus_add_device(MAX6675_SPI_HOST, &dev_config, &spi_handle));
    
    while (1) {
        
        gpio_set_level(MAX6675_CS, 0);
        vTaskDelay(400 / portTICK_RATE_MS);
        
        rawtemp = 0x000;
        data = 0x000;
        
        trans_word.flags     = 0;
        trans_word.length    = 8 * 2; // Total data length, in bits NOT number of bytes.
        trans_word.rxlength  = 0; // (0 defaults this to the value of ``length``)
        trans_word.tx_buffer = &data;
        trans_word.rx_buffer = &rawtemp;
        ESP_ERROR_CHECK(spi_device_transmit(spi_handle, &trans_word));
        
        gpio_set_level(MAX6675_CS, 1);
        
        temp = ((((rawtemp & 0x00FF) << 8) | ((rawtemp & 0xFF00) >> 8))>>3)*25;
        
        ESP_LOGI(TAG, "readMax6675 spiReadWord=%x temp=%.2f",rawtemp,temp/100);
        
        vTaskDelay(900 / portTICK_PERIOD_MS);
    }
}

void app_main(void)
{
    nvs_flash_init();
    ESP_ERROR_CHECK( esp_event_loop_init(event_handler, NULL));
    
    init_gpio();
    readMax6675();
}

Prasad.

Re: SPI warning "Allocate RX buffer for DMA"

Posted: Mon Nov 05, 2018 12:21 am
by WiFive
The rx and tx buffer need to be length of multiples of 32 bits to avoid heap corruption.

Re: SPI warning "Allocate RX buffer for DMA"

Posted: Mon Nov 05, 2018 7:24 am
by Prasad
Thanks mate. But that wasn't the case here. I've got away with this,

Code: Select all

uint16_t dataone[1] = {0};

Code: Select all

trans_word.rx_buffer = dataone;

Code: Select all

rawtemp = *(uint32_t *)dataone;
rx_buffer size is same.

Re: SPI warning "Allocate RX buffer for DMA"

Posted: Mon Nov 05, 2018 7:50 am
by WiFive
Ok but it was probably luck your variable landed on a word boundary and it doesn't stop dma controller from corrupting data adjacent to your variable.

Re: SPI warning "Allocate RX buffer for DMA"

Posted: Mon Nov 05, 2018 8:07 am
by Prasad
Actually MAX6675 spits out 16bits per transaction, So that wasn't a prediction. However i'm new to DMA controller and let me know if i was doing anything wrong. Thanks again mate.