Página 1 de 2
TMR clock source -> cortex M3.

Enviado:
06 Mai 2010 17:50
por fabim
Cara eu estou fulo com isso, ou sei lá que esta acontecendo com esse fdp..
To utilizando o TMR0 com Math0 interrupt e reset no estouro....
Eu estou configurando o seguinte.
CCLOCK = 102mhz..
Ou seja a fonte de clock para os perifericos é de 102mhz. Estou jogando direto no timer sem preescaler.
o tempo que eu estou utilizando para comparaçao do math0 =.
(1/12000) / (1/102000000) == 102000000/12000.
Acontece que o frame rate, fica 4X maior!!!!!
no user manual fala que eu não pego o sinal do PLL0 out, e sim na saida de clock que vai para CPU.
Que coisa estranha, eu procurei errata e nao achei nada..
Re: TMR clock source -> cortex M3.

Enviado:
06 Mai 2010 18:39
por Rodrigo_P_A
fabim escreveu:Cara eu estou fulo com isso, ou sei lá que esta acontecendo com esse fdp..
To utilizando o TMR0 com Math0 interrupt e reset no estouro....
Eu estou configurando o seguinte.
CCLOCK = 102mhz..
Ou seja a fonte de clock para os perifericos é de 102mhz. Estou jogando direto no timer sem preescaler.
o tempo que eu estou utilizando para comparaçao do math0 =.
(1/12000) / (1/102000000) == 102000000/12000.
Acontece que o frame rate, fica 4X maior!!!!!
no user manual fala que eu não pego o sinal do PLL0 out, e sim na saida de clock que vai para CPU.
Que coisa estranha, eu procurei errata e nao achei nada..
tem certeza que o clock é o mesmo da CPU?
você já verificou os registradores de divisão de clock? pois existem registros de divisão do clock dos periféricos.

Enviado:
08 Mai 2010 17:21
por fabim
Rodrigo, estava eu agora "08/05/2010 - 17:05", fazendo alguns testes aqui. Num é possivel, a unica explicação, é que aquele init system tem algum purrete, ou sei lá que raios.
Entrei no debug e estava observando a configuração dos clocks, não tem como aquilo estar correto..
Pelos meus calculos, quando ele deveria estar com 102mhz, ele esta com 204mhz...
OBS, a saida do PLL0 esta com 408mhz, CPU running at 102mhz.
GPIOS e latches tudo a 102mhz também .. pombas, bom.. mais funcionou agora.
Onde eu fazia
uint32_t init_timer0 ( uint32_t SampleRate )
{
LPC_TIM0->MR0 = (SystemFrequency/SampleRate)-1;
LPC_TIM0->MCR = 3;
NVIC_EnableIRQ(TIMER0_IRQn);
return (0);
}
o qual, estava com pitch 2X maior nos teoricos 102mhz!!
agora eu faço
uint32_t init_timer0 ( uint32_t SampleRate )
{
LPC_TIM0->MR0 = (SystemFrequency/(SampleRate/2))-1;
LPC_TIM0->MCR = 3;
NVIC_EnableIRQ(TIMER0_IRQn);
return (0);
}
que bate na chuncha, e consigo uma resolução de.
32 bits com 1/1.2kk para gerar os tempos de wave, ou qualquer que é muito preciso nos samples pares e inteiros.
8K,16K,22K,44K...
vai entender... só sei que agora funcionou.. hehehehe intão fockyouda-se o clock..

