chipKIT® Development Platform

Inspired by Arduino™

SPI problem [SOLVED, caused by power difference]

Created Sun, 21 Aug 2011 23:40:37 +0000 by rasmadrak


rasmadrak

Sun, 21 Aug 2011 23:40:37 +0000

Hi there, I cannot for the life of me get SPI working with my display on a Chipkit Max32.

I have an Arduino Mega2560 that compiles the exact same code, same environment and same compiler - and it works just fine. The Max32 with the exact same layout, including the cabling etc, does not work.

It is not a bit-order thing, the code use MSBFIRST. Also, the voltage requirements should be very low, around 0.7 V for a logic 1 - so the voltage difference should not matter either.

Please, does anyone have a clue what could be wrong here? Surely there must be something the Mega2560 does "behind the scenes" that the Max32 doesn't? I've connected my dataout/clock cables to the center pins of J13 - do I need to move any jumpers for these to work (currently both are set to master)? I need to have Max32 acting as a master SPI.

The whole reason for me switching to Max32 was to drive the display with it, so I'm a sad camper currently. :(


dc101

Mon, 22 Aug 2011 00:30:42 +0000

Check the max clockrate of your LCD. The Max32 is clocked at 80 MHz while the Mega2560 is 16 MHz. This will make a big difference in the clockrate of your SPI bus.

I tried to use my old LCD that supports SPI as well, but I can't set the clockrate of the Max32 slow enough. My LCD only supports a max clock of 18.182 kHz, unfortunately for now the slowest clock speed for SPI on the Max32 is 625 kHz.

I ended up making a SPI bus manually by using digitalWrite for the clock and data and saw that at least my LCD still works, but manual SPI bus is very tedious.

-Tim

Hi there, I cannot for the life of me get SPI working with my display on a Chipkit Max32. I have an Arduino Mega2560 that compiles the exact same code, same environment and same compiler - and it works just fine. The Max32 with the exact same layout, including the cabling etc, does not work. It is not a bit-order thing, the code use MSBFIRST. Also, the voltage requirements should be very low, around 0.7 V for a logic 1 - so the voltage difference should not matter either. Please, does anyone have a clue what could be wrong here? Surely there must be something the Mega2560 does "behind the scenes" that the Max32 doesn't? I've connected my dataout/clock cables to the center pins of J13 - do I need to move any jumpers for these to work (currently both are set to master)? I need to have Max32 acting as a master SPI. The whole reason for me switching to Max32 was to drive the display with it, so I'm a sad camper currently. :(


dc101

Mon, 22 Aug 2011 01:30:03 +0000

I played around with this some more and realized it's easy to just edit SPI.h and add your own SPI_CLOCK_DIVxxxx.

I added #define SPI_CLOCK_DIV1024 0x1FF to SPI.h which got me down to 78.2 kHz. SPIxBRG is only a 9 bit register, so I believe that 78.2 is the slowest SPI can do if the main clock is still at 80MHz (someone please correct me if I'm wrong).

Hopefully this helps with your situation. For mine I still need to figure out how to change the main clock speed.

-Tim


dc101

Mon, 22 Aug 2011 02:27:49 +0000

If you need to go slower still, I finally figured out how to change the main clock speed. This code keeps the main core at 80 MHz but sets the peripheral bus to 20 MHz. Obviously you will have to play around with setting the SPI clock divider and the PBCLK based on your needs.

////////////////80MHz/20MHz(SYSCLK/PBCLK)///////////////////////// //IMPORTANT: To Prevent Flash Timing Issues when in Higher Frequency SYSTEMConfigPerformance( 80000000UL ); // + Always while switching to higher frequency the // + First thing to take care is the Flsh Timing // + Else the Program would Hang and Core will not work OSCConfig(OSC_POSC_PLL, OSC_PLL_MULT_20,OSC_PLL_POST_1,0); //Realign the PBCLK frequency Divider for new Frequency mOSCSetPBDIV( OSC_PB_DIV_4 );


rasmadrak

Mon, 22 Aug 2011 08:38:35 +0000

Hi there,

