Jump to content
43oh

bit banging I2C


Recommended Posts

Well, I have my bit banging I2C primitives mostly working - mostly.

 

post-955-135135542037_thumb.jpg

 

The only problem I have is my bit reading routine.

/******************************************************************************
*
*	MPS430 digital I/O function prototypes:
*
*	char pinread( int port, char pin )
*
*	Given the pin number, this function will read that pin number of PORT1
*	of the target MSP430.
*
*	Returns right justified LSBit of the specified port and pin.
*
******************************************************************************/
char pinread( int port, char pin )
{
int tempvar = 0;

//	tempvarm = P2IN;
//	tempmask = 0x01 << pin;
//	tempvarm &= tempmask;
//	tempvarm = tempvarm >> pin;
//	tempmask = 0xbeef;

if( PORT1 == port )
{
	return( P1IN & ( 1<> pin );
}
else
if( PORT2 == port )
{
//		tempvar =  (P2IN & ( 1<> pin;
	return( P2IN & ( 1<> pin );
//		return( tempvar );
}

return(0);
}

 

The code reads the port register, ANDs it with a variable that indicates the desired bit position, then shifts it back right to place that bit in the least significant position.

 

You can then process the return value like this:

if( 0x01 == PORT2, PIN0 )
 ... do something

 

It seems to return 0xFF all the time. Weird.

 

I've got a gut feeling that there are some macros out there that would make this easy.

 

Is there a better way of reading the level on an input pin?

Link to post
Share on other sites

Use a bitmask (BIT0, BIT1, BIT2, ....) instead of a pin #. That will eliminate the runtime evaluation of 1 << N and the code will be much faster.

 

unsigned pin_read(volatile unsigned char *pin, const unsigned char mask) { return (*pin & mask) ? 1 : 0; }

 

if(pin_read(&P1IN, BIT3)) {
   ...
}

 

Using a C++ template would be even faster, and you could use pin # if you want with no performance penalty (because it would be evaluated at compile time).

Link to post
Share on other sites

Okay, I figured out why my attempt at your method failed. It was the definitions of the bits.

 

Your method started working when I used these definitions:

// pin definitions
#define P0	0x01
#define P1	0x02
#define	P2	0x04
#define	P3	0x08
#define	P4	0x10
#define	P5	0x20
#define	P6	0x40
#define	P7	0x80

 

My spidey senses are telling me that TI defined BIT0 .. BIT7 somewhere already. I should check that out.

Link to post
Share on other sites

Ha! Turns out that TI defined them alright.

BIT0 = 0x0001
BIT1 = 0x0002
BIT2 = 0x0004
BIT3 = 0x0008
BIT4 = 0x0010
BIT5 = 0x0020
BIT6 = 0x0040
BIT7 = 0x0080

 

It turns out that the problem with my read function was a confusion between the suitability of the above definitions and the pin assignment method that I used.

 

I have to go back and simplify my stuff to use proper bit masking instead of bit shifting.

 

I'll post up my code once I edit out all the shame. :lol:

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...