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.

RM46L852: N2HET REQ to DMA

Part Number: RM46L852
Other Parts Discussed in Thread: HALCOGEN

I'm having a problem configurating a DMA REQ through the N2HET.
My het code generates a PWM and when the compare matches de pwm goes up and generates de Request. I'm trying to redirect the data to the first 8 pins of HET1 and can't seem to figure it out.
Can someone help?
Here is the main code with all the drivers from HalCoGen.
Appreciated,

Nuno Olive

/** @file sys_main.c 
*   @brief Application main file
*   @date 11-Dec-2018
*   @version 04.07.01
*
*   This file contains an empty main function,
*   which can be used for the application.
*/

/* 
* Copyright (C) 2009-2018 Texas Instruments Incorporated - www.ti.com 
* 
* 
*  Redistribution and use in source and binary forms, with or without 
*  modification, are permitted provided that the following conditions 
*  are met:
*
*    Redistributions of source code must retain the above copyright 
*    notice, this list of conditions and the following disclaimer.
*
*    Redistributions in binary form must reproduce the above copyright
*    notice, this list of conditions and the following disclaimer in the 
*    documentation and/or other materials provided with the   
*    distribution.
*
*    Neither the name of Texas Instruments Incorporated nor the names of
*    its contributors may be used to endorse or promote products derived
*    from this software without specific prior written permission.
*
*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
*  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
*  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
*  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
*  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
*  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
*  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
*  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
*  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/


/* USER CODE BEGIN (0) */
#include "het.h"
#include "mibspi.h"
#include "sys_dma.h"
#include "gio.h"
#include "PWM.h"
/* USER CODE END */

/* Include Files */

#include "sys_common.h"

/* USER CODE BEGIN (1) */
/* USER CODE END */

/** @fn void main(void)
*   @brief Application main function
*   @note This function is empty by default.
*
*   This function is called after startup.
*   The user can use this function to implement the application.
*/

/* USER CODE BEGIN (2) */
#define D_SIZE      2

void dmaConfigCtrlPacket(uint32 sadd,uint32 dadd,uint32 dsize);
void mibspiDmaConfig(mibspiBASE_t *mibspi,uint32 channel, uint32 txchannel, uint32 rxchannel);

uint8 TX_DATA[D_SIZE] = {1<<6,0x0} ;         /* transmit buffer in sys ram */

static uint8 *reg_out; //output register

g_dmaCTRL g_dmaCTRLPKT;    /* dma control packet configuration stack */
/* USER CODE END */

uint8	emacAddress[6U] = 	{0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU};
uint32 	emacPhyAddress	=	0U;

int main(void)
{
/* USER CODE BEGIN (3) */

          hetInit();

          reg_out = &((uint8_t *) &(hetREG1->DOUT))[0];
          hetREG1->REQDS = 1<<4;
          /* - assigning dma request: channel-0 with request line - 1 */
          dmaReqAssign(4,20 );

          /* - configuring dma control packets   */
          dmaConfigCtrlPacket((uint32)(&TX_DATA),(uint32)reg_out,D_SIZE);
          /* upto 32 control packets are supported. */

          /* - setting dma control packets */
          dmaSetCtrlPacket(DMA_CH4,g_dmaCTRLPKT);

          /* - setting the dma channel to trigger on h/w request */
          dmaSetChEnable(DMA_CH4, DMA_HW);

          /* - enabling dma module */
          dmaEnable();

          while(1)
          {

          }




/* USER CODE END */
}


/* USER CODE BEGIN (4) */

