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.

RM57L843: DMA Register Issue

Part Number: RM57L843

Hello, 

I am observing strange behavior when writing to the DREQASI DMA Register in the dmaReqAssign method.


The following OP codes produce the correct behavior:

e3a0003f MOV R0, 63
e1a01103 MOV R1, R3 <i>, LSL 2
e1a05210 MOV R5, R0, LSL R2 <j>
e5110fac LDR R0,[R1,-0xfac]
e1c00005 BIC R0, R0, R5
e5010fac STR R0,[R1,-0xfac]
e1a01103 MOV R1, R3 <i>, LSL 2
e5110fac LDR R0,[R1,-0xfac]
e1800214 ORR R0, R0, R4 <reqline>, LSL R2 <j>
e5010fac STR R0,[R1,-0xfac]

The following OP codes stall the DMA:

e1a00103 MOV R0, R3 <i>, LSL 2
e5100fac LDR R0,[R0,-0xfac]
e3a0503f MOV R5, 63
e1a05215 MOV R5, R5, LSL R2 <j>
e1c01005 BIC R1, R0, R5
e1a00103 MOV R0, R3 <i>, LSL 2
e5001fac STR R1,[R0,-0xfac]
e1a00103 MOV R0, R3 <i>, LSL 2
e5100fac LDR R0,[R0,-0xfac]
e1a05214 MOV R5, R4 <reqline>, LSL R2 <j>
e1851000 ORR R1, R5, R0
e1a00103 MOV R0, R3 <i>, LSL 2
e5001fac STR R1,[R0,-0xfac]

Both sets of op codes leave the DREQASI Register with the same end state: 

0x1e1f0203

 But one causes the DMA to stop functioning and the other do not.

Is there something special about accessing DREQASI registers? The behavior is very troubling.

Thanks!

  • Hi Dmitri,

    Do you use assembly code to configure the DMA? Do you try the example code using c code?
  • Hello,

    The code was originally written in C and I am just posting dis-assembly for clarity.

    Code looks like:

    Not working:

    write_register32(&dmaREG->DREQASI[i], read_register32(&dmaREG->DREQASI[i]) & ~((uint32_t)0x3FU << j));
     e1a00103 MOV R0, R3 <i>, LSL 2
     e5100fac LDR R0,[R0,-0xfac]
     e3a0503f MOV R5, 63
     e1a05215 MOV R5, R5, LSL R2 <j>
     e1c01005 BIC R1, R0, R5
     e1a00103 MOV R0, R3 <i>, LSL 2
     e5001fac STR R1,[R0,-0xfac]
    write_register32(&dmaREG->DREQASI[i], read_register32(&dmaREG->DREQASI[i]) | ((uint32_t)reqline << j));
     e1a00103 MOV R0, R3 <i>, LSL 2
     e5100fac LDR R0,[R0,-0xfac]
     e1a0521c MOV R5, IP <reqline>, LSL R2 <j>
     e1851000 ORR R1, R5, R0
     e1a00103 MOV R0, R3 <i>, LSL 2
     e5001fac STR R1,[R0,-0xfac]

    Working:

    dmaREG->DREQASI[i] &= ~((uint32_t)0x3FU << j);
     e3a0003f MOV R0, 63
     e1a01103 MOV R1, R3 <i>, LSL 2
     e1a05210 MOV R5, R0, LSL R2 <j>
     e5110fac LDR R0,[R1,-0xfac]
     e1c00005 BIC R0, R0, R5
     e5010fac STR R0,[R1,-0xfac]
    dmaREG->DREQASI[i] |= ((uint32_t)reqline << j);
     e1a01103 MOV R1, R3 <i>, LSL 2
     e5110fac LDR R0,[R1,-0xfac]
     e180021c ORR R0, R0, IP <reqline>, LSL R2 <j>
     e5010fac STR R0,[R1,-0xfac]

    Read and write register are helper methods:

    /**
    * @brief Write a 32-bit register
    */
    inline void write_register32( volatile uint32_t *target, const uint32_t value )
    {
    *target = value;
    }


    /**
    * @brief Read a 32-bit register
    */
    inline uint32_t read_register32( volatile uint32_t *target )
    {
    return *target;
    }

  • Hi Dmitri,

    I did a test using your function on RM57 launchpad, I didn't see any problem:

    uint32_t i, j, reqline=10, channel=6;

    i = channel / 4U; /* Find the register to configure */
    j = channel % 4U; /* Find the offset */
    j = (uint8)3U - j; /* reverse the byte order */
    j = j * 8U; /* find the bit location */

    dmaREG->DREQASI[i] &= ~((uint32_t)0x3FU << j);
    dmaREG->DREQASI[i] |= ((uint32_t)reqline << j);

    write_register32(&dmaREG->DREQASI[i], read_register32(&dmaREG->DREQASI[i]) & ~((uint32_t)0x3FU << j));
    write_register32(&dmaREG->DREQASI[i], read_register32(&dmaREG->DREQASI[i]) | ((uint32_t)reqline << j));
  • This may be a compiler issue, I am not using the TI ARM compiler for the target.

    Thanks!