sondeben
Posts: 9
Joined: Tue Jul 17, 2018 11:03 pm

Setting register bit

Tue Jul 17, 2018 11:35 pm

Hello all

First of all thanks a lot for this forum in which I found all answers now by reading through the replies. I am a mechanical engineer (41) and realized several hobby RPI projects up to now.

But now I am stuck: I have a FDC2214 capacitive sensor I want to connect to the RPI via I2C. I am an absolute I2C newbie and already struggle with the wake-up command.
The datasheed says:
When the FDC powers up, it enters into Sleep Mode and will wait for configuration. Once the device is
configured, exit Sleep Mode by setting CONFIG.SLEEP_MODE_EN to b0.


Device address is: 0x2A
Config register is: 0x1A
CONFIG.SLEEP_MODE_EN is on bit 13

What I did for trial is this:

Code: Select all

onmode = bus.read_byte_data(0x2A, 0x1A)
print "onmode: ", onmode
bus.write_byte_data(0x2A, 0x1A, 0)
onmode = bus.read_byte_data(0x2A, 0x1A)
print "onmode: ", onmode
With the result, that I always get a value of 0, even when I write a value of 1.

My problem: The write method only allows to enter the address and register (and value) but no bit. How can I specify the bit I need to set? Or am I completely wrong?

Anyone an idea or a link where I can find an explanation. All the tutorials I went through did not answer this question yet....

Thanks in advance for any support.

Regards,
Benno

KnarfB
Posts: 194
Joined: Wed Dec 14, 2016 10:47 am
Location: Germany

Re: Setting register bit

Thu Jul 19, 2018 1:30 pm

Hi sondeben,

I have not worked with those chips, but take a look at the datasheet (SNOSCZ9–MAY 2016) page 21 figure 16 and 17 (i2c write and read) and take a look at 7.6.1 Register List.

All registers are 16-bit. So you need ro read/write two bytes of data (read_word_data...). One cannot address a single bit via i2c. If you need to extract/set/reset inididual bits, read the whole word, use bitwise operators and write back the result.

hth

KnarfB

Pi Flyer
Posts: 40
Joined: Sat Jun 04, 2016 1:57 pm

Re: Setting register bit

Thu Jul 19, 2018 9:18 pm

Benno,

You're not going to be able to just write one bit, the smbus "write_byte_data" method expects you to write at least one byte...hence the name of the method. Furthermore, it looks like your device expects more than one byte.

User avatar
DougieLawson
Posts: 34168
Joined: Sun Jun 16, 2013 11:19 pm
Location: Basingstoke, UK
Contact: Website

Re: Setting register bit

Thu Jul 19, 2018 9:27 pm

Pi Flyer wrote:
Thu Jul 19, 2018 9:18 pm
Benno,

You're not going to be able to just write one bit, the smbus "write_byte_data" method expects you to write at least one byte...hence the name of the method. Furthermore, it looks like your device expects more than one byte.
Yes you can. Read the register first. Use logicial OR to set a bit. Use logical AND to reset a bit.

Code: Select all

def pinOn(bank, pin):
  global valueA
  global valueB
  bit = pin - 1
  if bank == 'B':
    valueB = valueB | (1 << bit) # OR to SET bit
    bus.write_byte_data(ADDR, OLATB, valueB)
  else:
    valueA = valueA | (1 << bit)
    bus.write_byte_data(ADDR, OLATA, valueA)

def pinOff(bank, pin):
  global valueA
  global valueB
  bit = pin - 1
  if (bank == 'B'):
    valueB = valueB & (0xff - (1 << bit)) # RESET bit
    bus.write_byte_data(ADDR, OLATB, valueB)
  else:
    valueA = valueA & (0xff - (1 << bit))
    bus.write_byte_data(ADDR, OLATA, valueA)
Note:The use of baseball bats for educational purposes is completely disallowed on this forum.

Any DMs sent on Twitter will be answered next month.

Pi Flyer
Posts: 40
Joined: Sat Jun 04, 2016 1:57 pm

Re: Setting register bit

Thu Jul 19, 2018 11:07 pm

But you must write a byte...which I thought was the obvious point of my post. The OPs code included a single value for the data portion of the i2c message as he thought he could write a bit.

sondeben
Posts: 9
Joined: Tue Jul 17, 2018 11:03 pm

Re: Setting register bit

Sat Jul 21, 2018 12:13 am

Hi all

Thanks for all your replies. Surprisingly I am getting realistic values by using word_data or byte_data. Nevertheless I do not really understand why, as I am only adressing CONFIG on 0x1A with a value of 0. For my understanding I would also need to specify the bit 13 as there are different setting in CONFIG.

