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

TWI nrf_frv_twi_tx without response

nrf52832 softdevice S132 SDK15 custom board

TWI instance

TX(nrf_drv_twi_tx) failed, slave device is AD5252 digital potentiometer, i want to send data to the potentiometer, it works when i combine gpiote and twi, it is a simple example.

but i combine twi with ble_app_uart and saadc,it doesn't work.

in sdk_config.h i enable NRFX_TWI_ENABLED and TWI_ENABLED, i use  twi0 instance  without easyDMA.

i also enable UART \ UARTE \GPIOTE \SAADC (triggered by PPI+timer) for other modules.

i can't get any twi error when i debug, SDA and SCL have already been pulled up.

twi register shows:

the STARTTX task is not triggered, and what event can trigger this task?

i doubt if the PPI channel twi use collides with other event/task ?

Any reply will be appreciated!!!

  • Hi

    Are you able to see what happens (if anything) on the TWI lines (with a logic analyzer for example)? Do they go low at any point or is the problem that the TWI doesn't start sending at all? In that case, can you show me the snippet of code where you initialize your TWI, please?

    Best regards,

    Simon

  • thanks for your reply!

    unfortunately i don't have a logic analyzer, so i use a oscilloscope to capture SCL and SDA signals , they runs fast  so i can only get part of it.

    they go low when i press the button(start transmission), i may get the whole waveform with a logic analyzer.

    "TWI TXD byte sent" is differnt form what i said before,i sent two bytes,  the EVENTS_TXDSENT is 1(not 0), and turns 0 when the nrd_drv_twi_tx finished.

    the following is part of my code:

    #define TWI_INSTANCE_ID0     0
    static volatile bool m_xfer_done = false;
    static const nrf_drv_twi_t m_twi0 = NRF_DRV_TWI_INSTANCE(TWI_INSTANCE_ID0);
    
    void twi_handler(nrf_drv_twi_evt_t const * p_event, void * p_context)
    {
        switch (p_event->type)
        {
            case NRF_DRV_TWI_EVT_DONE:
    			NRF_LOG_INFO("Error event: NRF_DRV_TWI_EVT_DONE.");
                m_xfer_done = true;
                break;
    				
    		case NRF_DRV_TWI_EVT_ADDRESS_NACK:
                NRF_LOG_INFO("Error event: NACK received after sending the address.");
                break;
            
            case NRF_DRV_TWI_EVT_DATA_NACK:
                NRF_LOG_INFO("Error event: NACK received after sending a data byte.");
                break;
    
            default:
                break;
        }
    }
    
    void twi0_init (void)
    {
        ret_code_t err_code;
    
        const nrf_drv_twi_config_t twi0_ADA5252_config = {
           .scl                = 25,
           .sda                = 27,
           .frequency          = NRF_DRV_TWI_FREQ_100K,
           .interrupt_priority = 2,
           .clear_bus_init     = false
        };
        err_code = nrf_drv_twi_init(&m_twi0, &twi0_ADA5252_config, twi_handler, NULL);
        APP_ERROR_CHECK(err_code);
        nrf_drv_twi_enable(&m_twi0);
    }
    
    void bsp_event_handler(bsp_event_t event)//°å¼¶´¦Àíʼþ
    {
        uint32_t err_code;
        switch (event)
        {
    		case BSP_EVENT_KEY_3:
    		    nrf_gpio_pin_toggle(LED_4);
    			NRF_LOG_INFO("channel auto nulling begin");
    			NRF_LOG_INFO ("enable register: %x\n", NRF_TWI0->ENABLE);
    			channel_nulling();	
    		    break;
            default:
                break;
        }
    }
    
    static void buttons_leds_init(bool * p_erase_bonds)
    {
        bsp_event_t startup_event;
    
        uint32_t err_code = bsp_init(BSP_INIT_LEDS | BSP_INIT_BUTTONS, bsp_event_handler);
        APP_ERROR_CHECK(err_code);
    
        err_code = bsp_btn_ble_init(NULL, &startup_event);
        APP_ERROR_CHECK(err_code);
    
        *p_erase_bonds = (startup_event == BSP_EVENT_CLEAR_BONDING_DATA);
    }
    
    void channel_nulling(void)
    {
    	ret_code_t err_code;					
    	nrf_gpio_cfg_output(WP1);
        nrf_gpio_pin_set(WP1);	
    	uint8_t salve1_addr = 0x2C;
    	uint8_t reg[2];
    	reg[1]=0x01;
    	reg[0]=0xFF;
    	err_code = nrf_drv_twi_tx(&m_twi0, salve1_addr, reg, sizeof(reg), false);
    	APP_ERROR_CHECK(err_code);
    	while(m_xfer_done == false){}
    //	NRF_LOG_INFO ("Start TWI transmit sequence: %x\n", NRF_TWI0->TASKS_STARTTX);	
    //	NRF_LOG_INFO ("Address used in the TWI transfer: %x\n", NRF_TWI0->ADDRESS);
    //	NRF_LOG_INFO ("TXD register: %x\n", NRF_TWI0->TXD);
    //	NRF_LOG_INFO ("Pin select for SCL and SDA: %x %x\n ", NRF_TWI0->PSELSCL,NRF_TWI0->PSELSDA);
    //	NRF_LOG_INFO ("TWI TXD byte sent: %x\n", NRF_TWI0->EVENTS_TXDSENT);
    //	NRF_LOG_INFO ("TWI error: %x\n", NRF_TWI0->EVENTS_ERROR);
    //	NRF_LOG_INFO ("Enable interrupt : %x\n", NRF_TWI0->INTENSET);	
    //	NRF_LOG_INFO ("Stop TWI transaction : %x\n", NRF_TWI0->TASKS_STOP);			
    //	NRF_LOG_INFO("brifge num.1 nulling end");
    	nrf_gpio_pin_clear(WP1);
    }
    
    int main(void)
    {
        // Initialize.
    	bool erase_bonds;
    	twi0_init();
        uart_init();
        log_init();
        timers_init();
        buttons_leds_init(&erase_bonds);
    	fds_test();
    	
        power_management_init();
        ble_stack_init();
        gap_params_init();
        gatt_init();
        services_init();
        advertising_init();
        conn_params_init();
    	conn_evt_len_ext_set();
    
         // Start execution.
        printf("\r\nUART started.\r\n");
        NRF_LOG_INFO("Debug logging for UART over RTT started.");
        advertising_start();
    	tx_power_set();
    		
        // Enter main loop.
        for (;;)
        {
            idle_state_handle();
        }
    }
    
    

    i get  NRF_DRV_TWI_EVT_DONE and m_xfer_done = true, but there is no respones of slave device.

    i didn't use SPIM/SPIS/TWIM/SPI/TWIS which have same base address with TWI either.

    thanks for your suggestions in advance!

  • I get same result when i change SCL and SDA to 22 and 23;

    i get error below when i change SCL and SDA to 9 and 10

    (already CONFIG_NFCT_PINS_AS_GPIOS);

  • Hi

    Ok, so what you want is to get a response from the peripheral (slave) when you've sent two bytes to it, correct? It seems like the TWI master is behaving normally the way you describe it below. What you'll have to find out is how you can get a response from the slave device upon a successful transfer. Seeing as that is an AD5252 you'll have to check out their data sheets/user guides or contact AD to find out how to do this, as we're not familiar with their products.

    As for the error you're seeing when using pins 9 and 10, that is because when the NFC pins are defined as GPIOs, they will operate with restricted frequency, and therefore won't be able to do high-frequency tasks such as SPI and TWI transfers. Please use any of the other GPIOs for serial communication.

    Best regards,

    Simon

  • thanks for your reply!

    i don't think the problem is caused by the slave device,in my first example, it works well without softdevice

    my first example:

    //main.c
    #define WP       11   
      
    void RDAC_init(void);    
    void twi0_init (void);    
    
    int main(void)
    {
    	nrf_gpio_cfg_output(WP);
    	nrf_gpio_pin_set(WP);   
    	twi0_init();            
    	RDAC_init();            
    	LED_Init();            
    	EXIT_KEY_Init();       
    	while(1)
    	{
    	}
    }
    
    //TWI 
    #define TWI_INSTANCE_ID0   0
    static const nrf_drv_twi_t m_twi0 = NRF_DRV_TWI_INSTANCE(TWI_INSTANCE_ID0);
    
    /**@brief TWI initialization.
     */
    void twi0_init (void)
    {
        const nrf_drv_twi_config_t twi0_ADA5252_config = 
    		{
           .scl                = 25,//25
           .sda                = 27,//27
           .frequency          = NRF_DRV_TWI_FREQ_100K,
           .interrupt_priority = 2,
           .clear_bus_init     = false 
        };
        nrf_drv_twi_init(&m_twi0, &twi0_ADA5252_config, NULL, NULL);
        nrf_drv_twi_enable(&m_twi0);
    }
    
    uint8_t salve_addr = 0x2C;
    void RDAC_init()      
    {
    	uint8_t reg1[2];
    	reg1[0]=0x01;
    	reg1[1]=0x80;
    	uint8_t reg2[2];
    	reg2[0]=0x03;
    	reg2[1]=0x80;	
    	nrf_drv_twi_tx(&m_twi0, salve_addr, reg1, sizeof(reg1), false);
    	nrf_drv_twi_tx(&m_twi0, salve_addr, reg2, sizeof(reg2), false);
    }
    void RDAC1_INC(int i)
    {
    	uint8_t reg[2];
        reg[0]=0x01;
        reg[1]=i;
    	nrf_drv_twi_tx(&m_twi0, salve_addr, reg, sizeof(reg), false);
    }
    void RDAC1_DEC(int i)
    {
    	uint8_t reg[2];
    	reg[0]=0x01;
    	reg[1]=i;
    	nrf_drv_twi_tx(&m_twi0, salve_addr, reg, sizeof(reg), false);
    }
    void RDAC3_INC(int j)
    {
    	uint8_t reg[2];
    	reg[0]=0x03;
    	reg[1]=j;
    	nrf_drv_twi_tx(&m_twi0, salve_addr, reg, sizeof(reg), false);
    }
    void RDAC3_DEC(int j)
    {
    	uint8_t reg[2];
    	reg[0]=0x03;
    	reg[1]=j;
    	nrf_drv_twi_tx(&m_twi0, salve_addr, reg, sizeof(reg), false);
    }
    
    //GPIOTE
    void EXIT_KEY_Init(void)
    {
    	nrf_gpio_pin_set(13);
    	nrf_gpio_pin_set(14);
    	nrf_gpio_pin_set(15);
    	nrf_gpio_pin_set(16);
    	nrf_gpio_cfg_input(KEY_0,NRF_GPIO_PIN_PULLUP);
    	nrf_gpio_cfg_input(KEY_1,NRF_GPIO_PIN_PULLUP);
    	nrf_gpio_cfg_input(KEY_2,NRF_GPIO_PIN_PULLUP);
    	nrf_gpio_cfg_input(KEY_3,NRF_GPIO_PIN_PULLUP);   
        NVIC_EnableIRQ(GPIOTE_IRQn);
        NRF_GPIOTE->CONFIG[0] =  (GPIOTE_CONFIG_POLARITY_HiToLo << GPIOTE_CONFIG_POLARITY_Pos)
                               | (13 << GPIOTE_CONFIG_PSEL_Pos) 
                               | (GPIOTE_CONFIG_MODE_Event << GPIOTE_CONFIG_MODE_Pos);
        NRF_GPIOTE->INTENSET  = GPIOTE_INTENSET_IN0_Set << GPIOTE_INTENSET_IN0_Pos;
    	NRF_GPIOTE->CONFIG[1] =  (GPIOTE_CONFIG_POLARITY_HiToLo << GPIOTE_CONFIG_POLARITY_Pos)
                               | (14<< GPIOTE_CONFIG_PSEL_Pos)  
                               | (GPIOTE_CONFIG_MODE_Event << GPIOTE_CONFIG_MODE_Pos);
        NRF_GPIOTE->INTENSET  = GPIOTE_INTENSET_IN1_Set << GPIOTE_INTENSET_IN1_Pos;
        NRF_GPIOTE->CONFIG[2] =  (GPIOTE_CONFIG_POLARITY_HiToLo << GPIOTE_CONFIG_POLARITY_Pos)
                               | (15 << GPIOTE_CONFIG_PSEL_Pos)  
                               | (GPIOTE_CONFIG_MODE_Event << GPIOTE_CONFIG_MODE_Pos);
        NRF_GPIOTE->INTENSET  = GPIOTE_INTENSET_IN2_Set << GPIOTE_INTENSET_IN2_Pos;
    	NRF_GPIOTE->CONFIG[3] =  (GPIOTE_CONFIG_POLARITY_HiToLo << GPIOTE_CONFIG_POLARITY_Pos)
                               | (16<< GPIOTE_CONFIG_PSEL_Pos)  
                               | (GPIOTE_CONFIG_MODE_Event << GPIOTE_CONFIG_MODE_Pos);
        NRF_GPIOTE->INTENSET  = GPIOTE_INTENSET_IN3_Set << GPIOTE_INTENSET_IN3_Pos;
    }
    
    int i=128,j=128,k=0;
    void GPIOTE_IRQHandler(void)
    {
       if(nrf_gpio_pin_read(KEY_0)== 0)
    	{
    		if ((NRF_GPIOTE->EVENTS_IN[0] == 1) && (NRF_GPIOTE->INTENSET & GPIOTE_INTENSET_IN0_Msk))
    		{
    			NRF_GPIOTE->EVENTS_IN[0] = 0;
    			LED1_Toggle();
    			i++;
    			k=i<=256?i:256;
    			if(k==0)
    			{i=k;}
    			RDAC3_INC(k);
    		}
        } 
    	if(nrf_gpio_pin_read(KEY_1)== 0)
    	{
    		if ((NRF_GPIOTE->EVENTS_IN[1] == 1) && (NRF_GPIOTE->INTENSET & GPIOTE_INTENSET_IN1_Msk))
            {
                NRF_GPIOTE->EVENTS_IN[1] = 0; 
    			LED2_Toggle();
    			i--;
    			k=i>=0?i:0;
    			if(k==0)
    			{i=k;}
    			RDAC3_DEC(k);
    		 }
    	}
        if(nrf_gpio_pin_read(KEY_2)== 0)
    	{
    		if ((NRF_GPIOTE->EVENTS_IN[2] == 1) && (NRF_GPIOTE->INTENSET & GPIOTE_INTENSET_IN0_Msk))
            {
                NRF_GPIOTE->EVENTS_IN[2] = 0; 
    			LED3_Toggle();
    			j++;
    			k=j<=256?j:256;
    			if(k==0)
    			{j=k;}
    			 RDAC1_INC(k);
    		}
        } 
    	if(nrf_gpio_pin_read(KEY_3)== 0)
    	{
    		if ((NRF_GPIOTE->EVENTS_IN[3] == 1) && (NRF_GPIOTE->INTENSET & GPIOTE_INTENSET_IN1_Msk))
            {
                NRF_GPIOTE->EVENTS_IN[3] = 0; 
    		    LED4_Toggle();
    			j--;
    			k=j>=0?j:0;
    		    if(k==0)
    			{j=k;}			
    			RDAC1_DEC(k);
            }
    	}
    }
    

    codes about TWI are same in two example including twi_init, salve address, SCL,SDA......

    but in my second example, i use ble_app_uart, add a nus service, saadc.....and softdevice

    this is my whole project:

    it seems like that the master send two bytes out but the slave doesn't get them, or the master doesn't send bytes successfully at all. I am totally confused, could you please give me some suggestions?

    As for pins 9 and 10, i got it.

    Thanks!

Related