Is it possible to store Pin ref in a structure field

Coding and general discussion relating to the compiler

Moderators: David Barker, Jerry Messina

Post Reply
User avatar
octal
Registered User
Registered User
Posts: 583
Joined: Thu Jan 11, 2007 12:49 pm
Location: Paris IDF
Contact:

Is it possible to store Pin ref in a structure field

Post by octal » Fri Jul 10, 2020 9:16 pm

Hi,
is it possible (and what's the best way if any) to store physical pins references in SF Structures?

To be explainful
When we create sub/func, we can pass a pin ByRef and then let the procedure act on the pin.

I need to pass a set of pins to a procedure/function, and to make things clean, it would be nice to be able to store the ref to the pins in a structure and pass the structure to the sub/func.

Regards

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

Re: Is it possible to store Pin ref in a structure field

Post by Jerry Messina » Fri Jul 10, 2020 11:46 pm

The library module shift.bas shows the definitions and usage of programmable pins...

Code: Select all

// a pin structure...
structure TPin
   PortAddr as word         // PORT addr (input), LAT addr (output)
   TrisAddr as word         // TRIS addr
   Pin      as byte
   PinMask  as byte
end structure
The SetInput() and SetOutput() routines show how to setup the data structures, while Out() and In() show a bit of how to use those structures.

I would only do this if you really need to. Runtime programmable pins carry a LOT of overhead.

You have to be careful... a lot of older examples show adding +9 and +18 to the PORT address to get TRIS and LAT and that doesn't work for a number of newer devices. The LAT_OFFSET and TRIS_OFFSET macros in shift.bas show how to find the correct addresses of those registers

Code: Select all

{
****************************************************************************
* Name    : LAT_OFFSET/TRIS_OFFSET                                         *
* Purpose : these macros load 'wresult' with the LAT and TRIS register     *
*         : offsets from PORT. they assume wresult is a 16-bit word        *
*         : located in the access bank (PROD is a good choice)             *
****************************************************************************
}
macro LAT_OFFSET(wresult)
    asm-
        movlw low(LATA-PORTA)
        movwf wresult
        movlw high(LATA-PORTA)
        movwf wresult+1
    end asm
end macro

macro TRIS_OFFSET(wresult)
    asm-
        movlw low(TRISA-PORTA)
        movwf wresult
        movlw high(TRISA-PORTA)
        movwf wresult+1
    end asm
end macro
Even after that I recall there are a few devices/ports where this doesn't work (J94 PORTK???)

User avatar
octal
Registered User
Registered User
Posts: 583
Joined: Thu Jan 11, 2007 12:49 pm
Location: Paris IDF
Contact:

Re: Is it possible to store Pin ref in a structure field

Post by octal » Fri Jul 10, 2020 11:56 pm

Hi Jerry,
thank you for the answer. The offset thing (18 ...) is the main problem I was facing. I couldn't really find a clean way to avoid it to make things hardware independant.
We need POINTERs support in Swordfish BASIC ... :mrgreen:

bitfogav
Registered User
Registered User
Posts: 155
Joined: Sat Oct 09, 2010 1:39 pm
Location: United Kingdom

Re: Is it possible to store Pin ref in a structure field

Post by bitfogav » Sat Jul 11, 2020 12:20 am

I think Jerrys "multiple software I2C module" also shows some structure pin def examples.. :mrgreen:

Code: Select all

// a pin structure...
public structure TPin
    PortAddr as word
    Pin      as byte
    PinMask  as byte
end structure 

https://www.sfcompiler.co.uk/wiki/pmwik ... User.PSI2C

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

Re: Is it possible to store Pin ref in a structure field

Post by Jerry Messina » Sat Jul 11, 2020 9:49 am

I couldn't really find a clean way to avoid it to make things hardware independant.
You can't really make it truly hardware independent.

The problem is that the PORTx, LATx, and TRISx registers change offsets depending on the device, so once you compile it for
one device another device won't work. Here are examples showing some of the different layouts I've run across...

Code: Select all

// "standard" addresses
D:\Swordfish\Includes\18F4520.bas
   PORTA as byte absolute $0F80
   LATA  as byte absolute $0F89     // LAT  = PORT + 9
   TRISA as byte absolute $0F92     // TRIS = PORT + 18

D:\Swordfish\Includes\18F24K40.bas
   PORTA as byte absolute $0F8D
   LATA  as byte absolute $0F83
   TRISA as byte absolute $0F88

D:\Swordfish\Includes\18F24K42.bas
   PORTA as byte absolute $3FCA
   LATA  as byte absolute $3FBA
   TRISA as byte absolute $3FC2

D:\Swordfish\Includes\18F24Q10.bas
   PORTA as byte absolute $0F8C
   LATA  as byte absolute $0F82
   TRISA as byte absolute $0F87

// the 18F97J94 PORTK and PORTL have a different PORT/LAT/TRIS
// layout than the other ports
D:\Swordfish\Includes\18F97J94.bas
   PORTK as byte absolute $0EE7
   LATK as byte absolute $0EE8
   TRISK as byte absolute $0EE9
If you look carefully you''ll see that not only are the offsets between them different, but the order is different too!
That's why I had to replace the code in shift.bas with those macros to compute the offsets.

We need POINTERs support in Swordfish BASIC
As far as port pins go, since the PIC itself has no mechanism for such a thing I don't know that there's a way to do.

Post Reply