A study of using PSoC 4 DMA's dual descriptors (CY8CKIT-044)

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
lock attach
Attachments are accessible only for community members.
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Hi,

As you know, the DMA of PSoC 4 has 2 descriptors to implement PING-PONG, or back-to-back buffering translation.

So I was expecting to configure them for two different translations, which will result utilizing a DMA channel just like they were a couple of DMA channels.

In my previous study, I used 8 DMA channels to implement ADC-DMA-UART for displaying human readable hexadecimal strings.

A study of simple ADC and DMA and UART (CY8CKIT-044)

020-data-flow.JPG

This time I tried to combine each ADC_RAW_H and ADC_RAW_L,  DMA_H_ADR and DMA_L_ADR into one DMA with 2 descriptors.

And also I merged 4 DMAs used to send the result output into one DMA, but it required another DMA to transfer the char addresses into the result string,

I ended up 4 DMAs total, and 3 of them are using two descriptors.

030-data-flow.JPG

Actually I have been trying to use this dual descriptor feature since I tried to write a simple oscilloscope sample.

A study of simple oscilloscope using ADC and DMA (CY8CKIT-044) version 1

But somehow I have managed to keep failing to use this feature.

This time I decided to challenge this for good, it took me more than a whole week though...

Although I could not find explicit description(s) how to do this.

Following is how I could make it work.

I use DMA_ASC for a sample.

(1) Obviously I "Number of descriptors" needs to be 2

034-DMA_ADC_Config1.JPG

(2) Descriptor 0 Configuration

Transfer mode: Entire descriptor chain per trigger

Post completion actions: "Chain to descriptor 1" (This is automatically checked.)

035-DMA_ASC_Config_desc0.JPG

(3) Descriptor 1 Configuration

Transfer mode: Entire descriptor per trigger

Post completion actions: Chain to descriptor 0

Note: For me this configuration was hard to come up with.

036-DMA_ASC_Config_desc1.JPG

Since descriptor 0 works without farther configuration, it took me very long time and many trials to figure out that

descriptor 1 needs to be manually validated

So initialization for this DMA_ASC looks like

====================

    DMA_ASC_Start((void *)h_char, (void *)(&CYDMA_DESCR_BASE.descriptor[DMA_STR_CHANNEL][0].src)) ;

    DMA_ASC_SetSrcAddress(1, (void *)l_char);

    DMA_ASC_SetDstAddress(1, (void *)(&CYDMA_DESCR_BASE.descriptor[DMA_STR_CHANNEL][1].src)) ;

    CyDmaValidateDescriptor(DMA_ASC_CHANNEL, 1) ;

====================

With above modification(s), the schematic was modified

from  the previous schematic

012-schematic.JPG

to the current schematic

032-schematic.JPG

Pins

033-Pins.JPG

Tera Term log

031-TeraTerm-log.JPG

main.c

========================

#include "project.h"

#include "stdio.h"

#include "ascii_byte_table.h"

uint32_t h_char_address = (uint32_t) ascii_h ;

uint32_t l_char_address = (uint32_t) ascii_l ;

uint8_t *h_char = (void *)&h_char_address ;

uint8_t *l_char = (void *)&l_char_address ;

char out_str[7] = { '0', 'x', 'H', 'L', '\n', '\r', '\0' } ;

void init_hardware(void)

{   

    CyGlobalIntEnable; /* Enable global interrupts. */   

   

    UART_Start() ;

   

    ADC_Start() ;

   

    DMA_UART_Start((void *)out_str, (void *)UART_TX_FIFO_WR_PTR) ;

  

    DMA_STR_Start((void*)h_char, (void *)(&out_str[2])) ;

    DMA_STR_SetSrcAddress(1, (void *)l_char);

    DMA_STR_SetDstAddress(1, (void *)(&out_str[3])) ;

    CyDmaValidateDescriptor(DMA_STR_CHANNEL, 1) ;

   

    DMA_ASC_Start((void *)h_char, (void *)(&CYDMA_DESCR_BASE.descriptor[DMA_STR_CHANNEL][0].src)) ;

    DMA_ASC_SetSrcAddress(1, (void *)l_char);

    DMA_ASC_SetDstAddress(1, (void *)(&CYDMA_DESCR_BASE.descriptor[DMA_STR_CHANNEL][1].src)) ;

    CyDmaValidateDescriptor(DMA_ASC_CHANNEL, 1) ;

    DMA_ADC_Start((void *)ADC_SAR_CHAN0_RESULT_PTR, (void *)h_char) ;

    DMA_ADC_SetSrcAddress(1, (void *)h_char) ;

    DMA_ADC_SetDstAddress(1, (void *)l_char) ;

    CyDmaValidateDescriptor(DMA_ADC_CHANNEL, 1) ;

}

int main(void)

{   

    init_hardware() ;

   

    UART_UartPutString("\x1b[2J\x1b[;H") ;

    UART_UartPutString("ADC-DMA-UART 2-descriptors Test\n\r") ;

   

    Timer_Start() ;

       

    for(;;)

    {

    }

}

========================

ascii_byte_table.h

========================

#ifndef _ASCII_BYTE_TABLE_H_

#define _ASCII_BYTE_TABLE_H_

#include "project.h"

   

extern const uint8_t ascii_h[256] ;

extern const uint8_t ascii_l[256] ;

#endif

========================

ascii_byte_table.c

========================

#include "project.h"

#include "ascii_byte_table.h"

const uint8_t ascii_h[256]

__ALIGNED(0x100u)

= {

'0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',

'1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1',

'2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2',

'3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3',

'4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4',

'5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5',

'6', '6', '6', '6', '6', '6', '6', '6', '6', '6', '6', '6', '6', '6', '6', '6',

'7', '7', '7', '7', '7', '7', '7', '7', '7', '7', '7', '7', '7', '7', '7', '7',

'8', '8', '8', '8', '8', '8', '8', '8', '8', '8', '8', '8', '8', '8', '8', '8',

'9', '9', '9', '9', '9', '9', '9', '9', '9', '9', '9', '9', '9', '9', '9', '9',

'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',

'B', 'B', 'B', 'B', 'B', 'B', 'B', 'B', 'B', 'B', 'B', 'B', 'B', 'B', 'B', 'B',

'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C',

'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D',

'E', 'E', 'E', 'E', 'E', 'E', 'E', 'E', 'E', 'E', 'E', 'E', 'E', 'E', 'E', 'E',

'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F'

} ;

const uint8_t ascii_l[256]

__ALIGNED(0x100u)

= {

'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',

'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',

'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',

'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',

'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',

'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',

'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',

'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',

'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',

'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',

'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',

'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',

'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',

'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',

'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',

'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'

} ;

========================

moto

0 Replies