Jump to content


  • Content Count

  • Joined

  • Last visited

  • Days Won


Posts posted by spirilis

  1. I'm just hypothesizing here but doesn't the F5529 have an RTC within?

    Makes me wonder why Energia doesn't leverage that for millis and such functions.

    IIRC, it does, but only under sleep() and sleepSeconds() mode.  Higher resolution is available via DCO which is why it uses it.  Just not necessarily the best accuracy I guess...

  2. That is true, millis only updates when the ISR fires, so your sketch may be pulling the millis value some time "after" the last tick.


    For the purpose of getting a super-accurate clock, I would look into making your "own" millis-style API using one of the Timer_A peripherals and include a direct-read of the TAxR register to compensate for between-ISR timing.  You should have free access to declare one of the Timer_A interrupt vector entries in your own sketch without Energia getting in the way.  Just be sure you're not using a PWM output pin that happens to use that same Timer_A instance or else Energia's analogWrite() call will clobber your timer settings.

  3. Not too terribly accurate as you've found. It would require modifying the Energia core quite a bit to change millis() as it uses the Watchdog timer.


    Jitter and drift will be caused by the main oscillator (DCO) mostly. It's not known to be all that accurate but can be trimmed. At least with the F5529 there is an FLL driven by the 32.768KHz XTAL to auto-trim it.

  4. @@spirilis


    So I picked up that book for go lang you mentioned above. Partly because of what you said here. But also very recently I talked with another developer for the project I've been writting test software for lately. Who pretty much started out in C exactly how I did gamedev, and reading Andre Lamothe's programming books . . . but anyhow he is writing the functional application code for this same project using GO . . . So now, I'm forced to read this book on a new object oriented language that uses no classes, inheritance . . . etc heh. Sounds interesting so far !


    Sorry @@chicken, but I did not know where else to post this . . .

    Yeah Go really goes about it a bit differently, the "implicitly satisfied interfaces" becomes your rough method of inheritance and class-ishness I guess.  It's working well enough for me so far.

  5. What kind of errors?  I have Windows 10 Professional (laptop came with it preinstalled though) and no problems, but I will note I made sure to install all the TI drivers in signature-ignore mode (i.e. hold Shift while clicking the Restart menu option under Start>Power, select reboot to options menu, select option 7 after the reboot for booting with no driver signature verification, then install drivers in that special mode).  I did the same thing when I installed CCSv6 too.

  6. The Energia framework itself doesn't really play well with the MSP430 USB API from what I recall. There is a "USBSerial" example shipping with Energia but it's mostly a hacked up example using an old version of the MSP430 USB API (pre-driverlib if I'm not mistaken).


    With straight CCS C/C++ you can use the MSP430 USB descriptor tool to generate custom USB setups.

  7. Well another consideration, and perhaps you've already thought of this too is this: What kind of performance implications are incurred because of this ? But . . . GO being interpreted . . . I'm not going to expect it to be super fast anyway,


    But anyhow. This is part of what makes up a good programmer right ? Knowing the limits of the languages we use, *OR* as in my case, I code defensively in many cases. So like in @@chicken's example above. I try my best in many case, unless I do not care about the code ( test code etc ), not to let values auto-overflow. You can see proof of that in the WDT code ive been sharing lately. The last several code posts keep at least one variable ( volatile unsigned int ) from overflowing.

    Fwiw Go is actually compiled.  With a bit of a binary runtime that "tags" along and manages the threading subsystem + garbage collection... but the Go compiler actually has its own assembler & linker and circumvents the use of any "C" code whatsoever.  The compiler used to be built as a C program for quite a while but around 1-2 major releases back, they ditched the C portion and it's now written entirely in Go from what I read


    Mind you, Go is written by Rob Pike (think Plan9), Ken Thompson (think UNIX) formerly of Bell Labs... and their team of folks at Google along with other input/help/contributed libraries from the open source community at large.  The book that introduced me to the language, "The Go Programming Language", was coauthored by Brian Kernighan (also of Bell Labs and the 'k' in the AWK utility under Unix).  These guys pretty much know what they're doing.  Anyway enough threadjacking :)

  8. Yeah, you and I do not always see eye to eye on topics such as this. But what bothers me so much about situations like this is that people start second guessing other people, and then they tend to lose focus on what really matters. Like language features. In this particular case, I expect a loop to iterate in the order that makes sense ( 0, 1, 2 . . . unless step x), and I also expect a number key, to somehow programmatically return it's dictionary value. So if the implementers of GO broke a part of their language on purpose that keeps that from happening. I'm going to start second guessing that they are language implementers SUCK for having too much time on their hands . . . ;)


    That last little bit was tongue in cheek about the implementers of GO "being SUCK". But I still do think if I have it correct above - that what they did was extremely silly.


    As far as on topic goes . . . I usually do not optimize all that much, and I always view the more extreme optimization options as  . . . "off limits".


    Well yeah one fun thing about the example I gave is that I specifically assigned the entries in a logical order ... but the point here is, that iteration doesn't necessarily make sense in the case of a map because things can be deleted and re-added arbitrarily and the order can be a bit "undefined" and difficult to ascertain.



    myMap := make(map[string]int)
    myMap["ten"] = 10
    myMap["nine"] = 9
    myMap["zero"] = 0
    myMap["one"] = 1
    for k, v := range myMap {
        // One might "assume" to see 10, 9, 0, then 1 here
        fmt.Printf("Value: %d\n", v)
    myMap["three"] = 3
    for k, v := range myMap {
        // But what about this?
        fmt.Printf("Value: %d\n", v)
    myOtherUnrelatedMap := make(map[string]string)
    myOtherUnrelatedMap["foo"] = "bar"
    myOtherUnrelatedMap["bleh"] = "this sucks"
    myOtherUnrelatedMap["america"] = "fu** YEAH"
    for k, v := range myOtherUnrelatedMap {
        // Just what kind of order do you expect here?
        fmt.Printf("Value: %s\n", v)

    It looked logical in my first example that the for ... range ... fmt.Printf should print stuff in some kind of numerical order, but a map isn't meant to be an ordered list.  It's an unordered hash map.  So Go destroys anyone's temptation to assume it an ordered list by making CERTAIN it's unordered - using randomization.  The idea here is to avoid programmers from "assuming" the map will get iterated in a consistent logical order (and structuring some small but potentially critical part of their code logic around this assumption) and then go off and do something stupid with it that makes their assumed "order" incorrect but they don't realize it.  By ensuring iteration through a map is random, they can't fall into that trap.


    Alas, I get your position on this one.

  9. Oh and I did not read that fully:

    break programmers' code when they try to rely on assumptions based on consistent undefined behaviors

    Morons  to the power of two. Iterating through values from 0 to n is considered "undefined behavior" in go ? Yeah wow Nova ( No va) for me ;)

    I personally find it a good thing, in that this is creating a programming environment where the likelihood of mental blindspot-like errors is low.  Combining Go with an IDE that actively syntax-checks, like Visual Studio Code (the javascript side project of the M$ VS team), I've found that I can write Go code that usually works pretty much perfectly as expected ... sometimes on the first compile.  I'm quite pleased with what Google and the Go team are doing here.  Alas, to each his own ;)

  10. Here's a very interesting presentation about how modern compiler optimization may lead to unexpected results. This goes way beyond the failure of naive delay loops.



    If you ever relied on buffer indices wrapping around (integer overflow), this is a must read. There are many other scenarios discussed.


    For example I'm pretty sure I fell for this trap myself:

    volatile int buffer_ready;
    char buffer[BUF_SIZE];
    void buffer_init() {
      for (size_t i = 0; i < BUF_SIZE; i++)
        buffer[i] = 0;
      buffer_ready = 1;

    It probably works today. But it's a bug waiting to happen when I recompile with different optimization settings or a different compiler. (hint: buffer_ready=1 may be moved before the for loop because the loop does not affect any volatile location).


    Lol reading this presentation is almost nauseating!

    As a side note, one thing about the "Go" programming language I found amusing is how they intentionally break a few undefined behaviors, such as:

    myMap := make(map[string]int)
    myMap["zero"] = 0
    myMap["one"] = 1
    myMap["two"] = 2
    myMap["three"] = 3
    myMap["four"] = 4
    myMap["five"] = 5
    for k, v := range myMap {
        fmt.Printf("Value: %d\n", v);

    This code will not produce a neat order of 0, 1, 2, 3 .... It will be shuffled/randomized.  The Go designers did this intentionally to break programmers' code when they try to rely on assumptions based on consistent undefined behaviors.  As a result you are forced to convert those sorts of things into a list and sort them or whatever ... something better-defined anyhow.

  11. I do know the CC3200 peripherals are different from the TM4C123's.  I personally liked the TM4C123 peripherals.  CC3200 peripherals suck, and the MSP432 just uses a jacked version of the old MSP430 peripherals which suck compared to the TM4C123's too.


    Luckily, the newer SimpleLink CC26xx (BLE/2.4GHz 802.15.4 ZigBee-et-al type of crap) and CC13xx (sub-1GHz) ARM chipsets appear to borrow the TM4C123 peripherals from what I can tell... (and throw power consumption metrics down even further than the MSP432).

    They also have a digital I/O switch matrix that lets you route any peripheral's function to any of the GPIO's which is sweet.

    (</end TI marketing schpiel since I don't actually work for TI>)


    Of course none of this helps you with WiFi...

  12. ah, i figured it would get a directory not found error.

    works perfectly, thank you. :)

    Have a peek at <energia install location>\hardware\<platform>\libraries BTW... e.g.:




    Some stuff might be in the core, which is also fun to peruse:


  13. I'd say the main (perhaps only) reason for making your own PCBs is if you enjoy it. Whilst in theory I could make a board in a couple of hours, it would take me 2 weeks to find those spare hours!

    It's been a rare incident when I've needed a quick prototype PCB "that" quickly.... and mostly for quick Christmas gifts 1 week before ;-)

  14. Good catch.

    @@energia minor documentation fail!

    Although the method is related to the one accidentally described, but it should have been rewritten for clarity IMO.


    Plus the capitalization in the link down below for Stream.SetTimeout looks weird... though I can't corroborate if that's correct on my phone right now.

  15. There's a bunch of /etc/udev.d/rules entries you should have that might "grease the skids" for Energia FET updates.  Unfortunately I don't have them handy anymore (blew away my Linux install and went with a new Windows 10 laptop...)


    edit: Are you using Energia as a normal user or as root?

    This is important, what those "udev rules" I mentioned do is allow normal users (or users in the "dialout" group usually) to have write access to the USB VID/PID of the FET's USB bootstrap loader.

  16. @@spirilis When I click on the link all I see is the 5x2 configuration, J103 is a 1x7 configuration.


    EDIT: Also, if you happen to know where to get those .05 1x7 connectors, I would be interested.

    Ahh nevermind... I should've checked the datasheet/schematic :P


    Yeah no idea what to do there.  I mean strips of 50mil pins are available (just cut to length)... I am happy they improved this in the later XDS110 LP's like CC2650 & CC1310.

  17. How about J103 - XDSET_DEBUG_CON... The description on the schematic: "External XDS-ET access. Debug external targets. Set S101 appropriately".

    Could this be used (somehow) to program external MCU?

    OK maybe that's it!


    FYI- I ordered some 50mil 2x5 cables from Tag-Connect recently ( http://www.tag-connect.com/ ), although the 2x5 connectors themselves (for your own external board) aren't sold by all distributors...


    More info on that connector:


    http://www2.keil.com/coresight/coresight-connectors/ - first one


    A 10-pin header (Samtec FTSH-105-01) is specified with these dimensions:

    0.25" x 0.188" (6.35 mm x 4.78 mm).


    Mouser.com doesn't sell Samtec products but Digikey does: http://www.digikey.com/product-search/en?keywords=FTSH-105-01 - I haven't looked but they might sell the 10-pin F-F patch cables too.  Mouser didn't seem to...


    My plan will be to use the 6 pin Tag-Connect footprint on my boards and their pogo-pin no-legs contact footprint.

  18. Yes remove the jumper block and attach a suitable cable ... IIRC (don't have mine in front of me) there is an ARM Cortex SWD header on the board, 2x5 pin 50mil (1.27mm) pitch header, that can be used with a suitable jumper cable to program another MSP432 project externally.  Remove the jumpers from the jumper block of course so the XDS110 JTAG programmer (top 1/3rd of the launchpad board) isn't trying to program the launchpad's own MSP432 of course.


    edit: hmm, I might be wrong about this, the 2x5 header on the MSP432 launchpad might only be for attaching external JTAG tools to the MSP432 onboard chip.  Some of TI's newer XDS110-based launchpads, namely the CC2650 LP and CC1310 LP both have headers allowing you to use the onboard XDS110 to program external chips (rather than the header existing solely to attach external JTAG tools to the launchpad's own main chip).

  19. Oh man.  What's worse though, is when TI blatantly ignores the XDC system and tosses an "XDC-lookalike" API in place instead...


    C:\ti\tirtos_cc13xx_cc26xx_2_16_01_14\products\tidrivers_cc13xx_cc26xx_2_16_01_13\packages\ti\drivers\PIN.h being a fantastic example.


    All the right object names, such as "PIN_Handle", but typedef'd inside one huge .h file instead of properly implemented using XDC code.  Not even sure where some of the functions live since they're declared extern inside the .h file while some of the "methods" are declared static with code present inside the header.


    What a mess!

  20. Oh, sounds like TI has another "fan" of their function naming convention ;)


    @@spirilis on a side note though I get their reason, at least partially, and of course from my own perspective. C, is fairly straight forward and easy to grasp as a language. Where C++ can get really complex, depending.


    But I think if I could, I would *maybe* opt out of both ( definitely C++ ), and use javascript instead. . .  ;)


    Well the function naming convention does have a method to its madness.  It's just a poor man's C way of defining namespaces.


    Power_init() is probably best thought of as "Power.init()" ... Spi_Handle (or any Modulename_Handle) is just the inevitable pointer to an object's internal variables that you need to carry around when referencing objects; C++ does this for you implicitly but under the hood the same damned thing basically happens (look at the generated ASM from a C++ program's object's method calls, you'll find a pointer to the object's internal struct loaded into one of the argument registers before the call happens, you just don't have to explicitly tell it to do that in your C++ code).

  • Create New...