I worked with a sensor BMP085. The situation is similar:
The sensor has an address:
#define BMP085_ADDRESS 0x77
But the logic analyzer shows is 0xEE and 0xEF. So it must be.
Attached is a screenshot of logger.
For your device:
#define DS1631_ADDRESS 0x48
PSoC routines use a slave address of less than 128 because the command-bit is appended to the address automatically. This is "Not intuitive"?? Imho this is far more easier to understand than having two different "addresses". Greatfully more and more of the suppliers use the real addressing scheme in their datasheets,
When you upload your project here we will have a look at and probably can see what goes wrong. To do so, use
Creator->File->Create Workspace Bundle (minimal)
and attach the resulting file.
Just achive the complete project then when fin with reduced project
erase everything in its folder, then un zip archive back into
“Create Workspace Bundle”
When reading from I2C use
MasterSendRestart() not another MasterSendStart()
I strongly recommend to use the pre-#defined constants for read, write Ack and nak- Makes it easier to check for typos and will survive a switch to PSoC4 where some differences are.
From the 1631 DS -
Slave Address: Every slave device on the bus has a unique 7-bit address that allows the master to access
that device. The 7-bit bus address is 1 0 0 1 A2 A1 A0, where A2, A1, and A0 are user-selectable through
the corresponding input pins. The three address pins allow up to eight DS1631s, DS1631As, or DS1731s
to be multidropped on the same bus.
Control Byte: The control byte is transmitted by the master and consists of the 7-bit slave address plus a
read/write (R/W) bit (see Figure 7). If the master is going to read data from the slave device then R/W =
1, and if the master is going to write data to the slave device then R/W = 0
So the address for one 1631 in system is 1001000 0x48. The MasterSendStart will take that address, and
your R/W parameter, and do the shift OR operation to form the byte sent to the 1631.
Setting the pins to pullup resistive might fail because the component accesses the pins itself. Use external resistors instead.
Your calculation of the temperature will fail, you are using ints. The low byte will get sign-extended unwantet. Multiply with 100 looks unusual, same for the shifts and division by 655.
I would use
// read DataH & DalaL
DTemp = (int16)DataH << 😎 | (uint16)DataL;
Temperature = (double)DTemp / 256;
A good source for failure analyses would be the result of the functions. Stop after every function call and look which bits are set in the returned byte.
The component seems to imply user has to setup pin -
sda – In/Out Serial data (SDA) is the I2C data signal. It is a bidirectional data signal used to transmit or receive all bus data. The pin connected to sda should be configured as Open-Drain-Drives-Low.
scl – In/Out Serial clock (SCL) is the master-generated I2C clock. Although the slave never generates the clock signal, it may hold the clock low, stalling the bus until it is ready to send data or ACK/NAK2 the latest data or address. The pin connected to scl should be configured as Open-Drain-Drives Low.
So adding the register write to implement pullup shopuld be OK. Check with a scope.
Only issue is internal pullups have a very wide tolerance, > 8K worst case, and
if you had a lot of C buss loading on SDA, SCL, that could impact signal integrity.
Scope again to be sure looks OK.
You can always take a look at the generated code for that function in
workspace explorer to see if it is blocking, but should be called out
in API definitions in datasheet.
When I2C was standardized there was no timeout in discussion, too bad!
So to keep consistent with the original Cypress did not include a timeout into the standard routines.