Jump to content
43oh

Stellaris - cbi sbi and portOutputRegister


Recommended Posts

Quick questions:

Is there already a macro in Energia for the StellarPad which is equivilant to cbi and sbi?

Am I correct that portDATARegister in Energia.h (for stellaris) is basically the same as portOutputRegister for the Mps430 or AVR's?

I am trying to port a library to Stellaris which uses cbi, sbi, and the portOutputRegister macro's.  Any advice is appreciated.

 

 

 

 

 

L293D

Link to post
Share on other sites

I figure SBI and CBI stand for Set Bit and Clear Bit. The MSP430 has assembly instructions BIC and BIS to do this.Ddin't read correctly, the same story still holds. In C just use masking to get it compiled to this.

// Set bit 4 (base 0) in register X
X |= BIT4;
// Clear bit 4 (base 0) in register X
X &= ~(BIT4);
// Set bit 4 and 6
X |= BIT4 | BIT6;
// Clear bit 4 and 6
X &= ~(BIT4 | BIT6);
// Clear bit 4 and set bit 6
X = (X & ~(BIT4)) | BIT6;
Link to post
Share on other sites

I appreciate the help.  I understand how all of that works, however implementing it on the Stellaris appears to be very different.

 

No double we have all seen things like this in both MSP430 libraries, and Arduino libraries:

P_SDA	= portOutputRegister(digitalPinToPort(RS));
		B_SDA	= digitalPinToBitMask(RS);
		P_SCL	= portOutputRegister(digitalPinToPort(WR));
		B_SCL	= digitalPinToBitMask(WR);
		P_CS	= portOutputRegister(digitalPinToPort(CS));
		B_CS	= digitalPinToBitMask(CS);
		P_RST	= portOutputRegister(digitalPinToPort(RST));
		B_RST	= digitalPinToBitMask(RST);
		if (display_serial_mode!=SERIAL_4PIN)
		{
			P_RS	= portOutputRegister(digitalPinToPort(SER));
			B_RS	= digitalPinToBitMask(SER);
			pinMode(SER,OUTPUT);
		}

(code above is from UTFT.c from the UTFT library by Henning Karlsen.)

 

portOutputRegister in that case returns something like (in the case of the MSP430) P1OUT.  Pretty simple.

 

The closest thing on Stellaris seems to be portDATARegister, which returns the GPIO base with the correct offset.

 

So, I have something like:

 

#define cbi(reg, bit) HWREG((uint32_t)reg) &= ~bit

#define sbi(reg, bit) HWREG((uint32_t)reg) |= bit

 

 

 

 

If I open a new energia program, define those at the top, and then use portDATARegister to return the register and digitalPintoBitmask to return the bitmask for the pin...I can toggle LED's all day long...HOWEVER...if I change part of the library that I posted to:

 



P_SDA	= portDATARegister(digitalPinToPort(RS));
		B_SDA	= digitalPinToBitMask(RS);
		P_SCL	= portDATARegister(digitalPinToPort(WR));
		B_SCL	= digitalPinToBitMask(WR);
		P_CS	= portDATARegister(digitalPinToPort(CS));
		B_CS	= digitalPinToBitMask(CS);
		P_RST	= portDATARegister(digitalPinToPort(RST));
		B_RST	= digitalPinToBitMask(RST);
		if (display_serial_mode!=SERIAL_4PIN)
		{
			P_RS	= portDATARegister(digitalPinToPort(SER));
			B_RS	= digitalPinToBitMask(SER);
			pinMode(SER,OUTPUT);
		}

It still does not work.  It think that it has something to do with how for example...P_RS and B_RS are defined.  P_RS is defined as a volatile unint32 and I changed the B_RS to be a uint8_t because the compiler threw a fit.  

 

Btw, for anybody interested, this is all still related to porting Henning Karlsen's UTFT library to Energia for Stellaris.  Porting it for the MSP430G2553 was a breeze because cbi, sbi, and portOutputRegister are all already defined...so I basically just changed some ports, etc..created new HW defines, and it was all good.

 

Stellaris as I am finding out is a whole different animal.

 

Anyway...if anybody has anything to offer on this, I would appreciate it.  This library would be very useful to anybody using a TFT as it supports a large number of controllers, each in both 8 and 16 bit modes.

 

Thx again.

 

L293D

Link to post
Share on other sites

It's less clear to me what you plan to achieve. Do you want functions similar to digitalWrite() for the Stellaris? Then what's precisely wrong with my approach? You tell me you have these defines working which allow you to toggle LEDs (i.e.: allow you to emulate digitalWrite()). If that's the case, then where is the problem?

As a rule of thumb, put braces around every function like macro and every parameter in a macro, this is done to avoid unexpected operator presendence changes when concatenating function like macros

#define cbi(reg, bit) HWREG((uint32_t)reg) &= ~bit
#define sbi(reg, bit) HWREG((uint32_t)reg) |= bit

if (cbi(X + 3, Y + 4) == true){}
// expands to 
if (HWREG((uint32_t)X + 3) &= ~Y + 4 == true){}
//which is evaluated as
if (HWREG(((uint32_t)X) + 3) &= (~Y) + (4 == true)){}
//while you wanted
if (HWREG(((uint32_t)(X + 3)) &= ~(Y + 4)) == true){}

// so define the function like macros like
#define cbi(reg, bit) (HWREG((uint32_t)(reg)) &= ~(bit))
#define sbi(reg, bit) (HWREG((uint32_t)(reg)) |= (bit))

I don't know exactly what pinMode expects, but if the Stellaris is anything like the MSP430, I assume the first parameter is a volatile uint8_t* and the second is a uint8_t. That is, if the ports are actually 8 bits wide. It is gravely discouraged to assume a pointer/memory location fits in an ordinary integer type, try to use pointer types as much as possible for these cases.

Link to post
Share on other sites

I apologize if I have offended you.  The problem appears to be my lack of understanding of pointers.  Passing P_CS and B_CS from here:

P_CS	= portDATARegister(digitalPinToPort(CS));
B_CS	= digitalPinToBitMask(CS);

to sbi or cbi, doesn't seem to work.  In fact to even get it to compile without errors I have to do something like:

P_CS	= (uint32_t*)portDATARegister(digitalPinToPort(CS));
B_CS	= digitalPinToBitMask(CS);

Then it compiles, but still does not work.  I DO appreciate your help, and again, I apologize if I seemed ungrateful.  

 

I have made note of the way you altered the #defines for cbi and sbi and will try that when I get home tonight.

 

L293D

Link to post
Share on other sites

So it seems to me that portOutputRegister() and digitalPinToBitMask() are used so that you can do things like reg |= mask and reg &= ~mask.

 

Aren't these just faster versions of digitalWrite(pin, HIGH) and digitalWrite(pin, LOW)?

 

So maybe get it working with digitalWrite first and optimize later?

 

Just a thought,

Steve

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...