/** void dmaConfigCtrlPacket(uint32 sadd,uint32 dadd,uint32 dsize)
*
*   configuring dma control packet stack
*
*       sadd  > source address
*       dadd  > destination  address
*       dsize > data size
*
*   @ note : after configuring the stack the control packet needs to be set by calling dmaSetCtrlPacket()
*/
void dmaConfigCtrlPacket(uint32 sadd,uint32 dadd,uint32 dsize)
{
  g_dmaCTRLPKT.SADD      = sadd;              /* source address             */
  g_dmaCTRLPKT.DADD      = dadd;              /* destination  address       */
  g_dmaCTRLPKT.CHCTRL    = 0;                 /* channel control            */
  g_dmaCTRLPKT.FRCNT     = 1;                 /* frame count                */
  g_dmaCTRLPKT.ELCNT     = dsize;             /* element count              */
  g_dmaCTRLPKT.ELDOFFSET = 4;                 /* element destination offset */
  g_dmaCTRLPKT.ELSOFFSET = 0;                 /* element destination offset */
  g_dmaCTRLPKT.FRDOFFSET = 0;                 /* frame destination offset   */
  g_dmaCTRLPKT.FRSOFFSET = 0;                 /* frame destination offset   */
  g_dmaCTRLPKT.PORTASGN  = 4;                 /* port b                     */
  g_dmaCTRLPKT.RDSIZE    = ACCESS_16_BIT;     /* read size                  */
  g_dmaCTRLPKT.WRSIZE    = ACCESS_16_BIT;     /* write size                 */
  g_dmaCTRLPKT.TTYPE     = FRAME_TRANSFER ;   /* transfer type              */
  g_dmaCTRLPKT.ADDMODERD = ADDR_INC1;         /* address mode read          */
  g_dmaCTRLPKT.ADDMODEWR = ADDR_OFFSET;       /* address mode write         */
  g_dmaCTRLPKT.AUTOINIT  = AUTOINIT_ON;       /* autoinit                   */
}

