Página 1 de 2

Interpretação DMA.

MensagemEnviado: 13 Mar 2012 13:21
por fabim
Pessoal, depois de 3 anos mexendo com ARM, eu resolvi que vou precisar utilizar o DMA no novo projeto.
Eu estou tentando interpretar a forma operacional dele.

Se eu pude entender bem.
Se eu setar ORIGEN RAM, DESTINO RAM, a velocidade que ele vai transferir os dados, é igual a CLOCK setado para o dito DMA.
Se eu setar ORIGEN RAM, DESTINO FLASH, a velocidade é igual ao setado pelo periférico destino.

Por exemplo vou utilizar o DMA da ram para a SPI por exemplo.
Eu seto o clock rate da SPI para 10khz por exemplo.
E também seto 256 bytes.

O hardware do DMA recebe algum tipo de sinalização da SPI que informa que ja pode mandar outro byte pois o outro foi transferido. Desta forma a velocidade de transferencia do DMA segue a máxima velocidade configurada pela SPI.

Isto também se aplica ao I2S por exemplo ?

Abraços

Fabim

MensagemEnviado: 13 Mar 2012 15:01
por proex
Oh Zigoto, presta atenção,................ tá prestando?

Não existe DMA entre memoria e periférico. O que existe é DMA entre memoria e Buffer do periferico.

Seu periférico pode estar rodando com clock de 100hz por exemplo, mas o buffer desse periferico será lido pelo DMA na velocidade que vc especificou pra o DMA.

Vai te catar.

MensagemEnviado: 13 Mar 2012 15:13
por fabim
proex escreveu:Oh Zigoto, presta atenção,................ tá prestando?

Não existe DMA entre memoria e periférico. O que existe é DMA entre memoria e Buffer do periferico.

Seu periférico pode estar rodando com clock de 100hz por exemplo, mas o buffer desse periferico será lido pelo DMA na velocidade que vc especificou pra o DMA.

Vai te catar.


Não não!!
OS LPC possuem 3 módos de operação.

Periferal to Memory Ram
Memory Ram to Periferal
Memory Ram to Memory Ram

Não existe controle de velocidade para o DMA, ele opera na velocidade de clock da RAM, caso seja setado de RAM para RAM.

Agora, de RAM para periferal, eu não estou conseguindo imaginar como funciona.
Periferal, eu imagino que o flag de byte recebido crie algum tipo de togle no DMA que irá incrementar o contador de 8 bits até o math, gerando uma interrupção.

Entende ?

MensagemEnviado: 13 Mar 2012 15:37
por mastk
Isso fabim, no PC, por exemplo tem pinos de REQUISITAR_TRANSFERENCIA_DE_DMA, para que o periferico só receba dados quanto estar apto para.


...Se não me falha a memoria...

MensagemEnviado: 13 Mar 2012 15:38
por tcpipchip
Opa...

Eu e outros daqui lembram do STM32 CIRCLE OS...pois bem....uma vez eu joguei dentro dele um Software para EGC...e ele utiliza-va DMA para acessar o ADC e jogar num BUFFER...achei legal...aqui um resumo do AUTOR...

Código: Selecionar todos
ECG Data Acquisition

