0
votes

I'm trying to port nRF24L01 library to ESP32 (I'm using esp-idf). All I have to do is to replace functions that are using spi. That's how I do this:

static uint8_t *create_tx(uint8_t cmd, const uint8_t *buff, uint8_t length){
    uint8_t *tx = (uint8_t*)heap_caps_malloc(64, MALLOC_CAP_DMA);
    tx[0] = cmd;
    if(buff != NULL)
        memcpy(tx + 1, buff, length);
    return tx;
}

uint8_t NRF24L01::Read(uint8_t cmd, uint8_t *pBuff, uint8_t length){
    uint8_t *recv = (uint8_t*)heap_caps_malloc(64, MALLOC_CAP_DMA);
    uint8_t *send = (uint8_t*)heap_caps_malloc(64, MALLOC_CAP_DMA);
    memset(send, NRF24_CMD_NOP, 32);

    send[0] = cmd;

    CSPIBuilder builder;
    spi_transaction_t t =
        builder
        .SetLength(length)
        .SetTx(send)
        .SetRx(recv)
        .build();

    spi_device_transmit(m_Spi, &t);

    memcpy(pBuff, recv + 1, length);
    uint8_t status = recv[0];
    free(recv);
    free(send);
    return status;
}
uint8_t NRF24L01::Write(uint8_t cmd, uint8_t *pBuff, uint8_t length){
    uint8_t *txBuff = create_tx(cmd, pBuff, length);
    uint8_t *rxBuff = (uint8_t*)heap_caps_malloc(64, MALLOC_CAP_DMA);
    memset(rxBuff, NRF24_CMD_NOP, length + 1);

    spi_transaction_t t = 
        CSPIBuilder()
        .SetLength(length)
        .SetTx(txBuff)
        .SetRx(rxBuff)
        .build();


    spi_device_transmit(m_Spi, &t);
    free(txBuff);
    uint8_t status = rxBuff[0];
    free(rxBuff);
    return status;
}

class CSPIBuilder{
public:
    CSPIBuilder(){
        memset(&t, 0, sizeof(t));
    }

    CSPIBuilder &UseTxData() { t.flags |= SPI_TRANS_USE_TXDATA; return *this; }
    CSPIBuilder &UseRxData() { t.flags |= SPI_TRANS_USE_RXDATA; return *this; }
    CSPIBuilder &UseTRxData() { t.flags |= SPI_TRANS_USE_TXDATA | SPI_TRANS_USE_RXDATA; return *this; }

    CSPIBuilder &SetLength(uint8_t length) { t.length = (length + 1) * 8; return *this; }
    CSPIBuilder &SetRxLength(uint8_t rxLength) { t.rxlength = (rxLength + 1) * 8; return *this; }

    CSPIBuilder &SetTx(uint8_t *txBuffer) { t.tx_buffer = txBuffer; return *this; }
    CSPIBuilder &SetRx(uint8_t *rxBuffer) { t.rx_buffer = rxBuffer; return *this; }

    spi_transaction_t build() {return t;}
private:
    spi_transaction_t t;
};

But... There is nothing works. SPI wires are connected properly. I can read status via spi. I cannot confirm that it is correct value, but it's changing every time I distonnect GND from nRF24L01. So I think wiring is OK.

What's wrong with this code?

1

1 Answers

1
votes

Well, as I understood there are big problems with native esp-idf spi api. The solution was to replace full spi transaction (more than 1 byte) by small transactions byte-by-byte (since spi api can send only first byte correctly (in my case atleast)). Also I have to control CS pin by myself and respect datasheet's timings

The result of these manipulations is my own library (haha) Feel free to use it