|
|
View previous topic :: View next topic |
Author |
Message |
Pavel Kolinko
Joined: 15 Mar 2005 Posts: 10
|
How do I pass a generic pin argument to a function? |
Posted: Fri May 20, 2005 2:10 pm |
|
|
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) .
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
|
|
|
Pavel Kolinko
Joined: 15 Mar 2005 Posts: 10
|
|
Posted: Fri May 20, 2005 2:21 pm |
|
|
Thank you!
I will check these out! |
|
|
Ttelmah Guest
|
|
Posted: Fri May 20, 2005 2:38 pm |
|
|
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
|
|
Posted: Fri May 20, 2005 2:42 pm |
|
|
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
|
|
Posted: Fri May 20, 2005 3:13 pm |
|
|
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
|
|
Posted: Fri May 20, 2005 3:54 pm |
|
|
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.
Best Wishes |
|
|
|
|
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
|