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.

AM64x: Understanding interrupts

Other Parts Discussed in Thread: SYSCONFIG

Hello,
I am currently in the process of writing an abstraction for interrupts in our TI-RTOS based system using the MCU+-SDK for AM64x-Sitara.

My area of application for interrupts is currently GPIOs, but I would like to have a standard interface for interrupts.
My problem here is that I seem to be droning in different ID numbers, where I am not aware why I need all those.
I would be happy if you could correct me where I am wrong.

My current understanding
*******************************************************************************************
When I am on my home PC, I got a single processor with, I guess a single interrupt controller.
There are IRQ-Numbers, some are hardwired others can be set in the BIOS.
They tell the processor which peripheral is responsible for triggering an interrupt.

On the AM64x we have multiple MCUs with several cores. So we need to not only set the interrupt source peripheral but also the interrupt destination MCU/Core.
Some peripherals have a direct interrupt line to a destination MCU. Here we use simply a HwIP_Params struct to
set the interrupt number of the concerning interrupt controller for the peripheral that triggered the interrupt.
Where that interrupt number is hardwired and described in the TRM.(Interrupt ID, for CORE0 R5F in Table 9-80 for instance).
Then we set an ISR as callback in the HwIP_Params struct and well I guess the priority is something we can set as we wish
according to how our set of interrupts looks like.

Now there are certain peripherals like GPIOs that don't have each a hardwired interrupt line to the destination MCU/Core.
Those use an interrupt router for muxing the interrupt to the desired destination.

This works by utilizing the TISCI interface, where requests to the DMSC subsystem take the form described here:

software-dl.ti.com/.../rm_irq.html

In my understanding all i need to provide to source index (src_index) connected to input index for the INTR, which is probably the device ID of the source peripheral (my GPIO for instance),
although the device ID of the source could also be the src_id. Here I don't understand the difference, maybe it is for SMDs with several pads, where the device ID is for the SMD
and the src_index is for the pad?
And then I need to provide the destination index (dst_host_irq) connected to output index for the INTR, which is probably the same as the IRQ number provided in the TRM in table 9-80?
Though in the description of "struct tisci_msg_rm_irq_set_req - Interrupt Router Mux Configuration" here

https://software-dl.ti.com/tisci/esd/latest/2_tisci_msgs/rm/rm_irq.html

it says that for a direct connection both src_id and dst_id are the device IDs of the interrupt router, which doesn't
make much sense to me. As I would think the dst_id should be that of the MCU and the src_id that of the peripheral.

Also when I look in the tables here:

http://software-dl.ti.com/tisci/esd/latest/5_soc_doc/am64x/interrupt_cfg.html

There seem to be some irregularities, at least in my understanding.
For instance, in table 9-80, TRM (R5FSS0_CORE0 Interrupt Map)



It says, interrupt number 43 (is intNum in HwIP_Params the same as interrupt-ID here?) is connected to INTR0 Output index 11.
which seems correct, when looking at the table here:

software-dl.ti.com/.../interrupt_cfg.html



but it says that the destination is GICSS, which is the interrupt controller for the Cortex-A53 and not the R5F like it says in the TRM.
So I am not sure if those numbers are just a coincidence here and if the HwIP_Params.intNum is really the Interrupt-ID and also the destination index of the INTR0.

If they are not the same, why do I need the intNum in addition to source and destination indexes. Shouldn't those 2 be enough to uniquely describe an interrupt line?

Next is the interrupt aggregator.
My understanding is, when I have a global event (like for instance "power down") which can be triggered by a multitude of sources, where it is not important which source triggered the event,
those events are mapped to virtual interrupts. Those VINTs are bitsets which are connected to a hardwired destination identified by a destination index.
The destination can be either an interrupt controller of one of the MCUs/Cores or an INTR.
A bit in the vint can be mapped to a global event, so that when the event occurs the destination is notified about the bit change.

The mapping of the global event to the vint is kept in those INTA registers described here:

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/devicetree/bindings/interrupt-controller/ti,sci-inta.yaml

where I guess those are the same as the OES registers described here:

https://software-dl.ti.com/tisci/esd/latest/2_tisci_msgs/rm/rm_irq.html#tisci-msg-rm-irq-set-irq-route-set

I would assume the INTA/OES register is also the place where the vint_status_bit_index is kept.

*******************************************************************************************

So if my understanding is correct, the things that I need the user of an interrupt interface to provide are

1. a source index
2. a destination index
3. in case of a virtual interrupt a global event

