Can SSPI and SPI be run in parallel?

Coding and general discussion relating to the compiler

Moderators: David Barker, Jerry Messina

Post Reply
User avatar
Jason
Posts: 50
Joined: Mon Mar 10, 2008 1:10 pm
Location: Australia

Can SSPI and SPI be run in parallel?

Post by Jason » Sun Mar 20, 2011 2:25 pm

Hi Guys,
I was wondering if anyone has been successful in running SPI and SSPI modules together in one program. I'm trying to run 16 MCP23S17 chips on one PICv18F452 using 2 instances of Octal's module called MCP23S17_Mult.

This idea of running 2 instances of the module was given to me by jmessina, and I renamed the modules so they were different, as well as the module line in the modules themselves, and had one set to software SPI and the other set to Harware SPI, with appropriate ports set up for each.

It kept gettting stuck when compiling it at a Writebyte line in one of the modules. I spent a long while attempting to make every sub rountine different from the other, and didn't have a win compiling it.

Can anyone see any problem with running both hardware and software spi together, or could anyone help out with getting 2 "MCP23S17_Mult" modules going?

Many thanks.

Here is the thread I started the other day at digital-diy...
http://digital-diy.com/forum/swordfish- ... t1370.html

Here is a module pack with the module in it http://digital-diy.com/file-browser/doc ... -pack.html

Here is the page that explains the module http://digital-diy.com/Swordfish-Compil ... ister.html

Jerry Messina
Swordfish Developer
Posts: 1473
Joined: Fri Jan 30, 2009 6:27 pm
Location: US

Post by Jerry Messina » Sun Mar 20, 2011 3:25 pm

One thing I've noticed is that the file MCP23S17_MULT.bas calls a routine named 'EnableSPI()', but that sub isn't in my copy of SPI.bas.

If you open SPI.bas, you'll see that routine referenced in the comments at the top. To add it, open SPI.bas and add the following to the end

Code: Select all

Public Sub EnableSPI()
    Dim pDummy As Byte
    Enabled = true
    pDummy = SSPBuffer
    SSPIF = 0
End Sub
Now, to use two copies of MCP23S17_MULT.bas:
1- copy the file, and rename it to MCP23S17_MULT2.bas
2 - there's two things in the new file that you have to change. The first is to give it a new module name, and second is the '#Option MCP_CS' that defines the chip select pin. You need to have a different option for the second file, say "#Option MCP2_CS". To do this, there's a few spots that need replacing. Edit the new copy and replace

Code: Select all

Module MCP23S17_MULT

// hardware or software SPI...
#if IsOption(MCPSPI_SOFTWARE) And Not (MCPSPI_SOFTWARE in (true, false))
   #error MCPSPI_SOFTWARE, "Invalid option, must be TRUE or FALSE."
#endif
#option MCPSPI_SOFTWARE = false

// enable delays...
#if IsOption(MCP23S17_DELAYS) And Not (MCP23S17_DELAYS in (true, false))
   #error MCP23S17_DELAYS, "Invalid option, must be TRUE or FALSE."
#endif
#option MCP23S17_DELAYS = false

#option MCP23S17_DELAY_US = 10
Const MCP23S17_DELAY_US_ = MCP23S17_DELAY_US

#if MCPSPI_SOFTWARE=true // use software SPI...
Include "sspi.bas"
#else // use hardware SPI...
Include "SPI.BAS"
#EndIf

#Option MCP_CS  = PORTC.1
//#Option MCP_RST = PORTC.2   // may be commented If RST is Not used

// validate SCK pin...
#If IsOption(MCP_CS) And Not IsValidPortPin(MCP_CS) 
   #Error MCP_CS, "Invalid option. MCP_CS must be a valid port pin."
#EndIf

// validate RST pin...
#If IsOption(MCP_RST) And Not IsValidPortPin(MCP_RST) 
   #Error MCP_RST, "Invalid option. MCP_RST must be a valid port pin."
