Saturday, March 11, 2017

General update

It has been several months since the last post; several projects starting up at work, and several projects around the house keeping me busy.

Here is the plan over the next few weeks:
  1. New OrangePI Zero buildroot tutorial 
    1. Basic configuration 
    2. Patches (from Armbian) for WiFi 
    3. How to configure kernel for RT_PREEMPT 
      1. Best way to configure OS for real-time multicore response
  2. Updates on BetaFlight conversion to Linux (never ending)
    1. Issues in porting
      1.  creating a HAL (Hardware abstraction Library)
        1. SPI 
        2. Serial
        3. I2C
        4. GPIO
        5. Interrupts
        6. Timers
    2. Goal is to be able to run BetaFlight 
      1. Linux
      2. Micro-controller 
        1. Must have I2C flash or SDCard
        2. Use FreeRTOS
          1.  Zephyr RTOS is interesting more of a Linux based RTOS (ITS NOT LINUX)
    3. Also doing a for arducopter 
  3. Complete Udoo NEO M4 port OpenAMP
    1. Update MQX to use OpenAMP
      1. Did a port a while back need update this

Yes this is a large list, but there are 25 hours in a day ! ;) yes a management theorem.

If there is any questions please ask.. always looking for idea's for postings

Saturday, November 12, 2016

LinuxFlight parts list

Making progress:

  • Fixed gyro interrupt.
    • Able to single with gyro ISR callback using epoll, and GPIO.  Need to merge into the flight controller loop.
    • Started moving code for GPS parsing using C++/ boost ASIO
Here is the parts list:
Opted to use a OrangePI Zero over the Neo AIR.  The goal is to get something in the air and then move to using a camera OSD/OpenCV.

Still can use a USB camera for a simple test.  

Here is a trace of the flight controller loop at 8Khz.  What is interesting is the I2C poll for the baro/Mag.

Saturday, November 5, 2016

LinuxFlight Progress OrangePI PC

Testing barometer(MS5611) and compass (HMC5883L) with CleanFlight configurator.  The first trial will be with the OPC, then with the new OrangePI Zero.

Things to do:

  • Need to add GPIO interrupt callback to sync the gryo
  •  Merge GPS parser boost asio thread. 
  • Add blackbox logging
  • lttng logging to validate timing
Some progress, going to order quad-frame, moters,esc, etc.  Time it is all assembly board should be ready along with firmware. 

Any questions? 

Wednesday, October 26, 2016

OrangePI PC with Buildroot and Linux-4.9 (LinuxFlight)

The OrangePI PC booting/working with 4.9-rc1.  This is possible due to github project.

[    0.000000] Linux version 4.9.0-rc1 (tcmichals@tcmichals-Studio-540) (gcc version 5.4.0 (Buildroot 2016.11-git-01024-g731b3c5) ) #6

So far have tested:

  • Ethernet works
  • I2C works.
  • THS works
  • Added some patches to SPI  Instead of using the entire patch, just changed the FIFO to 64 and added DT changes.  Also changed spidev.c and added:

