This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TMS320F28P559SG-Q1: Deploying Tflite on NPU

Part Number: TMS320F28P559SG-Q1

Hi Experts,

I am trying to explore TMS320F28P559 launch pad, specifically its NPU. I see, the Edge AI model composer is being used to generate the files from the data that eventually is integrated with Code Composer Studio Project.

I would like to know if we can use .tflite file that is modelled and generated using Python tensorflow.

If it can be cone, may I know the step by step procedure how to realise that on Python Tesnorflow? Furthermore, please let me know the tools that are used to achieve this.

Cheers,

Rajesh.

  • Hi Rajesh

    Let me talk to compiler team if .tflite file can be used. I will respond you as soon as I get the answer.

    Thank you 

    Amir Hussain

  • Hi Rajesh


    TI compiler only supports PyTorch/ONNX flow for TI-NPU.

    Thank you 

    Amir Hussain

  • PyTorch

    Thanks for the reply Hussain!


    Would you please share the documentation that explains step by step procedure- integrating the Pytorch/ONNX with TMS320F8P55's NPU.

    Cheers,

    Rajesh.

  • Hi Rajesh

    The documentation is available in digital power SDK. You can download the latest SDK using link below
    https://www.ti.com/tool/C2000WARE-DIGITALPOWER-SDK#downloads
    Once downloaded, Please find the document and firmware in the below directory

    C:\ti\c2000ware-digital-power-sdk\solutions\tida_010955

    You can also find the detail of board below

    https://www.ti.com/tool/TIDA-010955

    Thank you 

    Amir Hussain

  • Dear Amir,

    I have gone through the example and documentation as well. It explains how to verify the project using Edge AI and I think I have understood it.

    Coming to my question, I am trying to realize a simple problem using F28P55.

    Objective:

    1. NPU does normal arc and abnormal arc detection

    2. CPU interrupt management including NPU

    The objectives other than NPU related have been achieved, that is  CPU timer, ADC, PWM etc. Re the NPU, some part of the NPU part has been done, for instance, generating artifacts using EdgeAI and copying them into the project. The next important part- integrating this artifacts into the project and eventually onto NPU has not been done successfully and I believe this part is not clearly explained in the documentation which might not be the objective of the project u shared.

    It would be really helpful if you could explain more clearly how to initialize NPU and how to  transfer the data into the NPU. 

    The project that has been shared by the TI is a bit overwhelming as it consists too many files like fft, hal, model selection, detection, data  capture etc. and there is no description about these in the manual. I can understand these files are relevant to your objective, however my objective is too simple- transfering 1D data to NPU and waiting for NPU interrupt!

    I am sharing my project6471.pwm_p55.zip  and I have copied the artifacts that were generated by the EdgeAI.

    I tried to call the tvmgen_default_run() function on main.c source file after defining and including

    #include "tvmgen_default.h"
    
    struct tvmgen_default_inputs inputs;
    struct tvmgen_default_outputs outputs;

    Then tried sending data to the NPU using 

            for(m = 0; m < 256;m++)
            {
                input_buffer[m] = 2;
                inputs.onnx__Add_0 = input_buffer;
            }
    
            tvmgen_default_run(&inputs, &outputs);


    Program built successfully, however with this line- tvmgen_default_run(&inputs, &outputs), compiler threw insufficient memory error, then following lines have been added to allocate memory to the NPU and that error has been dissapeared  :)
                         .rodata.tvm     : > FLASH_BANK3  // Place read-only TVM data in FLASH
                         .bss.noinit.tvm : > RAMGS3, type=NOINIT  // Place uninitialized TVM BSS in SRAM (NOINIT prevents zero-init overhead)

    However, few errors still persists
    Error1:
    unresolved symbol Interrupt_disable, first referenced in ../artifacts/mod.a<tinie_c28.obj> pwm_p55 C/C++ Problem
    Error2:

    Description Resource Path Location Type
    unresolved symbol Interrupt_enable, first referenced in ../artifacts/mod.a<tinie_c28.obj> pwm_p55 C/C++ Problem

    Even, these errors were resolved, I don't know if the NPU would be called and successfully meet the objective.

    please explain or share precise documentation that explains how to initialize and transfer the data into NPU.

    Furthermore, I see TI_NPU_init() function in the files of artifacts but it doesn't direct to any function.

    I hope you understand my question.

    Please help me to get over this!

    Cheers,

    Rajesh.

  • Hi Rajesh

    I understand that you want to transfering 1D data to NPU and wait for NPU interrupt!

    The current project does not use NPU interrupt. Also, we do not intend for customer to program the NPU directly, but use our Edge AI tools https://dev.ti.com/edgeaistudio/ to model/deploy the inference engine onto the NPU on the C2000 device.

    Thank you 

    Amir Hussain

  • Dear Amir!
     
    As I already mentioned in my previous messages (generating artifacts using EdgeAI), stating clearly that I have used Edge AI to generate artifacts to program NPU. So, I believe, providing the link for Edge AI link again is of no help to me. The model generated by the Edge AI were copied to the project as per the instructions in the documentation provided.

    My question or my intention is not to program NPU directly and all I want is to invoke NPU with the command  tvmgen_default_run(&inputs, &outputs); as the file-tvmgen_defaults says so!

    The command  tvmgen_default_run is clearly mentioned in the tvmgen_defaults.h file- generated by the Edge AI which is shown below for your reference

    /*****************************************************************************/
    /* Copyright (c) 2025 Texas Instruments Incorporated                         */
    /* http://www.ti.com/                                                        */
    /*                                                                           */
    /*  Redistribution and  use in source  and binary forms, with  or without    */
    /*  modification,  are permitted provided  that the  following conditions    */
    /*  are met:                                                                 */
    /*                                                                           */
    /*     Redistributions  of source  code must  retain the  above copyright    */
    /*     notice, this list of conditions and the following disclaimer.         */
    /*                                                                           */
    /*     Redistributions in binary form  must reproduce the above copyright    */
    /*     notice, this  list of conditions  and the following  disclaimer in    */
    /*     the  documentation  and/or   other  materials  provided  with  the    */
    /*     distribution.                                                         */
    /*                                                                           */
    /*     Neither the  name of Texas Instruments Incorporated  nor the names    */
    /*     of its  contributors may  be used to  endorse or  promote products    */
    /*     derived  from   this  software  without   specific  prior  written    */
    /*     permission.                                                           */
    /*                                                                           */
    /*  THIS SOFTWARE  IS PROVIDED BY THE COPYRIGHT  HOLDERS AND CONTRIBUTORS    */
    /*  "AS IS"  AND ANY  EXPRESS OR IMPLIED  WARRANTIES, INCLUDING,  BUT NOT    */
    /*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR    */
    /*  A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT    */
    /*  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
    /*  SPECIAL,  EXEMPLARY,  OR CONSEQUENTIAL  DAMAGES  (INCLUDING, BUT  NOT    */
    /*  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,    */
    /*  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY    */
    /*  THEORY OF  LIABILITY, WHETHER IN CONTRACT, STRICT  LIABILITY, OR TORT    */
    /*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE    */
    /*  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.     */
    /*                                                                           */
    /*****************************************************************************/
    /*
     * Generated by TI MCU NNC 2.1.0
     * cross-compiler: C:\ti\ti_cgt_c2000_22.6.2.LTS\bin\cl2000
     * cross-compiler-opts: --abi=eabi -O3 --opt_for_speed=5 --c99 -v28 -ml -mt --gen_func_subsections --float_support=fpu32 -IC:\ti\ti_cgt_c2000_22.6.2.LTS\include -IC:\ti\C2000Ware_5_04_00_00\driverlib\f28p55x\driverlib -IC:\ti\C2000Ware_5_04_00_00\device_support\f28p55x\common\include -I. -Iartifacts --obj_directory=.
     * input model file: C:\Users\rks68146\EdgeAIRoot\8d7ddb4dd46ce1e8\projects\7382ba70\train\20260211-121643\output\training_quantization\model.onnx
     * module name: default
     */
    
    #ifndef TVMGEN_DEFAULT_H_
    #define TVMGEN_DEFAULT_H_
    #include <stdint.h>
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    /* Symbol defined when running model on TI NPU hardware accelerator */
    #define TVMGEN_DEFAULT_TI_NPU
    #ifdef TVMGEN_DEFAULT_TI_NPU_SOFT
    	#error Conflicting definition for where model should run.
    #endif
    
    /* The generated model library expects the following inputs/outputs:
     * Inputs:
     *    Tensor[(1, 1, 256, 1), int8]
     * Outputs:
     *    Tensor[(1, 2), int8]
     */
    
    /* Input feature normalization parameters:
     *   input_int = clip(((int32_t)((input_float + bias) * scale)) >> shift, min, max)
     *   where (min, max) = (-128, 127) if int8 type, (0, 255) if uint8 type
     */
    #define TVMGEN_DEFAULT_BIAS_LEN 1
    #define TVMGEN_DEFAULT_SCALE_LEN 1
    #define TVMGEN_DEFAULT_SHIFT_LEN 1
    extern const float tvmgen_default_bias_data[] __attribute__((weak)) = {8.099171};
    extern const int32_t tvmgen_default_scale_data[] __attribute__((weak)) = {154};
    extern const int32_t tvmgen_default_shift_data[] __attribute__((weak)) = {7};
    
    
    /* TI NPU hardware accelerator initialization */
    extern void TI_NPU_init();
    
    /* Flag for model execution completion on TI NPU hardware accelerator */
    extern volatile int32_t tvmgen_default_finished;
    
    
    /*!
     * \brief Input tensor pointers for TVM module "default" 
     */
    struct tvmgen_default_inputs {
      void* onnx__Add_0;
    };
    
    /*!
     * \brief Output tensor pointers for TVM module "default" 
     */
    struct tvmgen_default_outputs {
      void* output;
    };
    
    /*!
     * \brief entrypoint function for TVM module "default"
     * \param inputs Input tensors for the module 
     * \param outputs Output tensors for the module 
     */
    int32_t tvmgen_default_run(
      struct tvmgen_default_inputs* inputs,
      struct tvmgen_default_outputs* outputs
    );
    
    #ifdef __cplusplus
    }
    #endif
    
    #endif // TVMGEN_DEFAULT_H_
    

    There are 3 important sections in the above code 1. Initialization, 2. Inputs and Outputs 3.Invoking NPU 4. wait for finish. 

    1.Initialization: 

    TI_NPU_init();

    2.Inputs and Outputs: 

    struct tvmgen_default_inputs {
    void* onnx__Add_0;
    };
    struct tvmgen_default_outputs {
    void* output;
    };

    3.Invoking NPU
    tvmgen_default_run(
    struct tvmgen_default_inputs* inputs,
    struct tvmgen_default_outputs* outputs
    );

    4.wait for finish
    tvmgen_default_finished;

    Also in the  *TMS320F28P55x Real-Time Microcontrollers Technical Reference Manual (Rev. C), on page 108, the table clearly shows INT 9.16 is an NPU interrupt and it can be of course enabled using Vector Table registers. However, NPU does not apear in the PieVectTable structure. So, I don't understand why cant we invoke NPU by calling the Edge AI generated function and wait for the CPU's NPU interrupt!  I think   is the right person to comment on this Wink

    Let me know if my understanding is wrong and explain where I need to correct the program to make it work.

    Cheers,

    Rajesh.

  • Hi Rajesh

    Please allow some time to find the best person to respond to your questions.

    Thank you 

    Amir Hussain

  • Hi Rajesh,

    Your understanding is correct. If you have specified that you want to compile the model artifacts to NPU during the compilation stage using either training tools, the "TI_NPU_init()" function handles the NPU interrupt initialization and completion of the computation on NPU is indicated by the flag "tvmgen_default_finished".

    Thanks,

    Jiaxin

  • Hi Jiaxin!
    Thanks for the response. 

    So, checking for 'tvmgen_default_finished'  HIGH/LOW appears to me "if(tvmgen_default_finished ==1/0)". If this is the case, isn't it keeping CPU idle and waiting for the flag? This defeats the purpose of the interrupts! 

    Cheers,

    Rajesh.

  • Hi Rajesh,

    The CPU is freed for other tasks once you invoke NPU. The flag just mark the completion of NPU. Similar working scheme as CLA.

    Thanks,

    Jiaxin

  • Dear Jiaxin

    I understand that NPU is an independent hardware like any other periphreal, however I dont see the ISR for NPU similar to CLA in the interrupt ISR vector structures.

    Cheers,

    Rajesh.

  • Hi Rajesh,

    I got your point. The NPU is a closed IP and user do not have the access to that level. The low-end logic is handled automatically by the hardware itself.

    Thanks,

    Jiaxin

  • Dear Jiaxin,
    Got It! I don't have the access to the NPU's interrupt.

    But, on Page 108 of TMS320F28P55x Real-Time Microcontrollers Technical Reference Manual (Rev. C) the interrupt table explicitly shows NPU at INT9.16. I dont understand why it is shown in the table, If I don't have the access to it.  Just asking out of curiosity.

    Cheers,

    Rajesh.

  • Dear Jiaxin!

    Any update?

  • Hi Rajesh,

    Sorry for the late response. Yes, you are right. I will discuss with the team and we may have it removed in the following revisions.

    Thanks,

    Jiaxin