The rest should be able to deduce internally.
Is that correct?
(Plase don't simply answer with yes/no, since I had more questions above)

Thank you for your time and trouble.


Best regards

Philip.

  • Hi Philip,

    I am currently in the process of writing an abstraction for interrupts in our TI-RTOS based system using the MCU+-SDK for AM64x-Sitara.

    TI-RTOS isn't supported in AM64x MCU+SDK. Instead, MCU+SDK supports FreeRTOS and No-RTOS (bare metal) options. Can you please confirm you're using AM64x MCU+SDK with one of these options?

    Are you developing for R5F cores, M4F cores, or both? Are you using Linux on the A53 cores?

    I'm looking into your questions and will get back with you. My responses will likely be delayed due to the upcoming winter holiday.

    Regards,
    Frank

  • I am using FreeRTOS. I thought TI-RTOS is the TI version of FreeRTOS.
    I am developing on R5F cores, also later on M4F.
    I am not using Linux on any cores.
    Also I am not sure if that is of any relevance to begin with. Please correct me but shouldn't interrupts be hardware dependant but independant of the OS?!
    I was referring above to the YAML files since I couldn't figure out the working of the interrupt router and aggregator from the TRM and needed every additional source of documentation.
    The TRM seems to describe the functionality on an abstract level, but I wasn't able to see the connection to the actual code.
    I am still not sure if the vints are just a number and the bit sets are in the OEM registers or the bit-sets are in different registers and the vint is the bit-set itself which lies in the registers and so on.
    In the yaml file concerning the interrupt aggregator it seems in the picture that the vints are the bit-sets themselves holding bits 0-63, but then on the resource page, where the  DMSC-Request fields are described, it says that the vints are uint16_t so there are 16 Bits and not 64. This again leaves me confused.

    If I had a documentation explaining for the aggregator the whole process of mapping local events to global events, then connecting those to a vint which is itself conntected to a destination index (is destination index the device ID of the destination? And if not, why not?).
    Also when the aggregator is connected to the router, is the destination index then one of the input indexes of the router?
    And how does the DMSC- request- play along with the HwIP_Params structure, is the intNum, as I suspect the destination index of the destination MCU or interrupt controller?

    As for the interrupt router is there a difference between source/destination index and device ID to begin with, and if yes why?
    If I were to design that I would give every hardware element a device ID and then one or more subIDs if hardware elements are structured in a hierarchy.
    And that would be it. But here I find device IDs then indexes (source, destination, input, output) that could be the same as device IDs but maybe not, also I have tables with interrupt numbers, where again it is unlcear to me if those numbers are device IDs or indexes or something completely different.

    Those are the questions that I didn't find an answer to.
    I am not sure why it is of importance on which system or with which hardware I develop here.
    I assume that the identifiers in a solid system design would be chosen with the same meaning for any supported system.

    Thank you for your time and trouble.


    Best regards

    Philip.

  • Ok,
    I guess I understood most of it now after reading the comments in drivers/sciclient/include/tisci/rm/tisci_rm_irq.h
    together with

    http://software-dl.ti.com/tisci/esd/latest/5_soc_doc/am64x/interrupt_cfg.html .

    Please correct me if I am wrong somewhere.
    The vint is the virtual interrupt number which is hardwired connected to an IRQ of a destination device.
    The vint is also connected to vint status register.
    I assume that this is not the same register as the interrupt sources OES register, please correct me if I am wrong.
    The OES register stores the global event number, which can be mapped to a vint. The OES register is part of the source peripheral,
    whereas the vint status register is part of the virtual interrupt which can be connected to a multitude of global events, if they share the same interrupt destination.
    In case the global event should not be connected to a hardware interrupt but handled by software, 

    The vint status register holds a bit set where each global event is represented by a single bit.
    The vint_status_bit_index holds the bit position representing the global event in the bit set inside the vint status register.
    I guess the index starts from 0 and is part of the source peripheral.

    I am not sure what the secondary_host value is for if the vints are connected to a hardwired destination though.
    In my understanding a secondary_host value would only make sense if there was a need to further specify the destination
    in case it is different from the originating MCU.

    Concerning the interrupt router, I am still not sure what the different IDs and indexes mean.
    In drivers/sciclient/include/tisci/rm/tisci_rm_irq.h  it says for instance:

    " * \param src_id
     * ID of interrupt source peripheral
     *
     * \param src_index
     * Interrupt source index within source peripheral"

    So it seems that src_id is the device ID of the source peripheral and the src_index is some sub-ID for instance, as I suspected the device being some SMD-chip and the src_index identifying the pads.

    but then:

    " * Interrupt Router Mux Configuration - Configures an IR input to output mux
     *                                      connection where the IR input is the
     *                                      src_index and the IR output is the
     *                                      dst_host_irq.  Both the src_id and the
     *                                      dst_id must be the device ID of the
     *                                      IR being configured."

    So here src_id is the device ID of the interrupt router, which means if the above still stands correct that src_index should be the input index of the interrupt router and not the source index within the source peripheral device. Is this correct?
    This would make sense as far as the interrupt router doesn't need to know what the source peripheral is, only which of its own input indexes is to be connected to which of its own output indexes.
    I guess as the outputs of the interrupt router are probably hardwired to the specific interrupt destinations there is no need to differentiate between the routers output index and the destinations interrupt number. So for simplification we only provide the destinations IRQ.
    But this is just a guess. I would be delighted if you would clarify this.



  • Hi Philip,

    Sorry for the long delayed response. I'm looking at this again and will be happy to help you.

    There is quite a bit to work through here. I understand your frustration with all the TISCI API functions and numerous module/interrupt IDs.

    I understand you're writing an interrupt abstraction layer, but I suggest we start with a concrete example of configuring a GPIO interrupt to R5F VIM using software in the MCU+SDK. This will establish the procedure for:

    • Configuring interrupt route through MAIN domain GPIOMUX_INTRTR0 to R5F SS VIM
    • Configuring HWI (for R5F, this is the VIM interrupt controller)

    I know you've reviewed the AM64x TRM, but just to ensure we're aligned on the relevant hardware, please see these TRM sections:

    • Table 12-156. GPIO Modules Allocation within Device Domains
    • 12.1.2.3.2 GPIO Integration in MAIN Domain
    • Table 12-165. GPIO Hardware Requests
    • 12.1.2.4.4 GPIO Interrupt Connectivity
    • 9.3.2.2 GPIOMUX_INTRTR0 Integration
    • Table 9-61. GPIOMUX_INTRTR0 Hardware Requests
    • 9.3.3.1 GPIOMUX_INTRTR0 Registers
    • Table 9-80. R5FSS0_CORE0 Interrupt Map (and Table 9-81, 9-82 & 9-83)

    There is a GPIO interrupt example in <SDK>\examples\drivers\gpio\gpio_input_interrupt\am64x-evm\r5fss0-0_nortos

    Documentation is here: https://software-dl.ti.com/mcu-plus-sdk/esd/AM64X/08_01_00_36/exports/docs/api_guide_am64x/EXAMPLES_DRIVERS_GPIO_INPUT_INTERRUPT.html

    The example uses GPIO1_43, and GPIO_1_BANK2_INT.

    •  GPIO_1_BANK2_INT is connected to MAIN_GPIO_INTRTR_IN_182
    • GPIOMUX_INTRTR0_MUXCNTL_8 is configured to output MAIN_GPIO_INTRTR_IN_182
    • MAIN_GPIOMUX_INTROUTER0_OUTP_8 is connected to R5FSS0_CORE0_INTR_IN_40

    The interrupt router configuration occurs in board.c:Sciclient_gpioIrqSet(). The configuration is handled using Sciclient_rmIrqSet().

    The VIM interrupt configuration is handled in gpio_main_interrupt.c:HwiP_construct().

    Can you please review this software and see if it helps answer some of your questions?

    Regards,
    Frank

  • Hello Frank,
    thank you for your sophisticated response.
    Maybe I am thinking just too complicated.

    My task is to develop a vendor-independant interface and a vendor (TI) dependant implementation in C++ (object oriented).

    So the questions I am asking myself is:

    1. What are those IDs and indexes, are they TI-specific or not ?

    The answer here probably is, they are.

    2. Which of those can I probably deduce from other general parameters that I can expect the user to know,
    even if they don't know the TI-specific implementation?
    And even if the user needs to know the TI-specific numbers,
    I would like to at least abstract if possible from the use of interrupt router and interrupt aggregator and let all interrupt initialization look the same to the user.
    The user should not have to understand the use of interrupt router nor interrupt aggregator to create an interrupt instance.

    And here my problem is that in the example there are many preprocessor defines that are not semantically clear to me.
    It is great to know what numbers I put where and in which files or tables I could find those numbers.
    But my problem is, that I don't understand in several cases, why I use those numbers, like what is their meaning.
    And I cannot translate them to something general if I have no idea, what they are.

    Even if I accept that I need to do the construction of the interrupts TI-dependant, I am still struggling to describe to the user what inputs are expected of him, because I don't know what they are.

    From the example:

    1. The input dievice ID is defined in drivers/sciclient/include/tisci/am64x_am243x/tisci_devices.h
    which is, as it says an autogenerated file from SYSFW.
    The defines are simply numbers, there is no comment above explaining what the numbers are semantically.
    From the name "TISCI_DEV_GPIO1" I deduce, that it is probably not the ID of Cortex-R5F Core0 but some internal ID of something that I don't know.

    http://downloads.ti.com/tisci/esd/18_08_00/5_soc_doc/am6x/devices.html

    says

    "The device IDs represent SoC subsystems that can be modified via DMSC TISCI message APIs"

    So how can I explain that to a user without him having to know how to use the TISCI requests for programming the interrupt router and interrupt aggregator himself? What are those SoC subsystems? Can the user find those subsystems on a circuit diagram somehow? How does he know which one he needs?

    2. TISCI_BANK_SRC_IDX_BASE_GPIO1 + GPIO_GET_BANK_INDEX(GPIO_PUSH_BUTTON_PIN)
    I know from the use of GPIOs in drivers/gpio/v0/cslr_gpio.h in combination with drivers/gpio/v0/gpio.h that the banks are bitsets with single pins being mapped to a specific bit. So the part "GPIO_GET_BANK_INDEX(GPIO_PUSH_BUTTON_PIN)" gets the bit-index
     of the pin in the bank bitset. But what does the sum of both do. It is the source index, but what is a source index?
    Is it some numbering of the pads of an MCU with the device ID being that of the MCU? Here again I am lost because I don't know where on my circuit board those "SoC subsystems" are to be found.

    3. The destination ID really seems as expected to be the ID of the destination MCU, although SS0 indicates that it is some SoC subsystem 0 on the MCU. So again how does a user decide which is the right subsystem when looking at his board?

    Also the destination index is for some reason the output index of the interrupt router as defined in, drivers/gpio/gpio_input_interrupt/am64x-evm/r5fss0_0-nortos/board.c, line 43:

    #define BOARD_BUTTON_GPIO_INTR_NUM      (CSLR_R5FSS0_CORE0_INTR_MAIN_GPIOMUX_INTROUTER0_OUTP_8)

    Yet here:

    http://software-dl.ti.com/tisci/esd/latest/5_soc_doc/am64x/interrupt_cfg.html#cmp-event-introuter0-interrupt-router-output-destinations

    There is a destination index on the right side of the table which is clearly different from the interrupt routers output index.
    So why is in the example the output index used as destination index?

    4. The example doesn't give any information about the use of the interrupt aggregator since those fields are left out.

    The interrupt aggregator is not that important to me at the moment, but at least using the interrupt router I would like to be able to hide the use of the router and make an easy to use interface where I am able to explain to users what is expected of them.

    Thank you for reading my long text. I appreciate any help on this.

  • So basically, to sum it up, what I am struggling with is the scenario:

    I have some peice of hardware that can change its state somehow.
    And when a specific state change occurs, I want an MCU of my choice to react to it by being interrupted.
    I am not interested if there is a direct line or if the interrupt has to be routed or aggregated or whatever.

    I know what my destination MCU is, probably I just want to reach it and am not that much interested in stuff like on which input line the interrupt comes in. So this part would be much simpler. I could just choose one of the MCUs as destinationc,
    and the abstraction would do the rest.

    What I need to know is, how do I address the piece of hardware that I want as my interrupt source and the MCU or it interrupt controller that I want as my interrupt destination.
    I know where the piece of hardware resides on my board. Also I know what pin should emit the interrupt signal.
    The pin could be on one of the MCUs or it could be on a controller or about any SMD.

    Main question:
    How do I find out now which combination of device ID and source index or some other means of identification I need to use to define the designated pin on my piece of hardware as interrupt source?

    That would be all I really need here.
    Thank you for your time and trouble.


    Best regards

    Philip.

  • subsystems are not described in the TRM but in the Sitara AM64x Datasheet here:

    https://www.ti.com/lit/ds/sprsp56b/sprsp56b.pdf?ts=1642499350797&ref_url=https%253A%252F%252Fwww.ti.com%252Ftool%252FTMDS64GPEVM

    In section 8.2, so the Device IDs are probably identifications for those subsystems, is that correct?
    I hope I find out about the indexes there as well.

  • Philip,

    I'm working on this and will get back with you shortly.

    Regards,
    Frank

  • Hi Philip,

    I carefully reviewed the Sciclient docs and API in the SDK, and the GPIO interrupt example.

    I see little usage of Sciclient calls in the MCU+ SDK. I suspect this is because of the comment here: https://software-dl.ti.com/mcu-plus-sdk/esd/AM64X/08_01_00_36/exports/docs/api_guide_am64x/DRIVERS_SCICLIENT_PAGE.html#autotoc_md571

    "It is strongly recommend to use SysConfig where it is available instead of using direct SW API calls. This will help simplify the SW application and also catch common mistakes early in the development cycle."

    The GPIO interrupt example relies on application-level code in board.c for configuring GPIOMUX_INTRTR0. Hence, Sysconfig doesn't generate the code for configuring GPIOMUX_INTRTR0.

    I modified the GPIO interrupt example to experiment with different approachs to configuring interrupt router. I found that each of these approaches works properly:

    1. Sciclient_rmIrqSet()
    2. Sciclient_rmIrqSetRaw()
    3. Sciclient_rmGetResourceRange(), Sciclient_rmIrqTranslateIrOutput(), Sciclient_rmIrqSet()

    I've attached my modified gpio_input_interrupt.c for your inspection. I included comments in each case indicating where I believe the API function parameters are obtained.

    The information needed for the Sciclient API functions is sometimes in the TISCI tables, sometimes in the TRM, and other times in the Sciclient library build (e.g. sciclient_defaultBoardcfg_rm.c, sciclient_irq_rm.c).

    I agree with you that the semantics of different API parameters isn't always clear:

    Currently, I'm locating an internal SYSFW/Sciclient expert on the software development team to help us figure this out. I'll keep you posted.

    Regards,
    Frank

    gpio_input_interrupt.c
    /*
     *  Copyright (C) 2021 Texas Instruments Incorporated
     *
     *  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.
     */
    
    #include <kernel/dpl/DebugP.h>
    #include <kernel/dpl/ClockP.h>
    #include <kernel/dpl/AddrTranslateP.h>
    #include <kernel/dpl/HwiP.h>
    #include "ti_drivers_config.h"
    #include "ti_drivers_open_close.h"
    #include "ti_board_open_close.h"
    
    #include <drivers/sciclient.h> // FL
    #define TISCI_BANK_SRC_IDX_BASE_GPIO1       (90U)
    
    /*
     * This example configures a GPIO pin in input mode
     * and configures it to generate interrupt on rising edge.
     * The application waits for 5 key presses, prints the
     * number of times the keys are pressed and exits.
     */
    
    uint32_t            gGpioBaseAddr = GPIO_PUSH_BUTTON_BASE_ADDR;
    HwiP_Object         gGpioHwiObject;
    volatile uint32_t   gGpioIntrDone = 0;
    
    static void GPIO_bankIsrFxn(void *args);
    
    extern void Board_gpioInit(void);
    extern void Board_gpioDeinit(void);
    extern uint32_t Board_getGpioButtonIntrNum(void);
    extern uint32_t Board_getGpioButtonSwitchNum(void);
    
    static void Sciclient_test(void); // FL
    
    void gpio_input_interrupt_main(void *args)
    {
        int32_t         retVal;
        uint32_t        pinNum, intrNum;
        uint32_t        bankNum, waitCount = 5;
        HwiP_Params     hwiPrms;
    
        /* Open drivers to open the UART driver for console */
        Drivers_open();
        Board_driversOpen();
        //Board_gpioInit();
    
        Sciclient_test();
    
        DebugP_log("GPIO Input Interrupt Test Started ...\r\n");
        DebugP_log("GPIO Interrupt Configured for Rising Edge (Button release will trigger interrupt) ...\r\n");
    
        pinNum          = GPIO_PUSH_BUTTON_PIN;
        intrNum         = Board_getGpioButtonIntrNum();
        bankNum         = GPIO_GET_BANK_INDEX(pinNum);
    
        /* Address translate */
        gGpioBaseAddr = (uint32_t) AddrTranslateP_getLocalAddr(gGpioBaseAddr);
    
        /* Setup GPIO for interrupt generation */
        GPIO_setDirMode(gGpioBaseAddr, pinNum, GPIO_PUSH_BUTTON_DIR);
        GPIO_setTrigType(gGpioBaseAddr, pinNum, GPIO_PUSH_BUTTON_TRIG_TYPE);
        GPIO_bankIntrEnable(gGpioBaseAddr, bankNum);
    
        /* Register pin interrupt */
        HwiP_Params_init(&hwiPrms);
        hwiPrms.intNum   = intrNum;
        hwiPrms.callback = &GPIO_bankIsrFxn;
        hwiPrms.args     = (void *) pinNum;
        retVal = HwiP_construct(&gGpioHwiObject, &hwiPrms);
        DebugP_assert(retVal == SystemP_SUCCESS );
    
        DebugP_log("Press and release SW%d button on EVM to trigger GPIO interrupt ...\r\n", Board_getGpioButtonSwitchNum());
        while(gGpioIntrDone < waitCount)
        {
            /* Keep printing the current GPIO value */
            DebugP_log("Key is pressed %d times\r\n", gGpioIntrDone);
            ClockP_sleep(1);
        }
        DebugP_log("Key is pressed %d times\r\n", gGpioIntrDone);
    
        /* Unregister interrupt */
        GPIO_bankIntrDisable(gGpioBaseAddr, bankNum);
        GPIO_setTrigType(gGpioBaseAddr, pinNum, GPIO_TRIG_TYPE_NONE);
        GPIO_clearIntrStatus(gGpioBaseAddr, pinNum);
        HwiP_destruct(&gGpioHwiObject);
    
        DebugP_log("GPIO Input Interrupt Test Passed!!\r\n");
        DebugP_log("All tests have passed!!\r\n");
    
        Board_gpioDeinit();
        Board_driversClose();
        Drivers_close();
    }
    
    static void GPIO_bankIsrFxn(void *args)
    {
        uint32_t    pinNum = (uint32_t) args;
        uint32_t    bankNum =  GPIO_GET_BANK_INDEX(pinNum);
        uint32_t    intrStatus, pinMask = GPIO_GET_BANK_BIT_MASK(pinNum);
    
        /* Get and clear bank interrupt status */
        intrStatus = GPIO_getBankIntrStatus(gGpioBaseAddr, bankNum);
        GPIO_clearBankIntrStatus(gGpioBaseAddr, bankNum, intrStatus);
    
        /* Per pin interrupt handling */
        if(intrStatus & pinMask)
        {
            gGpioIntrDone++;
        }
    }
    
    // FL: sciclient tests
    #if 0
    static void Sciclient_test(void)
    {
        int32_t                             retVal;
        struct tisci_msg_rm_irq_set_req     rmIrqReq;
        struct tisci_msg_rm_irq_set_resp    rmIrqResp;
    
        rmIrqReq.valid_params           = 0U;
        rmIrqReq.valid_params          |= TISCI_MSG_VALUE_RM_DST_ID_VALID;
        rmIrqReq.valid_params          |= TISCI_MSG_VALUE_RM_DST_HOST_IRQ_VALID;
        rmIrqReq.global_event           = 0U;
        // FL: https://software-dl.ti.com/tisci/esd/latest/5_soc_doc/am64x/devices.html, AM64X_DEV_GPIO1
        rmIrqReq.src_id                 = TISCI_DEV_GPIO1;
        // FL: <SDK>\source\drivers\sciclient\soc\am64x_am243x?, GPIO1_gpio_bank_90_98_to_MAIN_GPIOMUX_INTROUTER0_in_180_188?
        rmIrqReq.src_index              = TISCI_BANK_SRC_IDX_BASE_GPIO1 + GPIO_GET_BANK_INDEX(GPIO_PUSH_BUTTON_PIN);
        // FL: https://software-dl.ti.com/tisci/esd/latest/5_soc_doc/am64x/devices.html, AM64X_DEV_R5FSS0_CORE0
        rmIrqReq.dst_id                 = TISCI_DEV_R5FSS0_CORE0;
        // FL: VIM IRQ number (TRM)
        rmIrqReq.dst_host_irq           = Board_getGpioButtonIntrNum();
        rmIrqReq.ia_id                  = 0U;
        rmIrqReq.vint                   = 0U;
        rmIrqReq.vint_status_bit_index  = 0U;
        rmIrqReq.secondary_host         = TISCI_MSG_VALUE_RM_UNUSED_SECONDARY_HOST;
    
        retVal = Sciclient_rmIrqSet(&rmIrqReq, &rmIrqResp, SystemP_WAIT_FOREVER);
        if(0 != retVal)
        {
            DebugP_log("[Error] Sciclient event config failed!!!\r\n");
            DebugP_assert(FALSE);
        }
    
        return;
    }    
    #endif
    #if 1
    static void Sciclient_test(void)
    {
        int32_t                             retVal;
        struct tisci_msg_rm_irq_set_req     rmIrqReq;
        struct tisci_msg_rm_irq_set_resp    rmIrqResp;
    
        rmIrqReq.valid_params           = 0U;
        rmIrqReq.valid_params          |= TISCI_MSG_VALUE_RM_DST_ID_VALID;
        rmIrqReq.valid_params          |= TISCI_MSG_VALUE_RM_DST_HOST_IRQ_VALID;
        rmIrqReq.global_event           = 0U;
        // FL: https://software-dl.ti.com/tisci/esd/latest/5_soc_doc/am64x/devices.html, AM64X_DEV_MAIN_GPIOMUX_INTROUTER0
        rmIrqReq.src_id                 = TISCI_DEV_MAIN_GPIOMUX_INTROUTER0;
        // FL: GPIO interrupt router input (TRM)
        rmIrqReq.src_index              = 182;
        // FL: https://software-dl.ti.com/tisci/esd/latest/5_soc_doc/am64x/devices.html, AM64X_DEV_MAIN_GPIOMUX_INTROUTER0
        rmIrqReq.dst_id                 = TISCI_DEV_MAIN_GPIOMUX_INTROUTER0;
        // FL: GPIO interrupt router output (TRM)
        rmIrqReq.dst_host_irq           = 8;
        rmIrqReq.ia_id                  = 0U;
        rmIrqReq.vint                   = 0U;
        rmIrqReq.vint_status_bit_index  = 0U;
        rmIrqReq.secondary_host         = TISCI_MSG_VALUE_RM_UNUSED_SECONDARY_HOST;
    
        retVal = Sciclient_rmIrqSetRaw(&rmIrqReq, &rmIrqResp, SystemP_WAIT_FOREVER);
        if(0 != retVal)
        {
            DebugP_log("[Error] Sciclient event config failed!!!\r\n");
            DebugP_assert(FALSE);
        }
    
        return;   
    }
    #endif
    #if 0
    static void Sciclient_test(void)
    {
        struct tisci_msg_rm_get_resource_range_req  rmGetRsrcRngReq;
        struct tisci_msg_rm_get_resource_range_resp rmGetRsrcRngResp;
        struct tisci_msg_rm_irq_set_req rmIrqSetReq;
        struct tisci_msg_rm_irq_set_resp rmIrqSetResp;
        uint16_t dstInput;    
        int32_t retVal;
    
        /* Get interrupt router output number range assigned to Host */
        // FL: https://software-dl.ti.com/tisci/esd/latest/5_soc_doc/am64x/devices.html, AM64X_DEV_MAIN_GPIOMUX_INTROUTER0
        rmGetRsrcRngReq.type = TISCI_DEV_MAIN_GPIOMUX_INTROUTER0;
        rmGetRsrcRngReq.subtype = TISCI_RESASG_SUBTYPE_IR_OUTPUT;
        // FL: https://software-dl.ti.com/tisci/esd/latest/5_soc_doc/am64x/hosts.html, MAIN_0_R5_1
        rmGetRsrcRngReq.secondary_host = TISCI_HOST_ID_MAIN_0_R5_1;
        retVal = Sciclient_rmGetResourceRange(&rmGetRsrcRngReq, &rmGetRsrcRngResp, SystemP_WAIT_FOREVER);
        if ((retVal != 0) && (rmGetRsrcRngResp.range_num == 0))
        {
            /* No range assigned to Host, try with HOST_ID_ALL */
            rmGetRsrcRngReq.secondary_host = TISCI_HOST_ID_ALL;
    
            retVal = Sciclient_rmGetResourceRange(
                     &rmGetRsrcRngReq,
                     &rmGetRsrcRngResp,
                     SystemP_WAIT_FOREVER);
        }
        
        if (retVal == 0)
        {
            /* Translate interrupt router output to interrupt controller input to which it's connected */
            // FL: https://software-dl.ti.com/tisci/esd/latest/5_soc_doc/am64x/devices.html, AM64X_DEV_MAIN_GPIOMUX_INTROUTER0
            // FL: https://software-dl.ti.com/tisci/esd/latest/5_soc_doc/am64x/devices.html, AM64X_DEV_R5FSS0_CORE0
            retVal = Sciclient_rmIrqTranslateIrOutput(TISCI_DEV_MAIN_GPIOMUX_INTROUTER0,
                rmGetRsrcRngResp.range_start, TISCI_DEV_R5FSS0_CORE0, &dstInput);
            
            if (retVal == 0)
            {
                // FL: https://software-dl.ti.com/tisci/esd/latest/5_soc_doc/am64x/devices.html, AM64X_DEV_R5FSS0_CORE0
                rmIrqSetReq.dst_id = TISCI_DEV_R5FSS0_CORE0;
                // FL: https://software-dl.ti.com/tisci/esd/latest/5_soc_doc/am64x/hosts.html, MAIN_0_R5_1
                rmIrqSetReq.secondary_host = TISCI_HOST_ID_MAIN_0_R5_1;
            
                rmIrqSetReq.ia_id                   = 0U;
                rmIrqSetReq.vint                    = 0U;
                rmIrqSetReq.global_event            = 0U;
                rmIrqSetReq.vint_status_bit_index   = 0U;
                rmIrqSetReq.valid_params            = TISCI_MSG_VALUE_RM_DST_ID_VALID
                                                      | TISCI_MSG_VALUE_RM_DST_HOST_IRQ_VALID
                                                      | TISCI_MSG_VALUE_RM_SECONDARY_HOST_VALID;
                                                      
                // FL: https://software-dl.ti.com/tisci/esd/latest/5_soc_doc/am64x/devices.html, AM64X_DEV_GPIO1
                rmIrqSetReq.src_id = TISCI_DEV_GPIO1;
                // FL: <SDK>\source\drivers\sciclient\soc\am64x_am243x?, GPIO1_gpio_bank_90_98_to_MAIN_GPIOMUX_INTROUTER0_in_180_188?
                rmIrqSetReq.src_index = TISCI_BANK_SRC_IDX_BASE_GPIO1 + GPIO_GET_BANK_INDEX(GPIO_PUSH_BUTTON_PIN);
                // FL: VIM IRQ number (TRM)
                rmIrqSetReq.dst_host_irq = dstInput;
    
                /* Configure interrupt route between peripheral and Host */
                retVal = Sciclient_rmIrqSet(&rmIrqSetReq, &rmIrqSetResp, SystemP_WAIT_FOREVER);
                
            }
        }
    }
    #endif
    #if 0
    static void Sciclient_test(void)
    {
        uint16_t srcOutput;
        
        Sciclient_rmIrqTranslateIrqInput(TISCI_DEV_R5FSS0_CORE0, 
            40, 
            TISCI_DEV_MAIN_GPIOMUX_INTROUTER0, 
            &srcOutput);
    }
    #endif
    
    

  • Hello Frank,
    first of all, thank you for your hard work.
    As I was told by my colleague during the meeting that you attended together with us, I am now aware that I can input questions and requests for clarification concerning the TRM in the forms provided by the link on the bottom of each page in the TRM.
    I will do so when I have the time.

    Concerning the current conversation, find in the following the questions that I am able to pinpoint at the moment:
    ******************************************************************************************
    1. First of all, concerning your advise from the comment:

    "It is strongly recommended to use SysConfig where it is available instead of using direct SW API calls. This will help simplify the SW application and also catch common mistakes early in the development cycle."

    As far as I can see SysConfig can only be used to set the trigger type (none, rising edge, falling edge, both).
    Also I can only use SysConfig for the initial configuration since the configuration works at compile time.

    So I cannot use SysConfig to change the trigger at runtime. Also I cannot use SysConfig to set an interrupt route as far as I am aware. Mapping system events also does not work using SysConfig as far as I know.

    Just to mention, while I am convinced that you know that since you are the expert, but the pinmux in SysConfig is not the same as the interrupt route muxing by the interrupt router. I mixed that up in the beginning when I started working with the Sitara.
    The pinmux is only for determining the pin mode at compile time as a pin can have different uses depending on the platform the Sitara is used on.

    As I said I am confident you know that, just wanted to make sure we are not confusing anything here.
    ******************************************************************************************

    2. Concerning the cofusion according to the contradiction in the sciclient docs, my biggest issue seems to be, as I mentioned above, the contradiction with the "Interrupt Router Mux Configuration" documented in tisci_rm_irq.h, line 94ff.
    As in the example there is no interrupt aggregator involved and the "Interrupt Router Mux Configuration" seems to be the only tisci IRQ request using solely the interrupt router, I would assume that is the one in the example, yet it doesn't provide the interrupt routers device ID as source ID and destination ID as said in the comments of tisci_rm_irq.h but instead the device ID of the source and destination SoC subsystems.

    So is the documentation wrong here then?
    ******************************************************************************************

    3. As I would like to obscure the existence of interrupt router and aggregator to the user of my interface, I would like to work only with device ID and index of the source peripheral as well as the destination interrupt controller or MCU. I probably use this functions for translation:
    Sciclient_rmIrqTranslateIrqInput

    I find in drivers/sciclient/sciclient_rm.c, line 1282ff that, if a destination interrupt controllers interrupt input line is not connected to an interrupt router,
    the query using above function would return probably CSL_EBADARGS.

    So in case I only want to connect my route to any interrupt line of the destination interrupt controller, do I have to test all of its input lines in a loop until I find one that isn't yet connected?
    Or is there a function that tells me about what routes are currently established and which are still available for connecting something?
    ******************************************************************************************

    4. What are those resource ranges that you tested? In sciclient_rm.h, in the description of the function Sciclient_rmGetResourceRange it says in my code:

    "Retrieves a host's assigned range for a resource
     *
     *  Returns the range for a unique resource type assigned to the specified host,
     *  or secondary host.  The unique resource type is formed by combining the
     *  10 LSB of type and the 6 LSB of subtype."

    So for instance if the resource type is memory the function will tell me something like "sector 00000 - 00FFF are available for use with MCU1_0" or what is the "range for a resource"?
    Or is it about index range and tells me for an interrupt router something like "output index 42 - 95 are connected to the provided interrupt controller"?

    What if I have output 0 connected, also output 10 and output 42, is the range then 3 or 43? I would rather expect a set of index numbers here instead of a range.
    But maybe the range is something different. My problem here is that the function documentation doesn't seem to say anything about what such a range is to begin with.
    Maybe it is for a subsystem which is mapped into memory and provides the address block in which it resides, I don't know.
    ******************************************************************************************
    5. In the same file, sciclient_rm.h it says in the description of the function Sciclient_rmIrqSet:

    "*  Configures an interrupt route between the peripheral and host processor
     *  specified within the #tisci_msg_rm_irq_set_req payload.  The interrupt
     *  destination is either the processor sending the request, or the secondary
     *  host if it's defined as a valid host."

    So, if the destination is already defined by the current MCU or if provided the secondary host ID, why do I need to provide a dst_id then at all?

    ******************************************************************************************
    6. I guess to find out if for the interrupt router an output index of an interrupt router is connected to a peripheral source over the IRs input index, I need to read those MUXCNTL_N registers sitting in struct CSL_intr_router_cfgRegs.
    I assume the index of the array of MXCNTL registers is the output index of the interrupt router.

    When I look for instance at the interrupt map of GPIOMUX_INTRTR0 (table 9-86 TRM) I see all the values for the MXCNTL-Registers when connecting it to an interrupt source.
    What is unclear to me is what value do I set when the output index is still unoccupied (no route set to the output).
    Should I assume that in that case the INT_ENABLE bit is 0?
    Is there a difference between "route not set" and "mcu doesn't allow interrupt over that route"? I would assume the latter one being the case where I set e INT_ENABLE to 0. But I am not sure, that is the question here.
    ******************************************************************************************

    7. Concerning the interrupt aggregator to find out which lines have still free bit positions or are still not mapped to a global event, I probably need to utilize those SEVI, LEVI and GEVI values.
    I am still not sure, how to make use of them. This one I can maybe figure out on my own.
    But would be great if there was an example using them.
    ******************************************************************************************
    8. Concerning your example, in line 263 the src_index is given as GPIO1_gpio_bank_90_98_to_MAIN_GPIOMUX_INTROUTER0_in_180_188
    This seems to be a predefined route in the IRQ tree, where the source ID index that of the source peripheral and the remote ID is that of the destination MCU.

    What I want concerning providing the specification of the source, is the user to simply provide the source peripherals source ID and source index.
    They shouldn't have to know what interrupt router is used or if one at all.
    I would assume that the source peripheral identification is a property of the source peripheral independant of if I want interrupts at all or what destination I want.
    Isn't there some table or anything where I can just read the source index of a peripheral independant of the attached interrupt router?
    *******************************************************************************************

    I think that sums up about my current most urgent problems.
    Thank you for looking into it.


    Best regards

    Philip.

  • Concerning the meaning of the index numbers, as I understand it, the interrupt routes are managed in an interrupt route tree with each node being one hopp.
    Now the source and destination index could be those bases described in dirvers/sciclient/sciclient_rm_priv.h (I am aware that this is a private header which is not for direct use by the API user. I am simply using it to understand what those numbers are.)

    struct Sciclient_rmIrqIf

    In the comment it says:
     "* \param lbase
     * Local subsystem's outgoing interrupt interface base
     *
     * \param rbase
     * Remote subsystem's incoming interrupt interface base
     *"

    Those could be the index numbers, though I am not sure what a "base" is. There seems to be a word missing like "base address", "base index", "base node", "base class", etc. .
    Since we are on an ARM- based system and ARM is a 32Bit RISC architecture (with later chipsets being 64Bit) I guess it doesn't mean "base address" since lbase and rbase are both uin16_t instead of uint32_t.

  • After studying drivers/sciclient/sciclient_rm_irq.c my understanding is now that indeed the source and destination index numbers identify the nodes in the interrupt path tree, and are those lbase and rbase members in struct Sciclient_rmIrqIf.

    Which I also found as I looked at your comment of source index in your provided example.
    As I understand it, in drivers/sciclient/soc/am64x_am243x/sciclient_irq_rm.c the interrupt routes are statically stored instead of calculated at runtime.

    The problem here with your example comment is, that taking the source index from one of those routes does not abstract from the interrupt router. And as I understand it, the source index belongs to the source peripheral. So every source peripheral should be identified by the device ID of the SoC subsystem that holds the source peripheral and the subsystem intern peripheral index.

    If possible I would like to provide the user with a lookup table independant of the interrupt router, which is not what you used in your example comment.

  • Hi Philip,

    Sorry for the delayed response, I'm looking at this today.

    Regards,
    Frank

  • Hi Philip,

    I can't comment concerning the design of your abstraction layer. Do you think you have a handle on the semantics for parameters for the RM API functions? As I said before, it appears the parameters come from the TRM, the TISCI docs, and the Sciclient board configuration.

    A colleague pointed me to some additional documentation you may find useful:

    https://software-dl.ti.com/processor-sdk-rtos/esd/AM65X/08_01_00_11/exports/docs/pdk_am65xx_08_01_00_33/docs/userguide/am65xx/family_cfg/am65xx/index_modules_sciclient_am65xx.html

    Please bear in mind some of these details are only relevant to other TI SOCs.

    These docs support the notion that some of information comes from the Sciclient board configuration:

    I'm locating an internal expert in SYSFW/TISCI/Sciclient to help answer your questions.

    Regards,
    Frank

  • Thank you for looking into it.
    Concerning the resource ranges I have to apologize for not reading your example thoroughly as it appears to me now.
    The meaning of those ranges became quite clear once I looked up the defines used in your example.
    What was unclear where the function comments. in drivers/sciclient/include/tisci/rm/tisci_rm_core.h, line 58ff.

    What is left, as far as I see it is:

    1. I still need to find out how to check if an IR output is still free.
    As far as I can see it, that can be done using Sciclient_rmIrOutpIsFree, which is sadly not exposed in a public header though,
    only available locally within drivers/sciclient/sciclient_rm_irq.c.
    And, as far as I can see is embedded only in parameter validation functions. Maybe I am missing something here, or there is a different way to find out if a mapping to an IR output is still available (free).

    2. As I said above, I would like a way for the user to be able to provide the source index as a property of the source peripheral independant of the use of an IR.

    I guess those are the most important points. And we could close this topic afterwards.
    Thank you for your time and trouble.


    Best regards

    Philip.

  • Hi Philip,

    I've located internal software experts, and we're looking into these last items. Thanks for your patience.

    There were some mistakes in the comments I had in the example code I shared earlier. I've fixed the comments and shared the updated code below.

    Regards,
    Frank

    2781.gpio_input_interrupt.c
    /*
     *  Copyright (C) 2021 Texas Instruments Incorporated
     *
     *  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.
     */
    
    #include <kernel/dpl/DebugP.h>
    #include <kernel/dpl/ClockP.h>
    #include <kernel/dpl/AddrTranslateP.h>
    #include <kernel/dpl/HwiP.h>
    #include "ti_drivers_config.h"
    #include "ti_drivers_open_close.h"
    #include "ti_board_open_close.h"
    
    #include <drivers/sciclient.h> // FL
    #define TISCI_BANK_SRC_IDX_BASE_GPIO1       (90U)
    
    /*
     * This example configures a GPIO pin in input mode
     * and configures it to generate interrupt on rising edge.
     * The application waits for 5 key presses, prints the
     * number of times the keys are pressed and exits.
     */
    
    uint32_t            gGpioBaseAddr = GPIO_PUSH_BUTTON_BASE_ADDR;
    HwiP_Object         gGpioHwiObject;
    volatile uint32_t   gGpioIntrDone = 0;
    
    static void GPIO_bankIsrFxn(void *args);
    
    extern void Board_gpioInit(void);
    extern void Board_gpioDeinit(void);
    extern uint32_t Board_getGpioButtonIntrNum(void);
    extern uint32_t Board_getGpioButtonSwitchNum(void);
    
    static void Sciclient_test(void); // FL
    
    void gpio_input_interrupt_main(void *args)
    {
        int32_t         retVal;
        uint32_t        pinNum, intrNum;
        uint32_t        bankNum, waitCount = 5;
        HwiP_Params     hwiPrms;
    
        /* Open drivers to open the UART driver for console */
        Drivers_open();
        Board_driversOpen();
        //Board_gpioInit();
    
        Sciclient_test();
    
        DebugP_log("GPIO Input Interrupt Test Started ...\r\n");
        DebugP_log("GPIO Interrupt Configured for Rising Edge (Button release will trigger interrupt) ...\r\n");
    
        pinNum          = GPIO_PUSH_BUTTON_PIN;
        intrNum         = Board_getGpioButtonIntrNum();
        bankNum         = GPIO_GET_BANK_INDEX(pinNum);
    
        /* Address translate */
        gGpioBaseAddr = (uint32_t) AddrTranslateP_getLocalAddr(gGpioBaseAddr);
    
        /* Setup GPIO for interrupt generation */
        GPIO_setDirMode(gGpioBaseAddr, pinNum, GPIO_PUSH_BUTTON_DIR);
        GPIO_setTrigType(gGpioBaseAddr, pinNum, GPIO_PUSH_BUTTON_TRIG_TYPE);
        GPIO_bankIntrEnable(gGpioBaseAddr, bankNum);
    
        /* Register pin interrupt */
        HwiP_Params_init(&hwiPrms);
        hwiPrms.intNum   = intrNum;
        hwiPrms.callback = &GPIO_bankIsrFxn;
        hwiPrms.args     = (void *) pinNum;
        retVal = HwiP_construct(&gGpioHwiObject, &hwiPrms);
        DebugP_assert(retVal == SystemP_SUCCESS );
    
        DebugP_log("Press and release SW%d button on EVM to trigger GPIO interrupt ...\r\n", Board_getGpioButtonSwitchNum());
        while(gGpioIntrDone < waitCount)
        {
            /* Keep printing the current GPIO value */
            DebugP_log("Key is pressed %d times\r\n", gGpioIntrDone);
            ClockP_sleep(1);
        }
        DebugP_log("Key is pressed %d times\r\n", gGpioIntrDone);
    
        /* Unregister interrupt */
        GPIO_bankIntrDisable(gGpioBaseAddr, bankNum);
        GPIO_setTrigType(gGpioBaseAddr, pinNum, GPIO_TRIG_TYPE_NONE);
        GPIO_clearIntrStatus(gGpioBaseAddr, pinNum);
        HwiP_destruct(&gGpioHwiObject);
    
        DebugP_log("GPIO Input Interrupt Test Passed!!\r\n");
        DebugP_log("All tests have passed!!\r\n");
    
        Board_gpioDeinit();
        Board_driversClose();
        Drivers_close();
    }
    
    static void GPIO_bankIsrFxn(void *args)
    {
        uint32_t    pinNum = (uint32_t) args;
        uint32_t    bankNum =  GPIO_GET_BANK_INDEX(pinNum);
        uint32_t    intrStatus, pinMask = GPIO_GET_BANK_BIT_MASK(pinNum);
    
        /* Get and clear bank interrupt status */
        intrStatus = GPIO_getBankIntrStatus(gGpioBaseAddr, bankNum);
        GPIO_clearBankIntrStatus(gGpioBaseAddr, bankNum, intrStatus);
    
        /* Per pin interrupt handling */
        if(intrStatus & pinMask)
        {
            gGpioIntrDone++;
        }
    }
    
    // FL: sciclient tests
    #if 0
    static void Sciclient_test(void)
    {
        int32_t                             retVal;
        struct tisci_msg_rm_irq_set_req     rmIrqReq;
        struct tisci_msg_rm_irq_set_resp    rmIrqResp;
    
        rmIrqReq.valid_params           = 0U;
        rmIrqReq.valid_params          |= TISCI_MSG_VALUE_RM_DST_ID_VALID;
        rmIrqReq.valid_params          |= TISCI_MSG_VALUE_RM_DST_HOST_IRQ_VALID;
        rmIrqReq.global_event           = 0U;
        // FL: https://software-dl.ti.com/tisci/esd/latest/5_soc_doc/am64x/devices.html, AM64X_DEV_GPIO1
        rmIrqReq.src_id                 = TISCI_DEV_GPIO1;
        // FL: <SDK>\source\drivers\sciclient\soc\am64x_am243x\sciclient_irq_rm.c, GPIO1_gpio_bank_90_98_to_MAIN_GPIOMUX_INTROUTER0_in_180_188
        rmIrqReq.src_index              = TISCI_BANK_SRC_IDX_BASE_GPIO1 + GPIO_GET_BANK_INDEX(GPIO_PUSH_BUTTON_PIN);
        // FL: https://software-dl.ti.com/tisci/esd/latest/5_soc_doc/am64x/devices.html, AM64X_DEV_R5FSS0_CORE0
        rmIrqReq.dst_id                 = TISCI_DEV_R5FSS0_CORE0;
        // FL: VIM IRQ number (TRM)
        rmIrqReq.dst_host_irq           = Board_getGpioButtonIntrNum();
        rmIrqReq.ia_id                  = 0U;
        rmIrqReq.vint                   = 0U;
        rmIrqReq.vint_status_bit_index  = 0U;
        rmIrqReq.secondary_host         = TISCI_MSG_VALUE_RM_UNUSED_SECONDARY_HOST;
    
        retVal = Sciclient_rmIrqSet(&rmIrqReq, &rmIrqResp, SystemP_WAIT_FOREVER);
        if(0 != retVal)
        {
            DebugP_log("[Error] Sciclient event config failed!!!\r\n");
            DebugP_assert(FALSE);
        }
    
        return;
    }    
    #endif
    #if 1
    static void Sciclient_test(void)
    {
        int32_t                             retVal;
        struct tisci_msg_rm_irq_set_req     rmIrqReq;
        struct tisci_msg_rm_irq_set_resp    rmIrqResp;
    
        rmIrqReq.valid_params           = 0U;
        rmIrqReq.valid_params          |= TISCI_MSG_VALUE_RM_DST_ID_VALID;
        rmIrqReq.valid_params          |= TISCI_MSG_VALUE_RM_DST_HOST_IRQ_VALID;
        rmIrqReq.global_event           = 0U;
        // FL: https://software-dl.ti.com/tisci/esd/latest/5_soc_doc/am64x/devices.html, AM64X_DEV_MAIN_GPIOMUX_INTROUTER0
        rmIrqReq.src_id                 = TISCI_DEV_MAIN_GPIOMUX_INTROUTER0;
        // FL: GPIO interrupt router input (TRM)
        rmIrqReq.src_index              = 182;
        // FL: https://software-dl.ti.com/tisci/esd/latest/5_soc_doc/am64x/devices.html, AM64X_DEV_MAIN_GPIOMUX_INTROUTER0
        rmIrqReq.dst_id                 = TISCI_DEV_MAIN_GPIOMUX_INTROUTER0;
        // FL: GPIO interrupt router output (TRM)
        rmIrqReq.dst_host_irq           = 8;
        rmIrqReq.ia_id                  = 0U;
        rmIrqReq.vint                   = 0U;
        rmIrqReq.vint_status_bit_index  = 0U;
        rmIrqReq.secondary_host         = TISCI_MSG_VALUE_RM_UNUSED_SECONDARY_HOST;
    
        retVal = Sciclient_rmIrqSetRaw(&rmIrqReq, &rmIrqResp, SystemP_WAIT_FOREVER);
        if(0 != retVal)
        {
            DebugP_log("[Error] Sciclient event config failed!!!\r\n");
            DebugP_assert(FALSE);
        }
    
        return;   
    }
    #endif
    #if 0
    static void Sciclient_test(void)
    {
        struct tisci_msg_rm_get_resource_range_req  rmGetRsrcRngReq;
        struct tisci_msg_rm_get_resource_range_resp rmGetRsrcRngResp;
        struct tisci_msg_rm_irq_set_req rmIrqSetReq;
        struct tisci_msg_rm_irq_set_resp rmIrqSetResp;
        uint16_t dstInput;    
        int32_t retVal;
    
        /* Get interrupt router output number range assigned to Host */
        // FL: https://software-dl.ti.com/tisci/esd/latest/5_soc_doc/am64x/devices.html, AM64X_DEV_MAIN_GPIOMUX_INTROUTER0
        rmGetRsrcRngReq.type = TISCI_DEV_MAIN_GPIOMUX_INTROUTER0;
        rmGetRsrcRngReq.subtype = TISCI_RESASG_SUBTYPE_IR_OUTPUT;
        // FL: https://software-dl.ti.com/tisci/esd/latest/5_soc_doc/am64x/hosts.html, MAIN_0_R5_1
        rmGetRsrcRngReq.secondary_host = TISCI_HOST_ID_MAIN_0_R5_1;
        retVal = Sciclient_rmGetResourceRange(&rmGetRsrcRngReq, &rmGetRsrcRngResp, SystemP_WAIT_FOREVER);
        if ((retVal != 0) && (rmGetRsrcRngResp.range_num == 0))
        {
            /* No range assigned to Host, try with HOST_ID_ALL */
            rmGetRsrcRngReq.secondary_host = TISCI_HOST_ID_ALL;
    
            retVal = Sciclient_rmGetResourceRange(
                     &rmGetRsrcRngReq,
                     &rmGetRsrcRngResp,
                     SystemP_WAIT_FOREVER);
        }
        
        if (retVal == 0)
        {
            /* Translate interrupt router output to interrupt controller input to which it's connected */
            // FL: https://software-dl.ti.com/tisci/esd/latest/5_soc_doc/am64x/devices.html, AM64X_DEV_MAIN_GPIOMUX_INTROUTER0
            // FL: https://software-dl.ti.com/tisci/esd/latest/5_soc_doc/am64x/devices.html, AM64X_DEV_R5FSS0_CORE0
            retVal = Sciclient_rmIrqTranslateIrOutput(TISCI_DEV_MAIN_GPIOMUX_INTROUTER0,
                rmGetRsrcRngResp.range_start, TISCI_DEV_R5FSS0_CORE0, &dstInput);
            
            if (retVal == 0)
            {
                // FL: https://software-dl.ti.com/tisci/esd/latest/5_soc_doc/am64x/devices.html, AM64X_DEV_R5FSS0_CORE0
                rmIrqSetReq.dst_id = TISCI_DEV_R5FSS0_CORE0;
                // FL: https://software-dl.ti.com/tisci/esd/latest/5_soc_doc/am64x/hosts.html, MAIN_0_R5_1
                rmIrqSetReq.secondary_host = TISCI_HOST_ID_MAIN_0_R5_1;
            
                rmIrqSetReq.ia_id                   = 0U;
                rmIrqSetReq.vint                    = 0U;
                rmIrqSetReq.global_event            = 0U;
                rmIrqSetReq.vint_status_bit_index   = 0U;
                rmIrqSetReq.valid_params            = TISCI_MSG_VALUE_RM_DST_ID_VALID
                                                      | TISCI_MSG_VALUE_RM_DST_HOST_IRQ_VALID
                                                      | TISCI_MSG_VALUE_RM_SECONDARY_HOST_VALID;
                                                      
                // FL: https://software-dl.ti.com/tisci/esd/latest/5_soc_doc/am64x/devices.html, AM64X_DEV_GPIO1
                rmIrqSetReq.src_id = TISCI_DEV_GPIO1;
                // FL: <SDK>\source\drivers\sciclient\soc\am64x_am243x\sciclient_irq_rm.c, GPIO1_gpio_bank_90_98_to_MAIN_GPIOMUX_INTROUTER0_in_180_188
                rmIrqSetReq.src_index = TISCI_BANK_SRC_IDX_BASE_GPIO1 + GPIO_GET_BANK_INDEX(GPIO_PUSH_BUTTON_PIN);
                // FL: VIM IRQ number (TRM)
                rmIrqSetReq.dst_host_irq = dstInput;
    
                /* Configure interrupt route between peripheral and Host */
                retVal = Sciclient_rmIrqSet(&rmIrqSetReq, &rmIrqSetResp, SystemP_WAIT_FOREVER);
                
            }
        }
    }
    #endif
    #if 0
    static void Sciclient_test(void)
    {
        uint16_t srcOutput;
        
        Sciclient_rmIrqTranslateIrqInput(TISCI_DEV_R5FSS0_CORE0, 
            40, 
            TISCI_DEV_MAIN_GPIOMUX_INTROUTER0, 
            &srcOutput);
    }
    #endif
    
    

  • Hi Philip,

    1. I still need to find out how to check if an IR output is still free.

    I agree with your assessment, and I don't see any exposed API function for checking whether an IR route is free.

    I experimented with trying to set the same IR route more than once using Sciclient_rmIrqSet(). As expected, attempting to set a route which is already set fails.

    I also tried releasing a route with Sciclient_rmIrqRelease(), and then setting the route again with Sciclient_rmIrqSet(). This also works as expected.

    I've shared my updated experimental code below. Please see the section of the code with the comment, "test programming same route more than once, test route release and reprogram".

    I think the proper way to handle this is to use Sciclient_rmGetResourceRange(). Sciclient_rmGetResourceRange() returns range_start and range_num, which your application can track. Also, your application code won't need to have prior knowledge about the static RM information in the Sciclient library.

    It seems like it would be a useful to have a function for checking whether a route is free. I'll share this feedback with the SDK team.


    2. As I said above, I would like a way for the user to be able to provide the source index as a property of the source peripheral independant of the use of an IR.

    I know you've probably described this before, but can you elaborate a little on this point? Are you requesting a change to the Sciclient API?

    It seems like your abstraction code will need to have private information about which source peripherals have interrupts connected through an interrupt router. The abstraction layer can then use whichever source indices you choose. In other words, this is a question of how you decide to design your abstraction layer.

    Regards,
    Frank

    1325.gpio_input_interrupt.c
    /*
     *  Copyright (C) 2021 Texas Instruments Incorporated
     *
     *  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.
     */
    
    #include <kernel/dpl/DebugP.h>
    #include <kernel/dpl/ClockP.h>
    #include <kernel/dpl/AddrTranslateP.h>
    #include <kernel/dpl/HwiP.h>
    #include "ti_drivers_config.h"
    #include "ti_drivers_open_close.h"
    #include "ti_board_open_close.h"
    
    #include <drivers/sciclient.h> // FL
    #define TISCI_BANK_SRC_IDX_BASE_GPIO1       (90U)
    
    /*
     * This example configures a GPIO pin in input mode
     * and configures it to generate interrupt on rising edge.
     * The application waits for 5 key presses, prints the
     * number of times the keys are pressed and exits.
     */
    
    uint32_t            gGpioBaseAddr = GPIO_PUSH_BUTTON_BASE_ADDR;
    HwiP_Object         gGpioHwiObject;
    volatile uint32_t   gGpioIntrDone = 0;
    
    static void GPIO_bankIsrFxn(void *args);
    
    extern void Board_gpioInit(void);
    extern void Board_gpioDeinit(void);
    extern uint32_t Board_getGpioButtonIntrNum(void);
    extern uint32_t Board_getGpioButtonSwitchNum(void);
    
    static void Sciclient_test(void); // FL
    
    void gpio_input_interrupt_main(void *args)
    {
        int32_t         retVal;
        uint32_t        pinNum, intrNum;
        uint32_t        bankNum, waitCount = 5;
        HwiP_Params     hwiPrms;
    
        /* Open drivers to open the UART driver for console */
        Drivers_open();
        Board_driversOpen();
        //Board_gpioInit();
    
        Sciclient_test();
    
        DebugP_log("GPIO Input Interrupt Test Started ...\r\n");
        DebugP_log("GPIO Interrupt Configured for Rising Edge (Button release will trigger interrupt) ...\r\n");
    
        pinNum          = GPIO_PUSH_BUTTON_PIN;
        intrNum         = Board_getGpioButtonIntrNum();
        bankNum         = GPIO_GET_BANK_INDEX(pinNum);
    
        /* Address translate */
        gGpioBaseAddr = (uint32_t) AddrTranslateP_getLocalAddr(gGpioBaseAddr);
    
        /* Setup GPIO for interrupt generation */
        GPIO_setDirMode(gGpioBaseAddr, pinNum, GPIO_PUSH_BUTTON_DIR);
        GPIO_setTrigType(gGpioBaseAddr, pinNum, GPIO_PUSH_BUTTON_TRIG_TYPE);
        GPIO_bankIntrEnable(gGpioBaseAddr, bankNum);
    
        /* Register pin interrupt */
        HwiP_Params_init(&hwiPrms);
        hwiPrms.intNum   = intrNum;
        hwiPrms.callback = &GPIO_bankIsrFxn;
        hwiPrms.args     = (void *) pinNum;
        retVal = HwiP_construct(&gGpioHwiObject, &hwiPrms);
        DebugP_assert(retVal == SystemP_SUCCESS );
    
        DebugP_log("Press and release SW%d button on EVM to trigger GPIO interrupt ...\r\n", Board_getGpioButtonSwitchNum());
        while(gGpioIntrDone < waitCount)
        {
            /* Keep printing the current GPIO value */
            DebugP_log("Key is pressed %d times\r\n", gGpioIntrDone);
            ClockP_sleep(1);
        }
        DebugP_log("Key is pressed %d times\r\n", gGpioIntrDone);
    
        /* Unregister interrupt */
        GPIO_bankIntrDisable(gGpioBaseAddr, bankNum);
        GPIO_setTrigType(gGpioBaseAddr, pinNum, GPIO_TRIG_TYPE_NONE);
        GPIO_clearIntrStatus(gGpioBaseAddr, pinNum);
        HwiP_destruct(&gGpioHwiObject);
    
        DebugP_log("GPIO Input Interrupt Test Passed!!\r\n");
        DebugP_log("All tests have passed!!\r\n");
    
        Board_gpioDeinit();
        Board_driversClose();
        Drivers_close();
    }
    
    static void GPIO_bankIsrFxn(void *args)
    {
        uint32_t    pinNum = (uint32_t) args;
        uint32_t    bankNum =  GPIO_GET_BANK_INDEX(pinNum);
        uint32_t    intrStatus, pinMask = GPIO_GET_BANK_BIT_MASK(pinNum);
    
        /* Get and clear bank interrupt status */
        intrStatus = GPIO_getBankIntrStatus(gGpioBaseAddr, bankNum);
        GPIO_clearBankIntrStatus(gGpioBaseAddr, bankNum, intrStatus);
    
        /* Per pin interrupt handling */
        if(intrStatus & pinMask)
        {
            gGpioIntrDone++;
        }
    }
    
    // FL: sciclient tests
    #if 0 // test Sciclient_rmIrqSet()
    static void Sciclient_test(void)
    {
        int32_t                             retVal;
        struct tisci_msg_rm_irq_set_req     rmIrqReq;
        struct tisci_msg_rm_irq_set_resp    rmIrqResp;
    
        rmIrqReq.valid_params           = 0U;
        rmIrqReq.valid_params          |= TISCI_MSG_VALUE_RM_DST_ID_VALID;
        rmIrqReq.valid_params          |= TISCI_MSG_VALUE_RM_DST_HOST_IRQ_VALID;
        rmIrqReq.global_event           = 0U;
        // FL: https://software-dl.ti.com/tisci/esd/latest/5_soc_doc/am64x/devices.html, AM64X_DEV_GPIO1
        rmIrqReq.src_id                 = TISCI_DEV_GPIO1;
        // FL: <SDK>\source\drivers\sciclient\soc\am64x_am243x\sciclient_irq_rm.c, GPIO1_gpio_bank_90_98_to_MAIN_GPIOMUX_INTROUTER0_in_180_188
        rmIrqReq.src_index              = TISCI_BANK_SRC_IDX_BASE_GPIO1 + GPIO_GET_BANK_INDEX(GPIO_PUSH_BUTTON_PIN);
        // FL: https://software-dl.ti.com/tisci/esd/latest/5_soc_doc/am64x/devices.html, AM64X_DEV_R5FSS0_CORE0
        rmIrqReq.dst_id                 = TISCI_DEV_R5FSS0_CORE0;
        // FL: VIM IRQ number (TRM)
        rmIrqReq.dst_host_irq           = Board_getGpioButtonIntrNum();
        rmIrqReq.ia_id                  = 0U;
        rmIrqReq.vint                   = 0U;
        rmIrqReq.vint_status_bit_index  = 0U;
        rmIrqReq.secondary_host         = TISCI_MSG_VALUE_RM_UNUSED_SECONDARY_HOST;
    
        retVal = Sciclient_rmIrqSet(&rmIrqReq, &rmIrqResp, SystemP_WAIT_FOREVER);
        if(0 != retVal)
        {
            DebugP_log("[Error] Sciclient event config failed!!!\r\n");
            DebugP_assert(FALSE);
        }
    
        return;
    }    
    #endif
    #if 0 // test Sciclient_rmIrqSetRaw()
    static void Sciclient_test(void)
    {
        int32_t                             retVal;
        struct tisci_msg_rm_irq_set_req     rmIrqReq;
        struct tisci_msg_rm_irq_set_resp    rmIrqResp;
    
        rmIrqReq.valid_params           = 0U;
        rmIrqReq.valid_params          |= TISCI_MSG_VALUE_RM_DST_ID_VALID;
        rmIrqReq.valid_params          |= TISCI_MSG_VALUE_RM_DST_HOST_IRQ_VALID;
        rmIrqReq.global_event           = 0U;
        // FL: https://software-dl.ti.com/tisci/esd/latest/5_soc_doc/am64x/devices.html, AM64X_DEV_MAIN_GPIOMUX_INTROUTER0
        rmIrqReq.src_id                 = TISCI_DEV_MAIN_GPIOMUX_INTROUTER0;
        // FL: GPIO interrupt router input (TRM)
        rmIrqReq.src_index              = 182;
        // FL: https://software-dl.ti.com/tisci/esd/latest/5_soc_doc/am64x/devices.html, AM64X_DEV_MAIN_GPIOMUX_INTROUTER0
        rmIrqReq.dst_id                 = TISCI_DEV_MAIN_GPIOMUX_INTROUTER0;
        // FL: GPIO interrupt router output (TRM)
        rmIrqReq.dst_host_irq           = 8;
        rmIrqReq.ia_id                  = 0U;
        rmIrqReq.vint                   = 0U;
        rmIrqReq.vint_status_bit_index  = 0U;
        rmIrqReq.secondary_host         = TISCI_MSG_VALUE_RM_UNUSED_SECONDARY_HOST;
    
        retVal = Sciclient_rmIrqSetRaw(&rmIrqReq, &rmIrqResp, SystemP_WAIT_FOREVER);
        if(0 != retVal)
        {
            DebugP_log("[Error] Sciclient event config failed!!!\r\n");
            DebugP_assert(FALSE);
        }
    
        return;   
    }
    #endif
    #if 0 // test Sciclient_rmGetResourceRange(), Sciclient_rmIrqTranslateIrOutput(), Sciclient_rmIrqSet()
    static void Sciclient_test(void)
    {
        struct tisci_msg_rm_get_resource_range_req  rmGetRsrcRngReq;
        struct tisci_msg_rm_get_resource_range_resp rmGetRsrcRngResp;
        struct tisci_msg_rm_irq_set_req rmIrqSetReq;
        struct tisci_msg_rm_irq_set_resp rmIrqSetResp;
        uint16_t dstInput;    
        int32_t retVal;
    
        /* Get interrupt router output number range assigned to Host */
        // FL: https://software-dl.ti.com/tisci/esd/latest/5_soc_doc/am64x/devices.html, AM64X_DEV_MAIN_GPIOMUX_INTROUTER0
        rmGetRsrcRngReq.type = TISCI_DEV_MAIN_GPIOMUX_INTROUTER0;
        rmGetRsrcRngReq.subtype = TISCI_RESASG_SUBTYPE_IR_OUTPUT;
        // FL: https://software-dl.ti.com/tisci/esd/latest/5_soc_doc/am64x/hosts.html, MAIN_0_R5_1
        rmGetRsrcRngReq.secondary_host = TISCI_HOST_ID_MAIN_0_R5_1;
        retVal = Sciclient_rmGetResourceRange(&rmGetRsrcRngReq, &rmGetRsrcRngResp, SystemP_WAIT_FOREVER);
        if ((retVal != 0) && (rmGetRsrcRngResp.range_num == 0))
        {
            /* No range assigned to Host, try with HOST_ID_ALL */
            rmGetRsrcRngReq.secondary_host = TISCI_HOST_ID_ALL;
    
            retVal = Sciclient_rmGetResourceRange(
                     &rmGetRsrcRngReq,
                     &rmGetRsrcRngResp,
                     SystemP_WAIT_FOREVER);
        }
        
        if (retVal == 0)
        {
            /* Translate interrupt router output to interrupt controller input to which it's connected */
            // FL: https://software-dl.ti.com/tisci/esd/latest/5_soc_doc/am64x/devices.html, AM64X_DEV_MAIN_GPIOMUX_INTROUTER0
            // FL: https://software-dl.ti.com/tisci/esd/latest/5_soc_doc/am64x/devices.html, AM64X_DEV_R5FSS0_CORE0
            retVal = Sciclient_rmIrqTranslateIrOutput(TISCI_DEV_MAIN_GPIOMUX_INTROUTER0,
                rmGetRsrcRngResp.range_start, TISCI_DEV_R5FSS0_CORE0, &dstInput);
            
            if (retVal == 0)
            {
                // FL: https://software-dl.ti.com/tisci/esd/latest/5_soc_doc/am64x/devices.html, AM64X_DEV_R5FSS0_CORE0
                rmIrqSetReq.dst_id = TISCI_DEV_R5FSS0_CORE0;
                // FL: https://software-dl.ti.com/tisci/esd/latest/5_soc_doc/am64x/hosts.html, MAIN_0_R5_1
                rmIrqSetReq.secondary_host = TISCI_HOST_ID_MAIN_0_R5_1;
            
                rmIrqSetReq.ia_id                   = 0U;
                rmIrqSetReq.vint                    = 0U;
                rmIrqSetReq.global_event            = 0U;
                rmIrqSetReq.vint_status_bit_index   = 0U;
                rmIrqSetReq.valid_params            = TISCI_MSG_VALUE_RM_DST_ID_VALID
                                                      | TISCI_MSG_VALUE_RM_DST_HOST_IRQ_VALID
                                                      | TISCI_MSG_VALUE_RM_SECONDARY_HOST_VALID;
                                                      
                // FL: https://software-dl.ti.com/tisci/esd/latest/5_soc_doc/am64x/devices.html, AM64X_DEV_GPIO1
                rmIrqSetReq.src_id = TISCI_DEV_GPIO1;
                // FL: <SDK>\source\drivers\sciclient\soc\am64x_am243x\sciclient_irq_rm.c, GPIO1_gpio_bank_90_98_to_MAIN_GPIOMUX_INTROUTER0_in_180_188
                rmIrqSetReq.src_index = TISCI_BANK_SRC_IDX_BASE_GPIO1 + GPIO_GET_BANK_INDEX(GPIO_PUSH_BUTTON_PIN);
                // FL: VIM IRQ number (TRM)
                rmIrqSetReq.dst_host_irq = dstInput;
    
                /* Configure interrupt route between peripheral and Host */
                retVal = Sciclient_rmIrqSet(&rmIrqSetReq, &rmIrqSetResp, SystemP_WAIT_FOREVER);
                
            }
        }
    }
    #endif
    #if 0 // test  Sciclient_rmIrqTranslateIrqInput()
    static void Sciclient_test(void)
    {
        uint16_t srcOutput;
        
        Sciclient_rmIrqTranslateIrqInput(TISCI_DEV_R5FSS0_CORE0, 
            40, 
            TISCI_DEV_MAIN_GPIOMUX_INTROUTER0, 
            &srcOutput);
    }
    #endif
    #if 1 // test programming same route more than once, test route release and reprogram
    static void Sciclient_test(void)
    {
        struct tisci_msg_rm_get_resource_range_req  rmGetRsrcRngReq;
        struct tisci_msg_rm_get_resource_range_resp rmGetRsrcRngResp;
        struct tisci_msg_rm_irq_set_req rmIrqSetReq;
        struct tisci_msg_rm_irq_set_resp rmIrqSetResp;
        struct tisci_msg_rm_irq_release_req rmIrqRelReq;
        uint16_t dstInput;    
        int32_t retVal;
    
        /* Get interrupt router output number range assigned to Host */
        // FL: https://software-dl.ti.com/tisci/esd/latest/5_soc_doc/am64x/devices.html, AM64X_DEV_MAIN_GPIOMUX_INTROUTER0
        rmGetRsrcRngReq.type = TISCI_DEV_MAIN_GPIOMUX_INTROUTER0;
        rmGetRsrcRngReq.subtype = TISCI_RESASG_SUBTYPE_IR_OUTPUT;
        // FL: https://software-dl.ti.com/tisci/esd/latest/5_soc_doc/am64x/hosts.html, MAIN_0_R5_1
        rmGetRsrcRngReq.secondary_host = TISCI_HOST_ID_MAIN_0_R5_1;
        retVal = Sciclient_rmGetResourceRange(&rmGetRsrcRngReq, &rmGetRsrcRngResp, SystemP_WAIT_FOREVER);
        if ((retVal != 0) && (rmGetRsrcRngResp.range_num == 0))
        {
            /* No range assigned to Host, try with HOST_ID_ALL */
            rmGetRsrcRngReq.secondary_host = TISCI_HOST_ID_ALL;
    
            retVal = Sciclient_rmGetResourceRange(
                     &rmGetRsrcRngReq,
                     &rmGetRsrcRngResp,
                     SystemP_WAIT_FOREVER);
        }
        
        if (retVal == 0)
        {
            /* Translate interrupt router output to interrupt controller input to which it's connected */
            // FL: https://software-dl.ti.com/tisci/esd/latest/5_soc_doc/am64x/devices.html, AM64X_DEV_MAIN_GPIOMUX_INTROUTER0
            // FL: https://software-dl.ti.com/tisci/esd/latest/5_soc_doc/am64x/devices.html, AM64X_DEV_R5FSS0_CORE0
            retVal = Sciclient_rmIrqTranslateIrOutput(TISCI_DEV_MAIN_GPIOMUX_INTROUTER0,
                rmGetRsrcRngResp.range_start, TISCI_DEV_R5FSS0_CORE0, &dstInput);
            
            if (retVal == 0)
            {
                // FL: https://software-dl.ti.com/tisci/esd/latest/5_soc_doc/am64x/devices.html, AM64X_DEV_R5FSS0_CORE0
                rmIrqSetReq.dst_id = TISCI_DEV_R5FSS0_CORE0;
                // FL: https://software-dl.ti.com/tisci/esd/latest/5_soc_doc/am64x/hosts.html, MAIN_0_R5_1
                rmIrqSetReq.secondary_host = TISCI_HOST_ID_MAIN_0_R5_1;
            
                rmIrqSetReq.ia_id                   = 0U;
                rmIrqSetReq.vint                    = 0U;
                rmIrqSetReq.global_event            = 0U;
                rmIrqSetReq.vint_status_bit_index   = 0U;
                rmIrqSetReq.valid_params            = TISCI_MSG_VALUE_RM_DST_ID_VALID
                                                      | TISCI_MSG_VALUE_RM_DST_HOST_IRQ_VALID
                                                      | TISCI_MSG_VALUE_RM_SECONDARY_HOST_VALID;
                                                      
                // FL: https://software-dl.ti.com/tisci/esd/latest/5_soc_doc/am64x/devices.html, AM64X_DEV_GPIO1
                rmIrqSetReq.src_id = TISCI_DEV_GPIO1;
                // FL: <SDK>\source\drivers\sciclient\soc\am64x_am243x\sciclient_irq_rm.c, GPIO1_gpio_bank_90_98_to_MAIN_GPIOMUX_INTROUTER0_in_180_188
                rmIrqSetReq.src_index = TISCI_BANK_SRC_IDX_BASE_GPIO1 + GPIO_GET_BANK_INDEX(GPIO_PUSH_BUTTON_PIN);
                // FL: VIM IRQ number (TRM)
                rmIrqSetReq.dst_host_irq = dstInput;
    
                // FL: set route -- PASS
                /* Configure interrupt route between peripheral and Host */
                retVal = Sciclient_rmIrqSet(&rmIrqSetReq, &rmIrqSetResp, SystemP_WAIT_FOREVER);
    
                // FL: try to set route again -- FAIL
                /* Configure interrupt route between peripheral and Host */
                retVal = Sciclient_rmIrqSet(&rmIrqSetReq, &rmIrqSetResp, SystemP_WAIT_FOREVER);
            }
            
            // FL: Get destination IRQ for next IR output
            retVal = Sciclient_rmIrqTranslateIrOutput(TISCI_DEV_MAIN_GPIOMUX_INTROUTER0,
                rmGetRsrcRngResp.range_start+1, TISCI_DEV_R5FSS0_CORE0, &dstInput);
    
            rmIrqSetReq.ia_id                   = 0U;
            rmIrqSetReq.vint                    = 0U;
            rmIrqSetReq.global_event            = 0U;
            rmIrqSetReq.vint_status_bit_index   = 0U;
            rmIrqSetReq.valid_params            = TISCI_MSG_VALUE_RM_DST_ID_VALID
                                                  | TISCI_MSG_VALUE_RM_DST_HOST_IRQ_VALID
                                                  | TISCI_MSG_VALUE_RM_SECONDARY_HOST_VALID;
            rmIrqSetReq.src_id = TISCI_DEV_GPIO1;
            rmIrqSetReq.src_index = TISCI_BANK_SRC_IDX_BASE_GPIO1 + GPIO_GET_BANK_INDEX(GPIO_PUSH_BUTTON_PIN) + 1; // FL: next GPIO1 source interrupt
            rmIrqSetReq.dst_id = TISCI_DEV_R5FSS0_CORE0;
            rmIrqSetReq.dst_host_irq = dstInput;
            rmIrqSetReq.secondary_host = TISCI_HOST_ID_MAIN_0_R5_1;
    
            // FL: set next route -- PASS
            retVal = Sciclient_rmIrqSet(&rmIrqSetReq, &rmIrqSetResp, SystemP_WAIT_FOREVER);
            
            // FL: try to set next route again -- FAIL
            retVal = Sciclient_rmIrqSet(&rmIrqSetReq, &rmIrqSetResp, SystemP_WAIT_FOREVER);
            
            // FL: release route
            rmIrqRelReq.ia_id                   = 0U;
            rmIrqRelReq.vint                    = 0U;
            rmIrqRelReq.global_event            = 0U;
            rmIrqRelReq.vint_status_bit_index   = 0U;
            rmIrqRelReq.valid_params            = TISCI_MSG_VALUE_RM_DST_ID_VALID
                                                  | TISCI_MSG_VALUE_RM_DST_HOST_IRQ_VALID
                                                  | TISCI_MSG_VALUE_RM_SECONDARY_HOST_VALID;
            rmIrqRelReq.src_id = TISCI_DEV_GPIO1;
            rmIrqRelReq.src_index = TISCI_BANK_SRC_IDX_BASE_GPIO1 + GPIO_GET_BANK_INDEX(GPIO_PUSH_BUTTON_PIN) + 1;
            rmIrqRelReq.dst_id = TISCI_DEV_R5FSS0_CORE0;
            rmIrqRelReq.dst_host_irq = dstInput;
            rmIrqRelReq.secondary_host = TISCI_HOST_ID_MAIN_0_R5_1;
            retVal = Sciclient_rmIrqRelease(&rmIrqRelReq, SystemP_WAIT_FOREVER);
            
            // FL: try to set next route again -- PASS
            retVal = Sciclient_rmIrqSet(&rmIrqSetReq, &rmIrqSetResp, SystemP_WAIT_FOREVER);
        }
    }
    #endif
    
    

  • Hello Frank,

    1. I don't think the SDK needs a new function for finding out which routes are still free. For me, it would be perfectly fine, if you could decide for a public header (not one of the priv-headers) where to expose Sciclient_rmIrOutpIsFree.
    For the time being I will write my own function on top of the SDK.


    2. Let me explain again, what I would like to have concerning the Device-IDs, Host-IDs and index numbers.
    Below see a simplified sketch of how I imagine the numbering to work.

    As far as I understand it currently the board is divided into logical subsystems.
    I just put in a few, since this is only an example (also it does not matter if all the numbers are correctly corresponding to the tables in TRM, documentation or datasheet. Let us please not get pedantic about that).
    I didn't put the INTR into any subsystem, as I wasn't sure in which one it resides.

    Every subsystem is identified by a "Device-ID".
    Inside a subsystem the elements that can be addressed like pins and maybe also other parts are given an index.
    I would denominate that as a peripheral index, for instance.

    Then I have MCUs with Interrupt-Controllers. Those MCUs and Interrupt-Controllers are identified by "Host-IDs".
    For the interrupt router, the peripheral index numbers are divided into input index numbers and output index numbers.

    ********************************************************************************************
    Example:

    So now let's say that I have a GPIO at subsystem MCU_ARMSS, index 6. And I want it to generate an intrrupt with destination of the interrupt-controller with host-ID 42 on input line with index 3.

    Now I want the user of my functions to provide those aformentioned parameters. The user should not be concerned with stuff like if there is an interrupt router used or not. So he should not have to provide intput- our output-index numbers of the interrupt router or interrupt aggregator.

    Additionally, he should not have to provide the hosts input-line. In my understanding I can get the interrupt output-index numbers connected to a host for a specified subtype, which I hope to be able to deduce either from the SoC sbusystem of the source or its purpose within in the subsystem. I am confident that I can calculate that somehow.

    So the user should provide a device-ID for the source (which, I guess, is the src_id in a tsici-irq-message), also a peripheral index (which I guess, is the src_index) and also a host-ID for the destination (I guess that will be dst_id).

    I would like him to have some means like a table, where he can lookup in this example case:

    MCU_ARMSS has device-ID = 119, and within that subsystem, the pin that should generate the interrupt has index number 6.
    Also he should be able to lookup that the host that should be the destination with host-ID = 42.

    The user should not have to know anything about which input or output of an interrupt router is used or which is the device-ID of the used interrupt router.

  • Hi Philip,

    1. I'll consult with the SDK team and see if this is possible, or if there are any reasons for not placing this function in the Sciclient public API.

    Interestingly, I notice Sciclient_rmIrInpIsFree() is what causes the 2nd call to Sciclient_rmIrqSet() to fail in my example program, not Sciclient_rmIrOutpIsFree(). The function checks for dev_id=3 (IR Device ID for AM64X_DEV_MAIN_GPIOMUX_INTROUTER0) and inp=182 (IR Input Index), please see https://software-dl.ti.com/tisci/esd/latest/5_soc_doc/am64x/interrupt_cfg.html#main-gpiomux-introuter0-interrupt-router-input-sources.

    2. Thank you very much for the diagram and detailed response. I think I have a better understanding of what you want. 

    Two key questions for you:

    • Do you think the existing Sciclient API can be used for the Interrupt Abstraction Layer (IAL)?
    • Are you asking for any change to the Sciclient API?

    As I said below, this seems like a question of how you decide to design your IAL. Provided you don't see any gaps in the Sciclient API, I think this should be possible. A few additional comments are below.

    Regards,
    Frank

    Now I want the user of my functions to provide those aformentioned parameters

    The parameters would include the Source Device ID, Source Index (0...M-1, M:number of Source Indices), Destination Host ID, and Destination Index (0...N-1, N:number of Destination Indices).

    The user should not be concerned with stuff like if there is an interrupt router used or not. So he should not have to provide intput- our output-index numbers of the interrupt router or interrupt aggregator.

    IR routes would be hidden from the user and configured inside the IAL. The IAL contains sufficient information about Sciclient/TISCI to handle this using only the provided IAL parameters.

    Additionally, he should not have to provide the hosts input-line.

    Ok, so not even the Destination Index is supplied in the IAL parameters, and the IAL determines the required (absolute) Destination ID using Sciclient.

    As you said, it seems like the IAL will need a table containing details about which Sources are routed through an IR to get to different Destinations. After that, perhaps you could use an approach similar to the one I shared in the example code for configuring the IR route.

  • Hello Frank,
    thank you for getting back to me.

    1. Concerning your testing program.
    I guess you tried the same tisci request 2 times in a row, and it failed at the source?
    If I am correct in assuming that, there is nothing wrong with this.

    What I read from the code is Sciclient_rmIrqSet() calls Sciclient_rmProgramInterruptRoute, and there in sciclient_rm_irq.c,
    line 875 I got the test for the request being a routing request without virtual interrupts (no IA used):

    Sciclient_rmIrqCfgIsDirectNonEvent(cfg.valid_params) == true


    Inside the if-block in line 887, the route is checked with Sciclient_rmIrqFindRoute.
    And inside that in line 1812, the root node of the sources SoC subsystem is fetched.
    And from there on the route is traversed from source to destination,
    starting with the SoC subsystems first index, as far as I understand it.

    So if you try the same request twice, the error will occur directly at the source peripheral node.

    Which is probably what happened to you.

    But I tell you what I want, what I really really want (sorry, couldn't resist :) ).
    My case is that I have multiple interrupt sources all destined for the same destination host.
    And now I want to connect all of them. In that case, I would assume that when the first one is connected by a route,
    and now I try to connect the second one, I wouldn't get an error at the INTRs input index, since I use different sources,
    but I would get an error at the output index as the output is already connected.
    So what I wanted was a means to check if the INTR output is already used.

    2. I don't ask for a change in the sciclient API, and I can absolutely use this as it is.
    What I am asking for is an update of the documentation.
    I would like a table telling about SoC subsystem device IDs and intra subsystem index numbers identifying the pins and other atomic hardware elements within a SoC subsystem. Currently it seems they are only provided in connection to the documentation of the interrupt router or interrupt aggregator.
    I understand them more as a general means to identify atomic hardware parts inside my system. 

    Ok, so not even the Destination Index is supplied in the IAL parameters, and the IAL determines the required (absolute) Destination ID using Sciclient.

    Yes, I have to apologize for the confusion, first I said I want the user to provide the aformentioned parameters, and then I said not even the destination index should be provided.
    The thing is, as I see it, for instance for GPIOs with interrupts destined to Core 0 of Cortex-R5F, there are 16 output index numbers of the INTR connected to input lines of the destination interrupt controller.
    The user of my IAL wants to get his interrupt to the destination interrupt controller.
    I would assume that he doesn't care if INTR interrupt output 0 is used or 5 or 8 or whatever.
    But as you conveniently showed me how to use the resource range request (thank you again for that),
    he doesn't have to. As long as I have the subtype, which I probably can get from a combination of destination host and interrupt source, then I can obtain the rsource range of all INTR outputs suitable for routing the interrupt that the user wants to setup.
    And then when I can test which of those INTR outputs is still free, I can connect the provided iinterrupt source to that output.
    Hope it helps in understanding what the idea is.
    Thank you for your hard work.


    Best regards

    Philip.

  • Maybe an analogy for better understanding:

    I, as a person, have a passport ID. I also use transportation to get from one point to another.
    Let us say, I exist in a world (board) together with a finite number of people (pins or other atomic elments on a board).
    Those people live at different locations, and they all use transport means (interrupt routes) to reach other locations.

    Now let's say some use their private car (own direct interrupt line) others use the train (interrupt router).
    Trains go from the peoples living areas (source index hardwired to INTR input index) to multiple locations (destination index).

    There are many people. Not all people can use the same train to the same location at the same time.
    Each train for a specific destination has a limited number of passenger seats (INTR output index)
    People normally want to reach a destination. They don't care all seats being equal what seat number they get
    (GPIOS don't care which of the 16 interrupt output index numbers for a specific destination MCU they get for routing an interrupt)
    Now the train company has a database for train passengers. They could now register all possible people using the train with all their IDs.
    Then a plane company would do the same, also a bus company.

    Or instead there would be a people database holding the IDs of all people independant of which vehicle they use.
    Since their ID is not conditional on the transportation they use (device ID and intra SoC index is independant of existence of
    INTR router).

    And now when people wanted to reach some destination, a booking site could simply tell them what vehicle to use,
    depending on where there are still free passenger seats. Then those people would register for that vehicle for the time of the journey.

    As it is currently in TIs documentation people are listed in the table of the train with their ID (device ID and source index are listed in INTR table).
    What I want is to find the people in a people table, independant of what transportation they use.
    So I would like the TRM to hold a table with SoC subsystem device IDs holding all the index numbers of some atomic hardware peripheral within that SoC subsystem.

    Hope that helps

    Best regards

    Philip.

  • Hi Philip,

    I need some time to digest your latest answers. I'll get back with you shortly.

    Regards,
    Frank

  • Hi Philip,

    I guess you tried the same tisci request 2 times in a row, and it failed at the source?
    If I am correct in assuming that, there is nothing wrong with this.

    My intent was to demonstrate how Sciclient_rmIrqSet() can be used to detect an already configured route, albeit indirectly. This works as expected, and Sciclient_rmIrqSet() returns a failure when attempting to configure a previously configured route.

    I've stepped through the Sciclient library code for the first (passing) and second (failing) calls to Sciclient_rmIrqSet(). I constructed a call graph in both cases, but I haven't thoroughly analyzed the code. I pointed out the failure for the 2nd call to Sciclient_rmIrqSet() is caused by Sciclient_rmIrInpIsFree() only to suggest Sciclient_rmIrInpIsFree() could also included in the API. At any rate, I don't want to speculate too much about this before consulting with an Sciclient expert.

    So what I wanted was a means to check if the INTR output is already used.

    Ok, understood. As I said before, I'll consult with the SDK team concerning your request to include Sciclient_rmIrOutpIsFree() in the API. I'll keep you posted on what I find.

    What I am asking for is an update of the documentation.

    Understood, I agree with you. I've already discussed this with the software development team, and I've filed a formal request for the documentation to be improved. Do you need this update urgently?

    Hope it helps in understanding what the idea is.

    Indeed, it helps a lot. As I said before, thanks much for sharing the diagram and detailed feedback.

    Regards,
    Frank

  • Hi Philip,

    I filed a request with the software team to add an Sciclient API function to check if an IR output is free.

    Regards,
    Frank

  • Hello Frank,
    I think I figured out my misunderstanding concerning the SoC device IDs and index numbers by now.
    But first of all concerning your answer.

    1.

    I guess you tried the same tisci request 2 times in a row, and it failed at the source?
    If I am correct in assuming that, there is nothing wrong with this.

    My intent was to demonstrate how Sciclient_rmIrqSet() can be used to detect an already configured route, albeit indirectly. This works as expected, and Sciclient_rmIrqSet() returns a failure when attempting to configure a previously configured route.

    I've stepped through the Sciclient library code for the first (passing) and second (failing) calls to Sciclient_rmIrqSet(). I constructed a call graph in both cases, but I haven't thoroughly analyzed the code. I pointed out the failure for the 2nd call to Sciclient_rmIrqSet() is caused by Sciclient_rmIrInpIsFree() only to suggest Sciclient_rmIrInpIsFree() could also included in the API. At any rate, I don't want to speculate too much about this before consulting with an Sciclient expert.


    I think there was again a misunderstanding, all I was asking for was, if you tried the exact same request twice in a row and the second one failed right at the input or if you tried with a different GPIO and the request failed right at the input.
    No need to consult an expert.

    2. Now concerning the device IDs and index numbers.
    My problem was that in this documentation

    https://software-dl.ti.com/tisci/esd/latest/2_tisci_msgs/rm/rm_irq.html

    as well as in the code comments of the SDK we use, it says:



    Those comments suggest from my point of view, that those IDs and index numbers are some general identification mechanism in the DMSC when working with peripherals.
    This is why I requested a table where I can find the identifications of peripherals inside a SoC subsystem, instead of those numbers just existing inside the table of the interrupt router.

    Though that is not the case here.
    I rechecked on the other TISCI messages here

    https://software-dl.ti.com/tisci/esd/latest/2_tisci_msgs/index.html#power-management-pm

    and it seems that those index numbers are solely used by the IRQ TISCI messages.
    When looking into drivers/sciclient/sciclient_rm_irq.c, line 1840ff it says, that the source index is the IRQ number of an interrupt line
    outgoing from the interrupt source. It is not some general identification of the source peripheral within its SoC subsystem as the above screenshot suggests (at least from my point of view).

    Generally I would like to say, at least I would save a lot of time if the documentation was done more from the point of view of somebody that is not the developer who wrote the code. Like let the comments be read and explained by some tester who knows nothing about the project or similar.
    Also don't explain to him personally what the terms mean unless you put the same explanation in the comments afterwards as well.
    Maybe you did that already, and I am simply not compatible with the way of documentation, could be as well. In that situation forget what I said.


    In my experience developers think in the context of their project and have a lot of insight into the code that they don't put into the comments because it seems natural to them, which it is only when inside that context.

    Especially stuff like "source_index - Comment: This is the index of a source" and similar things are stuff that I see a lot in documentations.
    Since to the developer it is clear what the ID of the source is for. But I as a user only know that an ID is something that uniquely denotes something and the source is some hardware part on the board.
    It does not say that this identification is only valid within the interrupt path tree or that it does not apply in other contexts but interrupt routing. Those things are only clear when you are the developer who wrote the code.
    A far better explanation would be "source_index - Comment: This is the IRQ number of an interrupt line outgoing from the source peripheral."
    Admittedly the current comment says that it is an interrupt source index. But since I don't know what a source index is at all in the context of interrupts that does not really explain it to me, A source index would be to me some set of index numbers. As it is an interrupt source index, it would mean something in the context of interrupts.
    On the other hand an IRQ number is a general term that everybody understands.

    Also it seems somehow conntected to the source ID, where it doesn't say in the comment what that ID is and what the difference between ID and index is for identifying the source. A good comment for source ID in my point of view would be something in the lines of "source_id - Comment: /see Device ID of the /see SoC subsystem encompassing the source peripheral."

    And then at some different place "Device ID - Comment: ID number of a /see SoC subsystem used within /see DMSC /see TISCI requests" (or are Device IDs used outside the DMSC as well?).

    And finally "SoC subsystem - The /see DMSC address system divides the board into subsystems depending on the type of resource the peripherals belong to like RAM, MCU, devices or network."

    It might look like more work in documentation but I would argue that it will save months long forum ping pongs in the long run.

    3. I still have problems understanding the interrupt aggregator but will mark this as resolved for now, since I think it is better to discuss this in a different post. I have all the information I need now concerning the interrupt router and can work with that for the moment.

    Thank you again for all your troubles.
    Was a pleasure working with you.


    Best regards

    Philip.

  • Hi Philip,

    Thanks for the detailed feedback. The SW dev team agrees the documentation should be improved. I added your comments to the request I filed to have the docs improved.

    I was a pleasure working with you. Thanks a lot for your patience while we worked through it to this point.

    Regards,
    Frank

  • Thank you,
    please regard, that I only used bold writing to emphasize that in my opinion this block was the essential one,
    since I have a habit of writing a lot. Which can be a bit overwhelming at certain times, I guess.


    Best regards

    Philip.