5 Replies Latest reply on Oct 29, 2020 11:16 PM by NoTa_4591161

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

    MoTa_728816

      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.

      (5) Then the table address value will be DMAed to the source address of Letter to UART DMA. (DMA_H_ADR and DMA_L_ADR)

       

      020-data-flow.JPG

       

      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...

      012-schematic.JPG

      Pins

      003-pins.JPG

      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() ;

       

          ADC_Start() ;

       

          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_H_ADR_Start((void *)h_char, (void *)(&CYDMA_DESCR_BASE.descriptor[DMA_ASC_H_CHANNEL][0].src)) ;

          DMA_L_ADR_Start((void *)l_char, (void *)(&CYDMA_DESCR_BASE.descriptor[DMA_ASC_L_CHANNEL][0].src)) ;

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

          DMA_RAW_L_Start((void *)ADC_SAR_CHAN0_RESULT_PTR, (void *)l_char) ;

       

          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_H_ADR: ") ;

          dump_dma_ch(DMA_H_ADR_CHANNEL) ;

          print("DMA_L_ADR: ") ;

          dump_dma_ch(DMA_L_ADR_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",

              h_char_address, l_char_address) ;

          print(str) ;

          print("\n\r") ;

      }

       

      int main(void)

          init_hardware() ;

       

          splash("ADC-DMAx2 Test") ;

          print("\n\r") ;

       

          Timer_Start() ;

           

          for(;;)

          {

          }

      }

       

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

       

      Tera Term log

      010-TeraTerm-log.JPG

       

      moto

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