Declaração "absolute" MikroC e DsPic33fj + DMA

Software e Hardware para uC PIC

Moderadores: andre_luis, 51, guest2003, Renie

Declaração "absolute" MikroC e DsPic33fj + DMA

Mensagempor Silvio51 » 08 Ago 2015 02:31

Caros, alguém poderia me dizer (escrever acho que é melhor) como alocar um buffer em um endereço específico sem que o compilador bagunce tudo?

Quando aloco o dados sem inicializar os valores, como abaixo, o dado fica no local correto...

Código: Selecionar todos
unsigned int Buffer_A [256] absolute 0x4000 ;


Quando fuço no .list, o dado está alocado realmente no endereço 0x4000 (endereço inicial da DPRAM dos canais de DMA).

Código: Selecionar todos
0x4000 ics Buffer_A


Porém se inicializo meu buffer, como abaixo, o compilador joga os dados para o endereço 0x8000...

Código: Selecionar todos
unsigned int Buffer_B [256] = {Dado1, Dado2...Dado256} absolute 0x4300 ;



Código: Selecionar todos
0x8000 ics Buffer_B


Eu já tentei mudar a declaração para "volatile" e outras cositas más, pero o compilador sempre aloca em 0x8000...

É claro que se eu declarar sem inicializar (como no Buffer_A) e preencher depois meu buffer com algo do tipo abaixo (preencher o buffer), a coisa funciona, mas...

Código: Selecionar todos
for (int i =0 ; i <= 255 ; i++) {

              Buffer_B [i] = i +5 ;
              } ;
   


Como referência, tô usando os canais 1 e 2 do DMA para transferir dados para o canal de Output Compare 1 e para a porta SPI para gerar video, respectivamente...DsPic33FJ128GP802 e Mikroc Pro DsPic V6.2
Silvio51
Byte
 
Mensagens: 383
Registrado em: 02 Nov 2006 14:04
Localização: Brasil

Re: Declaração "absolute" MikroC e DsPic33fj + DMA

Mensagempor Eduardo Augusto » 08 Ago 2015 11:34

Acho que declarando e inicializando a variável ao mesmo tempo você esta passando para o compilador a responsabilidade de alocar toda essa memória de uma única vez, não sei talvez esteja falando mer..da...
Minha recomendação com vetores é declarar o vetor, e depois inicializar ele passando valores para ele. Afinal você pode inicializar um na próxima linha de instrução...
unsigned int Buffer_A [256];

Buffer_A[256]= {Dado1, Dado2...Dado256}
Não é possível dormir com todas mulheres do mundo, mas deve-se fazer o esforço.
Avatar do usuário
Eduardo Augusto
Byte
 
Mensagens: 105
Registrado em: 03 Mar 2014 08:57
Localização: São Paulo, SP

Re: Declaração "absolute" MikroC e DsPic33fj + DMA

Mensagempor Eduardo Augusto » 08 Ago 2015 13:13

http://ww1.microchip.com/downloads/en/D ... 70182C.pdf

Tem um manual de referencia da microchip para o desenvolvimento com DMA, da uma olhada na página 18, da uma exemplo de um DMA com dois buffers....
Código: Selecionar todos
unsigned int BufferA[8] __attribute__((space(dma)));
unsigned int BufferB[8] __attribute__((space(dma)));
DMA0STA = __builtin_dmaoffset(BufferA);
DMA0STB = __builtin_dmaoffset(BufferB);


Mais abaixo na página 24 tem um exemplo onde ele linka dois buffers do pwm com o canal DMA.

Código: Selecionar todos
Set up Output Compare 1 module for PWM mode:
OC1CON = 0; // Reset OC module
OC1R = 0x60; // Initialize PWM Duty Cycle
OC1RS = 0x60; // Initialize PWM Duty Cycle Buffer
OC1CONbits.OCM = 6; // Configure OC for the PWM mode
Set up DMA Channel 3 for in Post Increment mode with Timer2 Request source:
unsigned int BufferA[32] __attribute__((space(dma)));
/* Insert code here to initialize BufferA with desired Duty Cycle values */
DMA3CONbits.AMODE = 0; // Configure DMA for Register indirect mode
// with post-increment
DMA3CONbits.MODE = 0; // Configure DMA for Continuous mode
DMA3CONbits.DIR = 1; // RAM-to-Peripheral data transfers
DMA3PAD = (volatile unsigned int)&OC1RS; // Point DMA to OC1RS
DMA3CNT = 31; // 32 DMA request
DMA3REQ = 7; // Select Timer2 as DMA Request source
DMA3STA = __builtin_dmaoffset(BufferA);
IFS2bits.DMA3IF = 0; // Clear the DMA interrupt flag bit
IEC2bits.DMA3IE = 1; // Set the DMA interrupt enable bit
DMA3CONbits.CHEN = 1; // Enable DMA
Set up Timer2 for Output Compare PWM mode:
PR2 = 0xBF; // Initialize PWM period
T2CONbits.TON = 1; // Start Timer2
Set up DMA Channel 3 Interrupt Handler:
void __attribute__((__interrupt__)) _DMA3Interrupt(void)
{
/* Update BufferA with new Duty Cycle values if desired here*/
IFS2bits.DMA3IF = 0; //Clear the DMA3 Interrupt Flag
}
Não é possível dormir com todas mulheres do mundo, mas deve-se fazer o esforço.
Avatar do usuário
Eduardo Augusto
Byte
 
