- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Everyone,
I am new to the world of PSoC and working on my second project.
I am trying to 'talk' with a DS1302 (a pointless exercise I know as the PSoC has a RTC) as a way to learn SPI and the three wire interface, and this was the only device I had to hand.
I have tried numerous ways to do this and had no sucess with any. Can somebody with more experience than I have please tell me if it is a fault in my code or some quirk of this particular chip. One thing I did notice on the data sheet was that during a read cycle the address is clocked on the rising edge but the data packet is clocked on the falling edge - is that normal?
The code is as follows:
#include <project.h>
int main()
{
//Declare a few variables
int8 myData = 0u;
//Enable Interupts
CyGlobalIntEnable;
//Start the SPI Module
SPIM_1_Start();
//Clear all buffers just for good luck!
SPIM_1_ClearFIFO();
/* --------------------------------------------- */
// Let's try to send some data to the slave device.
/* --------------------------------------------- */
//Enable the manual slave select line
//This needs to go HIGH to enable the chip
Control_Reg_1_Write(1);
//Enable Transmit from Master
SPIM_1_TxEnable();
//Clear the write protect bit by setting register 0x8E to be zero
SPIM_1_WriteTxData(0x8E);
SPIM_1_WriteTxData(0x00);
//Set the first RAM address to contain 0xAA
SPIM_1_WriteTxData(0xC0);
SPIM_1_WriteTxData(0xAA);
//Wait for transmission to complete and then go back to receive mode
while(!(SPIM_1_ReadTxStatus() & SPIM_1_STS_SPI_DONE));
SPIM_1_TxDisable();
//Disable the manual slave select line
Control_Reg_1_Write(0);
//Have a short delay and than start again
CyDelay(100);
/* --------------------------------------------- */
// Now read the data back from the slave device.
/* --------------------------------------------- */
//Clear all the buffers
SPIM_1_ClearFIFO();
//Enable the manual slave select line
//This needs to go HIGH to enable the chip
Control_Reg_1_Write(1);
//Enable Transmit from the Master
SPIM_1_TxEnable();
//Send the address that we wish to read from
SPIM_1_WriteTxData(0xC1);
//Wait for transmission to complete and then go back to receive mode
while(!(SPIM_1_ReadTxStatus() & SPIM_1_STS_SPI_DONE));
SPIM_1_TxDisable();
//Disable the manual slave select line
Control_Reg_1_Write(0);
//Read the received data
myData = SPIM_1_ReadByte(); //Returns 00
myData = SPIM_1_ReadByte(); //Returns C1
myData = SPIM_1_ReadByte(); //Returns 00
myData = SPIM_1_ReadByte(); //Returns C0
//Enter never ending loop
for(;;)
{
/* Place your application code here. */
}
}
/* [] END OF FILE */
- Labels:
-
PSoC 5LP
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You should always consider posting the complete project with all of your settings, that is much easier for us to find any bug. To do so, use
Creator->File->Create Workspace Bundle (minimal)
and attach the resulting file (you may use chrome, that should work from now on).
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The DS1302 follows the normal SPI procedure. Data is changed in the falling edge of the clock, and read at the rising edge of the clock. During a read operation, after the address has been written, the rolses of who is writing data swaps between PSoC and DS1302. Thats why the diagram is a little bit confusing.
I see two mistakes: when writing to the DS1302, you should clear CE after each operation. Otherwise I'm not sure whether the DS1302 will accept the next operation (or finish the first one properly). Also, when trying to read you should not disable the CE line after sending the address - it still needs to be 1 during the read.
And since you didn't specify burst mode, you should read only one byte (and not 4).
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Are you QUITE sure that the ss - signal is active high? Usually this is an active low signal as it is in the SPI-component.
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You are using SPI clock of 1MHz. Since you are working at 3.3V I would suggest to lower the speed.
As you can see all inputs of the ds1302 are having pull-down resistors. your PSoC's output pin should not have strong drive or you will never read anything other than the output value. better use open drain dives high. So when PSoC outputs a zero you are able to read the signal at the input.
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I have changed the clock to run at 1Mhz (500 KHz SPI) and changed the pind drive as suggested.
The device now returns 0xC3 rather than 0xC1!
Think I will have to wait till I get a scope unless you have any other ideas?
Thanks to everyone for your continued support and suggstions. What I thought was going to be simple is proving more difficlt than I thought!
Asin the SPI sample application where they create a master and a slave on the one device, is there any way that I can easily make an SPI 3-wite slave to test the code or is that just going to make things even more complicated?
Roop
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Read carefully in SPI's datasheet about SPIM_GetRxData(). You should wati until the byte is ready.
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
If I have understood the Datasheet for the SPI module and your instructions correctly, I now have the following:-
<code>
//Wait for transmission to complete and then go back to receive mode
while(!(SPIM_1_ReadTxStatus() & SPIM_1_STS_SPI_DONE));
SPIM_1_TxDisable();
//Wait for data to be received from the slave device
while(SPIM_1_GetRxBufferSize() == 0);
//Collect all data from the buffer
int i;
for (i = 1; i <= SPIM_1_GetRxBufferSize(); i++){
myData = SPIM_1_ReadRxData();
}
//Disable the manual slave select line
Control_Reg_1_Write(0u);
</code>
Unfortunately this still produces the same result.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Are you suing the maxim DS1302? I think it is not using SPI interfae
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Yes, I am using the Dallas DS1302+. I thought it uses the three wire (bidirectional) mode od SPI - see data sheet above. I am driving the CS line via a manual register because it is active high in this component, I have also tried using the SS line of the SPIM module via a NOT on the schematic, but I am basically getting the same result.
I have also double checked all the jumper wires, power supply etc and even changed the chip. Both chips respond with the same information so I guess it is a timing or communications issue.
If it is not SPI then what do you believe it is and how do I talk to it?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Author of this post states it is not SPI, One Wire, or I2C.
http://playground.arduino.cc/Main/DS1302
Maybe bit banging this is the way to go.
Regards, Dana.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Yes, the author of that article states:
The DS1302 uses three lines (CE, I/O, SCLK). It is not I2C, it's not OneWire, and it is not SPI. The most used name is "3-wire interface".
But the datasheet for the SPIM also says:
The SPI Master component provides an industry-standard, 4-wire master SPI interface. It can also provide a 3-wire (bidirectional) SPI interface.The SPI Master component provides an industry-standard, 4-wire master SPI interface. It can also provide a 3-wire (bidirectional) SPI interface.
Are you saying that these are not the same thing?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Where the DS1302 is not a "standard" interface first thing I would look
at is timing, both electrical and functional (like delays needed between
address decode and next command).
The fact that PSOC SPI can handle "generic" interfaces does not remove
need for above with non standard interfaces.
Regards, Dana.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The timing seems to be OK using Mode 0 of SPIM
I used 4 wire SPI for all my projects and never used 3 wire version.
See if this can help
/* Assume that you already send a read address C1 */
//Wait for transmission to complete and then go back to receive mode
while(!(SPIM_1_ReadTxStatus() & SPIM_1_STS_SPI_DONE));
SPIM_1_TxDisable();
//Clear all the buffers
SPIM_1_ClearRxBuffer();
//Read the received data
myData = SPIM_1_ReadByte(); //ignore this, dummy read
myData = SPIM_1_ReadByte(); //This should be your data
//Disable the manual slave select line
Control_Reg_1_Write(0u);
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
For testing I would slow the clock to a lower one to this, I may used 100khz first, and change it to a faster one once done.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I would set RX buffer size to 1 as well.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@ H L,
How do you know you have a reliable robust design if you do
not evaluate the timing ? In this case Creator timing analyzer
pointless since it does not model or incorporate the external
device.
Regards, Dana.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi All,
Where the DS1302 is not a "standard" interface first thing I would look
at is timing, both electrical and functional (like delays needed between
address decode and next command).
The fact that PSOC SPI can handle "generic" interfaces does not remove
need for above with non standard interfaces.
Dana: How would or can I do this without access to an oscilloscope. As far as I can tell the code procedures follow the requird timings, but for example I don't know when the processor starts to Tx after I have given the command.
//Read the received data
myData = SPIM_1_ReadByte(); //ignore this, dummy read
myData = SPIM_1_ReadByte(); //This should be your data
H L: The read buffer only contains one byte, so I just get 0x00 if I try to read more
For testing I would slow the clock to a lower one to this, I may used 100khz first, and change it to a faster one once done.
I would set RX buffer size to 1 as well.
H L: I now have the clock running at 400KHz and have to date seen no change in results from any seed changes. How do I set the Rx buffer to 1? The component configuration tool throws an error if set to <4 (Rx & Tx) and I can't find any API command to do this.
Thanks to all for your support, time to buy a scope or try a different chip I think, either that or I will just have to 'bit bang' the thing to get it to work!
Have a great weeeknd,
Roop
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
This might be useful, very cheap, I bought 2 and they work pretty good, and
SW (free also) is very good. Link is just one of many on ebay. Note they do not have
any overvoltage protection on inputs so be aware. Some guys have made up diode
arrays with R's to limit current to condition inputs for that problem.
Regards, Dana.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Saleae is not selling the product anymore. And the cheap clones are using their SW
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The link is a clone, not a product manufactured by Saleae, but
does use the Saleae software.
Regards, Dana.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
A big thanks to all who have answered this thread so far.
I will get a logic analyser and oscilloscope onto this and see what is happening. I have also tried to make a master & slave in the same schematic and although they work in full-duplex (using the cypress example project), they also don't work in bidirectional mode. When (if) I ever get this working I will post the code here for others to reference in the future.
Thanks again for all your suggestions and ideas. So much to learn on these PSoC devices, it will keep me entertained for years!
Regards,
Roop
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Unless someone else sees the problem here consider posting a CASE.
To create a technical case at Cypress -
“Support”
“Technical Support”
“Create a Case”
You have to be registered on Cypress web site first.
Regards, Dana.