The ECG signal is digitized by ADC1 (channel 2, AIN2). The sampling rate is 480/sec. ADC1 is set to the single conversion mode with the external event triggering the conversion. The conversion trigger source is the Timer1 (TIM1) channel 1. The prescaler of TIM1 is set to 24 while the modular register (Auto-reload register TIM1_ARR) is set to 6250. The system clock frequency is 72MHz and the TIM1 channel output is 72MHz / 24 / 6250 = 480 Hz. DMA channel 1 is setup for transfer the ADC sampled data from the ADC regular data register (ADC_DR) to a memory buffer. The memory buffer size is 240 bytes to hold 120 16-bit data entries, which is size for a period of ¼ second. The DMA Half-Transfer-Interrupt (HTIE), Transfer-Complete-Interrupt (TCIE) and destination memory address auto-increment mode are enabled. The DMA channel 1 destination address is increased each time a sampled data is transferred to the memory buffer until it reaches to the end of the buffer. Then the DMA is automatically wraps the destination address back to the beginning of the memory buffer to form a circular buffer scheme. The double buffering (or so called Ping-Pong buffering) is made by the dual interruptions. When the memory buffer is filled with half of the buffer size data, the Half-Transfer-Interrupt flag (HTIF) is set and signal an interruption. The interrupt service routine (ISR) is activated and a global pointer (for ECG data rendering) is set to point the beginning of the memory buffer. The data in first half of the memory buffer (60 data entries), therefore, is being processed by the ECG data rendering procedure (in the Application_Handler function) while the DMA continue transferring the ADC sampled data to the second half of the memory buffer. When the memory buffer is full, the Transfer-Complete-Interrupt flag (TCIF) is set and there ISR is activated again. At this time, the global pointer is pointing to middle of the memory buffer. So the ECG data rendering procedure processes the data in second half of the memory buffer while the DMA continues transferring the DAC sampled data to first half of the memory buffer (see Figure 2). In this way, the data acquisition and data rendering is decoupled without pending each other. The chunk of the buffered data (representing the period of 1/8 second) is served at 8 Hz.


ECG Data Rendering

The ECG render procedure is in the Application_Handler function. While the Application_Handler function is activated at 30Hz (when sysclk = 72MHz), the ADC data buffer for process is at a rate of 8 Hz. The global pointer (pointing to the memory buffer) is evaluated each time the Application_Handler function is called. If the global pointer is not null (a block data is ready), the ECG data rendering procedure starts. The data is first processed by a 4th order Chebyshev IIR (Infinite Impulse Response) low pass digital filter (LPF). The LPF cut-off frequency is set to 40 Hz to remove the higher frequency noise (including the 60 Hz AC interference at USA and 50 Hz AC interference at Europe). In order to speed the filtering process and reduce the code size, the fixed point process instead of floating point process is used in the filtering. All the coefficients are pre-scaled by 65536. Only integer multiplications are involved during the calculation. The final result is then shifted 16-bit right (equivalent divided by 65536). The filter procedure also reduces the data rate by 4 times for easy rendering at the low resolution
LCD display. The filtered data (reduced to 15 bytes) is then rendered at the LCD display. In order to increase the ECG trace drawing efficiency and avoid the display flickering, the LCD hardware scroll function is used. First, the entire LCD drawing is shift to left 15 pixels by the LCD scrolling commands (the SCRLAR and VSCSAD commands). Then the 15 pixels wide area at right most of the screen is erased. The new trace is drawn on the erased area. In this way, the ECG trance is continuously scrolling from right to left on the screen at the 8 Hz update rate without the screen flickering.
In order to calculate the heart rate, a threshold based QRS wave detector is used. The threshold is also drawn at the screen for visual assessment. If the signal is over the threshold, a short beep is on and the red LED flashes to indicate the heart pulse. The interval between the detected QRS waves is converted to heart rate and displayed on the up-left corner of the LCD display. A hysteresis at the threshold and an inhibiting period are used to avoid the mistake triggering by the noise or high T-wave.


USB Data Transfer


Besides drawing the ECG trace on the LCD display screen, the device also sends the ECG data to a PC through the USB port (the USB port behind the pushbutton). The USB data transfer is using the Human Interface Device (HID) class. The code implementation references the PrimerMouse project posted on the stm32circle.com website. The HID report descriptor is rewritten. Instead of the predefined mouse and pointer device, the report descriptor usage page and the usage are vendor defined classes. The input report size set to 16 for the16-bit ECG data and the report count is set to 60 for sending the entire block of the ECG data at once. Other descriptors are also modified accordingly. When the block of ECG data is ready, besides the trace rendering the Application_Handler function also copies the ECG data to the 512-byte USB dedicated SRAM memory for the input report at Endpoint 1. Because the data block is ready every 128 ms (in 8 Hz), the interrupt (polling) interval is set to 64 ms for guaranteeing there is no missing for the input report. When the device senses the report request, if the data is ready the device sends the data to the host PC.
PC USB Handler and ECG Display Software
The PC USB handler and ECG display program is written in Windows .NET environment using the C# language. Figure 6 is screenshot of the PC host GUI. Since the PC software development is not in the scope of the contest, detail description is omitted.
However, the PC software executable is provided in the uploaded zip file (require .NET framework 2.0 or later installed).


