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

iic error NRF_ERROR_NO_MEM with app_sched_event_put

hi 

i want to use iic in my project ,and i add iic func to my project refrence project twi_sensor.

the code of iic like this:

	i2c_config_t iic_config=
	{
		.scl_pin = I2C_CLK_PIN,
		.sda_pin = I2C_SDA_PIN,
		.freq    = I2C_SPEED_400K,
	};
void am_app_i2c_init (i2c_config_t i2c_config)
{
    ret_code_t err_code;

		nrf_drv_twi_frequency_t fre_table[]=
		{
			NRF_DRV_TWI_FREQ_100K,
			NRF_DRV_TWI_FREQ_250K,
			NRF_DRV_TWI_FREQ_400K,
		};
	
    const nrf_drv_twi_config_t twi_config = {
       .scl                = i2c_config.scl_pin,
       .sda                = i2c_config.sda_pin,
       .frequency          = fre_table[i2c_config.freq],
       .interrupt_priority = APP_IRQ_PRIORITY_HIGH,
       .clear_bus_init     = false
    };

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

    nrf_drv_twi_enable(&m_twi);
}

void am_i2c_send_data(uint8_t addr,uint8_t const * p_data, uint8_t length, bool no_stop)
{
    ret_code_t err_code;

    err_code = nrf_drv_twi_tx(&m_twi, addr, p_data, length, no_stop);
    APP_ERROR_CHECK(err_code);
    while (m_xfer_done == false);

}

I call the api in the main 

	port_i2c_init();
		
	port_i2c_send(0xaa , data,  10);

then compile and download the hex to the chip,but the log show like this:

00> <error> app: ERROR 4 [NRF_ERROR_NO_MEM] at ..\..\..\..\..\..\components\libraries\timer\app_timer2.c:181
00> 
00> PC at: 0x0003817F

the code of app_timer2.c:181 is 

uint32_t err_code = app_sched_event_put(&timer_event,
sizeof(timer_event),
scheduled_timeout_handler);

some para like this:

#define NRF_QUEUE_ENABLED 1

#define SCHED_QUEUE_SIZE                    20                                         /**< Maximum number of events in the scheduler queue. */

i try change the  SCHED_QUEUE_SIZE   to 40 and change the ram ,it is  no effect. so what should i do to solve this problem ?

Parents
  • void port_i2c_send(uint8_t addr,uint8_t *p_data, uint8_t length)
    {

    am_i2c_send_data( addr, p_data,length, 0 );

    }


    void port_i2c_read(uint8_t device_addr,uint8_t word_addr,uint8_t *p_data, uint8_t length)
    {

    am_i2c_read_data( device_addr, word_addr, p_data, length );

    }

  • i find the NRF_DRV_TWI_EVT_DONE of twi_handler can never comming by set the breakpoint be after "NRF_DRV_TWI_EVT_DONE:" in project twi_sensor, i try to comment the code "while (m_xfer_done == false);",it can work ,and i can see the wave by logic anlyzer:

    so,now my confuse is why the event NRF_DRV_TWI_EVT_DONE of twi_handler will not comming ?and there if any 

    potentially dangerous when send large data and the code comment "while (m_xfer_done == false)"?

  • hi,thank for you reply,when i realize the problem of ack,connect to the iic device, and the iic work well.but now i try to send iic data in a timer handler,i open the  APP_SCHEDULER_ENABLED 1.  and i init the usb in my project.so i dont kown why i send the data in the timer handler will report 

    ERROR 4 [NRF_ERROR_NO_MEM] at ..\..\..\..\..\..\components\libraries\timer\app_timer2.c:181

    this is my code

    //扫描定时器回调
    void led_scan_timer_handler(void * p_context)
    {
    	disp_scan();
    	
    //stream_prase(stream_page.para,led_data);
    	
    }
    //定时器初始化
    void led_scan_timer_init(void)
    {
        
    	  ret_code_t err_code;
        err_code = app_timer_create(&m_led_scan_timer_id,
                                    APP_TIMER_MODE_REPEATED,
                                    led_scan_timer_handler);
        APP_ERROR_CHECK(err_code);
    }
    //启动定时器
    void led_scan_timer_start(void )
    {
        ret_code_t err_code;
    
        err_code = app_timer_start(m_led_scan_timer_id, LED_FLASH_INTERVAL, NULL);
        APP_ERROR_CHECK(err_code);
    
    }
    //关闭定时器
    void led_scan_timer_stop(void)
    {
        ret_code_t err_code;
    
        err_code = app_timer_stop(m_led_scan_timer_id);
        APP_ERROR_CHECK(err_code);
    }

    void am_i2c_send_data(uint8_t addr,uint8_t const * p_data, uint8_t length, bool no_stop)
    {
        ret_code_t err_code;
    	
        err_code = nrf_drv_twi_tx(&m_twi, addr, p_data, length, no_stop);
    //		iic_printf("err_code  == %d ",err_code);
        APP_ERROR_CHECK(err_code);
        while (m_xfer_done == false);	//没有器件调试的时候暂时不使用
    		m_xfer_done = false;
    		//while(err_code == NRF_ERROR_BUSY);//等待传输完成
    	
    
    }
    
    
    void port_i2c_send(uint8_t addr,uint8_t *p_data, uint8_t length)
    {
    	#if (SOC_TYPE ==NRF_52832)
    
    	#elif (SOC_TYPE ==NRF_52840)
    	
    	am_i2c_send_data( addr,  p_data,length, 0 );
    	
    		#else
    	#endif
    }

    void disp_scan(void)
    {
    	
    	uint8_t need_flash=0;
    	/*
    	if(!disp_control.valid)
    		return;
    	*/
    	
    	
    	//控制速度   显示间隔: 50+(101-speed)*10  ms
    	if(disp_control.time_count%(LED_MIN_INTERVAL_MS+LED_SCAN_BASE_MS*(100-disp_control.disp_page->speed))==0)
    	{
    		//数据解析
    		if(disp_control.disp_page->value_prase!=NULL)
    		{
    			need_flash = disp_control.disp_page->value_prase(disp_control.disp_page->para,led_data);
    		}
    		
    		
    		//定时器是否需要关闭
    		if(need_flash)
    		{
    			
    		}
    		else
    		{
    			led_scan_timer_stop();
    			//关闭定时器
    		}
    		
    		
    		//led 显示函数
    	//	disp_frame_data( led_data,disp_control.disp_page->lightness);
    		
    		
    		//for test
    		uint8_t data=0x20;
    		port_i2c_send(0x74 ,&data,  1);
    		
    	}
    }

  • i test the problem by code 

    		uint8_t data=0x20;
    		port_i2c_send(0x74 ,&data,  1);

    send iic data and report.what shuold i modify for this problem ?i guess mybe rtc config

  • Hi,

    The send function will become blocking if the 'm_xfer_done' flag for some reason is not getting cleared, and in that case, prevent the scheduler queue from being processed. To see if this could be the reason in this case, can you try to comment the "while (m_xfer_done == false)" line in the send function and see if the problem persists.

  • i know your means,and i try to do as you say, comment the "while (m_xfer_done == false)" will result in another problem,the twi have no enough time to send all the data before new send call comming.and it report

     00> <error> app: ERROR 17 [NRF_ERROR_BUSY] at ..\..\..\am_app\am_driver\I2C\am_app_i2c.c:79

     

    so if there is some way to avoid this problem ,for example,send the big data in the main loop?

  • It sounds like you have to increase the timer interval to give TWI time to complete the transaction between each call to the send function, or simply ignore the NRF_ERROR_BUSY error when it occurs.

