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)"?

  • 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.

  • 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?

Reply
  • 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?

Children
Related