Enviado:
08 Mai 2010 19:21
por fabim
e agora fiquei um pouco decepcionado...
void TIMER0_IRQHandler (void)
{
uint32_t sample;
LPC_DAC->DACR = sample; //3 ciclos "ja subtraido do timer"
((char *)&sample)[1] = *dados; //4 ciclos
sample |= 0x00010000; // 3 ciclos
dados++; // 5 ciclos
tamanho--; // 5 ciclos
if(tamanho==0) acabou();
LPC_TIM0->IR = 1; /* clear interrupt flag */
return;
}
- Código: Selecionar todos
57: LPC_DAC->DACR = sample; //3 ciclos "ja subtraido do timer"
0x00004088 4920 LDR r1,[pc,#128] ; @0x0000410C
0x0000408A 9800 LDR r0,[sp,#0x00]
0x0000408C 6008 STR r0,[r1,#0x00]
58: ((char *)&sample)[1] = *dados; //4 ciclos
0x0000408E 481C LDR r0,[pc,#112] ; @0x00004100
0x00004090 6800 LDR r0,[r0,#0x00]
0x00004092 7800 LDRB r0,[r0,#0x00]
0x00004094 F88D0001 STRB r0,[sp,#0x01]
59: sample |= 0x00010000; // 3 ciclos
0x00004098 9800 LDR r0,[sp,#0x00]
0x0000409A F4403080 ORR r0,r0,#0x10000
0x0000409E 9000 STR r0,[sp,#0x00]
60: dados++; // 5 ciclos
0x000040A0 4817 LDR r0,[pc,#92] ; @0x00004100
0x000040A2 6800 LDR r0,[r0,#0x00]
0x000040A4 1C40 ADDS r0,r0,#1
0x000040A6 4916 LDR r1,[pc,#88] ; @0x00004100
0x000040A8 6008 STR r0,[r1,#0x00]
61: tamanho--; // 5 ciclos
0x000040AA 4816 LDR r0,[pc,#88] ; @0x00004104
0x000040AC 6800 LDR r0,[r0,#0x00]
0x000040AE 1E40 SUBS r0,r0,#1
0x000040B0 4914 LDR r1,[pc,#80] ; @0x00004104
0x000040B2 6008 STR r0,[r1,#0x00]
62: if(tamanho==0) acabou();
0x000040B4 4608 MOV r0,r1
0x000040B6 6800 LDR r0,[r0,#0x00]
0x000040B8 B910 CBNZ r0,0x000040C0
0x000040BA 2001 MOVS r0,#0x01
0x000040BC 4912 LDR r1,[pc,#72] ; @0x00004108
0x000040BE 7008 STRB r0,[r1,#0x00]
63: LPC_TIM0->IR = 1; /* clear interrupt flag */
64: return;

Enviado:
09 Mai 2010 08:29
por proex
Incremento no ARM :
dados++; // 5 ciclos
LDR r0,[pc,#92]
LDR r0,[r0,#0x00]
ADDS r0,r0,#1
LDR r1,[pc,#88]
STR r0,[r1,#0x00]
Incremento no PIC:
dado++; // 1 ciclo
INCF dado,f
Ai que saudade que dá !!!!
.

Enviado:
09 Mai 2010 08:56
por fabim
proex escreveu:Incremento no ARM :
dados++; // 5 ciclos
LDR r0,[pc,#92]
LDR r0,[r0,#0x00]
ADDS r0,r0,#1
LDR r1,[pc,#88]
STR r0,[r1,#0x00]
Incremento no PIC:
dado++; // 1 ciclo
INCF dado,f
Ai que saudade que dá !!!!
.
Decremento do pic.
tamanho--;
decf var,f; 1 linha

Enviado:
09 Mai 2010 09:16
por fabim
proex, abre o debug, vai em "view > CODE COVERAGE".
De uma olhada na quantidade de instruções. de cada sub, ou mesmo no main...
Sei não, acho que agora estou entendendo perfeitamente o que o Marcelo Samsonite diz acerca de ARM.
Po, se para encrementar uma simples variavel, o cara gasta 5 ciclos de clock rodando a 102mhz, e o mesmo para decrementar.
Quer dizer que.
A performance dele para estas duas instruções = 102/5 = 20.4mhz. E se fizer escalar seria uma média de 10.2mhz ?
Agora, me responde, de onde a NXP tirou que é 1.15Dmip mhz ?
Fiz centenas de outros testes, de varias formas possiveis, olhando o manual do ASM do ARM. e é isso ai mesmo........
Bom, no literal é o seguinte.
Para que nossa perspectiva seja atingida, é necessario um Cortex M3 de 510mhz, pelo menos nos inc e dec, para que realmente seja 102mhz..
Vou continuar estudando isso, mais até o momento, estou meio decepcionado..

Enviado:
09 Mai 2010 10:20
por tcpipchip
A ideia inicial do ARM nao era para ser aplicações em tempo real.
Se possivel, declare o tipos de dados de 16 bits paras as variáveis que forem acessadas dentro da interrupt e tambem declare a interrupt como THUMB.
Vai te ajudar.

Enviado:
09 Mai 2010 12:10
por proex
......Agora, me responde, de onde a NXP tirou que é 1.15Dmip mhz ?..........
Eu ja te expliquei isso. Esse desempenho é medido com o código rodando na RAM.
.

Enviado:
09 Mai 2010 12:45
por msamsoniuk
para esse tipo de aplicacao eh melhor usar um processador que tenha canal de DMA ou entao um DAC que tenha FIFO. no caso de um processdor com canal de DMA, vc soh tera interrupcao no final da transmissao de um buffer completo, onde vc ira programar o DMA para apontar para o proximo frame. no caso de usar um DAC com FIFO, na interrupcao vc otimiza o codigo criando um loop com variaveis register e transferindo um bloco maior para a FIFO.
mas se nao tem outra opcao, o que vc pode fazer eh tentar minimizar ao maximo o processamento. a primeira coisa que eu diria que seria legal eh eliminar qq processamento tipo leitura-modificacao-escrita para fora da interrupcao principal:
- Código: Selecionar todos
void TIMER0_IRQHandler(void)
{
*LPC_DAC_DACRL = *dados++;
*LPC_DAC_DACRH = 0x0001;
if (dados==(dados+tamanho))
acabou();
*LPC_TIM0_IR = 1;
return;
}
no lugar de fazer o OR, eu setei um valor e depois setei outro valor, separando o DAC ali em H e L. nao sei se eh permitido no seu processador, imagino que o valor do OR eh um flag ou algo assim. e no lugar de usar um contador separado, usar o proprio ponteiro e comparar com um valor final, eliminando assim o outro decremento (q eh uma operacao tipo leitura-modifica-escrita). usar a comparacao ali no fim eh mais em conta pq uma vez lido o dado, ele pode ser somado, comparado e incrementado, porem apenas o incremento impacta em escrita.
outra possibilidade:
- Código: Selecionar todos
void TIMER0_IRQHandler(void)
{
*LPC_DAC_DACRL = dados[idx++];
*LPC_DAC_DACRH = 0x0001;
if (idx==tamanho)
acabou();
*LPC_TIM0_IR = 1;
return;
}
nesse caso, a unica variavel com leitura-modificacao-escrita eh idx, mas a operacao consome menos banda pq idx poderia ser char ou short... mas o ganho varia de processador para processador e teria que tentar varias possibilidades e ir comparando ateh achar o caminho mais otimizado.

Enviado:
10 Mai 2010 18:10
por MarcusPonce
Caro Fabim, muito interessantes os seus testes.
Fiquei curioso: você chegou a ajustar nas "Options fot Target nnnnn", aba "C/C++", item "Optimization" como Level 3 (-O3) ? Acho que o código ficaria um pouco menor do que aquele que você obteve, pois para incrementar uma posição de memória parece que bastaria um load, um add, e um store.
Você já viu alguém comparar um ARM com um canhão para matar mosca ? Pois é, carregar o canhão com a bala de canhão dá mais trabalho mesmo. Para apenas uma mosca seria mais prático alguma coisa mais simples, mas o canhão também mata mosca...
Em outras palavras: INCF é apenas 1 instrução e é realmente uma pena que o ARM não tenha uma instrução igual, mas para nos consolarmos com a situação:
a) Em um PIC, se não me engano, INCF só pode incrementar 1 byte e o espaço que ele atinge é de apenas 128 bytes ou 256bytes. No ARM é incrementada uma variável de 32bits de uma vez e você pode usar qualquer posição de memória.
b) Para fazer uma comparação mais justa com INCF e DECF precisamos lembrar que elas usam 1 ciclo de instrução = 4 ciclos de clock...
Já incrementou uma variável de 32bits na memória de um PIC ?

Enviado:
10 Mai 2010 18:24
por fabim
Marcus.. hehe.
Acho que não entendeu o meu sarcasmo..
Seguinte. o optimization fica sempre no talo..
E 1.15Dmips em 102mhz, somente na ram... Nem no sapo, perereca nem o scambal..
Fiz varios testes, e realmente.. não sei de onde eles tiraram 1.15Dmips..
Fiz um testinho hoje de manhã.
Coloquei um *.C pra rodar na ram.
liga timer, executa tal coisa, desliga timer etc.
Coloquei o mesmo no na flash, fiz o mesmo, e comparei os tempos.
Divinha ? Na ram, melhorou muito pouco do que na flash. Pode fazer o teste ai pra você ver..
Bom, de qualquer forma.. espero que tenha entendido agora

Enviado:
10 Mai 2010 19:34
por MarcusPonce
Fabim, acho que tenho uma idéia de onde eles tiraram aquele número de DMIPS. No link abaixo dentro da ARM está escrito aquilo que a NXP publicou:
http://www.arm.com/products/processors/ ... ifications
Qual o significado da contagem de DMIPS ? Bem, como explicado no link abaixo, 1 DMIPS no ARM não é a mesma coisa que "1 milhão de instruções por segundo no ARM":
http://en.wikipedia.org/wiki/Dhrystone
Pois é: marketing

Enviado:
10 Mai 2010 20:08
por fabim
Sim, é 1.15Dmips.Mhz@FMPO

Enviado:
10 Mai 2010 20:09
por fabim
rum, rummmmmm;;
FREQUENCIA MÁXIMA PARA OTÁRIOS