Reply Children
  • i try to increse the interval ,it is effective .but i need a key scan timer when i flash my led(control one frame led need 25ms to send iic data) .so the problem is the keyboard 's key scan interval should less than 10 ms . when  the key scan timeout comming ,if the system work for send iic data .the system bad.

    so my confuse is

    1.my iic data more than 600 bytles at once sending,so if i ignore the NRF_ERROR_BUSY error.will i lose data?

    2.if there is some method to slove the confilt between the short key scan interval with data send of  25ms?

  • 1. The data will only be sent when the driver returns NRF_SUCCESS, so the app would need to account for that. Like, implement retries in cases where the driver returns NRF_ERROR_BUSY.

    2. If I'm understanding this correctly, the conflict is that the "key scan" and "data send" transaction can end up being initiated at the same time causing one of them to fail with the busy error. The trick would then be to make the code so that there always a certain amount of time between the transactions. Alternatively, use something like the TWI transaction manager to queue up multiple transactions.

  • thank for your reply.And your answer take me some mind to slove this problem.i find the pca10056 in my hand cant achieve 400k speed. i set the speed 400k,actually it is 206k .and i set it 250k,it work at 250k.first i tink my code have not set correctly.and than i modify the speed of project nRF5_SDK_16.0.0_98a08e2\examples\peripheral\twi_sensor

    the problem also occured. the 400k cant achieve.so is there any config i have not set correctly?

    the speed test on 400k speed set:

    the code i modify in the project twi_sensor:

    the speed test on 250k speed set:

  • I compiled the twi scanner example:

    \nRF5_SDK_15.3.0_59ac345\examples\peripheral\twi_scanner

    Then modified twi_init():

    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_DRV_TWI_FREQ_400K,
           .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_gpio_cfg_input(ARDUINO_SCL_PIN, NRF_GPIO_PIN_PULLUP);
        nrf_gpio_cfg_input(ARDUINO_SDA_PIN, NRF_GPIO_PIN_PULLUP);
    
        nrf_drv_twi_enable(&m_twi);
    }

    Can you repeat the same?

  • hi. thank for your reply .

    i try to modify the project as you say in

    nRF5_SDK_16.0.0_98a08e2\examples\peripheral\twi_scanner

    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_DRV_TWI_FREQ_400K,
           .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);
    }

    and the speed is also 200k,i use the chip is nrf52840.

    and in this QA,the nrf52840 may have the same problem, in the sdk 16.0,it will occur.

    devzone.nordicsemi.com/.../247002

Related