The max clock speed of my display should be at least 8 Mhz, and I've tried running the Arduino with both DIV2 -> DIV16 and it works just fine. Using the lower refresh makes it flicker thou, as expected. The fastest becomes 8 Mhz on Mega2560 and works just fine.

It doesn't make a difference on the Chipkit however, even if the clock cycle is far below what the display should be able to handle. With DIV16 it's about 5 Mhz.

I've connected the following: 7,6,5,4 = control pins (display enable, row data, row clock, column latch) J13 centerpins = clock and data pins.

I have yet to connect the Chipkit by the 50->53 pins since I need to make new cables for that. Do I need to modify the jumpers in any way?

For those who are interested, I'm building a Pinball machine and I am using SPI to control the LED display of the machine. Until I've recently ran out of RAM on the Mega it worked just fine. But the Chipkit is superior in many ways which is why I would really like this to work.


jasonk

Mon, 22 Aug 2011 16:14:06 +0000

@dc101

Just be careful when reducing the peripheral bus clock speed. There may be some libraries that are configured by default for 80 MHz.


dc101

Mon, 22 Aug 2011 18:01:46 +0000

@Jason Good point about the other libraries. I think I really just to need to get a decent LCD.

@rasmadrak I wasn't trying to imply that your speed was too slow, in fact I thought the clock rate of your ChipKit might have been too fast, as was the case for me.

I haven't tried the J13 pins, I've only used 50-53. I will check J13 with my scope tonight and see if there's any difference. You shouldn't need to modify the jumpers, just ensure the jumpers on the Max32 are set to master and not slave.


rasmadrak

Mon, 22 Aug 2011 18:19:37 +0000

Hi there... It would seem I'm out of luck -

"Dear Robert, the display has a power supply mounted that deliver 5VDC. The logic is also 5V level. I can’t say it for sure that the display will work also with 3,3V logic."

Is there any easy way I can turn these 3.3V to 5V? All six pins probably have to use 5V, at hopefully around 8MHz...


dc101

Mon, 22 Aug 2011 18:57:03 +0000

I'm new to electronics, but would pull up resistors tied to a 5V source help? The Max32 ref manual says that the digital IO pins are 5V tollerant.


rasmadrak

Mon, 22 Aug 2011 19:59:25 +0000

Hmm... You mean simply adding ~1.5V to the 3.3V? I guess that could work. If the 1.5V doesn't trigger the logic (which it doesn't seem to do) this should be ok...

I'm not a grandmaster wiz at electronics either, so anyone with more experience is more than welcome to comment! :)


GeneApperson

Mon, 22 Aug 2011 20:13:24 +0000

All of the pins on the PIC32 devices support an open drain output mode. This currently isn't supportd by the pinMode function (I'm going to add it in a future version). However, you can bypass the pinMode function and write directly to the register.

If you set the output pins to open drain, then you can use pull-ups to 5V and get 5V output levels.

The relevant registers are the ODC registers. ODCx, where x is A, B, C, D, etc. for the particular port. When the PIC32 comes out of reset, the ODC registers are set to 0, which makes all pins normal outputs (if they are ouputs). Setting ODC an register bit to 1 makes the corresponding pin be open drain.

You need to refer to either the schematic or the pin-out tables at the end of the reference manual to figure out which PORTs and bits correspond to the pins you need. Assuming that you needed PORT D, bit n, the following statement would set the bit in the ODC register making that pin be open drain.

ODCDSET = (1<<n);

This will turn it back to a normal output

ODCDCLR = (1<<n);

Of course, you have to make the pin be an output before it's an open drain output.

Gene Apperson Digilent


rasmadrak

Mon, 22 Aug 2011 20:40:42 +0000

Hi there!

Thanks for this reply, but I'm afraid I have to ask more questions.. :)

I tried using pin 2, which would be bit 3, Port E, correct? I then tried both ODCESET = (1<<3); and ODCESET = 0xFF. But the voltage level is still 3.28V.

Is there something more I need to do, or does it require external components as well? If so - how should it be wired up?

Thanks again!


rasmadrak

Mon, 22 Aug 2011 20:45:33 +0000

[url]http://focus.ti.com/logic/docs/orphan.tsp?contentId=123208[/url]

