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

Hardware references in re-useable functions?

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








Hardware references in re-useable functions?
PostPosted: Tue Aug 25, 2009 11:38 am     Reply with quote

What's the best way to make a hardware driver routine reuseable?

Specifically I'm dealing with several BQ2018 battery monitoring chips on the same board - for anyone not familiar this part communicates over TI's HDQ one wire protocol and is not addressed like the maxim/dallas one wire protocol. Communication is fairly simple, just some time critical bit twiddling...

In addition to the specific pin each unit is connected to, I also need to maintain a few other bytes of information that are known at compile time (eeprom addresses to store part specific data, charge capacity of each battery, life expectancy of each battery, etc)

What's a good way to handle this without incurring run-time penalties?

I'd like a function that works like:
Code:
MyValue = GetBatteryLevel(x); //where x is an integer 0-3 specifing which BQ2018 and battery to read

My first thought was to create a STRUCT to hold the info, then create a constant array of my that struct and use the integer to index the array. Although I may have mucked up the implementation, it functioned but introduced as much as 100uS of extra time in my bit twiddling - not acceptable.

Here's one of my simplest low level routines for discussion:
Code:

void BQSendBreak(BattReff)
{
Output_Low(BatteryParams(BattRef).IO_Pin);
delay_us(190);
Output_Float(BatteryParams(BattRef).IO_Pin);
delay_us(40);
}


So, obviously there's a better way to do this, and I can't believe that no one else has come up against something like this before... Sugestions?

Thanks,
-Denny
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Aug 25, 2009 12:09 pm     Reply with quote

If you have code that requires strict timing, then the fastest way to
do it is to use a pin constant for output_low() and output_high().

Create separate routines for each BQ chip.
You could use a switch-case to select which routine to call.

Or possibly you could use an array of function pointers. See the post
near the end of this thread:
http://www.ccsinfo.com/forum/viewtopic.php?t=37478
DEsterline



Joined: 25 Aug 2009
Posts: 6

View user's profile Send private message

PostPosted: Tue Aug 25, 2009 1:19 pm     Reply with quote

Thanks for the quick reply (and for tweeking the formatting of my post :-)

So if I understand this correctly (always in doubt), function Pointers would allow me to write a seperate set of functions for each of the seperate chips - and I can hard code the paramaters for fast and operations - but then access them with an index so I can code them into loops and such.

But I still end up with nearly identical functions for each of the components, very code inefficent. There's no better way to do this?

How does the compiler handle something like serial data on multiple pins? I see the #use directive seems to change which of the ports gets accessed... Is there a way I could duplicate that functionality?

-Denny
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Aug 25, 2009 1:30 pm     Reply with quote

If you use a variable pin number, it's much more inefficient than
using a fixed pin constant. Here's the ASM code:
Code:

.................... output_low(pin);
0068:  MOVFF  06,08
006C:  CLRF   09
006E:  MOVLW  0F
0070:  MOVWF  0B
0072:  MOVLW  89
0074:  MOVWF  0A
0076:  RCALL  0004
0078:  MOVFF  06,08
007C:  CLRF   09
007E:  MOVLW  0F
0080:  MOVWF  0B
0082:  MOVLW  92
0084:  MOVWF  0A
0086:  RCALL  0004
.................... 
.................... output_high(PIN_B0);
0088:  BCF    F93.0
008A:  BSF    F8A.0


Here's the test program:
Code:
#include <18F452.h>
#fuses XT,NOWDT,PUT,BROWNOUT,NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)

//======================================
void main(void)
{
int16 pin = PIN_B0;

output_low(pin);

output_high(PIN_B0);

while(1);
}
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