Attachments are accessible only for community members.

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

Level 9
Level 9
Distributor - Marubun (Japan)

Hi,

As I accumulated homework in my previous sample/study,

I wanted attack one by one.

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

So the first one I challenged was

Display ADC value into UART without using CPU (except initialization).

As you know, the result of ADC component is a binary value,

I must figure out (aka hack) a way to convert a binary value into UART readable ascii letters.

Of course if we use CPU, it's a peace of cake, but without CPU it was not.

After a few days of struggle I came up with the following trick.

(1) I limit the result value of ADC as 8bit. So it's a couple of ascii letters, such as "00" "1A", etc.

(2) I prepared a couple tables which has the upper letter and the lower letter of the value.

(3) At first I assign the beginning of the above tables into the letter to UART DMA. (DMA_ASC_H and DMA_ASC_L)

(4) Each ADC results, the value will be DMAed to the LSB of each table address variable(s). (DMA_RAW_H and DMA_RAW_L)

Note: As a register is 4 bytes structure, I needed to create a 4 bytes variable then DMA the variable word to word.

The higher nibble letter table

Note: For the trick, the table is aligned to 0x100 boundary.

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

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'

} ;

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

The lower nibble letter table

Note: For the trick, the table is aligned to 0x100 boundary.

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

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'

} ;

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

Note ascii_h[0xAB] = 'A' and ascii_l[0xAB] = 'B'

Schematic

Almost a Rube Goldberg machine...

Pins

main.c

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

#include "project.h"

#include "stdio.h"

#include "tty_utils.h"

#include "ascii_byte_table.h"

#define DEBUG_INFO 0

uint32_t h_char_address = (uint32_t) ascii_h ;

uint32_t l_char_address = (uint32_t) ascii_l ;

uint8_t *h_char = (uint8_t *)&h_char_address ;

uint8_t *l_char = (uint8_t *)&l_char_address ;

volatile int dma_done_flag = 0 ;

CY_ISR(dma_done_isr)

{

dma_done_flag = 1 ;

}

void init_hardware(void)

CyGlobalIntEnable; /* Enable global interrupts. */

tty_init() ;

DMA_PRE_Start(  (void *)prefix, (void *)UART_TX_FIFO_WR_PTR) ;

DMA_ASC_H_Start((void *)h_char, (void *)UART_TX_FIFO_WR_PTR) ;

DMA_ASC_L_Start((void *)l_char, (void *)UART_TX_FIFO_WR_PTR) ;

DMA_EOL_Start(  (void *)eol,    (void *)UART_TX_FIFO_WR_PTR) ;

dma_done_int_ClearPending() ;

dma_done_int_StartEx(dma_done_isr) ;

}

void dump_dma_ch(int ch)

{

snprintf(str, STR_BUF_LEN, "DMA%d\n\r", ch) ;

print(str) ;

print("descriptor 0 :") ;

snprintf(str, STR_BUF_LEN, "0x%08X -> 0x%08X CTRL:0x%08X Status:0x%08X\n\r",

(uint32_t)CYDMA_DESCR_BASE.descriptor[ch][0].src,

(uint32_t)CYDMA_DESCR_BASE.descriptor[ch][0].dst,

(uint32_t)CYDMA_DESCR_BASE.descriptor[ch][0].ctl,

(uint32_t)CYDMA_DESCR_BASE.descriptor[ch][0].status

) ;

print(str) ;

print("descriptor 1 :") ;

snprintf(str, STR_BUF_LEN, "0x%08X -> 0x%08X CTRL:0x%08X Status:0x%08X\n\r",

(uint32_t)CYDMA_DESCR_BASE.descriptor[ch][1].src,

(uint32_t)CYDMA_DESCR_BASE.descriptor[ch][1].dst,

(uint32_t)CYDMA_DESCR_BASE.descriptor[ch][1].ctl,

(uint32_t)CYDMA_DESCR_BASE.descriptor[ch][1].status

) ;

print(str) ;

}

void dump_dma(void)

{

print("DMA_RAW_H:  ") ;

dump_dma_ch(DMA_RAW_H_CHANNEL) ;

print("DMA_RAW_L:  ") ;

dump_dma_ch(DMA_RAW_L_CHANNEL) ;

print("DMA_ASC_H:  ") ;

dump_dma_ch(DMA_ASC_H_CHANNEL) ;

print("DMA_ASC_L:  ") ;

dump_dma_ch(DMA_ASC_L_CHANNEL) ;

print("DMA_PRE:    ") ;

dump_dma_ch(DMA_PRE_CHANNEL) ;

print("DMA_EOL:    ") ;

dump_dma_ch(DMA_EOL_CHANNEL) ;

print("DMA_ASC_LF:  ") ;

snprintf(str, STR_BUF_LEN, "h_char: 0x%08X l_char: 0x%08X\n\r",

print(str) ;

print("\n\r") ;

}

int main(void)

init_hardware() ;

print("\n\r") ;

Timer_Start() ;

for(;;)

{

}

}

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

Tera Term log

moto

P.S. Diagram for data flow added 25-Oct-2020

5 Replies

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

Level 8
Level 8
Distributor - Marubun (Japan)

Hi Moto-san,

I think you can reduce the number of DMA channels as follows.

Regards,

Kenshow

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

Level 9
Level 9
Distributor - Marubun (Japan)

Dear Kenshow-san,

Thank you very much for your suggestion!

BTW, I wonder if we can transfer nibble to nibble by using DMA.

0xAB is 8bit (= 1 byte)

0xA is 4bit (= 1 nibble)

So, I'm afraid that we can not add 0xA to 0x150 to create 0x15A.

I will think if we can do something like that.

Best Regards,

30-Oct-2020

Motoo Tanaka

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

Level 8
Level 8
Distributor - Marubun (Japan)

Dear Motoo-san,

Okey, we should consider using bitband aliases. Please refer to the following web.

ビットバンド | APS｜半導体技術コンテンツ・メディア  (I'm sorry in Japanese)

Best Regards,

Kenshow

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

Level 9
Level 9
Distributor - Marubun (Japan)

Dear Kenshow-san,

That is a good information!

If we can use this feature, the character table can be only 16 bytes.

....

As we talked over chat, the only drawback was neither PSoC4 nor PSoC 6 (63) supports this feature...

Well, let's not worry!

It's Friday!

Best Regards,

30-Oct-2020

Motoo "Trick or Retreat!" Tanaka

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

Level 8
Level 8
Distributor - Marubun (Japan)

Dear Motoo-san,

It was very disappointing that my idea could not be realized.

I think you can leave the 256-byte table as it is and reduce the DMA channels. I modified the figure a little. Please refer to it in the future.

Best Regards,

Kenshow