#EndIf

Public Dim 
   CS As MCP_CS.MCP_CS@   // Chip select

#if IsOption(MCP_RST)
Public Dim
   RST As MCP_RST.MCP_RST@    // RST pin
#endif
with

Code: Select all

Module MCP23S17_2

// hardware or software SPI...
#if IsOption(MCPSPI_SOFTWARE) And Not (MCPSPI_SOFTWARE in (true, false))
   #error MCPSPI_SOFTWARE, "Invalid option, must be TRUE or FALSE."
#endif
#option MCPSPI_SOFTWARE = false

// enable delays...
#if IsOption(MCP23S17_DELAYS) And Not (MCP23S17_DELAYS in (true, false))
   #error MCP23S17_DELAYS, "Invalid option, must be TRUE or FALSE."
#endif
#option MCP23S17_DELAYS = false

#option MCP23S17_DELAY_US = 10
Const MCP23S17_DELAY_US_ = MCP23S17_DELAY_US

#if MCPSPI_SOFTWARE=true // use software SPI...
Include "sspi.bas"
#else // use hardware SPI...
Include "SPI.BAS"
#EndIf

#Option MCP2_CS  = PORTC.1
//#Option MCP_RST = PORTC.2   // may be commented If RST is Not used

// validate SCK pin...
#If IsOption(MCP2_CS) And Not IsValidPortPin(MCP2_CS)
   #Error MCP_CS, "Invalid option. MCP2_CS must be a valid port pin."
#EndIf

// validate RST pin...
#If IsOption(MCP_RST) And Not IsValidPortPin(MCP_RST)
   #Error MCP_RST, "Invalid option. MCP_RST must be a valid port pin."
#EndIf

Public Dim
   CS As MCP2_CS.MCP2_CS@   // Chip select

#if IsOption(MCP_RST)
Public Dim
   RST As MCP_RST.MCP_RST@    // RST pin
#endif
You can access the routines in the new file using the module name "MCP23S17_2"

like this:

Code: Select all

device = 18f452

#option MCP_CS = PORTB.1
#option MCP2_CS = PORTA.1

include "mcp23s17_mult.bas"
include "mcp23s17_mult2.bas"


// only need to call it once
MCP23S17_MULT.Initialize()


MCP23S17_MULT.WritePortA(0, $55)
MCP23S17_2.WritePortA(0, $55)


User avatar
Jason
Posts: 50
Joined: Mon Mar 10, 2008 1:10 pm
Location: Australia

Post by Jason » Sun Mar 20, 2011 4:35 pm

Trying it now Jerry,
Thank you so much..

User avatar
Jason
Posts: 50
Joined: Mon Mar 10, 2008 1:10 pm
Location: Australia

Post by Jason » Sun Mar 20, 2011 4:53 pm

Hi Jerry,
I'm just working through this and I just realized and wondered, will 2 modules like this both work with hardware spi?

if it will, that is so amazing...

Jerry Messina
Swordfish Developer
Posts: 1473
Joined: Fri Jan 30, 2009 6:27 pm
Location: US

Post by Jerry Messina » Sun Mar 20, 2011 5:10 pm

yes, they'll both use the hardware SPI module. The only restriction is that you can't use the routines in an interrupt since they share the same SPI hardware.

You'd have to make a few more changes to the various "#option"s if you wanted them to be different (ie one hardware, one software)

User avatar
Jason
Posts: 50
Joined: Mon Mar 10, 2008 1:10 pm
Location: Australia

Post by Jason » Sun Mar 20, 2011 5:27 pm

It worked beautifully Jerry!

Full control over all 16 devices, and more I'd imagine using this method.

Much was learned out of that exercise! Thank you..

Now I can order my parts and get this ferris wheel flashing the house down!!

Jerry Messina
Swordfish Developer
Posts: 1473
Joined: Fri Jan 30, 2009 6:27 pm
Location: US

Post by Jerry Messina » Mon Mar 21, 2011 2:44 pm

