Controlling binary mode interfaces for existing software

Any thoughts on how to handle different binary modes where we don’t control the protocol/software? Not for stuff written for the bus pirate, I mean other projects ported into binary mode.

It’s a cute parlor trick to make a bunch of apps work in a single interface, but the code ends up absolutely filthy and unmaintainable.

Some scenarios:

serial port access

For example GusmanB logic analyzer and pico_sdk_pio logic analyzer. I’ve ported both already and they work, but getting them to play nice on the same serial port is not happening. In this case I think a new menu option under the c config menu to set the binary mode interface:

  1. Bus Pirate (compatible) mode
  2. Logic Analyzer 1
  3. Other device
  4. etc

This makes my life a lot easier for serial stuff.

Other USB access

Some devices, like the three JTAG interfaces I’m porting, are USB bulk or USB HID interfaces (not serial port/CDC). Further, most are identified by software that looks for their USB VID/PID.

We can add a USB bulk and HID interface, but it will use our existing USB VID/PID. That means submitting patches in most instances.

As far as I’ve seen, it’s not practical to make a single firmware change USB descriptors (USB VID/PID, interface types). Maybe it could be done with different compiles re-aligned in flash with a jump instruction?

end points

We have 16 USB endpoints.
1 Config
6 (3*2) 2 USB CDC serial
2 USB MSD disk

We have 7 remaining.

Bus Pirate framework

A possible solution is to make our own compiles of other firmwares within a small Bus Pirate framework to handle the LCD, buffers, power supply, etc.

Then the next step is to make compiling and releases efficient. I did some reading on CMake, and it doesn’t seem geared towards multiple builds in the same CMake file. I need to look into this more, it would be really nice to build multiple releases at once and make automation much easier.

1 Like

Cmake checks its configuration and prepares the precompilation files

cd build
cmake …

If you then want to manage specific compilations you could do it with make. Some examples:

  1. make sigrok
  2. make jtagxxx
  3. make lcd

or provide something more general, as for the examples present on the Rasberry Pico 2040 SDK which can be compiled individually or all together

cd build
cmake …
make

At the end of the compilation inside the bin folder there will be several folders each with the specific firmware.

1 Like

thats what im looking for, I’ll try it out tomorrow. thank you.

Hi IAN

I have my PC turned on with personal notes on Raspberry Pi Pico.
In the official documentation they recommend the entire SDK which includes the example package to start working with the RP2040.
I’m a Linux user so I have this approach but I’m sure it’s identical with Windows too.

  1. Download Examples repository

     mkdir pico
     pico cd
     git clone -b master https://github.com/raspberrypi/pico-examples.git
    
     cd pico-examples
     git pull
     git submodule update --init
    
  2. Pre-Compilation

     mkdir build
     cd build
     cmake ..
    

At the end of this operation approximately 30 new folders and some files will be created inside the build folder.

Now we have 2 compilation possibilities

A) Total compilation: This will take a long time but it will compile all the projects inside the Build folder

    make

B) Selective Compilation: This will take little and will generate the binary only inside the Blink folder

   make blink

I hope this is what you wanted.

As I recall the pico examples have top level cmakes and sub cmakes in the various project folders. Maybe thats the right way to do it and I just dont understand how to structure the project that way.

What id like to do is have multiple compiles from the same code but with different combinations of files and a few defines. Maybe i need to make the main bus pirate stuff a library like the pico sdk is structured and build the sub projects using that “framework”. Hum.

# Generated Cmake Pico project file

cmake_minimum_required(VERSION 3.13)

set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)

# initalize pico_sdk from installed location
# (note this can come from environment, CMake cache etc)
#set(PICO_SDK_PATH "C:/pico113/pico-sdk")

# Pull in Raspberry Pi Pico SDK (must be before project)
include(pico_sdk_import.cmake)

set(PICO_BOARD pico)

project(bus_pirate C CXX ASM) 

# Initialise the Raspberry Pi Pico SDK
pico_sdk_init()  

#add_compile_definitions(BP_FIRMWARE_HASH=${BP_FIRMWARE_HASH})
#add_compile_definitions(BP5_REV=8) 

# Add executable. Default name is the project name, version 0.1

