I am trying to control Digi XBee module (XB-8XR-DMRM-001) by ESP32-S3 chip via SPI interface (I'm using ESP IDF).

Example of my code is below; also an oscillogram of MOSI, MISO, CLK and nCS data lines, and I have no success, in any combination (like changing logic from MSB to LSB, or reversing byte array, or pulling nCS low by myself, or adding extra delays after and before pulling nCS low and so on).

Here like the page of datasheet to this module with an example of one of the request type. Actually, the problem is that I'm every time receiving response 0xFF, which is confirmed by MISO line, which every time pulled high, there is no activity on it. At the same time that chips work perfectly via UART with Digi's proprietary software called "XCTU", but I need to make it work exactly with SPI interface.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/spi_master.h"
#include "driver/gpio.h"
#include "sdkconfig.h"
#include "esp_log.h"

#define PIN_NUM_CS GPIO_NUM_11

static const char TAG[] = "main";

void app_main(void)
    ESP_LOGI(TAG, "Initializing bus SPI%d...", SPI_HOST);
    spi_bus_config_t buscfg = {
        .miso_io_num = PIN_NUM_MISO,
        .mosi_io_num = PIN_NUM_MOSI,
        .sclk_io_num = PIN_NUM_CLK,
    ESP_ERROR_CHECK(spi_bus_initialize(SPI_HOST, &buscfg, SPI_DMA_CH_AUTO));

    spi_device_handle_t devhandle;
    spi_device_interface_config_t devcfg = {
        .clock_speed_hz = 1000000UL,
        .mode = 0,
        .spics_io_num = PIN_NUM_CS,
        .queue_size = 10,
    ESP_ERROR_CHECK(spi_bus_add_device(SPI_HOST, &devcfg, &devhandle));
    void *p = heap_caps_malloc(sizeof(uint8_t) * 32, MALLOC_CAP_DMA);
    for (int i = 0; i < 32; i++)
        *((uint8_t *)p + i * sizeof(uint8_t)) = 0;
    uint8_t data_tx[] = {0x7E, 0x00, 0x0E, 0x10, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFE, 0x00, 0x00, 0xF1};
    spi_transaction_t t = {
        .tx_buffer = &data_tx,
        .rx_buffer = p,
        .length = sizeof(data_tx) * 8,
    while (1)
        ESP_ERROR_CHECK(spi_device_transmit(devhandle, &t));
        for (int i = 0; i < 32; i++)
            printf("%i ", *((uint8_t *)p + i * sizeof(uint8_t)));
        vTaskDelay(1000 / portTICK_PERIOD_MS);

Yellow - CLK, red - MISO Yellow - CLK, red - MISO

Yellow - CLK, red - MOSI Yellow - CLK, red - MOSI

Yellow - CLK, red - nCS Yellow - CLK, red - nCS

  • \$\begingroup\$ A hint, just found in the datasheet: "To force SPI mode on through-hole devices, hold DOUT/DIO13 low while resetting the device until SPI_ATTN asserts." \$\endgroup\$
    – Jens
    Sep 23 at 0:28


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Browse other questions tagged or ask your own question.