PE DMA modify address adjustment at runtime

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 

PE DMA modify address adjustment at runtime

ソリューションへジャンプ
1,611件の閲覧回数
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 解決策
1,379件の閲覧回数
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 返答(返信)
1,380件の閲覧回数
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 件の賞賛
返信
1,379件の閲覧回数
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 件の賞賛
返信