Hi. I don't believe this question would be strictly be considered a duplicate. I have seen posts discussing the same issue I'm having, but resolutions don't appear to solve my problem and are fairly stale overall.
I was hoping someone could check out my configuration below. I'm using an nrf52840-dk with ncs 1.8.0, but trying to utilize nrfx drivers.
I'm simply reading and writing to an encoder counter IC (ls7366r). Unfortunately, my RX buffers are not being populated with information upon reading; however, in looking at the traffic with my logic analyzer, everything appears to be working as expected, which leads me to believe this is a configuration issue on my end. I should note, using the Zephyr APIs, this works fine (for frequencies under 2Mhz), so it is not a hardware issue: I just wanted to apply nrfx drivers, as zephyr apis aren't allowing me to use any frequencies over 2MHz (still trying to figure that one out).

The logic analyzer traffic looks good and I believe all signal timings meet the requirements defined the IC's data sheet (https://lsicsi.com/datasheets/LS7366R.pdf). As the encoder turns, the count increments and is viewable within the analyzer, which is illustrated in the screen shot provided (read command byte 0x60 followed by two bytes of count data); however, this information doesn't seem to write to my counter rx buffer. This also applies to my reading back my register configs.
I am aware of that the first X bytes of an rx buffer would not contain my count information as that byte(s) would be attributed to the TX traffic. In looking at log prints and debugging, the RX buffer elements all remain zero.
Thank you
#include <zephyr.h>
#include <drivers/gpio.h>
#include <nrfx_gpiote.h>
#include <nrfx_ppi.h>
#include <nrfx_spim.h>
#include <drivers/nrfx_errors.h>
#include <logging/log.h>
// #define HIGH_DRIVE
#define COUNTER_1X_QUAD 0x01
#define COUNTER_2X_QUAD 0x02
#define COUNTER_4X_QUAD 0x03
#define COUNTER_MODE_24 0x01
#define COUNTER_MODE_16 0x02
#define COUNTER_MODE_8 0x03
#define WRITE_MDR0 0x88
#define READ_MDR0 0x48
#define READ_MDR1 0x50
#define WRITE_MDR1 0x90
#define READ_CNTR 0x60
#define WRITE_DTR 0x98
#define CLR_STR 0x30
#define CLR_CNTR 0x20
#define LOAD_CNTR 0xE0
#define SCK_PIN (47)
#define MISO_PIN (46)
#define MOSI_PIN (45)
#define CS_PIN (44)
static volatile bool spi_ready = true;
uint32_t position;
static const nrfx_spim_t spi_instance = NRFX_SPIM_INSTANCE(3);
static nrfx_spim_config_t spi_config = {
.sck_pin = SCK_PIN,
.mosi_pin = MISO_PIN,
.mosi_pin = MOSI_PIN,
.ss_pin = CS_PIN,
.ss_active_high = false,
.frequency = NRF_SPIM_FREQ_1M,
// .frequency = SPIM_FREQUENCY_FREQUENCY_K125,
.mode = NRF_SPIM_MODE_0,
.bit_order = NRF_SPIM_BIT_ORDER_MSB_FIRST,
.orc = 0xFF,
.irq_priority = NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY
};
LOG_MODULE_REGISTER(nrfx_encoder, LOG_LEVEL_INF);
void setMDRX(uint8_t mdr_write, uint8_t mdr_command, const char* reg_name)
{
int err;
uint8_t tx_buffer[2] = {mdr_write, mdr_command};
uint8_t rx_buffer[] = {0x00}; //no feedback expected
if (spi_ready == true)
{
spi_ready = false;
nrfx_spim_xfer_desc_t transfer = {
.p_tx_buffer = tx_buffer,
.tx_length = sizeof(tx_buffer),
.p_rx_buffer = rx_buffer,
.rx_length = sizeof(rx_buffer)
};
err = nrfx_spim_xfer(&spi_instance, &transfer, 0);
if (err != NRFX_SUCCESS)
{
LOG_ERR("Write %s Error: %08x", reg_name, err);
return;
}
while(spi_ready == false)
{
__WFE();
}
} else
{
LOG_ERR("SPI not Ready");
}
}
void readMDRX(uint8_t read_reg_cmd, const char* reg_name)
{
int err;
uint8_t tx_buffer[] = { read_reg_cmd };
uint8_t rx_buffer[2]; //get one byte back from MRD0 and/or MDR1
if(spi_ready == true)
{
spi_ready = false;
nrfx_spim_xfer_desc_t transfer = {
.p_tx_buffer = tx_buffer,
.tx_length = sizeof(tx_buffer),
.p_rx_buffer = rx_buffer,
.rx_length = sizeof(rx_buffer)
};
err = nrfx_spim_xfer(&spi_instance, &transfer, 0);
if (err != NRFX_SUCCESS)
{
LOG_ERR("%s Read Error: %08x", reg_name, err);
return;
}
while(spi_ready == false)
{
__WFE();
}
LOG_INF("%s Contents: %i", reg_name, rx_buffer[1]);
} else
{
LOG_ERR("SPI not Ready");
}
}
void clearRegs(uint8_t reg_clear_command)
{
int err;
uint8_t tx_buffer[] = {reg_clear_command};
uint8_t rx_buffer[] = {0x00}; //no feedback expected
if(spi_ready == true)
{
spi_ready = false;
nrfx_spim_xfer_desc_t transfer = {
.p_tx_buffer = tx_buffer,
.tx_length = sizeof(tx_buffer),
.p_rx_buffer = rx_buffer,
.rx_length = sizeof(rx_buffer)
};
err = nrfx_spim_xfer(&spi_instance, &transfer, 0);
if (err != NRFX_SUCCESS)
{
LOG_ERR("Clear Error: %08x", err);
return;
}
while(spi_ready == false)
{
__WFE();
}
} else
{
LOG_ERR("SPI not Ready");
}
}
void readEncoder(void)
{
int err;
uint8_t tx_buffer[] = { READ_CNTR };
uint8_t count_buffer[3]; // should get two bytes of data given my MDR1 settings (count_buffer[0] will be 0xFF from tx)
if(spi_ready == true)
{
spi_ready = false;
nrfx_spim_xfer_desc_t transfer = {
.p_tx_buffer = tx_buffer,
.tx_length = sizeof(tx_buffer),
.p_rx_buffer = count_buffer,
.rx_length = sizeof(count_buffer)
};
err = nrfx_spim_xfer(&spi_instance, &transfer, 0);
if (err != NRFX_SUCCESS)
{
LOG_ERR("Count Error: %08x", err);
return;
}
while(spi_ready == false)
{
__WFE();
}
for (int i = 0; i <sizeof(count_buffer); i++)
{
LOG_INF("count_buffer[%i] = %zx", i, count_buffer[i]);
}
// position = (count_buffer[0] << 8) + count_buffer[1];
// LOG_INF("Position: %i\n", position);
} else
{
LOG_ERR("SPI not Ready to Count");
}
}
static void spim_handler(nrfx_spim_evt_t const *p_event, void *p_context)
{
if (p_event->type == NRFX_SPIM_EVENT_DONE)
{
LOG_INF("transfer complete");
spi_ready = true;
}
}
void main(void)
{
LOG_INF("Configuring SPI");
nrfx_err_t err;
#ifdef HIGH_DRIVE
LOG_INF("High Drive");
nrf_gpio_cfg(CS_PIN,
NRF_GPIO_PIN_DIR_OUTPUT,
NRF_GPIO_PIN_INPUT_DISCONNECT,
NRF_GPIO_PIN_PULLUP,
NRF_GPIO_PIN_H0H1,
NRF_GPIO_PIN_NOSENSE);
nrf_gpio_cfg(SCK_PIN,
NRF_GPIO_PIN_DIR_OUTPUT,
NRF_GPIO_PIN_INPUT_DISCONNECT,
NRF_GPIO_PIN_PULLDOWN,
NRF_GPIO_PIN_H0H1,
NRF_GPIO_PIN_NOSENSE);
nrf_gpio_cfg(MOSI_PIN,
NRF_GPIO_PIN_DIR_OUTPUT,
NRF_GPIO_PIN_INPUT_DISCONNECT,
NRF_GPIO_PIN_PULLDOWN,
NRF_GPIO_PIN_H0H1,
NRF_GPIO_PIN_NOSENSE);
k_sleep(K_MSEC(100));
#endif
IRQ_CONNECT(SPIM3_IRQn, 0, nrfx_isr, nrfx_spim_3_irq_handler, 0);
irq_enable(SPIM3_IRQn);
err = nrfx_spim_init(&spi_instance, &spi_config, spim_handler, NULL);
if (err != NRFX_SUCCESS)
{
LOG_ERR("nrfx_spim_init error: %08x", err);
return;
}
k_sleep(K_MSEC(250));
clearRegs(CLR_STR);
clearRegs(CLR_CNTR);
setMDRX(WRITE_MDR0, COUNTER_1X_QUAD, "MDR0");
k_sleep(K_MSEC(250));
setMDRX(WRITE_MDR1, COUNTER_MODE_16, "MDR1");
readMDRX(READ_MDR0, "MDR0");
k_sleep(K_MSEC(250));
readMDRX(READ_MDR1, "MDR1");
while(1)
{
k_sleep(K_MSEC(2000));
readEncoder();
}
}// prj.conf CONFIG_LOG=y CONFIG_SPI=n CONFIG_NRFX_SPIM=y CONFIG_NRFX_SPIM3=y CONFIG_MAIN_STACK_SIZE=4096