Is this the correct application? I figure I need to add +5V -> resistor -> output pin.. I'll give it a shot.


rasmadrak

Mon, 22 Aug 2011 21:21:16 +0000

No success at all...

Maybe I should continue this topic in a different thread, since it's not actually related to the SPI.


dc101

Tue, 23 Aug 2011 02:11:16 +0000

Try this, I just got it working. Also I've attached a very precise schematic :lol: of my set up. Hopefully it is self explanatory, but in case not the blue line is my scope probe, the black line coming off is to the common ground. I forgot to label the connections from the max32 but the black wire is ground as I'm sure you've figured, the red wire is from pin 37. Probe between the resistor and the max32 and you should be good, if you probe between the resistor and the power supply it will always be +5v.

Also, the resistor is 10K (brown black orange, so you don't have to look it up). Not sure how to determine the proper resistor value though, I borrowed them from the I2C section. Perhaps someone else can help with the values.

void setup() {
 
  pinMode(37, OUTPUT); 
  ODCESET = 0x00000001;

}

void loop() {
  digitalWrite(37, HIGH);
  delay(500);
  digitalWrite(37, LOW);
  delay(500);

}

rasmadrak

Tue, 23 Aug 2011 06:20:30 +0000

Lovely schematics! ;)

I will check this out later today. :) Someone also suggested something like this [url]http://www.sparkfun.com/products/8745[/url]. In my opinion, the latter is cleaner. Too bad I've already placed an order a couple of days ago from Sparkfun..


hairymnstr

Tue, 23 Aug 2011 09:56:29 +0000

A 74HCTxx logic/buffer chip could be a good solution. They are TTL compatible (i.e. 1 = 2.0v or more) so will trigger off a 3.3V CMOS input without error even while running off 5V (and therefore driving outputs at 5V). A 74HCT125 is a favourite for buffering SPI connections. If you post a schematic I might be able to provide more detailed suggestions.

EDIT: I've just realised this post makes no sense here, I must have missed the page 2 link first time I read this.


GeneApperson

Tue, 23 Aug 2011 15:53:17 +0000

Perhaps someone else can help with the values.

The formula is Vo = Vi * (1 - e^-t/R*C)

R*C is called a time constant. One time constant results in a voltage rise to about 60% of Vcc. You have to estimate the capacitance. Assuming a pin capacitance of 50pF (which is probably conservative unless you have a long wire run), the 10K resistor gives a rise time of about 500ns. So this would limit operation to well under 2Mhz (probably in the 750Khz range)

You need to determine the desired operating frequency, figure about 4 or 5 times the rise time for each half cycle. Determine the pin capacitance (or estimate it) and you can then compute the R.

Of course, estimating the pin capacitance is a black art. Solderless breadboards have a very large capacitance compared to PCB traces or short wires.

Open drain outputs don't work well for high frequency operation. Using the 74HCTxxx buffers suggested earlier is a good idea. We've done this on several of our boards. They have 5V tolerant inputs when operated at 3.3V and a threshold that allows 3.3V inputs when operated at 5V.

Gene Apperson Digilent


dc101

Wed, 24 Aug 2011 13:42:15 +0000

Appreciate the info, this certainly explains why the trace looked like garbage on my scope at the faster rates.

the 10K resistor gives a rise time of about 500ns. So this would limit operation to well under 2Mhz (probably in the 750Khz range) You need to determine the desired operating frequency, figure about 4 or 5 times the rise time for each half cycle. Determine the pin capacitance (or estimate it) and you can then compute the R. Of course, estimating the pin capacitance is a black art. Solderless breadboards have a very large capacitance compared to PCB traces or short wires.


rasmadrak

Sat, 10 Sep 2011 01:22:46 +0000

Hi there!

Solved this "problem" with a logic converter from Futurlec. Now I've got a nice 16+ color display on my machine instead of a flickering 6 color one... Thanks Chipkit! :D

I can probably push this a lot further (the display runs fine with DIV4 = 20MHz!) but I need the rest of the processing power to load frames of a SD card, run lights and parse serial commands. Phew.

Anywho - The SPI runs as intended. The problem was the voltage difference!