CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug Reports on this forum. Send them to support@ccsinfo.com

SPI with MAX7219 and MAX31855
Goto page Previous  1, 2, 3
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
edbfmi1



Joined: 18 Jul 2006
Posts: 87

View user's profile Send private message

PostPosted: Fri Mar 23, 2018 2:22 pm     Reply with quote

Sorry PCM programmer I didn't see your request.

I am just using 8 seven segment displays that are being driven by the MAX7219CWG+ The part is a LITEON LSHD-5503 Below is the link to the display.
https://media.digikey.com/pdf/data%20sheets/lite-on%20pdfs/lshd-5503.pdf


Last edited by edbfmi1 on Fri Mar 23, 2018 2:34 pm; edited 1 time in total
edbfmi1



Joined: 18 Jul 2006
Posts: 87

View user's profile Send private message

PostPosted: Fri Mar 23, 2018 2:29 pm     Reply with quote

More weirdness.

When I have the #use spi setups as follows
Code:

#use spi(SPI1, MASTER, MODE=0, bits=32, stream=MAX31855)
#use spi(SPI1, MASTER, MODE=0, bits=32, stream=MAX7219)

I can only set a breakpoint on the first #use spi

When I use the following I can set a breakpoint on either one?
Code:

#use spi(SPI1, MASTER, MODE=0, bits=32, stream=MAX31855)
#use spi(SPI1, MASTER, MODE=0, bits=8, stream=MAX7219)
edbfmi1



Joined: 18 Jul 2006
Posts: 87

View user's profile Send private message

PostPosted: Fri Mar 23, 2018 2:40 pm     Reply with quote

Since I originally had the spi configured using SETUP_SPI when I started this thread would it be worth trying to go back to that? I only switched because the data sheet was misleading and looked like I had 2 different modes but after reviewing the timing diagrams they are both mode 0.
Ttelmah



Joined: 11 Mar 2010
Posts: 13531

View user's profile Send private message

PostPosted: Sat Mar 24, 2018 11:26 am     Reply with quote

edbfmi1 wrote:
Since I originally had the spi configured using SETUP_SPI when I started this thread would it be worth trying to go back to that? I only switched because the data sheet was misleading and looked like I had 2 different modes but after reviewing the timing diagrams they are both mode 0.


No.
The fundamental problem is because the two different clock modes have different levels on the lines. You have to force the actual bus to switch before you select the second chip.
Have you tried the version I posted?.

If you don't need to change modes, then you don't need to use two streams. Just use the spi_speed command. However it is critical that you read the return from the spi_xfer command. This ensures the byte has completed clocking oout.
temtronic



Joined: 01 Jul 2010
Posts: 6249
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sat Mar 24, 2018 12:01 pm     Reply with quote

simplify your code and life...just use ONE speed, say 100K, at least for initial test purposes. Usually 'temperature stuff' is snail slow and displays only have to be say 100 Hz for us humans to see OK.
Since you can use one mode for both peripherals, that makes coding easier.
It almost sounds like you need to start over, usng the two working sections of code, get the display working 100%, then the temperature, then merge the two and see what happens.
edbfmi1



Joined: 18 Jul 2006
Posts: 87

View user's profile Send private message

PostPosted: Sat Mar 24, 2018 12:34 pm     Reply with quote

I came in Saturday and this is what I found.
When I remarked out all the lines in the subroutine for MAX31855 temperature IC so only the Display IC would be written to as follows.
Code:
void readMAX()
{
   delay_us(2);
//   int32 MAXread;
//   spi_xfer(MAX31855,0,32);                //switches the stream to mode 0
//   delay_us(2);   
//   output_low(TEMP);
//   delay_us(2);
//   MAXread=spi_xfer(MAX31855,0,32);
//   delay_us(2);
//   output_high(TEMP);
//   delay_us(2);
//   TempByte3=MAXread>>24 & 0xff;
//   TempByte2=MAXread>>16 & 0xff;
//   TempByte1=MAXread>>8 & 0xff;
//   TempByte0=MAXread & 0xff;
}

and remark out the #use spi that refers to the MAX31855
Code:
//#use spi(SPI1, MASTER, MODE=0, bits=32, stream=MAX31855)
#use spi(SPI1, MASTER, MODE=0, bits=32, stream=MAX7219)

and looked at the chip selects and data lines for the two ICs with my scope, only the chip select and data lines for the MAX7219 display IC are active.
This is as expected,
but when I do the same thing for the MAX7219 display driver IC so only the MAX31855 will be read as follows
Code:
void maxsend()                     // send routine for max7219 to update display
{
   delay_us(2);
//   spi_xfer(MAX7219,0,8);             //switches the stream to mode 0
//   delay_us(2);     
//   output_low(DISP);
//   delay_us(2);                     
//   spi_xfer(MAX7219,address,8);         //send address
//   delay_us(2);     
//   spi_xfer(MAX7219,data,8);            //send data
//   delay_us(2);
//   output_high(DISP);
//   delay_us(2);
}

and remark out the #use spi that refers to the MAX7219 display driver
Code:

#use spi(SPI1, MASTER, MODE=0, bits=32, stream=MAX31855)
// #use spi(SPI1, MASTER, MODE=0, bits=32, stream=MAX7219)

I get the chip select and data on for the MAX31855 temperature IC as expected but I also get signal on the data line for the MAX7219 (SPI_DO Pin) and get nothing on the chip select for the Display IC.
Since I am not doing anything to the SPI_DO pin at this time I am confused.

The final thing I tried since both ICs are operating on the same mode was to only have one #USE SPI and then kept them both at 8 bits. I then took the information from the MAX31855 in four successive spi_xfer and the problem went away.
This was my final code.
Code:

#use spi(SPI1, MASTER, MODE=0, bits=32, stream=SPI_PORT1)


Code:

/**********************************************************************************
// Send Update Display, MAX7219
**********************************************************************************/
void maxsend()                     // send routine for max7219 to update display
{
   delay_us(2);
   delay_us(2);     
   output_low(DISP);
   delay_us(2);                     
   spi_xfer(SPI_PORT1,address,8);         //send address
   delay_us(2);     
   spi_xfer(SPI_PORT1,data,8);            //send data
   delay_us(2);
   output_high(DISP);
   delay_us(2);
}

/*******************************************************************************
//Read SPI data From MAX31855
*******************************************************************************/ 
void readMAX()
{
   delay_us(2);
   int32 MAXread;
   output_low(BURNER_TEMP);
   delay_us(2);
   TempByte3=spi_xfer(SPI_PORT1,0,8);
   TempByte2=spi_xfer(SPI_PORT1,0,8);
   TempByte1=spi_xfer(SPI_PORT1,0,8);
   TempByte0=spi_xfer(SPI_PORT1,0,8);
   delay_us(2);
   output_high(BURNER_TEMP);
   delay_us(2);
}


When I look at the Chip selects and Data doing it this way the data is only active for the corresponding chip select.
That is when chip select for the MAX31855 is selectived data is only seen on the SPI_IN pin
and when the chip select for the MAX7219 is selected data is only seen on the SPI_OUT pin

Maybe someone smarter than me can figure out why this happens but for now it is doing what I need.

Thanks for all the help everyone. If anyone has any ideas why this worked I am all ears.
temtronic



Joined: 01 Jul 2010
Posts: 6249
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sat Mar 24, 2018 2:04 pm     Reply with quote

Just because you don't send data out by the SPI DO line doesn't necesarily mean the SPI peripheral doesn't, at least to my old school thinking.
SPI was originally a method of 'clocking' data in and data out at the same time, send one bit out, get one in,clk, send another out, get another in. It's a form of 'full duplex' mode of serial communications.
I don't know if the SPI peripheral in a PIC will send 'zero' as bits if you're doing a 'receive only' form of SPI. What I can see is the SPI xmt buffer having random bits set and transmitting that.
That being said the 'chip select' lines _should_ disable an SPI device but....it sounds like that isn't happening, at least not properly. Perhaps you need to 'reset' the SPI bus and pause a bit between accessing the 2 devices?
You may need to load 'dummy data' into the xmt buffer when you want to receive data from the temp. sensor.
Hopefully someone very,very familiar with the actual silicon inside the PIC will reply.

Jay
Ttelmah



Joined: 11 Mar 2010
Posts: 13531

View user's profile Send private message

PostPosted: Sat Mar 24, 2018 3:09 pm     Reply with quote

You need to understand SPI.

SPI is always full duplex. A byte is sent at the same time as one is received.

If you perform the instruction:

spi_xfer(SPI_PORT1,data,8); //send data

A byte is loaded into the SPI buffer and the command returns _immediately_. The hardware starts clocking the data out at the specified rate.
At the same time the chip clocks in the data being received. May be real, or may just be garbage.
This is all going on while you perform subsequent instructions.

If instead you perform:

val=spi_xfer(SPI_PORT1,data,8); //send data

This loads the data and waits for the byte to sent and be received.

This is why I told you earlier to use a dummy variable and load this.

The key point is that if you do:

spi_xfer(SPI_PORT1,data,8); //send data
and then raise the CS, the CS line will be going up _before_ the byte has actually sent.

The delays added here are rescuing you, but basically you need to read the return, even from commands that are not actually returning anything. This then ensures that the value has completed sending.

The spi buffer will contain the last byte sent or received, if you trigger a receive only, so this is what will be sent in this case.
edbfmi1



Joined: 18 Jul 2006
Posts: 87

View user's profile Send private message

PostPosted: Sat Mar 24, 2018 3:10 pm     Reply with quote

Thank Jay,
I am not too familiar with the SPI protocol.
I did notice on the data sheet for the MAX7219 that it says the MAX7221 is a fully SPI compatible.
The MAX7219 has a “Load” instead of “Chip Select”. The data sheet says
Quote:
For the MAX7219, serial data at DIN, sent in 16-bit
packets, is shifted into the internal 16-bit shift register
with each rising edge of CLK regardless of the state of
LOAD. For the MAX7221, CS must be low to clock data
in or out. The data is then latched into either the digit or
control registers on the rising edge of LOAD/CS.
LOAD/CS must go high concurrently with or after the
16th rising clock edge, but before the next rising clock
edge or data will be lost.

I need to look into this a little more to see if this is what was causing the issues.
Thanks again for all the help!
temtronic



Joined: 01 Jul 2010
Posts: 6249
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sat Mar 24, 2018 3:48 pm     Reply with quote

Do as Mr. T. tells you

IE:
val=spi_xfer(SPI_PORT1,data,8); //send data

val is just a 'dummy' data variable, you never use data in it.
this will get rid of the nasty timing problem and the 'no display' on the MAX7221 due to the data being lost.

also, just for the sake of 'clarity'..

this
output_high(TEMP);

perhaps should be changed to
output_high(TEMP_CS); // chip select of temperature device

'TEMP' to most means a 'TEMPorary' variable, not an important item like 'chip select' !

These days compilers/lauguages allow you lots of space to call variables self descriptive names unlike the 'good old days' where we were only allow 2 characters for a variable name.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page Previous  1, 2, 3
Page 3 of 3

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group