If you were going to extend this for more devices, it might make more sense to use a single module and just add in support for it to use multiple chip selects, perhaps controlled via the 'address' byte, so $00-$07 --> CS1, $10-$17 --> CS2, etc.
It kept gettting stuck when compiling it at a Writebyte line in one of the modules.
I see this too when trying to use different options. I'll post a question about this in a different topic.

User avatar
Jason
Posts: 50
Joined: Mon Mar 10, 2008 1:10 pm
Location: Australia

Post by Jason » Mon Mar 21, 2011 4:16 pm

Hi Jerry,
I think your other idea works ok
This is how I used it....

Code: Select all

{
*****************************************************************************
*  Name    : UNTITLED.BAS                                                   *
*  Author  : [select VIEW...EDITOR OPTIONS]                                 *
*  Notice  : Copyright (c) 2011 [select VIEW...EDITOR OPTIONS]              *
*          : All Rights Reserved                                            *
*  Date    : 3/16/2011                                                      *
*  Version : 1.0                                                            *
*  Notes   :                                                                *
*          :                                                                *
*****************************************************************************
}
Device = 18F452
Clock = 20
Config OSC = xt

Include "mcp23s17_mult.bas"
Include "mcp23s17_mult2.bas" 
Dim tmpLongWord As Byte       //just a couple of bit patterns I was playing with
Dim tmpLongWord2 As Byte 
Dim tmpLongWord3 As Byte 
Dim tmpLongWord4 As Byte 
Const mcp1 = %000,  // First chip address
      mcp2 = %001,   // 2nd  ""
      mcp3 = %010,
      mcp4 = %011,
      mcp5 = %100,
      mcp6 = %101,
      mcp7 = %110,
      mcp8 = %111
      

 
MCP23S17_MULT.SetTrisPortA(mcp1,$00)
MCP23S17_MULT.SetTrisPortB(mcp1,$00)
MCP23S17_MULT.SetTrisPortA(mcp2,$00)
MCP23S17_MULT.SetTrisPortB(mcp2,$00)
MCP23S17_MULT.SetTrisPortA(mcp3,$00)
MCP23S17_MULT.SetTrisPortB(mcp3,$00)
MCP23S17_MULT.SetTrisPortA(mcp4,$00)
MCP23S17_MULT.SetTrisPortB(mcp4,$00)
MCP23S17_MULT.SetTrisPortA(mcp5,$00)
MCP23S17_MULT.SetTrisPortB(mcp5,$00)
MCP23S17_MULT.SetTrisPortA(mcp6,$00)
MCP23S17_MULT.SetTrisPortB(mcp6,$00) 
MCP23S17_MULT.SetTrisPortA(mcp7,$00)
MCP23S17_MULT.SetTrisPortB(mcp7,$00)
MCP23S17_MULT.SetTrisPortA(mcp8,$00)
MCP23S17_MULT.SetTrisPortB(mcp8,$00) 
MCP23S17_2.SetTrisPortA(mcp1,$00)
MCP23S17_2.SetTrisPortB(mcp1,$00)
MCP23S17_2.SetTrisPortA(mcp2,$00)
MCP23S17_2.SetTrisPortB(mcp2,$00)
MCP23S17_2.SetTrisPortA(mcp3,$00)
MCP23S17_2.SetTrisPortB(mcp3,$00)
MCP23S17_2.SetTrisPortA(mcp4,$00)
MCP23S17_2.SetTrisPortB(mcp4,$00)
MCP23S17_2.SetTrisPortA(mcp5,$00)
MCP23S17_2.SetTrisPortB(mcp5,$00)
MCP23S17_2.SetTrisPortA(mcp6,$00)
MCP23S17_2.SetTrisPortB(mcp6,$00) 
MCP23S17_2.SetTrisPortA(mcp7,$00)
MCP23S17_2.SetTrisPortB(mcp7,$00)
MCP23S17_2.SetTrisPortA(mcp8,$00)
MCP23S17_2.SetTrisPortB(mcp8,$00) 
TRISD=%00000000 
//Low(PORTB.0)
tmpLongWord = %10101010
tmpLongWord2 = %01010101
tmpLongWord3 = %11111111
tmpLongWord4 = %00000000
While True

