SPIM and DS1302

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
ruha_285291
Level 2
Level 2

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 */

   
    Any comments or assistance would be much appreciated otherwise I will have to go and buy an oscilloscope and have a look at what is happening (well that sounds a good excuse to me!).   
   
        
   
    Thanks for your help,   
   
        
   
    Rupert   
0 Likes
25 Replies
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

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
 

0 Likes
lock attach
Attachments are accessible only for community members.
ruha_285291
Level 2
Level 2

 Thanks for the heads up om that Bob.

   

Please find the project attached.

   

Regards,

   

 

   

Roop

0 Likes
HeLi_263931
Level 8
Level 8
100 solutions authored 50 solutions authored 25 solutions authored

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).

0 Likes
lock attach
Attachments are accessible only for community members.
ruha_285291
Level 2
Level 2

 Have changed the code as shown below, but unfortunately still no joy 😞

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

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

0 Likes
lock attach
Attachments are accessible only for community members.
ruha_285291
Level 2
Level 2

 That is my understanding based on the timing diagram from the datasheet.

   

DS1302 Datasheet attached.

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

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

0 Likes
ruha_285291
Level 2
Level 2

 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

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

Read carefully in SPI's datasheet about SPIM_GetRxData(). You should wati until the byte is ready.

   

 

   

Bob

0 Likes
ruha_285291
Level 2
Level 2

 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.

0 Likes
Anonymous
Not applicable

Are you suing the maxim DS1302? I think it is not using SPI interfae

0 Likes
ruha_285291
Level 2
Level 2

 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?

0 Likes
ETRO_SSN583
Level 9
Level 9
250 likes received 100 sign-ins 5 likes given

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.

0 Likes
ruha_285291
Level 2
Level 2

 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?

0 Likes
ETRO_SSN583
Level 9
Level 9
250 likes received 100 sign-ins 5 likes given

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.

0 Likes
Anonymous
Not applicable

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);

0 Likes
Anonymous
Not applicable

 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. 

0 Likes
Anonymous
Not applicable

 I would set RX buffer size to 1 as well.

0 Likes
ETRO_SSN583
Level 9
Level 9
250 likes received 100 sign-ins 5 likes given

@ 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.

0 Likes
ruha_285291
Level 2
Level 2

 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

0 Likes
ETRO_SSN583
Level 9
Level 9
250 likes received 100 sign-ins 5 likes given

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.

   

 

   

    

   

          http://www.ebay.com/itm/Compatible-with-Saleae-USB-Logic-24MHz-8Ch-Logic-Analyzer-Supports-1-1-15-US...

   

 

   

Regards, Dana.

0 Likes
Anonymous
Not applicable

 Saleae is not selling the product anymore. And the cheap clones are using their SW 

0 Likes
ETRO_SSN583
Level 9
Level 9
250 likes received 100 sign-ins 5 likes given

The link is a clone, not a product manufactured by  Saleae, but

   

does use the  Saleae software.

   

 

   

Regards, Dana.

0 Likes
ruha_285291
Level 2
Level 2

 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

0 Likes
ETRO_SSN583
Level 9
Level 9
250 likes received 100 sign-ins 5 likes given

Unless someone else sees the problem here consider posting a CASE.

   

 

   

    

   

          

   

To create a technical case at Cypress -

   

 

   

www.cypress.com

   

“Support”

   

“Technical Support”

   

“Create a Case”

   

 

   

You have to be registered on Cypress web site first.

   

 

   

Regards, Dana.

0 Likes