Beaglebone FPP and P5 panels with FM6126 controller (solution)

bepa

New elf
Joined
Sep 19, 2021
Messages
14
Hi everyone!

After buying some P5 panels I really had issues getting them to work.
My friend Falk found out they were using the FM6126A driver, which need a initialization sequence. First tries with a RPI and using the RPI-RGB-LED-Matrix library (https://github.com/hzeller/rpi-rgb-led-matrix) worked, so we moved on to FPP for RPI.
It seems that the RPI FPP panel output is based on this lib and it was possible to use the panels adding
Code:
options.panel_type = "FM6126A";
to the RGBMatrix.cpp and recompile FPP. But it is awful slow even with 2 P5 16x32 panels. So we moved on a Beaglebone.

Tldr:
For using these panels, add the init function (based on the lib from hzeller) to BBBMatrix.cpp:
Code:
bool BBBMatrix::InitSequenceFM6126( Json::Value& root )
{
    int columns = m_height > m_width ? m_height : m_width;
    std::vector<std::string> ctrlPinNames = { "oe", "latch", "clock", "sel0", "sel1", "sel2", "sel3" };
    std::vector<std::string> panelPinNames = { "r1", "g1", "b1", "r2", "g2", "b2" };
    
    std::vector<const PinCapabilities*> ctrlPins;
    std::vector<const PinCapabilities*> panelPins;
    
    // init all pins
    for( auto& ctype : ctrlPinNames )
    {
        std::string pinName = root["controls"][ctype]["pin"].asString();
        const PinCapabilities* pin = PinCapabilities::getPinByName( pinName ).ptr();
        
        pin->configPin( "gpio" );
        ctrlPins.push_back( pin );
    }
    const PinCapabilities* pin_oe       = ctrlPins[0];
    const PinCapabilities* pin_latch    = ctrlPins[1];
    const PinCapabilities* pin_clock    = ctrlPins[2];
    const PinCapabilities* pin_sel0     = ctrlPins[3];
    const PinCapabilities* pin_sel1     = ctrlPins[4];
    const PinCapabilities* pin_sel2     = ctrlPins[5];
    const PinCapabilities* pin_sel3     = ctrlPins[6];
    for( auto& ctype : panelPinNames )
    {
        std::string pinName = root["outputs"][0]["pins"][ctype].asString();
        const PinCapabilities* pin = PinCapabilities::getPinByName( pinName ).ptr();
        
        pin->configPin( "gpio" );
        pin->setValue( false );
        panelPins.push_back( pin );
    }
        
    // first set all pins to default value:
    pin_oe->setValue( false );
    pin_latch->setValue( false );
    pin_clock->setValue( false );
    pin_sel0->setValue( true );
    pin_sel1->setValue( true );
    pin_sel2->setValue( true );
    pin_sel3->setValue( true );
    
    // wait a little
    std::this_thread::sleep_for( std::chrono::microseconds( 800 ) );
    
    pin_oe->setValue( true );
    std::this_thread::sleep_for( std::chrono::microseconds( 80 ) );
    
    static const char* init_b12 = "0111111111111111";  // full bright
    static const char* init_b13 = "0000000001000000";  // panel on.
    
    for( int i = 0; i < columns; ++i )
    {
        bool value = init_b12[i % 16] == '0' ? false : true;
        if (i > columns - 12)
        {
            pin_latch->setValue( true );
        }
        else
        {
            pin_latch->setValue( false );
        }
        for( auto& pin : panelPins )
        {
            pin->setValue( value );
        }
        pin_clock->setValue( true );
        pin_clock->setValue( false );
    }
    pin_latch->setValue( false );
    
    for( int i = 0; i < columns; ++i )
    {
        bool value = init_b13[i % 16] == '0' ? false : true;
        if (i > columns - 13)
        {
            pin_latch->setValue( true );
        }
        else
        {
            pin_latch->setValue( false );
        }
        for( auto& pin : panelPins )
        {
            pin->setValue( value );
        }
        pin_clock->setValue( true );
        pin_clock->setValue( false );
    }
    pin_latch->setValue( false );
    
    std::this_thread::sleep_for( std::chrono::microseconds( 800 ) );
    
    // de-init all pins
    for( auto& pin : ctrlPins )
    {
        pin->configPin( "default", false );
    }   
    for( auto& pin : panelPins )
    {
        pin->configPin( "default", false );
    }
    
    return true;
}

add to the private declaration of BBBMatrix.h:
Code:
bool InitSequenceFM6126( Json::Value& root );

Add before
Code:
 configureControlPin("latch", root, outputFile);
in BBBMatrix.cpp:
Code:
InitSequenceFM6126( root );

Now recompile FPP and thats it. Every time FPP is started / restarted, the Init is called and the panels are working.

Greets
Bepa
 

Skymaster

Crazy elf
Global moderator
Generous elf
Joined
Dec 19, 2021
Messages
1,094
Location
Western Sydney
Well done!
Might I suggest (if you havent already) submitting a pull request to the FPP GitHub repository, that way it can be incorporated into the main-line code for everyone to use; along with any UI changes that are needed to make them selectable?
 

bepa

New elf
Joined
Sep 19, 2021
Messages
14
Thank you :)

As I find out how to enable this with all 8 and not only output 1 of the Octoscroller, I will submit a full request.
 
Last edited:
Top