- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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)
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() ;
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
moto
P.S. Diagram for data flow added 25-Oct-2020
- Labels:
-
PSoC 345 LP
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Moto-san,
I think you can reduce the number of DMA channels as follows.
Regards,
Kenshow
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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