L293D 11 Posted April 15, 2013 Share Posted April 15, 2013 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 Quote Link to post Share on other sites
roadrunner84 466 Posted April 15, 2013 Share Posted April 15, 2013 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; Quote Link to post Share on other sites
L293D 11 Posted April 15, 2013 Author Share Posted April 15, 2013 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 Quote Link to post Share on other sites
roadrunner84 466 Posted April 16, 2013 Share Posted April 16, 2013 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. Quote Link to post Share on other sites
L293D 11 Posted April 16, 2013 Author Share Posted April 16, 2013 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 Quote Link to post Share on other sites
jscrane 12 Posted April 17, 2013 Share Posted April 17, 2013 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 Quote Link to post Share on other sites
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.