PE DMA modify address adjustment at runtime

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 
已解决

PE DMA modify address adjustment at runtime

跳至解决方案
1,061 次查看
andrewparlane
Contributor IV

Hi,

I'm setting up my project using PE. I have a UART, DMA controller, 2 DMA channels, etc... I can transmit data using DMA and receive it. However I haven't found a decent way of transmitting a variable amount of bytes. Say my DMA TX buffer is 512 bytes, and I want to send a 20 byte packet, I need to change the request count size, which is easy to do using: UART_TX_DMA_SetRequestCount(). However I also want to change the "after transfer complete source address adjustment" to go back to the beginning of my buffer.

I could do this manually, IE. disable this option in PE, and when I receive my dma complete event, change the source address using UART_TX_DMA_SetSourceAddress(). Or I can change the address adjust manually using register writes: DMA_TCD4_SLAST = DMA_SLAST_SLAST(0-size); (note this may be the wrong code to use, I can't test it until Monday). However this makes the assumption that I'm using DMA Channel 4 for this. Which is fine until I change that and forget to change this line of code.

I would like to be able to do one of:

1) UART_TX_DMA_SetAfterTransferSourceAddressAdjust(..., 0-size);

2) DMA_SLAST_REG(DMA_BASE_PTR, UART_TX_DMA_CHANNEL_NUM) = DMA_SLAST_SLAST(0-size); // Note the CHANNEL_NUM define doesn't exist like this. I could try and get access to the DMAController_TChnInit struct and get the logical channel number, and from the physical channel number, but that's quite messy, and that data is largely defined in .c files Including the DMAController_TDevConst struct, which would make it a bit nasty to get the info.

Am I missing something? Or is PE missing this feature?

Using KDS 1.1.0, PE 1.1.0.RT6_b1428-0121, windows 7.

Thanks,

Andy

标签 (1)
标记 (2)
0 项奖励
回复
1 解答
829 次查看
MVa
NXP Employee
NXP Employee

Hi Andy,

  try this:

void UART_TX_DMA_SetAfterTransferSourceAddressAdjust(LDD_TDeviceData *DeviceDataPtr, int32_t AddressAdjustment)

{

  (*((DMA1_TTCD **)DeviceDataPtr))->DMA_TCD_SLAST_Reg = (uint32_t)AddressAdjustment;

}

int main(void) {

    LDD_TDeviceData* hDmaChannel;

  /*** Processor Expert internal initialization. DON'T REMOVE THIS CODE!!! ***/

  PE_low_level_init();

  /*** End of Processor Expert internal initialization.                    ***/

  hDmaChannel = UART_TX_DMA_Init(NULL);

  UART_TX_DMA_SetSourceAddress(hDmaChannel, (LDD_DMA_TData *)0x12345678);

  UART_TX_DMA_SetAfterTransferSourceAddressAdjust(hDmaChannel, -2);

 

} /*** End of main routine. DO NOT MODIFY THIS TEXT!!! ***/

Note: hDmaChannel returned by UART_TX_DMA_Init() method is pointer to DMA1_TChnDevData structure:

/* Channel device data structure prototype */

typedef struct DMA1_TChnDevData_stuct {

  DMA1_TTCD                                 *TCDPtr;                        /*!< Channel TCD address */

  DMA1_TChnDevConst const        *ChnDevConstPtr;         /*!< Channel device constants structure address */

  LDD_DMA_TErrorFlags                  ErrorFlags;                   /*!< Channel error flags */

  LDD_TUserData                            *UserDataPtr;                /*!< User data pointer */

  DMA1_TEvents                               Events;                          /*!< Events state variable */

} DMA1_TChnDevData, *DMA1_TChnDevDataPtr;

As you can see the first item in the TChnDevData structure is:

  DMA1_TTCD                                 *TCDPtr;                        /*!< Channel TCD address */

This TCDPtr pointer is initialized in the UART_TX_DMA_Init() method to the TCD address of the selected DMA channel (=address of real HW registers for this DMA channel).

Best Regards

Marek Varecha

在原帖中查看解决方案

0 项奖励
回复
2 回复数
830 次查看
MVa
NXP Employee
NXP Employee

Hi Andy,

  try this:

void UART_TX_DMA_SetAfterTransferSourceAddressAdjust(LDD_TDeviceData *DeviceDataPtr, int32_t AddressAdjustment)

{

  (*((DMA1_TTCD **)DeviceDataPtr))->DMA_TCD_SLAST_Reg = (uint32_t)AddressAdjustment;

}

int main(void) {

    LDD_TDeviceData* hDmaChannel;

  /*** Processor Expert internal initialization. DON'T REMOVE THIS CODE!!! ***/

  PE_low_level_init();

  /*** End of Processor Expert internal initialization.                    ***/

  hDmaChannel = UART_TX_DMA_Init(NULL);

  UART_TX_DMA_SetSourceAddress(hDmaChannel, (LDD_DMA_TData *)0x12345678);

  UART_TX_DMA_SetAfterTransferSourceAddressAdjust(hDmaChannel, -2);

 

} /*** End of main routine. DO NOT MODIFY THIS TEXT!!! ***/

Note: hDmaChannel returned by UART_TX_DMA_Init() method is pointer to DMA1_TChnDevData structure:

/* Channel device data structure prototype */

typedef struct DMA1_TChnDevData_stuct {

  DMA1_TTCD                                 *TCDPtr;                        /*!< Channel TCD address */

  DMA1_TChnDevConst const        *ChnDevConstPtr;         /*!< Channel device constants structure address */

  LDD_DMA_TErrorFlags                  ErrorFlags;                   /*!< Channel error flags */

  LDD_TUserData                            *UserDataPtr;                /*!< User data pointer */

  DMA1_TEvents                               Events;                          /*!< Events state variable */

} DMA1_TChnDevData, *DMA1_TChnDevDataPtr;

As you can see the first item in the TChnDevData structure is:

  DMA1_TTCD                                 *TCDPtr;                        /*!< Channel TCD address */

This TCDPtr pointer is initialized in the UART_TX_DMA_Init() method to the TCD address of the selected DMA channel (=address of real HW registers for this DMA channel).

Best Regards

Marek Varecha

0 项奖励
回复
829 次查看
andrewparlane
Contributor IV

Thanks, that's much neater than my methods, so I'll move to that.

However it still would be nice to have an auto-generated method for this, or alternatively an auto-generated #define for the channel number.

I get that you can't add everything possible to every component, but this seems like quite an important one, seeing as it's quite likely you'll want to transmit different amounts of data every time.

EDIT 2: After testing and debugging, I found the correct line to use was: (*(DMAController_TTCDPtr *)IUART_TX_DMA_DeviceData)->DMA_TCD_SLAST_Reg = DMA_SLAST_SLAST(0-size);

We must be using slightly different versions of PE since my struct had a different name.

Thanks again,

Andy

0 项奖励
回复