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.

RTOS/AM5728: I2C, memory mapping, interrupts from IPU

Expert 1915 points
Part Number: AM5728
Other Parts Discussed in Thread: SYSBIOS,

Tool/software: TI-RTOS

Hello,

I boot Linux on the A15 core, the IPU and the DSP both run SYSBIOS. All cores communicate using IPC MessageQueues, CMEM is used as shared memory.

Now I'd like to use the IPU for some I2C accesses (UART, GPIOs also planned).

On the IPU I resolved the following issues:

- the interface clock is not activated. I do it manually: *((uint32_t*)0x6a0097b0)=2; This is probably not the recommended way  and might better be done using some lines in the xdc config files. I modified the Linux device tree so linux does not use the I2C instance.

-> How should I active the interface clock in SYSBIOS?

- The bitbanding area on the M4 uses the same locations as the peripherals on the L3. The IOMMU remaps 0x6800.0000 to 0x48000.000, so the I2C device appears at 0x6806.0000 (phys 0x4806.0000). Sysbios still looks for it at 0x4806.0000. This is my workaround:

    I2C_HwAttrs   i2c_attributes;
    I2C_socGetInitCfg(DI2C_BUS, &i2c_attributes);
    i2c_attributes.baseAddr=0x68060000;
    I2C_socSetInitCfg(DI2C_BUS, &i2c_attributes);
And this although I've set the socType for OSAL and CSL to "am572x".

-> How do I tell SYSBIOS the correct address for the peripherals used?

Next step would be to used HW interrupts for the IPU.

-> Is there an example how to use them if the A15 is running Linux?

Using the VPDMA on the DSP would also be a benefit, but I fear the mystical xdctools configs.

I tested some examples for different use cases but getting the xs config files right for a mixed use case is not easy.  Is there a way to get a xs/xdctools specialist to look at my config files for DSP and IPU?

Best regards,