Talvez ajude :)

Abraços

XIP

MensagemEnviado: 13 Mar 2012 15:44
por fabim
Nussa, só dizer se sim ou não. C quer me matar em miguel ? Eu li o texto e entendi menos ainda como funciona...

MensagemEnviado: 13 Mar 2012 18:32
por msamsoniuk
eu pensei que a galera que mexia com ARM estava mais adiantada! ;D

em qualquer processador do universo:

- memoria para memoria: a velocidade de leitura depende da velocidade programada no chip-select da memoria de leitura e a velocidade de escrita depende da velocidade programada no chip-select da memoria de escrita. portanto: de ram para flash ele le em velocidade de ram e escreve em velocidade de flash (obvio). de ram para ram, ele le em velocidade de ram e escreve em velocidade de ram (novamente obvio). e de flash para ram ele le na velocidade da flash e escreve na velocidade da ram (triplo-obvio! nao tem pegadinhas aqui). normalmente o start do dma eh condicionado a um flag e um contador de tamanho: uma vez startado, ele soh para quando atinge o fim do contador. e finalmente, alguns controladores permitem controlar o bandwidth, inserindo esperas entre uma transferencia e outra, para variar o uso e permitir o processador usar em paralelo.

- memoria para periferico: tipica transferencia condicionada pela escrita no periferico. a velocidade de leitura da memoria depende do chip-select da memoria e a velocidade de escrita depende do chip-select do periferico. a existencia de fifo de escrita ou nao eh irrelevante e encapsulada no periferico (se for um periferico sincrono, como ethernet, a fifo interna eh essencial) e vc nao precisa entender ou conhecer isso. o que vc precisa saber eh que cada transferencia eh determinada por um dma request por parte do periferico. se vc tem um i2c e ele tem suporte a dma, ele vai fazer um dma request periodico. senao nao.

- periferico para memoria: novamente, condicionada pelo periferico, mas agora na leitura. a velocidade de leitura depende do chip-select do periferico e a velocidade de escrita depende do chip-select da memoria. vale o mesmo para buffer e dma request. se o periferico tem dma request, ele periodicamente ativa o dma, senao nao.

exemplo 1:

transferir a flash p/ a ram (tecnica conhecida como shadow): seta o src com o inicio da flash, o dst como inicio da ram, o size com o tamanho da flash e seta o bit de start do dma. faz um loop lendo o bit done no status register do dma, o que indica que a transferencia terminou. se a velocidade da ram eh 1 clock por word, a velocidade da flash 4 clocks por word, entao cada transferencia requer 5 clocks.

exemplo 2:

serial assincrona a 115200 full-duplex com dma: precisa de dois canais, um para o rx path e outro para o tx path. no rx path temos o dma1, com o src1 o endereco uart_rxfifo e dst1 o buffer de recepcao. o size fica como o tamanho do buffer e liga a interrupcao de overflow. o start nao eh ativado, pq sera ativado por dma request e, quando o buffer encher, vc tera uma interrupcao p/ trocar de buffer e processar o buffer cheio. quando chega um byte na uart, ela ativa o dma request e eh feita uma transferencia. e assim vai de um em um. se a velocidade da uart eh 115200 e cada byte consome 10 bits, vc tem 11520 dma request por segundo. se o tempo de acesso dos registros da uart consomem 4 clocks e ram apenas 1, vc tem 5 clocks por transferencia. portanto, para os 11520 transferencias, vc consome 57600 clocks. no dma2, para o tx, vc seta o src2 como o buffer de transmissao, o dst2 como o uart_txfifo e o size como o tamanho do buffer, com uma interrupcao p/ indicar o fim do buffer transferido. a uart vai gerar um dma request cada vez q a fifo estiver vazia, nos mesmos moldes do rx e vc vai ter, da mesma forma, 57600 clocks. no fim de cada buffer vc tem uma interrupcao p/ indicar que o buffer de dma esta vazio.

