Jump to content
yyrkoon

More C versus C++

Recommended Posts

1 minute ago, NurseBob said:

Sound very cool, and I assume, a fair amount of time spent deciphering Logic Analyzer and Oscilloscope traces. Were it not for those two pieces of equipment my aging brain would be on fire (oh, and the 60's rock on pandora helps keep me sane, too)... I have an email-friend in Australia who designs and develops for the '430 and only writes in assembler. Per his comments, it's theoretically possible to use only a blinking LED to figure this all out, but that's far beyond my ken...

It shouldn't be. For GPIO, the blinking LED is obvious, but for testing other peripherals, you just have to use a set of conditionals to test for various conditions, then act accordingly through the LED. I've done this myself too, but prefer to use "printf() debugging" through UART when at all possible.

As far as using an oscilloscope, I do not have to do that, and in fact do not really know how to use one. Using a logic analyzer may be different, and I have one. But have never had to use one in the past. Maybe that'll change with this project, we'll see. Anyway, my buddy who has been an EE for years has several oscilloscope, and definitely knows how to use them. So I defer to him, when(if) his hardware has issues. I know my way around Linux, and most of it's programming interface ( userspace ) usually to know when something is "my fault". I2C on the MSP430 is a bit new to me however, so we'll see how that works out. I have seen a few different bits of example code for the MSP430 though, that makes it all look very trivial. Software communications wise, it seems very similar to setup, and usage compared to UART. The one thing I don't know how it works yet is how to setup the device bus address, but maybe I'm a little bit too worried about that. The rest of the code seems almost trivial. For hardware based I2C that is.

 

Share this post


Link to post
Share on other sites
2 minutes ago, yyrkoon said:

The one thing I don't know how it works yet is how to setup the device bus address

If the device is a commercial part, it's published. If it's your own design, the '430 peripheral code examples will be your guide. Basically, you set up the I2C handler for the slave to respond to its transmitted address. FWIW, the hand-coded examples in Davies' MSP430 Microcontroller Basics(there's a pdf version - google "msp430 microcontroller basics") book on the '430 give a reasonable explanation.  If you're designing something to be incorporated with other I2C devices, then you need to pick an address or addresses that aren't in conflict with other devices.  I don't know if there's a "registry" for I2C device addresses.... The example code for TI and Davies all use 0x48 and 0x90; for the addresses.

Share this post


Link to post
Share on other sites
1 minute ago, NurseBob said:

If the device is a commercial part, it's published. If it's your own design, the '430 peripheral code examples will be your guide. Basically, you set up the I2C handler for the slave to respond to its transmitted address. FWIW, the hand-coded examples in Davies' MSP430 Microcontroller Basics(there's a pdf version - google "msp430 microcontroller basics") book on the '430 give a reasonable explanation.  If you're designing something to be incorporated with other I2C devices, then you need to pick an address or addresses that aren't in conflict with other devices.  I don't know if there's a "registry" for I2C device addresses.... The example code for TI and Davies all use 0x48 and 0x90; for the addresses.

So the idea with our hardware is that we're going to have X amount of jumpers to represent X amount of addresses. So without knowing much about I2C in general, I figure I take the binary form of these jumpers combined, and use that to represent a device address. Which seems obvious to me, an I2C slave implementer newb. So ok, great I'll check out that read, and see if it starts to make sense to me then.

From what you're saying though, it sounds like I just pull the first X amount of bits ( excluding start bits, etc )  from a transmission, and see if the comm traffic is meant for the device or not?

Share this post


Link to post
Share on other sites

@NurseBob

Uh, yeah, no offense, I think I'll look for a different source. To understand I2C better. From what I've seen in that book, the guy is setting up datatypes( enums, etc ) and additional code inside an interrupt handler ? Yeah, that's not usually a good sign . . hehehe

Yeah, never mind, it seems I was mistaken.

Share this post


Link to post
Share on other sites

Typical I2C addresses are the top 7 bits, with the 8th bit determining if the conversation is a read or write. I've been working with a port expander (sx1509) which has 4 possible addresses (determined by pins that are high or low). So multiple addressing for devices is a common theme.  I've actually found using binary representation for addressing, or registers, handy.

I also found this on implementing an I2C slave from scratch, which proved useful conceptually: http://dsscircuits.com/articles/arduino-i2c-slave-guide

While the GPS code is not necessarily relevant, he offers a pretty decent explanation of the communication and setting up of address registers.

Re: Davies code - yes, at times he hides implementation via enums, etc, but his long form and ISR versions of an I2C handler are a bit more complete and explanatory than the TI code examples.  

The "challenge" with the TI code examples is getting past the point that they do nothing useful... Typically they iterate though a defined list of numbers and then restart. The slave code I'm using is focused on the F2013, which is limited to USI.  I suspect you want to use the more advanced capabilities in the USCI. My recollection is you're using the G2553? If so, look at the MSP430Ware->Devices->MSP430G2xx->Code Examples->MSP430G2x53- msp430g2xx3_uscib0_i2c_12.c  and msp430g2xx3_uscib0_i2c_13.c -

the 12 code: USCI_B0 I2C Master TX/RX multiple bytes from MSP430 Slave with a repeated start in between TX and RX operations.

and 13 code:  USCI_B0 I2C Slave RX/TX multiple bytes to MSP430 Master

serve as useful examples of the setup and ISR handlers.  Don't omit the pullup resistors - the internal pullups are not sufficient or consistent.

Bob

Share this post


Link to post
Share on other sites

@NurseBob Thanks for you input. We should move the I2C talk to the other thread if more conversation presents it's self. So we can try to keep this post on topic. Just sayin' and not blaming anyone, which if anyone is to blame it's me who shifted the conversation towards I2C.

Share this post


Link to post
Share on other sites
23 hours ago, NurseBob said:

Well, I don't find any real conflict between OO and event-driven systems; the events just need to be incorporated into the design.  I guess I think of hardware events as a variant of messaging. My '430 code tends to have a setup in main that ends in a "forever" while loop structured around an LPM3 statement. Hardware events set state flags and the loop figures out how to handle the event, then goes back to sleep. I know from a '430 standpoint that's pretty much a standard design, but the "fun" has been in figuring out how to code for the ISRs, which live in a C subroutine and then chain back to a C++ class handler. The main concern and complexity for my limited brain is the design of a "generic" I2C ISR to handle the I2C communication for each of my I2C device classes. In essence the design for each I2C device is class-based, but dependent on the one I2C ISR, which uses a state variable and switch/case construct contain the handling of each I2C device's needs.  I'll be soon finding out if the overall design is sound as I incorporate the remaining I2C sensors and devices.

I meant to respond to your post here in more detail concerning "Event driven". So, I'll usually mix up OO with event driven when talking about event driven. Which I do not think that event driven is necessarily a part of what makes a language Object Oriented. But I can not remember using an Object Oriented language that did not have some form of events. VB.NET, C#, and Javascript are all languages I've personally had hands on with using events. In the context of C++, using events is very similar to you'd do the same thing in C. Which is to say, for me, this does not feel very much like an event at all. Just a function that is occasionally called when some condition is met. With other languages higher level than C++, such as those I've already mentioned, The message pump loop is all abstracted away, and for me this totally feels like an event. Weird huh ? Using interrupts though, again feels very naturally event driven to me. But on some very low level, I'm sure there is something similar to a "hardware message pump", or at minimum some sort of conditional checks that fire the interrupts off. I won't pretend to know the hardware on that level however. Knowing just enough to know how to use an interrupt is good enough for me.

I also do not really know the low level gory details of how these events work, but I'm fairly confident that there is some form "wrapper" or interface code, that's really running a message pump loop. Similar to how you'd see in C, or C++. Now days with C++, there may even be something in the STL, but I do not know for sure. I try to keep myself busy programming, instead of spending all my days keeping up with the C++ STL. Which is one reason why I'll try to avoid C++ most of the time. I do not feel like I have enough time to keep up with the language 100%, and still do what I need to get done programmatically. The other part of that equation, is that unless I really know something in full detail, I'm not exactly happy about using that thing. This does not mean I think I know everything about C. This means, I think I'm proficient enough with C, that if I am unfamiliar with a concept, or language feature. It will not take me long to brush up on the subject - Usually.

So here is my take on the whole C++ class ISR thing. It's too complex. Complex code is more likely to be buggy, or have mistakes in it. If in contrast you feel more comfortable using C, for ISR handlers. Then by all means just write the code in C, and use C++ elsewhere where it makes more sense for you. Do keep in mind, I understand the *need* to do things differently in order to learn something, or possibly start thinking about that given thing differently. Complex code is also more likely to be slower. Unless your compiler is very good at optimizing things out. Which C++ compilers seem to be working "magic" in this area in the last several years. But this is yet more information you need to overfill that full glass of a brain we have already . . .

Share this post


Link to post
Share on other sites

Events: Such a range of sources. Hardware (internal and external), timers, user-generated, etc.  As you alluded to, there's usually a heirarchy of priorities that impact how they are, or need to be, handled. I don't really have any internal association between event-driven and OO; one reflects how things happen, the other is merely one way to define a world view. The PC GUI world is certainly built around the event model and the understanding of the potentially random timing of events coupled with a management of event priority. My fading memory seems to recall that the original implementation of the Windows GUI several decades back was niether OO nor C++, but a loop which handled and/or generated messages.

As to my own project, the ISRs are C.  The name mangling of C++ led to problems. So, just as TI's C++ libraries do, I define the ISRs as extern C routines. I do spend some time looking at the order and frequency of the case statements in terms of execution, but my implementation spends very little time doing any communication with the sensors, and typically only in response to a sensor-generated interrupt (also rare events), otherwise the app is spending it's time sleeping.

I agree, complex code is likely slower to execute. And almost never should reside in an ISR; aside from my TX RX event handlers, my ISRs follow the "set a flag or generate a software  interrupt and return" rule. And as much as possible, even the TX RX handlers are setting flags for a main-based while loop to process then go back to sleep where communication timing is not an issue.

My knowledge of the C language is probably barely adequate to the task, as well as is my knowledge of C++. However, experimentation is a basis for how my brain works and remembers.  I've spent hours in the debugger stepping through both C and disassembled code; fixed problems, and sometimes have even remembered not to create the same problem again. Were it not for Google, code snippets, reference circuits, etc., my little project would have never gotten started, let alone to the point it's reached. Ok, now I'm rambling...

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×