DelayMS(5)
MCP23S17_MULT.WritePortA(mcp1, tmpLongWord3)
MCP23S17_MULT.WritePortB(mcp1, tmpLongWord3)
DelayMS(5)
MCP23S17_MULT.WritePortA(mcp2, tmpLongWord3)
MCP23S17_MULT.WritePortB(mcp2, tmpLongWord3)
DelayMS(5)
MCP23S17_MULT.WritePortA(mcp3, tmpLongWord3)
MCP23S17_MULT.WritePortB(mcp3, tmpLongWord3)
DelayMS(5)
MCP23S17_MULT.WritePortA(mcp4, tmpLongWord3)
MCP23S17_MULT.WritePortB(mcp4, tmpLongWord3)
DelayMS(5)
MCP23S17_MULT.WritePortA(mcp5, tmpLongWord3)
MCP23S17_MULT.WritePortB(mcp5, tmpLongWord3)
DelayMS(5)
MCP23S17_MULT.WritePortA(mcp6, tmpLongWord3)
MCP23S17_MULT.WritePortB(mcp6, tmpLongWord3)
DelayMS(5)
MCP23S17_MULT.WritePortA(mcp7, tmpLongWord3)
MCP23S17_MULT.WritePortB(mcp7, tmpLongWord3)
DelayMS(5)
MCP23S17_MULT.WritePortA(mcp8, tmpLongWord3)
MCP23S17_MULT.WritePortB(mcp8, tmpLongWord3)
DelayMS(5)
MCP23S17_2.WritePortA(mcp1, tmpLongWord3) 
MCP23S17_2.WritePortB(mcp1, tmpLongWord3) 
DelayMS(5)
MCP23S17_2.WritePortA(mcp2, tmpLongWord3) 
MCP23S17_2.WritePortB(mcp2, tmpLongWord3) 
DelayMS(5)
MCP23S17_2.WritePortA(mcp3, tmpLongWord3) 
MCP23S17_2.WritePortB(mcp3, tmpLongWord3) 
DelayMS(5)
MCP23S17_2.WritePortA(mcp4, tmpLongWord3) 
MCP23S17_2.WritePortB(mcp4, tmpLongWord3) 
DelayMS(5)
MCP23S17_2.WritePortA(mcp5, tmpLongWord3) 
MCP23S17_2.WritePortB(mcp5, tmpLongWord3) 
DelayMS(5)
MCP23S17_2.WritePortA(mcp6, tmpLongWord3) 
MCP23S17_2.WritePortB(mcp6, tmpLongWord3) 
DelayMS(5)
MCP23S17_2.WritePortA(mcp7, tmpLongWord3) 
MCP23S17_2.WritePortB(mcp7, tmpLongWord3) 
DelayMS(5)
MCP23S17_2.WritePortA(mcp8, tmpLongWord3) 
MCP23S17_2.WritePortB(mcp8, tmpLongWord3) 
DelayMS(5)
MCP23S17_MULT.WritePortA(mcp1, tmpLongWord4)
MCP23S17_MULT.WritePortB(mcp1, tmpLongWord4)
DelayMS(5)
MCP23S17_MULT.WritePortA(mcp2, tmpLongWord4)
MCP23S17_MULT.WritePortB(mcp2, tmpLongWord4)
DelayMS(5)
MCP23S17_MULT.WritePortA(mcp3, tmpLongWord4)
MCP23S17_MULT.WritePortB(mcp3, tmpLongWord4)
DelayMS(5)
MCP23S17_MULT.WritePortA(mcp4, tmpLongWord4)
MCP23S17_MULT.WritePortB(mcp4, tmpLongWord4)
DelayMS(5)
MCP23S17_MULT.WritePortA(mcp5, tmpLongWord4)
MCP23S17_MULT.WritePortB(mcp5, tmpLongWord4)
DelayMS(5)
MCP23S17_MULT.WritePortA(mcp6, tmpLongWord4)
MCP23S17_MULT.WritePortB(mcp6, tmpLongWord4)
DelayMS(5)
MCP23S17_MULT.WritePortA(mcp7, tmpLongWord4)
MCP23S17_MULT.WritePortB(mcp7, tmpLongWord4)
DelayMS(5)
MCP23S17_MULT.WritePortA(mcp8, tmpLongWord4)
MCP23S17_MULT.WritePortB(mcp8, tmpLongWord4)
DelayMS(5)
MCP23S17_2.WritePortA(mcp1, tmpLongWord4) 
MCP23S17_2.WritePortB(mcp1, tmpLongWord4) 
DelayMS(5)
MCP23S17_2.WritePortA(mcp2, tmpLongWord4) 
MCP23S17_2.WritePortB(mcp2, tmpLongWord4) 
DelayMS(5)
MCP23S17_2.WritePortA(mcp3, tmpLongWord4) 
MCP23S17_2.WritePortB(mcp3, tmpLongWord4) 
DelayMS(5)
MCP23S17_2.WritePortA(mcp4, tmpLongWord4) 
MCP23S17_2.WritePortB(mcp4, tmpLongWord4) 
DelayMS(5)
MCP23S17_2.WritePortA(mcp5, tmpLongWord4) 
MCP23S17_2.WritePortB(mcp5, tmpLongWord4) 
DelayMS(5)
MCP23S17_2.WritePortA(mcp6, tmpLongWord4) 
MCP23S17_2.WritePortB(mcp6, tmpLongWord4) 
DelayMS(5)
MCP23S17_2.WritePortA(mcp7, tmpLongWord4) 
MCP23S17_2.WritePortB(mcp7, tmpLongWord4) 
DelayMS(5)
MCP23S17_2.WritePortA(mcp8, tmpLongWord4) 
MCP23S17_2.WritePortB(mcp8, tmpLongWord4)


Wend

And this crazy design I made in isis actually worked...
http://members.iinet.net.au/~efry/FW.JPG

here are the isis files if you want to check it out....
I must mention that this was thown together with out regard for tidyness, I just wanted to know if it would work!!


http://members.iinet.net.au/~efry/

User avatar
RangerBob
Posts: 152
Joined: Thu May 31, 2007 8:52 am
Location: Beds, UK

Post by RangerBob » Tue Mar 22, 2011 11:06 am

Perhaps you should think about putting some of that into loops. ;) Might save you lots of legwork later!

eg.

Code: Select all

For n = 0 to 7
MCP23S17_MULT.SetTrisPortA(n,$00) 
MCP23S17_MULT.SetTrisPortB(n,$00)
next
and

Code: Select all

For n = 0 to 7
DelayMS(5)
MCP23S17_MULT.WritePortA(n, tmpLongWord3)
MCP23S17_MULT.WritePortB(n, tmpLongWord3) 
next

//etc
[/code]

User avatar
Jason
Posts: 50
Joined: Mon Mar 10, 2008 1:10 pm
Location: Australia

Post by Jason » Tue Mar 22, 2011 11:56 am

Yes, I agree.
Thanks for that. That will teach me for posting messy code and having an affinity with ctrl c and v.

He he...

I'm starting work on understanding how to control the Ti chip, TLC5940.

It looks like the ultimate for driving large arrays of leds, individual channel dimming, broken led feedback among a long list of features.

I think I'll stick to using the uln2803 chips to do the driving in this project, because it will take me a long time, but a module for that chip would be a nice compliment to the vast array on the wiki so far....

There are alot of projects on this chip done with Arduino dev kits on the net, I think SF needs to come to the party with a module (cough.., anyone?)

Post Reply