portanto o consumo total na maxima cadencia de transferencia da sua uart assincrona com dma vai ser de 115200 clocks. note que, se a uart vai ter fifo ou nao, nao eh muito relevante para vc.

as coisas funcionam dessa forma praticamente em qq processador. claro, tem variacoes: nos coldfires q eu uso, por exemplo, os controladores de dma tem contadores de tamanho maior e menor, q permitem transferencias de areas bi-dimensionais, listas encadeadas de buffers ou listas infinitas com auto-reload. mas daih eh outro nivel neh...

entao fabim, entendeu o quer que desenhe?

MensagemEnviado: 14 Mar 2012 08:40
por fabim
Ou seja, o DMA REQ, é coisa interna e não tem nada haver com o processo.
Quando eu seto RAM to PERIF, o PERIF envia um DMA REQ para o DMA e ele por sua vez vai mandando BtB até que o contador chegue ao fim, neste momento caso tenha setado o bit DONE causa uma interrupção, e eu sei que ja foram enviados os X bytes. O mesmo acontece na recepção de PERI to RAM, etc.

É entendi sim.

Resumindo na pratica.

Eu configurei o I2S para 22050*16*1.
Quando eu setar os 256 bytes da ram para I2S, a transferencia nao irá atropelar um byte com outro, ele irá esperar o DMA REQ para que o hW envie o proximo word.
Desta forma, eu vou ter um sample rate de 22050hz.

O Mesmo seria para a Serial, I2C, ou SPI.
Faz logicamente todo sentido do mundo, mais como eu não achei configuração afinada para o DMA, eu fiquei na duvida sobre isso.

MensagemEnviado: 14 Mar 2012 08:50
por albertorcneto
Marcelo Samsoniuk escreveu:portanto o consumo total na maxima cadencia de transferencia da sua uart assincrona com dma vai ser de 115200 clocks. note que, se a uart vai ter fifo ou nao, nao eh muito relevante para vc.

as coisas funcionam dessa forma praticamente em qq processador. claro, tem variacoes: nos coldfires q eu uso, por exemplo, os controladores de dma tem contadores de tamanho maior e menor, q permitem transferencias de areas bi-dimensionais, listas encadeadas de buffers ou listas infinitas com auto-reload. mas daih eh outro nivel neh...

entao fabim, entendeu o quer que desenhe?


Ate onde eu sei, o tamanho da buffer fifo eh relevante porque o periferico transfere todo o buffer antes de gerar uma interrupcao de fim de buffer. Ou entendi o que voce explicou errado?

O OMAP3530 (da Beagleboard) pelo menos tambem tem transferencia bidimensional e acho que auto-reload tambem.

MensagemEnviado: 14 Mar 2012 11:36
por msamsoniuk
albertorcneto escreveu:
Marcelo Samsoniuk escreveu:portanto o consumo total na maxima cadencia de transferencia da sua uart assincrona com dma vai ser de 115200 clocks. note que, se a uart vai ter fifo ou nao, nao eh muito relevante para vc.

as coisas funcionam dessa forma praticamente em qq processador. claro, tem variacoes: nos coldfires q eu uso, por exemplo, os controladores de dma tem contadores de tamanho maior e menor, q permitem transferencias de areas bi-dimensionais, listas encadeadas de buffers ou listas infinitas com auto-reload. mas daih eh outro nivel neh...

entao fabim, entendeu o quer que desenhe?


Ate onde eu sei, o tamanho da buffer fifo eh relevante porque o periferico transfere todo o buffer antes de gerar uma interrupcao de fim de buffer. Ou entendi o que voce explicou errado?

O OMAP3530 (da Beagleboard) pelo menos tambem tem transferencia bidimensional e acho que auto-reload tambem.


