This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Read register issue using nrf52 TWI

Hi ,

I have recently bought a nRF5232 PCA10040 development kit and i am trying to interface nRf52832 development kit(Master) with AS3955(slave) over twi. I tested the twi_scanner example and AS3955 responds with correct slave address(i.e 0x50). Now i am trying to read a single register from AS3955. I see that for twi in order to read a register we first have to send SLAVE ADDRESS and REGISTER ADDRESS using nrf_drv_twi_tx driver function and then we have to read using nrf_drv_twi_rx driver function. The AS3955 should respond with register value 0x01(as that is the default value present at REGISTER ADDRESS). But the device does not respond with correct register value and always says 0xFF. Please any help/guidance would be appreciated as i new to this environment and i am stuck on this for a couple of days now. I have attached the code and timing diagram for the slave. image description

#include <stdio.h> 
#include "boards.h"
#include "app_util_platform.h"
#include "app_error.h"
#include "nrf_drv_twi.h"
#include "nrf_delay.h" 

#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "nrf_log_default_backends.h"

/* /SS GPIO for AS3955 (This pin should be kept low for AS3955 in order to activate i2c on the chip)*/
#define SLAVE_SELECT_GPIO 2

/* TWI instance ID. */
#define TWI_INSTANCE_ID     0

 #define AS3955_ADDRESS			0x50
/* TWI instance. */
static const nrf_drv_twi_t m_twi = NRF_DRV_TWI_INSTANCE(TWI_INSTANCE_ID);
uint8_t register_address = 0x3E;    //Address of the register to be read
    
/**
 * @brief TWI initialization.
 */
void twi_init (void)
{
    ret_code_t err_code;    
    const nrf_drv_twi_config_t twi_config = {
       .scl                = ARDUINO_SCL_PIN,
       .sda                = ARDUINO_SDA_PIN,
       .frequency          = NRF_TWI_FREQ_100K,
       .interrupt_priority = APP_IRQ_PRIORITY_HIGH,
       .clear_bus_init     = false
    };

    err_code = nrf_drv_twi_init(&m_twi, &twi_config, NULL, NULL);
    APP_ERROR_CHECK(err_code);

    nrf_drv_twi_enable(&m_twi);
}
    
/**
 * @brief Function for main application entry.
 */
int main(void)
{
    ret_code_t err_code;
    uint8_t sample_data;
    bool detected_device = false;

    APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
    NRF_LOG_DEFAULT_BACKENDS_INIT();

	nrf_gpio_cfg_output(SLAVE_SELECT_GPIO);
	nrf_gpio_pin_write(SLAVE_SELECT_GPIO, 0);
    twi_init();

	err_code = nrf_drv_twi_tx(&m_twi, AS3955_ADDRESS, &register_address, 1, true);
	if(err_code == NRF_SUCCESS)
	{
		NRF_LOG_INFO("Device Address and Register Address(3 bit mode+ 5 bit reg address sent");
	}
	NRF_LOG_FLUSH();
		

	err_code = nrf_drv_twi_rx(&m_twi, AS3955_ADDRESS, &sample_data, sizeof(sample_data));
	if (err_code == NRF_SUCCESS)
	{
		NRF_LOG_INFO("The Register read = 0x%x", sample_data);
	}
		
	NRF_LOG_FLUSH();
	nrf_gpio_pin_write(SLAVE_SELECT_GPIO, 1);

    while (true)
    {
        /* Empty loop. */
    }
}

/** @} */
Parents
  • Hi martin,

    Sorry for the late reply, I was caught up with some other work. And Thank you the register read i think is working fine. In order to enable I2C on AS3955, /SS pin of AS3955 should be pulled low which i was already doing in the code using

    nrf_gpio_cfg_output(SLAVE_SELECT_GPIO);
    nrf_gpio_pin_write(SLAVE_SELECT_GPIO, 0);
    

    but looks like i have to add a delay of 10ms(or less) in order to stabilize I2C pins(i am actually not sure why). Adding the delay of 10ms after writing to GPIO actually worked for me.

    nrf_gpio_cfg_output(SLAVE_SELECT_GPIO);
    nrf_gpio_pin_write(SLAVE_SELECT_GPIO, 0);
    nrf_delay_ms(10);
    

    The default value at register address 0x3E(0x1E) is 0x01(according to datasheet) but for me it reads as 0x02. But i tried reading other registers and all read correct values.

Reply
  • Hi martin,

    Sorry for the late reply, I was caught up with some other work. And Thank you the register read i think is working fine. In order to enable I2C on AS3955, /SS pin of AS3955 should be pulled low which i was already doing in the code using

    nrf_gpio_cfg_output(SLAVE_SELECT_GPIO);
    nrf_gpio_pin_write(SLAVE_SELECT_GPIO, 0);
    

    but looks like i have to add a delay of 10ms(or less) in order to stabilize I2C pins(i am actually not sure why). Adding the delay of 10ms after writing to GPIO actually worked for me.

    nrf_gpio_cfg_output(SLAVE_SELECT_GPIO);
    nrf_gpio_pin_write(SLAVE_SELECT_GPIO, 0);
    nrf_delay_ms(10);
    

    The default value at register address 0x3E(0x1E) is 0x01(according to datasheet) but for me it reads as 0x02. But i tried reading other registers and all read correct values.

Children
No Data
Related