I2C driver work_queue function

Hi all.

I am trying to add a new i2c driver for a i2c supporting device, however it just runs one cycle and not works repeatedly. Since I’ve made the driver similar to the mb12xx driver, there is a ‘cycle’ function should be frequently called by ‘work_queue’ function. However, after the cycle function run once and then it is never called again.

work_queue(HPWORK,
&_work,
(worker_t)&UWB::cycle_trampoline,
this,
USEC2TICK(_cycling_rate));

Some tips will be very thanksful.

M. Kim

You’ll need another call at the end of the cycle to put the next iteration in the work_queue.

Hi.

Thank you for your answer, but the work_queue function I mentioned above is the one I put the end of my cycle function.

What’s in cycle? Are you able to debug and step through? It’s likely not getting through to the end of cycle to be called again. We might be able to provide more help if you post your code somewhere like github.

void
UWB::cycle(){

/* perform collection */
if (OK != collect(&_coordinates)) {
	DEVICE_DEBUG("collection error");
	/* if error restart the measurement state machine */
	start();
	return;
}


/* Perform measurement */
if (OK != measure()) {
	DEVICE_DEBUG("measure error sonar adress %d", _index_counter);
}


work_queue(HPWORK,
		   &_work,
		   (worker_t)&UWB::cycle_trampoline,
		   this,
		   USEC2TICK(_cycling_rate));

}

int
UWB::measure(){

int ret;

/*
 * Send the command to begin a measurement.
 */
uint8_t alg_cmd[2] = {};
uint8_t pos_state[1] = {0};
uint8_t cmd = POZYX_POS_ALG;
uint8_t dimension = 1;
uint8_t algorithm = 0x00;
uint8_t alg_options = (dimension<<4) | algorithm;
alg_cmd[0] = cmd;
alg_cmd[1] = alg_options;

ret = transfer(&alg_cmd[0], 2, nullptr,0);

cmd = POZYX_INT_STATUS;

ret = transfer(&cmd, 1, &_int_status,1);

cmd = POZYX_DO_POSITIONING;

ret = transfer(&cmd,1,&pos_state[0],1);


if (OK != ret) {
	perf_count(_comms_errors);
	DEVICE_DEBUG("i2c::transfer returned %d", ret);
	return ret;
}

ret = OK;

return ret;

}

int
UWB::collect(uwb_pos_s *coordinates){
int ret = -EIO;
perf_begin(_sample_perf);

uint8_t cmd = POZYX_POS_X;

ret = transfer(&cmd,1,&coord[0],sizeof(uwb_pos_s));
memcpy(coordinates, &coord[0], sizeof(uwb_pos_s));

if (ret < 0) {
	DEVICE_DEBUG("error reading from sensor: %d", ret);
	perf_count(_comms_errors);
	perf_end(_sample_perf);
	return ret;
}

if (_uwb_pos_topic != nullptr) {
	orb_publish(ORB_ID(uwb_pos), _uwb_pos_topic, &coordinates);
}


	/* notify anyone waiting for data */
poll_notify(POLLIN);

ret = OK;

perf_end(_sample_perf);
return ret;

}

void
UWB::read(){

if (OK != measure()) {
	//warnx("measure error");
}
//warnx("measure");

usleep(400000);

if (OK != collect(&_coordinates)) {
	//warnx("collection error");
	return;
}

	//warnx("collect:  x = %d, y = %d, z = %d",_coordinates.x,_coordinates.y,_coordinates.z);

}

Above is my cycle function and related functions. When I run ‘read’ function on nsh, it worked fine. Therefore, I guess there is no probem with ‘measure’ and ‘collect’ functions.

Read is measure, then collect, but it’s the opposite order in cycle. Is the collect returning from the cycle?
Are you able to debug and see if it’s returning? If not you could just put printfs throughout cycle.