Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 15 of 15

Thread: C# Library for Uploading Firmware from User Applications

  1. #1
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    799

    C# Library for Uploading Firmware from User Applications

    Hello all,

    I'm currently working on a commercial project which will include a Teensy 3.1. As discussed a few times in the forum for many applications it is desirable to upload new firmware from within windows applications. I therefore wrote a little easy to use C# library which handles uploads to Teensy boards. For the protocol I used the algorithms from the Teensy_Loader_CLI. Communication with the board is done via Mike O'Brians HIDLibrary (https://github.com/mikeobrien/HidLibrary). The lib is published it at GitHub (https://github.com/luni64/TeensySharp, VS2013 Solution).

    The usage is quite simple. Below you find some pseudo code showing the idea. A working test app is included in the repo
    Code:
                        
    var Board = PJRC_Board.Teensy_31;  // all boards implemented but only Teensy 3.1 tested so far           
    var FlashImage = SharpUploader.GetEmptyFlashImage(Board);  //Get an empty flash image with the correct size and all bytes cleared (i.e. set to 0xFF)    
    
    // Open the hex file, parse it and write the result into the image file
    var HexStream = File.OpenText(testfile);
    SharpHexParser.ParseStream(HexStream, FlashImage);    
    
    // Upload the image to the board and reboot
    int result = SharpUploader.Upload(FlashImage, Board, reboot: true);
    The Lib works nicely for T3.1. I don't have other Teensies so I couldn't test it for those boards. Any feedback, test results and improvement suggestions welcome

    Have fun
    Lutz
    Last edited by luni; 07-01-2015 at 08:56 PM.

  2. #2
    Senior Member
    Join Date
    Jul 2014
    Posts
    139
    This looks great, thank you.

  3. #3
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    799
    I updated the TeensySharp library with a class to find all Teensies on the USB tree of a windows system. This class can be used in your Windows applications to provide a list of all currently connected Teensies (USB Serial) together with their Serialnumbers and the Port Names (COMXY). Windows has a habit of changing those Com Port Numbers from time to time which can be quite confusing for the average user.
    With the libaray you can open the SerialPort without having the user to know or select the Port Number from a list or whatever. You can even attach an eventhandler which will notify you if somebody connected / disconnected a Teensy board. Effectively this will allow for a fully transparent autoconnect feature in your applications (You can automatically open the ComPort when a user plugs in your Teensy Device)

    Documentation, source code and examples can be found on GitHub. https://github.com/luni64/TeensySharp


    Questions:
    1. To upload firmware I still have to start HalfKay by pressing the program button. Pauls GUI Loader can do this automagically, I didn't find any documentation on how to achieve this. Any pointers?
    2. If Teensy is running the USB Serial protocoll it reports a nice (unique?) serial number in the DeviceID. This comes in handy if you have more than one board connected. HalfKay does not seem to report this number, at least I didn't find it. This would be a very nice feature. (e.g. In a production system I want to be sure that my users download the firmware to the correct device which can be difficult if I have more than one Teensy running)


    Lutz

  4. #4
    Senior Member Koromix's Avatar
    Join Date
    Dec 2013
    Location
    Lille, France
    Posts
    198
    You can reboot a board in serial mode by setting the baudrate to 134. The procedure is obviously different if your board runs in HID (such as Raw HID), then it involves sending a magic feature report

    HalfKay reports the serial number, but with a few caveats:
    - it's hexadecimal (e.g. 000116FF)
    - since Teensyduino 1.19 (IIRC) the running serial number is multiplied by ten to work around a bug in the OSX serial driver (so 000116FF in HalfKay == 714230 when running)

    So to match the running serial number, you just have to convert the number from hexadecimal and multiply it by ten unless it's equal or superior to 10000000. I send you to the core commit related to this: https://github.com/PaulStoffregen/co...9bb2e90aaf194d

    I believe you can get the serial number from a HID handle with HidD_GetSerialNumberString().

  5. #5
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    799
    Thanks for the information Koromix, that helps a lot. I will try the HalfKay serial number parsing this evening.
    I assume in order to reboot I have to set the baudrate to 136 on the teensy firmware? If so, I still don't understand how the TeensyLoader is able to start HalfKay regardless what firmware is running...

  6. #6
    Senior Member Koromix's Avatar
    Join Date
    Dec 2013
    Location
    Lille, France
    Posts
    198
    Nono, you do it on the computer using SetCommState() on the device HANDLE, which you get by opening the COM port. I don't know much about the .NET framework and if it provides anything to manage serial ports, but here is some (untested) C/Win32 code to do it (without error management).

    Code:
    DCB dcb;
    DWORD previous_rate;
    
    dcb.DCBlength = sizeof(dcb);
    
    /* Get this HANDLE with CreateFile("COMx") */
    GetCommState(handle, &dcb);
    previous_rate = dcb.BaudRate;
    
    dcb.BaudRate = 134;
    SetCommState(handle, &dcb);
    
    /* Restore the previous baudrate, to make sure Windows does not try to apply this setting on
        a future device/Teensy (and reboot it again) */
    dcb.BaudRate = previous_rate;
    SetCommState(handle, &dcb);

  7. #7
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    799
    Great, that works perfectly. In .net it is as simple as

    Code:
    ...
    var Com = new SerialPort("COM14"); 
    Com.Open();
    
    int OldBaudRate = Com.BaudRate; 
    Com.BaudRate = 134;
    Com.BaudRate = OldBaudRate;
    ...
    Thanks a lot

  8. #8
    Junior Member
    Join Date
    Jan 2018
    Posts
    9
    Thanks for sharing that library. How reliable is it? Have you ever bricked a Teensy with it?

  9. #9
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    799
    I never bricked a Teensy with it and I never got any complaints.
    The library uses the algorithms from Pauls CLI uploader. I'm quite sure that technically you can not brick a Teensy by downloading firmware but of course I can not guarantee anything.

  10. #10
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    3,267
    you cant “brick” a teensy unless you intentionally try to erase the flash boot sector or short the wiring, ir apply too much voltage to any pin...

  11. #11
    Quote Originally Posted by tonton81 View Post
    or apply too much voltage to any pin...
    That would be "smoking" or "blowing", not "bricking".

  12. #12
    Junior Member
    Join Date
    Jan 2018
    Posts
    9
    Quote Originally Posted by luni View Post
    Pauls CLI uploader.
    Is the code for that uploader available somewhere?

    I was just looking at TeensySharp source code and could not find a Teensy 3.2 value in PJRC_Board. I guess I should just use Teensy_31 since both 3.1 and 3.2 boards are compatible right?

  13. #13
    Junior Member
    Join Date
    Jan 2018
    Posts
    9
    So I just gave it a try and TeensyWatcher could not find my board as it's not matching any of the expected product IDs.
    My product ID is 0x0476 but that very much depends how you configured it.
    For Teensy 3.2 I've noted the the following product IDs for instance:
    const int KProductIdTeensy32KeyboardMouseJoystick = 0x0482;
    const int KProductIdTeensy32RawHid = 0x0486;
    const int KProductIdTeensy32AllTheThings = 0x0476;

    The TeensyWatcher code is expecting either:
    const uint serPid = 0x483;
    const uint halfKayPid = 0x478;

    Is this a limitation of the uploader or an issue with TeensyWatcher implementation?

  14. #14
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    799
    Uploader: https://github.com/PaulStoffregen/teensy_loader_cli

    I guess I should just use Teensy_31 since both 3.1 and 3.2 boards are compatible right?
    Yes

  15. #15
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    799
    The TeensyWatcher code is expecting either:
    const uint serPid = 0x483;
    const uint halfKayPid = 0x478;

    Is this a limitation of the uploader or an issue with TeensyWatcher implementation?
    This is not a principle limitation. When I did TeensySharp / TeensyWatcher I only implemented it for Teensies in serial mode (0x483). Extending to the other modes is possible (and not really difficult) but since I didn't have a use case / request until now I never did it.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •