无法使用 ESP32 (esp-idf) 处理 nRF24L01+
Can't handle nRF24L01+ using ESP32 (esp-idf)
我正在尝试将 nRF24L01 library 移植到 ESP32(我正在使用 esp-idf)。我所要做的就是替换正在使用 spi 的函数。我就是这样做的:
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;
};
但是...没有任何效果。 SPI 线连接正确。我可以通过 spi 读取状态。我无法确认它是正确的值,但每次我从 nRF24L01 断开 GND 时它都会改变。所以我觉得接线没问题。
这段代码有什么问题?
嗯,据我所知,原生 esp-idf spi api 存在很大问题。解决方案是用逐字节的小事务替换完整的 spi 事务(超过 1 个字节)(因为 spi api 只能正确发送第一个字节(至少在我的情况下))。此外,我必须自己控制 CS 引脚并遵守数据表的时序
这些操作的结果是我自己的library(哈哈)
放心使用吧
我正在尝试将 nRF24L01 library 移植到 ESP32(我正在使用 esp-idf)。我所要做的就是替换正在使用 spi 的函数。我就是这样做的:
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;
};
但是...没有任何效果。 SPI 线连接正确。我可以通过 spi 读取状态。我无法确认它是正确的值,但每次我从 nRF24L01 断开 GND 时它都会改变。所以我觉得接线没问题。
这段代码有什么问题?
嗯,据我所知,原生 esp-idf spi api 存在很大问题。解决方案是用逐字节的小事务替换完整的 spi 事务(超过 1 个字节)(因为 spi api 只能正确发送第一个字节(至少在我的情况下))。此外,我必须自己控制 CS 引脚并遵守数据表的时序
这些操作的结果是我自己的library(哈哈) 放心使用吧