set(bp5_common 
        pirate.c pirate.h commands.h commands.c 
        ui/ui_lcd.c ui/ui_lcd.h rgb.c rgb.h bio.h bio.c
        msc_disk.c usb_descriptors.c  
        shift.h shift.c psu.h psu.c amux.h amux.c buttons.c buttons.h
        system_config.h system_config.c modes.c modes.h auxpinfunc.h auxpinfunc.c
        pwm.c pwm.h freq.c freq.h adc.c adc.h pullups.c pullups.h helpers.h helpers.c
        mode/dummy1.c mode/dummy1.h mode/hiz.h mode/hiz.c mode/hwspi.c mode/hwspi.h
        mode/usart.h mode/usart.c mode/hwi2c.c mode/hwi2c.h mode/hwled.c mode/hwled.h
        ui/ui_cmdln.c ui/ui_cmdln.h ui/ui_process.h ui/ui_process.c
        mode/hw1wire.h mode/hw1wire.c mode/onewire.h mode/onewire.c
        ui/ui_flags.h
        debug.c debug.h
        ui/ui_parse.c ui/ui_parse.h ui/ui_prompt.h ui/ui_prompt.c  ui/ui_mode.c ui/ui_mode.h
        ui/ui_info.h ui/ui_info.c ui/ui_format.c ui/ui_format.c ui/ui_init.c ui/ui_init.h
        ui/ui_const.h ui/ui_const.c ui/ui_config.h ui/ui_config.c 
        translation/base.h translation/base.c translation/en-us.h translation/zh-cn.h
        queue.c queue.h 
        usb_tx.c usb_tx.h usb_rx.c usb_rx.h
        mcu/rp2040.h mcu/rp2040.c
        printf-4.0.0/printf.c printf-4.0.0/printf.h
        font/font.h font/hunter-14pt-19h15w.h font/hunter-12pt-16h13w.h font/hunter-20pt-21h21w.h font/hunter-23pt-24h24w.h font/background.h font/background_image_v4.h
        fatfs/diskio.c fatfs/diskio.h fatfs/ff.c fatfs/ff.h fatfs/ffconf.h fatfs/ffsystem.c fatfs/ffunicode.c 
        pio_i2c.c pio_i2c.h
        storage.h storage.c
        ui/ui_term.c ui/ui_term.h  ui/ui_statusbar.c ui/ui_statusbar.h
        system_monitor.h system_monitor.c
        mjson/mjson.h mjson/mjson.c 
        postprocess.c postprocess.h syntax.h syntax.c  syntax_struct.h
        dump.c dump.h opt_args.h command_attributes.h bytecode.h
        lib/minmea/minmea.h lib/minmea/minmea.c lib/minmea/gps.h lib/minmea/gps.c lib/ms5611/ms5611.c lib/ms5611/ms5611.h
        lib/tsl2561/driver_tsl2561.c  lib/tsl2561/driver_tsl2561.h
        mode/binio.c mode/binio.h
        #mem buffer for shared malloc
        mem.c mem.h
        )

add_executable(bus_pirate5_rev8
        ${bp5_common}
        platform/bpi-rev8.h platform/bpi-rev8.c 
        #tf card access control
        fatfs/tf_card.c fatfs/tf_card.h
        )

target_compile_definitions(bus_pirate5_rev8 PUBLIC BP5_REV=8)

add_executable(bus_pirate5_rev10
        ${bp5_common}
        platform/bpi-rev10.h platform/bpi-rev10.c 
        #nand flash management and dhara
        dhara/bytes.h dhara/error.c dhara/error.h dhara/journal.c dhara/journal.h dhara/map.c dhara/map.h dhara/nand.c dhara/nand.h
        nand/nand.c nand/nand.h nand/nand_ftl_diskio.c nand/nand_ftl_diskio.h nand/spi.c nand/spi.h nand/spi_nand.c nand/spi_nand.h 
        nand/sys_time.c nand/sys_time.h
        )
target_compile_definitions(bus_pirate5_rev10 PUBLIC BP5_REV=10)

set(stdlibs
        pico_stdlib
        hardware_spi
        hardware_i2c
        hardware_dma
        hardware_pio
        hardware_interp
        hardware_timer
        hardware_watchdog
        hardware_clocks
        hardware_adc
        hardware_uart
        pico_multicore
        pico_unique_id
        pico_bootrom 
        hardware_pwm
        tinyusb_device
        tinyusb_board
        )        

set(revisions
        bus_pirate5_rev8  
        bus_pirate5_rev10
        )

foreach(revision ${revisions})
        pico_generate_pio_header(${revision} ${CMAKE_CURRENT_LIST_DIR}/i2c.pio)
        pico_generate_pio_header(${revision} ${CMAKE_CURRENT_LIST_DIR}/ws2812.pio)
        pico_generate_pio_header(${revision} ${CMAKE_CURRENT_LIST_DIR}/apa102.pio)
        pico_generate_pio_header(${revision} ${CMAKE_CURRENT_LIST_DIR}/mode/onewire.pio)

        pico_set_program_name(${revision} ${revision})
        pico_set_program_version(${revision} "0.1.0")
        pico_set_program_description(${revision} "Bus Pirate 5 Firmware for RP2040")

        pico_enable_stdio_uart(${revision} 0)
        pico_enable_stdio_usb(${revision} 0)

        # Add the standard library to the build
        target_link_libraries(${revision} ${stdlibs} )
        target_include_directories(${revision} PUBLIC ${CMAKE_CURRENT_LIST_DIR} . )
        pico_add_extra_outputs(${revision})
endforeach()

string(APPEND CMAKE_EXE_LINKER_FLAGS "-Wl,--print-memory-usage")

Figured this bit out:

  • define one main project
  • include common files into a variable with set()
  • create rev8 and rev10 targets, include common and specific files
  • loop through targets list and apply common settings and libraries

Yeah! First step towards managing sub-projects.