static const struct of_device_id spidev_dt_ids[] = {
{ .compatible = "rohm,dh2228fv" },
{ .compatible = "lineartechnology,ltc2488" },
        { .compatible = "spidev" },  //TCM:FIX 

One issue just encountered several days ago is how to run Java; the solution is Java SE embedded.  Just follow the instructions here.

# java -version
java version "1.8.0_111"
Java(TM) SE Embedded Runtime Environment (build 1.8.0_111-b14, profile compact1, headless)
Java HotSpot(TM) Embedded Client VM (build 25.111-b14, mixed mode)

The goal of LinuxFlight is to be able to run Java, Python and C++ plugins/modules.  Pieces of the flight code can be offloaded to other modules, or to different programming languages. 

The current goal is to use Python to load and "wire" modules, with additional configuration.  This allows:
  • First module, will be GPS.  All of the parsing and configuration of the GPS will be written in python and calls into the Flight controller software.  Now, different GPS modules can be added using python. 

Saturday, October 15, 2016

LinuxFlight connecting to CleanFlight Configurator

Just finished updating github LinuxFlight.  CleanFlight Configurator, is not able to connect and start sending MSP packets; but something is hanging up in getting data messages.  Work on that next week.

How to build LinuxFlight (Linux only):
  • Need to build boost C++ libraries and install them 
  • make
  • ./PC
  • open another terminal 
    •  socat -d -d pty,raw,echo=0 tcp:localhost:56000
    • This will create a pty, the output from socat show which pty to connect configurator
      • i.e /dev/pts/9

There is a lot to do to improve the IPC speed, i.e not to copy std::vector, but to use std::move, so there is no copy.  Also, move the IPC queue struct from std::queue to boost::lockfree::queue with a semaphore to wake up the FC thread.  

The heart of the IPC is a send-reply via std::function<void (void)> type function.  So, how can a void function be able to process arguments and do process callbacks?  
  • Use std::bind, this arguments.   For example, in  mspSerialTCPPort.h,  function: handle_read creates a std::function<void (void)> 
                  msgPost_t _msg;
                  mspCallback_t _callback = std::bind(&mspSerialTCPClient::postHandleWrite,                                                                                            shared_from_this(),                                                                                                                                std::placeholders::_1);
                      _msg.m_in = std::bind(&callToMSPFromTCP, _pkt, _callback);

    So, msgPost_t is created with a function callback.  The std::bind takes the packet and places it in one of the arguments.  Along with a call back function.  It is important to use shared_ptr, so the class does not disappear until all callbacks are completed. So, when the function is invoked the arguments are unpacked and the MSP function is call.

    This is a simple way, to keep a callback IPC API and allow any type of arguments.  Yes, it is confusing, but look at the code, run it and debug it. 

    So, the current design is to move most of the I/O from the flight controller main thread, this way I2C. serial, etc are processed out side of the thread.  All data will be posted to the FC thread, this way, this should minimize jitter.  

    Saturday, October 8, 2016

    LinuxFlight github

    After several rounds of code porting and trying to keep the code compatible with a micro-controller decided to just move to Linux only port.

    The goal is to keep the main Flight-Controller loop reads accelerometer, and gyro, and move the reset of the I/O to read threads.  This way keeps the main loop on time.

    Also, the Neo Air is out, so, that will be the FC board with I/O processor.

    • ARM Linux board
      • GPS (Serial)
      • MS5611  (I2C)
      • MPU9250 (SPI)
      • I/O processor (USB)
      • MSP via TCP/IP
      • RX (Need to validate and test serial Ports are able to handle iBUS, or sBUS)
    • I/O processor
      • RX (PWM or Serial)
      • Telemetry
      • PWM out (motor control)
    So, go, but making progress.. 

    Saturday, September 24, 2016

    OrangePI PC with 4.8.x using buildroot

    Finally got some time to get back to testing OrangePI-PC as a Flight Controller board.  The OrangePI-PC offers several advantages over the Pi Zero:
    • Multiple serial ports (3) 
    • Multiple USB ports (each have port has its own controller not a Hub)
    • Camera (Still working on that)
    • Cost is low around $12

    I'm using standard buildroot with the orangePI defconfig, but using a different Linux kernel which has several patches for Ethernet, USB (slave), and thermal control (Which is big).   Using orange-pi-4.8 branch.

    Also made a couple of code changes:
    • spidev 
    static const struct of_device_id spidev_dt_ids[] = {
        { .compatible = "rohm,dh2228fv" },
        { .compatible = "lineartechnology,ltc2488" },
            { .compatible = "spidev" },

    • device tree: 
      • sun8i-h3-orangepi-pc.dts:
            spi0_pins_a: spi0@0 {
                    allwinner,pins = "PC0", "PC1", "PC2";
                    allwinner,function = "spi0";
                    allwinner,drive = <SUN4I_PINCTRL_10_MA>;
                    allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;

        spi0_cs0_pins_a: spi0_cs0@0 {
                    allwinner,pins = "PC3";
                    allwinner,function = "spi0";
                    allwinner,drive = <SUN4I_PINCTRL_10_MA>;
                    allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
            i2c0_pins_a: i2c0@0 {
            allwinner,pins = "PA11", "PA12";
                allwinner,function = "i2c0";
                allwinner,drive = <SUN4I_PINCTRL_10_MA>;
                allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;

    &spi0 {
        pinctrl-names = "default";
        pinctrl-0 = <&spi0_pins_a>, <&spi0_cs0_pins_a>;
        status = "okay";
            spidev0: spidev@0 {
                    #address-cells = <1>;
                #size-cells = <0>;
                compatible = "spidev";
            reg = <0>;
            spi-max-frequency = <50000000>;

    &i2c0 {
        pinctrl-names = "default";
        pinctrl-0 = <&i2c0_pins_a>;
        status = "okay";

        • sun8i-h3.dtsi
            spi0: spi@01c68000 {
                compatible = "allwinner,sun6i-a31-spi";
                reg = <0x01c68000 0x1000>;
                interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&ccu CLK_BUS_SPI0>, <&ccu CLK_SPI0>;
                clock-names= "ahb", "mod";
                resets = <&ccu RST_BUS_SPI0>;
                dmas = <&dma 23>, <&dma 23>;
                dma-names = "rx", "tx";
                status = "disabled";
                #address-cells = <1>;
                #size-cells = <0>;
            i2c0: i2c@01c2ac00 {
                compatible = "allwinner,sun6i-a31-i2c";
                reg = <0x01c2ac00 0x400>;
                interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&ccu CLK_BUS_I2C0>;
                resets = <&ccu  RST_BUS_I2C0>;
                status = "disabled";
                #address-cells = <1>;
    #size-cells = <0>;
    So, this adds a SPI interface and another I2C.

    Next is to do some testing with SPI and I2C.

    Also, still adding code to CleanFlight port to Linux.   Please post if you have any questions.