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 CCS Technical Support

How do I pass a generic pin argument to a function?

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Pavel Kolinko



Joined: 15 Mar 2005
Posts: 10

View user's profile Send private message

How do I pass a generic pin argument to a function?
PostPosted: Fri May 20, 2005 2:10 pm     Reply with quote

I haven't been able to figure out a way to do the following task, which would be very useful in a variety of functions that I have written.

At the moment I am implementing an SPI bus (in software), so I will use it as an example.

Here is a function that sends 1 byte via SPI:

Code:
#define DEV_ENABLE PIN_C5
#define SDATA          PIN_C4
#define SCLK            PIN_C3

/* insert lots of main() code here :grin:  */

void SPI_send8(BYTE data)
{
   BYTE i;
   output_low(ENABLE);

                 for(i=0;i<8;++i)
                        {
                         output_bit(SDATA, shift_left(&data,1,0));
                         output_high(SCLK);
                         output_low (SCLK);
                         }

       output_high(DEV_ENABLE); 
}


Here is the problem:
In order to implement the SPI bus && keep the SPI_send8 function generic, the function needs to know which ENABLE line to use.

I would like to pass to the function an extra argument to make DEV_ENABLE a variable, instead of a constant.
However, I don't want to put an if-else type structure inside the function.
I would like to pass the ENABLE pin address to the function directly.
The problem is that the PINS are all boolean, so I can't pass by reference
(pointers) Sad.


Here is a pseudo code that demonstrates the idea,
but unfortunately is not possible:

Code:
#define DEV1_ENABLE    PIN_C6
#define DEV2_ENABLE    PIN_C5
#define SDATA              PIN_C4
#define SCLK                PIN_C3

int1 *ptr_device_enable_ID;

/* insert lots of main() code here :grin: */


if(DEVICE_1)
  ptr_device_enable_ID=DEV1_ENABLE;
else 
  ptr_device_enable_ID=DEV2_ENABLE;

/* again, lots of other code here */

void SPI_send8(BYTE data, int1 *ptr_device_enable_ID)
{
   BYTE i;
   output_low(ptr_device_enable_ID);

                 for(i=0;i<8;++i)
                        {
                         output_bit(SDATA, shift_left(&data,1,0));
                         output_high(SCLK);
                         output_low (SCLK);
                         }

       output_high(ptr_device_enable_ID); 
}


If I could pass the addresses of the pins in variable/pointer/structure form
to the functions directly,
it would eliminate the need to pass to the functions a bunch of flags.
Writing if-else or switch() for every function to test for the flags
seems like a big waste of ROM, since it is known ahead of time
which data line needs to be used.

Any advice would be much appreciated!
Thanks,
Pavel
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri May 20, 2005 2:19 pm     Reply with quote

Here are some posts that show how to re-write the output_high()
and output_low() functions so they can accept a variable.

Read Mark's post with his functions: my_output_high() and my_output_low():
http://www.ccsinfo.com/forum/viewtopic.php?t=18233

Tomi made a post on this:
http://www.ccsinfo.com/forum/viewtopic.php?t=222
Pavel Kolinko



Joined: 15 Mar 2005
Posts: 10

View user's profile Send private message

PostPosted: Fri May 20, 2005 2:21 pm     Reply with quote

Thank you!
I will check these out!
Ttelmah
Guest







PostPosted: Fri May 20, 2005 2:38 pm     Reply with quote

No 'warranties' here, writing these without testing, but it should be possible to do this with something like:
Code:

#define NUMPORTS (5)

int8 IOarray[numports];
#byte IOarray = 0xF80

#define set_bit(x) IOarray[(x-PIN_A0)>>3]=IOarray[(x-PIN_A0)>>3]|(1<<(x&3))
#define clear_bit(x) IOarray[(x-PIN_A0)>>3]=IOarray[(x-PIN_A0)>>3]&((1<<(x&3))^0xFF)


This for a 18F chip with five I/O ports.

Might be worth an 'experiment'.

Best Wishes
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri May 20, 2005 2:42 pm     Reply with quote

I know that you posted some functions too, recently, and I wanted
to post a link to them as well, but I couldn't find them.
Ttelmah
Guest







PostPosted: Fri May 20, 2005 3:13 pm     Reply with quote

Yes, I think I posted some routines earlier, but these macros, are an 'off the cuff' attempt to make a generic form that is compact, and should work with the standard pin numbers from the CCS include file.

Best Wishes
Ttelmah
Guest







PostPosted: Fri May 20, 2005 3:54 pm     Reply with quote

Using the bit set and bit clear functions will make the macros quicker, so:
Code:

#define NUMPORTS (5)

int8 IOarray[numports];
#byte IOarray = 0xF80

#define set_bit(x) bit_set(IOarray[(x-PIN_A0)>>3],(x&3))
#define clear_bit(x) bit_clear(IOarray[(x-PIN_A0)>>3],(x&3))


Or:

Code:

#define set_bit(x) bit_set(*(int8 *)((x-PIN_A0)>>3),(x&3))
#define clear_bit(x) bit_clear(*(int8 *)((x-PIN_A0)>>3),(x&3))


I reckon these must be approaching the simplest versions possible, and ought to work for any of the processors, using the standard pin defintions, passed to functions (as a 'long' though).
So you can for example code:
Code:

void flashbit(int16 bit) {
   set_bit(bit);
   delay_us(50);
   clear_bit(bit);
}

void main(void) {
   int16 pin;
   while (1) {
       for (pin=PIN_A0;pin<=PIN_A5;pin++)
          flashbit(pin);
   }
}

This must be the closest approach to the standard 'fixed' operation, in a simple form. Smile

Best Wishes
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
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