CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

I2C problem with sensor PAJ7620U2 [Solved]
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
ddevices



Joined: 15 Jun 2020
Posts: 13

View user's profile Send private message

I2C problem with sensor PAJ7620U2 [Solved]
PostPosted: Mon Jun 15, 2020 1:45 pm     Reply with quote

I have an I2C problem and any help would be very much appreciated. My chip is the PIC18LF2550 and compiler is PCWHD V5.093c. The I2C chip that I’m attempting to connect to is the PAJ7620U2 on DFRobot SEN0315 Gesture Sensor board. Correct pull ups are on I2C lines. Most of the code to communicate to the sensor is from DFRobot Wiki page and github (https://github.com/DFRobot/DFRobot_PAJ7620U2). I have this sensor working with Arduino, I know the sensor works and code is fundamentally correct. I am transferring it to the PIC.

I have an oscilloscope and can see 99% of the code is working, just one register is failing and locking up board. To configure the sensor you have to write 219 registers with parameters, one register locks up. Register 0x72, the Enable/Disable (0=Disable, 1=Enable). Below are code snippets that show the core of the problem. Configuration of chip:

Code:
#define __USB_PIC_PERIF__ 1
#include <18LF2550.h>
#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN,NOMCLR
#use delay(clock=48000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
#use i2c(master, sda=PIN_B0, scl=PIN_B1)  //have tried FORCE_HW OR SW, no difference


Configuration of PAJ is below, rewritten so it does not lock up:
Code:

int8 paj7620Init(void) {
    unsigned char i = 0;
    int8 ack;
    unsigned char data[2];
    ack = paj7620ReadReg(0x00,1,data);
    if(ack==1)
      printf("Wake up Failure %d\r",ack);
    else
      printf("Wake Up Good! %d\r",ack);
    delay_us(400);
    ack = paj7620ReadReg(0x00,1,data);
    if(ack==1)
      printf("Wake up Failure %d\r",ack);
    else
      printf("Wake Up Good! %d\r",ack);   
   
    paj7620SelectBank(0);
    paj7620SelectBank(0);
 
    for (i = 0; i < 219; i++) {                    //INIT_REG_ARRAY_SIZE   219
        data[0] = initRegisterArray[i][0];
        data[1] = initRegisterArray[i][1];
        //printf("%u %x %x\r",i,data[0],data[1]);   //shows correct data
        if(i != 210) ack = i2c_transfer_out(PAJ7620_write,data,2);  //210 fails!
        if(ack==1) printf("Init Failure %u\r",i);   
     }

    paj7620SelectBank(1);  //gesture flage reg in Bank1
    // paj7620WriteReg(0x65, 0xB7); // far mode 120 fps
    // paj7620WriteReg(0x65, 0x12);  // near mode 240 fps
    data[0]=0x65;
    data[1]=0xB7;
    ack = i2c_transfer_out(PAJ7620_write,data,2);
    if(ack==1) printf("Set Mode Failure \r");
   
    paj7620SelectBank(0);  //gesture flag reg in Bank0

    printf("Paj7620 initialize register finished.\r");
    return 0;
}




Below is main, heavily rewritten for diagnostic purposes:

Code:
void main() {
  int8 i, count;
  unsigned char data[2];
 
  setup_adc_ports ( NO_ANALOGS ) ;
  setup_adc( ADC_OFF ) ;
 
  set_tris_a( 0b11111111 ) ;
  #use fast_io( A )
  set_tris_b( 0b11111111 ) ;
  #use fast_io( B )
  set_tris_c( 0b10111110 ) ;

  for(i=0; i<10; i++)
   {
   LED1_OFF() ;
   delay_ms(100);
   LED1_ON();
   delay_ms(100);
   }
   
  SETUP_WDT( WDT_OFF ) ;
  SETUP_TIMER_0( T0_OFF ) ;
  SETUP_TIMER_1( T1_DISABLED ) ;
  SETUP_TIMER_2( T2_DISABLED , 255 , 16 ) ;
  SETUP_TIMER_3( T3_DISABLED ) ;
 
  paj7620Init();
 

  paj7620SelectBank(1);  //0x72 is in bank 1
  count = 200;
  while ( TRUE ) { // main infinite while loop

    MAINLOOP_WAIT() ;   //10ms
 
   if(count>0) count--;
   if(count==1)
      {
      output_toggle(LED1);
 
      i2c_start();
      i2c_write(PAJ7620_write);     
      i2c_write(0x72);
      i2c_write(0x01);  //0x00 no lockup - 0x01 locks up (LED stops)
      i2c_stop();     
     
      count=200;  //2 secs
      }   

  }//end main infinite while loop


Normally writing to 0x72 is during the initialize of the chip but it would fail when reaching that register so I removed that one parameter and program would not lock up, verifying that was issue. The SelectBank sub provides confirmation to serial debug port, it is working with ACK received. Below shows the register configuration and is same as working Arduino code. This is very puzzling, any help appreciated.

Code:
ROM unsigned char initRegisterArray[219][2] = {   // Initial Gesture
    {0xEF, 0x00},
    {0x32, 0x29},
    {0x33, 0x01},
    {0x34, 0x00},
    {0x35, 0x01},
    {0x36, 0x00},
    {0x37, 0x07},
    {0x38, 0x17},
    {0x39, 0x06},
    {0x3A, 0x12},
    {0x3F, 0x00},
    {0x40, 0x02},
    {0x41, 0xFF},
    {0x42, 0x01},
    {0x46, 0x2D},
    {0x47, 0x0F},
    {0x48, 0x3C},
    {0x49, 0x00},
    {0x4A, 0x1E},
    {0x4B, 0x00},
    {0x4C, 0x20},
    {0x4D, 0x00},
    {0x4E, 0x1A},
    {0x4F, 0x14},
    {0x50, 0x00},
    {0x51, 0x10},
    {0x52, 0x00},
    {0x5C, 0x02},
    {0x5D, 0x00},
    {0x5E, 0x10},
    {0x5F, 0x3F},
    {0x60, 0x27},
    {0x61, 0x28},
    {0x62, 0x00},
    {0x63, 0x03},
    {0x64, 0xF7},
    {0x65, 0x03},
    {0x66, 0xD9},
    {0x67, 0x03},
    {0x68, 0x01},
    {0x69, 0xC8},
    {0x6A, 0x40},
    {0x6D, 0x04},
    {0x6E, 0x00},
    {0x6F, 0x00},
    {0x70, 0x80},
    {0x71, 0x00},
    {0x72, 0x00},
    {0x73, 0x00},
    {0x74, 0xF0},
    {0x75, 0x00},
    {0x80, 0x42},
    {0x81, 0x44},
    {0x82, 0x04},
    {0x83, 0x20},
    {0x84, 0x20},
    {0x85, 0x00},
    {0x86, 0x10},
    {0x87, 0x00},
    {0x88, 0x05},
    {0x89, 0x18},
    {0x8A, 0x10},
    {0x8B, 0x01},
    {0x8C, 0x37},
    {0x8D, 0x00},
    {0x8E, 0xF0},
    {0x8F, 0x81},
    {0x90, 0x06},
    {0x91, 0x06},
    {0x92, 0x1E},
    {0x93, 0x0D},
    {0x94, 0x0A},
    {0x95, 0x0A},
    {0x96, 0x0C},
    {0x97, 0x05},
    {0x98, 0x0A},
    {0x99, 0x41},
    {0x9A, 0x14},
    {0x9B, 0x0A},
    {0x9C, 0x3F},
    {0x9D, 0x33},
    {0x9E, 0xAE},
    {0x9F, 0xF9},
    {0xA0, 0x48},
    {0xA1, 0x13},
    {0xA2, 0x10},
    {0xA3, 0x08},
    {0xA4, 0x30},
    {0xA5, 0x19},
    {0xA6, 0x10},
    {0xA7, 0x08},
    {0xA8, 0x24},
    {0xA9, 0x04},
    {0xAA, 0x1E},
    {0xAB, 0x1E},
    {0xCC, 0x19},
    {0xCD, 0x0B},
    {0xCE, 0x13},
    {0xCF, 0x64},
    {0xD0, 0x21},
    {0xD1, 0x0F},
    {0xD2, 0x88},
    {0xE0, 0x01},
    {0xE1, 0x04},
    {0xE2, 0x41},
    {0xE3, 0xD6},
    {0xE4, 0x00},
    {0xE5, 0x0C},
    {0xE6, 0x0A},
    {0xE7, 0x00},
    {0xE8, 0x00},
    {0xE9, 0x00},
    {0xEE, 0x07},
    {0xEF, 0x01},
    {0x00, 0x1E},
    {0x01, 0x1E},
    {0x02, 0x0F},
    {0x03, 0x10},
    {0x04, 0x02},
    {0x05, 0x00},
    {0x06, 0xB0},
    {0x07, 0x04},
    {0x08, 0x0D},
    {0x09, 0x0E},
    {0x0A, 0x9C},
    {0x0B, 0x04},
    {0x0C, 0x05},
    {0x0D, 0x0F},
    {0x0E, 0x02},
    {0x0F, 0x12},
    {0x10, 0x02},
    {0x11, 0x02},
    {0x12, 0x00},
    {0x13, 0x01},
    {0x14, 0x05},
    {0x15, 0x07},
    {0x16, 0x05},
    {0x17, 0x07},
    {0x18, 0x01},
    {0x19, 0x04},
    {0x1A, 0x05},
    {0x1B, 0x0C},
    {0x1C, 0x2A},
    {0x1D, 0x01},
    {0x1E, 0x00},
    {0x21, 0x00},
    {0x22, 0x00},
    {0x23, 0x00},
    {0x25, 0x01},
    {0x26, 0x00},
    {0x27, 0x39},
    {0x28, 0x7F},
    {0x29, 0x08},
    {0x30, 0x03},
    {0x31, 0x00},
    {0x32, 0x1A},
    {0x33, 0x1A},
    {0x34, 0x07},
    {0x35, 0x07},
    {0x36, 0x01},
    {0x37, 0xFF},
    {0x38, 0x36},
    {0x39, 0x07},
    {0x3A, 0x00},
    {0x3E, 0xFF},
    {0x3F, 0x00},
    {0x40, 0x77},
    {0x41, 0x40},
    {0x42, 0x00},
    {0x43, 0x30},
    {0x44, 0xA0},
    {0x45, 0x5C},
    {0x46, 0x00},
    {0x47, 0x00},
    {0x48, 0x58},
    {0x4A, 0x1E},
    {0x4B, 0x1E},
    {0x4C, 0x00},
    {0x4D, 0x00},
    {0x4E, 0xA0},
    {0x4F, 0x80},
    {0x50, 0x00},
    {0x51, 0x00},
    {0x52, 0x00},
    {0x53, 0x00},
    {0x54, 0x00},
    {0x57, 0x80},
    {0x59, 0x10},
    {0x5A, 0x08},
    {0x5B, 0x94},
    {0x5C, 0xE8},
    {0x5D, 0x08},
    {0x5E, 0x3D},
    {0x5F, 0x99},
    {0x60, 0x45},
    {0x61, 0x40},
    {0x63, 0x2D},
    {0x64, 0x02},
    {0x65, 0x96},
    {0x66, 0x00},
    {0x67, 0x97},
    {0x68, 0x01},
    {0x69, 0xCD},
    {0x6A, 0x01},
    {0x6B, 0xB0},
    {0x6C, 0x04},
    {0x6D, 0x2C},
    {0x6E, 0x01},
    {0x6F, 0x32},
    {0x71, 0x00},
    {0x72, 0x01},
    {0x73, 0x35},
    {0x74, 0x00},
    {0x75, 0x33},
    {0x76, 0x31},
    {0x77, 0x01},
    {0x7C, 0x84},
    {0x7D, 0x03},
    {0x7E, 0x01}
};


Last edited by ddevices on Thu Jun 18, 2020 6:30 am; edited 1 time in total
temtronic



Joined: 01 Jul 2010
Posts: 9101
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Mon Jun 15, 2020 2:50 pm     Reply with quote

hmm, can you write just to that one register( 0x72) ?

create a new, very small program to select the device and write... see what happens.

Jay
ddevices



Joined: 15 Jun 2020
Posts: 13

View user's profile Send private message

PostPosted: Mon Jun 15, 2020 3:19 pm     Reply with quote

Thank you for the suggestion. In a way that's what I tried to do with the mainloop:

Code:
MAINLOOP_WAIT() ;   //10ms
    if(count>0) count--;
   if(count==1)
      {
      output_toggle(LED1);

      i2c_start();
      i2c_write(PAJ7620_write);     
      i2c_write(0x72);
      i2c_write(0x01);  //if 0x00 it's okay , if 0x01 it locks up
      i2c_stop();     
     
      count=200;
      }   
 


You can see in mainloop all I'm trying to do is write to that one register. It has no problem when parameter is 0 but switch it to 1 and PIC locks up. I assume it is waiting for ACK?
temtronic



Joined: 01 Jul 2010
Posts: 9101
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Mon Jun 15, 2020 3:54 pm     Reply with quote

Could you please post a link to the device datasheet that has all the registers ? I've downloaded 2 and can't see register 0x72 anywhere !

edit, OK 3rd datasheet has them listed BUT nothing about what they do.

also, are you running PIC at 3 volts ??

thanks
Jay
ddevices



Joined: 15 Jun 2020
Posts: 13

View user's profile Send private message

PostPosted: Mon Jun 15, 2020 4:13 pm     Reply with quote

It is hard to find on some of the datasheets. Check this out:
https://files.seeedstudio.com/wiki/Xadow_Gesture_v1.0/res/PAJ7620U2_Datasheet_V0.8_20140611.pdf
On page 8 (complete description), 33 (in matrix), and 40.
Reviewing the datasheets, you are helpful!
I am running at 5 volts, the gesture board has voltage regulator and data line translators, board is rated for 3 to 5 volts.
Thanks
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Jun 15, 2020 4:32 pm     Reply with quote

Quote:
PAJ7620_write

Post the value of this.


Quote:
Correct pull ups are on I2C lines

Tell us the value of the pull-ups.
ddevices



Joined: 15 Jun 2020
Posts: 13

View user's profile Send private message

PostPosted: Mon Jun 15, 2020 4:41 pm     Reply with quote

// DEVICE ID
#define PAJ7620_ID 0x73
#define PAJ7620_write 0xE6
#define PAJ7620_read 0xE7

Pull ups are 2.2K. Also, please keep in mind the hundreds of other writes function correctly (as determined by the ACK), only to register 0x72 with parameter 0x01 fails.

Thank you for your help.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Jun 15, 2020 5:03 pm     Reply with quote

Quote:
I have this sensor working with Arduino

Post the Arduino code that writes 01 to reg 0x72.

Also post a link to the full Arduino code.

We can analyze what the Arduino code is doing
and make equivalent CCS code.
Ttelmah



Joined: 11 Mar 2010
Posts: 19217

View user's profile Send private message

PostPosted: Tue Jun 16, 2020 12:03 am     Reply with quote

Screaming thing is your setup is not legal....

The PAJ7620, is a 3.3v max device. The PIC you have, is legal to run at
3.3v, but at 18.7MHz max. You are showing a 48Mhz setup.
So either you have a clock speed that is illegal for the PIC, or you are
running the PIC at 5v....
If you are running the PIC at 5v, the I2C inputs require to go up to 4v.
Not possible with the PAJ7620.
Now I'd suspect you are at 5v, for a second reason. You have the USB
VREG enabled. This has a minimum input voltage of 4.1v. To run below
this, you have to supply the USB power.

However, if you are running the PIC at 5v (so clock setting is legal), and
the PAJ7620 at 3.3v, then you may be able to work by selecting the
'SMBUS' option on the I2C setup. This should switch the I2C inputs to
accepting SMBUS voltage levels.
Now expand here a little. On most PIC's, the data sheet lists the voltage
levels for SMBUS as 2.1v for ViH. However the xx50 datasheet does not
say this. However it does still refer to SMBUS mode on the input pins, so
should switch to this. The Arduino inputs are normal 'TTL' inputs, so have
a ViH of 2.4v, while the I2C pin inputs on the PIC have a ViH by default
of 0.8*Vdd. So with a 5v supply, 4v, which the chip is not going to give...

So what you post has problems. Describe what voltages are being used?.
What pull up resistors on the I2C, and to what voltage these go?.
How is the supply generated for the PAJ?.

This write is actually a main 'enable' for the chip. That earlier writes
seem to work, doesn't actually prove anything.
Ttelmah



Joined: 11 Mar 2010
Posts: 19217

View user's profile Send private message

PostPosted: Tue Jun 16, 2020 3:53 am     Reply with quote

OK. See this:
Quote:

I am running at 5 volts, the gesture board has voltage regulator and data line translators, board is rated for 3 to 5 volts.


Means you need the 'SMBUS' option in your #use i2c.

The point is that by default the PIC is setup to use 5v I2C inputs, which need
to go up to 4v to work. The Arduino, only needs 2.4v.
Adding this option should reprogram the PIC inputs down to a voltage
more like the Arduino....

Also, what is PAJ7620_write defined as?. Needs to be 0xE6.
ddevices



Joined: 15 Jun 2020
Posts: 13

View user's profile Send private message

PostPosted: Tue Jun 16, 2020 6:52 am     Reply with quote

Ttelmah, good effort and I did try the SMBUS option that you suggested but same results. The board is fully compatible from 3.3V to 5V, it has voltage regulator and data line level shifters. Below is link to board:
https://wiki.dfrobot.com/Gravity%3A%20PAJ7620U2%20Gesture%20Sensor%20SKU%3A%20SEN0315
Link to schematic:
https://github.com/John-1997/schematiC
Using an oscilloscope I can see the PAJ7620U2 is pulling the SDA line low for valid ACK for all other registers (also with scope I can see full 5V SDA & SCL to PIC).

Below is link to code I have running on Arduino:
https://github.com/DFRobot/DFRobot_PAJ7620U2
Second set of code that is very similar:
https://github.com/Seeed-Studio/Gesture_PAJ7620

Most of the code does not have to be translated, my code is failing in the initialize of the registers which on Arduino is:
Code:
for (int i = 0; i < sizeof(initRegisterArray)/sizeof(initRegisterArray[0]); i++) {
    writeReg(initRegisterArray[i][0], &initRegisterArray[i][1],1);

My equivalent code you can see in first post, it stops at element 210 which is register 0x72.
temtronic



Joined: 01 Jul 2010
Posts: 9101
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Tue Jun 16, 2020 7:42 am     Reply with quote

I have to come back to doing the simple test..
cut code to access ONLY register 0x72 and see if you can read and write the data, which should be 0x00 or 0x01 according to the datasheet.
That eliminates 99.44% of all other code and focuses on the ONE register that's causes the problem.

it'd be nice to KNOW what that register actually does... 'disable' is vague... as in if it does 'disable' the device I can see it 'locking up' as no more I2C traffic would be possible....
Ttelmah



Joined: 11 Mar 2010
Posts: 19217

View user's profile Send private message

PostPosted: Tue Jun 16, 2020 7:58 am     Reply with quote

I repeat the question. "what is PAJ7620_write defined as"?.

The code you link to has:
PAJ7620_IIC_ADDR = 0x73

You do understand this will have to be doubled for use on a PIC.

PIC's use the 8bit 'address byte', not the 7bit address format, that the Pi/Arduino uses.
ddevices



Joined: 15 Jun 2020
Posts: 13

View user's profile Send private message

PostPosted: Tue Jun 16, 2020 8:16 am     Reply with quote

Sorry, in six posts above I had written PAJ7620_write is 0xE6.

I think you are on to something about the write to that register only. I changed the main code to:
Code:
void main() {
  int8 scntr, i, count, status;
  unsigned char data[2];
 
  setup_adc_ports ( NO_ANALOGS ) ;
  setup_adc( ADC_OFF ) ;
 
  set_tris_a( 0b11111111 ) ;
  #use fast_io( A )
  set_tris_b( 0b11111111 ) ;
  #use fast_io( B )
  set_tris_c( 0b10111110 ) ;

   SETUP_WDT( WDT_OFF ) ;
  SETUP_TIMER_0( T0_OFF ) ;
  SETUP_TIMER_1( T1_DISABLED ) ;
  SETUP_TIMER_2( T2_DISABLED , 255 , 16 ) ;
  SETUP_TIMER_3( T3_DISABLED ) ;
 
  paj7620SelectBank(1);
  count = 100;   //one second timing
  while ( TRUE ) { // main infinite while loop

    MAINLOOP_WAIT() ;   //10ms


   if(count>0) count--;
   i=0;
   if(count==1)
      {
      output_toggle(LED1);

      i2c_start();
      i2c_write(PAJ7620_write);     
      i2c_write(0x72);
      i2c_write(0x01);
      i2c_stop();     
     
      count=100;
      }   

  }//end main infinite while loop
 
}

You can see I eliminated the initialization of the PAJ and every second write to 0x72, it now does not lock up with either 0 or 1 as parameter. I did have to set the bank to 1 as that is where 0x72 is located, but outside of that it is the only register I am writing and now I2C does not lock up. I would think this means problem is in one of the other 219 registers that I write parameters to. Finding it might be an issue. Also, the Arduino code is the same exact registers and parameters without problem.
Disable does not stop the I2C bus in PAJ, it continues to operate.
I will see if I can find the other offending register, it might take some time.
Thanks for help.
ddevices



Joined: 15 Jun 2020
Posts: 13

View user's profile Send private message

PostPosted: Tue Jun 16, 2020 8:50 am     Reply with quote

Unfortunately I spoke too soon. In the 'short' code example I selected bank 1 only once but that at start is really only waking up the PAJ, you have to do it twice:
paj7620SelectBank(1);
paj7620SelectBank(1);

The first wakes the PAJ and the second correctly shifts it to bank 1. Once that is done then writing 0x72 with 0x01 locks up chip. It did not lock in my first test because I was still in bank 0.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group