eh relevante para o tamanho do buffer, mas normalmente os buffers sao muito maiores que as fifos. a dinamica da fifo do periferico pode ser encarada como uma caixa preta desenhada para evitar que dispositivos sincronos engasguem por latencia de acesso ao dma. por exemplo, suponha que vc tem uma memoria de 8 bits clockada a 50MHz e que consome 2 clocks por acesso. entao vc tem 25MB/s de bandwidth para dividir com o dma e processador. imagine entao que vc tem 4 controladores de dma. o pior caso possivel de latencia seria o processador jah estar usando o bus e os outros tres canais jah terem priorizado seus acessos. a latencia vai ser de 8 clocks de 50MHz ateh o seu canal conseguir acessar.

daih suponha que vc tem uma ethernet de 100mbps. cada byte chega a cadencia de 12.5MB/s, ou seja, equivalente a 4 clocks de 50MHz. o lado receptor nao tem controle de fluxo e nao para depois q comeca um frame, portanto eh possivel que cheguem 2 bytes naquele tempo de latencia do controlador de dma. normalmente desenhamos as fifos "seguras" em um layout de double buffer, onde o tamanho da janela de entrada eh do tamanho da janela de saida, assim vc teria uma fifo de 4 bytes.

isso em certas condicoes. se vc extender o problema, tem a questao de chip-selects externos. supondo que o processador esta acessando um periferico externo e os outros 3 canais tambem, e que este periferico tem wait-states, a latencia p/ tomar o bus aumenta. e com isso o tamanho da fifo para o controlador ethernet tem que aumentar. o que eu tenho visto na pratica sao fifos de 16 bytes nos controladores que eu chamaria de "arrojados". nessa condicao, ele pode ter uma latencia equivalente a 64 clocks de 50MHz. uma vez conseguindo tomar o bus, ele vai limpar a fifo de 16 bytes ou o que tiver disponivel em uma rajada e parar. daih o ciclo recomeca e, claro, ele fica novamente sujeito a latencia.

mas vc nao precisa necessariamente conhecer esse mecanismo. o que vc precisa conhecer eh algo mais alto nivel: o frame sera transferido via dma e ele nao vai parar! entao esqueca a parte da fifo e concentre-se no mecanismo como um todo: o mtu do frame ethernet tipico eh de 1500 bytes e o controlador pode anexar descritores com flags e crc. entao uma boa pratica eh alocar um buffer p/ o dma da ordem de 1516 bytes. independente entao do tamanho da fifo, vc precisa suprir a necessidade de alto nivel do controlador, pq nao dah tempo de trocar o buffer no meio da recepcao de um frame.

os controladores que tem auto-reload integrado sao interessantes pq no exemplo da ethernet eles nao parariam depois de transferir um frame: eles fariam reload dos registros do controlador p/ apontar para o proximo buffer automaticamente. a interrupcao eh necessaria pq vc precisa ir processando os frames jah recebidos, mas o recurso permitiria receber frames em cadencias mais rapida que o processamento, evitando problemas com latencias (por exemplo, o processador pode estar atendendo outra interrupcao mais importante).

o coldfire tem auto-reload, mas o powerpc tem um negocio mais legal ainda: ring buffers. os ring buffers sao listas com listas de ponteiros para buffers. se nao me falha a memoria, cada descritor (ele tem centenas de descritores) corresponde a um canal de dma (portanto ele tem centenas de canais independentes) e aponta para uma lista de descritores de buffers (cada entrada eh um buffer) que sao usados em sequencia (por isso o termo ring buffer). os limites, se nao me falham a memoria, sao 16384 descritores de buffers e cada buffer tipicamente tem o tamanho de um frame (1516 bytes).

por exemplo, se vc tiver um MPC860, que eh um powerpc antigo, vc tem 4 controladores HDLC dentro dele e cada um deles pode ser quebrado em ateh 32 sub-controladores. assim, vc poderia configurar uma interface PCM de 8MHz e quebrar 1/4 dessa interface p/ cada controlador, tendo assim 128 canais PCM que podem trabalhar com voz ou dados (HDLC). tipicamente, cada canal vai ter um ring-buffer de 8 a 32 frames com um certo tamanho. por exemplo, para audio o payload tipico eh o mesmo dos frames RTP e, portanto costuma ser de 40, 80 ou 160 bytes. se vc pegar o caso mais amplo, vc teria entao 32 frames de 160 bytes em cada canal, com 128 canais no total. sao 4096 buffers de 160 bytes para ele gerenciar. com 160 bytes, a cadencia do stream RTP fica em 50 frames/s por canal.

