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

the problem of high frequency send iic data

hi,i want to control a led driver by frequency send iic data, i need send 600 bytles once at least  10ms each time ,and the 600 bytles send by 3times.send the 600 bytles need 24ms.i create a 10ms once timer,and in the end of the timer handler start the timer again.but now i find after run few mins the seeger will report the error:

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

and the chip cant work before reset.

at frist i guess the reson is the time of execute the 10ms timer handler is so long(24ms) that  reslut in the scheduler problem.but when try to replace the iic send api to nrf_delay_ms( 24); the problem will not occur.so it is obvious that the reson is the iic send action.

this is my code 

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//
void led_scan_timer_handler(void * p_context)
{
UNUSED_PARAMETER(p_context);
disp_scan();
// led_test();
//stream_prase(stream_page.para,led_data);
}
//
void led_scan_timer_init(void)
{
ret_code_t err_code;
/*
err_code = app_timer_init();
APP_ERROR_CHECK(err_code);
*/
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

disp_frame_data() in the disp_scan() is my iic send api

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//led
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 SCAN_DEBUG
//
if(disp_control.disp_page->value_prase!=NULL)
{
need_flash = disp_control.disp_page->value_prase(disp_control.disp_page->para,led_data);
// stream_prase(stream_page.para, led_data);
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
void disp_frame_data(uint8_t (*led_data)[RGB_LED_X_NUM][3],uint8_t lightness_per)
{
frame_data_to_chip( led_data);
disp_one_chip_data( AW_CHIP_INDEX_0, chip0_data,lightness_per);
disp_one_chip_data( AW_CHIP_INDEX_1, chip1_data,lightness_per);
disp_one_chip_data( AW_CHIP_INDEX_2, chip2_data,lightness_per);
}
static void disp_one_chip_data(uint8_t device_index,uint8_t *pwm_data,uint8_t brightness)
{
static uint8_t last_brightness[AW_CHIP_MAX_NUM] ={0};
if(last_brightness[device_index]!=brightness)
{
set_chip_led_brightness( chip_table[device_index], brightness);
}
set_led_pwm_brightness(chip_table[device_index], pwm_data);
last_brightness[device_index] = brightness;
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

when i comment the code 

Fullscreen
1
disp_frame_data( led_data,/*disp_control.disp_page->lightness*/10);
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

and replace by the code 

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
port_delay_ms(24);
void port_delay_ms(uint32_t ms)
{
#if (SOC_TYPE ==NRF_52832)
nrf_delay_ms( ms );
#elif (SOC_TYPE ==NRF_52840)
nrf_delay_ms( ms );
#endif
}
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

the problem will not occur.

so i dont konw if the twi cant send data frequency ? and what should i do to slove this problem?

  • Hi,

    From the location of the error, it looks like you are using the app_timer with the application scheduler library (APP_TIMER_CONFIG_USE_SCHEDULER). Most likely the frequent transfers are causing the application to not process the scheduler queue fast enough, causing the NO_MEM error when the scheduler queue is full. You could try increasing the scheduler queue size in the scheduler initialization (second parameter to APP_SCHED_INIT()).

    It may also be a better option to push the interrupt handling to the scheduler, to process it in the way that the events come in. That way, the lengthy interrupt handler will not prevent other events from being handled. See the application scheduler tutorial for more details.

    Best regards,
    Jørgen 

  • Hi,

    at first ,i guess the reson is as your description.

    1. but i try to replace the iic transfer api to cpu delay api,it is also 24ms,but it will not occur the error report.so if it is because the scheduler queue is full.the cpu delay will also result in this problem.

    2.i try to place the iic sned api in the main loop ,and it will also occur the problem ,report the NO_MEM .as my understand,if it is the scheduler queue is full.the main loop operation wiil not report this erro.

    3.i try to increase the SCHED_QUEUE_SIZE.the condition  has been improved. but the chip will also report the erro or down that cant printf any info and cant find the advertisement.

  • iic data, i need send 600 bytles once at least  10ms each time

    Not possible with an I²C bus: 600 bytes (4800 bits) * 100 Hz = 480.000 Hz. The TWI busses on NRF chips can only go up to 400 kHz.

    Does your LED driver support SPI?

  • i know your means,so i use the single shot timer.i restart the single timer after 600 bytles send over(24ms after).so the logic of the timer like this:

    |    10ms     |     send data(24ms)   |     10ms      |      send data (24ms)    | ...

    but it also occur this problem .so i suspect i was the twi's problem at hight frequency sned.because i test cpu delay funcation. it also delay 24ms,but there is no report and chip run well.

    i also consider driver it by spi (high transfer speed),but the driver cant support spi .tank for your reply.

       

  • im sure it is the problem of hw iic.i exchange the hw iic api to soft iic api ,and now it work well , will not report the erro.

1 2