Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
Collapse
Brand Logo

ModalAI Forum

  1. ModalAI Support Forum
  2. Software Development
  3. Baremetal peripheral interaction via the SDSP

Baremetal peripheral interaction via the SDSP

Scheduled Pinned Locked Moved Software Development
9 Posts 4 Posters 1.3k Views 3 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • Alexandre PabouctsidisA Offline
    Alexandre PabouctsidisA Offline
    Alexandre Pabouctsidis
    wrote on last edited by
    #1

    Hello,

    In order to get a better grasp of the voxl2 module, i'm trying to develop a very basic test code from scratch, starting from the qualcom demo code + inspiration from the PX4 cmake, etc.

    I've reached the stage where I can build the ARM app + DSP lib, load it on the DSP and run it.

    I'm now trying to interact with the SPI+USART+GPIO(?) peripherals. I've spent countless hours digging through the px4 code base, dspal, etc. but I'm having trouble finding the absolute low level code which actually interacts with the peripheral/HW.

    Could someone show me where in the code base is the actual implementation of the SPI or USART transfer (and not just one of the many, many hardware abstractions 😛 )

    After following the chain, the lowest i got is that the spi/usart functions are passed to the _muorb__slpi module, which are initialized through "px4muorb_orb_initialize", which should be called by the apps processor? but i can't find any instance of where it's done. etc.

    The first goal is to read the whoami register of the icm, without any of the HALs (dspal, etc.)

    Thanks for the help!
    Alex

    Eric KatzfeyE 1 Reply Last reply
    0
    • Chad SweetC Offline
      Chad SweetC Offline
      Chad Sweet
      ModalAI Team
      wrote on last edited by Chad Sweet
      #2

      Hi Alexandre,

      Impressive start to your development!

      We will find that pointer and let you know where the SPI, UART are called.

      1 Reply Last reply
      0
      • Alexandre PabouctsidisA Alexandre Pabouctsidis

        Hello,

        In order to get a better grasp of the voxl2 module, i'm trying to develop a very basic test code from scratch, starting from the qualcom demo code + inspiration from the PX4 cmake, etc.

        I've reached the stage where I can build the ARM app + DSP lib, load it on the DSP and run it.

        I'm now trying to interact with the SPI+USART+GPIO(?) peripherals. I've spent countless hours digging through the px4 code base, dspal, etc. but I'm having trouble finding the absolute low level code which actually interacts with the peripheral/HW.

        Could someone show me where in the code base is the actual implementation of the SPI or USART transfer (and not just one of the many, many hardware abstractions 😛 )

        After following the chain, the lowest i got is that the spi/usart functions are passed to the _muorb__slpi module, which are initialized through "px4muorb_orb_initialize", which should be called by the apps processor? but i can't find any instance of where it's done. etc.

        The first goal is to read the whoami register of the icm, without any of the HALs (dspal, etc.)

        Thanks for the help!
        Alex

        Eric KatzfeyE Offline
        Eric KatzfeyE Offline
        Eric Katzfey
        ModalAI Team
        wrote on last edited by
        #3

        @Alexandre-Pabouctsidis The DSP runs an OS called QURT. This OS provides IO services to applications running on it so that they can access I2C, SPI, UART, and interrupts. Unfortunately, all of that code is Qualcomm Proprietary and so we have had to abstract it into the function calls that you see bound to PX4 in muorb. Everything below that is built into our DSP image and cannot be shared to non-QC licensees.

        1 Reply Last reply
        0
        • Chad SweetC Offline
          Chad SweetC Offline
          Chad Sweet
          ModalAI Team
          wrote on last edited by Chad Sweet
          #4

          @Alexandre-Pabouctsidis this might be helpful for what you are trying to do:

          -> ICM42688P whoami register read code
          --> ICM42688P::RegisterRead
          ---> SPI::transfer
          ----> light-weight callback into DSP OS to perform _spi_transfer

          1 Reply Last reply
          0
          • Alexandre PabouctsidisA Offline
            Alexandre PabouctsidisA Offline
            Alexandre Pabouctsidis
            wrote on last edited by
            #5

            Thanks for responding. Is this proprietary code the Qualcom Hexagon SDK?

            I'm already building the DSP code with QuRT, but it's unclear how to do the system calls in order to interact with the devices.

            For example, i've tried this to blink a LED:

            int fd; 
            fd = open("/sys/class/gpio/gpio1182/value", O_WRONLY);
            if (fd == -1) {
                FARF(ALWAYS,"Unable to open /sys/class/gpio/gpio1182/value");
                qurt_thread_exit(QURT_EOK);
            }
            
            // Toggle LED 50 ms on, 50ms off, 100 times (10 seconds)
            
            for (int i = 0; i < 100; i++) {
                if (write(fd, "1", 1) != 1) {
                    FARF(ALWAYS,"Error writing to /sys/class/gpio/gpio1182/value");
                    qurt_thread_exit(QURT_EOK);
                }
                qurt_timer_sleep(50000);
            
                if (write(fd, "0", 1) != 1) {
                    FARF(ALWAYS,"Error writing to /sys/class/gpio/gpio1182/value");
                    qurt_thread_exit(QURT_EOK);
                }
                qurt_timer_sleep(50000);
            }
            
            close(fd);
            

            It builds and runs but nothing happens.

            as for the SPI, the hexagon system libraries don't contain headers for <sys/ioctrl.h>. I noticed in the PX4, the headers are defined in the DSPAL, and the implementation is in dspal_imp.c (https://gitlab.com/voxl-public/flight-core-px4/px4-firmware-ci/-/blob/v1.4.20-modalai-rb5-flight-beta/platforms/qurt/src/px4/common/dspal_impl.c), but are just stubs?

            Eric KatzfeyE 1 Reply Last reply
            0
            • Chad SweetC Offline
              Chad SweetC Offline
              Chad Sweet
              ModalAI Team
              wrote on last edited by
              #6

              I believe you should be accessing gpio1182 from the Linux CPU.

              The DSP portion has a partitioned subset of the I/O needed for flight control. The rest should be accessed from the CPU. The two are kept separate on purpose so the DSP can keep running if the CPU is bogged down or has an issue.

              1 Reply Last reply
              0
              • Alexandre PabouctsidisA Alexandre Pabouctsidis

                Thanks for responding. Is this proprietary code the Qualcom Hexagon SDK?

                I'm already building the DSP code with QuRT, but it's unclear how to do the system calls in order to interact with the devices.

                For example, i've tried this to blink a LED:

                int fd; 
                fd = open("/sys/class/gpio/gpio1182/value", O_WRONLY);
                if (fd == -1) {
                    FARF(ALWAYS,"Unable to open /sys/class/gpio/gpio1182/value");
                    qurt_thread_exit(QURT_EOK);
                }
                
                // Toggle LED 50 ms on, 50ms off, 100 times (10 seconds)
                
                for (int i = 0; i < 100; i++) {
                    if (write(fd, "1", 1) != 1) {
                        FARF(ALWAYS,"Error writing to /sys/class/gpio/gpio1182/value");
                        qurt_thread_exit(QURT_EOK);
                    }
                    qurt_timer_sleep(50000);
                
                    if (write(fd, "0", 1) != 1) {
                        FARF(ALWAYS,"Error writing to /sys/class/gpio/gpio1182/value");
                        qurt_thread_exit(QURT_EOK);
                    }
                    qurt_timer_sleep(50000);
                }
                
                close(fd);
                

                It builds and runs but nothing happens.

                as for the SPI, the hexagon system libraries don't contain headers for <sys/ioctrl.h>. I noticed in the PX4, the headers are defined in the DSPAL, and the implementation is in dspal_imp.c (https://gitlab.com/voxl-public/flight-core-px4/px4-firmware-ci/-/blob/v1.4.20-modalai-rb5-flight-beta/platforms/qurt/src/px4/common/dspal_impl.c), but are just stubs?

                Eric KatzfeyE Offline
                Eric KatzfeyE Offline
                Eric Katzfey
                ModalAI Team
                wrote on last edited by
                #7

                @Alexandre-Pabouctsidis The IO mapped to the DSP is not directly accessible using the SDK. It's at a lower layer that isn't exposed to "guest" applications.

                Alex PabouctsidisA 1 Reply Last reply
                0
                • Eric KatzfeyE Eric Katzfey

                  @Alexandre-Pabouctsidis The IO mapped to the DSP is not directly accessible using the SDK. It's at a lower layer that isn't exposed to "guest" applications.

                  Alex PabouctsidisA Offline
                  Alex PabouctsidisA Offline
                  Alex Pabouctsidis
                  wrote on last edited by Alex Pabouctsidis
                  #8

                  @Eric-Katzfey We've started working again on this project. I've now managed to create a bare bones setup for the apps + sdsp, which piggy packs on the fc_sensor lib.

                  something like this:

                  #include <stdio.h>
                  #include <fc_sensor.h>
                  
                  void receive_cb(const char *topic,
                                   const uint8_t *data,
                                   uint32_t length_in_bytes)
                  {
                  }
                  void advertise_cb(const char *topic)
                  {
                  }
                  void add_subscription_cb(const char *topic)
                  {
                  }
                  void remove_subscription_cb(const char *topic)
                  {
                  }
                  
                  int main(int argc, char **argv)
                  {
                      fc_callbacks func_ptr = {
                          .rx_callback = &receive_cb,
                          .ad_callback = &advertise_cb,
                          .sub_callback = &add_subscription_cb,
                          .remove_sub_callback = &remove_subscription_cb
                      };
                      fc_sensor_initialize(false, &func_ptr);
                      
                      printf("Hello, world!\n");
                      return 0;
                  }
                  

                  and

                  #include <main.h>
                  
                  #define FARF_LOW 1
                  #include <qurt.h>
                  #include <HAP_farf.h>
                  
                  static fc_func_ptrs g_func_ptrs;
                  // entry point - called by fc_sensor system
                  int px4muorb_orb_initialize(fc_func_ptrs *func_ptrs, int32_t clock_offset_us)
                  {
                      FARF(LOW, "SLPI Flya Main\n");
                      g_func_ptrs = *func_ptrs;
                  
                      return 0;
                  }
                  
                  int px4muorb_topic_advertised(const char *name)
                  {
                      return 0;
                  }
                  int px4muorb_add_subscriber(const char *name)
                  {
                      return 0;
                  }
                  int px4muorb_remove_subscriber(const char *name)
                  {
                      return 0;
                  }
                  int px4muorb_send_topic_data(const char *name, const uint8_t *data, int data_len_in_bytes)
                  {
                      return 0;
                  }
                  

                  And from there I could use the spi functions to read the IMU, so all good.

                  I was hoping to get some clarification on where does the the proprietary code that interacts with the HW sit? (i.e. sns_flight_controller_sensor). Is it part of libfc_sensor.so? or is it baked in the SLPI firmware found in /home/firmware/slpi.bxx?

                  Eric KatzfeyE 1 Reply Last reply
                  0
                  • Alex PabouctsidisA Alex Pabouctsidis

                    @Eric-Katzfey We've started working again on this project. I've now managed to create a bare bones setup for the apps + sdsp, which piggy packs on the fc_sensor lib.

                    something like this:

                    #include <stdio.h>
                    #include <fc_sensor.h>
                    
                    void receive_cb(const char *topic,
                                     const uint8_t *data,
                                     uint32_t length_in_bytes)
                    {
                    }
                    void advertise_cb(const char *topic)
                    {
                    }
                    void add_subscription_cb(const char *topic)
                    {
                    }
                    void remove_subscription_cb(const char *topic)
                    {
                    }
                    
                    int main(int argc, char **argv)
                    {
                        fc_callbacks func_ptr = {
                            .rx_callback = &receive_cb,
                            .ad_callback = &advertise_cb,
                            .sub_callback = &add_subscription_cb,
                            .remove_sub_callback = &remove_subscription_cb
                        };
                        fc_sensor_initialize(false, &func_ptr);
                        
                        printf("Hello, world!\n");
                        return 0;
                    }
                    

                    and

                    #include <main.h>
                    
                    #define FARF_LOW 1
                    #include <qurt.h>
                    #include <HAP_farf.h>
                    
                    static fc_func_ptrs g_func_ptrs;
                    // entry point - called by fc_sensor system
                    int px4muorb_orb_initialize(fc_func_ptrs *func_ptrs, int32_t clock_offset_us)
                    {
                        FARF(LOW, "SLPI Flya Main\n");
                        g_func_ptrs = *func_ptrs;
                    
                        return 0;
                    }
                    
                    int px4muorb_topic_advertised(const char *name)
                    {
                        return 0;
                    }
                    int px4muorb_add_subscriber(const char *name)
                    {
                        return 0;
                    }
                    int px4muorb_remove_subscriber(const char *name)
                    {
                        return 0;
                    }
                    int px4muorb_send_topic_data(const char *name, const uint8_t *data, int data_len_in_bytes)
                    {
                        return 0;
                    }
                    

                    And from there I could use the spi functions to read the IMU, so all good.

                    I was hoping to get some clarification on where does the the proprietary code that interacts with the HW sit? (i.e. sns_flight_controller_sensor). Is it part of libfc_sensor.so? or is it baked in the SLPI firmware found in /home/firmware/slpi.bxx?

                    Eric KatzfeyE Offline
                    Eric KatzfeyE Offline
                    Eric Katzfey
                    ModalAI Team
                    wrote on last edited by
                    #9

                    @Alex-Pabouctsidis Nice! That whole process and API will be cleaned up in the future but looks like you were able to figure it out. All of the actual I/O driver code is baked into the sensors DSP image. As Qualcomm licensees we have access to it (and build that image) but we cannot share it.

                    1 Reply Last reply
                    0

                    Hello! It looks like you're interested in this conversation, but you don't have an account yet.

                    Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.

                    With your input, this post could be even better 💗

                    Register Login
                    Reply
                    • Reply as topic
                    Log in to reply
                    • Oldest to Newest
                    • Newest to Oldest
                    • Most Votes


                    ModalAI
                    Categories Recent Tags ModalAI.com Docs
                    © 2026 ModalAI® · Accelerating autonomy for smaller, smarter, safer drones · Powered by NodeBB
                    • Login

                    • Login or register to search.
                    • First post
                      Last post
                    0
                    • Categories
                    • Recent
                    • Tags
                    • Popular
                    • Users
                    • Groups