Shop OBEX P1 Docs P2 Docs Learn Events
Questions you think are too stupid to ask... — Parallax Forums

Questions you think are too stupid to ask...

DavidZemonDavidZemon Posts: 2,973
edited 2014-05-01 17:09 in Propeller 1
A thread with this title exists in another forum I'm on. It's wonderfully helpful.
I'll start.

In the propeller manual, the DIRA section contains the line: "[ensure] no two cogs cause logical contention on the same I/O pin"
What does this mean? Ensure that one cog outputs a 0 while another cog outputs a 1? If I were to accidentally do this, would the chip release it's magic blue smoke?
«13

Comments

  • JonnyMacJonnyMac Posts: 9,105
    edited 2012-02-11 12:56
    No. The outputs from each cog are OR'd together before going to the pin. What this means, though, is that if one cog makes the pin high (1), it doesn't matter what any other cog is doing, that pin will be high.
  • Cluso99Cluso99 Posts: 18,069
    edited 2012-02-11 14:16
    Also checkout the stickie at the top of this forum for links to other beginner information. Lots of good bits there for beginners.
  • JRetSapDoogJRetSapDoog Posts: 954
    edited 2012-02-11 21:44
    About your blue-smoke scenario, that would be the case if TWO different pins were being used that were BOTH set for OUTPUT (DIRA-wise) and those two pins were directly connected together (without sufficient limiting resistance) while at different voltage states (one high, the other low), as current flow would exceed the I/O ratings and built-in protection of the pins. That's probably an effective way to generate the blue smoke you seek. However, if one cog set one pin as an output and the other cog set the other pin as an input (with the two pins being directly connected together), then I don't think that would be a problem as the input pin uses/has high impedance. Nevertheless, one might want to use a current-limiting resistor between them just in case a programming mistake caused both pins to be outputs and different levels were output on them, to thus avoid the magic blue (sometimes yellow, green or even brown)smoke.

    But the scenario in the text that you've cited (in a good question, by the way) is not the blue-smoke case, as only ONE PIN is involved, and, at any one time, the pin, itself (with it's associated circuitry), can only be successfully set for either input or output (whether high or low, in the case of being an output), not set for being both an input and an output at the same time. But two (or more cogs) can still "request" (or attempt) to set a pin differently (from other cogs), but any cog that sets the pin as an output (using DIRA) will "win," and the pin will be an output pin, as JonnyMac said. In a sense, an attempt to set a pin as an input is a "request" (from the pin viewpoint) that is only honored if NO (zero) other cogs try to set it as an output. But an instruction to set a pin as an output will definitely be honored, so, in that sense, is not really a request but a command.

    As the manual says just prior to the text you've cited, "no electrical contention between cogs is POSSIBLE" (emphasis added). So, this is not a blue-smoke generating scenario that one needs to worry about because electrical contention is precluded due to the way the pins are wired internally (which is quite nice or the only practical way for cogs to have access to the same pins). Note that the text that you've cited mentions "logical contention," not the electrical or physical kind. Logical contention is still quite possible, and while such wouldn't generate blue smoke, it's possible that such wouldn't consistently give the result desired. And it's up to the programmer to avoid any such logical contention that would be problematic (not all "contention" in terms of requested pin settings is problematic).

    For example, suppose one cog "sets" (recall it's kind of a request) all the pins as inputs using DIRA but only uses the first 4 pins (0..3) as inputs (by the way, all pins being configured as inputs (high impedance) is, I believe, the default state, thank goodness). Further suppose that another cog comes along and sets (commands) pins 20 through 27 to be outputs using DIRA. That's NOT going to cause a problem, even though the requested/commanded pin states don't agree. The cog that sets pins 20..27 as outputs will "win" based on the TWO LAWS mentioned in the text just prior to the text you've cited (see the manual). But the fact that the second cog's setting won won't matter here because the first cog that had set or requested them to be inputs doesn't use them. In such a case, one could argue that the first cog shouldn't have bothered to set those pins (or any other pins other than the first four) as inputs (or outputs) because it doesn't use them, but, nonetheless, this disagreement in issued pin setting instructions won't cause electrical, blue-smoke contention; the pins will be outputs based on the two laws, case closed.

    But there are other scenarios where such disagreement in pin settings would be problematic, not because it would create a blue smoke condition, but because one cog's use of a pin as an output pin (wherein such usage would prevail over another cog's request for usage as an input) *could* trample on some other signals from elsewhere. Thinking about it, if a cog has requested to use a pin as an input, then it's trying to read a signal from somewhere else. That somewhere else could be, for example, a sensor device. In such case, if another cog were trying to use the same pin as an output, then, obviously, such usage would tramp on the sensor's output. I believe it's the case that a cog can still read the state of a pin at any time regardless of how the pin is actually configured input/ouput-wise (someone correct me if I'm wrong, and I really shouldn't be writing this without knowing and or testing that, but I think it's the case). I assume that's how Hanno's ViewPort can read the state of all of the pins without requiring any other pins (assuming that's the case as I haven't used it yet), regardless of whether the pins are set as inputs or outputs (in various combinations). Similarly, the afforementioned "somewhere else" signal source could also be from another cog generating output. In that case, such "disagreement" in usage would be deliberate and not unwanted contention. One cog would use a pin as an output, setting it either high or low, possibly varying over time, while another cog "peeked" at the status. Such would, effectively, save a pin as an input pin wouldn't have to be connected to a separate output pin (in such an intercog communication scenario) and hub memory would not be involved. Someone please correct me if I'm wrong (I'm still a bit new at this).

    But what one needs to keep in mind is that the above case is different from that of two (or more) cogs using a pin as an OUTPUT (that has been set to an output by at least one of the cogs using DIRA). In that case, if one cog outputs a high, while another cog outputs a low, then the cog outputting a high will prevail based on ANOTHER pair of laws (see the OUTA section of the manual). I mention this because I think it's easy to get DIRA and OUTA (or input and output usage) confused by the novice and/or not-so-novice. That situation also doesn't result in electrical, blue-smoke contention, as the internal pin wiring will let the output state of ANY one cog outputting a high win or prevail over any cogs that might be trying to output a low on the same pin (i.e., the low-attempting-outputters will "lose"). See, this current situation is different than the abovementioned discussion concerning contention as to the input or output condition of a pin (by "competing" cogs). Here, all cogs are agreeing that the pin is an output (and even if a cog didn't agree, its voice in the matter (or requested use as an input) would be overridden). But even if the cogs agree on a pin's usage in terms of input/output, such cogs all using the output mode, they might still try to set such a pin at different logical levels (at least one to high, and at least another to low). And by design, the cog or cogs that set it high will win. It's important to differentiate this situation from the above first scenario (the one existing for the OP's cited text of two cogs not agreeing on the input/output state). So, where might the current situation of two cogs ATTEMPTING (but not succeeding) to output different levels on the same pin be useful? Consider the following:

    Sometimes it's necessary for code in one cog to "share" a pin with the same or different code in another cog for various reasons. For example, one might have one cog responsible for outputting a video signal with graphics and have another cog responsible for overlaying (super-imposing) text on top of that video. In such a case, the two cogs would likely share video output pins (such usage also being synchronized). The cog charged with overlaying text would likely be configured to "step on" the output of the graphics cog by setting an output pin high (to produce, for example, white lettering/pixels), potentially overriding a low setting from the graphics cog. In this case, both cogs would use the same pin (or pin group) for output. Both cogs could actually issue DIRA instructions to set the pin(s) to output, but, strictly speaking, I think it's sufficient for only one cog to do so. That is, I don't think (but I'm not currently too sure) that a cog is prevented from issuing an output command (OUTA) just because it hasn't set the pin direction as ouput using DIRA, at least I don't think that the compiler would object. But unless another cog has set the pin to output, I guess its output attempts wouldn't work (again, assuming it hadn't issued a DIRA instruction to make the pin an output). I'd test this now but I'm too wrapped up in writing this ever-expanding reply.

    Anyway, to the original poster (OP) and any interested readers, in thinking about all of this, try to clearly distinguish between input and output usage, as, I think, it's easy to get them confused. I'm admittedly not so clear on all of this or related matters, either, as witnessed by my two requests for correction above. However, with a clear distinction between input and output usage, I think it makes the lack of electrical contention but the possibility of logical contention easier to understand (such a logical contention possibility applying to both cases). Incidentally, another intriguing thing you may come across (perhaps such as in reading a PS/2 keyboard or similar) is the rapid turing around of the pin direction using DIRA to effect signaling/clocking (I forget the details). That may throw (perplex) one at first, but that's probably a topic for a different post (or slightly/somewhat more "advanced" usage). As for me, after a year or two of occasional usage, I too am still casually attempting to create the blue smoke and expect to any day now (as I've just cursed myself with the foregoing, no doubt), but I think such will have to involve either connecting two output pins directly together, or connecting a single output pin to the outside world with a voltage differential and no current-limiting protection resistor therebetween. I'm sure my "failure" to fry a chip so far is due in large part to not experimenting/attempting enough (though I may have unknowingly compromised a pin's ability). However, I also think the Propeller is also rather robust given half a chance (i.e., not doing anything too too "stupid"). At any rate, best of luck with your efforts! Apologies in advance for any disinformatoin; I'm still learning, too. --Jim
  • Cluso99Cluso99 Posts: 18,069
    edited 2012-02-11 22:09
    All pins can be read by all props (as inputs) irrespective of the DIR setting. You are actually reading the voltage at the pin. Therefore, if you have 8 unused pins you could use them to pass data between cogs. Or you could have one cog waiting for another cog to set a pin to synchronise between them. IIRC this is how some of the VGA objects work using multiple cogs to alternately generate each line.
  • DavidZemonDavidZemon Posts: 2,973
    edited 2012-02-15 15:51
    Is there a more thorough description of all the counter modes than page 98 of the prob manual v1.2?
    Table 2-7: Counter Modes (CTRMODE Field Values)
  • HShankoHShanko Posts: 402
    edited 2012-02-15 15:58
    @ SwimDude0614,


    Have you seen App Note AN001?
  • JonnyMacJonnyMac Posts: 9,105
    edited 2012-02-15 16:03
    Section 4.9 of the data sheet.
  • DavidZemonDavidZemon Posts: 2,973
    edited 2012-02-15 16:38
    HShanko wrote: »
    @ SwimDude0614,


    Have you seen App Note AN001?

    I had not! Thank you! Starting to read it now...
  • DavidZemonDavidZemon Posts: 2,973
    edited 2012-03-13 11:12
    Still reading through that AN001. Lots of big words (or small acronyms lol) that I haven't seen before and am looking up. But, overall very cool.

    Here's another question:
    Why didn't Parallax implement interrupts, watchdog timer, or extra peripherals?
    I understand it's nice that we have 8 cores to utilize, and we can still do a lot without interrupts... but we could do SO MUCH more if we had them. It seems silly that I need to use an entire cog to poll a pin and wait on input to do something while a second cog runs foreground tasks. This is something that can easily be done with a single cog if it had interrupts, allowing the other 7 cogs to do other useful tasks.
    WDT: self explanitory. Why no WDT?
    Extra peripherals: As a relative newbie to the uC world, I'm always looking at specs for other uC that I hear about. It seems like every other chip out there has many many more peripherals on it than the prop (with the exclusion of the timers & video generators). Why no ADCs? No built-in serial communication modules? No built-in ____? Again, this chip would become even more versatile if it had these.

    I know the prop2 prelim says it will have ADCs. I'm very grateful for that. But still not adding the rest of it?

    Are there any other uC out there that have all of these? I know ARM makes some multi-core processors, but IIRC they are in the $50 range.

    Thanks,
    David
  • DavidZemonDavidZemon Posts: 2,973
    edited 2012-03-13 11:43
    Ok, I did some looking at the ARMs. The ARM11 and Cortex-A offer up to 4 cores per chip, but the ARM11 is around $30 and doesn't come with ADCs and the Cortex-A5 (cheapest of the A series) isn't on sale on digikey. The Cortex-R series only comes in single and dual core packages, and also costs around $30 (for the lowest end - R4).

    I can't wait til the Prop2 comes out...
  • CircuitsoftCircuitsoft Posts: 1,166
    edited 2012-03-13 11:58
    The propeller doesn't have interrupts because the concept of emulating necessary hardware in software works best without. Microchip released a PIC without interrupts, and it was quite useful, though limited.

    By building your own peripherals, you can add the little bits of smarts you wish they would've had on any other micro.

    As for ARMs, I know you can buy asymmetric multi-core MCUs. The OMAP5 series is a dual-core A15 with two M4s as well.
  • DavidZemonDavidZemon Posts: 2,973
    edited 2012-03-13 12:17
    "the concept of emulating necessary hardware in software works best without"


    Can you expand on that? Doesn't make any sense to me. I would think that if interrupts were allowed, some people could use them, and if a different user didn't need them, they wouldn't have to use them. The only architecture (other than the prop) that I know very well at the assembly level is the Intel 8051. If you want to use interrupts with that, you simply ensure your main program starts with ORG 0x30 instead of ORG 0. If you don't want to use interrupts, you ignore them and program as if they didn't exist.
  • Mike GreenMike Green Posts: 23,101
    edited 2012-03-13 12:19
    The decision to not have interrupts was very deliberately done. Interrupts were originally developed to provide a mechanism for a processor to respond to an external event within a small amount of time, mostly so the processor could do some kind of I/O ... usually to read a hardware register before that register was overwritten with the next piece of information to come in or to respond to some kind of external event. Unfortunately, this messes up whatever else was going on before the interrupt occurred and it doesn't always fix the issue. For example, what if one device interrupts, then another device interrupts before the first interrupt routine is finished. The 2nd device may have to wait too long to be serviced and data might be lost or you need to have nested interrupt processing with its relative complexity in both hardware and software. This tends to introduce a lot of complexity into the code and some very very careful design and testing to ensure that this whole complex mess works reliably.

    By not having interrupts, but having multiple processors ensures that at least one processor can be assigned to each device that may need servicing. It also ensures that the code's timing is predictable and reproducible. There are no "magic" external events that can delay processing. Although it can complicate the code significantly, it is possible to write multithreaded routines that run in a single cog. FullDuplexSerial handles the receive and transmit sides of the serial port as interleaved threads and there's a 4-port serial driver that uses separate threads for the receive and transmit sides of each of up to 4 ports. Some of the video drivers do their initialization as a separate thread that executes during the vertical retrace interval. The JMPRET instruction makes this very straightforward.

    The Propeller is a software defined I/O device. The multiple cogs can either be used to implement one or more I/O devices or can run other code. You may worry about cogs sitting around occupying silicon real estate or just sitting around waiting for something to happen, but the same can be said for an unused UART or unused SPI interface. In addition, if you don't like how an I/O device is implemented or if it doesn't do something you need, you can change the code on the Propeller. If the device is implemented in silicon, you're stuck with workarounds until a new model comes out.

    A WDT can be implement using a cog or an external CMOS 555 timer depending on how separate you want the WDT from the rest of the hardware.
  • DavidZemonDavidZemon Posts: 2,973
    edited 2012-03-13 12:33
    Interrupts: So interrupts were not implemented to ensure prop devs do not try to make things more complex than they need to be? What about when they *do* need to be complex. The engine control unit I'm working on won't have any extra cogs to run these simple tasks (monitoring an input pin for a pulse, recording the delay since the last pulse).

    WDT & other peripherals: So this was a cost savings thing?
  • Martin HodgeMartin Hodge Posts: 1,246
    edited 2012-03-13 12:43
    I don't think it's fair to compare the Propeller with a full CPU architecture like ARM. The Propeller is a micro-controller, and it doesn't pretend to be anything more. It was designed to expand upon the successful software-peripheral architecture of the 8-bit SX.
  • DavidZemonDavidZemon Posts: 2,973
    edited 2012-03-13 12:45
    Sorry - I didn't mean to compare it to the ARM. I know most of the ARMs are in another class. I'm just trying to see if there's something else that has what I'm looking for and fits the bill better (so far, with the price of the prop where it is, it's still my first choice despite my above complaints)
  • KyeKye Posts: 2,200
    edited 2012-03-13 13:01
    You can often use up less prop chip cores by making one do more and more work.

    So... for example. I have a product that is about to come out next week called the CMUcam4:

    One core does serial. It runs a receive and transmit thread. Up to 150,000 baud.
    One core does high speed SPI bus interactions to a uSD card.
    One core inputs 8 MHz 8-bit parallel video data from a camera module and does basic image processing between video lines.
    One core takes processed binary images and displays them on a TV screen in NTSC or PAL.

    One core does all the up level code interaction, protocol, and functional stuff.

    And one core drives two servos, de-bounces a button, and does PID control on the two servos from data produced by the cog that is looking at video data. It updates at 1 KHz. If I told it to do more stuff it would have to update at a slower speed. But, If I rewrote it in ASM it would go much faster.

    I still have 2 cores left... I ran out of I/O pins before cores.

    Moral lesson? Don't waste your cores.
  • Heater.Heater. Posts: 21,230
    edited 2012-03-13 13:02
    SwimDude0614,
    Why didn't Parallax implement interrupts, watchdog timer, or extra peripherals?

    A very good question, not to stupid at all, and one that many newcomers to the Propeller ask.

    I might put it like this:

    In an ideal situation when your code runs it runs, and because we are dealing with the real world and real time external events we really want to be sure that nothing holds our code up from doing what it has to do. Else it might miss it's hard real-time deadlines. If there are no interrupts we can instruction by instruction calculate how long it takes to do whatever it is we have to do and be sure if we meet the timing requirements or not. Lets say we are driving a video signal and any delay would upset synchronization of the display.

    But now if we have some other real world even to handle what should we do?

    The logically simplest solution to that is to feed this new event to another processor and have it handle it whilst our first processor continues with whatever it has to do.

    Then if there were a third external stimulus to deal with, no problem, just feed it to another processor. And so on.

    Of course historically we did not have enough transistors available to implement a whole processor per external event in a micro-controller. The work around for this is to implement a single CPU with interrupts. Logically the same. IF the processor has the speed to do all the work of all the events. But now you are into a whole world of complication, having to hook processes into interrupts, assign priorities etc. Plus if my software module uses, and needs, all the time available how are you going to use it in your project on a single CPU micro-controller?

    Bottom line is: Interrupts are the poor mans way of getting multiple processes. They works as long as your CPU is fast enough. They introduce a whole world of pain when integrating software components from external sources (think Parallax OBEX) where you have to analyse everything to figure out the timing budget.

    Now, about the extra peripherals:

    Logically, any logical function that can be done in hardware can be done in software. Functionally they are equivalent. That is of course if the processor running the software is fast enough.

    Given that idea, it would be grate to not have any specialized hardware peripherals. Just have a lot of processors and implement those peripheral functions in software. That would mean instead of having to search out and find the correct chip with the right combination of peripheral for you next job you just pull another one of your multi-core chips out of stock and configure it how you like. If your design changes, no prob, no need to find a new chip, just reconfigure the one you have. By the way, with the Prop any COG can use any pin so there is no rearranging of board design to shuffle things around.

    So, there you have it. No interrupts because they are a cludge to get around not having processors and make software integration and timing analysis hard. No peripherals because they are a cludge to getting around not having a fast enough processor(s) and inhibit flexibility of design.

    At this point I should point out that XMOS (oops I said it) has the same idea with their line of multi-core MCUs.

    Having said all that, following the "no periphals, no interrupts, multi-core philosophy has its limits. Perhaps you really need USB 2 or ethernet speeds that really can't be done on the Prop. A product designer has to choose what works.

    Still the Prop II will push those limits further out without giving up the central idea.
  • DavidZemonDavidZemon Posts: 2,973
    edited 2012-03-13 13:04
    Kye wrote: »
    You can often use up less prop chip cores by making one do more and more work.

    So... for example. I have a product that is about to come out next week called the CMUcam4:

    One core does serial. It runs a receive and transmit thread. Up to 150,000 baud.
    One core does high speed SPI bus interactions to a uSD card.
    One core inputs 8 MHz 8-bit parallel video data from a camera module and does basic image processing between video lines.
    One core takes processed binary images and displays them on a TV screen in NTSC or PAL.

    One core does all the up level code interaction, protocol, and functional stuff.

    And one core drives two servos, de-bounces a button, and does PID control on the two servos from data produced by the cog that is looking at video data. It updates at 1 KHz. If I told it to do more stuff it would have to update at a slower speed. But, If I rewrote it in ASM it would go much faster.

    I still have 2 cores left... I ran out of I/O pins before cores.

    Moral lesson? Don't waste your cores.

    Sweet. Sounds like I have lots to learn about efficiency still. I'll probably post up questions regarding that efficiency once I get further into the project and start needing it.
  • Mike GreenMike Green Posts: 23,101
    edited 2012-03-13 13:06
    Peripherals: Not at all a cost savings thing. This was a deliberate design decision. The designer (Chip Gracey) of the Propeller has a lot of experience with the Microchip product line which is characterized by lots and lots of slightly different models with different combinations of hardware peripherals. Historically, these have often been buggy for a few "revisions" of the silicon requiring sometimes messy workarounds. Among other things, he decided to base the Propeller on the notion of software defined peripherals. I've had a Propeller with one cog containing a PS/2 keyboard and mouse driver, one cog with an I2C and SPI driver used for EEPROM and SD card access, two cogs with a VGA text display driver (two for throughput reasons), one cog with a high speed UART, and one cog for the main program. That leaves 2 cogs. If I don't use them, they use virtually no power. On the other hand, I can use one for a high speed serial port to a PC running ViewPort for debugging and I can even add another display (an NTSC TV text display) for debug output separate from ViewPort.

    The Propeller does have some special purpose hardware. They're not complex enough to be labelled "peripheral blocks" and they do need the support of a cog. These would be the two counters in each cog and the video output shift register. They can be used for a variety of time dependent tasks. On the other hand, a cog can easily track the time since any of several pulses have begun. It may require some brute-force coding rather than making use of some of the special instructions like WAITPxx. It depends on the details of what you need to do. The system-wide clock counter can be used to mark the start of a measurement period.

    The Prop-1 can do multiple ADCs (2 per cog) using 2 I/O pins, a pair of resistors, and a pair of capacitors per ADC. They're not as good as you can get using an external ADC, but they're good enough for audio in the voice range.

    No one here is claiming that the Propeller is the "best microcontroller", whatever that means. It happens to be carefully and very well designed. It's reliable and resistant to a lot of abuse. There's good support for it. The decisions made in its design make it extremely useful for a variety of tasks, particularly where signal processing is involved. It's also different from many other microcontrollers and that may require rethinking how things need to be done.
  • Heater.Heater. Posts: 21,230
    edited 2012-03-13 13:11
    SwimDude0614,
    Can you expand on that? Doesn't make any sense to me. I would think that if interrupts were allowed, some people could use them, and if a different user didn't need them, they wouldn't have to use them.

    True except:

    When you are mixing and matching software components from different sources, like OBEX or just the forum or whatever, if they all have their different timing requirements and use various interrupts in different ways you are going to have to analyze the complete ensemble to figure out if it is going to work or not.

    With multi-cores and no interrupts you can be sure that throwing in that serial driver you suddenly realized you need is not going to upset any of the carefully timed code in your project already.

    This is a situation that happens all the time around here.
  • pedwardpedward Posts: 1,642
    edited 2012-03-13 13:21
    I just wanted to add to what Mike said. Chip was the architect for the SX chip too. He worked with Scenix to design the chip based on the PIC instruction set. He didn't do the actual HDL, but he wrote the specs and designed the hardware debug interface. You could sort of consider the SX a test run for the Propeller, since it has many of the same design principles; the SX is basically a single COG. I'm oversimplifying a little bit here, but that's to convey a point, not to make a highly technical comparison.
  • DavidZemonDavidZemon Posts: 2,973
    edited 2012-03-13 13:25
    Heater: That makes a lot more sense now. Hadn't thought of that.

    Mike: That clears up a lot more, as always.

    Does the SX have interrupts? If it's as similar the prop as I'm hearing, it might work beautifully as a "peripheral" to the prop. I might use that to communicate with all the engine sensors and then stream data back to the prop.
  • CircuitsoftCircuitsoft Posts: 1,166
    edited 2012-03-13 13:55
    I really think of the prop as a fantastic peripheral in-and-of itself. I plan to make my own engine management system as well, but it'll probably be rather different from yours (fuel injection via home-made servo drive on a CIS box...)

    I figure I should be able to do coil-on-plug spark timing, ion sensing, and crank-position capture with one cog, watch multiple MAPs and IATs with a second, leaving a third to run the fuel-flow servo, and a fourth do all the math, and 4 more for whatever else I decide to tack on later. Maybe VVT?
  • DavidZemonDavidZemon Posts: 2,973
    edited 2012-03-13 13:56
    VVT? You've got a much newer engine to play with than me lol.
  • CircuitsoftCircuitsoft Posts: 1,166
    edited 2012-03-13 14:09
    Well, not really. I'm building a VVT system...
  • JasonDorieJasonDorie Posts: 1,930
    edited 2012-03-13 14:40
    SwimDude - As a good example of where the Prop excels, I've written a program that flies a quad-rotor. The cogs are divided up as follows:

    - R/C receiver - Measures pulses from 8 incoming pins. The pulses don't have to be in any order, and it has 1us accuracy
    - Sensor I/O - A digital gyro and accelerometer are read at between 200 and 2000 hz, depending on the software settings
    - Servo output - 8 pins are simultaneously pulsed at either 250Hz or 50Hz, with pulse lengths between 1ms and 2ms, with 1us accuracy
    - Serial IO - For debugging or viewing sensor readings in a debug app
    - Flight control - All of the above is controlled by a main loop, taking the readings, doing some math, and setting the servo output values to balance the craft, at 250hz
    - SD card logging - 16 different readings are written to an SD card at 250 hz

    And I still have two hardware threads left over. I have another version of the software that uses those extra cogs to run an "orientation estimator" and a floating point math library, allowing the craft to balance itself with no user input. The closest thing to this on a single-threaded chip requires a lot of very skilled coding to handle all the timing requirements and interrupt priorities, and even then it'll still be a bit less accurate than the Prop if one of those interrupts fires at a bad time. In this case the design of the Propeller is very well suited to the problem.

    Also, you don't need to use a whole cog to monitor one pin - The R/C receiver cog mentioned above is a good example - It polls 8 pins in a loop, and if anything changes, it writes the pulse duration to the hub where other cogs can read it. It does 8 pins at better than 1us, which is the highest resolution I need. With clever use of the counter registers, you could monitor two pins with 80MHz accuracy, and that's with very minimal support from a cog. You could use the same cog to monitor additional pins in software.

    It may seem strange to use threads for things that other micros provide in hardware. I always found it strange that on other chips I had to write my code around which peripherals are supported on which pins, and how to arrange them so I can use the UART, timers, and ADC at the same time.
  • pedwardpedward Posts: 1,642
    edited 2012-03-13 15:11
    On Heater's point of interrupts, I wanted to share a bit of theory.

    I wrote some code for an embedded Hitachi processor to do datalogging of automobile sensors. There were several time based inputs (system timer, injector cycle, ignition timing, VSS) and these were implemented with interrupts.

    If you venture into interrupts, you have to treat interrupt handlers as lightweight threads that do the timing critical work, then offload that data to the main loop to process at a lower priority. In essence, interrupts are where all the work gets done, not the main loop, because the main loop isn't deterministic. While you are executing an interrupt, the timing of that interrupt is deterministic. You can use nested interrupts, but I don't consider that a good practice because you may be re-entrant (executing the same routine again before the first invocation is finished) or you may interrupt a handler to run another handler, both situations prevent the interrupts from running in a deterministic timeframe.

    The flip side of interrupts is that the interrupt has to complete before another interrupt can run, which means you might miss an event because interrupts are disabled (like Intel), or it might queue interrupts (where an interrupt mask is used).
  • cavelambcavelamb Posts: 720
    edited 2012-03-13 16:19
    pedward wrote: »
    On Heater's point of interrupts, I wanted to share a bit of theory.

    I wrote some code for an embedded Hitachi processor to do datalogging of automobile sensors. There were several time based inputs (system timer, injector cycle, ignition timing, VSS) and these were implemented with interrupts.

    If you venture into interrupts, you have to treat interrupt handlers as lightweight threads that do the timing critical work, then offload that data to the main loop to process at a lower priority. In essence, interrupts are where all the work gets done, not the main loop, because the main loop isn't deterministic. While you are executing an interrupt, the timing of that interrupt is deterministic. You can use nested interrupts, but I don't consider that a good practice because you may be re-entrant (executing the same routine again before the first invocation is finished) or you may interrupt a handler to run another handler, both situations prevent the interrupts from running in a deterministic timeframe.

    The flip side of interrupts is that the interrupt has to complete before another interrupt can run, which means you might miss an event because interrupts are disabled (like Intel), or it might queue interrupts (where an interrupt mask is used).


    And if your main loop doesn't complete in time to poll the "interrupt" pin???
  • Mike GreenMike Green Posts: 23,101
    edited 2012-03-13 16:54
    If your main loop takes too long to execute, you'll miss the time window for polling. If you're using interrupts, you may be able to service the hardware signal, but your main loop is still too slow and you'll eventually get behind and lose data. If you have a deterministic processor like the Propeller, you can calculate precisely how long the main loop will take to execute and change over to a very predictable multithreaded scheme to meet the timing requirements for the polling. You may also move the polling operation to another cog with time to spare. With interrupts, this is a much more difficult process because interrupts can literally occur at any point in the program and worst case situations are terrible.
Sign In or Register to comment.