View previous topic :: View next topic |
Author |
Message |
kWoody_uk
Joined: 29 Jan 2015 Posts: 47 Location: United Kingdom
|
Reusable code |
Posted: Thu Jan 29, 2015 6:42 am |
|
|
Hi guys,
I'm trying to communicate with 4 x Pics acting as SPI slaves to a Master Pic, i.e. 4 x CS lines from the master.
The master Pic (which is what this is concerning) is an 18F46K22.
I'm not that experienced with C code and would like to implement the following function in the master, to transfer SPI data:-
Code: |
// Transmit and receive SPI Data
void servicePic1Spi( void )
{
int rxData;
int txData;
// Preparing slave Pic device for Spi coms
output_low( PIC1_CS );
// Checking if there is any data to send to the slave
if ( dataInPic1SpiTxBuf() ) {
txData = getPic1TxBuf();
} else {
txData = 0x00;
}
// Start a simultaneous send/receive of spi data
rxData = xferSpi1( txData );
// Ending spi comms
output_high( PIC1_CS );
// Rest of code to parse received data...
}
|
How could I reuse this code to make a common function for each of the 4 slave pics? At the moment I have unique versions of this function for each slave device.
I experimented using structure pointers, but the code generated is quite large. I guess this is due to the architecture of the Pics.
Any suggestions would be greatly appreciated.
Thanks in advance,
Keith |
|
![](templates/subSilver/images/spacer.gif) |
temtronic
Joined: 01 Jul 2010 Posts: 9177 Location: Greensville,Ontario
|
|
Posted: Thu Jan 29, 2015 7:05 am |
|
|
I'm sure others that are real C programmers will reply but I'd probably just send the slavePIC # to your function ?
..
void servicePic1Spi( void )
becomes
void servicePic1Spi( char slave_cs )
... output_low( PIC1_CS )
could be
output_low( slave_cs)
slave_cs is a 'global variable'
You'd also have to have a separate 'buffer' for the slave's data( 1...4) so you know what data came from which PIC !
Hopefully you get my idea, as I'm self taught bodger of C !
Jay |
|
![](templates/subSilver/images/spacer.gif) |
kWoody_uk
Joined: 29 Jan 2015 Posts: 47 Location: United Kingdom
|
|
Posted: Thu Jan 29, 2015 8:09 am |
|
|
Ahh.. so I could assign a PIN_XX to a variable? Looking at the device file for this PIC they are defines in a 16bit number range, so I guess it should work.
That's the simple bit done then (thanks Jay).
How would I turn:-
Code: |
if ( dataInPic1SpiTxBuf() ) {
txData = getPic1TxBuf();
|
into something like:-
Code: |
if ( dataInPicXSpiTxBuf() ) {
txData = getPicXTxBuf();
|
that is make these common? Would I have to pass offsets of memory locations and read/write variables to these functions?
Sounds a bit daunting...
Keith |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19378
|
|
Posted: Thu Jan 29, 2015 8:17 am |
|
|
If you look back a few days, there was a thread entitled : "PIC18F26K22 + 2 PORT RS232 + INT". In this I posted a set of routines that handle multiple 'buffers' through common code using the buffer name as the thing to distinguish what is being referenced. Not directly 'right', but I have used the same technique to handle buffers mixed onto things like SPI. Might give you a hint. |
|
![](templates/subSilver/images/spacer.gif) |
kWoody_uk
Joined: 29 Jan 2015 Posts: 47 Location: United Kingdom
|
|
Posted: Thu Jan 29, 2015 8:20 am |
|
|
Thanks Ttelmah,
I'll have a look and see if I can learn from your example.
I love seeing how other people do things, it's inspiring .
Keith |
|
![](templates/subSilver/images/spacer.gif) |
kWoody_uk
Joined: 29 Jan 2015 Posts: 47 Location: United Kingdom
|
|
Posted: Fri Jan 30, 2015 5:51 am |
|
|
Hi Ttelmah,
I've been looking at your example for inspiration and I have been stuck on one of the macros you are using.
Code: |
#define tobuff(bname,c) { bname.buff[bname.in]=c; \
bname.in=incin(bname); \
if (bname.in==bname.out) bname.out=incout(bname); \
}
#define frombuff(bname) ( btemp##bname=bname.buff[bname.out], \
bname.out=incout(bname), \
btemp##bname )
|
I understand the first in the your code above and how it will expand. But the second I'm lost with. How will it expand? I think the main things confusing me are the commas between statements, and of course how it relates to legal C code when expanded.
Could you help me with this please, as I've looked all over the web and cannot find a similar example?
Thanks in advance,
Keith |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19378
|
|
Posted: Fri Jan 30, 2015 1:09 pm |
|
|
Yes, they are somewhat serious macros...
The '\' makes lines be treated as if they continue without breaks from each other. So all the lines are expanded.
The {} brackets make a section of code into a single code block.
Expressions separated by a comma, are evaluated left to right, and the type and size of the result, is that of the rightmost statement.
So the whole block:
( btemp##bname=bname.buff[bname.out],
bname.out=incout(bname),
btemp##bname )
Evaluates one statement at a time, and returns btemp##bname
The ## is the string catenation operator without spaces. So if used with (say) B1TX, results in btempB1TX being used as the variable name.
They are 'obtruse C', but make a tidy way to handle named buffers. |
|
![](templates/subSilver/images/spacer.gif) |
kWoody_uk
Joined: 29 Jan 2015 Posts: 47 Location: United Kingdom
|
|
Posted: Mon Feb 02, 2015 3:23 am |
|
|
Thanks for your explanation Ttelmah. As usual, real code differs somewhat from example code, so your help is a blessing.
Best Regards,
Keith |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19378
|
|
Posted: Mon Feb 02, 2015 3:40 am |
|
|
I had posted buffer code in the past, but 'avoided' this particular version, because while it works well, and is efficient, it is 'dark C' (there are a lot of things you 'can' do in C, which need a three page explanation attached...). ![Smile](images/smiles/icon_smile.gif) |
|
![](templates/subSilver/images/spacer.gif) |
|