(Besides I am fighting with a "IOError: [Errno 5] Input/output error" now, but this is a different story I think...)

Regards,
Benno

User avatar
DougieLawson
Posts: 34168
Joined: Sun Jun 16, 2013 11:19 pm
Location: Basingstoke, UK
Contact: Website

Re: Setting register bit

Sat Jul 21, 2018 9:33 am

You should be using read_word_data(0x2A, register) or read_word_data(0x2B) to get two bytes returned.

You'll need to check with i2cdetect -y 1 which address your sensor appears at.
Note:The use of baseball bats for educational purposes is completely disallowed on this forum.

Any DMs sent on Twitter will be answered next month.

sondeben
Posts: 9
Joined: Tue Jul 17, 2018 11:03 pm

Re: Setting register bit

Sun Jul 22, 2018 1:06 am

Hello Dougie

Thanks for your reply. The IOError: [Errno 5] seems to be linked to accessing via VNC in my case. i2cdetect -y 1showed random results. Solved now by working directly on the Pi.
Also understood now how to set the bits. Numbering from back and starting from 0 confused me as newbie.
I am getting some results now. But still need to figure out how to read the 12 bits with data from the 2 bytes I receive....

Thanks a lot for your support!
Benno

User avatar
DougieLawson
Posts: 34168
Joined: Sun Jun 16, 2013 11:19 pm
Location: Basingstoke, UK
Contact: Website

Re: Setting register bit

Sun Jul 22, 2018 7:39 am

To pick twelve bit from 16 bits, logically AND the result with 12 bits.

bit12value = bit16value & 0b0000111111111111
or (using hex because it's easier than binary bit strings)
bit12value = bit16value & 0x0fff
Note:The use of baseball bats for educational purposes is completely disallowed on this forum.

Any DMs sent on Twitter will be answered next month.

sondeben
Posts: 9
Joined: Tue Jul 17, 2018 11:03 pm

Re: Setting register bit

Wed Jul 25, 2018 11:12 am

Hi all

I am still fighting with the communication. Trying to understand the received values I realized that there is an endian issue with the RPI. So I changed the order of the bytes read with "word" in order to get this right. Reading the MANUFACTURER ID and DEVICE ID tells me I am on the right way as I am getting the correct values for these:

Code: Select all

def word_split1 (temp):
    first_byte = temp >> 8 # right shift 8 places
    return first_byte

def word_split2 (temp):
    first_byte = temp >> 8 # right shift 8 places
    first_byte_times256 = first_byte << 8 # shift left 8 places
    second_byte = temp - first_byte_times256 
    return second_byte

def read_sensor(adr):
    valI2C = bus.read_word_data(ADDRESS, adr)
    first_byte = word_split1 (valI2C)
    second_byte = word_split2 (valI2C)
    revised_word = (second_byte <<8) + first_byte
    return revised_word

But when I read back the CONFIG sent with the following statement:

Code: Select all

bus.write_word_data(ADDRESS, CONFIG, 0x1e01) 
I get as an answer: 0x1e

Somehow it seems I am loosing information here.
Do I also need to swap MSB/LSB for data I am sending to the device?

The readings of the sensor values are 0xfff or 0x0, so there seems to be an issue with the configuration I need to solve first....

Regards,
Benno

User avatar
joan
Posts: 13621
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: Setting register bit

Wed Jul 25, 2018 11:34 am

When sending a 16 bit word quantity I2C always sends the least significant byte first.

When reading a 16 bit quantity I2C always puts the first received byte in the least significant byte of the returned word.

sondeben
Posts: 9
Joined: Tue Jul 17, 2018 11:03 pm

Re: Setting register bit

Wed Jul 25, 2018 12:05 pm

Hi Joan

According to the Datasheet my device wants to have the MSB first - for reading and writing - or am I wrong?

http://www.ti.com/lit/ds/snoscz5a/snoscz5a.pdf Page 22

Writing:
ADDRESS - REGISTER - MSB - LSB

Reading:
ADDRESS - REGISTER - ADDRESS - MSB - LSB

I assume this is the reason why I do not get the right values...

User avatar
joan
Posts: 13621
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: Setting register bit

Wed Jul 25, 2018 12:11 pm

If the device wants MSB first you will have to swap the bytes at the Pi end. Yes, that will explain the errors.

sondeben
Posts: 9
Joined: Tue Jul 17, 2018 11:03 pm

Re: Setting register bit

Wed Jul 25, 2018 2:12 pm

Hi all

Yeah - it's working.
Changing the order of the written bytes for the configuration finally made it and I receive realistic readings on all channels!

Thanks for your support!
Benno

Return to “Interfacing (DSI, CSI, I2C, etc.)”