/* USER CODE END */
ira

  • Hi Nuno,

    We started working on your issue and will provide an update soon.

    --

    Thanks & regards,
    Jagadish.

  • Hi jagadish,
    Since the post on the begining i looked at the datasheet and found out i was missing 2 initializations. HETREQENS and HETREQDS. but i already added those initializations to my code and still nothing. Any luck on your end?

  • Hi Nuno,

    Is it possible for you to send your complete project so that i can easily reproduce and see the issue?

    You can send a private message to me so that no one can see it?

    --

    Thanks & regards,
    Jagadish.

  • Hi Nuno,

    Actually, my RM46 hardware is not working, because of that i unable to test your project.

    Give me some time to fix it and test it.

    --

    Thanks & regards,
    Jagadish.

  • Hi Nuno,

    I am sorry I didn't get your point. Are you going to move the data from data field of a N2HET instruction to MCU SRAM?

    The MCU supports N2HET transfer unit (HTU) module which is similar to the DMA module. The HTU is specialized to transfer N2HET data to or from
    the microcontroller RAM.

    The HTU request is generated by the N2HET instruction, for example 

  • Hi. I'm trying to move data from de MCU RAM to the pins. Let's say you have 16 bits for communication with another board. I'm trying to generate a request (or an IRQ either is fine) to put data from the MCU RAM to the 16 pins

  • Hi Nuno,

    The data can not be moved to the pin. It is moved to the buffer or register of a peripheral (e.g. SPI_MOSI, or NHET DOUT) who use the pin to output data. If you want to generate PWM using NHET, the NHET instructions (e.g. ECMP, CNT, DJZ, PWCNT, etc) should be executed from NHET RAM. To move data from MCU SRAM to those NHET instruction data fields, the HTU should be used. 

  • Hi QJ,

    Then how can I generate the Dma request and put the buffer in the hetpins?

    I now how to do it in the assembly code. It's the C configurations that I'm not fully understanding

  • You use NHET to generate PWM signals, right? The HALCoGen generates the code in opcode mode which is copied to NHET RAM in hetInit():

    https://www.ti.com/lit/an/spna217/spna217.pdf?ts=1691643144831&ref_url=https%253A%252F%252Fwww.google.com%252F

    The example in this appnot uses HTU to transfer data.

  • Yes but I want to use my own assembly code. Which I am using. I'm having trouble configuring the C code for my own assembly code. The Dma configurations for het lins

  • If you use DMA to move data from MCU SRAM to N2HET DOUT register (your code in your first message), the NHET hardware doesn't generate DMA request, you have to trigger the DMA transfer manually (SW trigger).

    You use NHET to generate PWM, right? One PWM can be generated by running the following code from NHET RAM:

    ; PWM with synchronous duty cycle update at compare match event
    L00 CNT { reg=A, irq=OFF, max= 10 }
    L01 ECMP { next=L03, cond_addr=L02, en_pin_action=ON, pin=1, action=PULSELO, reg=A, data= 2, hr_data=80}
    L02 MOV32 { remote=L01, type=IMTOREG&REM, reg=NONE, data=1, hr_data=20} ; CPU to write to this data field
    L03 BR { next= L00, cond_addr=L00, event= NOCOND }

    You can use DMA or HTU to move data from MCU SRAM to data field of NHET MOV32 instruction

  • Can´t i just generate the pwm with a CNT instruction and a ECMP instruction like this:

    L00 CNT { next=L01,reg=A,max=8,data=0};

    L01 ECMP { next=L00,reqnum=6,request=GENREQ,hr_lr=HIGH,en_pin_action=ON,cond_addr=L00,pin=6,action=PULSEHI,reg=A,irq=OFF,data=4,hr_data=60};

    Doesnt this trigger a HW request? i though it would



  • HI Nuno,

    Yes, you can use CNT and ECMP for PWM generation. If a different PWM duty-cycle is required, the host CPU or HTU has to modify the data field of ECMP. You may know that changing the data field of ECMP directly can lead a missing pulse.

    To avoid this, MOV32 or MOV64 is recommended to update the data field and/or control field of the ECMP instruction. The MOV32 or MOV64 is only executed when the compare of the ECMP matches. The host CPU or HTU can update the next compare value by writing asynchronously to the data field of the MOV32  or MOV64 instruction instead of writing directly to the data field of the ECMP instruction.

    MOV32 is used to modify the data field of other instruction, but MOV64 can modify the data field and control field of other instructions.

    Please refer to the example in the link I gave you:

    https://www.ti.com/lit/an/spna217/spna217.pdf?ts=1691643144831&ref_url=https%253A%252F%252Fwww.google.com%252F

  • In this example you gave me the dma request is in the CNT instruction and not in the ECMP instruction. Can´t it be in the ECMP instruction?

    ps: im not trying to update the duty cycle so no need to go for that route

  • Hi Nuno,

    Yes, you can enable the DMA request and define the request line in ECMP. The code in spna217 is a good example of using HTU.

  • In the code spna217 they use HTU. I'm trying to use DMA but i think im missing some initializations. i have a CNT and an ECMP. when ECMP compare matches it generates a request through channel 6. this is the main.c

    /** @file sys_main.c 
    *   @brief Application main file
    *   @date 11-Dec-2018
    *   @version 04.07.01
    *
    *   This file contains an empty main function,
    *   which can be used for the application.
    */
    
    /* 
    * Copyright (C) 2009-2018 Texas Instruments Incorporated - www.ti.com 
    * 
    * 
    *  Redistribution and use in source and binary forms, with or without 
    *  modification, are permitted provided that the following conditions 
    *  are met:
    *
    *    Redistributions of source code must retain the above copyright 
    *    notice, this list of conditions and the following disclaimer.
    *
    *    Redistributions in binary form must reproduce the above copyright
    *    notice, this list of conditions and the following disclaimer in the 
    *    documentation and/or other materials provided with the   
    *    distribution.
    *
    *    Neither the name of Texas Instruments Incorporated nor the names of
    *    its contributors may be used to endorse or promote products derived
    *    from this software without specific prior written permission.
    *
    *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
    *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
    *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
    *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
    *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
    *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
    *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
    *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    *
    */
    
    
    /* USER CODE BEGIN (0) */
    /* USER CODE END */
    
    /* Include Files */
    
    #include "sys_common.h"
    
    /* USER CODE BEGIN (1) */
    #include "rti.h"
    #include "het.h"
    #include "gio.h"
    #include "PWM.h"
    #include "sys_dma.h"
    /* USER CODE END */
    
    /** @fn void main(void)
    *   @brief Application main function
    *   @note This function is empty by default.
    *
    *   This function is called after startup.
    *   The user can use this function to implement the application.
    */
    
    /* USER CODE BEGIN (2) */
    void dmaConfigCtrlPacket(uint32 sadd,uint32 dadd,uint32 dsize);
    
    uint16 TX_DATA[]={0xff,0x0};
    
    g_dmaCTRL g_dmaCTRLPKT;
    
    static uint8_t *phetREG1DOUT8;
    /* USER CODE END */
    
    int main(void)
    {
    /* USER CODE BEGIN (3) */
    
    
        phetREG1DOUT8 = &((uint8_t *) &(hetREG1->DOUT))[3];
    
    
        dmaReqAssign(6,24);
    
        dmaConfigCtrlPacket((uint32)(&TX_DATA),((uint32) phetREG1DOUT8),1);
    
        dmaSetCtrlPacket(DMA_CH6,g_dmaCTRLPKT);
    
        dmaSetChEnable(DMA_CH6, DMA_HW);
    
        dmaEnable();
    
    
        hetInit();
    
    //    hetRAM2->Instruction[pHET_L00_1].Data = 0x1;
    
        hetREG2->INTENAS = pHET_L01_1;
    
        /* Enable IRQ - Clear I flag in CPS register */
        /* Note: This is usually done by the OS or in an svc dispatcher */
        _enable_IRQ();
    
    
        /* Run forever */
        while(1)
        {
        }
    
    /* USER CODE END */
    
    }
    
    
    /* USER CODE BEGIN (4) */
    void dmaConfigCtrlPacket(uint32 sadd,uint32 dadd,uint32 dsize)
    {
      g_dmaCTRLPKT.SADD      = sadd;              /* source address             */
      g_dmaCTRLPKT.DADD      = dadd;              /* destination  address       */
      g_dmaCTRLPKT.CHCTRL    = 0;                 /* channel control            */
      g_dmaCTRLPKT.FRCNT     = 1;                 /* frame count                */
      g_dmaCTRLPKT.ELCNT     = dsize;             /* element count              */
      g_dmaCTRLPKT.ELDOFFSET = 4;                 /* element destination offset */
      g_dmaCTRLPKT.ELSOFFSET = 0;                 /* element destination offset */
      g_dmaCTRLPKT.FRDOFFSET = 0;                 /* frame destination offset   */
      g_dmaCTRLPKT.FRSOFFSET = 0;                 /* frame destination offset   */
      g_dmaCTRLPKT.PORTASGN  = 4;                 /* port b                     */
      g_dmaCTRLPKT.RDSIZE    = ACCESS_8_BIT;     /* read size                  */
      g_dmaCTRLPKT.WRSIZE    = ACCESS_8_BIT;     /* write size                 */
      g_dmaCTRLPKT.TTYPE     = FRAME_TRANSFER ;   /* transfer type              */
      g_dmaCTRLPKT.ADDMODERD = ADDR_INC1;         /* address mode read          */
      g_dmaCTRLPKT.ADDMODEWR = ADDR_OFFSET;       /* address mode write         */
      g_dmaCTRLPKT.AUTOINIT  = AUTOINIT_ON;       /* autoinit                   */
    }
    
    /* USER CODE END */
    

  • Did you get interrupt? Is the DMA transfer triggered?

  • Is your NHET code loaded to HET2 RAM? The device has two HET modules: HET1 and HET2.

    You should at least get interrupt or HETFLAG bit set based on your configuration. 

    Does your code enable the DMA request line? This can be done by writing 1 to corresponding bit of Request Enable Set Register (HETREQENS).

    If you use DMA instead of HTU which is default, you need to write 1 to TDSn bit of Request Destination Select Register (HETREQDS). The default is 0x0, and HTU is selected. Using HTU can free up DMA channels for other purpose.

  • Yes it is. the Hercules code generator doest that automatically when you select the header and source file with advanced config mode. In het.c he adds the memcpy for het2ram

  • If all of those are configured, you should get interrupt and DMA request. It seems to me that you missed something in HET configuration.

  • Hi Nuno,

    Have you resolved the issue?

  • The het configuration is 2 registers and the generate request on the instruction. My problem is configuring the dma packet to the output pins of HET. So the destination register must be HET PINS (example: pins of het1 0 through 8)

  • Hi Nuno,

    It doesn't matter where the source and destination are. The DMA controller can transfer to and from any space within the 4 gigabyte physical address map, by programming the absolute address for the source and destination in the control packet. Control packets store the transfer information such as source address, destination address, transfer count and control attributes for each channel. 

    The problem is why N2HET instruction doesn't generate a DMA request. Can you share your N2HET code with me? I will do a quick test with your code.

  • Hi Nuno,

    Just created an example that a DMA transfer is triggered by N2HET instruction running from N2HET2 RAM.

    1. DMA transfers data from one buffer to another buffer located in MCU SRAM

    2. DMA request line 24 is mapped DMA channel 0. The request line 24 is request number 6 from N2HET instruction

        dmaReqAssign(DMA_CH0, 24);

       One N2HET instruction can select one of 8 request lines by programming the “reqnum”, the reqnum=6 is used in this example:

        ECMP { reqnum=6,request=GENREQ,en_pin_action=ON,pin=8,action=PULSELO,reg=A,irq=ON,data=5,hr_data=0};

    3. The N2HET Request Destination Select Register (HETREQDS) should be configured to trigger DMA channel rather than HTU channel:

        hetREG2->REQDS = 0xFF;

        hetREG2->REQENS = 0xFF;

    4. hetRAM2->Instruction[1].Control  |= ((0x1<<27) | (0x1 << 22));

       this is to enable the request and pin action.

    My test shows that the Data is transferred to RX_DATA buffer through DMA channel 0. The DMA interrupt, and N2HET interrupt are generated.

    RM46L852_N2HET_DMA.zip

  • do you need to have that last line of code ( hetRAM2 ->instruction[1].control = .... ) ? isnt the pin action already on and the generate request ON aswell in the het code?
    I dont know why we need to repeat the configurations of hetcode in the source file

  • Hi Nuno,

    You don't have to. Just show you how to manually modify enable/disable control bits of HET instructions in HET RAM 

    1. I changed the code manually to disable the DMA request 

    2. The last line is to enable the DMA request 

    hetRAM2->Instruction[1].Control  |= ((0x1<<27) | (0x1 << 22));

  • here is my sys_main.
    L06 triggers the dma request. i have selected the destination register to point to the last 8 pins of het1 and initialized them as output.
    With the logic analyzer i can't see anything.

    /** @file sys_main.c 
    *   @brief Application main file
    *   @date 11-Dec-2018
    *   @version 04.07.01
    *
    *   This file contains an empty main function,
    *   which can be used for the application.
    */
    
    /* 
    * Copyright (C) 2009-2018 Texas Instruments Incorporated - www.ti.com 
    * 
    * 
    *  Redistribution and use in source and binary forms, with or without 
    *  modification, are permitted provided that the following conditions 
    *  are met:
    *
    *    Redistributions of source code must retain the above copyright 
    *    notice, this list of conditions and the following disclaimer.
    *
    *    Redistributions in binary form must reproduce the above copyright
    *    notice, this list of conditions and the following disclaimer in the 
    *    documentation and/or other materials provided with the   
    *    distribution.
    *
    *    Neither the name of Texas Instruments Incorporated nor the names of
    *    its contributors may be used to endorse or promote products derived
    *    from this software without specific prior written permission.
    *
    *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
    *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
    *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
    *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
    *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
    *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
    *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
    *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    *
    */
    
    
    /* USER CODE BEGIN (0) */
    /* USER CODE END */
    
    /* Include Files */
    
    #include "sys_common.h"
    
    /* USER CODE BEGIN (1) */
    #include "rti.h"
    #include "het.h"
    #include "gio.h"
    #include "PWM.h"
    #include "sys_dma.h"
    /* USER CODE END */
    
    /** @fn void main(void)
    *   @brief Application main function
    *   @note This function is empty by default.
    *
    *   This function is called after startup.
    *   The user can use this function to implement the application.
    */
    
    /* USER CODE BEGIN (2) */
    void dmaConfigCtrlPacket(uint32 sadd,uint32 dadd,uint32 dsize);
    void delay();
    uint8 TX_DATA[]={0xff,0x0};
    
    g_dmaCTRL g_dmaCTRLPKT;
    
    void createTxDummyPacket(uint8_t *packet, uint32_t size);
    
    static uint8_t *phetREG1DOUT8;
    /* USER CODE END */
    
    int main(void)
    {
    /* USER CODE BEGIN (3) */
    
        uint8_t dummyPacket[1024];
    
        createTxDummyPacket(&dummyPacket[0], 1024);
    
        phetREG1DOUT8 = &((uint8_t *) &(hetREG2->DOUT))[3];
    
        dmaReqAssign(DMA_CH0,24);
    
        dmaConfigCtrlPacket((uint32)(&TX_DATA),((uint32) phetREG1DOUT8),2);
    
        dmaSetCtrlPacket(DMA_CH0,g_dmaCTRLPKT);
    
        dmaSetChEnable(DMA_CH0, DMA_HW);
    
        dmaEnable();
    
        /* Enable IRQ - Clear I flag in CPS register */
        /* Note: This is usually done by the OS or in an svc dispatcher */
    
    
        hetInit();
    
        hetREG2->HRSH &= 0xFFFF0000;
        hetREG2->AND &= 0xFFFF0000;
        hetREG2->XOR &= 0xFFFF0000;
    
        hetREG2->REQENS = (hetREG2->REQENS & 0xFFFFFF00) | ((uint32_t) (1 << DMA_CH0));
        hetREG2->REQDS = (hetREG2->REQDS & 0xFF00FF00) | ((uint32_t) (1 << DMA_CH0));
    
    
        /* Run forever */
    
            /* CORTEX request signal pin - HIGH / LOW */
        hetREG2->DIR |= (1 << PIN_HET_0);
        hetREG2->DIR |= (0 << PIN_HET_4);
        hetREG2->DIR |= (1 << PIN_HET_6);
    
        hetREG1->DIR |= (1 << PIN_HET_24);
        hetREG1->DIR |= (1 << PIN_HET_25);
        hetREG1->DIR |= (1 << PIN_HET_26);
        hetREG1->DIR |= (1 << PIN_HET_27);
        hetREG1->DIR |= (1 << PIN_HET_28);
        hetREG1->DIR |= (1 << PIN_HET_29);
        hetREG1->DIR |= (1 << PIN_HET_30);
        hetREG1->DIR |= (1 << PIN_HET_31);
    //    hetRAM2->Instruction[pHET_L00_0].Data = (hetRAM2->Instruction[pHET_L00_0].Data & 0x0000007F) | ((uint32_t) 0 << 7);
    
    
        hetRAM2->Instruction[pHET_L06_0].Program = (hetRAM2->Instruction[pHET_L06_0].Program & 0xFC7FFFFF) | ((uint32_t) DMA_CH0 << 23);
    
        hetRAM2->Instruction[pHET_L06_0].Control = (hetRAM2->Instruction[pHET_L06_0].Control & 0xFC7FFFFF) | ((uint32_t) 0x1 << 27);
    
        hetRAM2->Instruction[pHET_L09_0].Data = (hetRAM2->Instruction[pHET_L09_0].Data & 0x0000007F) | ((uint32_t) 24 << 7);
    
        while(1)
        {
            delay();
            hetRAM2->Instruction[pHET_L00_0].Data = (hetRAM2->Instruction[pHET_L00_0].Data & 0x0000007F) | ((uint32_t) 0 << 7);
        }
    
    /* USER CODE END */
    
        return 0;
    }
    
    
    /* USER CODE BEGIN (4) */
    void dmaConfigCtrlPacket(uint32 sadd,uint32 dadd,uint32 dsize)
    {
      g_dmaCTRLPKT.SADD      = sadd;              /* source address             */
      g_dmaCTRLPKT.DADD      = dadd;              /* destination  address       */
      g_dmaCTRLPKT.CHCTRL    = 0;                 /* channel control            */
      g_dmaCTRLPKT.FRCNT     = dsize;                 /* frame count                */
      g_dmaCTRLPKT.ELCNT     = 1;             /* element count              */
      g_dmaCTRLPKT.ELDOFFSET = 4;                 /* element destination offset */
      g_dmaCTRLPKT.ELSOFFSET = 0;                 /* element destination offset */
      g_dmaCTRLPKT.FRDOFFSET = 0;                 /* frame destination offset   */
      g_dmaCTRLPKT.FRSOFFSET = 0;                 /* frame destination offset   */
      g_dmaCTRLPKT.PORTASGN  = 4;                 /* port b                     */
      g_dmaCTRLPKT.RDSIZE    = ACCESS_8_BIT;     /* read size                  */
      g_dmaCTRLPKT.WRSIZE    = ACCESS_8_BIT;     /* write size                 */
      g_dmaCTRLPKT.TTYPE     = FRAME_TRANSFER ;   /* transfer type              */
      g_dmaCTRLPKT.ADDMODERD = ADDR_INC1;         /* address mode read          */
      g_dmaCTRLPKT.ADDMODEWR = ADDR_OFFSET;       /* address mode write         */
      g_dmaCTRLPKT.AUTOINIT  = AUTOINIT_ON;       /* autoinit                   */
    }
    
    void delay()
    {
        int i=0;
        for(i=0;i<300;i++)
        {
            asm(" nop ");
    
        }
    }
    
    void createTxDummyPacket(uint8_t *packet, uint32_t size)
    {
        uint32_t i = 0;
    
        for(i = 0; i < size; i++)
        {
            packet[i] = (i % 256);
        }
    }
    /* USER CODE END */
    

  • My example tells you how to trigger the DMA transfer from the NHET RAM code. Did you get the DMA triggered?

    Can you open NHET registers window to check if the data is transferred to DOUT register? 

  • I saw your example and it works perfectly in my hardware. My problem is when the destination register is the HET PINS. I don't know how to do that

  • You only need to change the destination address of DMA packet. 

    If you want to toggle HET pin 7, you have to write 0x80 to HET OUT register. Please be aware of that the RM46 is a little endian device. The bit[7:0] of DOUT register is at address &(hetREG2->DOUT) (0xFFF7B954), and bit[31:24] is at &(hetREG2->DOUT)+3 or (0xFFF7B954 + 0x3).

    Please check DOUT to make sure the value is written to correct bit field.

  • I have checked that. If you look at the source code i gave you i have the exact same inicializations as you and i have the destination adress pointing to the last 8 bits of HET1

    hetREG2->DOUT= &((uint8_t *) &(hetREG12>DOUT))[3];

    My DMA is still not working

  • You can not use REQNUM=0 to generate a DMA request.

    To generate a DMA request, the reqnum must be 4, or 5, or 6, or 7:

    Please refer to TRM: N2HET Requests to DMA and HTU

  • I use REQNUM= 6, REQ=24 and CH=0

  • Just so you know, in my debugger the Dma is working but im having trouble watching it happend with the logic analyzer. So if you check here im trying to pass 0xff to the last 8 pins of HET2.
    TX_DATA[]={0xff};




    When i go into de debug mode, this is what happens:




    So since this is little endian i know its working. but when i plug in the logic analyzer i dont see the bits going up. I am programming them as output with the default value at 0.
    Am i missing something?

  • Glad to know that the DMA works.

    Please check your pinmux configuration to make sure the PINs are assigned to N2HET1 signals

  • I got it to work perfectly. Thank you for you help. I have another question tho. My het code, when i use the dma request goes like this:





    For some reason there is always a delay associated with the dma request and the logic analyzer that i used to check the output pins.
    Everytime a dma request is made through the hetcode, there is an error of 180-200ns after i see the change in the output pins.
    Is this true everytime?

  • There is some delay between DMA request and Pin toggle. How did you capture the moment on logic analyzer when the DMA request is made?

  • in the het code i have the dma request when the pwm rises. the pwm is on het2 pin 6. the request puts information in the last 8 pins of het1. so i just plugged the logic analyzer to the ground in common, het2 pin 6 and het1 pins 24-31. i even tried to change the pwm frequency and duty cycle and the delay is always between 180-200ns with the pre escalers at LR=16 and HR=1.

  • HI Nuno,

    I know that it takes around 20 cycles for CPU to access a GPIO register, but I don't know how many cycles it will take for DMA to transfer one byte data to HET register. 

  • ok thank you very much!