Lo2

  • The RTOS team have been notified. they will respond here.
  • Hello.
    This is for enabling I2C3 clock in SysBios:

    CSL_FINST(l4PerCmReg->CM_L4PER_I2C3_CLKCTRL_REG,
    L4PER_CM_CORE_COMPONENT_CM_L4PER_I2C3_CLKCTRL_REG_MODULEMODE, ENABLE);

    while(CSL_L4PER_CM_CORE_COMPONENT_CM_L4PER_I2C3_CLKCTRL_REG_IDLEST_FUNC !=
    CSL_FEXT(l4PerCmReg->CM_L4PER_I2C3_CLKCTRL_REG,
    L4PER_CM_CORE_COMPONENT_CM_L4PER_I2C3_CLKCTRL_REG_IDLEST));

    and this is for enabling I2C5 clock:

    CSL_ipu_cm_core_aonRegs *ipuCmReg =
    (CSL_ipu_cm_core_aonRegs *) CSL_MPU_IPU_CM_CORE_AON_REGS;

    ipuCmReg->CM_IPU_I2C5_CLKCTRL_REG = (ipuCmReg->CM_IPU_I2C5_CLKCTRL_REG & ~CSL_IPU_CM_CORE_AON_CM_IPU_I2C5_CLKCTRL_REG_IDLEST_MASK) |
    (CSL_IPU_CM_CORE_AON_CM_IPU_I2C5_CLKCTRL_REG_IDLEST_FUNC | CSL_IPU_CM_CORE_AON_CM_IPU_I2C5_CLKCTRL_REG_MODULEMODE_ENABLE);

    while(ipuCmReg->CM_IPU_I2C5_CLKCTRL_REG != (CSL_IPU_CM_CORE_AON_CM_IPU_I2C5_CLKCTRL_REG_IDLEST_FUNC | CSL_IPU_CM_CORE_AON_CM_IPU_I2C5_CLKCTRL_REG_MODULEMODE_ENABLE));

    Regards,
    Enzo
  • Hi,

    Can you upload your config file for DSP and M4 so we can take a look? For the address mapping (e.g. 0x4806_0000 to 0x6806_0000), there is a resource table for this: processors.wiki.ti.com/.../IPC_Resource_customTable

    Regards, Eric
  • Hi Lo2,

    While we wait for your cfg files, I wanted to make sure you have seen this wiki page on Linux IPC on AM57xx:

    processors.wiki.ti.com/.../Linux_IPC_on_AM57xx

    Regards,
    Sahin
  • Bit-banding is only a way to modify some bits of a register without read-modify-write procedure but registers are always mapped to the address reported in the datasheet. Only bits of the registers are remapped following the formula:
    bit_word_offset = (byte_offset x 32) + (bit_number × 4)
    bit_word_addr = bit_band_base + bit_word_offset
    as reported at the following link: infocenter.arm.com/.../index.jsp
    But bit-banding is not preventing to access to the registers in canonical way: for this reason in cfg files in Sitara SDK examples for M4, you find :
    /* Large PAGE */
    AMMU.largePages[0].pageEnabled = AMMU.Enable_YES;
    AMMU.largePages[0].logicalAddress = 0x40000000;
    AMMU.largePages[0].translatedAddress = 0x40000000;
    ....
    and later:

    AMMU.largePages[3].pageEnabled = AMMU.Enable_YES;
    AMMU.largePages[3].logicalAddress = 0x60000000;
    AMMU.largePages[3].translatedAddress = 0x40000000;
    ....

    Regards,
    Enzo
  • Hello,


    please find attached to this post the config files for the IPU.

    They are based on th ipc ex_02 / ex_41 examples provided by IT. I've got IPC to work between A15 (Linux) and DSP and IPU (both SYSBIOS).

    The issues described in my other were caused by different sizes of enum on the A15/DSP/M4 (sizeof(enum) is 1 on M4). This has been resolved.


    I tried to extend the working setup (roughly ex_41 and added CMEM) to used the PDK drivers as I want the M4 to use I2C, GPIOs and interrupts.

    I added and configured (as far I got) the CSL and OSAL for am5728 to use the PDK drivers, still the M4 mapping (as Enzo described above) is not correct.


    It's not clear to me which parts of the build process are affected by xs/xdctools: I know it generates the linker file and generates lots of code for the configured setup, but it is not clear to me which parts need to be configured and what is affected by some of those flags/settings (or how you call it). The amount of output generated is too large to check it by trial and error.

    If there is an alternative to  xs/xdctools/rtsc I'd be very happy to give that a try.

    From the Linux side: should power and clock domains for hardware be setup? Or should that be done on the sysbios side?

    Best regards,

    Lo2

    Addendum: the e2e forum does not let me append cfg, bld or xs files.

    e2e_temp.tar.gz

  • Hi Lo2,

    We are taking a look at your files now.

    Also, I accidentally pressed the "TI Thinks Resolved" button, can you please click "No" to remove it?

    Best,
    Sahin
  • Hi,

    I looked at your resource table and .cfg files, I am not sure why the issue is related to XDC or SYSBIOS. If you want to access I2C and GPIO driver in M4, you need to add entries in your resource table for them. Below is an example when we want to access PCIE on M4:

    #define PCIE_SS1_CFG_REGS       0x51000000
    #define PCIE_SS1_CFG_REGS_VIRT  (PCIE_SS1_CFG_REGS + 0x20000000)

       {
            TYPE_DEVMEM,
            PCIE_SS1_CFG_REGS_VIRT, PCIE_SS1_CFG_REGS,
            SZ_1M, 0, 0, "PCIE_SS1_CFG_REGS",
        },
     

    Then in the ipu.cfg, we have:

    /* Load and use the PCIE packages */
    var socType = "am572x";
    var Pcie = xdc.loadPackage('ti.drv.pcie');

    I believe the same case for I2C, GPIO etc. Let me know if this works for you or why the issue came from XDC.

    Regards, Eric

  • Hi Eric,

    I've added the following lines to the rsc_table.h:

    #define I2C_CFG_REGS            0x48060000
    #define I2C_CFG_REGS_VIRT       (I2C_CFG_REGS + 0x20000000)

        {
            TYPE_DEVMEM,
            I2C_CFG_REGS_VIRT, I2C_CFG_REGS,
            SZ_1M, 0, 0, "I2C_REGS",
        },

    I've searched and grepped for strings like _CFG_REGS but could not find any in the documentation or in the sources, so I assume only used locally and naming should be consistent in the file itself but is not referenced outside, right?

    Still the access causes an abort:

    [0][      0.000] [t=0x00206aef] xdc.runtime.Main: waiting for message on queue IPU_CONTROL
    [0][     27.129] [t=0x00000002:94cbd331] ti.sysbios.family.arm.m3.Hwi: ERROR: line 1104: E_hardFault: FOR
    CED
    [0][     27.129] ti.sysbios.family.arm.m3.Hwi: line 1104: E_hardFault: FORCED
    [0][     27.129] [t=0x00000002:94ced23b] ti.sysbios.family.arm.m3.Hwi: ERROR: line 1181: E_busFault: PREC
    ISERR: Immediate Bus Fault, exact addr known, address: 480600a4
    [0][     27.129] ti.sysbios.family.arm.m3.H[   70.886823] virtio_rpmsg_bus virtio0: msg received with no
    recipient
    wi: line 1181: E_busFault: PRECISERR: Immediate Bus Fault, exact addr known, address: 480600a4
    [0][     27.129] Exception occurred in background thread at PC = 0x00024a9c.
    [0][     27.129] Core 0: Exception occurred in ThreadType_Task.
    [0][     27.129] Task name: SIPUtask, handle: 0x80060300.
    [0][     27.129] Task stack base: 0x80060350.
    [0][     27.129] Task stack size: 0x1000.
    [0][     27.129] R0 = 0x48060000  R8  = 0x00000000
    [0][     27.129] R1 = 0x00021e65  R9  = 0x00000001
    [0][     27.129] R2 = 0x00000008  R10 = 0x0001551c
    [0][     27.129] R3 = 0x00000000  R11 = 0xffffffff
    [0][     27.129] R4 = 0x8006c8a8  R12 = 0x800611a0
    [0][     27.129] R5 = 0x8006c67c  SP(R13) = 0x80061280
    [0][     27.129] R6 = 0x8006dc14  LR(R14) = 0x000154bf
    [0][     27.129] R7 = 0x00029858  PC(R15) = 0x00024a9c
    [0][     27.129] PSR = 0x81000000
    [0][     27.129] ICSR = 0x00438803
    [0][     27.129] MMFSR = 0x00
    [0][     27.129] BFSR = 0x82
    [0][     27.129] UFSR = 0x0000
    [0][     27.129] HFSR = 0x40000000
    [0][     27.129] DFSR = 0x00000000
    [0][     27.129] MMAR = 0x480600a4
    [0][     27.129] BFAR = 0x480600a4
    [0][     27.129] AFSR = 0x00000000
    [0][     27.129] Terminating execution

    This is the C code on the M4 without forcing the address:

        I2C_HwAttrs   i2c_attributes;
        I2C_socGetInitCfg(DI2C_BUS, &i2c_attributes);
        SHST_slLog(3, "i2c_attributes.baseAddr=0x%x",i2c_attributes.baseAddr);

        I2C_init();
        I2C_Params_init(&i2cParams);
        i2cParams.transferMode  = I2C_MODE_BLOCKING;
        i2cHandle = I2C_open(DI2C_BUS, &i2cParams);

    I2C access code:

        I2C_transactionInit(&i2cTransaction);
        i2cTransaction.masterMode = true;
        i2cTransaction.slaveAddress = ucSlaveId;
        i2cTransaction.writeBuf = NULL;
        i2cTransaction.writeCount = 0;
        i2cTransaction.readBuf = pucData;
        i2cTransaction.readCount = ucSizeData;
        i2cTransaction.timeout   = 2000;
        retval = I2C_transfer(i2cHandle, &i2cTransaction);

    The log reports: i2c_attributes.baseAddr=0x48060000

    So the address is correct but the mapping still isn't.

    Can you please provide me example code how to use the PDK I2C driver on the M4?

    Best regards,

    Lo2

  • Hi Eric,

    My current workaround is this:
    I2C_HwAttrs i2c_attributes;
    I2C_socGetInitCfg(DI2C_BUS, &i2c_attributes);
    SHST_slLog(3, "i2c_attributes.baseAddr=0x%x",i2c_attributes.baseAddr);
    i2c_attributes.baseAddr=0x68060000;
    I2C_socSetInitCfg(DI2C_BUS, &i2c_attributes);

    I force the SYSBIOS PDK driver to use the mapped access with the 0x20000000 offset.
    On the Linux side I set the GPIOs and enable the interface clock for I2C bus 3 before the M4 code starts.
    This works: M4 reads data and logs it.
    So my H/W is ok, this is only a workaround until the mapping is corrected.

    Best regards,
    Lo2
  • Hello,

    In order ti use the pdk CSL I need to fix my memory mapping. I stared development with a IPC example, so my IPU AMMU config is like this:

    ti-processor-sdk-rtos-am57xx-evm-04.01.00.06/ipc_3_46_02_04/examples/DRA7XX_linux_elf/ex02_messageq/ipu1/IpuAmmu.cfg

    That does not map the region 0x4000_0000 at all.

    Since some of the peripheral controls reside above 0x4a00_0000, I'd like to add a translation that maps 0x4000_0000 (logical) to 0x4000_0000 (physical), preferably a medium page type entry to map a whole block.

    CSL assumes that every peripheral is available at its L3 address, so I2C io muxes are at: 0x4A003774 / 8, GPIO interrupt at: 0x4a00362c, I2C clock at: 0x4a0097b0.

    I tried adding a medium sized page:
    AMMU.mediumPages[1].pageEnabled = AMMU.Enable_YES;
    AMMU.mediumPages[1].logicalAddress = 0x4A000000;
    AMMU.mediumPages[1].translatedAddress = 0x4A000000;
    AMMU.mediumPages[1].translationEnabled = AMMU.Enable_YES;
    AMMU.mediumPages[1].size = AMMU.Medium_256K;
    AMMU.mediumPages[1].L1_cacheable = AMMU.CachePolicy_CACHEABLE;
    AMMU.mediumPages[1].L1_posted = AMMU.PostedPolicy_POSTED;

    But that just completelt breaks IPC.

    How can I do a 1:1 map for addresses 0x4A00_0000 for the IPU so I can use CSL?

    xs generates a lot of files. Is there a memory map somewhere in there?

    Best regards,
    Lo
  • Some additional information:

    The cause is a call to GPIO_init(); I get a precise abort on 0x48053130.
    I can 'punch a hole' using the IpuAmmu.cfg:

    AMMU.smallPages[9].pageEnabled = AMMU.Enable_YES;
    AMMU.smallPages[9].logicalAddress = 0x48050000;
    AMMU.smallPages[9].translatedAddress = 0x48050000;
    AMMU.smallPages[9].translationEnabled = AMMU.Enable_YES;
    AMMU.smallPages[9].size = AMMU.Small_4K;

    But apparently I'm limited to 10 entries (for small pages).
    Depending on the address I try to map, IPC breaks.

    Which address ranges are used by IPC?

    How can I add more entries?

    In http://processors.wiki.ti.com/index.php/Linux_IPC_on_AM57xx?keyMatch=ipu%20ammu&tisearch=Search-EN#Changing_Cortex_M4_IPU_Memory_Map

    all IO addresses are mapped from 0x4... (phys) to 0x6.... (logical). While this works, and I'd like to use it, CSL references peripherals at 0x4....

    How can I tell CSL to use the 0x6... instead of 0x4...?

    Then I could use the IPC default IpuAmmu.cfg memory mapping. Looking at the sources, that looks fairly hardcoded.


    Best regards,
    Lo

  • Hi Lo,

    These IPC addresses are actually configurable, you can override them by writing to the mailboxBaseAddr[] array in the ti.sdo.ipc.family.vayu.InterruptIpu module.

    See the following wiki for more details.
    processors.wiki.ti.com/.../IPC_3.x_FAQ