Did you see this in datasheet -
No I'm afraid you don't understand. When I said "slave address" I mean the address of the slave I am trying to communicate with. The PSOC is implemented as a master. Anyone have any real experience with the DS1631 or similar device? And do I understand the addressing right )that I have to shift the slave address left by one bit) (Read my first post)
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
BMP05.png 71.7 K
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.
Ok, I would like to post a project that has the problems, but I want to make a minimal project rather than posting everything. I wanted to copy the project and then edit it down to just what is needed, but I cannot figure out how to copy a project to a different folder, rename it, and then open the new project. Everything I tried fails with some kind of error. Is there a way to do this? Thanks, Russ
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”
Ok, attached is an archive of a minimal system that shows the problem. It has code to communicate with a PC host, but a host does not need to be connected to observe the problem. Using the Creator 3.1 debugger it is easy to see that the problem starts in the InitDs1631 routine in main. The first call to TemperatureI2C_MasterWriteByte fails and after that the program will hang on a TemperatureI2C_MasterSendStart call if the ReadTemperature routine is called. Thank you for looking at this. Regards, Russ
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 << 8) | (uint16)DataL;
Temperature = (double)DTemp / 256;
Thanks to all for your suggestions. Taking the last one first, I did try this with setting the pins to high impedance. There are puilups on the lines anyway. However I received advice to use the CY_PINS_RES_UP instead. At one point I implemented a software I2C master that worked with that pin configuration. However I will revisit this and see if changing it makes a difference. To Dana, yes, I understand the addressing issue, It is too bad that some manufacturers use one way to express the addresses (7 bit) while others use 8 bit. I had figured it out but just wanted confirmation that I was doing it right – which you supplied. Thanks. To Bob, My understanding is that a restart is just a convenience to save time, but is not operationally better than a full stop followed by a start. If I ever get this working then I had intended to try the restart. Ok on the constants, good point. Unfortunately, none of these suggestions addresses the problem I am seeing ( except maybe for the pins configuration). Regardless of all else, after a start, the write byte fails to ack. I have to go out of town tomorrow for a doctor appointment so I will be unable to follow up on this until Friday, Thanks to all, Regards, Russ
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.
Thanks all. I got it working. I am not sure what I did because I am pretty sure I tried everything before, but maybe there was some missing part. The code I sent here was originated from an old project version and had one glaring error (shown below). After trying a few other things (including getting rid of the pin drive statements) I noticed the error and fixed. Things started working differently but still had the same error, later in the code. Am not sure how that was overcome, but the final fix was to replace the master start in the read temperature routing with a restart. (I thought there was a stop in there but there was not). Anyway it is now working just fine in the test code and also in the final. Here is the error that appeared in three places in the code I posted here: TemperatureI2C_Stop (); Should have been: TemperatuireI2C_MasterSendStop (); The thing is, the errors I was getting occurred before those bad code statements were ever reached, so I still am unsure just what the fix was. I hate it when that happens, but not enough to spend the time to load up the original code and modify step by step to find the difference! Life goes on and so do my projects! By the way, one more question: I do not like that the read and write master routines are blocking. Wish they had a settable time out value. I notice that the read and write butter description does not say that the routines are blocking – but it doesn’t say they are not blocking either. Looking at the code, I see no calls to the blocking routines, but cannot be sure, so – do they block? Maybe it would be better to use those routines even when only sending or receiving one byte at a time??? Thanks. Russ