o interessante eh que eh possivel alinhar a transferencia exatamente nos limites de um frame RTP, quer dizer, o dma preenche o frame automaticamente e depois o powerpc apenas coleta os frames, adiciona headers IP, UDP, RTP e roteia p/ a ethernet a cadencia de 6400 frames/s.

bom, na pratica, o IPv4 dah uma afogada pesada no powerpc soh p/ calcular CRC e vc descobre que um MPC860 pode nao dar conta hehehe daih vc comeca a procurar coisas mais potentes e, eventualmente, aceleracao IP e UDP em hardware comecam a fazer sentido (soh de nao precisar calcular CRC frame a frame a coisa jah melhora muito!). mas daih o merito comeca a sair do controlador de dma e ir p/ o periferico.

MensagemEnviado: 14 Mar 2012 16:40
por fabim
...
Bom, então, se eu setar RAM to SPI, a velocidade dos 128 bytes que eu setei da DMA, vai ser igual a velocidade de Bytes por segundo da SPI correto ?
Nestes 128 bytes, o meu programa não se preocupa com absolutamente nada, é tudo automático via hW. Ao fim dos 128 bytes, pode haver uma interrupção e eu tratar como necessário, ou nestes 128 bytes eu fiquei verificando o DONE como exemplificado acima ?

É isto mesmo sam ?

MensagemEnviado: 14 Mar 2012 16:41
por fabim
...
Bom, então, se eu setar RAM to SPI, a velocidade dos 128 bytes que eu setei da DMA, vai ser igual a velocidade de Bytes por segundo da SPI correto ?
Nestes 128 bytes, o meu programa não se preocupa com absolutamente nada, é tudo automático via hW. Ao fim dos 128 bytes, pode haver uma interrupção e eu tratar como necessário, ou nestes 128 bytes eu fiquei verificando o DONE como exemplificado acima ?

É isto mesmo sam ?

MensagemEnviado: 14 Mar 2012 17:01
por proex
Eu testei aqui DMA entre um buffer da ram e a SPI. Ficou uma bosta.

MensagemEnviado: 14 Mar 2012 19:03
por msamsoniuk
nao conheco o controlador que vc esta usando, mas em todos os controladores que eu vi, a interrupcao eh gerada pelo controlador quando o buffer na memoria enche, ou seja, se vc setar 128, quando o controlador de dma fizer 128 transferencias ele vai gerar uma interrupcao para vc trocar o buffer. portanto, sem ter que verificar o done.

fabim escreveu:...
Bom, então, se eu setar RAM to SPI, a velocidade dos 128 bytes que eu setei da DMA, vai ser igual a velocidade de Bytes por segundo da SPI correto ?
Nestes 128 bytes, o meu programa não se preocupa com absolutamente nada, é tudo automático via hW. Ao fim dos 128 bytes, pode haver uma interrupção e eu tratar como necessário, ou nestes 128 bytes eu fiquei verificando o DONE como exemplificado acima ?

É isto mesmo sam ?

MensagemEnviado: 14 Mar 2012 19:24
por fabim
Nossa será que to falando çhineix ?
hehehe
Eu observei vários DMAs, e nenhum deles pode-se configurar finamente o digamos sample rate !! hehehe
Procurei 3 app note de fabricantes diferentes, e todos eles.

Confirmaram o que eu imaginava e perguntei a afirmação ou não lá encima noprimeiro post.

" A transferencia pela DMA de dados para periférico, é controlado automaticamente sem a intervenção de software. A velocidade de transferencia de bytes é limitada pela velocidade de transferencia do periférico."

hehehe, tendeu agora minha duvida sam ?