teco-kit / Jennisense

A modularized open hardware, sensor drivers based on contiki for the JN51xx µController. A detailed description and how-to can be found in the wiki (see link below).
http://github.com/teco-kit/Jennisense/wiki
19 stars 16 forks source link

Can't read lightlevel-sensor (tsl2550) #3

Open aicastell opened 10 years ago

aicastell commented 10 years ago

Hello.

I'm working with a Jennic JN5148 on a jndevkit platform. I want to read lightlevel-sensor on the PCB board. To do that, I developed a very simple test (based on imu-serial.c).

include "contiki.h"

include "dev/temperature-sensor.h"

include "dev/lightlevel-sensor.h"

include "dev/leds.h"

include

PROCESS(my_process, "My process"); AUTOSTART_PROCESSES(&my_process); PROCESS_THREAD(my_process, ev, data) { static struct sensors_sensor *s;

PROCESS_BEGIN();

/* make sure that the sensor process is running! */
process_start(&sensors_process, NULL);
PROCESS_PAUSE();

printf("Activating sensors\r\n");

/* activate all sensors */
for (s=sensors_first(); s; s=sensors_next(s)) {
    printf("configuring...\r\n");
    if (s->configure(SENSORS_ACTIVE,1)) {
        printf("%s activated.\r\n", s->type);
    }
    else while (1) {
        PROCESS_YIELD();
        printf("%s not activated.\r\n", s->type);
    }
}

printf("While(1)...\r\n");

while(1)
{
    int a;

    PROCESS_YIELD_UNTIL(ev==sensors_event);
    s = (struct sensors_sensor*) data;

    if (s==&lightlevel_sensor) {
        a = s->value(LIGHT_VALUE_VISIBLE_CENTILUX);
        printf("lig:%d\n",a);
    }
}

PROCESS_END();

}

However, this test doesn't work. This is the output I get on the console debug:

Tentative link-local IPv6 address fe80:0000:0000:0000:fdff:ffff:ffff:ffff
Activating sensors configuring...
reset due to watchdog Tentative link-local IPv6 address fe80:0000:0000:0000:fdff:ffff:ffff:ffff Activating sensors configuring... reset due to watchdog Tentative link-local IPv6 address fe80:0000:0000:0000:fdff:ffff:ffff:ffff Activating sensors configuring... reset due to watchdog Tentative link-local IPv6 address fe80:0000:0000:0000:fdff:ffff:ffff:ffff Activating sensors

At file contiki-main.c (jndevkit platform) there is a "AppColdStart" function that seems the main function, and starts a watchdog:

/* enable watchdog on JN5148, there is none on JN5139 */

ifdef BA2

watchdog_start();

endif

I suppose each time I call PROCESS_YIELD, contiki should reset that watchdog, but it seems not to work as expected.

Can some of you point to me in the right direction to solve this issue?

pscholl commented 10 years ago

answered on contiki-dev: I assume you're compiling for the wrong platform.

aicastell commented 10 years ago

$ make TARGET=jndevkit myprocess.u ba-elf-objcopy myprocess.jndevkit -O binary myprocess.jndevkit.hex

sudo jenprog -c ftdi myprocess.jndevkit.hex

jenprog myprocess.jndevkit.hex
waiting for /dev/ttyUSB0..done
waiting until queues are emtpy..done
0%..10%..20%..30%..40%..50%..60%..70%..80%..90%..done - 8.42 kb/s - writing mac address and key..done
rm myprocess.jndevkit.hex

Maybe my PCB is not exactly a "jndevkit" platform? On the board I see Jennic (C) 2006 DR1048 V1.1. I'll take a look to the lightlevel_sensor driver implementation (printfs all around) to discover what's happening.

pscholl commented 10 years ago

That's odd, maybe try to enable the debugging in i2c.c. Then you'll see what's happening on the I²C bus. I assume the system hangs somewhere there. Are you using the I²C pins for something different?

aicastell commented 10 years ago

I just have tested three different boards from Jennic with exactly the same behabiour. This is the development kit I am working with, maybe this can help:

http://uk.farnell.com/jennic/jn5148-ek010/eval-kit-jn5148-zigbee-pro-2-4ghz/dp/1739333

So, I haven't modified the PCB at all...

I have simplified my test to focus the attention on the tsl2550 light sensor. This is the new version:

include "contiki.h"

include "dev/temperature-sensor.h"

include "dev/lightlevel-sensor.h"

include "dev/leds.h"

include stdio.h

/---------------------------------------------------------------------------/ PROCESS(myprocess, "My process"); /---------------------------------------------------------------------------_/ AUTOSTART_PROCESSES(&my_process);

PROCESS_THREAD(my_process, ev, data) { static struct sensors_sensor *s;

PROCESS_BEGIN();

printf("My process starts here...\r\n");

/* make sure that the sensor process is running! */
process_start(&sensors_process, NULL);
PROCESS_PAUSE();

printf("Activating sensors\r\n");

/* activate sensors */
SENSORS_ACTIVATE(lightlevel_sensor);
PROCESS_PAUSE();

while(1)
{
    printf("While(1)...\r\n");
    int a;

    PROCESS_YIELD_UNTIL(ev==sensors_event);
    s = (struct sensors_sensor*) data;

    if (s==&lightlevel_sensor) {
        a = s->value(LIGHT_VALUE_VISIBLE_CENTILUX);
        printf("lig:%d\n",a);
    } else {
        printf("Unknown sensor\n");
    }
}

PROCESS_END();

} /---------------------------------------------------------------------------/

With the I2C DEBUG enabled, and some extra debug I added on the tsl2550 configure() function, this is the output I'm getting on the debug console:

configure_tsl2550(SENSORS_HW_INIT,0)
My process starts here...
Activating sensors
configure_tsl2550(SENSORS_ACTIVE,1)
i2c: to 0x72 start, 1 written, 0 read
reset due to watchdog

Previous logs are repeated several times, until it stops with this output:

configure_tsl2550(SENSORS_HW_INIT,0)
My process starts here...
Activating sensors
configure_tsl2550(SENSORS_ACTIVE,1)
i2c: to 0x72 start, 1 written, 0 read
i2c: to 0x72 failed, 1 written, 0 read in 1584 ticks
i2c: to 0x72 completed, 1 written, 0 read in 230161 ticks (rc:0x3,)
While(1)...

Here it hangs forever (waiting a sensor event that obviously is not received).

Should I define some extra DEBUG to continue debugging this issue deeply?

aicastell commented 10 years ago

TSL2550 datasheet says the SMBus slave address of sensor is hardwired internally as 011 1001. I2C logs are showing address 0x72 (that is, TSL_ADDR macro defined at tsl2550-sensor.c). I have tested addressing that new address (0x39h), just to test. And this is the output EACH time I power off/on the board:

configure_tsl2550(SENSORS_HW_INIT,0) My process starts here... Activating sensors configure_tsl2550(SENSORS_ACTIVE,1) i2c: to 0x39 start, 1 written, 0 read i2c: to 0x39 failed, 1 written, 0 read in 852 ticks While(1)...

Sensor event is never notified to the protothread. But at least, watchdog doesn't interrupt now... I suppose that has sense, because process is YIELD and Contiki has thread control.

Maybe if I was able to debug the code where the light sensor notifies Contiki kernel when it has data to send, I can see something else. What files could be useful to add more debugging information to trace this issue?

pscholl commented 10 years ago

0x72 is 0x39 shifted by one to the left (I²C addresses are 7-bit, the LSB indicates reading or writing). So 0x72 is correct, the watchdog does not reset because there is no device with address 0x39 on the bus, hence init fails and you're getting to your while(1) loop.

What might be happening on the system is the TSL2550 ack'ing that its on the bus and then the system waits to be able to write the next byte on the I²C bus. You could confirm this with an oscilloscope on the clock line and check if its being pulled down continuously.

Maybe the watchdog timeout is too small, try ruling that out by adding a 'watchdog_periodic()' call at the hanging loop at i2c.c:196 :

    i2c_process.needspoll = false;
  }

On Wed, Feb 19, 2014 at 12:38:54PM -0800, aicastell wrote:

TSL2550 datasheet says the SMBus slave address of sensor is hardwired internally as 011 1001. I2C logs are showing address 0x72 (that is, TSL_ADDR macro defined at tsl2550-sensor.c). I have tested addressing that new address (0x39h), just to test. And this is the output EACH time I power off/on the board:

configure_tsl2550(SENSORS_HW_INIT,0) My process starts here... Activating sensors configure_tsl2550(SENSORS_ACTIVE,1) i2c: to 0x39 start, 1 written, 0 read i2c: to 0x39 failed, 1 written, 0 read in 852 ticks While(1)...

Sensor event is never notified to the protothread. But at least, watchdog doesn't interrupt now... I suppose that has sense, because process is YIELD and Contiki has thread control.

Maybe if I was able to debug the code where the light sensor notifies Contiki kernel when it has data to send, I can see something else. What files could be useful to add more debugging information to trace this issue?


Reply to this email directly or view it on GitHub: https://github.com/teco-kit/Jennisense/issues/3#issuecomment-35545529

aicastell commented 10 years ago

I have restored I2C light sensor address to 0x72, and added a watchdog_period() call at the i2c.c file, such as you suggested. Now watchdog is not an issue yet, so your suggestion works, fixing the watchdog problem. One step closer, and happy to see some progress with this issue! :)

However, system is hanging again. This is the output now:

configure_tsl2550(SENSORS_HW_INIT,0) My process starts here... Activating sensors configure_tsl2550(SENSORS_ACTIVE,1) i2c: to 0x72 start, 1 written, 0 read HERE HANGS...

After trying some power off/on tests, output has changed a bit, (again hanging, but showing new information).

configure_tsl2550(SENSORS_HW_INIT,0) My process starts here... Activating sensors configure_tsl2550(SENSORS_ACTIVE,1) i2c: to 0x72 start, 1 written, 0 read i2c: to 0x72 completed, 1 written, 0 read in 1578 ticks (rd:0x3,) configure_tsl2550(TSL_CONFIGURE_RANGE,24) i2c: to 0x72 start, 1 written, 0 read HERE HANGS...

I have added more debugging information at i2c.c file:

pending = true; while (pending) { if (i2c_process.needspoll) { process_post_synch(&i2c_process, PROCESS_EVENT_POLL, NULL); i2c_process.needspoll = false; }
watchdog_periodic(); // watchdog bugfix?? printf("Restarting watchdog\n"); // MORE DEBUGGING INFO }

And code seems to hang inside this while loop, because nobody is negating "pending" flag (I see "Restarting watchdog" hundreds of times...) Is this a bug? How can i fix this?

aicastell commented 10 years ago

I have solved the issue!! I just have changed the I2C bus speed, replacing this line (i2c.c):

vAHI_SiConfigure(true,true,I2C_400KHZ_FAST_MODE);

for this one:

vAHI_SiConfigure(true,true,I2C_10KHZ_SLOW_MODE);

I also have changed the while(1) on my application because sensor never notifies my YIELDed protothread. Instead, I created a 1 second timer, and read the sensor each second. Thats all!!

I'm so happy!! Thank you very much Mr. Philipp for your advises, they were very helpful :))