Mensagens: 105
Registrado em: 03 Mar 2014 08:57
Localização: São Paulo, SP

Re: Declaração "absolute" MikroC e DsPic33fj + DMA

Mensagempor andre_luis » 08 Ago 2015 14:20

Também já fiquei tentado em certas ocasiões a alocar dados em posições fixas de memória, mas a menos que isso seja realmente necessário, descer a programação a esse nível não é uma boa decisão, pois o código poderá eventualmente competir com alguma diretiva do linker do compilador, nessa ou em outra plataforma de hardware, caso deseje portar para outro uC.
"Por maior que seja o buraco em que você se encontra, relaxe, porque ainda não há terra em cima."
Avatar do usuário
andre_luis
Dword
 
Mensagens: 5447
Registrado em: 11 Out 2006 18:27
Localização: Brasil - RJ

Re: Declaração "absolute" MikroC e DsPic33fj + DMA

Mensagempor Silvio51 » 08 Ago 2015 22:40

Eduardo,

Eu conheço bem este material que você postou e creio que as diretivas do MPLAB diferem um pouco da forma como o MikroC trabalha nestes casos...como por exemplo na diretiva "built in":

Código: Selecionar todos
DMA0STA = __builtin_dmaoffset(BufferA);


Este código aloca o buffer justamente no espaço destinado ao DMA, resguardados os diversos tipos de DsPic33 (o endereço muda de acordo com o tipo) e não tem correspondente no mikroC


Este exemplo que você mostra é mais ou menos a forma como estou fazendo...e não tem problemas de funcionamento: o circuito funciona muito bem se inicializo depois de declarar...só queria saber se é assim mesmo ou é algum BUG...

Vou ficar fazendo então da forma que fiz e que você recomenda. Pelo menos não terei problemas!

Andre,

Neste caso é realmente necessário especificar o endereço porque é o endereço inicial da RAM do DMA, onde os dados que irão ser transferidos estão alocados...este endereço é fixo, então não posso delegar ao linker/compilador que aloque onde quiser, teria que ser neste exato endereço se não o DMA não vai funcionar...

Apesar da diretiva "built in" do MPLAB (C30 e XC16), não gosto muito de utilizar este compilador, prefiro o mikroC mesclado com assembly...

Grato,
Silvio51
Byte
 
Mensagens: 383
Registrado em: 02 Nov 2006 14:04
Localização: Brasil

Re: Declaração "absolute" MikroC e DsPic33fj + DMA

Mensagempor Silvio51 » 08 Ago 2015 23:52

Eduardo Augusto escreveu:Acho que declarando e inicializando a variável ao mesmo tempo você esta passando para o compilador a responsabilidade de alocar toda essa memória de uma única vez, não sei talvez esteja falando mer..da...
Minha recomendação com vetores é declarar o vetor, e depois inicializar ele passando valores para ele. Afinal você pode inicializar um na próxima linha de instrução...
unsigned int Buffer_A [256];

Buffer_A[256]= {Dado1, Dado2...Dado256}



Testei...assim não funciona:

Código: Selecionar todos
unsigned int Buffer_A [256] absolute 0x4200 ;


Código: Selecionar todos
 Buffer_A[256]= {Dado1, Dado2...Dado256} ;


O compilador retorna o seguinte erro: Line 21 "Message 393" : 'Buffer_A' Indentifier redefined

Terei que continuar inicializando no programa (em uma função) ?
Silvio51
Byte
 
Mensagens: 383
Registrado em: 02 Nov 2006 14:04
Localização: Brasil

Re: Declaração "absolute" MikroC e DsPic33fj + DMA

Mensagempor Silvio51 » 09 Ago 2015 07:02

Eureca!!! :mrgreen: Que burrice a minha!!!

Vou considerar como um "lapso de memória"....

É claro que o linker não pode alocar meu buffer na RAM: ele não acessa a RAM !!!

O compilador só pode "escrever" na memória de programa (gerar opcodes para a Flash)...claro...o que ele pode fazer é reservar um endereço pra mim na RAM através de um opcode salvo na Flash...e só....

Por isso que ele está alocando a tabela na flash mapeada em RAM (0x8000).

Meu firmware (e agora "lógico") é que pode pegar a tabela que o compilador inteligentemente (ao contrário de mim) colocou na Flash durante a compilação, daí carregar na RAM.

Obrigado Srs,
Silvio51
Byte
 
Mensagens: 383
Registrado em: 02 Nov 2006 14:04
Localização: Brasil


Voltar para PIC

Quem está online

Usuários navegando neste fórum: Nenhum usuário registrado e 1 visitante

x